"Прозрачное" сжатие BLOB-полей. Как реализовать в

IBX, FIBPlus, UIB, ADO, .Net и прочее-прочее-прочее, в общем все, что относится к созданию приложений, работающих с InterBase, Firebird и Yaffil - клиент-серверных, трехзвенных, консольных и т.п.

Модератор: kdv

SAV
Сообщения: 54
Зарегистрирован: 19 авг 2006, 17:59

"Прозрачное" сжатие BLOB-полей. Как реализовать в

Сообщение SAV » 30 авг 2006, 21:12

есть статья "Работа с BLOB-полями в клиентских приложениях InterBase и Firebird на основе компонентов FIBPlus" на http://www.devrace.com/ru/fibplus/articles/2261.php ,там есть раздел "Уникальные возможности FIBPlus: Client BLOB-filters. "Прозрачное" сжатие BLOB-полей". Попытался повторить всё сделанное на С++Builder6,но возникли осложнения:
1) zStream,у меня нет в Builder,поэтому использовал ZLib,думаю что в этом нет ничего страшного.
2) Сделал как в статье,но то что в Delphi ReallocMem(Buffer, BufSize) в С++ это Buffer = realloc(Buffer,BufSize) - НЕ РАБОТАЕТ!!! - Access violation... как так?
Совсем запарился,может ошибка где,то в FIBPlus? Если нет то подсажите как разрешить,я уже начинаю подeмывать о техподдержке FIBPlus. Вот листинг процедуры:

Код: Выделить всё

void __fastcall PackBuffer(void *SourceBuf,int &SourceLen)
{
  try
  {
  unsigned long DestLen=SourceLen*1.1+12;
  Bytef * DstBuf=NULL;
  DstBuf =(Bytef *) realloc(DstBuf,DestLen);

if (compress2  (   DstBuf, &DestLen,
                          (Bytef *)SourceBuf,SourceLen,
                          9)
     !=_OK
   )return;
  // число (длина неупакованного буфера) преобразованное в строку
  AnsiString SrcLenStr = IntToStr(SourceLen);
  // количество символов строки
  int SybolsLen =SrcLenStr.Length();
  /* размер упакованног буфера c дописанным значением исходного значения*/
  SourceLen =DestLen+SybolsLen+1;
  SourceBuf = realloc(SourceBuf,SourceLen);/* Вот тут ACCESS VIOLATION и выходит!!!!*/
  SourceBuf =(Bytef*) memcpy(SourceBuf, DstBuf,DestLen);
  free(DstBuf);
  ((Bytef *)SourceBuf)[DestLen] = '#';// разделитель <блок данных>#<исходный размер>
  //дописываем длину
  int cntr=1;
  for (int i= SourceLen-1;i>DestLen;i--)
    ((Bytef *)SourceBuf)[i]=(Bytef)SrcLenStr[cntr++];

  }
  catch (Exception &E)
  {
   ShowMessage("PackBuffer error\n"+E.Message);
   Form1->pFIBTransaction1->Rollback();
  }
}

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 30 авг 2006, 21:26

Вообще-то в таких случаях подемывать о техподдержке надо как бы в первую очередь... А так - жди а) Ц-шника, б) работающего с FIBPlus в) с блобами д) жмущего их чем ни попадя... Имхо долго ждать придётся.

SAV
Сообщения: 54
Зарегистрирован: 19 авг 2006, 17:59

Сообщение SAV » 30 авг 2006, 22:10

Merlin писал(а):Вообще-то в таких случаях подемывать о техподдержке надо как бы в первую очередь... А так - жди а) Ц-шника, б) работающего с FIBPlus в) с блобами д) жмущего их чем ни попадя... Имхо долго ждать придётся.
В техподдеожку написал,пока тишина. А по поводу " жмущего их чем ни попадя..." это ты зря ZLib ооочень распространённая библиотека сжатия. Жаль что "Ц-шников" маловато на этом форуме :-(

hvlad
Разработчик Firebird
Сообщения: 1244
Зарегистрирован: 21 мар 2005, 10:48

Re: "Прозрачное" сжатие BLOB-полей. Как реализоват

Сообщение hvlad » 30 авг 2006, 23:42

SAV писал(а):есть статья "Работа с BLOB-полями в клиентских приложениях InterBase и Firebird на основе компонентов FIBPlus" на http://www.devrace.com/ru/fibplus/articles/2261.php ,там есть раздел "Уникальные возможности FIBPlus: Client BLOB-filters. "Прозрачное" сжатие BLOB-полей". Попытался повторить всё сделанное на С++Builder6,но возникли осложнения:
1) zStream,у меня нет в Builder,поэтому использовал ZLib,думаю что в этом нет ничего страшного.
2) Сделал как в статье,но то что в Delphi ReallocMem(Buffer, BufSize) в С++ это Buffer = realloc(Buffer,BufSize) - НЕ РАБОТАЕТ!!! - Access violation... как так?

Код: Выделить всё

void __fastcall PackBuffer(void *SourceBuf,int &SourceLen)
{
  try
  {
  unsigned long DestLen=SourceLen*1.1+12;
  Bytef * DstBuf=NULL;
  DstBuf =(Bytef *) realloc(DstBuf,DestLen);
Зачем realloc для пустого указателя ? Попробуй обычный alloc или new

SAV
Сообщения: 54
Зарегистрирован: 19 авг 2006, 17:59

Re: "Прозрачное" сжатие BLOB-полей. Как реализоват

Сообщение SAV » 31 авг 2006, 06:30

hvlad писал(а): Зачем realloc для пустого указателя ? Попробуй обычный alloc или new
В этом месте ошибок не возникает,к тому же даже в справке написано:

void *realloc(void *block, size_t size);
....................................................................
The block argument points to a memory block previously obtained by calling malloc, calloc, or realloc. If block is a NULL pointer, realloc works just like malloc.

"ACCESS VIOLATION" вываливается при попытке уменьшить количество выделенной памяти для SourceBuf,которое было выделено где-то в функции pFIBDataSet1->Post(), я объектный паскаль не очень то знаю,поэтому копание исходников пока не помогло :-(

SourceBuf = realloc(SourceBuf,SourceLen);/* Вот тут ACCESS VIOLATION и выходит!!!!*/

Ivan_Pisarevsky
Заслуженный разработчик
Сообщения: 644
Зарегистрирован: 15 фев 2005, 11:34

Сообщение Ivan_Pisarevsky » 31 авг 2006, 08:30

Я последний раз на С писал курсе на 4...

Фраза "уменьшаем размер буфера" слехка не нравица...

Коллега, вы в курсе, что не всякая последовательность байтов сживамется? после обработки этой библиотекой блоб может стать и больше первоначального.

Попробуй выделить память под новый указатель , а не уменьшать имеющийся.

Dimitry Sibiryakov
Заслуженный разработчик
Сообщения: 1436
Зарегистрирован: 15 сен 2005, 09:05

Сообщение Dimitry Sibiryakov » 31 авг 2006, 08:51

И вообще: если тебе дали указатель, это еще не значит что ты можешь делать с ним все что тебе вздумается. Может, это указатель на стековую переменную?.. А ты ее освобождать...

SAV
Сообщения: 54
Зарегистрирован: 19 авг 2006, 17:59

Сообщение SAV » 31 авг 2006, 09:47

Ivan_Pisarevsky писал(а):Я последний раз на С писал курсе на 4...
Коллега, вы в курсе, что не всякая последовательность байтов сживамется? после обработки этой библиотекой блоб может стать и больше первоначального.
По поводу сжимаемости согласен,в коде отсутствует проверка после
compress2 ( DstBuf, &DestLen,(Bytef *)SourceBuf,SourceLen, 9), можно это учесть вот так if(SourceLen<=DestLen)return;
Ivan_Pisarevsky писал(а): Попробуй выделить память под новый указатель , а не уменьшать имеющийся.
Это как? Если я сделаю новый указатель,он выделится в другом "месте" то функция вызвавшая этот фильтр ничего не получит измененный буфер,а будет ссылаться на "старый". Вобщем копаюсь пока. Значит никто в Builder не пытался сделать сжатие BLOB-полей,обидно,досадно :(

SAV
Сообщения: 54
Зарегистрирован: 19 авг 2006, 17:59

Re: "Прозрачное" сжатие BLOB-полей. Как реализоват

Сообщение SAV » 31 авг 2006, 12:44

От Support второй день уже ничего не слышно. Подскажтите где пожно почитаь доки или найти рабочий пример на тему Client BLOB-filters в С++Builder для FIBPlus6.45

Dimitry Sibiryakov
Заслуженный разработчик
Сообщения: 1436
Зарегистрирован: 15 сен 2005, 09:05

Сообщение Dimitry Sibiryakov » 31 авг 2006, 13:31

Весь саппорт на пути к Бали :lol: :lol:

hvlad
Разработчик Firebird
Сообщения: 1244
Зарегистрирован: 21 мар 2005, 10:48

Re: "Прозрачное" сжатие BLOB-полей. Как реализоват

Сообщение hvlad » 31 авг 2006, 14:30

SAV писал(а):"ACCESS VIOLATION" вываливается при попытке уменьшить количество выделенной памяти для SourceBuf,которое было выделено где-то в функции pFIBDataSet1->Post(), я объектный паскаль не очень то знаю,поэтому копание исходников пока не помогло :-(

SourceBuf = realloc(SourceBuf,SourceLen);/* Вот тут ACCESS VIOLATION и выходит!!!!*/
Нужно смотреть, чем выделяется SourceBuf - менеджер памяти должен быть один и тот же

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 31 авг 2006, 14:47

Весь саппорт на пути к Бали
ничего подобного. :) это менеджмент на пути к Бали. А вот саппорт должен работать.

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 31 авг 2006, 14:57

kdv писал(а):
Весь саппорт на пути к Бали
ничего подобного. :) это менеджмент на пути к Бали. А вот саппорт должен работать.
Кста, как там прошёл ужин? В тёплой дружеской обстановке, переходящей в пение народных песен и так далее? Фотоотчётик какой-нить будет?

SAV
Сообщения: 54
Зарегистрирован: 19 авг 2006, 17:59

Re: "Прозрачное" сжатие BLOB-полей. Как реализоват

Сообщение SAV » 31 авг 2006, 14:59

hvlad писал(а):Нужно смотреть, чем выделяется SourceBuf - менеджер памяти должен быть один и тот же
Вот и я про тоже! Исходники смотю... но не нашёл пока ... к тому же я не знаю аналога ReallocMem(Buffer, BufSize) в С++ кроме realloc.

Dimitry Sibiryakov
Заслуженный разработчик
Сообщения: 1436
Зарегистрирован: 15 сен 2005, 09:05

Сообщение Dimitry Sibiryakov » 31 авг 2006, 15:29

У меня такое впечатление что этот код вообще работать не может. Откуда ты его взял?

SAV
Сообщения: 54
Зарегистрирован: 19 авг 2006, 17:59

Сообщение SAV » 31 авг 2006, 16:32

Dimitry Sibiryakov писал(а):У меня такое впечатление что этот код вообще работать не может. Откуда ты его взял?
Я код сам пишу! И если неполучается то... А какой код по-твоему может работать? Есть рабочий экземпляр? Я до покупки FIBPlus сжимал данные ZLib`ом и закидывал их в BLOB, но подобный фильтр,по-моему,намного удобнее будет.

Dimitry Sibiryakov
Заслуженный разработчик
Сообщения: 1436
Зарегистрирован: 15 сен 2005, 09:05

Сообщение Dimitry Sibiryakov » 01 сен 2006, 09:23

Ага, я уже догадался прочитать статью по ссылке. У тебя функция неправильно объявлена. Ей должен передаваться указатель на указатель на буфер. Т.е. примерно так:

Код: Выделить всё

PackBuffer(void *&SourceBuf,int &SourceLen)
Тогда должно заработать.

SAV
Сообщения: 54
Зарегистрирован: 19 авг 2006, 17:59

Сообщение SAV » 01 сен 2006, 17:28

Dimitry Sibiryakov писал(а):Ага, я уже догадался прочитать статью по ссылке. У тебя функция неправильно объявлена. Ей должен передаваться указатель на указатель на буфер. Т.е. примерно так:

Код: Выделить всё

PackBuffer(void *&SourceBuf,int &SourceLen)
Тогда должно заработать.
Попробовал в более простом варианте:
void __fastcall PackBuffer(void *& SourceBuf,int &SourceLen)
{
try
{
free(SourceBuf); //Теперь вот так ругается:-( !!! BadParametr:a bad memory block 0x...... has been passed to the function.!!!!!
....
К чему приводить SourceBuf для функции free???

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 04 сен 2006, 10:50

Ну и зачем ты его освобождаешь? Буфер не освобождается, а возвращается назад.
Ты уже весь пример переврал...

SAV
Сообщения: 54
Зарегистрирован: 19 авг 2006, 17:59

Сообщение SAV » 04 сен 2006, 23:59

WildSery писал(а):Ну и зачем ты его освобождаешь? Буфер не освобождается, а возвращается назад.
Ты уже весь пример переврал...
... попробовал по разному и realloc пробовал :-(
Кто нибудь делал хоть какие нибудь Client BLOB-filters на C++, как вы меняли размер буфера???

p.s. Support из fibplus пока молчит, как быстро вообще они ответят?

Ответить