blob: 6389184a41c5cb545bf2ee87db9a0797ae46815e [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 Geyer4115e952023-11-21 23:00:01 +010027#pragma warning disable IDE0079 // net20 - unneeded suppression
28#pragma warning disable IDE0290 // net8 - primary CTOR
Jens Geyer0d128322021-02-25 09:42:52 +010029
Jens Geyeraa0c8b32019-01-28 23:27:45 +010030namespace Thrift.Protocol
31{
32 // ReSharper disable once InconsistentNaming
33 public class TBinaryProtocol : TProtocol
34 {
Jens Geyeraa0c8b32019-01-28 23:27:45 +010035 protected const uint VersionMask = 0xffff0000;
36 protected const uint Version1 = 0x80010000;
37
Jens Geyer4115e952023-11-21 23:00:01 +010038 protected readonly bool StrictRead;
39 protected readonly bool StrictWrite;
Jens Geyeraa0c8b32019-01-28 23:27:45 +010040
Jens Geyer5a17b132019-05-26 15:53:37 +020041 // minimize memory allocations by means of an preallocated bytes buffer
42 // The value of 128 is arbitrarily chosen, the required minimum size must be sizeof(long)
Jens Geyer0d128322021-02-25 09:42:52 +010043 private readonly byte[] PreAllocatedBuffer = new byte[128];
Jens Geyer5a17b132019-05-26 15:53:37 +020044
Jens Geyeraa0c8b32019-01-28 23:27:45 +010045 public TBinaryProtocol(TTransport trans)
46 : this(trans, false, true)
47 {
48 }
49
50 public TBinaryProtocol(TTransport trans, bool strictRead, bool strictWrite)
51 : base(trans)
52 {
53 StrictRead = strictRead;
54 StrictWrite = strictWrite;
55 }
56
57 public override async Task WriteMessageBeginAsync(TMessage message, CancellationToken cancellationToken)
58 {
Jens Geyerdce22992020-05-16 23:02:27 +020059 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +010060
61 if (StrictWrite)
62 {
63 var version = Version1 | (uint) message.Type;
64 await WriteI32Async((int) version, cancellationToken);
65 await WriteStringAsync(message.Name, cancellationToken);
66 await WriteI32Async(message.SeqID, cancellationToken);
67 }
68 else
69 {
70 await WriteStringAsync(message.Name, cancellationToken);
71 await WriteByteAsync((sbyte) message.Type, cancellationToken);
72 await WriteI32Async(message.SeqID, cancellationToken);
73 }
74 }
75
Jens Geyerdce22992020-05-16 23:02:27 +020076 public override Task WriteMessageEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +010077 {
Jens Geyerdce22992020-05-16 23:02:27 +020078 cancellationToken.ThrowIfCancellationRequested();
79 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +010080 }
81
Jens Geyerdce22992020-05-16 23:02:27 +020082 public override Task WriteStructBeginAsync(TStruct @struct, CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +010083 {
Jens Geyerdce22992020-05-16 23:02:27 +020084 cancellationToken.ThrowIfCancellationRequested();
85 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +010086 }
87
Jens Geyerdce22992020-05-16 23:02:27 +020088 public override Task WriteStructEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +010089 {
Jens Geyerdce22992020-05-16 23:02:27 +020090 cancellationToken.ThrowIfCancellationRequested();
91 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +010092 }
93
94 public override async Task WriteFieldBeginAsync(TField field, CancellationToken cancellationToken)
95 {
Jens Geyerdce22992020-05-16 23:02:27 +020096 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +010097 await WriteByteAsync((sbyte) field.Type, cancellationToken);
98 await WriteI16Async(field.ID, cancellationToken);
99 }
100
Jens Geyerdce22992020-05-16 23:02:27 +0200101 public override Task WriteFieldEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100102 {
Jens Geyerdce22992020-05-16 23:02:27 +0200103 cancellationToken.ThrowIfCancellationRequested();
104 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100105 }
106
107 public override async Task WriteFieldStopAsync(CancellationToken cancellationToken)
108 {
Jens Geyerdce22992020-05-16 23:02:27 +0200109 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100110
111 await WriteByteAsync((sbyte) TType.Stop, cancellationToken);
112 }
113
114 public override async Task WriteMapBeginAsync(TMap map, CancellationToken cancellationToken)
115 {
Jens Geyerdce22992020-05-16 23:02:27 +0200116 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100117
Jens Geyer5a17b132019-05-26 15:53:37 +0200118 PreAllocatedBuffer[0] = (byte)map.KeyType;
119 PreAllocatedBuffer[1] = (byte)map.ValueType;
120 await Trans.WriteAsync(PreAllocatedBuffer, 0, 2, cancellationToken);
121
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100122 await WriteI32Async(map.Count, cancellationToken);
123 }
124
Jens Geyerdce22992020-05-16 23:02:27 +0200125 public override Task WriteMapEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100126 {
Jens Geyerdce22992020-05-16 23:02:27 +0200127 cancellationToken.ThrowIfCancellationRequested();
128 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100129 }
130
131 public override async Task WriteListBeginAsync(TList list, CancellationToken cancellationToken)
132 {
Jens Geyerdce22992020-05-16 23:02:27 +0200133 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100134 await WriteByteAsync((sbyte) list.ElementType, cancellationToken);
135 await WriteI32Async(list.Count, cancellationToken);
136 }
137
Jens Geyerdce22992020-05-16 23:02:27 +0200138 public override Task WriteListEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100139 {
Jens Geyerdce22992020-05-16 23:02:27 +0200140 cancellationToken.ThrowIfCancellationRequested();
141 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100142 }
143
144 public override async Task WriteSetBeginAsync(TSet set, CancellationToken cancellationToken)
145 {
Jens Geyerdce22992020-05-16 23:02:27 +0200146 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100147 await WriteByteAsync((sbyte) set.ElementType, cancellationToken);
148 await WriteI32Async(set.Count, cancellationToken);
149 }
150
Jens Geyerdce22992020-05-16 23:02:27 +0200151 public override Task WriteSetEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100152 {
Jens Geyerdce22992020-05-16 23:02:27 +0200153 cancellationToken.ThrowIfCancellationRequested();
154 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100155 }
156
157 public override async Task WriteBoolAsync(bool b, CancellationToken cancellationToken)
158 {
Jens Geyerdce22992020-05-16 23:02:27 +0200159 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100160 await WriteByteAsync(b ? (sbyte) 1 : (sbyte) 0, cancellationToken);
161 }
162
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100163 public override async Task WriteByteAsync(sbyte b, CancellationToken cancellationToken)
164 {
Jens Geyerdce22992020-05-16 23:02:27 +0200165 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100166
Jens Geyer5a17b132019-05-26 15:53:37 +0200167 PreAllocatedBuffer[0] = (byte)b;
168
169 await Trans.WriteAsync(PreAllocatedBuffer, 0, 1, cancellationToken);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100170 }
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100171 public override async Task WriteI16Async(short i16, CancellationToken cancellationToken)
172 {
Jens Geyerdce22992020-05-16 23:02:27 +0200173 cancellationToken.ThrowIfCancellationRequested();
174
zembord9d958a32019-11-21 13:11:44 +0300175 BinaryPrimitives.WriteInt16BigEndian(PreAllocatedBuffer, i16);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100176
Jens Geyer5a17b132019-05-26 15:53:37 +0200177 await Trans.WriteAsync(PreAllocatedBuffer, 0, 2, cancellationToken);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100178 }
179
180 public override async Task WriteI32Async(int i32, CancellationToken cancellationToken)
181 {
Jens Geyerdce22992020-05-16 23:02:27 +0200182 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100183
zembord9d958a32019-11-21 13:11:44 +0300184 BinaryPrimitives.WriteInt32BigEndian(PreAllocatedBuffer, i32);
Jens Geyer5a17b132019-05-26 15:53:37 +0200185
186 await Trans.WriteAsync(PreAllocatedBuffer, 0, 4, cancellationToken);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100187 }
188
Jens Geyer5a17b132019-05-26 15:53:37 +0200189
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100190 public override async Task WriteI64Async(long i64, CancellationToken cancellationToken)
191 {
Jens Geyerdce22992020-05-16 23:02:27 +0200192 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100193
zembord9d958a32019-11-21 13:11:44 +0300194 BinaryPrimitives.WriteInt64BigEndian(PreAllocatedBuffer, i64);
Jens Geyer5a17b132019-05-26 15:53:37 +0200195
196 await Trans.WriteAsync(PreAllocatedBuffer, 0, 8, cancellationToken);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100197 }
198
199 public override async Task WriteDoubleAsync(double d, CancellationToken cancellationToken)
200 {
Jens Geyerdce22992020-05-16 23:02:27 +0200201 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100202
203 await WriteI64Async(BitConverter.DoubleToInt64Bits(d), cancellationToken);
204 }
205
Jens Geyer5a17b132019-05-26 15:53:37 +0200206
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100207 public override async Task WriteBinaryAsync(byte[] bytes, CancellationToken cancellationToken)
208 {
Jens Geyerdce22992020-05-16 23:02:27 +0200209 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100210
211 await WriteI32Async(bytes.Length, cancellationToken);
212 await Trans.WriteAsync(bytes, 0, bytes.Length, cancellationToken);
213 }
214
Jens Geyer62445c12022-06-29 00:00:00 +0200215 public override async Task WriteUuidAsync(Guid uuid, CancellationToken cancellationToken)
216 {
217 cancellationToken.ThrowIfCancellationRequested();
218
219 var bytes = uuid.SwapByteOrder().ToByteArray();
220 await Trans.WriteAsync(bytes, 0, bytes.Length, cancellationToken);
221 }
222
Jens Geyer5a17b132019-05-26 15:53:37 +0200223 public override async ValueTask<TMessage> ReadMessageBeginAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100224 {
Jens Geyerdce22992020-05-16 23:02:27 +0200225 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100226
227 var message = new TMessage();
228 var size = await ReadI32Async(cancellationToken);
229 if (size < 0)
230 {
231 var version = (uint) size & VersionMask;
232 if (version != Version1)
233 {
234 throw new TProtocolException(TProtocolException.BAD_VERSION,
235 $"Bad version in ReadMessageBegin: {version}");
236 }
237 message.Type = (TMessageType) (size & 0x000000ff);
238 message.Name = await ReadStringAsync(cancellationToken);
239 message.SeqID = await ReadI32Async(cancellationToken);
240 }
241 else
242 {
243 if (StrictRead)
244 {
245 throw new TProtocolException(TProtocolException.BAD_VERSION,
246 "Missing version in ReadMessageBegin, old client?");
247 }
Jens Geyer5a17b132019-05-26 15:53:37 +0200248 message.Name = (size > 0) ? await ReadStringBodyAsync(size, cancellationToken) : string.Empty;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100249 message.Type = (TMessageType) await ReadByteAsync(cancellationToken);
250 message.SeqID = await ReadI32Async(cancellationToken);
251 }
252 return message;
253 }
254
Jens Geyerdce22992020-05-16 23:02:27 +0200255 public override Task ReadMessageEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100256 {
Jens Geyerdce22992020-05-16 23:02:27 +0200257 cancellationToken.ThrowIfCancellationRequested();
Philip Lee2d2790f2022-09-15 12:43:03 +0100258 Transport.ResetConsumedMessageSize();
Jens Geyerdce22992020-05-16 23:02:27 +0200259 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100260 }
261
Jens Geyerdce22992020-05-16 23:02:27 +0200262 public override ValueTask<TStruct> ReadStructBeginAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100263 {
Jens Geyerdce22992020-05-16 23:02:27 +0200264 cancellationToken.ThrowIfCancellationRequested();
265 return new ValueTask<TStruct>(AnonymousStruct);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100266 }
267
Jens Geyerdce22992020-05-16 23:02:27 +0200268 public override Task ReadStructEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100269 {
Jens Geyerdce22992020-05-16 23:02:27 +0200270 cancellationToken.ThrowIfCancellationRequested();
271 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100272 }
273
Jens Geyer5a17b132019-05-26 15:53:37 +0200274 public override async ValueTask<TField> ReadFieldBeginAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100275 {
Jens Geyerdce22992020-05-16 23:02:27 +0200276 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100277
Jens Geyer5a17b132019-05-26 15:53:37 +0200278 var type = (TType)await ReadByteAsync(cancellationToken);
279 if (type == TType.Stop)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100280 {
Jens Geyer5a17b132019-05-26 15:53:37 +0200281 return StopField;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100282 }
283
Jens Geyer5a17b132019-05-26 15:53:37 +0200284 return new TField {
285 Type = type,
286 ID = await ReadI16Async(cancellationToken)
287 };
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100288 }
289
Jens Geyerdce22992020-05-16 23:02:27 +0200290 public override Task ReadFieldEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100291 {
Jens Geyerdce22992020-05-16 23:02:27 +0200292 cancellationToken.ThrowIfCancellationRequested();
293 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100294 }
295
Jens Geyer5a17b132019-05-26 15:53:37 +0200296 public override async ValueTask<TMap> ReadMapBeginAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100297 {
Jens Geyerdce22992020-05-16 23:02:27 +0200298 cancellationToken.ThrowIfCancellationRequested();
299
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100300 var map = new TMap
301 {
302 KeyType = (TType) await ReadByteAsync(cancellationToken),
303 ValueType = (TType) await ReadByteAsync(cancellationToken),
304 Count = await ReadI32Async(cancellationToken)
305 };
Jens Geyer50806452019-11-23 01:55:58 +0100306 CheckReadBytesAvailable(map);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100307 return map;
308 }
309
Jens Geyerdce22992020-05-16 23:02:27 +0200310 public override Task ReadMapEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100311 {
Jens Geyerdce22992020-05-16 23:02:27 +0200312 cancellationToken.ThrowIfCancellationRequested();
313 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100314 }
315
Jens Geyer5a17b132019-05-26 15:53:37 +0200316 public override async ValueTask<TList> ReadListBeginAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100317 {
Jens Geyerdce22992020-05-16 23:02:27 +0200318 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100319
320 var list = new TList
321 {
322 ElementType = (TType) await ReadByteAsync(cancellationToken),
323 Count = await ReadI32Async(cancellationToken)
324 };
Jens Geyer50806452019-11-23 01:55:58 +0100325 CheckReadBytesAvailable(list);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100326 return list;
327 }
328
Jens Geyerdce22992020-05-16 23:02:27 +0200329 public override Task ReadListEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100330 {
Jens Geyerdce22992020-05-16 23:02:27 +0200331 cancellationToken.ThrowIfCancellationRequested();
332 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100333 }
334
Jens Geyer5a17b132019-05-26 15:53:37 +0200335 public override async ValueTask<TSet> ReadSetBeginAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100336 {
Jens Geyerdce22992020-05-16 23:02:27 +0200337 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100338
339 var set = new TSet
340 {
341 ElementType = (TType) await ReadByteAsync(cancellationToken),
342 Count = await ReadI32Async(cancellationToken)
343 };
Jens Geyer50806452019-11-23 01:55:58 +0100344 CheckReadBytesAvailable(set);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100345 return set;
346 }
347
Jens Geyerdce22992020-05-16 23:02:27 +0200348 public override Task ReadSetEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100349 {
Jens Geyerdce22992020-05-16 23:02:27 +0200350 cancellationToken.ThrowIfCancellationRequested();
351 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100352 }
353
Jens Geyer5a17b132019-05-26 15:53:37 +0200354 public override async ValueTask<bool> ReadBoolAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100355 {
Jens Geyerdce22992020-05-16 23:02:27 +0200356 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100357
358 return await ReadByteAsync(cancellationToken) == 1;
359 }
360
Jens Geyer5a17b132019-05-26 15:53:37 +0200361 public override async ValueTask<sbyte> ReadByteAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100362 {
Jens Geyerdce22992020-05-16 23:02:27 +0200363 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100364
Jens Geyer5a17b132019-05-26 15:53:37 +0200365 await Trans.ReadAllAsync(PreAllocatedBuffer, 0, 1, cancellationToken);
366 return (sbyte)PreAllocatedBuffer[0];
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100367 }
368
Jens Geyer5a17b132019-05-26 15:53:37 +0200369 public override async ValueTask<short> ReadI16Async(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100370 {
Jens Geyerdce22992020-05-16 23:02:27 +0200371 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100372
Jens Geyer5a17b132019-05-26 15:53:37 +0200373 await Trans.ReadAllAsync(PreAllocatedBuffer, 0, 2, cancellationToken);
zembord9d958a32019-11-21 13:11:44 +0300374 var result = BinaryPrimitives.ReadInt16BigEndian(PreAllocatedBuffer);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100375 return result;
376 }
377
Jens Geyer5a17b132019-05-26 15:53:37 +0200378 public override async ValueTask<int> ReadI32Async(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100379 {
Jens Geyerdce22992020-05-16 23:02:27 +0200380 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100381
Jens Geyer5a17b132019-05-26 15:53:37 +0200382 await Trans.ReadAllAsync(PreAllocatedBuffer, 0, 4, cancellationToken);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100383
zembord9d958a32019-11-21 13:11:44 +0300384 var result = BinaryPrimitives.ReadInt32BigEndian(PreAllocatedBuffer);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100385
386 return result;
387 }
388
Jens Geyer5a17b132019-05-26 15:53:37 +0200389 public override async ValueTask<long> ReadI64Async(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100390 {
Jens Geyerdce22992020-05-16 23:02:27 +0200391 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100392
Jens Geyer5a17b132019-05-26 15:53:37 +0200393 await Trans.ReadAllAsync(PreAllocatedBuffer, 0, 8, cancellationToken);
zembord9d958a32019-11-21 13:11:44 +0300394 return BinaryPrimitives.ReadInt64BigEndian(PreAllocatedBuffer);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100395 }
396
Jens Geyer5a17b132019-05-26 15:53:37 +0200397 public override async ValueTask<double> ReadDoubleAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100398 {
Jens Geyerdce22992020-05-16 23:02:27 +0200399 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100400
401 var d = await ReadI64Async(cancellationToken);
402 return BitConverter.Int64BitsToDouble(d);
403 }
404
Jens Geyer5a17b132019-05-26 15:53:37 +0200405 public override async ValueTask<byte[]> ReadBinaryAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100406 {
Jens Geyerdce22992020-05-16 23:02:27 +0200407 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100408
409 var size = await ReadI32Async(cancellationToken);
Jens Geyer50806452019-11-23 01:55:58 +0100410 Transport.CheckReadBytesAvailable(size);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100411 var buf = new byte[size];
412 await Trans.ReadAllAsync(buf, 0, size, cancellationToken);
413 return buf;
414 }
415
Jens Geyer62445c12022-06-29 00:00:00 +0200416 public override async ValueTask<Guid> ReadUuidAsync(CancellationToken cancellationToken)
417 {
418 cancellationToken.ThrowIfCancellationRequested();
419
420 Transport.CheckReadBytesAvailable(16); // = sizeof(uuid)
421 var buf = new byte[16];
422 await Trans.ReadAllAsync(buf, 0, 16, cancellationToken);
423 return new Guid(buf).SwapByteOrder();
424 }
425
Jens Geyer5a17b132019-05-26 15:53:37 +0200426 public override async ValueTask<string> ReadStringAsync(CancellationToken cancellationToken)
427 {
Jens Geyerdce22992020-05-16 23:02:27 +0200428 cancellationToken.ThrowIfCancellationRequested();
Jens Geyer5a17b132019-05-26 15:53:37 +0200429
430 var size = await ReadI32Async(cancellationToken);
431 return size > 0 ? await ReadStringBodyAsync(size, cancellationToken) : string.Empty;
432 }
433
434 private async ValueTask<string> ReadStringBodyAsync(int size, CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100435 {
Jens Geyerdce22992020-05-16 23:02:27 +0200436 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100437
Jens Geyer5a17b132019-05-26 15:53:37 +0200438 if (size <= PreAllocatedBuffer.Length)
439 {
440 await Trans.ReadAllAsync(PreAllocatedBuffer, 0, size, cancellationToken);
441 return Encoding.UTF8.GetString(PreAllocatedBuffer, 0, size);
442 }
443
Jens Geyer50806452019-11-23 01:55:58 +0100444 Transport.CheckReadBytesAvailable(size);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100445 var buf = new byte[size];
446 await Trans.ReadAllAsync(buf, 0, size, cancellationToken);
447 return Encoding.UTF8.GetString(buf, 0, buf.Length);
448 }
449
Jens Geyer50806452019-11-23 01:55:58 +0100450 // Return the minimum number of bytes a type will consume on the wire
451 public override int GetMinSerializedSize(TType type)
452 {
453 switch (type)
454 {
455 case TType.Stop: return 0;
456 case TType.Void: return 0;
457 case TType.Bool: return sizeof(byte);
458 case TType.Byte: return sizeof(byte);
459 case TType.Double: return sizeof(double);
460 case TType.I16: return sizeof(short);
461 case TType.I32: return sizeof(int);
462 case TType.I64: return sizeof(long);
463 case TType.String: return sizeof(int); // string length
464 case TType.Struct: return 0; // empty struct
465 case TType.Map: return sizeof(int); // element count
466 case TType.Set: return sizeof(int); // element count
467 case TType.List: return sizeof(int); // element count
Jens Geyer62445c12022-06-29 00:00:00 +0200468 case TType.Uuid: return 16; // uuid bytes
Jens Geyer0d128322021-02-25 09:42:52 +0100469 default: throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "unrecognized type code");
Jens Geyer50806452019-11-23 01:55:58 +0100470 }
471 }
472
Jens Geyer421444f2019-03-20 22:13:25 +0100473 public class Factory : TProtocolFactory
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100474 {
Jens Geyer4115e952023-11-21 23:00:01 +0100475 protected readonly bool StrictRead;
476 protected readonly bool StrictWrite;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100477
Jens Geyer4115e952023-11-21 23:00:01 +0100478 public Factory(bool strictRead = false, bool strictWrite = true)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100479 {
480 StrictRead = strictRead;
481 StrictWrite = strictWrite;
482 }
483
Jens Geyer421444f2019-03-20 22:13:25 +0100484 public override TProtocol GetProtocol(TTransport trans)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100485 {
486 return new TBinaryProtocol(trans, StrictRead, StrictWrite);
487 }
488 }
489 }
Jens Geyer421444f2019-03-20 22:13:25 +0100490}