blob: 9c234691917d31d019dc58fcb25836ea3c3eb43d [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#pragma warning disable IDE0079 // unnecessary suppression
27#pragma warning disable IDE0066 // use switch expression
28
Jens Geyeraa0c8b32019-01-28 23:27:45 +010029namespace Thrift.Protocol
30{
31 // ReSharper disable once InconsistentNaming
32 public class TBinaryProtocol : TProtocol
33 {
Jens Geyeraa0c8b32019-01-28 23:27:45 +010034 protected const uint VersionMask = 0xffff0000;
35 protected const uint Version1 = 0x80010000;
36
37 protected bool StrictRead;
38 protected bool StrictWrite;
39
Jens Geyer5a17b132019-05-26 15:53:37 +020040 // minimize memory allocations by means of an preallocated bytes buffer
41 // The value of 128 is arbitrarily chosen, the required minimum size must be sizeof(long)
Jens Geyer0d128322021-02-25 09:42:52 +010042 private readonly byte[] PreAllocatedBuffer = new byte[128];
Jens Geyer5a17b132019-05-26 15:53:37 +020043
Jens Geyeraa0c8b32019-01-28 23:27:45 +010044 public TBinaryProtocol(TTransport trans)
45 : this(trans, false, true)
46 {
47 }
48
49 public TBinaryProtocol(TTransport trans, bool strictRead, bool strictWrite)
50 : base(trans)
51 {
52 StrictRead = strictRead;
53 StrictWrite = strictWrite;
54 }
55
56 public override async Task WriteMessageBeginAsync(TMessage message, CancellationToken cancellationToken)
57 {
Jens Geyerdce22992020-05-16 23:02:27 +020058 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +010059
60 if (StrictWrite)
61 {
62 var version = Version1 | (uint) message.Type;
63 await WriteI32Async((int) version, cancellationToken);
64 await WriteStringAsync(message.Name, cancellationToken);
65 await WriteI32Async(message.SeqID, cancellationToken);
66 }
67 else
68 {
69 await WriteStringAsync(message.Name, cancellationToken);
70 await WriteByteAsync((sbyte) message.Type, cancellationToken);
71 await WriteI32Async(message.SeqID, cancellationToken);
72 }
73 }
74
Jens Geyerdce22992020-05-16 23:02:27 +020075 public override Task WriteMessageEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +010076 {
Jens Geyerdce22992020-05-16 23:02:27 +020077 cancellationToken.ThrowIfCancellationRequested();
78 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +010079 }
80
Jens Geyerdce22992020-05-16 23:02:27 +020081 public override Task WriteStructBeginAsync(TStruct @struct, CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +010082 {
Jens Geyerdce22992020-05-16 23:02:27 +020083 cancellationToken.ThrowIfCancellationRequested();
84 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +010085 }
86
Jens Geyerdce22992020-05-16 23:02:27 +020087 public override Task WriteStructEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +010088 {
Jens Geyerdce22992020-05-16 23:02:27 +020089 cancellationToken.ThrowIfCancellationRequested();
90 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +010091 }
92
93 public override async Task WriteFieldBeginAsync(TField field, CancellationToken cancellationToken)
94 {
Jens Geyerdce22992020-05-16 23:02:27 +020095 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +010096 await WriteByteAsync((sbyte) field.Type, cancellationToken);
97 await WriteI16Async(field.ID, cancellationToken);
98 }
99
Jens Geyerdce22992020-05-16 23:02:27 +0200100 public override Task WriteFieldEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100101 {
Jens Geyerdce22992020-05-16 23:02:27 +0200102 cancellationToken.ThrowIfCancellationRequested();
103 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100104 }
105
106 public override async Task WriteFieldStopAsync(CancellationToken cancellationToken)
107 {
Jens Geyerdce22992020-05-16 23:02:27 +0200108 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100109
110 await WriteByteAsync((sbyte) TType.Stop, cancellationToken);
111 }
112
113 public override async Task WriteMapBeginAsync(TMap map, CancellationToken cancellationToken)
114 {
Jens Geyerdce22992020-05-16 23:02:27 +0200115 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100116
Jens Geyer5a17b132019-05-26 15:53:37 +0200117 PreAllocatedBuffer[0] = (byte)map.KeyType;
118 PreAllocatedBuffer[1] = (byte)map.ValueType;
119 await Trans.WriteAsync(PreAllocatedBuffer, 0, 2, cancellationToken);
120
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100121 await WriteI32Async(map.Count, cancellationToken);
122 }
123
Jens Geyerdce22992020-05-16 23:02:27 +0200124 public override Task WriteMapEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100125 {
Jens Geyerdce22992020-05-16 23:02:27 +0200126 cancellationToken.ThrowIfCancellationRequested();
127 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100128 }
129
130 public override async Task WriteListBeginAsync(TList list, CancellationToken cancellationToken)
131 {
Jens Geyerdce22992020-05-16 23:02:27 +0200132 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100133 await WriteByteAsync((sbyte) list.ElementType, cancellationToken);
134 await WriteI32Async(list.Count, cancellationToken);
135 }
136
Jens Geyerdce22992020-05-16 23:02:27 +0200137 public override Task WriteListEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100138 {
Jens Geyerdce22992020-05-16 23:02:27 +0200139 cancellationToken.ThrowIfCancellationRequested();
140 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100141 }
142
143 public override async Task WriteSetBeginAsync(TSet set, CancellationToken cancellationToken)
144 {
Jens Geyerdce22992020-05-16 23:02:27 +0200145 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100146 await WriteByteAsync((sbyte) set.ElementType, cancellationToken);
147 await WriteI32Async(set.Count, cancellationToken);
148 }
149
Jens Geyerdce22992020-05-16 23:02:27 +0200150 public override Task WriteSetEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100151 {
Jens Geyerdce22992020-05-16 23:02:27 +0200152 cancellationToken.ThrowIfCancellationRequested();
153 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100154 }
155
156 public override async Task WriteBoolAsync(bool b, CancellationToken cancellationToken)
157 {
Jens Geyerdce22992020-05-16 23:02:27 +0200158 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100159 await WriteByteAsync(b ? (sbyte) 1 : (sbyte) 0, cancellationToken);
160 }
161
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100162 public override async Task WriteByteAsync(sbyte b, CancellationToken cancellationToken)
163 {
Jens Geyerdce22992020-05-16 23:02:27 +0200164 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100165
Jens Geyer5a17b132019-05-26 15:53:37 +0200166 PreAllocatedBuffer[0] = (byte)b;
167
168 await Trans.WriteAsync(PreAllocatedBuffer, 0, 1, cancellationToken);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100169 }
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100170 public override async Task WriteI16Async(short i16, CancellationToken cancellationToken)
171 {
Jens Geyerdce22992020-05-16 23:02:27 +0200172 cancellationToken.ThrowIfCancellationRequested();
173
zembord9d958a32019-11-21 13:11:44 +0300174 BinaryPrimitives.WriteInt16BigEndian(PreAllocatedBuffer, i16);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100175
Jens Geyer5a17b132019-05-26 15:53:37 +0200176 await Trans.WriteAsync(PreAllocatedBuffer, 0, 2, cancellationToken);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100177 }
178
179 public override async Task WriteI32Async(int i32, CancellationToken cancellationToken)
180 {
Jens Geyerdce22992020-05-16 23:02:27 +0200181 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100182
zembord9d958a32019-11-21 13:11:44 +0300183 BinaryPrimitives.WriteInt32BigEndian(PreAllocatedBuffer, i32);
Jens Geyer5a17b132019-05-26 15:53:37 +0200184
185 await Trans.WriteAsync(PreAllocatedBuffer, 0, 4, cancellationToken);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100186 }
187
Jens Geyer5a17b132019-05-26 15:53:37 +0200188
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100189 public override async Task WriteI64Async(long i64, CancellationToken cancellationToken)
190 {
Jens Geyerdce22992020-05-16 23:02:27 +0200191 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100192
zembord9d958a32019-11-21 13:11:44 +0300193 BinaryPrimitives.WriteInt64BigEndian(PreAllocatedBuffer, i64);
Jens Geyer5a17b132019-05-26 15:53:37 +0200194
195 await Trans.WriteAsync(PreAllocatedBuffer, 0, 8, cancellationToken);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100196 }
197
198 public override async Task WriteDoubleAsync(double d, CancellationToken cancellationToken)
199 {
Jens Geyerdce22992020-05-16 23:02:27 +0200200 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100201
202 await WriteI64Async(BitConverter.DoubleToInt64Bits(d), cancellationToken);
203 }
204
Jens Geyer5a17b132019-05-26 15:53:37 +0200205
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100206 public override async Task WriteBinaryAsync(byte[] bytes, CancellationToken cancellationToken)
207 {
Jens Geyerdce22992020-05-16 23:02:27 +0200208 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100209
210 await WriteI32Async(bytes.Length, cancellationToken);
211 await Trans.WriteAsync(bytes, 0, bytes.Length, cancellationToken);
212 }
213
Jens Geyer5a17b132019-05-26 15:53:37 +0200214 public override async ValueTask<TMessage> ReadMessageBeginAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100215 {
Jens Geyerdce22992020-05-16 23:02:27 +0200216 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100217
218 var message = new TMessage();
219 var size = await ReadI32Async(cancellationToken);
220 if (size < 0)
221 {
222 var version = (uint) size & VersionMask;
223 if (version != Version1)
224 {
225 throw new TProtocolException(TProtocolException.BAD_VERSION,
226 $"Bad version in ReadMessageBegin: {version}");
227 }
228 message.Type = (TMessageType) (size & 0x000000ff);
229 message.Name = await ReadStringAsync(cancellationToken);
230 message.SeqID = await ReadI32Async(cancellationToken);
231 }
232 else
233 {
234 if (StrictRead)
235 {
236 throw new TProtocolException(TProtocolException.BAD_VERSION,
237 "Missing version in ReadMessageBegin, old client?");
238 }
Jens Geyer5a17b132019-05-26 15:53:37 +0200239 message.Name = (size > 0) ? await ReadStringBodyAsync(size, cancellationToken) : string.Empty;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100240 message.Type = (TMessageType) await ReadByteAsync(cancellationToken);
241 message.SeqID = await ReadI32Async(cancellationToken);
242 }
243 return message;
244 }
245
Jens Geyerdce22992020-05-16 23:02:27 +0200246 public override Task ReadMessageEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100247 {
Jens Geyerdce22992020-05-16 23:02:27 +0200248 cancellationToken.ThrowIfCancellationRequested();
249 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100250 }
251
Jens Geyerdce22992020-05-16 23:02:27 +0200252 public override ValueTask<TStruct> ReadStructBeginAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100253 {
Jens Geyerdce22992020-05-16 23:02:27 +0200254 cancellationToken.ThrowIfCancellationRequested();
255 return new ValueTask<TStruct>(AnonymousStruct);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100256 }
257
Jens Geyerdce22992020-05-16 23:02:27 +0200258 public override Task ReadStructEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100259 {
Jens Geyerdce22992020-05-16 23:02:27 +0200260 cancellationToken.ThrowIfCancellationRequested();
261 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100262 }
263
Jens Geyer5a17b132019-05-26 15:53:37 +0200264 public override async ValueTask<TField> ReadFieldBeginAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100265 {
Jens Geyerdce22992020-05-16 23:02:27 +0200266 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100267
Jens Geyer5a17b132019-05-26 15:53:37 +0200268 var type = (TType)await ReadByteAsync(cancellationToken);
269 if (type == TType.Stop)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100270 {
Jens Geyer5a17b132019-05-26 15:53:37 +0200271 return StopField;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100272 }
273
Jens Geyer5a17b132019-05-26 15:53:37 +0200274 return new TField {
275 Type = type,
276 ID = await ReadI16Async(cancellationToken)
277 };
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100278 }
279
Jens Geyerdce22992020-05-16 23:02:27 +0200280 public override Task ReadFieldEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100281 {
Jens Geyerdce22992020-05-16 23:02:27 +0200282 cancellationToken.ThrowIfCancellationRequested();
283 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100284 }
285
Jens Geyer5a17b132019-05-26 15:53:37 +0200286 public override async ValueTask<TMap> ReadMapBeginAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100287 {
Jens Geyerdce22992020-05-16 23:02:27 +0200288 cancellationToken.ThrowIfCancellationRequested();
289
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100290 var map = new TMap
291 {
292 KeyType = (TType) await ReadByteAsync(cancellationToken),
293 ValueType = (TType) await ReadByteAsync(cancellationToken),
294 Count = await ReadI32Async(cancellationToken)
295 };
Jens Geyer50806452019-11-23 01:55:58 +0100296 CheckReadBytesAvailable(map);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100297 return map;
298 }
299
Jens Geyerdce22992020-05-16 23:02:27 +0200300 public override Task ReadMapEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100301 {
Jens Geyerdce22992020-05-16 23:02:27 +0200302 cancellationToken.ThrowIfCancellationRequested();
303 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100304 }
305
Jens Geyer5a17b132019-05-26 15:53:37 +0200306 public override async ValueTask<TList> ReadListBeginAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100307 {
Jens Geyerdce22992020-05-16 23:02:27 +0200308 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100309
310 var list = new TList
311 {
312 ElementType = (TType) await ReadByteAsync(cancellationToken),
313 Count = await ReadI32Async(cancellationToken)
314 };
Jens Geyer50806452019-11-23 01:55:58 +0100315 CheckReadBytesAvailable(list);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100316 return list;
317 }
318
Jens Geyerdce22992020-05-16 23:02:27 +0200319 public override Task ReadListEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100320 {
Jens Geyerdce22992020-05-16 23:02:27 +0200321 cancellationToken.ThrowIfCancellationRequested();
322 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100323 }
324
Jens Geyer5a17b132019-05-26 15:53:37 +0200325 public override async ValueTask<TSet> ReadSetBeginAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100326 {
Jens Geyerdce22992020-05-16 23:02:27 +0200327 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100328
329 var set = new TSet
330 {
331 ElementType = (TType) await ReadByteAsync(cancellationToken),
332 Count = await ReadI32Async(cancellationToken)
333 };
Jens Geyer50806452019-11-23 01:55:58 +0100334 CheckReadBytesAvailable(set);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100335 return set;
336 }
337
Jens Geyerdce22992020-05-16 23:02:27 +0200338 public override Task ReadSetEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100339 {
Jens Geyerdce22992020-05-16 23:02:27 +0200340 cancellationToken.ThrowIfCancellationRequested();
341 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100342 }
343
Jens Geyer5a17b132019-05-26 15:53:37 +0200344 public override async ValueTask<bool> ReadBoolAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100345 {
Jens Geyerdce22992020-05-16 23:02:27 +0200346 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100347
348 return await ReadByteAsync(cancellationToken) == 1;
349 }
350
Jens Geyer5a17b132019-05-26 15:53:37 +0200351 public override async ValueTask<sbyte> ReadByteAsync(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
Jens Geyer5a17b132019-05-26 15:53:37 +0200355 await Trans.ReadAllAsync(PreAllocatedBuffer, 0, 1, cancellationToken);
356 return (sbyte)PreAllocatedBuffer[0];
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100357 }
358
Jens Geyer5a17b132019-05-26 15:53:37 +0200359 public override async ValueTask<short> ReadI16Async(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100360 {
Jens Geyerdce22992020-05-16 23:02:27 +0200361 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100362
Jens Geyer5a17b132019-05-26 15:53:37 +0200363 await Trans.ReadAllAsync(PreAllocatedBuffer, 0, 2, cancellationToken);
zembord9d958a32019-11-21 13:11:44 +0300364 var result = BinaryPrimitives.ReadInt16BigEndian(PreAllocatedBuffer);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100365 return result;
366 }
367
Jens Geyer5a17b132019-05-26 15:53:37 +0200368 public override async ValueTask<int> ReadI32Async(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100369 {
Jens Geyerdce22992020-05-16 23:02:27 +0200370 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100371
Jens Geyer5a17b132019-05-26 15:53:37 +0200372 await Trans.ReadAllAsync(PreAllocatedBuffer, 0, 4, cancellationToken);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100373
zembord9d958a32019-11-21 13:11:44 +0300374 var result = BinaryPrimitives.ReadInt32BigEndian(PreAllocatedBuffer);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100375
376 return result;
377 }
378
Jens Geyer5a17b132019-05-26 15:53:37 +0200379 public override async ValueTask<long> ReadI64Async(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100380 {
Jens Geyerdce22992020-05-16 23:02:27 +0200381 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100382
Jens Geyer5a17b132019-05-26 15:53:37 +0200383 await Trans.ReadAllAsync(PreAllocatedBuffer, 0, 8, cancellationToken);
zembord9d958a32019-11-21 13:11:44 +0300384 return BinaryPrimitives.ReadInt64BigEndian(PreAllocatedBuffer);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100385 }
386
Jens Geyer5a17b132019-05-26 15:53:37 +0200387 public override async ValueTask<double> ReadDoubleAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100388 {
Jens Geyerdce22992020-05-16 23:02:27 +0200389 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100390
391 var d = await ReadI64Async(cancellationToken);
392 return BitConverter.Int64BitsToDouble(d);
393 }
394
Jens Geyer5a17b132019-05-26 15:53:37 +0200395 public override async ValueTask<byte[]> ReadBinaryAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100396 {
Jens Geyerdce22992020-05-16 23:02:27 +0200397 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100398
399 var size = await ReadI32Async(cancellationToken);
Jens Geyer50806452019-11-23 01:55:58 +0100400 Transport.CheckReadBytesAvailable(size);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100401 var buf = new byte[size];
402 await Trans.ReadAllAsync(buf, 0, size, cancellationToken);
403 return buf;
404 }
405
Jens Geyer5a17b132019-05-26 15:53:37 +0200406 public override async ValueTask<string> ReadStringAsync(CancellationToken cancellationToken)
407 {
Jens Geyerdce22992020-05-16 23:02:27 +0200408 cancellationToken.ThrowIfCancellationRequested();
Jens Geyer5a17b132019-05-26 15:53:37 +0200409
410 var size = await ReadI32Async(cancellationToken);
411 return size > 0 ? await ReadStringBodyAsync(size, cancellationToken) : string.Empty;
412 }
413
414 private async ValueTask<string> ReadStringBodyAsync(int size, CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100415 {
Jens Geyerdce22992020-05-16 23:02:27 +0200416 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100417
Jens Geyer5a17b132019-05-26 15:53:37 +0200418 if (size <= PreAllocatedBuffer.Length)
419 {
420 await Trans.ReadAllAsync(PreAllocatedBuffer, 0, size, cancellationToken);
421 return Encoding.UTF8.GetString(PreAllocatedBuffer, 0, size);
422 }
423
Jens Geyer50806452019-11-23 01:55:58 +0100424 Transport.CheckReadBytesAvailable(size);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100425 var buf = new byte[size];
426 await Trans.ReadAllAsync(buf, 0, size, cancellationToken);
427 return Encoding.UTF8.GetString(buf, 0, buf.Length);
428 }
429
Jens Geyer50806452019-11-23 01:55:58 +0100430 // Return the minimum number of bytes a type will consume on the wire
431 public override int GetMinSerializedSize(TType type)
432 {
433 switch (type)
434 {
435 case TType.Stop: return 0;
436 case TType.Void: return 0;
437 case TType.Bool: return sizeof(byte);
438 case TType.Byte: return sizeof(byte);
439 case TType.Double: return sizeof(double);
440 case TType.I16: return sizeof(short);
441 case TType.I32: return sizeof(int);
442 case TType.I64: return sizeof(long);
443 case TType.String: return sizeof(int); // string length
444 case TType.Struct: return 0; // empty struct
445 case TType.Map: return sizeof(int); // element count
446 case TType.Set: return sizeof(int); // element count
447 case TType.List: return sizeof(int); // element count
Jens Geyer0d128322021-02-25 09:42:52 +0100448 default: throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "unrecognized type code");
Jens Geyer50806452019-11-23 01:55:58 +0100449 }
450 }
451
Jens Geyer421444f2019-03-20 22:13:25 +0100452 public class Factory : TProtocolFactory
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100453 {
454 protected bool StrictRead;
455 protected bool StrictWrite;
456
457 public Factory()
458 : this(false, true)
459 {
460 }
461
462 public Factory(bool strictRead, bool strictWrite)
463 {
464 StrictRead = strictRead;
465 StrictWrite = strictWrite;
466 }
467
Jens Geyer421444f2019-03-20 22:13:25 +0100468 public override TProtocol GetProtocol(TTransport trans)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100469 {
470 return new TBinaryProtocol(trans, StrictRead, StrictWrite);
471 }
472 }
473 }
Jens Geyer421444f2019-03-20 22:13:25 +0100474}