blob: 1cbcbec5ff3c8249c9c57e521f6e28510da2b2d5 [file] [log] [blame]
Roger Meier2b2c0b22012-09-12 20:09:02 +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 *)
19unit Thrift.Serializer;
20
Jens Geyer9f7f11e2016-04-14 21:37:11 +020021{$I Thrift.Defines.inc}
Nick4f5229e2016-04-14 16:43:22 +030022
Roger Meier2b2c0b22012-09-12 20:09:02 +000023interface
24
25uses
Jens Geyer9f7f11e2016-04-14 21:37:11 +020026 {$IFDEF OLD_UNIT_NAMES}
27 Classes, Windows, SysUtils,
Nick4f5229e2016-04-14 16:43:22 +030028 {$ELSE}
Jens Geyer9f7f11e2016-04-14 21:37:11 +020029 System.Classes, Winapi.Windows, System.SysUtils,
30 {$ENDIF}
Roger Meier2b2c0b22012-09-12 20:09:02 +000031 Thrift.Protocol,
32 Thrift.Transport,
33 Thrift.Stream;
34
35
36type
37 // Generic utility for easily serializing objects into a byte array or Stream.
38 TSerializer = class
Jens Geyerfad7fd32019-11-09 23:24:52 +010039 strict private
Roger Meier2b2c0b22012-09-12 20:09:02 +000040 FStream : TMemoryStream;
41 FTransport : ITransport;
42 FProtocol : IProtocol;
43
44 public
45 // Create a new TSerializer that uses the TBinaryProtocol by default.
46 constructor Create; overload;
47
48 // Create a new TSerializer.
49 // It will use the TProtocol specified by the factory that is passed in.
50 constructor Create( const factory : IProtocolFactory); overload;
51
Jens Geyered994552019-11-09 23:24:52 +010052 // Create a new TSerializer.
53 // It will use the TProtocol and layered transports specified by the factories that are passed in.
54 constructor Create( const protfact : IProtocolFactory; const transfact : ITransportFactory); overload;
55
Roger Meier2b2c0b22012-09-12 20:09:02 +000056 // DTOR
57 destructor Destroy; override;
58
59 // Serialize the Thrift object.
60 function Serialize( const input : IBase) : TBytes; overload;
61 procedure Serialize( const input : IBase; const aStm : TStream); overload;
62 end;
63
64
65 // Generic utility for easily deserializing objects from byte array or Stream.
66 TDeserializer = class
Jens Geyerfad7fd32019-11-09 23:24:52 +010067 strict private
Roger Meier2b2c0b22012-09-12 20:09:02 +000068 FStream : TMemoryStream;
69 FTransport : ITransport;
70 FProtocol : IProtocol;
71
72 public
73 // Create a new TDeserializer that uses the TBinaryProtocol by default.
Jens Geyer41f47af2019-11-09 23:24:52 +010074 constructor Create( const aMaxMessageSize : Integer = DEFAULT_MAX_MESSAGE_SIZE); overload;
Roger Meier2b2c0b22012-09-12 20:09:02 +000075
76 // Create a new TDeserializer.
77 // It will use the TProtocol specified by the factory that is passed in.
Jens Geyer41f47af2019-11-09 23:24:52 +010078 constructor Create( const factory : IProtocolFactory;
79 const aMaxMessageSize : Integer = DEFAULT_MAX_MESSAGE_SIZE); overload;
Roger Meier2b2c0b22012-09-12 20:09:02 +000080
Jens Geyered994552019-11-09 23:24:52 +010081 // Create a new TDeserializer.
82 // It will use the TProtocol and layered transports specified by the factories that are passed in.
Jens Geyer41f47af2019-11-09 23:24:52 +010083 constructor Create( const protfact : IProtocolFactory;
84 const transfact : ITransportFactory;
85 const aMaxMessageSize : Integer = DEFAULT_MAX_MESSAGE_SIZE); overload;
Jens Geyered994552019-11-09 23:24:52 +010086
Roger Meier2b2c0b22012-09-12 20:09:02 +000087 // DTOR
88 destructor Destroy; override;
89
90 // Deserialize the Thrift object data.
91 procedure Deserialize( const input : TBytes; const target : IBase); overload;
92 procedure Deserialize( const input : TStream; const target : IBase); overload;
93 end;
94
95
96
97implementation
98
99
100{ TSerializer }
101
102
Jens Geyered994552019-11-09 23:24:52 +0100103constructor TSerializer.Create;
Roger Meier2b2c0b22012-09-12 20:09:02 +0000104// Create a new TSerializer that uses the TBinaryProtocol by default.
105begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200106 //no inherited;
Jens Geyered994552019-11-09 23:24:52 +0100107 Create( TBinaryProtocolImpl.TFactory.Create, nil);
Roger Meier2b2c0b22012-09-12 20:09:02 +0000108end;
109
110
111constructor TSerializer.Create( const factory : IProtocolFactory);
112// Create a new TSerializer.
113// It will use the TProtocol specified by the factory that is passed in.
Jens Geyered994552019-11-09 23:24:52 +0100114begin
115 //no inherited;
116 Create( factory, nil);
117end;
118
119
120constructor TSerializer.Create( const protfact : IProtocolFactory; const transfact : ITransportFactory);
121// Create a new TSerializer.
122// It will use the TProtocol specified by the factory that is passed in.
Roger Meier2b2c0b22012-09-12 20:09:02 +0000123var adapter : IThriftStream;
124begin
125 inherited Create;
126 FStream := TMemoryStream.Create;
127 adapter := TThriftStreamAdapterDelphi.Create( FStream, FALSE);
Jens Geyer41f47af2019-11-09 23:24:52 +0100128 FTransport := TStreamTransportImpl.Create( nil, adapter, TTransportControlImpl.Create(0)); // we don't read anything here
Jens Geyered994552019-11-09 23:24:52 +0100129 if transfact <> nil then FTransport := transfact.GetTransport( FTransport);
130 FProtocol := protfact.GetProtocol( FTransport);
131
132 if not FTransport.IsOpen
133 then FTransport.Open;
Roger Meier2b2c0b22012-09-12 20:09:02 +0000134end;
135
136
137destructor TSerializer.Destroy;
138begin
139 try
140 FProtocol := nil;
141 FTransport := nil;
142 FreeAndNil( FStream);
143 finally
144 inherited Destroy;
145 end;
146end;
147
148
149function TSerializer.Serialize( const input : IBase) : TBytes;
150// Serialize the Thrift object into a byte array. The process is simple,
151// just clear the byte array output, write the object into it, and grab the
152// raw bytes.
153var iBytes : Int64;
154begin
155 try
156 FStream.Size := 0;
157 input.Write( FProtocol);
Jens Geyered994552019-11-09 23:24:52 +0100158 FTransport.Flush;
159
Roger Meier2b2c0b22012-09-12 20:09:02 +0000160 SetLength( result, FStream.Size);
161 iBytes := Length(result);
162 if iBytes > 0
163 then Move( FStream.Memory^, result[0], iBytes);
164 finally
165 FStream.Size := 0; // free any allocated memory
166 end;
167end;
168
169
170procedure TSerializer.Serialize( const input : IBase; const aStm : TStream);
171// Serialize the Thrift object into a byte array. The process is simple,
172// just clear the byte array output, write the object into it, and grab the
Jens Geyerd5436f52014-10-03 19:50:38 +0200173// raw bytes.
Roger Meier2b2c0b22012-09-12 20:09:02 +0000174const COPY_ENTIRE_STREAM = 0;
175begin
176 try
177 FStream.Size := 0;
178 input.Write( FProtocol);
Jens Geyered994552019-11-09 23:24:52 +0100179 FTransport.Flush;
180
Roger Meier2b2c0b22012-09-12 20:09:02 +0000181 aStm.CopyFrom( FStream, COPY_ENTIRE_STREAM);
182 finally
183 FStream.Size := 0; // free any allocated memory
184 end;
185end;
186
187
188{ TDeserializer }
189
190
Jens Geyer41f47af2019-11-09 23:24:52 +0100191constructor TDeserializer.Create( const aMaxMessageSize : Integer);
Roger Meier2b2c0b22012-09-12 20:09:02 +0000192// Create a new TDeserializer that uses the TBinaryProtocol by default.
193begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200194 //no inherited;
Jens Geyer41f47af2019-11-09 23:24:52 +0100195 Create( TBinaryProtocolImpl.TFactory.Create, nil, aMaxMessageSize);
Roger Meier2b2c0b22012-09-12 20:09:02 +0000196end;
197
198
Jens Geyer41f47af2019-11-09 23:24:52 +0100199constructor TDeserializer.Create( const factory : IProtocolFactory; const aMaxMessageSize : Integer);
Roger Meier2b2c0b22012-09-12 20:09:02 +0000200// Create a new TDeserializer.
201// It will use the TProtocol specified by the factory that is passed in.
Jens Geyered994552019-11-09 23:24:52 +0100202begin
203 //no inherited;
Jens Geyer41f47af2019-11-09 23:24:52 +0100204 Create( factory, nil, aMaxMessageSize);
Jens Geyered994552019-11-09 23:24:52 +0100205end;
206
207
Jens Geyer41f47af2019-11-09 23:24:52 +0100208constructor TDeserializer.Create( const protfact : IProtocolFactory;
209 const transfact : ITransportFactory;
210 const aMaxMessageSize : Integer = DEFAULT_MAX_MESSAGE_SIZE);
Jens Geyered994552019-11-09 23:24:52 +0100211// Create a new TDeserializer.
212// It will use the TProtocol specified by the factory that is passed in.
Roger Meier2b2c0b22012-09-12 20:09:02 +0000213var adapter : IThriftStream;
214begin
215 inherited Create;
216 FStream := TMemoryStream.Create;
217 adapter := TThriftStreamAdapterDelphi.Create( FStream, FALSE);
Jens Geyer41f47af2019-11-09 23:24:52 +0100218 FTransport := TStreamTransportImpl.Create( adapter, nil, TTransportControlImpl.Create(aMaxMessageSize));
Jens Geyered994552019-11-09 23:24:52 +0100219 if transfact <> nil then FTransport := transfact.GetTransport( FTransport);
220 FProtocol := protfact.GetProtocol( FTransport);
221
222 if not FTransport.IsOpen
223 then FTransport.Open;
Roger Meier2b2c0b22012-09-12 20:09:02 +0000224end;
225
226
227destructor TDeserializer.Destroy;
228begin
229 try
230 FProtocol := nil;
231 FTransport := nil;
232 FreeAndNil( FStream);
233 finally
234 inherited Destroy;
235 end;
236end;
237
238
239procedure TDeserializer.Deserialize( const input : TBytes; const target : IBase);
240// Deserialize the Thrift object data from the byte array.
241var iBytes : Int64;
242begin
243 try
244 iBytes := Length(input);
245 FStream.Size := iBytes;
246 if iBytes > 0
247 then Move( input[0], FStream.Memory^, iBytes);
248
249 target.Read( FProtocol);
250 finally
251 FStream.Size := 0; // free any allocated memory
252 end;
253end;
254
255
256procedure TDeserializer.Deserialize( const input : TStream; const target : IBase);
257// Deserialize the Thrift object data from the byte array.
258const COPY_ENTIRE_STREAM = 0;
259var before : Int64;
260begin
261 try
262 before := FStream.Position;
263 FStream.CopyFrom( input, COPY_ENTIRE_STREAM);
264 FStream.Position := before;
265 target.Read( FProtocol);
266 finally
267 FStream.Size := 0; // free any allocated memory
268 end;
269end;
270
271
272end.
273