Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

64-бит паддинг


Страницы:   1 2

Glock ©   (2013-02-18 12:27:00) 

есть массив записей типа:

TYMLField = record
 Signature: Integer;
 Flag: Integer;
end;


нужно записать каждый элемент массива в объект типа TFileStream используя 64-padding. Это как?


Eraser   (2013-02-18 18:36:00) [1]


> Glock   (18.02.13 12:27) 

{$A8}

TYMLField = record
Signature: Integer;
Flag: Integer;
end;


http://docwiki.embarcadero.com/RADStudio/XE3/en/Align_fields_(Delphi)


Ega23   (2013-02-18 17:58:00) [2]

Я бы прям в рекорде метод сделал CheckAndLoad(Stream: TStream): Boolean;


Glock   (2013-02-18 17:41:00) [3]


> А версия delphi какая?


XE3


Ega23   (2013-02-18 17:37:00) [4]


> гляньте, как-то так?

А версия delphi какая?


Glock   (2013-02-18 17:34:00) [5]

сигнатуры блоков фиксированы


Glock   (2013-02-18 17:26:00) [6]

гляньте, как-то так?


type
 TYMLField = record
   Signature: Integer;
   Flag: Integer;
 end;

procedure YMLFieldArray.LoadFromStream(Stream: TStream);
var
 OldPos: Integer;
 YF: TYMLField;
 PaddingBuffer: array [0..7] of Byte;
begin
 Stream.Position := 0;
 while Stream.Position < Stream.Size do
 begin
   Stream.Read(YF, SizeOf(YF));
   if not CheckSignature(YF.Signature, Self.Signature) then
     raise Exception.CreateRes(@YML_FIELD_SIGNATURE_INVALID,
       [YF.Signature]);

  { if YF.Flag =  then
      что-то делаем }

   InternalRead(Stream);

   { ... }

   // читаем по 8 байт и смотрим совпадает ли сигнатура
   while Stream.Position < Stream.Size do
   begin
     OldPos := Stream.Position;
     Stream.Read(PaddingBuffer, SizeOf(PaddingBuffer));
     if CheckSignature(PaddingBuffer.Signature, Self.Signature) then
       Break;
   end;
   Stream.Position := OldPos;

   Add(YF);
 end;
end;


Ega23   (2013-02-18 17:06:00) [7]


> получается аналогично как с записью, только Write меняем
> на Read?
>

Нет, коль скоро у тебя всё выровнено, то читать по 8 байт. А дальше смотришь: если сигнатура совпадает, то твой клиент, заносишь в список. Если нет - читаешь следующие 8 байт.
Естественно, это справедливо, если сигнатуры блоков фиксированы.


Glock   (2013-02-18 16:54:00) [8]


var
Zero,P : int64;

P:=Stream.Position mod 8;
if (P<>0)
  Stream.Write(Zero,8-P); //<- что здесь


получается аналогично как с записью, только Write меняем на Read?


var
Zero,P : int64;

P:=Stream.Position mod 8;
if (P<>0)
  Stream.Read(Zero,8-P); //<- что здесь


icWasya   (2013-02-18 16:49:00) [9]

Естественно - как записали - так и читаете.


Glock   (2013-02-18 16:35:00) [10]

А вообще выравнивание только при записи делается или при чтении тоже?


icWasya   (2013-02-18 14:52:00) [11]

var
 Zero,P : int64;

 P:=Stream.Position mod 8;
 if (P<>0)
   Stream.Write(Zero,8-P); //<- что здесь


Ega23   (2013-02-18 14:51:00) [12]

Но если FileStream, то лучше сразу всё в памяти приготовить, а потом уже писать.


MBo   (2013-02-18 14:50:00) [13]

Stream.Position := (Stream.Position + 7) and $FFFFFFF8


Ega23   (2013-02-18 14:50:00) [14]


> Stream.Write(... //<- что здесь


var
 i, cnt: Integer;
 b: byte;
begin
 b := 0;
 cnt := Stream.Position mod 8;
 for i := 1 to cnt do
   Stream.WriteBuffer(b, 1);
end;


Glock   (2013-02-18 14:44:00) [15]

Спасибо, а как теперь дописать недостающие байты:

через метод Write стрима или как-то подругому

Stream.Write(... //<- что здесь


Ega23   (2013-02-18 14:41:00) [16]


> еще вызывается InternalWrite которая может записать количество
> байт не кратное 8.

Если InternalWrite пишет количество байт >= 8, то задача в общем виде не решаема.
Или я туплю?


Ega23   (2013-02-18 14:35:00) [17]


> не получается получить количество недостающих байт.

Stream.Position mod 8


Glock   (2013-02-18 14:22:00) [18]

не получается получить количество недостающих байт.


Glock   (2013-02-18 14:15:00) [19]

это в универе задали. задание кидали частями, поэтому сразу не увидел еще одно условие.

еще вызывается InternalWrite которая может записать количество байт не кратное 8.

for I := 0 to Length(YMLFieldArray) - 1 do
begin
 StreamWrite(YMLFieldArray[I], SizeOf(TYMLFieldArrayItem));
 L := InternalWrite(Stream, ...);
 // <- выполнить 8-байтовое выравнивание  
end;


Как правильно это делается?

Делим на 8, прибавляем недостающие байты и смещаем Stream.Position?


MBo   (2013-02-18 14:03:00) [20]

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


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо