blob: ba2a7abbc37beed54e0952d407f4a384be1e8967 [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;
Jens Geyer62445c12022-06-29 00:00:00 +020024using Thrift.Protocol.Utilities;
Jens Geyeraa0c8b32019-01-28 23:27:45 +010025using Thrift.Transport;
26
Jens Geyer0d128322021-02-25 09:42:52 +010027
Jens Geyeraa0c8b32019-01-28 23:27:45 +010028namespace Thrift.Protocol
29{
30 // ReSharper disable once InconsistentNaming
31 public class TBinaryProtocol : TProtocol
32 {
Jens Geyeraa0c8b32019-01-28 23:27:45 +010033 protected const uint VersionMask = 0xffff0000;
34 protected const uint Version1 = 0x80010000;
35
36 protected bool StrictRead;
37 protected bool StrictWrite;
38
Jens Geyer5a17b132019-05-26 15:53:37 +020039 // minimize memory allocations by means of an preallocated bytes buffer
40 // The value of 128 is arbitrarily chosen, the required minimum size must be sizeof(long)
Jens Geyer0d128322021-02-25 09:42:52 +010041 private readonly byte[] PreAllocatedBuffer = new byte[128];
Jens Geyer5a17b132019-05-26 15:53:37 +020042
Jens Geyeraa0c8b32019-01-28 23:27:45 +010043 public TBinaryProtocol(TTransport trans)
44 : this(trans, false, true)
45 {
46 }
47
48 public TBinaryProtocol(TTransport trans, bool strictRead, bool strictWrite)
49 : base(trans)
50 {
51 StrictRead = strictRead;
52 StrictWrite = strictWrite;
53 }
54
55 public override async Task WriteMessageBeginAsync(TMessage message, CancellationToken cancellationToken)
56 {
Jens Geyerdce22992020-05-16 23:02:27 +020057 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +010058
59 if (StrictWrite)
60 {
61 var version = Version1 | (uint) message.Type;
62 await WriteI32Async((int) version, cancellationToken);
63 await WriteStringAsync(message.Name, cancellationToken);
64 await WriteI32Async(message.SeqID, cancellationToken);
65 }
66 else
67 {
68 await WriteStringAsync(message.Name, cancellationToken);
69 await WriteByteAsync((sbyte) message.Type, cancellationToken);
70 await WriteI32Async(message.SeqID, cancellationToken);
71 }
72 }
73
Jens Geyerdce22992020-05-16 23:02:27 +020074 public override Task WriteMessageEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +010075 {
Jens Geyerdce22992020-05-16 23:02:27 +020076 cancellationToken.ThrowIfCancellationRequested();
77 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +010078 }
79
Jens Geyerdce22992020-05-16 23:02:27 +020080 public override Task WriteStructBeginAsync(TStruct @struct, CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +010081 {
Jens Geyerdce22992020-05-16 23:02:27 +020082 cancellationToken.ThrowIfCancellationRequested();
83 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +010084 }
85
Jens Geyerdce22992020-05-16 23:02:27 +020086 public override Task WriteStructEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +010087 {
Jens Geyerdce22992020-05-16 23:02:27 +020088 cancellationToken.ThrowIfCancellationRequested();
89 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +010090 }
91
92 public override async Task WriteFieldBeginAsync(TField field, CancellationToken cancellationToken)
93 {
Jens Geyerdce22992020-05-16 23:02:27 +020094 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +010095 await WriteByteAsync((sbyte) field.Type, cancellationToken);
96 await WriteI16Async(field.ID, cancellationToken);
97 }
98
Jens Geyerdce22992020-05-16 23:02:27 +020099 public override Task WriteFieldEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100100 {
Jens Geyerdce22992020-05-16 23:02:27 +0200101 cancellationToken.ThrowIfCancellationRequested();
102 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100103 }
104
105 public override async Task WriteFieldStopAsync(CancellationToken cancellationToken)
106 {
Jens Geyerdce22992020-05-16 23:02:27 +0200107 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100108
109 await WriteByteAsync((sbyte) TType.Stop, cancellationToken);
110 }
111
112 public override async Task WriteMapBeginAsync(TMap map, CancellationToken cancellationToken)
113 {
Jens Geyerdce22992020-05-16 23:02:27 +0200114 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100115
Jens Geyer5a17b132019-05-26 15:53:37 +0200116 PreAllocatedBuffer[0] = (byte)map.KeyType;
117 PreAllocatedBuffer[1] = (byte)map.ValueType;
118 await Trans.WriteAsync(PreAllocatedBuffer, 0, 2, cancellationToken);
119
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100120 await WriteI32Async(map.Count, cancellationToken);
121 }
122
Jens Geyerdce22992020-05-16 23:02:27 +0200123 public override Task WriteMapEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100124 {
Jens Geyerdce22992020-05-16 23:02:27 +0200125 cancellationToken.ThrowIfCancellationRequested();
126 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100127 }
128
129 public override async Task WriteListBeginAsync(TList list, CancellationToken cancellationToken)
130 {
Jens Geyerdce22992020-05-16 23:02:27 +0200131 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100132 await WriteByteAsync((sbyte) list.ElementType, cancellationToken);
133 await WriteI32Async(list.Count, cancellationToken);
134 }
135
Jens Geyerdce22992020-05-16 23:02:27 +0200136 public override Task WriteListEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100137 {
Jens Geyerdce22992020-05-16 23:02:27 +0200138 cancellationToken.ThrowIfCancellationRequested();
139 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100140 }
141
142 public override async Task WriteSetBeginAsync(TSet set, CancellationToken cancellationToken)
143 {
Jens Geyerdce22992020-05-16 23:02:27 +0200144 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100145 await WriteByteAsync((sbyte) set.ElementType, cancellationToken);
146 await WriteI32Async(set.Count, cancellationToken);
147 }
148
Jens Geyerdce22992020-05-16 23:02:27 +0200149 public override Task WriteSetEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100150 {
Jens Geyerdce22992020-05-16 23:02:27 +0200151 cancellationToken.ThrowIfCancellationRequested();
152 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100153 }
154
155 public override async Task WriteBoolAsync(bool b, CancellationToken cancellationToken)
156 {
Jens Geyerdce22992020-05-16 23:02:27 +0200157 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100158 await WriteByteAsync(b ? (sbyte) 1 : (sbyte) 0, cancellationToken);
159 }
160
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100161 public override async Task WriteByteAsync(sbyte b, CancellationToken cancellationToken)
162 {
Jens Geyerdce22992020-05-16 23:02:27 +0200163 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100164
Jens Geyer5a17b132019-05-26 15:53:37 +0200165 PreAllocatedBuffer[0] = (byte)b;
166
167 await Trans.WriteAsync(PreAllocatedBuffer, 0, 1, cancellationToken);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100168 }
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100169 public override async Task WriteI16Async(short i16, CancellationToken cancellationToken)
170 {
Jens Geyerdce22992020-05-16 23:02:27 +0200171 cancellationToken.ThrowIfCancellationRequested();
172
zembord9d958a32019-11-21 13:11:44 +0300173 BinaryPrimitives.WriteInt16BigEndian(PreAllocatedBuffer, i16);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100174
Jens Geyer5a17b132019-05-26 15:53:37 +0200175 await Trans.WriteAsync(PreAllocatedBuffer, 0, 2, cancellationToken);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100176 }
177
178 public override async Task WriteI32Async(int i32, CancellationToken cancellationToken)
179 {
Jens Geyerdce22992020-05-16 23:02:27 +0200180 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100181
zembord9d958a32019-11-21 13:11:44 +0300182 BinaryPrimitives.WriteInt32BigEndian(PreAllocatedBuffer, i32);
Jens Geyer5a17b132019-05-26 15:53:37 +0200183
184 await Trans.WriteAsync(PreAllocatedBuffer, 0, 4, cancellationToken);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100185 }
186
Jens Geyer5a17b132019-05-26 15:53:37 +0200187
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100188 public override async Task WriteI64Async(long i64, CancellationToken cancellationToken)
189 {
Jens Geyerdce22992020-05-16 23:02:27 +0200190 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100191
zembord9d958a32019-11-21 13:11:44 +0300192 BinaryPrimitives.WriteInt64BigEndian(PreAllocatedBuffer, i64);
Jens Geyer5a17b132019-05-26 15:53:37 +0200193
194 await Trans.WriteAsync(PreAllocatedBuffer, 0, 8, cancellationToken);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100195 }
196
197 public override async Task WriteDoubleAsync(double d, CancellationToken cancellationToken)
198 {
Jens Geyerdce22992020-05-16 23:02:27 +0200199 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100200
201 await WriteI64Async(BitConverter.DoubleToInt64Bits(d), cancellationToken);
202 }
203
Jens Geyer5a17b132019-05-26 15:53:37 +0200204
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100205 public override async Task WriteBinaryAsync(byte[] bytes, CancellationToken cancellationToken)
206 {
Jens Geyerdce22992020-05-16 23:02:27 +0200207 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100208
209 await WriteI32Async(bytes.Length, cancellationToken);
210 await Trans.WriteAsync(bytes, 0, bytes.Length, cancellationToken);
211 }
212
Jens Geyer62445c12022-06-29 00:00:00 +0200213 public override async Task WriteUuidAsync(Guid uuid, CancellationToken cancellationToken)
214 {
215 cancellationToken.ThrowIfCancellationRequested();
216
217 var bytes = uuid.SwapByteOrder().ToByteArray();
218 await Trans.WriteAsync(bytes, 0, bytes.Length, cancellationToken);
219 }
220
Jens Geyer5a17b132019-05-26 15:53:37 +0200221 public override async ValueTask<TMessage> ReadMessageBeginAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100222 {
Jens Geyerdce22992020-05-16 23:02:27 +0200223 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100224
225 var message = new TMessage();
226 var size = await ReadI32Async(cancellationToken);
227 if (size < 0)
228 {
229 var version = (uint) size & VersionMask;
230 if (version != Version1)
231 {
232 throw new TProtocolException(TProtocolException.BAD_VERSION,
233 $"Bad version in ReadMessageBegin: {version}");
234 }
235 message.Type = (TMessageType) (size & 0x000000ff);
236 message.Name = await ReadStringAsync(cancellationToken);
237 message.SeqID = await ReadI32Async(cancellationToken);
238 }
239 else
240 {
241 if (StrictRead)
242 {
243 throw new TProtocolException(TProtocolException.BAD_VERSION,
244 "Missing version in ReadMessageBegin, old client?");
245 }
Jens Geyer5a17b132019-05-26 15:53:37 +0200246 message.Name = (size > 0) ? await ReadStringBodyAsync(size, cancellationToken) : string.Empty;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100247 message.Type = (TMessageType) await ReadByteAsync(cancellationToken);
248 message.SeqID = await ReadI32Async(cancellationToken);
249 }
250 return message;
251 }
252
Jens Geyerdce22992020-05-16 23:02:27 +0200253 public override Task ReadMessageEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100254 {
Jens Geyerdce22992020-05-16 23:02:27 +0200255 cancellationToken.ThrowIfCancellationRequested();
256 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100257 }
258
Jens Geyerdce22992020-05-16 23:02:27 +0200259 public override ValueTask<TStruct> ReadStructBeginAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100260 {
Jens Geyerdce22992020-05-16 23:02:27 +0200261 cancellationToken.ThrowIfCancellationRequested();
262 return new ValueTask<TStruct>(AnonymousStruct);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100263 }
264
Jens Geyerdce22992020-05-16 23:02:27 +0200265 public override Task ReadStructEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100266 {
Jens Geyerdce22992020-05-16 23:02:27 +0200267 cancellationToken.ThrowIfCancellationRequested();
268 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100269 }
270
Jens Geyer5a17b132019-05-26 15:53:37 +0200271 public override async ValueTask<TField> ReadFieldBeginAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100272 {
Jens Geyerdce22992020-05-16 23:02:27 +0200273 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100274
Jens Geyer5a17b132019-05-26 15:53:37 +0200275 var type = (TType)await ReadByteAsync(cancellationToken);
276 if (type == TType.Stop)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100277 {
Jens Geyer5a17b132019-05-26 15:53:37 +0200278 return StopField;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100279 }
280
Jens Geyer5a17b132019-05-26 15:53:37 +0200281 return new TField {
282 Type = type,
283 ID = await ReadI16Async(cancellationToken)
284 };
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100285 }
286
Jens Geyerdce22992020-05-16 23:02:27 +0200287 public override Task ReadFieldEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100288 {
Jens Geyerdce22992020-05-16 23:02:27 +0200289 cancellationToken.ThrowIfCancellationRequested();
290 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100291 }
292
Jens Geyer5a17b132019-05-26 15:53:37 +0200293 public override async ValueTask<TMap> ReadMapBeginAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100294 {
Jens Geyerdce22992020-05-16 23:02:27 +0200295 cancellationToken.ThrowIfCancellationRequested();
296
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100297 var map = new TMap
298 {
299 KeyType = (TType) await ReadByteAsync(cancellationToken),
300 ValueType = (TType) await ReadByteAsync(cancellationToken),
301 Count = await ReadI32Async(cancellationToken)
302 };
Jens Geyer50806452019-11-23 01:55:58 +0100303 CheckReadBytesAvailable(map);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100304 return map;
305 }
306
Jens Geyerdce22992020-05-16 23:02:27 +0200307 public override Task ReadMapEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100308 {
Jens Geyerdce22992020-05-16 23:02:27 +0200309 cancellationToken.ThrowIfCancellationRequested();
310 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100311 }
312
Jens Geyer5a17b132019-05-26 15:53:37 +0200313 public override async ValueTask<TList> ReadListBeginAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100314 {
Jens Geyerdce22992020-05-16 23:02:27 +0200315 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100316
317 var list = new TList
318 {
319 ElementType = (TType) await ReadByteAsync(cancellationToken),
320 Count = await ReadI32Async(cancellationToken)
321 };
Jens Geyer50806452019-11-23 01:55:58 +0100322 CheckReadBytesAvailable(list);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100323 return list;
324 }
325
Jens Geyerdce22992020-05-16 23:02:27 +0200326 public override Task ReadListEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100327 {
Jens Geyerdce22992020-05-16 23:02:27 +0200328 cancellationToken.ThrowIfCancellationRequested();
329 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100330 }
331
Jens Geyer5a17b132019-05-26 15:53:37 +0200332 public override async ValueTask<TSet> ReadSetBeginAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100333 {
Jens Geyerdce22992020-05-16 23:02:27 +0200334 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100335
336 var set = new TSet
337 {
338 ElementType = (TType) await ReadByteAsync(cancellationToken),
339 Count = await ReadI32Async(cancellationToken)
340 };
Jens Geyer50806452019-11-23 01:55:58 +0100341 CheckReadBytesAvailable(set);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100342 return set;
343 }
344
Jens Geyerdce22992020-05-16 23:02:27 +0200345 public override Task ReadSetEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100346 {
Jens Geyerdce22992020-05-16 23:02:27 +0200347 cancellationToken.ThrowIfCancellationRequested();
348 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100349 }
350
Jens Geyer5a17b132019-05-26 15:53:37 +0200351 public override async ValueTask<bool> ReadBoolAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100352 {
Jens Geyerdce22992020-05-16 23:02:27 +0200353 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100354
355 return await ReadByteAsync(cancellationToken) == 1;
356 }
357
Jens Geyer5a17b132019-05-26 15:53:37 +0200358 public override async ValueTask<sbyte> ReadByteAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100359 {
Jens Geyerdce22992020-05-16 23:02:27 +0200360 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100361
Jens Geyer5a17b132019-05-26 15:53:37 +0200362 await Trans.ReadAllAsync(PreAllocatedBuffer, 0, 1, cancellationToken);
363 return (sbyte)PreAllocatedBuffer[0];
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100364 }
365
Jens Geyer5a17b132019-05-26 15:53:37 +0200366 public override async ValueTask<short> ReadI16Async(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, 2, cancellationToken);
zembord9d958a32019-11-21 13:11:44 +0300371 var result = BinaryPrimitives.ReadInt16BigEndian(PreAllocatedBuffer);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100372 return result;
373 }
374
Jens Geyer5a17b132019-05-26 15:53:37 +0200375 public override async ValueTask<int> ReadI32Async(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100376 {
Jens Geyerdce22992020-05-16 23:02:27 +0200377 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100378
Jens Geyer5a17b132019-05-26 15:53:37 +0200379 await Trans.ReadAllAsync(PreAllocatedBuffer, 0, 4, cancellationToken);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100380
zembord9d958a32019-11-21 13:11:44 +0300381 var result = BinaryPrimitives.ReadInt32BigEndian(PreAllocatedBuffer);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100382
383 return result;
384 }
385
Jens Geyer5a17b132019-05-26 15:53:37 +0200386 public override async ValueTask<long> ReadI64Async(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100387 {
Jens Geyerdce22992020-05-16 23:02:27 +0200388 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100389
Jens Geyer5a17b132019-05-26 15:53:37 +0200390 await Trans.ReadAllAsync(PreAllocatedBuffer, 0, 8, cancellationToken);
zembord9d958a32019-11-21 13:11:44 +0300391 return BinaryPrimitives.ReadInt64BigEndian(PreAllocatedBuffer);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100392 }
393
Jens Geyer5a17b132019-05-26 15:53:37 +0200394 public override async ValueTask<double> ReadDoubleAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100395 {
Jens Geyerdce22992020-05-16 23:02:27 +0200396 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100397
398 var d = await ReadI64Async(cancellationToken);
399 return BitConverter.Int64BitsToDouble(d);
400 }
401
Jens Geyer5a17b132019-05-26 15:53:37 +0200402 public override async ValueTask<byte[]> ReadBinaryAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100403 {
Jens Geyerdce22992020-05-16 23:02:27 +0200404 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100405
406 var size = await ReadI32Async(cancellationToken);
Jens Geyer50806452019-11-23 01:55:58 +0100407 Transport.CheckReadBytesAvailable(size);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100408 var buf = new byte[size];
409 await Trans.ReadAllAsync(buf, 0, size, cancellationToken);
410 return buf;
411 }
412
Jens Geyer62445c12022-06-29 00:00:00 +0200413 public override async ValueTask<Guid> ReadUuidAsync(CancellationToken cancellationToken)
414 {
415 cancellationToken.ThrowIfCancellationRequested();
416
417 Transport.CheckReadBytesAvailable(16); // = sizeof(uuid)
418 var buf = new byte[16];
419 await Trans.ReadAllAsync(buf, 0, 16, cancellationToken);
420 return new Guid(buf).SwapByteOrder();
421 }
422
Jens Geyer5a17b132019-05-26 15:53:37 +0200423 public override async ValueTask<string> ReadStringAsync(CancellationToken cancellationToken)
424 {
Jens Geyerdce22992020-05-16 23:02:27 +0200425 cancellationToken.ThrowIfCancellationRequested();
Jens Geyer5a17b132019-05-26 15:53:37 +0200426
427 var size = await ReadI32Async(cancellationToken);
428 return size > 0 ? await ReadStringBodyAsync(size, cancellationToken) : string.Empty;
429 }
430
431 private async ValueTask<string> ReadStringBodyAsync(int size, CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100432 {
Jens Geyerdce22992020-05-16 23:02:27 +0200433 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100434
Jens Geyer5a17b132019-05-26 15:53:37 +0200435 if (size <= PreAllocatedBuffer.Length)
436 {
437 await Trans.ReadAllAsync(PreAllocatedBuffer, 0, size, cancellationToken);
438 return Encoding.UTF8.GetString(PreAllocatedBuffer, 0, size);
439 }
440
Jens Geyer50806452019-11-23 01:55:58 +0100441 Transport.CheckReadBytesAvailable(size);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100442 var buf = new byte[size];
443 await Trans.ReadAllAsync(buf, 0, size, cancellationToken);
444 return Encoding.UTF8.GetString(buf, 0, buf.Length);
445 }
446
Jens Geyer50806452019-11-23 01:55:58 +0100447 // Return the minimum number of bytes a type will consume on the wire
448 public override int GetMinSerializedSize(TType type)
449 {
450 switch (type)
451 {
452 case TType.Stop: return 0;
453 case TType.Void: return 0;
454 case TType.Bool: return sizeof(byte);
455 case TType.Byte: return sizeof(byte);
456 case TType.Double: return sizeof(double);
457 case TType.I16: return sizeof(short);
458 case TType.I32: return sizeof(int);
459 case TType.I64: return sizeof(long);
460 case TType.String: return sizeof(int); // string length
461 case TType.Struct: return 0; // empty struct
462 case TType.Map: return sizeof(int); // element count
463 case TType.Set: return sizeof(int); // element count
464 case TType.List: return sizeof(int); // element count
Jens Geyer62445c12022-06-29 00:00:00 +0200465 case TType.Uuid: return 16; // uuid bytes
Jens Geyer0d128322021-02-25 09:42:52 +0100466 default: throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "unrecognized type code");
Jens Geyer50806452019-11-23 01:55:58 +0100467 }
468 }
469
Jens Geyer421444f2019-03-20 22:13:25 +0100470 public class Factory : TProtocolFactory
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100471 {
472 protected bool StrictRead;
473 protected bool StrictWrite;
474
475 public Factory()
476 : this(false, true)
477 {
478 }
479
480 public Factory(bool strictRead, bool strictWrite)
481 {
482 StrictRead = strictRead;
483 StrictWrite = strictWrite;
484 }
485
Jens Geyer421444f2019-03-20 22:13:25 +0100486 public override TProtocol GetProtocol(TTransport trans)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100487 {
488 return new TBinaryProtocol(trans, StrictRead, StrictWrite);
489 }
490 }
491 }
Jens Geyer421444f2019-03-20 22:13:25 +0100492}