2
0

BrookString.pas 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. (* _ _
  2. * | |__ _ __ ___ ___ | | __
  3. * | '_ \| '__/ _ \ / _ \| |/ /
  4. * | |_) | | | (_) | (_) | <
  5. * |_.__/|_| \___/ \___/|_|\_\
  6. *
  7. * Microframework which helps to develop web Pascal applications.
  8. *
  9. * Copyright (c) 2012-2020 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; inline;
  47. protected
  48. class procedure CheckEncoding(AEncoding: TEncoding); static; inline;
  49. function GetHandle: Pointer; override;
  50. public
  51. { Creates an instance of @code(TBrookString).
  52. @param(AHandle[in] String handle.) }
  53. constructor Create(AHandle: Pointer); virtual;
  54. { Frees an instance of @code(TBrookString). }
  55. destructor Destroy; override;
  56. { Determines if the handle is freed on the class destruction. }
  57. property OwnsHandle: Boolean read FOwnsHandle write FOwnsHandle;
  58. { Write a string buffer to the string handle. All strings previously
  59. written are kept.
  60. @param(ASource[in] String buffer source to be written.)
  61. @param(ALength[in] Length of the string buffer being written.)
  62. @returns(Length of the written string buffer.) }
  63. function WriteBytes(const ASource: TBytes;
  64. ALength: NativeUInt): NativeUInt; virtual;
  65. { Writes a string to the string handle. All strings previously written
  66. are kept.
  67. @param(ASource[in] String to be written.)
  68. @param(AEncoding[in] Determines the encoding of the string being written.) }
  69. procedure Write(const ASource: string;
  70. AEncoding: TEncoding); overload; virtual;
  71. { Writes a string to the string handle. All strings previously written
  72. are kept.
  73. @param(ASource[in] String to be written.) }
  74. procedure Write(const ASource: string); overload; virtual;
  75. { Gets the string from the string handle. }
  76. function ToString: string; override;
  77. { Clears all the content present in the string handle. }
  78. procedure Clear; virtual;
  79. { Gets the content buffer from the string handle. }
  80. property Content: TBytes read GetContent;
  81. { Gets the content length from the string handle. }
  82. property Length: NativeUInt read GetLength;
  83. { Gets or sets a string from or to the string handle. }
  84. property Text: string read GetText write SetText;
  85. end;
  86. implementation
  87. constructor TBrookString.Create(AHandle: Pointer);
  88. begin
  89. inherited Create;
  90. FOwnsHandle := not Assigned(AHandle);
  91. if FOwnsHandle then
  92. begin
  93. SgLib.Check;
  94. FHandle := sg_str_new;
  95. end
  96. else
  97. FHandle := AHandle;
  98. end;
  99. destructor TBrookString.Destroy;
  100. begin
  101. try
  102. if FOwnsHandle then
  103. begin
  104. SgLib.Check;
  105. sg_str_free(FHandle);
  106. FHandle := nil;
  107. end;
  108. finally
  109. inherited Destroy;
  110. end;
  111. end;
  112. class procedure TBrookString.CheckEncoding(AEncoding: TEncoding);
  113. begin
  114. if not Assigned(AEncoding) then
  115. raise EArgumentNilException.CreateFmt(SParamIsNil, ['AEncoding']);
  116. end;
  117. function TBrookString.GetHandle: Pointer;
  118. begin
  119. Result := FHandle;
  120. end;
  121. function TBrookString.GetText: string;
  122. begin
  123. Result :=
  124. {$IFDEF FPC}string({$ENDIF}TEncoding.UTF8.GetString(GetContent){$IFDEF FPC}){$ENDIF};
  125. end;
  126. function TBrookString.WriteBytes(const ASource: TBytes;
  127. ALength: NativeUInt): NativeUInt;
  128. begin
  129. SgLib.Check;
  130. Result := ALength;
  131. SgLib.CheckLastError(sg_str_write(FHandle, @ASource[0], Result));
  132. end;
  133. procedure TBrookString.Write(const ASource: string; AEncoding: TEncoding);
  134. var
  135. VBytes: TBytes;
  136. begin
  137. CheckEncoding(AEncoding);
  138. VBytes := AEncoding.GetBytes(
  139. {$IFDEF FPC}UnicodeString({$ENDIF}ASource{$IFDEF FPC}){$ENDIF});
  140. WriteBytes(VBytes, System.Length(VBytes));
  141. end;
  142. procedure TBrookString.Write(const ASource: string);
  143. begin
  144. Write(ASource, TEncoding.UTF8);
  145. end;
  146. procedure TBrookString.Clear;
  147. begin
  148. SgLib.Check;
  149. SgLib.CheckLastError(sg_str_clear(FHandle));
  150. end;
  151. function TBrookString.GetLength: NativeUInt;
  152. begin
  153. SgLib.Check;
  154. Result := sg_str_length(FHandle);
  155. end;
  156. procedure TBrookString.SetText(const AValue: string);
  157. begin
  158. Clear;
  159. Write(AValue);
  160. end;
  161. function TBrookString.GetContent: TBytes;
  162. begin
  163. SgLib.Check;
  164. Result := TMarshal.ToBytes(sg_str_content(FHandle), GetLength);
  165. end;
  166. function TBrookString.ToString: string;
  167. begin
  168. Result := GetText;
  169. end;
  170. end.