blob: eee137ca16a0adbcd5916e015338a77cbbe992e9 [file] [log] [blame]
Jens Geyer421444f2019-03-20 22:13:25 +01001// Licensed to the Apache Software Foundation(ASF) under one
Jens Geyeraa0c8b32019-01-28 23:27:45 +01002// or more contributor license agreements.See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License. You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied. See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18using System;
zembord9d958a32019-11-21 13:11:44 +030019using System.Buffers.Binary;
Jens Geyeraa0c8b32019-01-28 23:27:45 +010020using System.Text;
21using System.Threading;
22using System.Threading.Tasks;
23using Thrift.Protocol.Entities;
24using Thrift.Transport;
25
Jens Geyer0d128322021-02-25 09:42:52 +010026
Jens Geyeraa0c8b32019-01-28 23:27:45 +010027namespace Thrift.Protocol
28{
29 // ReSharper disable once InconsistentNaming
30 public class TBinaryProtocol : TProtocol
31 {
Jens Geyeraa0c8b32019-01-28 23:27:45 +010032 protected const uint VersionMask = 0xffff0000;
33 protected const uint Version1 = 0x80010000;
34
35 protected bool StrictRead;
36 protected bool StrictWrite;
37
Jens Geyer5a17b132019-05-26 15:53:37 +020038 // minimize memory allocations by means of an preallocated bytes buffer
39 // The value of 128 is arbitrarily chosen, the required minimum size must be sizeof(long)
Jens Geyer0d128322021-02-25 09:42:52 +010040 private readonly byte[] PreAllocatedBuffer = new byte[128];
Jens Geyer5a17b132019-05-26 15:53:37 +020041
Jens Geyeraa0c8b32019-01-28 23:27:45 +010042 public TBinaryProtocol(TTransport trans)
43 : this(trans, false, true)
44 {
45 }
46
47 public TBinaryProtocol(TTransport trans, bool strictRead, bool strictWrite)
48 : base(trans)
49 {
50 StrictRead = strictRead;
51 StrictWrite = strictWrite;
52 }
53
54 public override async Task WriteMessageBeginAsync(TMessage message, CancellationToken cancellationToken)
55 {
Jens Geyerdce22992020-05-16 23:02:27 +020056 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +010057
58 if (StrictWrite)
59 {
60 var version = Version1 | (uint) message.Type;
61 await WriteI32Async((int) version, cancellationToken);
62 await WriteStringAsync(message.Name, cancellationToken);
63 await WriteI32Async(message.SeqID, cancellationToken);
64 }
65 else
66 {
67 await WriteStringAsync(message.Name, cancellationToken);
68 await WriteByteAsync((sbyte) message.Type, cancellationToken);
69 await WriteI32Async(message.SeqID, cancellationToken);
70 }
71 }
72
Jens Geyerdce22992020-05-16 23:02:27 +020073 public override Task WriteMessageEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +010074 {
Jens Geyerdce22992020-05-16 23:02:27 +020075 cancellationToken.ThrowIfCancellationRequested();
76 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +010077 }
78
Jens Geyerdce22992020-05-16 23:02:27 +020079 public override Task WriteStructBeginAsync(TStruct @struct, CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +010080 {
Jens Geyerdce22992020-05-16 23:02:27 +020081 cancellationToken.ThrowIfCancellationRequested();
82 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +010083 }
84
Jens Geyerdce22992020-05-16 23:02:27 +020085 public override Task WriteStructEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +010086 {
Jens Geyerdce22992020-05-16 23:02:27 +020087 cancellationToken.ThrowIfCancellationRequested();
88 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +010089 }
90
91 public override async Task WriteFieldBeginAsync(TField field, CancellationToken cancellationToken)
92 {
Jens Geyerdce22992020-05-16 23:02:27 +020093 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +010094 await WriteByteAsync((sbyte) field.Type, cancellationToken);
95 await WriteI16Async(field.ID, cancellationToken);
96 }
97
Jens Geyerdce22992020-05-16 23:02:27 +020098 public override Task WriteFieldEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +010099 {
Jens Geyerdce22992020-05-16 23:02:27 +0200100 cancellationToken.ThrowIfCancellationRequested();
101 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100102 }
103
104 public override async Task WriteFieldStopAsync(CancellationToken cancellationToken)
105 {
Jens Geyerdce22992020-05-16 23:02:27 +0200106 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100107
108 await WriteByteAsync((sbyte) TType.Stop, cancellationToken);
109 }
110
111 public override async Task WriteMapBeginAsync(TMap map, CancellationToken cancellationToken)
112 {
Jens Geyerdce22992020-05-16 23:02:27 +0200113 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100114
Jens Geyer5a17b132019-05-26 15:53:37 +0200115 PreAllocatedBuffer[0] = (byte)map.KeyType;
116 PreAllocatedBuffer[1] = (byte)map.ValueType;
117 await Trans.WriteAsync(PreAllocatedBuffer, 0, 2, cancellationToken);
118
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100119 await WriteI32Async(map.Count, cancellationToken);
120 }
121
Jens Geyerdce22992020-05-16 23:02:27 +0200122 public override Task WriteMapEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100123 {
Jens Geyerdce22992020-05-16 23:02:27 +0200124 cancellationToken.ThrowIfCancellationRequested();
125 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100126 }
127
128 public override async Task WriteListBeginAsync(TList list, CancellationToken cancellationToken)
129 {
Jens Geyerdce22992020-05-16 23:02:27 +0200130 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100131 await WriteByteAsync((sbyte) list.ElementType, cancellationToken);
132 await WriteI32Async(list.Count, cancellationToken);
133 }
134
Jens Geyerdce22992020-05-16 23:02:27 +0200135 public override Task WriteListEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100136 {
Jens Geyerdce22992020-05-16 23:02:27 +0200137 cancellationToken.ThrowIfCancellationRequested();
138 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100139 }
140
141 public override async Task WriteSetBeginAsync(TSet set, CancellationToken cancellationToken)
142 {
Jens Geyerdce22992020-05-16 23:02:27 +0200143 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100144 await WriteByteAsync((sbyte) set.ElementType, cancellationToken);
145 await WriteI32Async(set.Count, cancellationToken);
146 }
147
Jens Geyerdce22992020-05-16 23:02:27 +0200148 public override Task WriteSetEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100149 {
Jens Geyerdce22992020-05-16 23:02:27 +0200150 cancellationToken.ThrowIfCancellationRequested();
151 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100152 }
153
154 public override async Task WriteBoolAsync(bool b, CancellationToken cancellationToken)
155 {
Jens Geyerdce22992020-05-16 23:02:27 +0200156 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100157 await WriteByteAsync(b ? (sbyte) 1 : (sbyte) 0, cancellationToken);
158 }
159
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100160 public override async Task WriteByteAsync(sbyte b, CancellationToken cancellationToken)
161 {
Jens Geyerdce22992020-05-16 23:02:27 +0200162 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100163
Jens Geyer5a17b132019-05-26 15:53:37 +0200164 PreAllocatedBuffer[0] = (byte)b;
165
166 await Trans.WriteAsync(PreAllocatedBuffer, 0, 1, cancellationToken);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100167 }
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100168 public override async Task WriteI16Async(short i16, CancellationToken cancellationToken)
169 {
Jens Geyerdce22992020-05-16 23:02:27 +0200170 cancellationToken.ThrowIfCancellationRequested();
171
zembord9d958a32019-11-21 13:11:44 +0300172 BinaryPrimitives.WriteInt16BigEndian(PreAllocatedBuffer, i16);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100173
Jens Geyer5a17b132019-05-26 15:53:37 +0200174 await Trans.WriteAsync(PreAllocatedBuffer, 0, 2, cancellationToken);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100175 }
176
177 public override async Task WriteI32Async(int i32, CancellationToken cancellationToken)
178 {
Jens Geyerdce22992020-05-16 23:02:27 +0200179 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100180
zembord9d958a32019-11-21 13:11:44 +0300181 BinaryPrimitives.WriteInt32BigEndian(PreAllocatedBuffer, i32);
Jens Geyer5a17b132019-05-26 15:53:37 +0200182
183 await Trans.WriteAsync(PreAllocatedBuffer, 0, 4, cancellationToken);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100184 }
185
Jens Geyer5a17b132019-05-26 15:53:37 +0200186
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100187 public override async Task WriteI64Async(long i64, CancellationToken cancellationToken)
188 {
Jens Geyerdce22992020-05-16 23:02:27 +0200189 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100190
zembord9d958a32019-11-21 13:11:44 +0300191 BinaryPrimitives.WriteInt64BigEndian(PreAllocatedBuffer, i64);
Jens Geyer5a17b132019-05-26 15:53:37 +0200192
193 await Trans.WriteAsync(PreAllocatedBuffer, 0, 8, cancellationToken);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100194 }
195
196 public override async Task WriteDoubleAsync(double d, CancellationToken cancellationToken)
197 {
Jens Geyerdce22992020-05-16 23:02:27 +0200198 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100199
200 await WriteI64Async(BitConverter.DoubleToInt64Bits(d), cancellationToken);
201 }
202
Jens Geyer5a17b132019-05-26 15:53:37 +0200203
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100204 public override async Task WriteBinaryAsync(byte[] bytes, CancellationToken cancellationToken)
205 {
Jens Geyerdce22992020-05-16 23:02:27 +0200206 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100207
208 await WriteI32Async(bytes.Length, cancellationToken);
209 await Trans.WriteAsync(bytes, 0, bytes.Length, cancellationToken);
210 }
211
Jens Geyer5a17b132019-05-26 15:53:37 +0200212 public override async ValueTask<TMessage> ReadMessageBeginAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100213 {
Jens Geyerdce22992020-05-16 23:02:27 +0200214 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100215
216 var message = new TMessage();
217 var size = await ReadI32Async(cancellationToken);
218 if (size < 0)
219 {
220 var version = (uint) size & VersionMask;
221 if (version != Version1)
222 {
223 throw new TProtocolException(TProtocolException.BAD_VERSION,
224 $"Bad version in ReadMessageBegin: {version}");
225 }
226 message.Type = (TMessageType) (size & 0x000000ff);
227 message.Name = await ReadStringAsync(cancellationToken);
228 message.SeqID = await ReadI32Async(cancellationToken);
229 }
230 else
231 {
232 if (StrictRead)
233 {
234 throw new TProtocolException(TProtocolException.BAD_VERSION,
235 "Missing version in ReadMessageBegin, old client?");
236 }
Jens Geyer5a17b132019-05-26 15:53:37 +0200237 message.Name = (size > 0) ? await ReadStringBodyAsync(size, cancellationToken) : string.Empty;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100238 message.Type = (TMessageType) await ReadByteAsync(cancellationToken);
239 message.SeqID = await ReadI32Async(cancellationToken);
240 }
241 return message;
242 }
243
Jens Geyerdce22992020-05-16 23:02:27 +0200244 public override Task ReadMessageEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100245 {
Jens Geyerdce22992020-05-16 23:02:27 +0200246 cancellationToken.ThrowIfCancellationRequested();
247 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100248 }
249
Jens Geyerdce22992020-05-16 23:02:27 +0200250 public override ValueTask<TStruct> ReadStructBeginAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100251 {
Jens Geyerdce22992020-05-16 23:02:27 +0200252 cancellationToken.ThrowIfCancellationRequested();
253 return new ValueTask<TStruct>(AnonymousStruct);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100254 }
255
Jens Geyerdce22992020-05-16 23:02:27 +0200256 public override Task ReadStructEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100257 {
Jens Geyerdce22992020-05-16 23:02:27 +0200258 cancellationToken.ThrowIfCancellationRequested();
259 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100260 }
261
Jens Geyer5a17b132019-05-26 15:53:37 +0200262 public override async ValueTask<TField> ReadFieldBeginAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100263 {
Jens Geyerdce22992020-05-16 23:02:27 +0200264 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100265
Jens Geyer5a17b132019-05-26 15:53:37 +0200266 var type = (TType)await ReadByteAsync(cancellationToken);
267 if (type == TType.Stop)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100268 {
Jens Geyer5a17b132019-05-26 15:53:37 +0200269 return StopField;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100270 }
271
Jens Geyer5a17b132019-05-26 15:53:37 +0200272 return new TField {
273 Type = type,
274 ID = await ReadI16Async(cancellationToken)
275 };
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100276 }
277
Jens Geyerdce22992020-05-16 23:02:27 +0200278 public override Task ReadFieldEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100279 {
Jens Geyerdce22992020-05-16 23:02:27 +0200280 cancellationToken.ThrowIfCancellationRequested();
281 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100282 }
283
Jens Geyer5a17b132019-05-26 15:53:37 +0200284 public override async ValueTask<TMap> ReadMapBeginAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100285 {
Jens Geyerdce22992020-05-16 23:02:27 +0200286 cancellationToken.ThrowIfCancellationRequested();
287
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100288 var map = new TMap
289 {
290 KeyType = (TType) await ReadByteAsync(cancellationToken),
291 ValueType = (TType) await ReadByteAsync(cancellationToken),
292 Count = await ReadI32Async(cancellationToken)
293 };
Jens Geyer50806452019-11-23 01:55:58 +0100294 CheckReadBytesAvailable(map);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100295 return map;
296 }
297
Jens Geyerdce22992020-05-16 23:02:27 +0200298 public override Task ReadMapEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100299 {
Jens Geyerdce22992020-05-16 23:02:27 +0200300 cancellationToken.ThrowIfCancellationRequested();
301 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100302 }
303
Jens Geyer5a17b132019-05-26 15:53:37 +0200304 public override async ValueTask<TList> ReadListBeginAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100305 {
Jens Geyerdce22992020-05-16 23:02:27 +0200306 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100307
308 var list = new TList
309 {
310 ElementType = (TType) await ReadByteAsync(cancellationToken),
311 Count = await ReadI32Async(cancellationToken)
312 };
Jens Geyer50806452019-11-23 01:55:58 +0100313 CheckReadBytesAvailable(list);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100314 return list;
315 }
316
Jens Geyerdce22992020-05-16 23:02:27 +0200317 public override Task ReadListEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100318 {
Jens Geyerdce22992020-05-16 23:02:27 +0200319 cancellationToken.ThrowIfCancellationRequested();
320 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100321 }
322
Jens Geyer5a17b132019-05-26 15:53:37 +0200323 public override async ValueTask<TSet> ReadSetBeginAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100324 {
Jens Geyerdce22992020-05-16 23:02:27 +0200325 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100326
327 var set = new TSet
328 {
329 ElementType = (TType) await ReadByteAsync(cancellationToken),
330 Count = await ReadI32Async(cancellationToken)
331 };
Jens Geyer50806452019-11-23 01:55:58 +0100332 CheckReadBytesAvailable(set);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100333 return set;
334 }
335
Jens Geyerdce22992020-05-16 23:02:27 +0200336 public override Task ReadSetEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100337 {
Jens Geyerdce22992020-05-16 23:02:27 +0200338 cancellationToken.ThrowIfCancellationRequested();
339 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100340 }
341
Jens Geyer5a17b132019-05-26 15:53:37 +0200342 public override async ValueTask<bool> ReadBoolAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100343 {
Jens Geyerdce22992020-05-16 23:02:27 +0200344 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100345
346 return await ReadByteAsync(cancellationToken) == 1;
347 }
348
Jens Geyer5a17b132019-05-26 15:53:37 +0200349 public override async ValueTask<sbyte> ReadByteAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100350 {
Jens Geyerdce22992020-05-16 23:02:27 +0200351 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100352
Jens Geyer5a17b132019-05-26 15:53:37 +0200353 await Trans.ReadAllAsync(PreAllocatedBuffer, 0, 1, cancellationToken);
354 return (sbyte)PreAllocatedBuffer[0];
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100355 }
356
Jens Geyer5a17b132019-05-26 15:53:37 +0200357 public override async ValueTask<short> ReadI16Async(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100358 {
Jens Geyerdce22992020-05-16 23:02:27 +0200359 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100360
Jens Geyer5a17b132019-05-26 15:53:37 +0200361 await Trans.ReadAllAsync(PreAllocatedBuffer, 0, 2, cancellationToken);
zembord9d958a32019-11-21 13:11:44 +0300362 var result = BinaryPrimitives.ReadInt16BigEndian(PreAllocatedBuffer);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100363 return result;
364 }
365
Jens Geyer5a17b132019-05-26 15:53:37 +0200366 public override async ValueTask<int> ReadI32Async(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100367 {
Jens Geyerdce22992020-05-16 23:02:27 +0200368 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100369
Jens Geyer5a17b132019-05-26 15:53:37 +0200370 await Trans.ReadAllAsync(PreAllocatedBuffer, 0, 4, cancellationToken);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100371
zembord9d958a32019-11-21 13:11:44 +0300372 var result = BinaryPrimitives.ReadInt32BigEndian(PreAllocatedBuffer);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100373
374 return result;
375 }
376
Jens Geyer5a17b132019-05-26 15:53:37 +0200377 public override async ValueTask<long> ReadI64Async(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100378 {
Jens Geyerdce22992020-05-16 23:02:27 +0200379 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100380
Jens Geyer5a17b132019-05-26 15:53:37 +0200381 await Trans.ReadAllAsync(PreAllocatedBuffer, 0, 8, cancellationToken);
zembord9d958a32019-11-21 13:11:44 +0300382 return BinaryPrimitives.ReadInt64BigEndian(PreAllocatedBuffer);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100383 }
384
Jens Geyer5a17b132019-05-26 15:53:37 +0200385 public override async ValueTask<double> ReadDoubleAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100386 {
Jens Geyerdce22992020-05-16 23:02:27 +0200387 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100388
389 var d = await ReadI64Async(cancellationToken);
390 return BitConverter.Int64BitsToDouble(d);
391 }
392
Jens Geyer5a17b132019-05-26 15:53:37 +0200393 public override async ValueTask<byte[]> ReadBinaryAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100394 {
Jens Geyerdce22992020-05-16 23:02:27 +0200395 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100396
397 var size = await ReadI32Async(cancellationToken);
Jens Geyer50806452019-11-23 01:55:58 +0100398 Transport.CheckReadBytesAvailable(size);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100399 var buf = new byte[size];
400 await Trans.ReadAllAsync(buf, 0, size, cancellationToken);
401 return buf;
402 }
403
Jens Geyer5a17b132019-05-26 15:53:37 +0200404 public override async ValueTask<string> ReadStringAsync(CancellationToken cancellationToken)
405 {
Jens Geyerdce22992020-05-16 23:02:27 +0200406 cancellationToken.ThrowIfCancellationRequested();
Jens Geyer5a17b132019-05-26 15:53:37 +0200407
408 var size = await ReadI32Async(cancellationToken);
409 return size > 0 ? await ReadStringBodyAsync(size, cancellationToken) : string.Empty;
410 }
411
412 private async ValueTask<string> ReadStringBodyAsync(int size, CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100413 {
Jens Geyerdce22992020-05-16 23:02:27 +0200414 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100415
Jens Geyer5a17b132019-05-26 15:53:37 +0200416 if (size <= PreAllocatedBuffer.Length)
417 {
418 await Trans.ReadAllAsync(PreAllocatedBuffer, 0, size, cancellationToken);
419 return Encoding.UTF8.GetString(PreAllocatedBuffer, 0, size);
420 }
421
Jens Geyer50806452019-11-23 01:55:58 +0100422 Transport.CheckReadBytesAvailable(size);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100423 var buf = new byte[size];
424 await Trans.ReadAllAsync(buf, 0, size, cancellationToken);
425 return Encoding.UTF8.GetString(buf, 0, buf.Length);
426 }
427
Jens Geyer50806452019-11-23 01:55:58 +0100428 // Return the minimum number of bytes a type will consume on the wire
429 public override int GetMinSerializedSize(TType type)
430 {
431 switch (type)
432 {
433 case TType.Stop: return 0;
434 case TType.Void: return 0;
435 case TType.Bool: return sizeof(byte);
436 case TType.Byte: return sizeof(byte);
437 case TType.Double: return sizeof(double);
438 case TType.I16: return sizeof(short);
439 case TType.I32: return sizeof(int);
440 case TType.I64: return sizeof(long);
441 case TType.String: return sizeof(int); // string length
442 case TType.Struct: return 0; // empty struct
443 case TType.Map: return sizeof(int); // element count
444 case TType.Set: return sizeof(int); // element count
445 case TType.List: return sizeof(int); // element count
Jens Geyer0d128322021-02-25 09:42:52 +0100446 default: throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "unrecognized type code");
Jens Geyer50806452019-11-23 01:55:58 +0100447 }
448 }
449
Jens Geyer421444f2019-03-20 22:13:25 +0100450 public class Factory : TProtocolFactory
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100451 {
452 protected bool StrictRead;
453 protected bool StrictWrite;
454
455 public Factory()
456 : this(false, true)
457 {
458 }
459
460 public Factory(bool strictRead, bool strictWrite)
461 {
462 StrictRead = strictRead;
463 StrictWrite = strictWrite;
464 }
465
Jens Geyer421444f2019-03-20 22:13:25 +0100466 public override TProtocol GetProtocol(TTransport trans)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100467 {
468 return new TBinaryProtocol(trans, StrictRead, StrictWrite);
469 }
470 }
471 }
Jens Geyer421444f2019-03-20 22:13:25 +0100472}