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