blob: b95cf61daa1bce7017ce47e710679548791c5720 [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.
74 constructor Create; overload;
75
76 // Create a new TDeserializer.
77 // It will use the TProtocol specified by the factory that is passed in.
78 constructor Create( const factory : IProtocolFactory); overload;
79
Jens Geyered994552019-11-09 23:24:52 +010080 // Create a new TDeserializer.
81 // It will use the TProtocol and layered transports specified by the factories that are passed in.
82 constructor Create( const protfact : IProtocolFactory; const transfact : ITransportFactory); overload;
83
Roger Meier2b2c0b22012-09-12 20:09:02 +000084 // DTOR
85 destructor Destroy; override;
86
87 // Deserialize the Thrift object data.
88 procedure Deserialize( const input : TBytes; const target : IBase); overload;
89 procedure Deserialize( const input : TStream; const target : IBase); overload;
90 end;
91
92
93
94implementation
95
96
97{ TSerializer }
98
99
Jens Geyered994552019-11-09 23:24:52 +0100100constructor TSerializer.Create;
Roger Meier2b2c0b22012-09-12 20:09:02 +0000101// Create a new TSerializer that uses the TBinaryProtocol by default.
102begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200103 //no inherited;
Jens Geyered994552019-11-09 23:24:52 +0100104 Create( TBinaryProtocolImpl.TFactory.Create, nil);
Roger Meier2b2c0b22012-09-12 20:09:02 +0000105end;
106
107
108constructor TSerializer.Create( const factory : IProtocolFactory);
109// Create a new TSerializer.
110// It will use the TProtocol specified by the factory that is passed in.
Jens Geyered994552019-11-09 23:24:52 +0100111begin
112 //no inherited;
113 Create( factory, nil);
114end;
115
116
117constructor TSerializer.Create( const protfact : IProtocolFactory; const transfact : ITransportFactory);
118// Create a new TSerializer.
119// It will use the TProtocol specified by the factory that is passed in.
Roger Meier2b2c0b22012-09-12 20:09:02 +0000120var adapter : IThriftStream;
121begin
122 inherited Create;
123 FStream := TMemoryStream.Create;
124 adapter := TThriftStreamAdapterDelphi.Create( FStream, FALSE);
125 FTransport := TStreamTransportImpl.Create( nil, adapter);
Jens Geyered994552019-11-09 23:24:52 +0100126 if transfact <> nil then FTransport := transfact.GetTransport( FTransport);
127 FProtocol := protfact.GetProtocol( FTransport);
128
129 if not FTransport.IsOpen
130 then FTransport.Open;
Roger Meier2b2c0b22012-09-12 20:09:02 +0000131end;
132
133
134destructor TSerializer.Destroy;
135begin
136 try
137 FProtocol := nil;
138 FTransport := nil;
139 FreeAndNil( FStream);
140 finally
141 inherited Destroy;
142 end;
143end;
144
145
146function TSerializer.Serialize( const input : IBase) : TBytes;
147// Serialize the Thrift object into a byte array. The process is simple,
148// just clear the byte array output, write the object into it, and grab the
149// raw bytes.
150var iBytes : Int64;
151begin
152 try
153 FStream.Size := 0;
154 input.Write( FProtocol);
Jens Geyered994552019-11-09 23:24:52 +0100155 FTransport.Flush;
156
Roger Meier2b2c0b22012-09-12 20:09:02 +0000157 SetLength( result, FStream.Size);
158 iBytes := Length(result);
159 if iBytes > 0
160 then Move( FStream.Memory^, result[0], iBytes);
161 finally
162 FStream.Size := 0; // free any allocated memory
163 end;
164end;
165
166
167procedure TSerializer.Serialize( const input : IBase; const aStm : TStream);
168// Serialize the Thrift object into a byte array. The process is simple,
169// just clear the byte array output, write the object into it, and grab the
Jens Geyerd5436f52014-10-03 19:50:38 +0200170// raw bytes.
Roger Meier2b2c0b22012-09-12 20:09:02 +0000171const COPY_ENTIRE_STREAM = 0;
172begin
173 try
174 FStream.Size := 0;
175 input.Write( FProtocol);
Jens Geyered994552019-11-09 23:24:52 +0100176 FTransport.Flush;
177
Roger Meier2b2c0b22012-09-12 20:09:02 +0000178 aStm.CopyFrom( FStream, COPY_ENTIRE_STREAM);
179 finally
180 FStream.Size := 0; // free any allocated memory
181 end;
182end;
183
184
185{ TDeserializer }
186
187
Jens Geyered994552019-11-09 23:24:52 +0100188constructor TDeserializer.Create;
Roger Meier2b2c0b22012-09-12 20:09:02 +0000189// Create a new TDeserializer that uses the TBinaryProtocol by default.
190begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200191 //no inherited;
Jens Geyered994552019-11-09 23:24:52 +0100192 Create( TBinaryProtocolImpl.TFactory.Create, nil);
Roger Meier2b2c0b22012-09-12 20:09:02 +0000193end;
194
195
196constructor TDeserializer.Create( const factory : IProtocolFactory);
197// Create a new TDeserializer.
198// It will use the TProtocol specified by the factory that is passed in.
Jens Geyered994552019-11-09 23:24:52 +0100199begin
200 //no inherited;
201 Create( factory, nil);
202end;
203
204
205constructor TDeserializer.Create( const protfact : IProtocolFactory; const transfact : ITransportFactory);
206// Create a new TDeserializer.
207// It will use the TProtocol specified by the factory that is passed in.
Roger Meier2b2c0b22012-09-12 20:09:02 +0000208var adapter : IThriftStream;
209begin
210 inherited Create;
211 FStream := TMemoryStream.Create;
212 adapter := TThriftStreamAdapterDelphi.Create( FStream, FALSE);
213 FTransport := TStreamTransportImpl.Create( adapter, nil);
Jens Geyered994552019-11-09 23:24:52 +0100214 if transfact <> nil then FTransport := transfact.GetTransport( FTransport);
215 FProtocol := protfact.GetProtocol( FTransport);
216
217 if not FTransport.IsOpen
218 then FTransport.Open;
Roger Meier2b2c0b22012-09-12 20:09:02 +0000219end;
220
221
222destructor TDeserializer.Destroy;
223begin
224 try
225 FProtocol := nil;
226 FTransport := nil;
227 FreeAndNil( FStream);
228 finally
229 inherited Destroy;
230 end;
231end;
232
233
234procedure TDeserializer.Deserialize( const input : TBytes; const target : IBase);
235// Deserialize the Thrift object data from the byte array.
236var iBytes : Int64;
237begin
238 try
239 iBytes := Length(input);
240 FStream.Size := iBytes;
241 if iBytes > 0
242 then Move( input[0], FStream.Memory^, iBytes);
243
244 target.Read( FProtocol);
245 finally
246 FStream.Size := 0; // free any allocated memory
247 end;
248end;
249
250
251procedure TDeserializer.Deserialize( const input : TStream; const target : IBase);
252// Deserialize the Thrift object data from the byte array.
253const COPY_ENTIRE_STREAM = 0;
254var before : Int64;
255begin
256 try
257 before := FStream.Position;
258 FStream.CopyFrom( input, COPY_ENTIRE_STREAM);
259 FStream.Position := before;
260 target.Read( FProtocol);
261 finally
262 FStream.Size := 0; // free any allocated memory
263 end;
264end;
265
266
267end.
268