blob: d78afe61c1077e3c95e539b0291f25d043cc780a [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
Nick4f5229e2016-04-14 16:43:22 +030022{$IF CompilerVersion >= 23.0}
23 {$LEGACYIFEND ON}
24{$IFEND}
25
Jens Geyerd5436f52014-10-03 19:50:38 +020026interface
27
28uses
29 Classes,
30 SysUtils,
31 SysConst,
32 RTLConsts,
Nick4f5229e2016-04-14 16:43:22 +030033 {$IF CompilerVersion < 23.0}
34 ActiveX,
35 {$ELSE}
36 Winapi.ActiveX,
37 {$IFEND}
38 Thrift.Utils;
Jens Geyerd5436f52014-10-03 19:50:38 +020039
40type
41
42 IThriftStream = interface
43 ['{732621B3-F697-4D76-A1B0-B4DD5A8E4018}']
44 procedure Write( const buffer: TBytes; offset: Integer; count: Integer);
45 function Read( var buffer: TBytes; offset: Integer; count: Integer): Integer;
46 procedure Open;
47 procedure Close;
48 procedure Flush;
49 function IsOpen: Boolean;
50 function ToArray: TBytes;
51 end;
52
53 TThriftStreamImpl = class( TInterfacedObject, IThriftStream)
54 private
55 procedure CheckSizeAndOffset( const buffer: TBytes; offset: Integer; count: Integer);
56 protected
57 procedure Write( const buffer: TBytes; offset: Integer; count: Integer); virtual;
58 function Read( var buffer: TBytes; offset: Integer; count: Integer): Integer; virtual;
59 procedure Open; virtual; abstract;
60 procedure Close; virtual; abstract;
61 procedure Flush; virtual; abstract;
62 function IsOpen: Boolean; virtual; abstract;
63 function ToArray: TBytes; virtual; abstract;
64 end;
65
66 TThriftStreamAdapterDelphi = class( TThriftStreamImpl )
67 private
68 FStream : TStream;
69 FOwnsStream : Boolean;
70 protected
71 procedure Write( const buffer: TBytes; offset: Integer; count: Integer); override;
72 function Read( var buffer: TBytes; offset: Integer; count: Integer): Integer; override;
73 procedure Open; override;
74 procedure Close; override;
75 procedure Flush; override;
76 function IsOpen: Boolean; override;
77 function ToArray: TBytes; override;
78 public
79 constructor Create( const AStream: TStream; AOwnsStream : Boolean);
80 destructor Destroy; override;
81 end;
82
83 TThriftStreamAdapterCOM = class( TThriftStreamImpl)
84 private
85 FStream : IStream;
86 protected
87 procedure Write( const buffer: TBytes; offset: Integer; count: Integer); override;
88 function Read( var buffer: TBytes; offset: Integer; count: Integer): Integer; override;
89 procedure Open; override;
90 procedure Close; override;
91 procedure Flush; override;
92 function IsOpen: Boolean; override;
93 function ToArray: TBytes; override;
94 public
95 constructor Create( const AStream: IStream);
96 end;
97
98implementation
99
100{ TThriftStreamAdapterCOM }
101
102procedure TThriftStreamAdapterCOM.Close;
103begin
104 FStream := nil;
105end;
106
107constructor TThriftStreamAdapterCOM.Create( const AStream: IStream);
108begin
109 inherited Create;
110 FStream := AStream;
111end;
112
113procedure TThriftStreamAdapterCOM.Flush;
114begin
115 if IsOpen then
116 begin
117 if FStream <> nil then
118 begin
119 FStream.Commit( STGC_DEFAULT );
120 end;
121 end;
122end;
123
124function TThriftStreamAdapterCOM.IsOpen: Boolean;
125begin
126 Result := FStream <> nil;
127end;
128
129procedure TThriftStreamAdapterCOM.Open;
130begin
131
132end;
133
134function TThriftStreamAdapterCOM.Read( var buffer: TBytes; offset: Integer; count: Integer): Integer;
135begin
136 inherited;
137 Result := 0;
138 if FStream <> nil then
139 begin
140 if count > 0 then
141 begin
142 FStream.Read( @buffer[offset], count, @Result);
143 end;
144 end;
145end;
146
147function TThriftStreamAdapterCOM.ToArray: TBytes;
148var
149 statstg: TStatStg;
150 len : Integer;
Nick4f5229e2016-04-14 16:43:22 +0300151 NewPos : {$IF CompilerVersion >= 29.0} UInt64 {$ELSE} Int64 {$IFEND};
Jens Geyerd5436f52014-10-03 19:50:38 +0200152 cbRead : Integer;
153begin
154 FillChar( statstg, SizeOf( statstg), 0);
155 len := 0;
156 if IsOpen then
157 begin
158 if Succeeded( FStream.Stat( statstg, STATFLAG_NONAME )) then
159 begin
160 len := statstg.cbSize;
161 end;
162 end;
163
164 SetLength( Result, len );
165
166 if len > 0 then
167 begin
168 if Succeeded( FStream.Seek( 0, STREAM_SEEK_SET, NewPos) ) then
169 begin
170 FStream.Read( @Result[0], len, @cbRead);
171 end;
172 end;
173end;
174
175procedure TThriftStreamAdapterCOM.Write( const buffer: TBytes; offset: Integer; count: Integer);
176var
177 nWritten : Integer;
178begin
179 inherited;
180 if IsOpen then
181 begin
182 if count > 0 then
183 begin
184 FStream.Write( @buffer[0], count, @nWritten);
185 end;
186 end;
187end;
188
189{ TThriftStreamImpl }
190
191procedure TThriftStreamImpl.CheckSizeAndOffset(const buffer: TBytes; offset,
192 count: Integer);
193var
194 len : Integer;
195begin
196 if count > 0 then
197 begin
198 len := Length( buffer );
199 if (offset < 0) or ( offset >= len) then
200 begin
201 raise ERangeError.Create( SBitsIndexError );
202 end;
203 if count > len then
204 begin
205 raise ERangeError.Create( SBitsIndexError );
206 end;
207 end;
208end;
209
210function TThriftStreamImpl.Read(var buffer: TBytes; offset,
211 count: Integer): Integer;
212begin
213 Result := 0;
214 CheckSizeAndOffset( buffer, offset, count );
215end;
216
217procedure TThriftStreamImpl.Write(const buffer: TBytes; offset, count: Integer);
218begin
219 CheckSizeAndOffset( buffer, offset, count );
220end;
221
222{ TThriftStreamAdapterDelphi }
223
224procedure TThriftStreamAdapterDelphi.Close;
225begin
226 FStream.Free;
227 FStream := nil;
228 FOwnsStream := False;
229end;
230
231constructor TThriftStreamAdapterDelphi.Create( const AStream: TStream; AOwnsStream: Boolean);
232begin
233 inherited Create;
234 FStream := AStream;
235 FOwnsStream := AOwnsStream;
236end;
237
238destructor TThriftStreamAdapterDelphi.Destroy;
239begin
240 if FOwnsStream then
241 begin
242 FStream.Free;
243 end;
244 inherited;
245end;
246
247procedure TThriftStreamAdapterDelphi.Flush;
248begin
249
250end;
251
252function TThriftStreamAdapterDelphi.IsOpen: Boolean;
253begin
254 Result := FStream <> nil;
255end;
256
257procedure TThriftStreamAdapterDelphi.Open;
258begin
259
260end;
261
262function TThriftStreamAdapterDelphi.Read(var buffer: TBytes; offset,
263 count: Integer): Integer;
264begin
265 inherited;
266 Result := 0;
267 if count > 0 then
268 begin
269 Result := FStream.Read( Pointer(@buffer[offset])^, count)
270 end;
271end;
272
273function TThriftStreamAdapterDelphi.ToArray: TBytes;
274var
275 OrgPos : Integer;
276 len : Integer;
277begin
278 len := 0;
279 if FStream <> nil then
280 begin
281 len := FStream.Size;
282 end;
283
284 SetLength( Result, len );
285
286 if len > 0 then
287 begin
288 OrgPos := FStream.Position;
289 try
290 FStream.Position := 0;
291 FStream.ReadBuffer( Pointer(@Result[0])^, len );
292 finally
293 FStream.Position := OrgPos;
294 end;
295 end
296end;
297
298procedure TThriftStreamAdapterDelphi.Write(const buffer: TBytes; offset,
299 count: Integer);
300begin
301 inherited;
302 if count > 0 then
303 begin
304 FStream.Write( Pointer(@buffer[offset])^, count)
305 end;
306end;
307
308end.