DEADSOFTWARE

fix network on big-endian machines
[d2df-sdl.git] / src / engine / e_msg.pas
index 6433511f3abd87e2d2570a4e05b272f3e1ecb7a8..f5711ec3079d6b46f7aa38d9a2b5b28b2ebe164c 100644 (file)
@@ -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
+  V := NtoLE(V);
   WriteData(@V, 1);
 end;
 
 procedure TMsg.Write(V: SmallInt); overload;
 begin
+  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, 1);
+  Result := LEtoN(Result);
 end;
 
 function TMsg.ReadSmallInt(): SmallInt;
 begin
   Result := 0;
   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;