Форум: "Начинающим";
Текущий архив: 2013.11.24;
Скачать: [xml.tar.bz2];
Вниз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;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.002 c