X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fengine%2Fe_msg.pas;h=f5711ec3079d6b46f7aa38d9a2b5b28b2ebe164c;hb=d8d321d9c14f9737beb8bf9b41125f3c1f4b6fe6;hp=1ed3809b3f313c857b086a2e906a00c512875f83;hpb=1bddfaf7b6421f1659a6f211dfdb1dfaef5d5173;p=d2df-sdl.git diff --git a/src/engine/e_msg.pas b/src/engine/e_msg.pas index 1ed3809..f5711ec 100644 --- a/src/engine/e_msg.pas +++ b/src/engine/e_msg.pas @@ -2,8 +2,7 @@ * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * the Free Software Foundation, version 3 of the License ONLY. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -28,6 +27,7 @@ type CurSize: Integer; ReadCount: Integer; Bit: Integer; + AllocStep: Integer; OwnMemory: Boolean; function Init(V: Pointer; N: Integer; Full: Boolean = False): Boolean; @@ -39,6 +39,9 @@ type function AssignBuffer(P: Pointer; N: Integer; Full: Boolean = False): Boolean; procedure BeginReading(); + procedure Seek(Pos: Integer); + procedure Skip(Size: Integer); + function BytesLeft(): Integer; function ReadData(V: Pointer; N: Integer): Integer; function ReadChar(): Char; function ReadByte(): Byte; @@ -61,6 +64,7 @@ type procedure Write(V: Int64); overload; procedure Write(V: String); overload; procedure Write(V: TMD5Digest); overload; + procedure Write(V: TMsg); end; type @@ -90,6 +94,7 @@ begin if P = nil then raise Exception.Create('TMsg.Alloc: no mem'); Init(P, N); + AllocStep := N; OwnMemory := True; end; @@ -97,6 +102,7 @@ procedure TMsg.Free(); begin if not OwnMemory then raise Exception.Create('TMsg.Free: called on borrowed memory'); + Clear(); OwnMemory := False; FreeMem(Data); Data := nil; @@ -136,17 +142,34 @@ begin end; procedure TMsg.WriteData(V: Pointer; N: Integer); +var + NewSize: Integer; begin if CurSize + N > MaxSize then begin - Overflow := True; - raise Exception.Create('TMsg.WriteData: buffer overrun!'); - Exit; + if OwnMemory then + begin + NewSize := MaxSize + ((N + AllocStep - 1) div AllocStep) * AllocStep; // round up + if ReAllocMem(Data, NewSize) = nil then + raise Exception.Create('TMsg.WriteData: out of memory on realloc'); + MaxSize := NewSize; + end + else + begin + Overflow := True; + raise Exception.Create('TMsg.WriteData: buffer overrun on borrowed memory!'); + end; end; + Move(V^, (Data + CurSize)^, N); CurSize := CurSize + N; end; +procedure TMsg.Write(V: TMsg); +begin + WriteData(V.Data, V.CurSize); +end; + procedure TMsg.Write(V: Byte); overload; begin WriteData(@V, 1); @@ -154,31 +177,37 @@ end; procedure TMsg.Write(V: Word); overload; begin + V := NtoLE(V); WriteData(@V, 2); end; procedure TMsg.Write(V: LongWord); overload; begin + V := NtoLE(V); WriteData(@V, 4); end; procedure TMsg.Write(V: ShortInt); overload; begin - WriteData(@V, 2); + V := NtoLE(V); + WriteData(@V, 1); end; procedure TMsg.Write(V: SmallInt); overload; begin - WriteData(@V, 1); + V := NtoLE(V); + WriteData(@V, 2); end; procedure TMsg.Write(V: LongInt); overload; begin + V := NtoLE(V); WriteData(@V, 4); end; procedure TMsg.Write(V: Int64); overload; begin + V := NtoLE(V); WriteData(@V, 8); end; @@ -206,6 +235,25 @@ begin Bit := 0; end; +procedure TMsg.Seek(Pos: Integer); +begin + if Pos > CurSize then + raise Exception.Create('TMsg.Seek: buffer overrun!'); + ReadCount := Pos; +end; + +procedure TMsg.Skip(Size: Integer); +begin + if ReadCount + Size > CurSize then + raise Exception.Create('TMsg.Skip: buffer overrun!'); + ReadCount := ReadCount + Size; +end; + +function TMsg.BytesLeft(): Integer; +begin + Result := CurSize - ReadCount; +end; + function TMsg.ReadData(V: Pointer; N: Integer): Integer; begin Result := 0; @@ -237,36 +285,42 @@ function TMsg.ReadWord(): Word; begin Result := 0; ReadData(@Result, 2); + Result := LEtoN(Result); end; function TMsg.ReadLongWord(): LongWord; begin Result := 0; ReadData(@Result, 4); + Result := LEtoN(Result); end; function TMsg.ReadShortInt(): ShortInt; begin Result := 0; - ReadData(@Result, 2); + ReadData(@Result, 1); + Result := LEtoN(Result); end; function TMsg.ReadSmallInt(): SmallInt; begin Result := 0; - ReadData(@Result, 1); + ReadData(@Result, 2); + Result := LEtoN(Result); end; function TMsg.ReadLongInt(): LongInt; begin Result := 0; ReadData(@Result, 4); + Result := LEtoN(Result); end; function TMsg.ReadInt64(): Int64; begin Result := 0; ReadData(@Result, 8); + Result := LEtoN(Result); end; function TMsg.ReadString(): string;