DEADSOFTWARE

6433511f3abd87e2d2570a4e05b272f3e1ecb7a8
[d2df-sdl.git] / src / engine / e_msg.pas
1 (* Copyright (C) Doom 2D: Forever Developers
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *)
16 {$INCLUDE ../shared/a_modes.inc}
17 unit e_msg;
19 interface
21 uses md5;
23 type
24 TMsg = record
25 Data: Pointer;
26 Overflow: Boolean;
27 MaxSize: Integer;
28 CurSize: Integer;
29 ReadCount: Integer;
30 Bit: Integer;
31 OwnMemory: Boolean;
33 function Init(V: Pointer; N: Integer; Full: Boolean = False): Boolean;
34 procedure Alloc(N: Integer);
35 procedure Clear();
36 procedure Free();
37 procedure CopyFrom(var From: TMsg; V: Pointer; N: Integer);
38 function Allocated(): Boolean;
39 function AssignBuffer(P: Pointer; N: Integer; Full: Boolean = False): Boolean;
41 procedure BeginReading();
42 function ReadData(V: Pointer; N: Integer): Integer;
43 function ReadChar(): Char;
44 function ReadByte(): Byte;
45 function ReadWord(): Word;
46 function ReadLongWord(): LongWord;
47 function ReadShortInt(): ShortInt;
48 function ReadSmallInt(): SmallInt;
49 function ReadLongInt(): LongInt;
50 function ReadInt64(): Int64;
51 function ReadString(): String;
52 function ReadMD5(): TMD5Digest;
54 procedure WriteData(V: Pointer; N: Integer);
55 procedure Write(V: Byte); overload;
56 procedure Write(V: Word); overload;
57 procedure Write(V: LongWord); overload;
58 procedure Write(V: ShortInt); overload;
59 procedure Write(V: SmallInt); overload;
60 procedure Write(V: LongInt); overload;
61 procedure Write(V: Int64); overload;
62 procedure Write(V: String); overload;
63 procedure Write(V: TMD5Digest); overload;
64 end;
66 type
67 pTMsg = ^TMsg;
69 implementation
71 uses SysUtils, e_log;
73 function TMsg.Init(V: Pointer; N: Integer; Full: Boolean = False): Boolean;
74 begin
75 Overflow := False;
76 if Full then CurSize := N else CurSize := 0;
77 ReadCount := 0;
78 Bit := 0;
79 MaxSize := N;
80 Data := V;
81 OwnMemory := False;
82 Result := (N > 0) and (V <> nil);
83 end;
85 procedure TMsg.Alloc(N: Integer);
86 var
87 P: Pointer;
88 begin
89 P := GetMem(N);
90 if P = nil then
91 raise Exception.Create('TMsg.Alloc: no mem');
92 Init(P, N);
93 OwnMemory := True;
94 end;
96 procedure TMsg.Free();
97 begin
98 if not OwnMemory then
99 raise Exception.Create('TMsg.Free: called on borrowed memory');
100 OwnMemory := False;
101 FreeMem(Data);
102 Data := nil;
103 MaxSize := 0;
104 end;
106 procedure TMsg.Clear();
107 begin
108 CurSize := 0;
109 ReadCount := 0;
110 Overflow := False;
111 Bit := 0;
112 end;
114 function TMsg.Allocated(): Boolean;
115 begin
116 Result := OwnMemory;
117 end;
119 procedure TMsg.CopyFrom(var From: TMsg; V: Pointer; N: Integer);
120 begin
121 if N < From.CurSize then
122 raise Exception.Create('TMsg.Copy: can''t copy into a smaller TMsg');
123 Move(From, Self, SizeOf(TMsg));
124 Data := V;
125 Move(From.Data^, Data^, From.CurSize);
126 end;
128 function TMsg.AssignBuffer(P: Pointer; N: Integer; Full: Boolean = False): Boolean;
129 begin
130 if OwnMemory then Self.Free();
131 Clear();
132 Data := P;
133 MaxSize := N;
134 if Full then CurSize := N;
135 Result := (N > 0) and (P <> nil);
136 end;
138 procedure TMsg.WriteData(V: Pointer; N: Integer);
139 begin
140 if CurSize + N > MaxSize then
141 begin
142 Overflow := True;
143 raise Exception.Create('TMsg.WriteData: buffer overrun!');
144 Exit;
145 end;
146 Move(V^, (Data + CurSize)^, N);
147 CurSize := CurSize + N;
148 end;
150 procedure TMsg.Write(V: Byte); overload;
151 begin
152 WriteData(@V, 1);
153 end;
155 procedure TMsg.Write(V: Word); overload;
156 begin
157 WriteData(@V, 2);
158 end;
160 procedure TMsg.Write(V: LongWord); overload;
161 begin
162 WriteData(@V, 4);
163 end;
165 procedure TMsg.Write(V: ShortInt); overload;
166 begin
167 WriteData(@V, 1);
168 end;
170 procedure TMsg.Write(V: SmallInt); overload;
171 begin
172 WriteData(@V, 2);
173 end;
175 procedure TMsg.Write(V: LongInt); overload;
176 begin
177 WriteData(@V, 4);
178 end;
180 procedure TMsg.Write(V: Int64); overload;
181 begin
182 WriteData(@V, 8);
183 end;
185 procedure TMsg.Write(V: AnsiString); overload;
186 var
187 I: Integer;
188 begin
189 // TODO: Write(Word(Length(V)));
190 Write(Byte(Length(V)));
191 for I := 1 to High(V) do
192 Write(Byte(V[I]));
193 end;
195 procedure TMsg.Write(V: TMD5Digest); overload;
196 var
197 I: Integer;
198 begin
199 for I := 0 to 15 do
200 Write(V[I]);
201 end;
203 procedure TMsg.BeginReading();
204 begin
205 ReadCount := 0;
206 Bit := 0;
207 end;
209 function TMsg.ReadData(V: Pointer; N: Integer): Integer;
210 begin
211 Result := 0;
212 if ReadCount + N > CurSize then
213 begin
214 // TODO: maybe partial reads?
215 ReadCount := CurSize + 1;
216 raise Exception.Create('TMsg.ReadData: buffer overrun!');
217 Exit;
218 end;
219 Move((Data + ReadCount)^, V^, N);
220 ReadCount := ReadCount + N;
221 Result := N;
222 end;
224 function TMsg.ReadChar(): Char;
225 begin
226 Result := #0;
227 ReadData(@Result, 1);
228 end;
230 function TMsg.ReadByte(): Byte;
231 begin
232 Result := 0;
233 ReadData(@Result, 1);
234 end;
236 function TMsg.ReadWord(): Word;
237 begin
238 Result := 0;
239 ReadData(@Result, 2);
240 end;
242 function TMsg.ReadLongWord(): LongWord;
243 begin
244 Result := 0;
245 ReadData(@Result, 4);
246 end;
248 function TMsg.ReadShortInt(): ShortInt;
249 begin
250 Result := 0;
251 ReadData(@Result, 1);
252 end;
254 function TMsg.ReadSmallInt(): SmallInt;
255 begin
256 Result := 0;
257 ReadData(@Result, 2);
258 end;
260 function TMsg.ReadLongInt(): LongInt;
261 begin
262 Result := 0;
263 ReadData(@Result, 4);
264 end;
266 function TMsg.ReadInt64(): Int64;
267 begin
268 Result := 0;
269 ReadData(@Result, 8);
270 end;
272 function TMsg.ReadString(): string;
273 var
274 I: Integer;
275 L: Byte;
276 begin
277 Result := '';
278 // TODO: L := ReadWord();
279 L := ReadByte();
280 if (L > 0) and (L <> Byte(-1)) then
281 begin
282 SetLength(Result, L);
283 for I := 1 to L do
284 Result[I] := ReadChar();
285 end;
286 end;
288 function TMsg.ReadMD5(): TMD5Digest;
289 var
290 I: Integer;
291 begin
292 for I := 0 to 15 do
293 Result[I] := ReadByte();
294 end;
296 end.