Форум: "Основная";
Текущий архив: 2004.03.09;
Скачать: [xml.tar.bz2];
ВнизКонвертация данных на лету (TMemoryStream) Найти похожие ветки
← →
Cosinus (2004-02-26 13:11) [0]Добрый день. Заранее прошу прощения за такое длинное вступление, но это сделано исключительно с целью удобства читающих. У меня в COM port идут некоторые данные блоком в 1к(ДЕЙСТВИТЕЛЬНОЙ информации). Протокол таков, что в начале идет несколько байт служебной информации (размер постоянен), конец посылки - это несколько байт контрольной суммы(размер сесенно тоже постоянен) и некоторый символ(допустим $F0). Откуда следует, что в "теле" блока символа $F0 попадаться не должно(почему так, я думаю объяснять не надо) и если он все таки попадается, он заменяется на два следующих друг за дружкой определенных байта, откуда, опять же, следует, что размер принятого блока не будет равен 1к. Меня интересует вся НЕ служебная инфа и соответственно я должен просканировать полученный блок на предмет этих самых двух байт, дабы их заменить на лету на $F0 и отделения данных от служебной инфы.
Вот код, как я читаю
Log(clLime,"Reading memory..."); //функция ведения лога
Gauge1.MaxValue:=64;
Mem_Unsort:=TMemoryStream.Create;// создаем поток
GetMem(Buffer, $8a0); // если данных $400, то при наихудшем раскладе мы получим $800 плюс служ. информация
DatStr:=#$00+Addr+#$00+#$00; //формирование запроса
For k:=0 to 63 do //читаем 64к
begin
WriteToPort(DatStr,true); //пересылаем в порт запрос
If not RAnswer(1000) then //если не девайс не отвечает
begin
Log(clRed,"Error with errorcode [1] - timeout"); //ошибка
Gauge1.Progress:=0;
exit;
end;
Mem_Unsort.WriteBuffer(R_Buff,Block_size); //R_Buff-принятые данные (PChar)
Addr:=AddrChange(Addr); // меняем запрос
DatStr:=#$00+Addr+#$00+#$00;
Gauge1.AddProgress(1);
end;
Mem_Unsort.SaveToFile("ReadTest.bin");
FreeMem(Buffer);
Mem_Unsort.Free;
Gauge1.Progress:=0;
Возможно вопрос глупый, но я не знаю, как на лету сканировать и конвертировать данные. Заранее благодарен за любую помощь.
← →
Cosinus (2004-02-26 13:45) [1]Уважаемые мастера я прошу ЛЮБОЙ помощи, в том числе и ссылки на статьи и F1+что-либо. В F1+TMemoryStream я не нашел. Видимо плохо искал. Дело в том, что эта конвертация критична по времени и единственное, что мне пришло в голову - это Memory.Read, Memory.Seek Memory.Write , но по-моему это будет долго.
← →
Никто (2004-02-26 14:39) [2]В случае, если блок данных фиксированной величины, то не следует использовать признак конца блока, а просто считывать фиксированный объем данных. В таком варианте нет необходимости использовать подмену для определенных байтов.
← →
Cosinus (2004-02-26 14:47) [3]>> Никто (26.02.04 14:39) [2]
Этот протокол придумал не я и изменить я его никак не могу. :(
По сабжу не подскажите?
← →
TUser (2004-02-26 14:49) [4]Так для отделения данных от сл. инфы не надо ничего сканировать. Если размер служебных данных постоянен - читай именно столько сколько он занимает. И символ конца блока данных тут не помеха, хотя он, действительно, не нужен.
← →
Рамиль (2004-02-26 15:00) [5]Я вот только не понял
> Откуда следует, что в "теле" блока символа $F0 попадаться
> не должно(почему так, я думаю объяснять не надо) и если
> он все таки попадается, он заменяется на два следующих друг
> за дружкой определенных байта,
А если вдруг попадутся эти два байта?.. В таких случаях применяеется байтстаффинг, т. е. надо задваивать байт F0h, и если в потоке встретится непарный F0h, значит это управляющий символ.
← →
Erik (2004-02-26 15:00) [6]Есть такое понятие PIPE, посмотри CreatePipe и пр.. При чтении закачиваеш в pipe при закачке можеш посимвольно пробежать R_Buff и заменить, что тебе надо. Тоесть удобно читать с другого конца и непрерывный поток данных додерживается.
← →
Cosinus (2004-02-26 15:02) [7]TUser © (26.02.04 14:49) [4]
Как? Он не постоянен, я же описал, что если в блоке данных встречается хотя бы 1 $F0, то размер принятого блока увеличивается, а размер принятой информации нет.
← →
Cosinus (2004-02-26 15:04) [8]Рамиль © (26.02.04 15:00) [5]
Не попадутся, так написан протокол, а насчет протокола см.[2]
← →
TUser (2004-02-26 15:13) [9]Он непоятоянен, как я понимаю, только из-за наличия этого удвоения символа. Так убери просто этот символ и все - у тебя будут пакеты постоянного размера. См [2].
← →
Cosinus (2004-02-26 15:20) [10]>>TUser © (26.02.04 15:13) [9]
Как? Как я могу убрать этот символ? Мне в порт приходят данные, я их считаваю блоком в переменную PChar. Считываю ВСЕ данные которые пришли в порт. Так библиотека работы с СОМ портом написана. Лезть в нее я не хочу - не вижу пока в себе сил для этого:(. Отсюда и проблемма.
← →
KSergey (2004-02-26 15:31) [11]Не совсем понял откуда в Memory Stream возьмутся данные (видимо в RAnswer) - ну да не важно. Возможно что-то пропустил.
Я так понял, что в поток данные несколько раз пропихиваются (блоками), а потом все скопом пишутся в файл. Ага? (Извиняюсь, я просто не силен в потоках).
А что мешает перед помещением буфера в поток - перед этой вот строкой
> Mem_Unsort.WriteBuffer(R_Buff,Block_size); //R_Buff-принятые данные (PChar)
пробежаться по R_Buff, порезать там повторяющиеся байты (с одновременным смещением на их место последующего куска, разумеется) и, естественно, скорректировав Block_size? Или я что-то недопонял?
← →
Polevi (2004-02-26 15:33) [12]>Cosinus © (26.02.04 15:20) [10]
для тебя проюлема пробежать по одномерному массиву и копировать байт за байтом в другой массив ?
← →
Cosinus (2004-02-26 17:14) [13]>>Polevi © (26.02.04 15:33) [12]
Мда-а-а-а, спасибо. А вот самое простое то мне в голову и не пришло..... Без коментариев :))))
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.03.09;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.009 c