From c9d3d6a9d0a2bb3426f8276857ec514eae786d82 Mon Sep 17 00:00:00 2001 From: bulatz Date: Sat, 25 Jul 2009 07:38:49 +0000 Subject: [PATCH] CELS: implemented "storing" git-svn-id: https://freearc.svn.sourceforge.net/svnroot/freearc@452 3a4f7f31-9599-433d-91b1-573e8b61252c --- ArcvProcessExtract.hs | 9 ++-- Compression/CELS.cpp | 97 +++++++++++++++++++++++++++++++++++++++---- Compression/CELS.h | 14 +++---- 3 files changed, 100 insertions(+), 20 deletions(-) diff --git a/ArcvProcessExtract.hs b/ArcvProcessExtract.hs index 316f61b..bcbd4ff 100644 --- a/ArcvProcessExtract.hs +++ b/ArcvProcessExtract.hs @@ -16,7 +16,7 @@ import Foreign.Ptr import Foreign.Marshal.Utils import Foreign.Storable -import TABI hiding (doNothing) +import TABI import Utils import Errors import Process @@ -159,7 +159,8 @@ de_compress_PROCESS1 de_compress reader times command limit_memory comprMethod n testMalloc #ifdef FREEARC_CELS let callback p = do - service <- TABI.required p "" + TABI.dump p + service <- TABI.required p "request" case service of -- Процедура чтения входных данных процесса упаковки/распаковки "read" -> do buf <- TABI.required p "buf" @@ -190,7 +191,7 @@ de_compress_PROCESS1 de_compress reader times command limit_memory comprMethod n else callback p -- Non-debugging wrapper debug f = f - debug_checked_callback what buf size = undefined --TABI.call checked_callback [Pair "" what, Pair "buf" size, Pair "buf" size] + debug_checked_callback what buf size = TABI.call (\a->fromIntegral `fmap` checked_callback a) [Pair "request" what, Pair "buf" buf, Pair "size" size] #else let -- Процедура чтения входных данных процесса упаковки/распаковки callback "read" buf size = do res <- reader buf size @@ -229,7 +230,7 @@ de_compress_PROCESS1 de_compress reader times command limit_memory comprMethod n #endif -- СОБСТВЕННО УПАКОВКА ИЛИ РАСПАКОВКА - res <- debug_checked_callback "read" nullPtr 0 -- этот вызов позволяет отложить запуск следующего в цепочке алгоритма упаковки/распаковки до момента, когда предыдущий возвратит хоть какие-нибудь данные (а если это поблочный алгоритм - до момента, когда он обработает весь блок) + res <- debug_checked_callback "read" nullPtr (0::Int) -- этот вызов позволяет отложить запуск следующего в цепочке алгоритма упаковки/распаковки до момента, когда предыдущий возвратит хоть какие-нибудь данные (а если это поблочный алгоритм - до момента, когда он обработает весь блок) opt_testMalloc command &&& showMemoryMap -- напечатаем карту памяти непосредственно перед началом сжатия real_method <- limit_memory num comprMethod -- обрежем метод сжатия при нехватке памяти result <- if res<0 then return res diff --git a/Compression/CELS.cpp b/Compression/CELS.cpp index 4e47642..50b3bec 100644 --- a/Compression/CELS.cpp +++ b/Compression/CELS.cpp @@ -4,12 +4,14 @@ namespace CELS { +// *********************************************************************************************************************** +// Реализация класса COMPRESSION_METHOD * +// *********************************************************************************************************************** + int COMPRESSION_METHOD::server() { char *service = p._str("service"); - if (strequ (service, "encryption?")) return 1; // to do: --- - // Global services if (strequ (service, "register")) return FREEARC_OK; //to do: Register(); @@ -31,8 +33,68 @@ int COMPRESSION_METHOD::server() return FREEARC_ERRCODE_NOT_IMPLEMENTED; } + +// **************************************************************************************************************************** +// МЕТОД "СЖАТИЯ" STORING ***************************************************************************************************** +// **************************************************************************************************************************** + +// Функция "(рас)паковки", копирующая данные один в один +int copy_data (CALLBACK_FUNC *callback, void *auxdata) +{ + char buf[BUFFER_SIZE]; int len, errcode; + for(;;) + { + READ_LEN_OR_EOF(len, buf, BUFFER_SIZE); + WRITE(buf, len); + } +finished: + return errcode; +} + +// Реализация метода "сжатия" STORING +struct STORING_METHOD : COMPRESSION_METHOD +{ + // Конструктор, присваивающий параметрам метода значения по умолчанию + STORING_METHOD (TABI_ELEMENT* params) : COMPRESSION_METHOD(params) {} + // Функции распаковки и упаковки + virtual int decompress (CALLBACK_FUNC *callback, void *auxdata) {return copy_data (callback, auxdata);} +#ifndef FREEARC_DECOMPRESS_ONLY + virtual int compress (CALLBACK_FUNC *callback, void *auxdata) {return copy_data (callback, auxdata);} + + // Разбирает строку с параметрами метода + virtual void parse_method() + { + if (!strequ (p._str("method"), "storing")) + throw "STORING_METHOD:parse_method"; + } + + // Записать в buf[MAX_METHOD_STRLEN] строку, описывающую метод сжатия (функция, обратная к parse_method) + virtual void ShowCompressionMethod (char *buf) {sprintf (buf, "storing");} + + // Получить/установить объём памяти, используемой при упаковке/распаковке, размер словаря или размер блока + virtual MemSize GetCompressionMem (void) {return BUFFER_SIZE;} + virtual MemSize GetDictionary (void) {return 0;} + virtual MemSize GetBlockSize (void) {return 0;} + virtual void SetCompressionMem (MemSize) {} + virtual void SetDecompressionMem (MemSize) {} + virtual void SetDictionary (MemSize) {} + virtual void SetBlockSize (MemSize) {} +#endif + virtual MemSize GetDecompressionMem (void) {return BUFFER_SIZE;} +}; + +// Function that represents STORING compression method +int storing_server (TABI_ELEMENT* params) +{ + return STORING_METHOD(params).server(); } +// Register STORING method in CELS +int storing_register = CELS_Register(storing_server); + +} // namespace CELS + + // **************************************************************************************************************************** // ПОДДЕРЖКА ТАБЛИЦЫ ЗАРЕГИСТРИРОВАННЫХ МЕТОДОВ СЖАТИЯ И ПОИСК В ЭТОЙ ТАБЛИЦЕ РЕАЛИЗАЦИИ ЧИСТО КОНКРЕТНОГО МЕТОДА ************* // **************************************************************************************************************************** @@ -55,19 +117,36 @@ int CELS_Register (TABI_FUNCTION *method) int CELS_Call (TABI_ELEMENT* params) { TABI_MAP p(params); p.dump(); + char *service = p._str("service"); + + // ==== AUTO-SERVICE ====================================== + // Ignore zero parameter to some Set* services + if (strequ (service, "SetCompressionMem") || strequ (service, "SetDecompressionMem") || strequ (service, "SetDictionary") || strequ (service, "SetBlockSize")) + if (p._int("mem",1)==0) + return p._return(p._str("method")); + if (start_with (service, "Limit")) return p._return(p._str("method")); // to do: get & set + if (strequ (service, "encryption?")) return 1; // to do: aes-specific + if (start_with (p._str("method",""), "aes")) return p._return(p._str("method")); // to do: aes-specific + //GetBlockSize {return 0;} + //SetBlockSize {} + //Limit get & set + // ======================================================== + + // Find appropriate method to service this call for (int i=0; i0) ...;} - //SetDictionary {if (dict>0) ...;} - //GetBlockSize {return 0;} - //SetBlockSize {} - //Limit get & set - if (x!=FREEARC_ERRCODE_NOT_IMPLEMENTED) return x; } return FREEARC_ERRCODE_NOT_IMPLEMENTED; } +// Temporary +extern "C" { +void tabi_dump(TABI_ELEMENT *params, int n=0) +{ + TABI_MAP(params).dump(n); +} +} + diff --git a/Compression/CELS.h b/Compression/CELS.h index 3216109..664ac2e 100644 --- a/Compression/CELS.h +++ b/Compression/CELS.h @@ -120,8 +120,8 @@ int CELS_Call (TABI_ELEMENT* params); // **************************************************************************************************************************** // Auxiliary code to read/write data blocks and 4-byte headers -#define INIT() callback (TABI_DYNAMAP("init")) -#define DONE() callback (TABI_DYNAMAP("done")) +#define INIT() callback (TABI_DYNAMAP("request","init")) +#define DONE() callback (TABI_DYNAMAP("request","done")) #define MALLOC(type, ptr, size) \ { \ @@ -145,7 +145,7 @@ int CELS_Call (TABI_ELEMENT* params); { \ void *localBuf = (buf); \ int localSize = (size); \ - if (localSize && (errcode=callback(TABI_DYNAMAP("read") ("buf",localBuf) ("size",localSize))) != localSize) { \ + if (localSize && (errcode=callback(TABI_DYNAMAP("request","read") ("buf",localBuf) ("size",localSize))) != localSize) { \ if (errcode>=0) errcode=FREEARC_ERRCODE_IO; \ goto finished; \ } \ @@ -153,14 +153,14 @@ int CELS_Call (TABI_ELEMENT* params); #define READ_LEN(len, buf, size) \ { \ - if ((errcode=(len)=callback(TABI_DYNAMAP("read") ("buf",buf) ("size",size))) < 0) { \ + if ((errcode=(len)=callback(TABI_DYNAMAP("request","read") ("buf",(void*)(buf)) ("size",size))) < 0) { \ goto finished; \ } \ } #define READ_LEN_OR_EOF(len, buf, size) \ { \ - if ((errcode=(len)=callback(TABI_DYNAMAP("read") ("buf",buf) ("size",size))) <= 0) { \ + if ((errcode=(len)=callback(TABI_DYNAMAP("request","read") ("buf",(void*)(buf)) ("size",size))) <= 0) { \ goto finished; \ } \ } @@ -170,7 +170,7 @@ int CELS_Call (TABI_ELEMENT* params); void *localBuf = (buf); \ int localSize = (size); \ /* "write" callback on success guarantees to write all the data and may return 0 */ \ - if (localSize && (errcode=callback(TABI_DYNAMAP("write") ("buf",localBuf) ("size",localSize)))<0) \ + if (localSize && (errcode=callback(TABI_DYNAMAP("request","write") ("buf",localBuf) ("size",localSize)))<0) \ goto finished; \ } @@ -199,7 +199,7 @@ int CELS_Call (TABI_ELEMENT* params); #define QUASIWRITE(size) \ { \ - callback(TABI_DYNAMAP("quasiwrite") ("size",size)); \ + callback(TABI_DYNAMAP("request","quasiwrite") ("size",size)); \ } #define ReturnErrorCode(x) \