IdStruct.pas 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. {
  2. $Project$
  3. $Workfile$
  4. $Revision$
  5. $DateUTC$
  6. $Id$
  7. This file is part of the Indy (Internet Direct) project, and is offered
  8. under the dual-licensing agreement described on the Indy website.
  9. (http://www.indyproject.org/)
  10. Copyright:
  11. (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
  12. }
  13. {
  14. $Log$
  15. }
  16. unit IdStruct;
  17. interface
  18. {$i IdCompilerDefines.inc}
  19. uses
  20. IdGlobal;
  21. type
  22. TIdStruct = class(TObject)
  23. protected
  24. function GetBytesLen: UInt32; virtual;
  25. public
  26. constructor Create; virtual;
  27. //done this way in case we also need to advance an index pointer
  28. //after a read or write
  29. procedure ReadStruct(const ABytes : TIdBytes; var VIndex : UInt32); virtual;
  30. procedure WriteStruct(var VBytes : TIdBytes; var VIndex : UInt32); virtual;
  31. property BytesLen: UInt32 read GetBytesLen;
  32. end;
  33. TIdUnion = class(TIdStruct)
  34. protected
  35. FBuffer: TIdBytes;
  36. function GetBytesLen: UInt32; override;
  37. procedure SetBytesLen(const ABytesLen: UInt32);
  38. public
  39. procedure ReadStruct(const ABytes : TIdBytes; var VIndex : UInt32); override;
  40. procedure WriteStruct(var VBytes : TIdBytes; var VIndex : UInt32); override;
  41. end;
  42. // TODO: rename to TIdUInt32
  43. TIdLongWord = class(TIdUnion)
  44. protected
  45. function Get_l: UInt32;
  46. function Gets_b1: UInt8;
  47. function Gets_b2: UInt8;
  48. function Gets_b3: UInt8;
  49. function Gets_b4: UInt8;
  50. function Gets_w1: UInt16;
  51. function Gets_w2: UInt16;
  52. procedure Set_l(const Value: UInt32);
  53. procedure Sets_b1(const Value: UInt8);
  54. procedure Sets_b2(const Value: UInt8);
  55. procedure Sets_b3(const Value: UInt8);
  56. procedure Sets_b4(const Value: UInt8);
  57. procedure SetS_w1(const Value: UInt16);
  58. procedure SetS_w2(const Value: UInt16);
  59. public
  60. constructor Create; override;
  61. property s_b1 : UInt8 read Gets_b1 write Sets_b1;
  62. property s_b2 : UInt8 read Gets_b2 write Sets_b2;
  63. property s_b3 : UInt8 read Gets_b3 write Sets_b3;
  64. property s_b4 : UInt8 read Gets_b4 write Sets_b4;
  65. property s_w1 : UInt16 read Gets_w1 write SetS_w1;
  66. property s_w2 : UInt16 read Gets_w2 write SetS_w2;
  67. property s_l : UInt32 read Get_l write Set_l;
  68. end;
  69. implementation
  70. // This is here to facilitate inlining
  71. {$IFDEF WINDOWS}
  72. {$IFDEF USE_INLINE}
  73. uses
  74. Windows;
  75. {$ENDIF}
  76. {$ENDIF}
  77. { TIdStruct }
  78. constructor TIdStruct.Create;
  79. begin
  80. inherited Create;
  81. end;
  82. function TIdStruct.GetBytesLen: UInt32;
  83. begin
  84. Result := 0;
  85. end;
  86. procedure TIdStruct.ReadStruct(const ABytes: TIdBytes; var VIndex: UInt32);
  87. begin
  88. Assert(UInt32(Length(ABytes)) >= VIndex + BytesLen, 'not enough bytes'); {do not localize}
  89. end;
  90. procedure TIdStruct.WriteStruct(var VBytes: TIdBytes; var VIndex: UInt32);
  91. var
  92. Len: UInt32;
  93. begin
  94. Len := VIndex + BytesLen;
  95. if UInt32(Length(VBytes)) < Len then begin
  96. SetLength(VBytes, Len);
  97. end;
  98. end;
  99. { TIdUnion }
  100. function TIdUnion.GetBytesLen : UInt32;
  101. begin
  102. Result := UInt32(Length(FBuffer));
  103. end;
  104. procedure TIdUnion.SetBytesLen(const ABytesLen: UInt32);
  105. begin
  106. SetLength(FBuffer, ABytesLen);
  107. end;
  108. procedure TIdUnion.ReadStruct(const ABytes: TIdBytes; var VIndex: UInt32);
  109. begin
  110. inherited ReadStruct(ABytes, VIndex);
  111. CopyTIdBytes(ABytes, VIndex, FBuffer, 0, Length(FBuffer));
  112. Inc(VIndex, Length(FBuffer));
  113. end;
  114. procedure TIdUnion.WriteStruct(var VBytes: TIdBytes; var VIndex: UInt32);
  115. begin
  116. inherited WriteStruct(VBytes, VIndex);
  117. CopyTIdBytes(FBuffer, 0, VBytes, VIndex, Length(FBuffer));
  118. Inc(VIndex, Length(FBuffer));
  119. end;
  120. { TIdLongWord }
  121. constructor TIdLongWord.Create;
  122. begin
  123. inherited Create;
  124. SetBytesLen(4);
  125. end;
  126. function TIdLongWord.Gets_w1: UInt16;
  127. begin
  128. Result := BytesToUInt16(FBuffer, 0);
  129. end;
  130. procedure TIdLongWord.SetS_w1(const Value: UInt16);
  131. begin
  132. CopyTIdUInt16(Value, FBuffer, 0);
  133. end;
  134. function TIdLongWord.Gets_b1: UInt8;
  135. begin
  136. Result := FBuffer[0];
  137. end;
  138. procedure TIdLongWord.Sets_b1(const Value: UInt8);
  139. begin
  140. FBuffer[0] := Value;
  141. end;
  142. function TIdLongWord.Gets_b2: UInt8;
  143. begin
  144. Result := FBuffer[1];
  145. end;
  146. procedure TIdLongWord.Sets_b2(const Value: UInt8);
  147. begin
  148. FBuffer[1] := Value;
  149. end;
  150. function TIdLongWord.Gets_b3: UInt8;
  151. begin
  152. Result := FBuffer[2];
  153. end;
  154. procedure TIdLongWord.Sets_b3(const Value: UInt8);
  155. begin
  156. FBuffer[2] := Value;
  157. end;
  158. function TIdLongWord.Gets_b4: UInt8;
  159. begin
  160. Result := FBuffer[3];
  161. end;
  162. procedure TIdLongWord.Sets_b4(const Value: UInt8);
  163. begin
  164. FBuffer[3] := Value;
  165. end;
  166. function TIdLongWord.Get_l: UInt32;
  167. begin
  168. Result := BytesToUInt32(FBuffer, 0);
  169. end;
  170. procedure TIdLongWord.Set_l(const Value: UInt32);
  171. begin
  172. CopyTIdUInt32(Value, FBuffer, 0);
  173. end;
  174. function TIdLongWord.Gets_w2: UInt16;
  175. begin
  176. Result := BytesToUInt16(FBuffer, 2);
  177. end;
  178. procedure TIdLongWord.SetS_w2(const Value: UInt16);
  179. begin
  180. CopyTIdUInt16(Value, FBuffer, 2);
  181. end;
  182. end.