Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.10.02;
Скачать: CL | DM;

Вниз

Протокол обмена между клиентом и сервером   Найти похожие ветки 

 
Gek1   (2005-05-18 18:30) [0]

Имееться ClientSocket, работающий в неблокирующим режиме.
Протокол обмена устроен так, что пакеты уходящие от сервера сжимаются алгоритмом Хаффмана. Каждый пакет имеет разную длинну.

Как известно - по пути пакеты могут резаться и склеиватся. Но получается что расжатый Хаффманом кусок пакета даст совсем другие данные. Практически всегда эти первая часть данных будет не поврежденна, что даст мне понять что за пакет идет и я смогу дождатся пока прийдет его полная длинна.

Но иногда рассжатый кусочек пакета настолько искажается, что мой алгоритм дает збои.

Сам протокол обмена я поменять не могу. Он придуман не мною и очень давно. Сервер тоже написан не мною. Я написал всего лишь клиент для сервера.

Возникает вопрос:
Можно ли всетаки как-то узнать длинну целого пакета, который отправлял сервер?

Мастера, подскажите пожалуйста что можно сделать в данной ситуации?

P.S. если понадобится код - приведу.


 
Polevi ©   (2005-05-18 20:05) [1]

напиши промежуточный сервис-прокси, отправляй данне через него
к каждому приходящему пакету прилепляй размер и отправляй куда надо


 
Polevi ©   (2005-05-18 20:08) [2]

стоп, не внимательно прочел
если данные отправляет сервер, тогда сервис должен работать на стороне сервера и подключаться к серверу надо через него


 
Digitman ©   (2005-05-19 08:11) [3]


> Как известно - по пути пакеты могут резаться и склеиватся


тебя это заботить никак не должно

ТСР - протокол с гарантированной доставкой : поток данных, отправляемый передатчиком, гарантированно доставляется приемнику точно в той же последовательности, в какой он формируется на передающей стороне.


> работающий в неблокирующим режиме


есть подозрение, что у тебя ошибки в алгоритме клиента


 
Slym ©   (2005-05-19 10:38) [4]

Что ты имеешь ввиду под "пакеты уходящие от сервера"?
TCP пакеты или пакеты протокол обмена...
Сжимается каждый пакет отдельно, или весь поток?

Если сжимается поток то и приходящие пакеты должны распаковываться с учетом поточности...


 
Gek1   (2005-05-19 12:30) [5]


> тогда сервис должен работать на стороне сервера

К сожалению никаких вещей на сервере производить нельзя. Сервер - будем считать черным ящиком, который никому не доступен физически.


> ТСР - протокол с гарантированной доставкой : поток данных,
> отправляемый передатчиком, гарантированно доставляется приемнику
> точно в той же последовательности, в какой он формируется
> на передающей стороне.

Я не говорю что TCP - протокол неправильно работает. Я имел ввиду другое, что когда я принимаю куски пакетов, порезанные TCP - протоколом, и пытаюсь расжать - там выходит проблема.


> Сжимается каждый пакет отдельно, или весь поток?

Сжимается поток данных. Причем в поток данных может входить один пакет или же несколько пакетов.
Прозьба не путать пакет TCP протокола с "этим" пакетом.
Под пакетом от сервера я имею ввиду некий тип данных, который дает мне полную информацию о определенной ситуации.


> что у тебя ошибки в алгоритме клиента

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

Вот мой код:

procedure TCharacter.GameClientOnRead(Sender: TObject; Socket: TCustomWinSocket);
{Принимаем от Server-а некие данные}
var i,c,index : Integer;
   SHex : String;
   TempBuf : Parray;
   TempBufLen : Integer;
   MD5Out : PArray;
   PacketLen : Integer;
begin

{ fIncomingBuf : PArray;
 fIncomingBufLen : Integer; }

{Если fIncomingBufLen меньше нуля то выходим дисконектом}
if fIncomingBufLen < 0 then
   begin
   AddtoDebugLog(GetCharName+": "+"Error: IncomingBuf < 0");
   GameClient.Close;
   Exit;
   end;

{Принимаем данные в TempBuff и дописываем содержимое в IncomingBuff}
New(TempBuf);
TempBufLen:=Socket.ReceiveLength;
  try
  Socket.ReceiveBuf(TempBuf^,TempBufLen);
  SHex := "";
  for i := 0 to TempBufLen - 1 do SHex := SHex + IntToHex(TempBuf^[i],2);
  AddPacket2Debug(0,SHex);
  except
  AddToDebugLog(GetCharName+": "+"Error with receiving Some Data");
  end;
for i := 0 to (TempBufLen-1) do
  begin
  fIncomingBuf^[fIncomingBufLen+i] := TempBuf^[i];
  end;
fIncomingBufLen:=fIncomingBufLen+TempBufLen;
Dispose(TempBuf);
{Принятые данные добавлены в конец IncomingBuf}

{Если EncryptMetod 4, то есть еще MD5}
if fEncryptMetod = 4 then
begin
New(MD5Out);
MD5Encrypt(@MD5Obj,fIncomingBuf,MD5Out,fIncomingBufLen);
for i := 0 to fIncomingBufLen - 1 do fIncomingBuf^[i] := MD5Out^[i];
Dispose(MD5Out);
end;

{Расжимаем буфер}
PHuffDecompressLen := fIncomingBufLen * 4 + 4;
DecompressNew(fIncomingBuf,PHuffDecompress,PHuffDecompressLen,fIncomingBufLen);

{Если длинна PHuffDecompressLen равна нулю то выходим}
if PHuffDecompressLen <= 0 then Exit;

{Далее проверяем чтобы в буффере было N целых пакетов}
index:=0;
PacketLen := 1; {Любое положительное число}
while (index < PHuffDecompressLen) and (PacketLen > 0) do
begin
New(TempBuf);
for i := 0 to PHuffDecompressLen - (index + 1) do TempBuf^[i] := PHuffDecompress^[i+index];
TempBufLen := PHuffDecompressLen - index;
{Ф-ция GetPacketLen вернет:
0 если пакет маленький и надо еще кусок
-1 если пакет неизвестный
длинну, если длина >= пакету}
PacketLen := GetPacketLen(TempBuf,TempBufLen);
{Освободим TempBuf}
Dispose(TempBuf);
{Если длинна больше нуля, то увеличиваем индекс}
if PacketLen > 0 then index := index + PacketLen;
{Если длинна равна 0, то выходим}
if PacketLen = 0 then Exit;
{Если длинна меньше нуля, то:}
if PacketLen < 0 then
   begin
   {Выдаем ошибку о неизвестном пакете}
   SHex := "";
   for i := index to PHuffDecompressLen - 1 do SHex:= SHex + IntToHex(PHuffDecompress^[i],2);
   AddtoDebugLog(GetCharName+": "+"Внимание! Обнаружен неизвестный пакет: "+SHex);
   {Останавливаем соединение}
   GameClient.Close;
   {Выходим}
   Exit;
   end;
{Если длинна больше $8000, то:}
if PacketLen > $8000 then
   begin
   {Выдаем ошибку о неверной длинне пакета}
   SHex := "";
   for i := index to PHuffDecompressLen - 1 do SHex:= SHex + IntToHex(PHuffDecompress^[i],2);
   AddtoDebugLog(GetCharName+": "+"Внимание! Неверная длинна пакета: "+SHex);
   {Останавливаем соединение}
   GameClient.Close;
   {Выходим}
   Exit;
   end;
{Далее или у нас будет только N целых пакетов
или выйдем ранее из процедуры}
end; {End while (index < PHuffDecompressLen) and (PacketLen > 0)}

{Далее обработаем данные}
while (PHuffDecompressLen > 0) do
begin
PacketLen := GetPacketLen(PHuffDecompress,PHuffDecompressLen);
i := UnPackGamePackets(PHuffDecompress,PHuffDecompressLen);
if (i <> PacketLen) or (i = -1) then
   begin
   {Выдаем ошибку о неверной обработке пакета}
   SHex := "";
   for c := 0 to PHuffDecompressLen - 1 do SHex:= SHex + IntToHex(PHuffDecompress^[c],2);
   AddtoDebugLog(GetCharName+": "+"Внимание! Неверно обработали пакет: "+SHex);
   AddtoDebugLog(GetCharName+"i = "+IntToStr(i)+", PacketLen = "+IntToStr(PacketLen));
   {Останавливаем соединение}
   GameClient.Close;
   {Выходим}
   Exit;
   end;
{Занесем в Debug обработанный пакет}
SHex := "";
for c := 0 to PacketLen - 1 do SHex:= SHex + IntToHex(PHuffDecompress^[c],2);
AddPacket2Debug(1,SHex);
{Вырезаем занесенный пакет}
for i := 0 to PHuffDecompressLen - (PacketLen + 1) do
PHuffDecompress^[i] := PHuffDecompress^[i+PacketLen];
PHuffDecompressLen := PHuffDecompressLen - PacketLen;
end;

{После обработки N целых пакетов
необходимо сбросить накапливаемый буффер}
fIncomingBufLen := 0;
end;


 
Polevi ©   (2005-05-19 12:56) [6]

кошмар


 
Polevi ©   (2005-05-19 13:02) [7]

если я правильно понял:
сервер формирует пакет данных, длина пакета разная в зависимости от типа
пакет сжимается и отправляется клиенту

правильность декомпресии возможна только в том случае если на вход декомпрессора подается сжатый пакет целиком - не больше и не меньше, в противном случае данные будут не правильно распакованы

поскольку клиент не знает размера сжатого пакета посланного сервером - "подать на вход декомпрессора сжатый пакет целиком" он не в состоянии

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


 
Gek1   (2005-05-19 13:29) [8]


> сервер формирует пакет данных, длина пакета разная в зависимости
> от типа
> пакет сжимается и отправляется клиенту

Сервер формирует цепочку N целых пакетов данных (пакет может быть один, а может и быть несколько в цепочке)
Далее все это дело сервер сжимает и отправляет.


> правильность декомпресии возможна только в том случае если
> на вход декомпрессора подается сжатый пакет целиком - не
> больше и не меньше, в противном случае данные будут не правильно
> распакованы

абсолютно верно.


> поскольку клиент не знает размера сжатого пакета посланного
> сервером - "подать на вход декомпрессора сжатый пакет целиком"
> он не в состоянии

Вот если какието средства, чтобы узнать полную длинну сжатых данных, не трогая сервер?


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

Таймаут отпадает. Пакет может быть один.... маленьким ... и на его приход необходимо немедленно ответить.
Все таки есть какоето решение, но как это сделать - я не могу понять. Разработчики сервера сделали клиент давно и он рабочий. Узнать в чем изюминка этого алгоритма - невозможно. Вот у вас, Мастера, спрашиваю может у вас есть идеи как определить эту изюминку?


 
Digitman ©   (2005-05-19 13:33) [9]


> Socket.ReceiveBuf(TempBuf^,TempBufLen);


вот и первая же ошибка , грубая причем

ReceiveBuf - это функция !

и возвращает она число РЕАЛЬНО прочитанных указанный в буфер байт, которое вовсе НЕ обязано быть точно равно требуемому  значению в TempBufLen (т.е. результат ф-ции - число, меньшее или равное значению 2-го параметра)

а дальше смотреть твой код даже нет смысла..


 
Маркони   (2005-05-19 13:35) [10]

Итого опишу задачу:

Сервер посылает блок данных большой, разом, одним куском. Клиент при приеме почему то получает эти данные кусками, хотя сервер ничего не режет а посылает одним блоком. Для правильной обработки данных Клиентом ему надо получить весь блок данных, а потом обработать. Вопрос... каким образом можно определить сколько данных надо принять и надо ли их дальше принимать если сервер послал целый пакет а клиент принимает его кусками... Таким пакетов может быть много так что надо как то определить это всё куски одно и того же пакета или это новый пакет.


 
Gek1   (2005-05-19 13:40) [11]


> и возвращает она число РЕАЛЬНО прочитанных указанный в буфер
> байт, которое вовсе НЕ обязано быть точно равно требуемому
>  значению в TempBufLen (т.е. результат ф-ции - число, меньшее
> или равное значению 2-го параметра)

Проверка стояла и я ее убрал когда переделывал алгоритм в очередной раз ...
По наблюдениям скажу что были проблемы и раньше, когда стояла проверка и ниразу не выловил чтобы ReceiveBuf() <> ReceiveLength.

Спасибо, что подметил... щас доделаю... Но почему то я уверен почти на 100% что дело не в ней.


 
Polevi ©   (2005-05-19 13:48) [12]

дело не в данной ошибке
клиенту просто недостаточно данных для реализации
ты уверен что сжатые пакеты не предваряются каким либо заголовком, содержащим размер ?


 
Маркони   (2005-05-19 13:54) [13]

Я описал проблему так как есть +) Ты можешь вообще забыть про сжатие и тд итп представь что это один блок даных , чтоб его обработать надо получить его весь.


 
Gek1   (2005-05-19 14:00) [14]


> ты уверен что сжатые пакеты не предваряются каким либо заголовком,
> содержащим размер

В данные размер не встаивается...
Иначе бы расжатые данные с длинной давали бы мне неверный результат всегда ....

Маркони прав.

Хочу добавить, проблема возникает очень редко. И как я заметил именно тогда, когда перегружен сервер и плохой интернет. Тогда сам TCP начинает жудко дробить данные на мелкие кусочки и посылать по кусочкам.

Как я понял надо на клиенской стороне заставить его сначала все это склеить назад и только потом дать знать что пришел пакет данных.


 
Polevi ©   (2005-05-19 14:01) [15]

осталось найти признак по которому определить конец блока
я понял что такого признака у тебя нет


 
Маркони   (2005-05-19 14:04) [16]

А это невозможно вычеслить представь что приходит пакет содержаший только нули... но чтоб обработать его надо получить его вначале весь ...


 
Digitman ©   (2005-05-19 14:12) [17]

без знания тобой установленного прикл.протоколом признака размера сообщения в потоке "склеивать" что-либо бессмысленно

чтобы что-то "склеить", нужно знать полный исходный размер "неразбитого"


 
Gek1   (2005-05-19 14:15) [18]


> Digitman ©   (19.05.05 14:12) [17]

Ну режет же не Серверное приложение... режет же сам протокол TCP ... он же должен передавать полную длинну? Вот как можно ее узнать?


 
Polevi ©   (2005-05-19 14:22) [19]

никак


 
Digitman ©   (2005-05-19 14:28) [20]


> он же должен передавать полную длинну?


какую такую "длину" ?

у потока НЕТ длины ! на то он и поток ...

TCP - поточный протокол !


 
Gek1   (2005-05-19 14:42) [21]

Получается вариантов никаких...

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


 
Alexander Panov ©   (2005-05-19 14:45) [22]

Gek1   (19.05.05 14:42) [21]
Как понял единственный вариант - распаковывать кусок и молится, чтобы первые пару байтиков небыли испорченны.


Это вообще не вариант. Вернее, неправильный вариант.

Длину упакованного блока данных тебе нужно передавать в неупакованном виде.
Получив блок соответствующей длины, распаковываешь его. И всё.


 
Polevi ©   (2005-05-19 14:49) [23]

>Alexander Panov ©   (19.05.05 14:45) [22]
сервер не его
попал человек


 
Digitman ©   (2005-05-19 14:49) [24]


> распаковывать кусок


какой кусок ?


 
Gek1   (2005-05-19 14:55) [25]


> Digitman ©   (19.05.05 14:49) [24]

Сжатый порезаный кусок распаковываю и молусь, чтобы первые байт небыли испорченны. Бо по первому байту я определяю ID пакета, а если его длинна динамическая, то второй и третий байт - длинна. Но это все работает, когда данные не коверкаются при распаковке.


 
Маркони   (2005-05-19 14:55) [26]

пакт порвался предпложим на два куска да так удачно что ... первые два пакета в запаковом виде в первой части а вторые во второй... получили кусок первый... распокавали весь из заголовка пакетов (а это первый байт пакета) получаем ага длинна 7 байт а унас там их 9 распаковалось смотрим по начало + 7 ага длинна пакета должна быть 2 байта ... то бишь нам теперь кажется... что мол мы приняли всё одним таким куском и следующий кусок будем уже воспринимать не как часть предудущего а как новый в резульатте распаковки получим мусор....  так как lzk получения правильной информация надо соединитье го было с предыдущем и распаковать весь.... вот такая хрень


 
Digitman ©   (2005-05-19 15:09) [27]


> Gek1   (19.05.05 14:55) [25]
>
> > Digitman ©   (19.05.05 14:49) [24]
>
> Сжатый порезаный кусок распаковываю


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

тебе же Alexander Panov ©   (19.05.05 14:45) [22] правильно говорит - прикладной протокол должен предусматривать передачу инф-ции о размере сжатых данных в несжатом виде, например, в 4-х байтах предшествующих "упаковке" ... зная это ты принимаешь сначала (хоть одним куском хоть четырьмя) эти самые 4 байта, берешь из них размер "упаковки" и далее ожидаешь/считываешь "куски" собственно "упаковки", "склеивая" их друг за другом в порядке поступления, до тех пор пока полный размер склеенных тобой "кусков" не будет точно равен тому значению, что ты получил из ранее принятых тех самых 4-х байт ... вот только ПОСЛЕ этого ты можешь смело передать склеенную тобой "упаковку" на дальнейшую обработку, как то "разжатие", "декодирование" и т.д. и т.п.

иными словами, протокол, реализованный сервером, ты не знаешь, тыкаешься как слепой, а алгоритм твой не будет работать как положено до тех пор пока ты не будешь знать ОТ и ДО этот протокол


 
Sha ©   (2005-05-19 15:13) [28]

Еще возможен такой вариант: сервер вставляет в поток данных спецсимволы сброса, которые сбрасывают алгоритм компрессии/декомпрессии в исходное состояние.
Это своеобразный признак конца/начала пакета.
В общем, имеет смысл детально разобраться с алгоритмом сжатия.

Кроме того, осталось невыясненным: клиент, написанный разработчиками, работает как надо?


 
Gek1   (2005-05-19 15:45) [29]


> Digitman ©   (19.05.05 15:09) [27]

Проверял и пытался определить возможную длинну сжатом пакете.
Ни вначале ни в конце признаков не заметил.
Если все же судить, что в сжатом пакете должна присутствовать гдето длинна - тогда кто мне обьяснит как распакованный пакет с длинной вместе дает мне практически всегда правильные данные?


> Еще возможен такой вариант: сервер вставляет в поток данных
> спецсимволы сброса, которые сбрасывают алгоритм компрессии/декомпрессии
> в исходное состояние.
> Это своеобразный признак конца/начала пакета.
> В общем, имеет смысл детально разобраться с алгоритмом сжатия.

С дерева таблицы хаффмана данные только читаются. Не записываются. Да и вообще дерево - константа.


> Кроме того, осталось невыясненным: клиент, написанный разработчиками,
> работает как надо?

В том то и дело, что клиент, написанный разработчиками работает отлично.

Сам протокол закрыт и его алгоритм был разгадан кодерами. Сами кодеры похоже тоже сталкивались с такой проблемой. Проблема ясна (выше описана), но алгоритм как ее обойти неизвестен. Я считаю что все же есть гдето какаято изюминка. Может особенность хаффмана или еще чего либо.
Определить так мне и не удалось, поэтому спрашиваю у вас. Может у вас будет решение этой проблеммы.


 
Sha ©   (2005-05-19 15:53) [30]

> Сам протокол закрыт и его алгоритм был разгадан кодерами.
> Сами кодеры похоже тоже сталкивались с такой проблемой.

Тут противоречие.


 
Gek1   (2005-05-19 16:16) [31]


> Sha ©   (19.05.05 15:53) [30]

Имеется виду что разгадали почти все:
Устройство пакетов, как криптуються .. различия криптации в разных версиях клиента. И тд и тп.


 
Digitman ©   (2005-05-19 16:20) [32]


> Проверял и пытался определить возможную длинну сжатом пакете


при fEncryptMetod = 4 до разжатия у тебя и дело может не дойти

пытаясь декодировать произвольный шматок принятых данных, ты нарушаешь принципы, заложенные в http://www.faqs.org/rfcs/rfc1321.html


 
Gek1   (2005-05-19 16:24) [33]


> при fEncryptMetod = 4 до разжатия у тебя и дело может не
> дойти

Это для других сервером. В моем случае я тестирую на сервере, где fEncryptMetod = 2. Поэтому это кусок все время пропускается.


 
Digitman ©   (2005-05-19 16:28) [34]

для работы MD5 требуется как минимум условие кратности четырем значения fIncomingBufLen

где ты это условие выполняешь ? нигде.


 
Digitman ©   (2005-05-19 16:30) [35]


> я тестирую на сервере, где fEncryptMetod = 2. Поэтому это
> кусок все время пропускается


угу .. а когда будешь  работать с MD5, то грабли тебе обеспечены при таком алгоритме


 
Gek1   (2005-05-19 17:21) [36]

Про MD5 спасибо, что подметил.

Но к сожалению у меня не выходит другое и все силы направленны на решение этой проблемы.


 
Digitman ©   (2005-05-19 17:31) [37]

что за процедура DecompressNew() ?

код можешь привести ?


 
Gek1   (2005-05-19 17:36) [38]


Procedure DecompressNew(pInData, pOutData : Pointer; var iOut : Integer; iLen : Integer );
var mask : Word;
   bitnum : Byte;
   treepos : SHORT;
   despos, value : Integer;
   pIn : Word;
   pInArray, pOutArray : PArray;
const
tree : array [0..511] of Word =
(
       $0001, $0002, $0003, $0004, $0005, $0000, $0006, $0007,
       $0008, $0009, $000A, $000B, $000C, $000D, $FF00, $000E,
       $000F, $0010, $0011, $0012, $0013, $0014, $0015, $0016,
       $FFFF, $0017, $0018, $0019, $001A, $001B, $001C, $001D,
       $001E, $001F, $0020, $0021, $0022, $0023, $0024, $0025,
       $0026, $0027, $0028, $FFC0, $0029, $002A, $002B, $002C,
       $FFFA, $002D, $002E, $002F, $0030, $0031, $0032, $0033,
       $FF89, $0034, $FFE0, $0035, $0036, $FFF2, $0037, $FFFB,
       $0038, $0039, $003A, $003B, $003C, $FFFE, $003D, $003E,
       $003F, $0040, $0041, $0042, $0043, $0044, $0045, $0046,
       $0047, $0048, $FFCD, $0049, $004A, $004B, $004C, $004D,
       $FF9B, $FF91, $FFFC, $FF9F, $004E, $004F, $FF92, $0050,
       $0051, $FF8C, $0052, $0053, $0054, $FF01, $0055, $0056,
       $0057, $0058, $0059, $005A, $FFF1, $FFF6, $005B, $005C,
       $FFEB, $005D, $FF8B, $005E, $005F, $0060, $0061, $0062,
       $0063, $0064, $FF8E, $0065, $FF97, $0066, $FFE6, $0067,
       $0068, $0069, $006A, $006B, $006C, $006D, $006E, $006F,
       $0070, $FFFD, $0071, $FFF9, $0072, $FF7D, $0073, $FF70,
       $0074, $0075, $FFEC, $0076, $0077, $0078, $0079, $007A,
       $007B, $007C, $007D, $007E, $007F, $0080, $0081, $FF9C,
       $0082, $FFF8, $0083, $0084, $0085, $0086, $FF88, $0087,
       $0088, $FFE1, $0089, $008A, $FF93, $FF16, $008B, $008C,
       $008D, $008E, $008F, $0090, $FF90, $0091, $FFED, $0092,
       $0093, $0094, $0095, $FFBE, $0096, $FF6F, $FFF3, $FFBF,
       $0097, $0098, $0099, $009A, $FFE2, $009B, $009C, $009D,
       $FF9D, $009E, $009F, $00A0, $00A1, $00A2, $FFE9, $00A3,
       $FFE3, $00A4, $FFF5, $00A5, $00A6, $FF8D, $00A7, $00A8,
       $00A9, $00AA, $FFF0, $00AB, $FFDE, $00AC, $00AD, $FF7C,
       $00AE, $FF94, $00AF, $FFEA, $00B0, $FFF7, $00B1, $FFAC,
       $FFEF, $FFDB, $FFE4, $00B2, $00B3, $00B4, $00B5, $00B6,
       $00B7, $00B8, $00B9, $00BA, $00BB, $FF98, $00BC, $FFB2,
       $00BD, $FFC3, $FFB1, $FF4E, $FFC5, $FF7A, $00BE, $FFE7,
       $FFAD, $FFEE, $00BF, $FFC7, $FFBD, $00C0, $FF9E, $00C1,
       $FFF4, $FFBC, $00C2, $00C3, $FFC9, $FF80, $FFE8, $FFCE,
       $FFBA, $00C4, $FFA2, $FFDF, $00C5, $FF7F, $FFB6, $00C6,
       $FFAE, $00C7, $FFC8, $FFA9, $FFD4, $00C8, $FF08, $00C9,
       $FF5D, $FFAF, $FFCC, $FF85, $00CA, $FF8F, $FFD0, $FFD7,
       $FF86, $FFD8, $00CB, $FFA6, $FFCA, $00CC, $FFAA, $FF40,
       $00CD, $00CE, $00CF, $FF7E, $FFCB, $00D0, $FF7B, $FFD3,
       $00D1, $00D2, $00D3, $FFA5, $00D4, $00D5, $FF96, $FFA8,
       $00D6, $00D7, $00D8, $00D9, $00DA, $FFCF, $00DB, $00DC,
       $00DD, $00DE, $00DF, $00E0, $00E1, $00E2, $00E3, $FF9A,
       $FF60, $00E4, $FFD2, $00E5, $FF81, $00E6, $FF99, $00E7,
       $00E8, $00E9, $FFC4, $00EA, $00EB, $FFB4, $00EC, $FF87,
       $00ED, $FFB7, $FF6B, $00EE, $00EF, $FF95, $FFDD, $00F0,
       $FFB9, $FFE5, $FFBB, $00F1, $FFA7, $FFB3, $FFC2, $FF8A,
       $FFB5, $FFAB, $FFB8, $FFC6, $FFC1, $FFB0, $00F2, $FFD6,
       $FF6A, $FF63, $FF75, $FF14, $FF82, $FF0D, $FF72, $FF2A,
       $FF76, $FF32, $FF10, $FF6E, $FF34, $FF6D, $FF68, $FF37,
       $FF1D, $FF31, $FF66, $FF2F, $FF67, $FF02, $FF50, $FF64,
       $FF5B, $FF2E, $FF54, $FF47, $FF3D, $FF56, $FF18, $FF2D,
       $FF25, $FF11, $FF38, $FF4F, $FF51, $FF2C, $FF0C, $FF71,
       $FF0A, $FF55, $FF35, $FF23, $FF36, $FF4B, $FF53, $FF06,
       $FF48, $FF5C, $FF3F, $FF26, $FF39, $FF24, $FF42, $FF07,
       $FF1A, $FF27, $FF57, $FF28, $FF41, $FF3B, $FFD1, $00F3,
       $00F4, $00F5, $00F6, $00F7, $FF6C, $FF61, $00F8, $00F9,
       $FFA4, $FFA3, $FFA0, $FF1F, $FF69, $FFA1, $00FA, $00FB,
       $FF0F, $00FC, $FF5F, $FFDC, $00FD, $00FE, $FF79, $FFD9,
       $FF45, $FF84, $00FF, $FF05, $FF5E, $FF12, $FF0E, $FFDA,
       $FFD5, $FF83, $FF29, $FF03, $FF74, $FF30, $FF77, $FF15,
       $FF62, $FF13, $FF78, $FF33, $FF65, $FF73, $FF1C, $FF1B,
       $FF2B, $FF58, $FF20, $FF3E, $FF3C, $FF1E, $FF49, $FF17,
       $FF19, $FF59, $FF52, $FF43, $FF04, $FF5A, $FF3A, $FF22,
       $FF44, $FF4D, $FF21, $FF4A, $FF4C, $FF46, $FF0B, $FF09
);

begin
bitnum := 8;
treepos := 0;
despos := 0;
pIn := 0;
pInArray := pInData;
pOutArray := pOutData;
value := 0;
mask := 0;
while true do
begin

if (bitnum = 8) then
begin
if (iLen = 0) then
   begin
   iOut := despos;
   Exit;
   end;
iLen := iLen - 1;
value := Byte(pInArray^[pIn]);
pIn := pIn + 1;
bitnum := 0;
mask := $80;
end;

if (value and mask) = mask then treepos := tree[treepos*2]
else treepos := tree[treepos*2+1];

mask := mask SHR 1;
bitnum := bitnum + 1;

if (treepos <= 0) then
begin
if (treepos = -256) then
   begin
   bitnum := 8;
   treepos := 0;
   continue;
   end;
if (despos = iOut) then Exit;
pOutArray^[despos] := -treepos;
despos := despos + 1;
treepos := 0;
end;

end;
end;


 
Digitman ©   (2005-05-19 17:51) [39]

где и как инициализируется значение PHuffDecompress, передаваемое тобой параметром pOutData ?


 
Gek1   (2005-05-19 18:07) [40]

pOutArray := pOutData;

Далее в коде уже:
pOutArray^[despos] := -treepos;



Страницы: 1 2 3 вся ветка

Текущий архив: 2005.10.02;
Скачать: CL | DM;

Наверх




Память: 0.61 MB
Время: 0.052 c
4-1116443316
Nik_vr
2005-05-18 23:08
2005.10.02
Как проверит, открыт ли лоток CD-ROM?


14-1126512028
deep
2005-09-12 12:00
2005.10.02
Лучшие блоги


1-1126025257
ДимДимыч
2005-09-06 20:47
2005.10.02
Аналог TActionList с дополнениями


14-1125398630
boriskb
2005-08-30 14:43
2005.10.02
Кто говорит, что МЫ предвзято относимся к США?


2-1124455979
user51
2005-08-19 16:52
2005.10.02
нет точки входа