You've already forked lazarus-ccr
- Field may be hidden by calling SetFieldSerializationVisibility() - Field may be mapped to XML Attribute by calling RegisterAttributeProperty() Some methods and routines have been marked "inline". By default the "inline" modifier is not enable. To enable it uncomment the "//{$DEFINE USE_INLINE}" line in wst_global.inc. git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@244 8e941d3f-bd1b-0410-a28a-d453659cc2b4
520 lines
13 KiB
ObjectPascal
520 lines
13 KiB
ObjectPascal
{
|
|
This file is part of the Web Service Toolkit
|
|
Copyright (c) 2006 by Inoussa OUEDRAOGO
|
|
|
|
This file is provide under modified LGPL licence
|
|
( the files COPYING.modifiedLGPL and COPYING.LGPL).
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
}
|
|
{$INCLUDE wst_global.inc}
|
|
{$RANGECHECKS OFF}
|
|
unit binary_streamer;
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, Types, wst_types;
|
|
|
|
Const
|
|
MAX_ARRAY_LENGTH = 1024*1024;
|
|
|
|
Type
|
|
|
|
TInt8U = Byte; TInt8S = ShortInt;
|
|
TInt16U = Word; TInt16S = SmallInt;
|
|
TInt32U = LongWord; TInt32S = LongInt;
|
|
TInt64S = Int64; TInt64U = QWord;
|
|
TBoolData = Boolean;
|
|
TEnumData = Int64;
|
|
TStringData = AnsiString;
|
|
|
|
TFloat_Single_4 = Single;
|
|
TFloat_Double_8 = Double;
|
|
TFloat_Extended_10 = Extended;
|
|
TFloat_Currency_8 = Currency;
|
|
|
|
IDataStore = Interface
|
|
['{CA767A0E-7660-4765-9959-6960A69B1660}']
|
|
procedure WriteInt8U(Const AData : TInt8U);
|
|
procedure WriteInt8S(Const AData : TInt8S);
|
|
|
|
procedure WriteInt16U(Const AData : TInt16U);
|
|
procedure WriteInt16S(Const AData : TInt16S);
|
|
|
|
procedure WriteInt32U(Const AData : TInt32U);
|
|
procedure WriteInt32S(Const AData : TInt32S);
|
|
|
|
procedure WriteInt64U(Const AData : TInt64U);
|
|
procedure WriteInt64S(Const AData : TInt64S);
|
|
|
|
procedure WriteBool(Const AData : TBoolData);
|
|
procedure WriteEnum(Const AData : TEnumData);
|
|
procedure WriteStr(Const AData : TStringData);
|
|
|
|
procedure WriteSingle(Const AData : TFloat_Single_4);
|
|
procedure WriteDouble(Const AData : TFloat_Double_8);
|
|
procedure WriteExtended(Const AData : TFloat_Extended_10);
|
|
procedure WriteCurrency(Const AData : TFloat_Currency_8);
|
|
End;
|
|
|
|
IDataStoreReader = Interface
|
|
['{AF50317E-6DD6-40C5-A2F6-3ED5F478564F}']
|
|
function IsAtEof():Boolean;
|
|
function ReadInt8U():TInt8U;
|
|
function ReadInt8S():TInt8S;
|
|
|
|
function ReadInt16U():TInt16U;
|
|
function ReadInt16S():TInt16S;
|
|
|
|
function ReadInt32U():TInt32U;
|
|
function ReadInt32S():TInt32S;
|
|
|
|
function ReadInt64U():TInt64U;
|
|
function ReadInt64S():TInt64S;
|
|
|
|
function ReadBool():TBoolData;
|
|
function ReadEnum():TEnumData;
|
|
function ReadStr():TStringData;
|
|
|
|
function ReadSingle():TFloat_Single_4;
|
|
function ReadDouble():TFloat_Double_8;
|
|
function ReadExtended():TFloat_Extended_10;
|
|
function ReadCurrency():TFloat_Currency_8;
|
|
End;
|
|
|
|
function CreateBinaryReader(AStream : TStream):IDataStoreReader;{$IFDEF USE_INLINE}inline;{$ENDIF}
|
|
function CreateBinaryWriter(AStream : TStream):IDataStore;{$IFDEF USE_INLINE}inline;{$ENDIF}
|
|
|
|
procedure ReverseBytes(var AData; const ALength : Integer);{$IFDEF USE_INLINE}{$IFDEF ENDIAN_BIG}inline;{$ENDIF}{$ENDIF}
|
|
function Reverse_16(const AValue:Word):Word;{$IFDEF USE_INLINE}inline;{$ENDIF}
|
|
function Reverse_32(const AValue:DWord):DWord;{$IFDEF USE_INLINE}inline;{$ENDIF}
|
|
function Reverse_64(const AValue:QWord):QWord;{$IFDEF USE_INLINE}inline;{$ENDIF}
|
|
|
|
function Reverse_Single(const AValue:Single):Single;{$IFDEF USE_INLINE}inline;{$ENDIF}
|
|
function Reverse_Double(const AValue:Double):Double;{$IFDEF USE_INLINE}inline;{$ENDIF}
|
|
function Reverse_Extended(const AValue:Extended):Extended;{$IFDEF USE_INLINE}inline;{$ENDIF}
|
|
function Reverse_Currency(const AValue:Currency):Currency;{$IFDEF USE_INLINE}inline;{$ENDIF}
|
|
|
|
implementation
|
|
|
|
{$IFDEF ENDIAN_BIG}
|
|
procedure ReverseBytes(var AData; const ALength : Integer); {$IFDEF USE_INLINE}inline;{$ENDIF}
|
|
begin
|
|
end;
|
|
{$ELSE} // assume ENDIAN_LITTLE
|
|
procedure ReverseBytes(var AData; const ALength : Integer);
|
|
Var
|
|
i,j : PtrInt;
|
|
c : Byte;
|
|
pDt : {$IFDEF FPC}^Byte{$ELSE}PByteArray{$ENDIF};
|
|
begin
|
|
pDt := @AData;
|
|
j := ALength div 2;
|
|
For i := 0 To Pred(j) Do Begin
|
|
c := pDt{$IFNDEF FPC}^{$ENDIF}[i];
|
|
pDt[i] := pDt[(ALength - 1 ) - i];
|
|
pDt[(ALength - 1 ) - i] := c;
|
|
End;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
function Reverse_16(const AValue:Word):Word;{$IFDEF USE_INLINE}inline;{$ENDIF}
|
|
begin
|
|
Result := AValue;
|
|
ReverseBytes(Result,2)
|
|
end;
|
|
|
|
function Reverse_32(const AValue:DWord):DWord;{$IFDEF USE_INLINE}inline;{$ENDIF}
|
|
begin
|
|
Result := AValue;
|
|
ReverseBytes(Result,4)
|
|
end;
|
|
|
|
function Reverse_64(const AValue:QWord):QWord;{$IFDEF USE_INLINE}inline;{$ENDIF}
|
|
begin
|
|
Result := AValue;
|
|
ReverseBytes(Result,8)
|
|
end;
|
|
|
|
function Reverse_Single(const AValue:Single):Single;{$IFDEF USE_INLINE}inline;{$ENDIF}
|
|
begin
|
|
Result := AValue;
|
|
ReverseBytes(Result,4)
|
|
end;
|
|
|
|
function Reverse_Double(const AValue:Double):Double;{$IFDEF USE_INLINE}inline;{$ENDIF}
|
|
begin
|
|
Result := AValue;
|
|
ReverseBytes(Result,8)
|
|
end;
|
|
|
|
function Reverse_Extended(const AValue:Extended):Extended;{$IFDEF USE_INLINE}inline;{$ENDIF}
|
|
begin
|
|
Result := AValue;
|
|
ReverseBytes(Result,10);
|
|
end;
|
|
|
|
function Reverse_Currency(const AValue:Currency):Currency;{$IFDEF USE_INLINE}inline;{$ENDIF}
|
|
begin
|
|
Result := AValue;
|
|
ReverseBytes(Result,8);
|
|
end;
|
|
|
|
Type
|
|
{ TDataStore }
|
|
|
|
TDataStore = class(TInterfacedObject,IDataStore)
|
|
Private
|
|
FStream : TStream;
|
|
Protected
|
|
procedure WriteInt8U(Const AData : TInt8U);
|
|
procedure WriteInt8S(Const AData : TInt8S);
|
|
|
|
procedure WriteInt16U(Const AData : TInt16U);
|
|
procedure WriteInt16S(Const AData : TInt16S);
|
|
|
|
procedure WriteInt32U(Const AData : TInt32U);
|
|
procedure WriteInt32S(Const AData : TInt32S);
|
|
|
|
procedure WriteInt64U(Const AData : TInt64U);
|
|
procedure WriteInt64S(Const AData : TInt64S);
|
|
|
|
procedure WriteBool(Const AData : TBoolData);
|
|
procedure WriteEnum(Const AData : TEnumData);
|
|
procedure WriteStr(Const AData : TStringData);
|
|
|
|
procedure WriteSingle(Const AData : TFloat_Single_4);
|
|
procedure WriteDouble(Const AData : TFloat_Double_8);
|
|
procedure WriteExtended(Const AData : TFloat_Extended_10);
|
|
procedure WriteCurrency(Const AData : TFloat_Currency_8);
|
|
Public
|
|
constructor Create(AStream : TStream);
|
|
End;
|
|
|
|
{ TDataStoreReader }
|
|
|
|
TDataStoreReader = class(TInterfacedObject,IDataStoreReader)
|
|
Private
|
|
FStream : TStream;
|
|
Protected
|
|
function IsAtEof():Boolean;
|
|
function ReadInt8U():TInt8U;
|
|
function ReadInt8S():TInt8S;
|
|
|
|
function ReadInt16U():TInt16U;
|
|
function ReadInt16S():TInt16S;
|
|
|
|
function ReadInt32U():TInt32U;
|
|
function ReadInt32S():TInt32S;
|
|
|
|
function ReadInt64U():TInt64U;
|
|
function ReadInt64S():TInt64S;
|
|
|
|
function ReadBool():TBoolData;
|
|
function ReadEnum():TEnumData;
|
|
function ReadStr():TStringData;
|
|
|
|
function ReadSingle():TFloat_Single_4;
|
|
function ReadDouble():TFloat_Double_8;
|
|
function ReadExtended():TFloat_Extended_10;
|
|
function ReadCurrency():TFloat_Currency_8;
|
|
Public
|
|
constructor Create(AStream : TStream);
|
|
End;
|
|
|
|
function CreateBinaryWriter(AStream : TStream):IDataStore;
|
|
begin
|
|
Result := TDataStore.Create(AStream) As IDataStore;
|
|
end;
|
|
|
|
function CreateBinaryReader(AStream : TStream):IDataStoreReader;
|
|
begin
|
|
Result := TDataStoreReader.Create(AStream) As IDataStoreReader;
|
|
end;
|
|
|
|
{ TDataStore }
|
|
|
|
procedure TDataStore.WriteInt8U(const AData: TInt8U);
|
|
begin
|
|
FStream.Write(AData,SizeOf(AData));
|
|
end;
|
|
|
|
procedure TDataStore.WriteInt8S(const AData: TInt8S);
|
|
begin
|
|
FStream.Write(AData,SizeOf(AData));
|
|
end;
|
|
|
|
{$IFDEF FPC}
|
|
procedure TDataStore.WriteInt16U(const AData: TInt16U);
|
|
begin
|
|
FStream.Write(Reverse_16(AData),SizeOf(AData));
|
|
end;
|
|
|
|
procedure TDataStore.WriteInt16S(const AData: TInt16S);
|
|
begin
|
|
FStream.Write(Reverse_16(AData),SizeOf(AData));
|
|
end;
|
|
|
|
procedure TDataStore.WriteInt32U(const AData: TInt32U);
|
|
begin
|
|
FStream.Write(Reverse_32(AData),SizeOf(AData));
|
|
end;
|
|
|
|
procedure TDataStore.WriteInt32S(const AData: TInt32S);
|
|
begin
|
|
FStream.Write(Reverse_32(AData),SizeOf(AData));
|
|
end;
|
|
|
|
procedure TDataStore.WriteInt64U(const AData: TInt64U);
|
|
begin
|
|
FStream.Write(Reverse_64(AData),SizeOf(AData));
|
|
end;
|
|
|
|
procedure TDataStore.WriteInt64S(const AData: TInt64S);
|
|
begin
|
|
FStream.Write(Reverse_64(AData),SizeOf(AData));
|
|
end;
|
|
{$ELSE}
|
|
procedure TDataStore.WriteInt16U(const AData: TInt16U);
|
|
var
|
|
bffr : TInt16U;
|
|
begin
|
|
bffr := Reverse_16(AData);
|
|
FStream.Write(bffr,SizeOf(AData));
|
|
end;
|
|
|
|
procedure TDataStore.WriteInt16S(const AData: TInt16S);
|
|
var
|
|
bffr : TInt16U;
|
|
begin
|
|
bffr := Reverse_16(AData);
|
|
FStream.Write(bffr,SizeOf(AData));
|
|
end;
|
|
|
|
procedure TDataStore.WriteInt32U(const AData: TInt32U);
|
|
var
|
|
bffr : TInt32U;
|
|
begin
|
|
bffr := Reverse_32(AData);
|
|
FStream.Write(bffr,SizeOf(AData));
|
|
end;
|
|
|
|
procedure TDataStore.WriteInt32S(const AData: TInt32S);
|
|
var
|
|
bffr : TInt32U;
|
|
begin
|
|
bffr := Reverse_32(AData);
|
|
FStream.Write(bffr,SizeOf(AData));
|
|
end;
|
|
|
|
procedure TDataStore.WriteInt64U(const AData: TInt64U);
|
|
var
|
|
bffr : TInt64U;
|
|
begin
|
|
bffr := Reverse_64(AData);
|
|
FStream.Write(bffr,SizeOf(AData));
|
|
end;
|
|
|
|
procedure TDataStore.WriteInt64S(const AData: TInt64S);
|
|
var
|
|
bffr : TInt64U;
|
|
begin
|
|
bffr := Reverse_64(AData);
|
|
FStream.Write(bffr,SizeOf(AData));
|
|
end;
|
|
{$ENDIF}
|
|
|
|
procedure TDataStore.WriteBool(const AData: TBoolData);
|
|
Var
|
|
i : TInt8U;
|
|
begin
|
|
If AData Then
|
|
i := 1
|
|
Else
|
|
i := 0;
|
|
WriteInt8U(i);
|
|
end;
|
|
|
|
procedure TDataStore.WriteEnum(const AData: TEnumData);
|
|
begin
|
|
WriteInt64S(AData);
|
|
end;
|
|
|
|
procedure TDataStore.WriteStr(const AData: TStringData);
|
|
Var
|
|
i : TInt32S;
|
|
begin
|
|
i := Length(AData);
|
|
WriteInt32S(i);
|
|
If ( i > 0 ) Then
|
|
FStream.Write(AData[1],i);
|
|
end;
|
|
|
|
{
|
|
procedure TDataStore.WriteSingle(const AData: TFloat_Single_4);
|
|
begin
|
|
FStream.Write(Reverse_Single(AData),SizeOf(AData));
|
|
end;
|
|
|
|
procedure TDataStore.WriteDouble(const AData: TFloat_Double_8);
|
|
begin
|
|
FStream.Write(Reverse_Double(AData),SizeOf(AData));
|
|
end;
|
|
|
|
procedure TDataStore.WriteExtended(const AData: TFloat_Extended_10);
|
|
begin
|
|
FStream.Write(Reverse_Extended(AData),SizeOf(AData));
|
|
end;
|
|
|
|
procedure TDataStore.WriteCurrency(const AData: TFloat_Currency_8);
|
|
begin
|
|
FStream.Write(Reverse_Currency(AData),SizeOf(AData));
|
|
end;
|
|
}
|
|
procedure TDataStore.WriteSingle(const AData: TFloat_Single_4);
|
|
var
|
|
bffr : TFloat_Single_4;
|
|
begin
|
|
bffr := Reverse_Single(AData);
|
|
FStream.Write(bffr,SizeOf(AData));
|
|
end;
|
|
|
|
procedure TDataStore.WriteDouble(const AData: TFloat_Double_8);
|
|
var
|
|
bffr : TFloat_Double_8;
|
|
begin
|
|
bffr := Reverse_Double(AData);
|
|
FStream.Write(bffr,SizeOf(AData));
|
|
end;
|
|
|
|
procedure TDataStore.WriteExtended(const AData: TFloat_Extended_10);
|
|
var
|
|
bffr : TFloat_Extended_10;
|
|
begin
|
|
bffr := Reverse_Extended(AData);
|
|
FStream.Write(bffr,SizeOf(AData));
|
|
end;
|
|
|
|
procedure TDataStore.WriteCurrency(const AData: TFloat_Currency_8);
|
|
var
|
|
bffr : TFloat_Currency_8;
|
|
begin
|
|
bffr := Reverse_Currency(AData);
|
|
FStream.Write(bffr,SizeOf(AData));
|
|
end;
|
|
|
|
constructor TDataStore.Create(AStream: TStream);
|
|
begin
|
|
Assert(Assigned(AStream));
|
|
FStream := AStream;
|
|
end;
|
|
|
|
{ TDataStoreReader }
|
|
|
|
function TDataStoreReader.IsAtEof(): Boolean;
|
|
begin
|
|
Result := ( FStream.Position >= FStream.Size );
|
|
end;
|
|
|
|
function TDataStoreReader.ReadInt8U(): TInt8U;
|
|
begin
|
|
FStream.Read(Result,SizeOf(Result));
|
|
end;
|
|
|
|
function TDataStoreReader.ReadInt8S(): TInt8S;
|
|
begin
|
|
FStream.Read(Result,SizeOf(Result));
|
|
end;
|
|
|
|
function TDataStoreReader.ReadInt16U(): TInt16U;
|
|
begin
|
|
FStream.Read(Result,SizeOf(Result));
|
|
Result := Reverse_16(Result);
|
|
end;
|
|
|
|
function TDataStoreReader.ReadInt16S(): TInt16S;
|
|
begin
|
|
FStream.Read(Result,SizeOf(Result));
|
|
Result := Reverse_16(Result);
|
|
end;
|
|
|
|
function TDataStoreReader.ReadInt32U(): TInt32U;
|
|
begin
|
|
FStream.Read(Result,SizeOf(Result));
|
|
Result := Reverse_32(Result);
|
|
end;
|
|
|
|
function TDataStoreReader.ReadInt32S(): TInt32S;
|
|
begin
|
|
FStream.Read(Result,SizeOf(Result));
|
|
Result := Reverse_32(Result);
|
|
end;
|
|
|
|
function TDataStoreReader.ReadInt64U(): TInt64U;
|
|
begin
|
|
FStream.Read(Result,SizeOf(Result));
|
|
Result := Reverse_64(Result);
|
|
end;
|
|
|
|
function TDataStoreReader.ReadInt64S(): TInt64S;
|
|
begin
|
|
FStream.Read(Result,SizeOf(Result));
|
|
Result := Reverse_64(Result);
|
|
end;
|
|
|
|
function TDataStoreReader.ReadBool(): TBoolData;
|
|
begin
|
|
Result := ( ReadInt8U() > 0 );
|
|
end;
|
|
|
|
function TDataStoreReader.ReadEnum(): TEnumData;
|
|
begin
|
|
Result := ReadInt64S();
|
|
end;
|
|
|
|
function TDataStoreReader.ReadStr(): TStringData;
|
|
Var
|
|
i : TInt32S;
|
|
begin
|
|
i := ReadInt32S();
|
|
SetLength(Result,i);
|
|
If ( i > 0 ) Then
|
|
FStream.ReadBuffer(Result[1],i);
|
|
end;
|
|
|
|
function TDataStoreReader.ReadSingle(): TFloat_Single_4;
|
|
begin
|
|
FStream.Read(Result,SizeOf(Result));
|
|
Result := Reverse_Single(Result);
|
|
end;
|
|
|
|
function TDataStoreReader.ReadDouble(): TFloat_Double_8;
|
|
begin
|
|
FStream.Read(Result,SizeOf(Result));
|
|
Result := Reverse_Double(Result);
|
|
end;
|
|
|
|
function TDataStoreReader.ReadExtended(): TFloat_Extended_10;
|
|
begin
|
|
FStream.Read(Result,SizeOf(Result));
|
|
Result := Reverse_Extended(Result);
|
|
end;
|
|
|
|
function TDataStoreReader.ReadCurrency(): TFloat_Currency_8;
|
|
begin
|
|
FStream.Read(Result,SizeOf(Result));
|
|
Result := Reverse_Currency(Result);
|
|
end;
|
|
|
|
constructor TDataStoreReader.Create(AStream: TStream);
|
|
begin
|
|
Assert(Assigned(AStream));
|
|
FStream := AStream;
|
|
end;
|
|
|
|
end.
|