blob: 7c448d8aa7eca37ff6b6ebe4bb95be8d68b9c918 [file] [log] [blame]
Jens Geyerd5436f52014-10-03 19:50:38 +02001(*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 *)
19
20unit Thrift.Stream;
21
Jens Geyer9f7f11e2016-04-14 21:37:11 +020022{$I Thrift.Defines.inc}
Nick4f5229e2016-04-14 16:43:22 +030023
Jens Geyerd5436f52014-10-03 19:50:38 +020024interface
25
26uses
27 Classes,
28 SysUtils,
29 SysConst,
30 RTLConsts,
Jens Geyer9f7f11e2016-04-14 21:37:11 +020031 {$IFDEF OLD_UNIT_NAMES}
32 ActiveX,
Nick4f5229e2016-04-14 16:43:22 +030033 {$ELSE}
Jens Geyer9f7f11e2016-04-14 21:37:11 +020034 Winapi.ActiveX,
35 {$ENDIF}
Nick4f5229e2016-04-14 16:43:22 +030036 Thrift.Utils;
Jens Geyerd5436f52014-10-03 19:50:38 +020037
38type
39
40 IThriftStream = interface
41 ['{732621B3-F697-4D76-A1B0-B4DD5A8E4018}']
42 procedure Write( const buffer: TBytes; offset: Integer; count: Integer);
43 function Read( var buffer: TBytes; offset: Integer; count: Integer): Integer;
44 procedure Open;
45 procedure Close;
46 procedure Flush;
47 function IsOpen: Boolean;
48 function ToArray: TBytes;
49 end;
50
51 TThriftStreamImpl = class( TInterfacedObject, IThriftStream)
52 private
53 procedure CheckSizeAndOffset( const buffer: TBytes; offset: Integer; count: Integer);
54 protected
55 procedure Write( const buffer: TBytes; offset: Integer; count: Integer); virtual;
56 function Read( var buffer: TBytes; offset: Integer; count: Integer): Integer; virtual;
57 procedure Open; virtual; abstract;
58 procedure Close; virtual; abstract;
59 procedure Flush; virtual; abstract;
60 function IsOpen: Boolean; virtual; abstract;
61 function ToArray: TBytes; virtual; abstract;
62 end;
63
64 TThriftStreamAdapterDelphi = class( TThriftStreamImpl )
65 private
66 FStream : TStream;
67 FOwnsStream : Boolean;
68 protected
69 procedure Write( const buffer: TBytes; offset: Integer; count: Integer); override;
70 function Read( var buffer: TBytes; offset: Integer; count: Integer): Integer; override;
71 procedure Open; override;
72 procedure Close; override;
73 procedure Flush; override;
74 function IsOpen: Boolean; override;
75 function ToArray: TBytes; override;
76 public
77 constructor Create( const AStream: TStream; AOwnsStream : Boolean);
78 destructor Destroy; override;
79 end;
80
81 TThriftStreamAdapterCOM = class( TThriftStreamImpl)
82 private
83 FStream : IStream;
84 protected
85 procedure Write( const buffer: TBytes; offset: Integer; count: Integer); override;
86 function Read( var buffer: TBytes; offset: Integer; count: Integer): Integer; override;
87 procedure Open; override;
88 procedure Close; override;
89 procedure Flush; override;
90 function IsOpen: Boolean; override;
91 function ToArray: TBytes; override;
92 public
93 constructor Create( const AStream: IStream);
94 end;
95
96implementation
97
98{ TThriftStreamAdapterCOM }
99
100procedure TThriftStreamAdapterCOM.Close;
101begin
102 FStream := nil;
103end;
104
105constructor TThriftStreamAdapterCOM.Create( const AStream: IStream);
106begin
107 inherited Create;
108 FStream := AStream;
109end;
110
111procedure TThriftStreamAdapterCOM.Flush;
112begin
Jens Geyer9f7f11e2016-04-14 21:37:11 +0200113 if IsOpen then begin
114 if FStream <> nil then begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200115 FStream.Commit( STGC_DEFAULT );
116 end;
117 end;
118end;
119
120function TThriftStreamAdapterCOM.IsOpen: Boolean;
121begin
122 Result := FStream <> nil;
123end;
124
125procedure TThriftStreamAdapterCOM.Open;
126begin
Jens Geyer9f7f11e2016-04-14 21:37:11 +0200127 // nothing to do
Jens Geyerd5436f52014-10-03 19:50:38 +0200128end;
129
130function TThriftStreamAdapterCOM.Read( var buffer: TBytes; offset: Integer; count: Integer): Integer;
131begin
132 inherited;
133 Result := 0;
Jens Geyer9f7f11e2016-04-14 21:37:11 +0200134 if FStream <> nil then begin
135 if count > 0 then begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200136 FStream.Read( @buffer[offset], count, @Result);
137 end;
138 end;
139end;
140
141function TThriftStreamAdapterCOM.ToArray: TBytes;
142var
143 statstg: TStatStg;
144 len : Integer;
Nick4f5229e2016-04-14 16:43:22 +0300145 NewPos : {$IF CompilerVersion >= 29.0} UInt64 {$ELSE} Int64 {$IFEND};
Jens Geyerd5436f52014-10-03 19:50:38 +0200146 cbRead : Integer;
147begin
148 FillChar( statstg, SizeOf( statstg), 0);
149 len := 0;
Jens Geyer9f7f11e2016-04-14 21:37:11 +0200150 if IsOpen then begin
151 if Succeeded( FStream.Stat( statstg, STATFLAG_NONAME )) then begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200152 len := statstg.cbSize;
153 end;
154 end;
155
156 SetLength( Result, len );
157
Jens Geyer9f7f11e2016-04-14 21:37:11 +0200158 if len > 0 then begin
159 if Succeeded( FStream.Seek( 0, STREAM_SEEK_SET, NewPos) ) then begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200160 FStream.Read( @Result[0], len, @cbRead);
161 end;
162 end;
163end;
164
165procedure TThriftStreamAdapterCOM.Write( const buffer: TBytes; offset: Integer; count: Integer);
Jens Geyer9f7f11e2016-04-14 21:37:11 +0200166var nWritten : Integer;
Jens Geyerd5436f52014-10-03 19:50:38 +0200167begin
168 inherited;
Jens Geyer9f7f11e2016-04-14 21:37:11 +0200169 if IsOpen then begin
170 if count > 0 then begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200171 FStream.Write( @buffer[0], count, @nWritten);
172 end;
173 end;
174end;
175
176{ TThriftStreamImpl }
177
178procedure TThriftStreamImpl.CheckSizeAndOffset(const buffer: TBytes; offset,
179 count: Integer);
180var
181 len : Integer;
182begin
Jens Geyer9f7f11e2016-04-14 21:37:11 +0200183 if count > 0 then begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200184 len := Length( buffer );
Jens Geyer9f7f11e2016-04-14 21:37:11 +0200185 if (offset < 0) or ( offset >= len) then begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200186 raise ERangeError.Create( SBitsIndexError );
187 end;
Jens Geyer9f7f11e2016-04-14 21:37:11 +0200188 if count > len then begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200189 raise ERangeError.Create( SBitsIndexError );
190 end;
191 end;
192end;
193
Jens Geyer9f7f11e2016-04-14 21:37:11 +0200194function TThriftStreamImpl.Read(var buffer: TBytes; offset, count: Integer): Integer;
Jens Geyerd5436f52014-10-03 19:50:38 +0200195begin
196 Result := 0;
197 CheckSizeAndOffset( buffer, offset, count );
198end;
199
200procedure TThriftStreamImpl.Write(const buffer: TBytes; offset, count: Integer);
201begin
202 CheckSizeAndOffset( buffer, offset, count );
203end;
204
205{ TThriftStreamAdapterDelphi }
206
207procedure TThriftStreamAdapterDelphi.Close;
208begin
209 FStream.Free;
210 FStream := nil;
211 FOwnsStream := False;
212end;
213
214constructor TThriftStreamAdapterDelphi.Create( const AStream: TStream; AOwnsStream: Boolean);
215begin
216 inherited Create;
217 FStream := AStream;
218 FOwnsStream := AOwnsStream;
219end;
220
221destructor TThriftStreamAdapterDelphi.Destroy;
222begin
Jens Geyer9f7f11e2016-04-14 21:37:11 +0200223 if FOwnsStream
224 then Close;
225
Jens Geyerd5436f52014-10-03 19:50:38 +0200226 inherited;
227end;
228
229procedure TThriftStreamAdapterDelphi.Flush;
230begin
Jens Geyer9f7f11e2016-04-14 21:37:11 +0200231 // nothing to do
Jens Geyerd5436f52014-10-03 19:50:38 +0200232end;
233
234function TThriftStreamAdapterDelphi.IsOpen: Boolean;
235begin
236 Result := FStream <> nil;
237end;
238
239procedure TThriftStreamAdapterDelphi.Open;
240begin
Jens Geyer9f7f11e2016-04-14 21:37:11 +0200241 // nothing to do
Jens Geyerd5436f52014-10-03 19:50:38 +0200242end;
243
244function TThriftStreamAdapterDelphi.Read(var buffer: TBytes; offset,
245 count: Integer): Integer;
246begin
247 inherited;
248 Result := 0;
Jens Geyer9f7f11e2016-04-14 21:37:11 +0200249 if count > 0 then begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200250 Result := FStream.Read( Pointer(@buffer[offset])^, count)
251 end;
252end;
253
254function TThriftStreamAdapterDelphi.ToArray: TBytes;
255var
256 OrgPos : Integer;
257 len : Integer;
258begin
259 len := 0;
260 if FStream <> nil then
261 begin
262 len := FStream.Size;
263 end;
264
265 SetLength( Result, len );
266
267 if len > 0 then
268 begin
269 OrgPos := FStream.Position;
270 try
271 FStream.Position := 0;
272 FStream.ReadBuffer( Pointer(@Result[0])^, len );
273 finally
274 FStream.Position := OrgPos;
275 end;
276 end
277end;
278
279procedure TThriftStreamAdapterDelphi.Write(const buffer: TBytes; offset,
280 count: Integer);
281begin
282 inherited;
Jens Geyer9f7f11e2016-04-14 21:37:11 +0200283 if count > 0 then begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200284 FStream.Write( Pointer(@buffer[offset])^, count)
285 end;
286end;
287
288end.