Проблема с освоением ZLIB

Тема в разделе "WASM.BEGINNERS", создана пользователем _nic, 10 май 2011.

  1. _nic

    _nic New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2007
    Сообщения:
    372
    Пакую так в BCB(текстовый файл)
    Код (Text):
    1. OpenDialog1->Execute(Form1->Handle);
    2.     HANDLE f=CreateFileA(AnsiString(OpenDialog1->FileName).c_str(),GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
    3.     if(f!=INVALID_HANDLE_VALUE)
    4.     {
    5.         uLongf inSZ=1024*1024;
    6.         uLongf outSZ=2*(1024*1024);
    7.         Bytef *INbuf=new Bytef[inSZ];
    8.         memset(INbuf,0,inSZ);
    9.         Bytef *OUTbuf=new Bytef[outSZ];
    10.         memset(OUTbuf,0,outSZ);
    11.         DWORD r=0,w=0;
    12.         ReadFile(f,INbuf,inSZ,&r,0);
    13.         wchar_t *unibuf=new wchar_t[outSZ];
    14.         MultiByteToWideChar(CP_ACP,0,INbuf,-1,unibuf,outSZ);
    15.         Memo1->Lines->Add(UnicodeString(unibuf));
    16.         Memo1->Lines->Add("----------------------------------------------------");
    17.         memset(unibuf,NULL,outSZ);
    18.         compress(OUTbuf,&outSZ,INbuf,inSZ);
    19.         CloseHandle(f);
    20.  
    21.         f=CreateFileA("test.pck",GENERIC_WRITE,FILE_SHARE_WRITE,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
    22.         WriteFile(f,OUTbuf,outSZ,&w,0);
    23.         CloseHandle(f);
    24.  
    25.         memset(INbuf,0,inSZ);
    26.         ShowMessage(inSZ);
    27.         uncompress(INbuf,&inSZ,OUTbuf,2*(1024*1024));
    28.         MultiByteToWideChar(CP_ACP,0,INbuf,-1,unibuf,2*(1024*1024));
    29.         Memo1->Lines->Add(UnicodeString(unibuf));
    30.         delete []INbuf;
    31.         delete []OUTbuf;
    32.         delete []unibuf;
    33.     }
    Распаковываю в Visual Studio
    Код (Text):
    1. HANDLE f=CreateFileA("C:\\Users\\user\\Documents\\RAD Studio\\Projects\\packer\\Debug\\test.pck",GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
    2.     if(f!=INVALID_HANDLE_VALUE)
    3.     {
    4.         uLongf inSZ=1024*1024;
    5.         uLongf outSZ=2*(1024*1024);
    6.         Bytef *INbuf=new Bytef[inSZ];
    7.         memset(INbuf,0,inSZ);
    8.         Bytef *OUTbuf=new Bytef[outSZ];
    9.         memset(OUTbuf,0,outSZ);
    10.         DWORD r=0;
    11.         ReadFile(f,INbuf,inSZ,&r,0);
    12.         printf("uncompress:%d\n",uncompress(OUTbuf,&outSZ,INbuf,inSZ));
    13.         printf("Decompressed sz: %d\n",inSZ);
    14.         getch();
    15.         printf("%s",INbuf);
    16.     }
    17.     else
    18.     {
    19.         printf("fail open file");
    20.     }
    21.     getch();
    Проблема в том что при распаковке полная пурга получается,хотя и uncompress возвращяет 0.В чем может быть проблема?(
     
  2. SilentSnowfall

    SilentSnowfall New Member

    Публикаций:
    0
    Регистрация:
    8 фев 2011
    Сообщения:
    27
    Ппц, мои глаза, ну и код.
    1. Во-первых, если уж запаковывать и распаковывать, то нужно хотя бы писать в файл размер упакованных данных. И не делать никаких предположений о размерах буферов, а нормально рассчитывать количество памяти, которое необходимо выделять для вызова каждой из функций. Естественно, у тебя полная чушь получается. В частности, при запаковке ты пишешь в файл outSZ байт:
    WriteFile(f,OUTbuf,outSZ,&w,0);
    При этом outSZ у тебя равно значению, возвращенному функцией compress во втором параметре, переданном по указателю. Соответственно, такой же объем данных нужно и распаковывать, но распаковывается у тебя почему-то жестко захардкоденное (1024*1024) количество байт.

    2. Во-вторых, почитай хоть какие-нибудь правила о стиле кодирования - о расстановке пробелов, именовании переменных и т.п. Без них код полное нечитаемое УГ. Для лабы (как я понял, это лаба) конечно сойдет, но нормальный код так писать нельзя.

    3. Не специалист во всяких BCB, но на 99.9% был уверен, что есть нормальные средства преобразования AnsiString в UnicodeString и Win32-функции использовать для этого не нужно. И точно, погуглив, стало известно, что UnicodeString имеет конструктор UnicodeString(const char*). Смысл тогда городить велосипеды?

    Код должен выглядеть примерно так (хотя все равно он УГ, но для лабы сойдет). Запаковка:
    Код (Text):
    1. OpenDialog1->Execute(Form1->Handle);
    2. HANDLE hFile = CreateFileA(AnsiString(OpenDialog1->FileName).c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    3. if (hFile == INVALID_HANDLE_VALUE)
    4.     return; //нефиг плодить лишние уровни вложенности отступов
    5.    
    6. uLongf inSize = 1024 * 1024;
    7. Bytef *inBuf = new Bytef[inSize];
    8. //memset тут нафиг не нужен
    9. //operator new[] и так инициализирует массив значениями по умолчанию (0 для целочисленных типов)
    10.  
    11. ReadFile(hFile, inBuf, inSize, &inSize, NULL); // считываем максимум 1MB, но фактический размер файла может быть меньше
    12. CloseHandle(hFile);
    13.  
    14. Memo1->Lines->Add(UnicodeString(reinterpret_cast<const char*>(inBuf)));
    15. Memo1->Lines->Add("----------------------------------------------------");
    16.        
    17. uLongf outSize = compressBound(inSize);
    18. Bytef *outBuf = new Bytef[outSize];
    19. compress(outBuf, &outSize, inBuf, inSize);
    20.  
    21. hFile = CreateFileA("test.pck", GENERIC_WRITE, FILE_SHARE_WRITE, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);        
    22. DWORD w = 0;
    23. WriteFile(hFile, &inSize, sizeof(inSize), &w, NULL); //пишем размер исходных данных
    24. WriteFile(hFile, outBuf, outSize, &w, NULL);
    25. CloseHandle(hFile);
    26.  
    27. memset(inBuf, 0, inSize);
    28. ShowMessage(inSize);
    29. uncompress(inBuf, &inSize, outBuf, outSize);
    30. Memo1->Lines->Add(UnicodeString(reinterpret_cast<const char*>(inBuf)));
    31. delete []inBuf;
    32. delete []outBuf;
    Распаковка:
    Код (Text):
    1. HANDLE hFile = CreateFileA("C:\\Users\\user\\Documents\\RAD Studio\\Projects\\packer\\Debug\\test.pck", GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    2. if (hFile == INVALID_HANDLE_VALUE)
    3. {
    4.     uLongf outSize;
    5.     uLongf inSize = GetFileSize(hFile, NULL) - sizeof(outSize);    
    6.     Bytef *inBuf = new Bytef[inSize];
    7.    
    8.     DWORD r;    
    9.     ReadFile(hFile, &outSize, sizeof(outSize), &r, NULL);
    10.     ReadFile(hFile, inBuf, inSize, &r, NULL);
    11.    
    12.     Bytef *outBuf = new Bytef[outSize];
    13.    
    14.     printf("uncompress: %d\n", uncompress(outBuf, &outSize, inBuf, inSize));
    15.     printf("Decompressed sz: %d\n",inSize);
    16.     getch();
    17.     printf("%s", inBuf);
    18.    
    19.     delete[] inBuf;
    20.     delete[] outBuf;
    21. }
    22. else
    23. {
    24.     printf("cannot open file");
    25. }
    26. getch();
     
  3. _nic

    _nic New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2007
    Сообщения:
    372
    Я был уставший, и просто при распаковке попутал память с результатом анпака :dntknw: Сори ,что затавил кого то вчитыватся в мой код.