GR32.BigEndian.pas 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. unit GR32.BigEndian;
  2. (* ***** BEGIN LICENSE BLOCK *****
  3. * Version: MPL 1.1 or LGPL 2.1 with linking exception
  4. *
  5. * The contents of this file are subject to the Mozilla Public License Version
  6. * 1.1 (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. * http://www.mozilla.org/MPL/
  9. *
  10. * Software distributed under the License is distributed on an "AS IS" basis,
  11. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  12. * for the specific language governing rights and limitations under the
  13. * License.
  14. *
  15. * Alternatively, the contents of this file may be used under the terms of the
  16. * Free Pascal modified version of the GNU Lesser General Public License
  17. * Version 2.1 (the "FPC modified LGPL License"), in which case the provisions
  18. * of this license are applicable instead of those above.
  19. * Please see the file LICENSE.txt for additional information concerning this
  20. * license.
  21. *
  22. * The Original Code is Graphics32
  23. *
  24. * The Initial Developer of the Original Code is
  25. * Anders Melander <[email protected]>
  26. *
  27. * Portions created by the Initial Developer are Copyright (C) 2000-2009
  28. * the Initial Developer. All Rights Reserved.
  29. *
  30. * Contributor(s):
  31. *
  32. * ***** END LICENSE BLOCK ***** *)
  33. interface
  34. {$include GR32.inc}
  35. uses
  36. Classes,
  37. SysUtils;
  38. // Define CHECKED_STREAM_READS to have stream read operations raise an exception
  39. // (of type EBigEndian) if they fail to read the required amount of data.
  40. {$define CHECKED_STREAM_READS}
  41. type
  42. EBigEndian = class(Exception);
  43. //------------------------------------------------------------------------------
  44. //
  45. // Big Endian I/O
  46. //
  47. //------------------------------------------------------------------------------
  48. type
  49. BigEndian = record
  50. class function ReadByte(Stream: TStream): Byte; static; {$IFDEF INLINING_ENHANCED_RECORDS} inline; {$ENDIF}
  51. class function ReadWord(Stream: TStream): Word; static; {$IFDEF INLINING_ENHANCED_RECORDS} inline; {$ENDIF}
  52. class function ReadSmallInt(Stream: TStream): SmallInt; static; {$IFDEF INLINING_ENHANCED_RECORDS} inline; {$ENDIF}
  53. class function ReadCardinal(Stream: TStream): Cardinal; static; {$IFDEF INLINING_ENHANCED_RECORDS} inline; {$ENDIF}
  54. class function ReadInt64(Stream: TStream): Int64; static; {$IFDEF INLINING_ENHANCED_RECORDS} inline; {$ENDIF}
  55. class procedure WriteByte(Stream: TStream; Value: Byte); static; {$IFDEF INLINING_ENHANCED_RECORDS} inline; {$ENDIF}
  56. class procedure WriteWord(Stream: TStream; Value: Word); static; {$IFDEF INLINING_ENHANCED_RECORDS} inline; {$ENDIF}
  57. class procedure WriteSmallInt(Stream: TStream; Value: SmallInt); static; {$IFDEF INLINING_ENHANCED_RECORDS} inline; {$ENDIF}
  58. class procedure WriteCardinal(Stream: TStream; Value: Cardinal); static; {$IFDEF INLINING_ENHANCED_RECORDS} inline; {$ENDIF}
  59. class procedure WriteInt64(Stream: TStream; Value: Int64); static; {$IFDEF INLINING_ENHANCED_RECORDS} inline; {$ENDIF}
  60. end;
  61. resourcestring
  62. sStreamReadError = 'Stream read error';
  63. implementation
  64. uses
  65. GR32_LowLevel;
  66. //------------------------------------------------------------------------------
  67. //
  68. // Big Endian I/O
  69. //
  70. //------------------------------------------------------------------------------
  71. //------------------------------------------------------------------------------
  72. // Big endian stream writers
  73. //------------------------------------------------------------------------------
  74. class procedure BigEndian.WriteByte(Stream: TStream; Value: Byte);
  75. begin
  76. Stream.Write(Value, SizeOf(Byte));
  77. end;
  78. class procedure BigEndian.WriteWord(Stream: TStream; Value: Word);
  79. begin
  80. Value := Swap16(Value);
  81. Stream.Write(Value, SizeOf(Word));
  82. end;
  83. class procedure BigEndian.WriteSmallInt(Stream: TStream; Value: SmallInt);
  84. begin
  85. Value := Swap16(Value);
  86. Stream.Write(Value, SizeOf(SmallInt));
  87. end;
  88. class procedure BigEndian.WriteCardinal(Stream: TStream; Value: Cardinal);
  89. begin
  90. Value := Swap32(Value);
  91. Stream.Write(Value, SizeOf(Cardinal));
  92. end;
  93. class procedure BigEndian.WriteInt64(Stream: TStream; Value: Int64);
  94. begin
  95. Value := Swap64(Value);
  96. Stream.Write(Value, SizeOf(Int64));
  97. end;
  98. //------------------------------------------------------------------------------
  99. // Big endian stream readers
  100. //------------------------------------------------------------------------------
  101. class function BigEndian.ReadByte(Stream: TStream): Byte;
  102. begin
  103. {$IFDEF CHECKED_STREAM_READS}
  104. if Stream.Read(Result, SizeOf(Byte)) <> SizeOf(Byte) then
  105. raise EBigEndian.Create(sStreamReadError);
  106. {$ELSE}
  107. Stream.Read(Result, SizeOf(Byte));
  108. {$ENDIF}
  109. end;
  110. class function BigEndian.ReadWord(Stream: TStream): Word;
  111. begin
  112. {$IFDEF CHECKED_STREAM_READS}
  113. if Stream.Read(Result, SizeOf(Word)) <> SizeOf(Word) then
  114. raise EBigEndian.Create(sStreamReadError);
  115. {$ELSE}
  116. Stream.Read(Result, SizeOf(Word));
  117. {$ENDIF}
  118. Result := Swap16(Result);
  119. end;
  120. class function BigEndian.ReadSmallInt(Stream: TStream): SmallInt;
  121. begin
  122. {$IFDEF CHECKED_STREAM_READS}
  123. if Stream.Read(Result, SizeOf(SmallInt)) <> SizeOf(SmallInt) then
  124. raise EBigEndian.Create(sStreamReadError);
  125. {$ELSE}
  126. Stream.Read(Result, SizeOf(SmallInt));
  127. {$ENDIF}
  128. Result := SmallInt(Swap16(Word(Result)));
  129. end;
  130. class function BigEndian.ReadCardinal(Stream: TStream): Cardinal;
  131. begin
  132. {$IFDEF CHECKED_STREAM_READS}
  133. Assert(SizeOf(Cardinal) = 4);
  134. if Stream.Read(Result, SizeOf(Cardinal)) <> SizeOf(Cardinal) then
  135. raise EBigEndian.Create(sStreamReadError);
  136. {$ELSE}
  137. Stream.Read(Result, SizeOf(Cardinal));
  138. {$ENDIF}
  139. Result := Swap32(Result);
  140. end;
  141. class function BigEndian.ReadInt64(Stream: TStream): Int64;
  142. begin
  143. {$IFDEF CHECKED_STREAM_READS}
  144. if Stream.Read(Result, SizeOf(Int64)) <> SizeOf(Int64) then
  145. raise EBigEndian.Create(sStreamReadError);
  146. {$ELSE}
  147. Stream.Read(Result, SizeOf(Int64));
  148. {$ENDIF}
  149. Result := Swap64(Result);
  150. end;
  151. end.