BrookString.pas 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. (* _ _
  2. * | |__ _ __ ___ ___ | | __
  3. * | '_ \| '__/ _ \ / _ \| |/ /
  4. * | |_) | | | (_) | (_) | <
  5. * |_.__/|_| \___/ \___/|_|\_\
  6. *
  7. * Microframework which helps to develop web Pascal applications.
  8. *
  9. * Copyright (c) 2012-2021 Silvio Clecio <[email protected]>
  10. *
  11. * Brook framework is free software; you can redistribute it and/or
  12. * modify it under the terms of the GNU Lesser General Public
  13. * License as published by the Free Software Foundation; either
  14. * version 2.1 of the License, or (at your option) any later version.
  15. *
  16. * Brook framework is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  19. * Lesser General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU Lesser General Public
  22. * License along with Brook framework; if not, write to the Free Software
  23. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  24. *)
  25. { String type used to represent a HTML body, POST payload and more. }
  26. unit BrookString;
  27. {$I BrookDefines.inc}
  28. interface
  29. uses
  30. RTLConsts,
  31. SysUtils,
  32. Classes,
  33. libsagui,
  34. Marshalling,
  35. BrookHandledClasses;
  36. { TODO: TBrookString.Assign() }
  37. type
  38. { String buffer class and its related methods. }
  39. TBrookString = class(TBrookHandledPersistent)
  40. private
  41. FHandle: Psg_str;
  42. FOwnsHandle: Boolean;
  43. function GetContent: TBytes;
  44. function GetLength: NativeUInt;
  45. procedure SetText(const AValue: string);
  46. function GetText: string; {$IFNDEF DEBUG}inline;{$ENDIF}
  47. protected
  48. class procedure CheckEncoding(AEncoding: TEncoding); static;
  49. {$IFNDEF DEBUG}inline;{$ENDIF}
  50. function GetHandle: Pointer; override;
  51. public
  52. { Creates an instance of @code(TBrookString).
  53. @param(AHandle[in] String handle.) }
  54. constructor Create(AHandle: Pointer); virtual;
  55. { Frees an instance of @code(TBrookString). }
  56. destructor Destroy; override;
  57. { Determines if the handle is freed on the class destruction. }
  58. property OwnsHandle: Boolean read FOwnsHandle write FOwnsHandle;
  59. { Write a string buffer to the string handle. All strings previously
  60. written are kept.
  61. @param(ASource[in] String buffer source to be written.)
  62. @param(ALength[in] Length of the string buffer being written.)
  63. @returns(Length of the written string buffer.) }
  64. function WriteBytes(const ASource: TBytes;
  65. ALength: NativeUInt): NativeUInt; virtual;
  66. { Writes a string to the string handle. All strings previously written
  67. are kept.
  68. @param(ASource[in] String to be written.)
  69. @param(AEncoding[in] Determines the encoding of the string being written.) }
  70. procedure Write(const ASource: string;
  71. AEncoding: TEncoding); overload; virtual;
  72. { Writes a string to the string handle. All strings previously written
  73. are kept.
  74. @param(ASource[in] String to be written.) }
  75. procedure Write(const ASource: string); overload; virtual;
  76. { Gets the string from the string handle. }
  77. function ToString: string; override;
  78. { Clears all the content present in the string handle. }
  79. procedure Clear; virtual;
  80. { Gets the content buffer from the string handle. }
  81. property Content: TBytes read GetContent;
  82. { Gets the content length from the string handle. }
  83. property Length: NativeUInt read GetLength;
  84. { Gets or sets a string from or to the string handle. }
  85. property Text: string read GetText write SetText;
  86. end;
  87. implementation
  88. constructor TBrookString.Create(AHandle: Pointer);
  89. begin
  90. inherited Create;
  91. FOwnsHandle := not Assigned(AHandle);
  92. if FOwnsHandle then
  93. begin
  94. SgLib.Check;
  95. FHandle := sg_str_new;
  96. end
  97. else
  98. FHandle := AHandle;
  99. end;
  100. destructor TBrookString.Destroy;
  101. begin
  102. try
  103. if FOwnsHandle then
  104. begin
  105. SgLib.Check;
  106. sg_str_free(FHandle);
  107. FHandle := nil;
  108. end;
  109. finally
  110. inherited Destroy;
  111. end;
  112. end;
  113. class procedure TBrookString.CheckEncoding(AEncoding: TEncoding);
  114. begin
  115. if not Assigned(AEncoding) then
  116. raise EArgumentNilException.CreateFmt(SParamIsNil, ['AEncoding']);
  117. end;
  118. function TBrookString.GetHandle: Pointer;
  119. begin
  120. Result := FHandle;
  121. end;
  122. function TBrookString.GetText: string;
  123. begin
  124. Result :=
  125. {$IFDEF FPC}string({$ENDIF}TEncoding.UTF8.GetString(GetContent){$IFDEF FPC}){$ENDIF};
  126. end;
  127. function TBrookString.WriteBytes(const ASource: TBytes;
  128. ALength: NativeUInt): NativeUInt;
  129. begin
  130. SgLib.Check;
  131. Result := ALength;
  132. SgLib.CheckLastError(sg_str_write(FHandle, @ASource[0], Result));
  133. end;
  134. procedure TBrookString.Write(const ASource: string; AEncoding: TEncoding);
  135. var
  136. VBytes: TBytes;
  137. begin
  138. CheckEncoding(AEncoding);
  139. VBytes := AEncoding.GetBytes(
  140. {$IFDEF FPC}UnicodeString({$ENDIF}ASource{$IFDEF FPC}){$ENDIF});
  141. WriteBytes(VBytes, System.Length(VBytes));
  142. end;
  143. procedure TBrookString.Write(const ASource: string);
  144. begin
  145. Write(ASource, TEncoding.UTF8);
  146. end;
  147. procedure TBrookString.Clear;
  148. begin
  149. SgLib.Check;
  150. SgLib.CheckLastError(sg_str_clear(FHandle));
  151. end;
  152. function TBrookString.GetLength: NativeUInt;
  153. begin
  154. SgLib.Check;
  155. Result := sg_str_length(FHandle);
  156. end;
  157. procedure TBrookString.SetText(const AValue: string);
  158. begin
  159. Clear;
  160. Write(AValue);
  161. end;
  162. function TBrookString.GetContent: TBytes;
  163. begin
  164. SgLib.Check;
  165. Result := TMarshal.ToBytes(sg_str_content(FHandle), GetLength);
  166. end;
  167. function TBrookString.ToString: string;
  168. begin
  169. Result := GetText;
  170. end;
  171. end.