IdStruct.pas 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  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. {$IF DEFINED(WINDOWS) AND DEFINED(USE_INLINE)}
  72. uses
  73. Windows;
  74. {$IFEND}
  75. { TIdStruct }
  76. constructor TIdStruct.Create;
  77. begin
  78. inherited Create;
  79. end;
  80. function TIdStruct.GetBytesLen: UInt32;
  81. begin
  82. Result := 0;
  83. end;
  84. procedure TIdStruct.ReadStruct(const ABytes: TIdBytes; var VIndex: UInt32);
  85. begin
  86. Assert(UInt32(Length(ABytes)) >= VIndex + BytesLen, 'not enough bytes'); {do not localize}
  87. end;
  88. procedure TIdStruct.WriteStruct(var VBytes: TIdBytes; var VIndex: UInt32);
  89. var
  90. Len: UInt32;
  91. begin
  92. Len := VIndex + BytesLen;
  93. if UInt32(Length(VBytes)) < Len then begin
  94. SetLength(VBytes, Len);
  95. end;
  96. end;
  97. { TIdUnion }
  98. function TIdUnion.GetBytesLen : UInt32;
  99. begin
  100. Result := UInt32(Length(FBuffer));
  101. end;
  102. procedure TIdUnion.SetBytesLen(const ABytesLen: UInt32);
  103. begin
  104. SetLength(FBuffer, ABytesLen);
  105. end;
  106. procedure TIdUnion.ReadStruct(const ABytes: TIdBytes; var VIndex: UInt32);
  107. begin
  108. inherited ReadStruct(ABytes, VIndex);
  109. CopyTIdBytes(ABytes, VIndex, FBuffer, 0, Length(FBuffer));
  110. Inc(VIndex, Length(FBuffer));
  111. end;
  112. procedure TIdUnion.WriteStruct(var VBytes: TIdBytes; var VIndex: UInt32);
  113. begin
  114. inherited WriteStruct(VBytes, VIndex);
  115. CopyTIdBytes(FBuffer, 0, VBytes, VIndex, Length(FBuffer));
  116. Inc(VIndex, Length(FBuffer));
  117. end;
  118. { TIdLongWord }
  119. constructor TIdLongWord.Create;
  120. begin
  121. inherited Create;
  122. SetBytesLen(4);
  123. end;
  124. function TIdLongWord.Gets_w1: UInt16;
  125. begin
  126. Result := BytesToUInt16(FBuffer, 0);
  127. end;
  128. procedure TIdLongWord.SetS_w1(const Value: UInt16);
  129. begin
  130. CopyTIdUInt16(Value, FBuffer, 0);
  131. end;
  132. function TIdLongWord.Gets_b1: UInt8;
  133. begin
  134. Result := FBuffer[0];
  135. end;
  136. procedure TIdLongWord.Sets_b1(const Value: UInt8);
  137. begin
  138. FBuffer[0] := Value;
  139. end;
  140. function TIdLongWord.Gets_b2: UInt8;
  141. begin
  142. Result := FBuffer[1];
  143. end;
  144. procedure TIdLongWord.Sets_b2(const Value: UInt8);
  145. begin
  146. FBuffer[1] := Value;
  147. end;
  148. function TIdLongWord.Gets_b3: UInt8;
  149. begin
  150. Result := FBuffer[2];
  151. end;
  152. procedure TIdLongWord.Sets_b3(const Value: UInt8);
  153. begin
  154. FBuffer[2] := Value;
  155. end;
  156. function TIdLongWord.Gets_b4: UInt8;
  157. begin
  158. Result := FBuffer[3];
  159. end;
  160. procedure TIdLongWord.Sets_b4(const Value: UInt8);
  161. begin
  162. FBuffer[3] := Value;
  163. end;
  164. function TIdLongWord.Get_l: UInt32;
  165. begin
  166. Result := BytesToUInt32(FBuffer, 0);
  167. end;
  168. procedure TIdLongWord.Set_l(const Value: UInt32);
  169. begin
  170. CopyTIdUInt32(Value, FBuffer, 0);
  171. end;
  172. function TIdLongWord.Gets_w2: UInt16;
  173. begin
  174. Result := BytesToUInt16(FBuffer, 2);
  175. end;
  176. procedure TIdLongWord.SetS_w2(const Value: UInt16);
  177. begin
  178. CopyTIdUInt16(Value, FBuffer, 2);
  179. end;
  180. end.