Мультиплатформенная поддержка двоичных файлов данных с расширенным типом - PullRequest
0 голосов
/ 30 января 2020

В настоящее время у меня есть следующий код для поддержки расширенных 10-байтовых значений, сохраненных в двоичных файлах из Win32, и загрузки их на другие платформы. Однако для Android (то есть ARM, а не INTEL) мне нужен код для преобразования в 10-байтовый формат IEEE и из него в 10-байтовой памяти и тип "Extended" в компиляторе (который на самом деле 8 -byte Double).

TYPE
  TExtended     = TExtended80Rec;

{$IFDEF INTEL64 }
PROCEDURE ExtendedToIEEE(VAR D : Extended ; VAR E : TExtended); ASSEMBLER;
  ASM
                FLD     QWORD PTR [RCX]
                FSTP    TBYTE PTR [RDX]
                FWAIT
  END;

PROCEDURE IEEEToExtended(CONST E : TExtended ; VAR D : Extended); ASSEMBLER;
  ASM
                FLD     TBYTE PTR [RCX]
                FSTP    QWORD PTR [RDX]
                FWAIT
  END;
{$ELSE }
PROCEDURE ExtendedToIEEE(D : Extended ; VAR E : TExtended);
  BEGIN
    {$IF SizeOf(Extended)=SizeOf(TExtended) }
      MOVE(D,E,SizeOf(Extended))
    {$ELSE }
      !! MISSING !!
    {$ENDIF }
  END;

PROCEDURE IEEEToExtended(CONST E : TExtended ; VAR D : Extended);
  BEGIN
    {$IF SizeOf(Extended)=SizeOf(TExtended) }
      MOVE(E,D,SizeOf(Extended))
    {$ELSE }
      !! MISSING !!
    {$ENDIF }
  END;
{$ENDIF }

Если возможно, я также хотел бы иметь возможность конвертировать в / из 16-байтового типа "Extended" из MacOS / Linux (если только не 16-байтовый размер "просто" выравнивание, ie. 10 байт дополняются до 16).

1 Ответ

0 голосов
/ 03 февраля 2020

С помощью Дэвида, приведенного выше в комментариях, я придумал это и предоставил его здесь для дальнейшего использования:

TYPE
  TExtended     = TExtended80Rec;
  PExtended     = ^TExtended;

{$IF SizeOf(Extended)=SizeOf(TExtended) }
PROCEDURE ExtendedToIntel(VAR D : Extended ; VAR E : TExtended); INLINE;
  BEGIN
    D:=Extended(E)
  END;

PROCEDURE IntelToExtended(VAR E : TExtended ; VAR D : Extended); INLINE;
  BEGIN
    E:=TExtended(D)
  END;
{$ELSEIF DEFINED(WIN64) }
PROCEDURE ExtendedToIntel(VAR D : Extended {Double} ; VAR E : TExtended); ASSEMBLER;
  ASM
                FLD     QWORD PTR [RCX]
                FSTP    TBYTE PTR [RDX]
                FWAIT
  END;

PROCEDURE IntelToExtended(VAR E : TExtended ; VAR D : Extended {Double} ); ASSEMBLER;
  ASM
                FLD     TBYTE PTR [RCX]
                FSTP    QWORD PTR [RDX]
                FWAIT
  END;
{$ELSE }
PROCEDURE ExtendedToIntel(D : Extended ; VAR E : TExtended);
  BEGIN
    PExtended(@E)^:=TExtended(D)
  END;

PROCEDURE IntelToExtended(CONST E : TExtended ; VAR D : Extended);
  BEGIN
    D:=Double(PExtended(@E)^)
  END;
{$ENDIF }

TYPE
  TStreamHelper = CLASS HELPER FOR TStream
                    FUNCTION ReadExtended : Extended;
                    PROCEDURE WriteExtended(E : Extended);
                  END;

{$IF SizeOf(Extended)=SizeOf(TExtended) }
FUNCTION TStreamHelper.ReadExtended : Extended;
  BEGIN
    Read(Result,SizeOf(Extended))
  END;

PROCEDURE TStreamHelper.WriteExtended(E : Extended);
  BEGIN
    Write(E,SizeOf(Extended))
  END;
{$ELSE }
FUNCTION TStreamHelper.ReadExtended : Extended;
  VAR
    EX  : TExtended;

  BEGIN
    Read(EX,SizeOf(TExtended));
    IntelToExtended(EX,Result)
  END;

PROCEDURE TStreamHelper.WriteExtended(E : Extended);
  VAR
    EX  : TExtended;

  BEGIN
    ExtendedToIntel(E,EX);
    Write(EX,SizeOf(EX))
  END;
{$ENDIF }
...