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

Вниз

64-бит паддинг   Найти похожие ветки 

 
Glock   (2013-02-18 12:27) [0]

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

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


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


 
MBo ©   (2013-02-18 13:36) [1]

Должно быть выравнивание  на границу 8 байт.
Только вот чего - всей записи или каждого поля?


 
Glock   (2013-02-18 13:43) [2]


> Должно быть выравнивание  на границу 8 байт.
> Только вот чего - всей записи или каждого поля?


всей записи

только я не понимаю нифига, SizeOf(TYMLField) = 8 байт. что тут еще выравнивать нужно.


 
Игорь Шевченко ©   (2013-02-18 13:54) [3]

Откуда дровишки ?


 
MBo ©   (2013-02-18 14:03) [4]

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


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

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

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

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


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

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


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

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


 
Ega23 ©   (2013-02-18 14:35) [7]


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

Stream.Position mod 8


 
Ega23 ©   (2013-02-18 14:41) [8]


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

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


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

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

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

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


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


> 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;


 
MBo ©   (2013-02-18 14:50) [11]

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


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

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


 
icWasya ©   (2013-02-18 14:52) [13]

var
 Zero,P : int64;

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


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

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


 
icWasya ©   (2013-02-18 16:49) [15]

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


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


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); //<- что здесь


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


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

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


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

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


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;



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

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


 
Ega23 ©   (2013-02-18 17:37) [20]


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

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


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


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


XE3


 
Ega23 ©   (2013-02-18 17:58) [22]

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


 
Eraser ©   (2013-02-18 18:36) [23]


> Glock   (18.02.13 12:27) 

{$A8}

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


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



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

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

Наверх




Память: 0.52 MB
Время: 0.007 c
2-1361087240
jonis_84
2013-02-17 11:47
2013.11.24
Кнопка вернуть


15-1370348553
"Добрый Сок"
2013-06-04 16:22
2013.11.24
Поскажите задачку, не соображу


2-1360930799
Camaro
2013-02-15 16:19
2013.11.24
Считывание данных со стрима


15-1370308346
brother
2013-06-04 05:12
2013.11.24
Что посмотреть подобного?


11-1249020271
MTsv DN
2009-07-31 10:04
2013.11.24
Работа с ассоциациями файлов