blob: cb62603dbf06f96ac4a3a8851c9fb09795cc6a20 [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}
Jens Geyera019cda2019-11-09 23:24:52 +010031 Thrift.Configuration,
Roger Meier2b2c0b22012-09-12 20:09:02 +000032 Thrift.Protocol,
33 Thrift.Transport,
34 Thrift.Stream;
35
36
37type
38 // Generic utility for easily serializing objects into a byte array or Stream.
39 TSerializer = class
Jens Geyerfad7fd32019-11-09 23:24:52 +010040 strict private
Roger Meier2b2c0b22012-09-12 20:09:02 +000041 FStream : TMemoryStream;
42 FTransport : ITransport;
43 FProtocol : IProtocol;
44
45 public
Jens Geyera019cda2019-11-09 23:24:52 +010046 constructor Create( const aProtFact : IProtocolFactory = nil; // defaults to TBinaryProtocol
47 const aTransFact : ITransportFactory = nil;
48 const aConfig : IThriftConfiguration = nil);
Jens Geyered994552019-11-09 23:24:52 +010049
Roger Meier2b2c0b22012-09-12 20:09:02 +000050 // DTOR
51 destructor Destroy; override;
52
53 // Serialize the Thrift object.
54 function Serialize( const input : IBase) : TBytes; overload;
55 procedure Serialize( const input : IBase; const aStm : TStream); overload;
56 end;
57
58
59 // Generic utility for easily deserializing objects from byte array or Stream.
60 TDeserializer = class
Jens Geyerfad7fd32019-11-09 23:24:52 +010061 strict private
Roger Meier2b2c0b22012-09-12 20:09:02 +000062 FStream : TMemoryStream;
63 FTransport : ITransport;
64 FProtocol : IProtocol;
65
66 public
Jens Geyera019cda2019-11-09 23:24:52 +010067 constructor Create( const aProtFact : IProtocolFactory = nil; // defaults to TBinaryProtocol
68 const aTransFact : ITransportFactory = nil;
69 const aConfig : IThriftConfiguration = nil);
Jens Geyered994552019-11-09 23:24:52 +010070
Roger Meier2b2c0b22012-09-12 20:09:02 +000071 // DTOR
72 destructor Destroy; override;
73
74 // Deserialize the Thrift object data.
75 procedure Deserialize( const input : TBytes; const target : IBase); overload;
76 procedure Deserialize( const input : TStream; const target : IBase); overload;
77 end;
78
79
80
81implementation
82
83
84{ TSerializer }
85
86
Jens Geyera019cda2019-11-09 23:24:52 +010087constructor TSerializer.Create( const aProtFact : IProtocolFactory;
88 const aTransFact : ITransportFactory;
89 const aConfig : IThriftConfiguration);
Roger Meier2b2c0b22012-09-12 20:09:02 +000090var adapter : IThriftStream;
Jens Geyera019cda2019-11-09 23:24:52 +010091 protfact : IProtocolFactory;
Roger Meier2b2c0b22012-09-12 20:09:02 +000092begin
93 inherited Create;
Jens Geyera019cda2019-11-09 23:24:52 +010094
Roger Meier2b2c0b22012-09-12 20:09:02 +000095 FStream := TMemoryStream.Create;
96 adapter := TThriftStreamAdapterDelphi.Create( FStream, FALSE);
Jens Geyera019cda2019-11-09 23:24:52 +010097
98 FTransport := TStreamTransportImpl.Create( nil, adapter, aConfig);
99 if aTransfact <> nil then FTransport := aTransfact.GetTransport( FTransport);
100
101 if aProtFact <> nil
102 then protfact := aProtFact
103 else protfact := TBinaryProtocolImpl.TFactory.Create;
104 FProtocol := protfact.GetProtocol( FTransport);
Jens Geyered994552019-11-09 23:24:52 +0100105
106 if not FTransport.IsOpen
107 then FTransport.Open;
Roger Meier2b2c0b22012-09-12 20:09:02 +0000108end;
109
110
111destructor TSerializer.Destroy;
112begin
113 try
114 FProtocol := nil;
115 FTransport := nil;
116 FreeAndNil( FStream);
117 finally
118 inherited Destroy;
119 end;
120end;
121
122
123function TSerializer.Serialize( const input : IBase) : TBytes;
124// Serialize the Thrift object into a byte array. The process is simple,
125// just clear the byte array output, write the object into it, and grab the
126// raw bytes.
127var iBytes : Int64;
128begin
129 try
130 FStream.Size := 0;
131 input.Write( FProtocol);
Jens Geyered994552019-11-09 23:24:52 +0100132 FTransport.Flush;
133
Roger Meier2b2c0b22012-09-12 20:09:02 +0000134 SetLength( result, FStream.Size);
135 iBytes := Length(result);
136 if iBytes > 0
137 then Move( FStream.Memory^, result[0], iBytes);
138 finally
139 FStream.Size := 0; // free any allocated memory
140 end;
141end;
142
143
144procedure TSerializer.Serialize( const input : IBase; const aStm : TStream);
145// Serialize the Thrift object into a byte array. The process is simple,
146// just clear the byte array output, write the object into it, and grab the
Jens Geyerd5436f52014-10-03 19:50:38 +0200147// raw bytes.
Roger Meier2b2c0b22012-09-12 20:09:02 +0000148const COPY_ENTIRE_STREAM = 0;
149begin
150 try
151 FStream.Size := 0;
152 input.Write( FProtocol);
Jens Geyered994552019-11-09 23:24:52 +0100153 FTransport.Flush;
154
Roger Meier2b2c0b22012-09-12 20:09:02 +0000155 aStm.CopyFrom( FStream, COPY_ENTIRE_STREAM);
156 finally
157 FStream.Size := 0; // free any allocated memory
158 end;
159end;
160
161
162{ TDeserializer }
163
164
Jens Geyera019cda2019-11-09 23:24:52 +0100165constructor TDeserializer.Create( const aProtFact : IProtocolFactory;
166 const aTransFact : ITransportFactory;
167 const aConfig : IThriftConfiguration);
Roger Meier2b2c0b22012-09-12 20:09:02 +0000168var adapter : IThriftStream;
Jens Geyera019cda2019-11-09 23:24:52 +0100169 protfact : IProtocolFactory;
Roger Meier2b2c0b22012-09-12 20:09:02 +0000170begin
171 inherited Create;
Jens Geyera019cda2019-11-09 23:24:52 +0100172
Roger Meier2b2c0b22012-09-12 20:09:02 +0000173 FStream := TMemoryStream.Create;
174 adapter := TThriftStreamAdapterDelphi.Create( FStream, FALSE);
Jens Geyera019cda2019-11-09 23:24:52 +0100175
176 FTransport := TStreamTransportImpl.Create( adapter, nil, aConfig);
177 if aTransfact <> nil then FTransport := aTransfact.GetTransport( FTransport);
178
179 if aProtFact <> nil
180 then protfact := aProtFact
181 else protfact := TBinaryProtocolImpl.TFactory.Create;
182 FProtocol := protfact.GetProtocol( FTransport);
Jens Geyered994552019-11-09 23:24:52 +0100183
184 if not FTransport.IsOpen
185 then FTransport.Open;
Roger Meier2b2c0b22012-09-12 20:09:02 +0000186end;
187
188
189destructor TDeserializer.Destroy;
190begin
191 try
192 FProtocol := nil;
193 FTransport := nil;
194 FreeAndNil( FStream);
195 finally
196 inherited Destroy;
197 end;
198end;
199
200
201procedure TDeserializer.Deserialize( const input : TBytes; const target : IBase);
202// Deserialize the Thrift object data from the byte array.
203var iBytes : Int64;
204begin
205 try
206 iBytes := Length(input);
207 FStream.Size := iBytes;
208 if iBytes > 0
209 then Move( input[0], FStream.Memory^, iBytes);
210
211 target.Read( FProtocol);
212 finally
213 FStream.Size := 0; // free any allocated memory
214 end;
215end;
216
217
218procedure TDeserializer.Deserialize( const input : TStream; const target : IBase);
219// Deserialize the Thrift object data from the byte array.
220const COPY_ENTIRE_STREAM = 0;
221var before : Int64;
222begin
223 try
224 before := FStream.Position;
225 FStream.CopyFrom( input, COPY_ENTIRE_STREAM);
226 FStream.Position := before;
227 target.Read( FProtocol);
228 finally
229 FStream.Size := 0; // free any allocated memory
230 end;
231end;
232
233
234end.
235