blob: 7f5b829ec51a0542019f8a9141ad08fad17abe3b [file] [log] [blame]
Jens Geyered994552019-11-09 23:24:52 +01001unit TestSerializer.Tests;
2(*
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *)
20
21interface
22
23uses
24 Classes,
25 Windows,
26 SysUtils,
27 Generics.Collections,
28 Thrift,
29 Thrift.Exception,
30 Thrift.Socket,
31 Thrift.Transport,
32 Thrift.Protocol,
33 Thrift.Protocol.JSON,
34 Thrift.Protocol.Compact,
35 Thrift.Collections,
Jens Geyera019cda2019-11-09 23:24:52 +010036 Thrift.Configuration,
Jens Geyered994552019-11-09 23:24:52 +010037 Thrift.Server,
38 Thrift.Utils,
39 Thrift.Serializer,
40 Thrift.Stream,
41 Thrift.WinHTTP,
42 Thrift.TypeRegistry,
43 System_,
Jens Geyere9f63e02024-11-23 01:01:13 +010044 test.ExceptionStruct,
45 test.SimpleException,
Jens Geyer07f4bb52022-09-03 14:50:06 +020046 DebugProtoTest;
Jens Geyered994552019-11-09 23:24:52 +010047
Jens Geyer62445c12022-06-29 00:00:00 +020048{$TYPEINFO ON}
Jens Geyered994552019-11-09 23:24:52 +010049
50type
51 TFactoryPair = record
Jens Geyer3e6be732025-06-04 22:31:55 +020052 proto : IProtocolFactory;
Jens Geyered994552019-11-09 23:24:52 +010053 trans : ITransportFactory;
54 end;
55
56 TTestSerializer = class //extends TestCase {
57 private type
58 TMethod = (
59 mt_Bytes,
60 mt_Stream
61 );
62
Jens Geyer07f4bb52022-09-03 14:50:06 +020063 strict private
Jens Geyered994552019-11-09 23:24:52 +010064 FProtocols : TList< TFactoryPair>;
65 procedure AddFactoryCombination( const aProto : IProtocolFactory; const aTrans : ITransportFactory);
66 class function UserFriendlyName( const factory : TFactoryPair) : string; overload;
67 class function UserFriendlyName( const method : TMethod) : string; overload;
68
69 class function Serialize(const input : IBase; const factory : TFactoryPair) : TBytes; overload;
70 class procedure Serialize(const input : IBase; const factory : TFactoryPair; const aStream : TStream); overload;
71
72 class procedure Deserialize( const input : TBytes; const target : IBase; const factory : TFactoryPair); overload;
73 class procedure Deserialize( const input : TStream; const target : IBase; const factory : TFactoryPair); overload;
74
Jens Geyer3e6be732025-06-04 22:31:55 +020075 class procedure Deserialize( const input : TBytes; out target : TGuid; const factory : TFactoryPair); overload;
76
77 class procedure ValidateReadToEnd( const serial : TDeserializer); overload;
Jens Geyer41f47af2019-11-09 23:24:52 +010078
Jens Geyer07f4bb52022-09-03 14:50:06 +020079 class function LengthOf( const bytes : TBytes) : Integer; overload; inline;
80 class function LengthOf( const bytes : IThriftBytes) : Integer; overload; inline;
81
82 class function DataPtrOf( const bytes : TBytes) : Pointer; overload; inline;
83 class function DataPtrOf( const bytes : IThriftBytes) : Pointer; overload; inline;
84
Jens Geyered994552019-11-09 23:24:52 +010085 procedure Test_Serializer_Deserializer;
Jens Geyer07f4bb52022-09-03 14:50:06 +020086 procedure Test_COM_Types;
Jens Geyer16819262024-03-07 23:01:20 +010087 procedure Test_ThriftBytesCTORs;
Jens Geyere9f63e02024-11-23 01:01:13 +010088
89 procedure Test_OneOfEach( const method : TMethod; const factory : TFactoryPair; const stream : TFileStream);
90 procedure Test_CompactStruct( const method : TMethod; const factory : TFactoryPair; const stream : TFileStream);
91 procedure Test_ExceptionStruct( const method : TMethod; const factory : TFactoryPair; const stream : TFileStream);
92 procedure Test_SimpleException( const method : TMethod; const factory : TFactoryPair; const stream : TFileStream);
Jens Geyered994552019-11-09 23:24:52 +010093
Jens Geyer3e6be732025-06-04 22:31:55 +020094 procedure Test_ProtocolConformity( const factory : TFactoryPair; const stream : TFileStream);
95 procedure Test_UuidDeserialization( const factory : TFactoryPair; const stream : TFileStream);
96
Jens Geyered994552019-11-09 23:24:52 +010097 public
98 constructor Create;
99 destructor Destroy; override;
100
101 procedure RunTests;
102 end;
103
104
105implementation
106
Jens Geyer07f4bb52022-09-03 14:50:06 +0200107const SERIALIZERDATA_DLL = 'SerializerData.dll';
108function CreateOneOfEach : IOneOfEach; stdcall; external SERIALIZERDATA_DLL;
109function CreateNesting : INesting; stdcall; external SERIALIZERDATA_DLL;
110function CreateHolyMoley : IHolyMoley; stdcall; external SERIALIZERDATA_DLL;
111function CreateCompactProtoTestStruct : ICompactProtoTestStruct; stdcall; external SERIALIZERDATA_DLL;
Jens Geyere9f63e02024-11-23 01:01:13 +0100112function CreateBatchGetResponse : IBatchGetResponse; stdcall; external SERIALIZERDATA_DLL;
113function CreateSimpleException : IError; stdcall; external SERIALIZERDATA_DLL;
Jens Geyer07f4bb52022-09-03 14:50:06 +0200114
Jens Geyered994552019-11-09 23:24:52 +0100115
116{ TTestSerializer }
117
118constructor TTestSerializer.Create;
119begin
120 inherited Create;
121 FProtocols := TList< TFactoryPair>.Create;
122
123 AddFactoryCombination( TBinaryProtocolImpl.TFactory.Create, nil);
124 AddFactoryCombination( TCompactProtocolImpl.TFactory.Create, nil);
125 AddFactoryCombination( TJSONProtocolImpl.TFactory.Create, nil);
126
127 AddFactoryCombination( TBinaryProtocolImpl.TFactory.Create, TFramedTransportImpl.TFactory.Create);
128 AddFactoryCombination( TCompactProtocolImpl.TFactory.Create, TFramedTransportImpl.TFactory.Create);
129 AddFactoryCombination( TJSONProtocolImpl.TFactory.Create, TFramedTransportImpl.TFactory.Create);
130
131 AddFactoryCombination( TBinaryProtocolImpl.TFactory.Create, TBufferedTransportImpl.TFactory.Create);
132 AddFactoryCombination( TCompactProtocolImpl.TFactory.Create, TBufferedTransportImpl.TFactory.Create);
133 AddFactoryCombination( TJSONProtocolImpl.TFactory.Create, TBufferedTransportImpl.TFactory.Create);
134end;
135
136
137destructor TTestSerializer.Destroy;
138begin
139 try
140 FreeAndNil( FProtocols);
141 finally
142 inherited Destroy;
143 end;
144end;
145
146
147procedure TTestSerializer.AddFactoryCombination( const aProto : IProtocolFactory; const aTrans : ITransportFactory);
148var rec : TFactoryPair;
149begin
Jens Geyer3e6be732025-06-04 22:31:55 +0200150 rec.proto := aProto;
Jens Geyered994552019-11-09 23:24:52 +0100151 rec.trans := aTrans;
152 FProtocols.Add( rec);
153end;
154
155
Jens Geyer07f4bb52022-09-03 14:50:06 +0200156class function TTestSerializer.LengthOf( const bytes : TBytes) : Integer;
157begin
158 result := Length(bytes);
159end;
160
161
162class function TTestSerializer.LengthOf( const bytes : IThriftBytes) : Integer;
163begin
164 if bytes <> nil
165 then result := bytes.Count
166 else result := 0;
167end;
168
169
170class function TTestSerializer.DataPtrOf( const bytes : TBytes) : Pointer;
171begin
172 result := bytes;
173end;
174
175
176class function TTestSerializer.DataPtrOf( const bytes : IThriftBytes) : Pointer;
177begin
178 if bytes <> nil
179 then result := bytes.QueryRawDataPtr
180 else result := nil;
181end;
182
183
Jens Geyer3e6be732025-06-04 22:31:55 +0200184procedure TTestSerializer.Test_ProtocolConformity( const factory : TFactoryPair; const stream : TFileStream);
185begin
186 Test_UuidDeserialization( factory, stream);
187 // add more tests here
188end;
189
190
191procedure TTestSerializer.Test_UuidDeserialization( const factory : TFactoryPair; const stream : TFileStream);
192
193 function CreateGuidBytes : TBytes;
194 var obj : TObject;
195 i : Integer;
196 begin
197 obj := factory.proto as TObject;
198
199 if obj is TJSONProtocolImpl.TFactory then begin
200 result := TEncoding.UTF8.GetBytes('"00112233-4455-6677-8899-aabbccddeeff"');
201 Exit;
202 end;
203
204 if (obj is TBinaryProtocolImpl.TFactory)
205 or (obj is TCompactProtocolImpl.TFactory)
206 then begin
207 SetLength(result,16);
208 for i := 0 to Length(result)-1 do result[i] := (i * $10) + i;
209 Exit;
210 end;
211
212 raise Exception.Create('Unhandled case');
213 end;
214
215
216var tested, correct : TGuid;
217 bytes : TBytes;
218begin
219 // write
220 bytes := CreateGuidBytes();
221
222 // init + read
223 Deserialize( bytes, tested, factory);
224
225 // check
226 correct := TGuid.Create('{00112233-4455-6677-8899-aabbccddeeff}');
227 ASSERT( tested = correct);
228end;
229
230
Jens Geyered994552019-11-09 23:24:52 +0100231procedure TTestSerializer.Test_OneOfEach( const method : TMethod; const factory : TFactoryPair; const stream : TFileStream);
232var tested, correct : IOneOfEach;
233 bytes : TBytes;
234 i : Integer;
235begin
236 // write
Jens Geyer07f4bb52022-09-03 14:50:06 +0200237 tested := CreateOneOfEach;
Jens Geyered994552019-11-09 23:24:52 +0100238 case method of
239 mt_Bytes: bytes := Serialize( tested, factory);
240 mt_Stream: begin
241 stream.Size := 0;
242 Serialize( tested, factory, stream);
243 end
244 else
245 ASSERT( FALSE);
246 end;
247
248 // init + read
249 tested := TOneOfEachImpl.Create;
250 case method of
251 mt_Bytes: Deserialize( bytes, tested, factory);
252 mt_Stream: begin
253 stream.Position := 0;
254 Deserialize( stream, tested, factory);
255 end
256 else
257 ASSERT( FALSE);
258 end;
259
260 // check
Jens Geyer07f4bb52022-09-03 14:50:06 +0200261 correct := CreateOneOfEach;
Jens Geyered994552019-11-09 23:24:52 +0100262 ASSERT( tested.Im_true = correct.Im_true);
263 ASSERT( tested.Im_false = correct.Im_false);
264 ASSERT( tested.A_bite = correct.A_bite);
265 ASSERT( tested.Integer16 = correct.Integer16);
266 ASSERT( tested.Integer32 = correct.Integer32);
267 ASSERT( tested.Integer64 = correct.Integer64);
268 ASSERT( Abs( tested.Double_precision - correct.Double_precision) < 1E-12);
269 ASSERT( tested.Some_characters = correct.Some_characters);
270 ASSERT( tested.Zomg_unicode = correct.Zomg_unicode);
Jens Geyer62445c12022-06-29 00:00:00 +0200271 ASSERT( tested.Rfc4122_uuid = correct.Rfc4122_uuid);
Jens Geyered994552019-11-09 23:24:52 +0100272 ASSERT( tested.What_who = correct.What_who);
273
Jens Geyer07f4bb52022-09-03 14:50:06 +0200274 ASSERT( LengthOf(tested.Base64) = LengthOf(correct.Base64));
275 ASSERT( CompareMem( DataPtrOf(tested.Base64), DataPtrOf(correct.Base64), LengthOf(correct.Base64)));
Jens Geyered994552019-11-09 23:24:52 +0100276
277 ASSERT( tested.Byte_list.Count = correct.Byte_list.Count);
278 for i := 0 to tested.Byte_list.Count-1
279 do ASSERT( tested.Byte_list[i] = correct.Byte_list[i]);
280
281 ASSERT( tested.I16_list.Count = correct.I16_list.Count);
282 for i := 0 to tested.I16_list.Count-1
283 do ASSERT( tested.I16_list[i] = correct.I16_list[i]);
284
285 ASSERT( tested.I64_list.Count = correct.I64_list.Count);
286 for i := 0 to tested.I64_list.Count-1
287 do ASSERT( tested.I64_list[i] = correct.I64_list[i]);
288end;
289
290
291procedure TTestSerializer.Test_CompactStruct( const method : TMethod; const factory : TFactoryPair; const stream : TFileStream);
292var tested, correct : ICompactProtoTestStruct;
293 bytes : TBytes;
294begin
295 // write
Jens Geyer07f4bb52022-09-03 14:50:06 +0200296 tested := CreateCompactProtoTestStruct;
Jens Geyered994552019-11-09 23:24:52 +0100297 case method of
298 mt_Bytes: bytes := Serialize( tested, factory);
299 mt_Stream: begin
300 stream.Size := 0;
301 Serialize( tested, factory, stream);
302 end
303 else
304 ASSERT( FALSE);
305 end;
306
307 // init + read
308 correct := TCompactProtoTestStructImpl.Create;
309 case method of
310 mt_Bytes: Deserialize( bytes, tested, factory);
311 mt_Stream: begin
312 stream.Position := 0;
313 Deserialize( stream, tested, factory);
314 end
315 else
316 ASSERT( FALSE);
317 end;
318
319 // check
Jens Geyer07f4bb52022-09-03 14:50:06 +0200320 correct := CreateCompactProtoTestStruct;
Jens Geyered994552019-11-09 23:24:52 +0100321 ASSERT( correct.Field500 = tested.Field500);
322 ASSERT( correct.Field5000 = tested.Field5000);
323 ASSERT( correct.Field20000 = tested.Field20000);
324end;
325
326
Jens Geyere9f63e02024-11-23 01:01:13 +0100327procedure TTestSerializer.Test_ExceptionStruct( const method : TMethod; const factory : TFactoryPair; const stream : TFileStream);
328var tested, correct : IBatchGetResponse;
329 bytes : TBytes;
330 corrDP, testDP : TPair<WideString, IGetRequest>;
331 corrEP, testEP : TPair<WideString, ISomeException>;
332begin
333 // write
334 tested := CreateBatchGetResponse;
335 case method of
336 mt_Bytes: bytes := Serialize( tested, factory);
337 mt_Stream: begin
338 stream.Size := 0;
339 Serialize( tested, factory, stream);
340 end
341 else
342 ASSERT( FALSE);
343 end;
344
345 // init + read
346 correct := TBatchGetResponseImpl.Create;
347 case method of
348 mt_Bytes: Deserialize( bytes, tested, factory);
349 mt_Stream: begin
350 stream.Position := 0;
351 Deserialize( stream, tested, factory);
352 end
353 else
354 ASSERT( FALSE);
355 end;
356
357 // check
358 correct := CreateBatchGetResponse;
359
360 // rewrite the following test if not
361 ASSERT( tested.Responses.Count = 1);
362 ASSERT( correct.Responses.Count = tested.Responses.Count);
363 for corrDP in correct.Responses do begin
364 for testDP in tested.Responses do begin
365 ASSERT( corrDP.Key = testDP.Key);
366 ASSERT( corrDP.Value.Id = testDP.Value.Id);
367 ASSERT( corrDP.Value.Data.Count = testDP.Value.Data.Count);
368 end;
369 end;
370
371 // rewrite the following test if not
372 ASSERT( tested.Errors.Count = 1);
373 ASSERT( correct.Errors.Count = tested.Errors.Count);
374 for corrEP in correct.Errors do begin
375 for testEP in tested.Errors do begin
376 ASSERT( corrEP.Key = testEP.Key);
377 ASSERT( corrEP.Value.Error = testEP.Value.Error);
378 end;
379 end;
380end;
381
382
383procedure TTestSerializer.Test_SimpleException( const method : TMethod; const factory : TFactoryPair; const stream : TFileStream);
384var tested, correct : IError;
385 bytes : TBytes;
386begin
387 // write
388 tested := CreateSimpleException;
389 case method of
390 mt_Bytes: bytes := Serialize( tested, factory);
391 mt_Stream: begin
392 stream.Size := 0;
393 Serialize( tested, factory, stream);
394 end
395 else
396 ASSERT( FALSE);
397 end;
398
399 // init + read
400 correct := TErrorImpl.Create;
401 case method of
402 mt_Bytes: Deserialize( bytes, tested, factory);
403 mt_Stream: begin
404 stream.Position := 0;
405 Deserialize( stream, tested, factory);
406 end
407 else
408 ASSERT( FALSE);
409 end;
410
411 // check
412 correct := CreateSimpleException;
413 while correct <> nil do begin
414 // validate
415 ASSERT( correct.ErrorCode = tested.ErrorCode);
416 ASSERT( IsEqualGUID( correct.ExceptionData, tested.ExceptionData));
417
418 // iterate
419 correct := correct.InnerException;
420 tested := tested.InnerException;
421 ASSERT( (tested <> nil) xor (correct = nil)); // both or none
422 end;
423end;
424
425
Jens Geyered994552019-11-09 23:24:52 +0100426procedure TTestSerializer.Test_Serializer_Deserializer;
427var factory : TFactoryPair;
428 stream : TFileStream;
429 method : TMethod;
430begin
431 stream := TFileStream.Create( 'TestSerializer.dat', fmCreate);
432 try
433 for method in [Low(TMethod)..High(TMethod)] do begin
434 Writeln( UserFriendlyName(method));
435
436 for factory in FProtocols do begin
437 Writeln('- '+UserFriendlyName(factory));
438
Jens Geyer3e6be732025-06-04 22:31:55 +0200439 // protocol conformity tests
440 if (method = TMethod.mt_Bytes) and (factory.trans = nil)
441 then Test_ProtocolConformity( factory, stream);
442
443 // normal objects
Jens Geyere9f63e02024-11-23 01:01:13 +0100444 Test_OneOfEach( method, factory, stream);
445 Test_CompactStruct( method, factory, stream);
446 Test_ExceptionStruct( method, factory, stream);
447 Test_SimpleException( method, factory, stream);
Jens Geyered994552019-11-09 23:24:52 +0100448 end;
449
450 Writeln;
451 end;
452
453 finally
454 stream.Free;
455 end;
456end;
457
458
459class function TTestSerializer.UserFriendlyName( const factory : TFactoryPair) : string;
460begin
Jens Geyer3e6be732025-06-04 22:31:55 +0200461 result := Copy( (factory.proto as TObject).ClassName, 2, MAXINT);
Jens Geyered994552019-11-09 23:24:52 +0100462
463 if factory.trans <> nil
464 then result := Copy( (factory.trans as TObject).ClassName, 2, MAXINT) +' '+ result;
465
466 result := StringReplace( result, 'Impl', '', [rfReplaceAll]);
467 result := StringReplace( result, 'Transport.TFactory', '', [rfReplaceAll]);
468 result := StringReplace( result, 'Protocol.TFactory', '', [rfReplaceAll]);
469end;
470
471
472class function TTestSerializer.UserFriendlyName( const method : TMethod) : string;
Jens Geyer62445c12022-06-29 00:00:00 +0200473const NAMES : array[TMethod] of string = ('TBytes','Stream');
Jens Geyered994552019-11-09 23:24:52 +0100474begin
Jens Geyer62445c12022-06-29 00:00:00 +0200475 result := NAMES[method];
Jens Geyered994552019-11-09 23:24:52 +0100476end;
477
478
Jens Geyer07f4bb52022-09-03 14:50:06 +0200479procedure TTestSerializer.Test_COM_Types;
480var tested : IOneOfEach;
481begin
482 {$IF cDebugProtoTest_Option_COM_types}
483 ASSERT( SizeOf(TSomeEnum) = SizeOf(Int32)); // -> MINENUMSIZE 4
484
485 // try to set values that allocate memory
486 tested := CreateOneOfEach;
487 tested.Zomg_unicode := 'This is a test';
488 tested.Base64 := TThriftBytesImpl.Create( TEncoding.UTF8.GetBytes('abc'));
489 {$IFEND}
490end;
491
492
Jens Geyer16819262024-03-07 23:01:20 +0100493procedure TTestSerializer.Test_ThriftBytesCTORs;
494var one, two : IThriftBytes;
495 bytes : TBytes;
496 sAscii : AnsiString;
497begin
498 sAscii := 'ABC/xzy';
Jens Geyerb53fa8e2024-03-08 00:33:22 +0100499 bytes := TEncoding.ASCII.GetBytes(string(sAscii));
Jens Geyer16819262024-03-07 23:01:20 +0100500
501 one := TThriftBytesImpl.Create( PAnsiChar(sAscii), Length(sAscii));
502 two := TThriftBytesImpl.Create( bytes, TRUE);
503
504 ASSERT( one.Count = two.Count);
505 ASSERT( CompareMem( one.QueryRawDataPtr, two.QueryRawDataPtr, one.Count));
506end;
507
508
Jens Geyered994552019-11-09 23:24:52 +0100509procedure TTestSerializer.RunTests;
510begin
511 try
512 Test_Serializer_Deserializer;
Jens Geyer07f4bb52022-09-03 14:50:06 +0200513 Test_COM_Types;
Jens Geyer16819262024-03-07 23:01:20 +0100514 Test_ThriftBytesCTORs;
Jens Geyered994552019-11-09 23:24:52 +0100515 except
516 on e:Exception do begin
517 Writeln( e.ClassName+': '+ e.Message);
518 Write('Hit ENTER to close ... '); Readln;
519 end;
520 end;
521end;
522
523
524class function TTestSerializer.Serialize(const input : IBase; const factory : TFactoryPair) : TBytes;
525var serial : TSerializer;
Jens Geyera019cda2019-11-09 23:24:52 +0100526 config : IThriftConfiguration;
Jens Geyered994552019-11-09 23:24:52 +0100527begin
Jens Geyera019cda2019-11-09 23:24:52 +0100528 config := TThriftConfigurationImpl.Create;
Jens Geyer62445c12022-06-29 00:00:00 +0200529 //config.MaxMessageSize := 0; // we don't read anything here
Jens Geyera019cda2019-11-09 23:24:52 +0100530
Jens Geyer3e6be732025-06-04 22:31:55 +0200531 serial := TSerializer.Create( factory.proto, factory.trans, config);
Jens Geyered994552019-11-09 23:24:52 +0100532 try
533 result := serial.Serialize( input);
534 finally
535 serial.Free;
536 end;
537end;
538
539
540class procedure TTestSerializer.Serialize(const input : IBase; const factory : TFactoryPair; const aStream : TStream);
541var serial : TSerializer;
Jens Geyera019cda2019-11-09 23:24:52 +0100542 config : IThriftConfiguration;
Jens Geyered994552019-11-09 23:24:52 +0100543begin
Jens Geyera019cda2019-11-09 23:24:52 +0100544 config := TThriftConfigurationImpl.Create;
Jens Geyer62445c12022-06-29 00:00:00 +0200545 //config.MaxMessageSize := 0; // we don't read anything here
Jens Geyera019cda2019-11-09 23:24:52 +0100546
Jens Geyer3e6be732025-06-04 22:31:55 +0200547 serial := TSerializer.Create( factory.proto, factory.trans, config);
Jens Geyered994552019-11-09 23:24:52 +0100548 try
549 serial.Serialize( input, aStream);
550 finally
551 serial.Free;
552 end;
553end;
554
555
556class procedure TTestSerializer.Deserialize( const input : TBytes; const target : IBase; const factory : TFactoryPair);
557var serial : TDeserializer;
Jens Geyera019cda2019-11-09 23:24:52 +0100558 config : IThriftConfiguration;
Jens Geyered994552019-11-09 23:24:52 +0100559begin
Jens Geyera019cda2019-11-09 23:24:52 +0100560 config := TThriftConfigurationImpl.Create;
561 config.MaxMessageSize := Length(input);
562
Jens Geyer3e6be732025-06-04 22:31:55 +0200563 serial := TDeserializer.Create( factory.proto, factory.trans, config);
Jens Geyered994552019-11-09 23:24:52 +0100564 try
565 serial.Deserialize( input, target);
Jens Geyer3e6be732025-06-04 22:31:55 +0200566 ValidateReadToEnd( serial);
Jens Geyered994552019-11-09 23:24:52 +0100567 finally
568 serial.Free;
569 end;
570end;
571
572
573class procedure TTestSerializer.Deserialize( const input : TStream; const target : IBase; const factory : TFactoryPair);
574var serial : TDeserializer;
Jens Geyera019cda2019-11-09 23:24:52 +0100575 config : IThriftConfiguration;
Jens Geyered994552019-11-09 23:24:52 +0100576begin
Jens Geyera019cda2019-11-09 23:24:52 +0100577 config := TThriftConfigurationImpl.Create;
578 config.MaxMessageSize := input.Size;
579
Jens Geyer3e6be732025-06-04 22:31:55 +0200580 serial := TDeserializer.Create( factory.proto, factory.trans, config);
Jens Geyered994552019-11-09 23:24:52 +0100581 try
582 serial.Deserialize( input, target);
Jens Geyer3e6be732025-06-04 22:31:55 +0200583 ValidateReadToEnd( serial);
Jens Geyered994552019-11-09 23:24:52 +0100584 finally
585 serial.Free;
586 end;
587end;
588
589
Jens Geyer3e6be732025-06-04 22:31:55 +0200590class procedure TTestSerializer.Deserialize( const input : TBytes; out target : TGuid; const factory : TFactoryPair);
591var serial : TDeserializer;
592 config : IThriftConfiguration;
593begin
594 config := TThriftConfigurationImpl.Create;
595 config.MaxMessageSize := Length(input);
596
597 serial := TDeserializer.Create( factory.proto, factory.trans, config);
598 try
599 serial.Stream.Write(input[0], Length(input));
600 serial.Stream.Position := 0;
601 serial.Transport.ResetMessageSizeAndConsumedBytes(); // size has changed
602
603 target := serial.Protocol.ReadUuid;
604 finally
605 serial.Free;
606 end;
607end;
608
609
610class procedure TTestSerializer.ValidateReadToEnd( const serial : TDeserializer);
Jens Geyer41f47af2019-11-09 23:24:52 +0100611// we should not have any more byte to read
612var dummy : IBase;
613begin
614 try
615 dummy := TOneOfEachImpl.Create;
Jens Geyer3e6be732025-06-04 22:31:55 +0200616 serial.Deserialize( nil, dummy);
Jens Geyer41f47af2019-11-09 23:24:52 +0100617 raise EInOutError.Create('Expected exception not thrown?');
618 except
Jens Geyer3e6be732025-06-04 22:31:55 +0200619 on e:TTransportException do {expected};
Jens Geyer41f47af2019-11-09 23:24:52 +0100620 on e:Exception do raise; // unexpected
621 end;
622end;
623
624
Jens Geyered994552019-11-09 23:24:52 +0100625end.