blob: 28b7d297839610bfafaac25997773c3115d236ce [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
26namespace Thrift.Protocol
27{
28 // ReSharper disable once InconsistentNaming
29 public class TBinaryProtocol : TProtocol
30 {
Jens Geyeraa0c8b32019-01-28 23:27:45 +010031 protected const uint VersionMask = 0xffff0000;
32 protected const uint Version1 = 0x80010000;
33
34 protected bool StrictRead;
35 protected bool StrictWrite;
36
Jens Geyer5a17b132019-05-26 15:53:37 +020037 // minimize memory allocations by means of an preallocated bytes buffer
38 // The value of 128 is arbitrarily chosen, the required minimum size must be sizeof(long)
39 private byte[] PreAllocatedBuffer = new byte[128];
40
Jens Geyeraa0c8b32019-01-28 23:27:45 +010041 public TBinaryProtocol(TTransport trans)
42 : this(trans, false, true)
43 {
44 }
45
46 public TBinaryProtocol(TTransport trans, bool strictRead, bool strictWrite)
47 : base(trans)
48 {
49 StrictRead = strictRead;
50 StrictWrite = strictWrite;
51 }
52
53 public override async Task WriteMessageBeginAsync(TMessage message, CancellationToken cancellationToken)
54 {
Jens Geyerdce22992020-05-16 23:02:27 +020055 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +010056
57 if (StrictWrite)
58 {
59 var version = Version1 | (uint) message.Type;
60 await WriteI32Async((int) version, cancellationToken);
61 await WriteStringAsync(message.Name, cancellationToken);
62 await WriteI32Async(message.SeqID, cancellationToken);
63 }
64 else
65 {
66 await WriteStringAsync(message.Name, cancellationToken);
67 await WriteByteAsync((sbyte) message.Type, cancellationToken);
68 await WriteI32Async(message.SeqID, cancellationToken);
69 }
70 }
71
Jens Geyerdce22992020-05-16 23:02:27 +020072 public override Task WriteMessageEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +010073 {
Jens Geyerdce22992020-05-16 23:02:27 +020074 cancellationToken.ThrowIfCancellationRequested();
75 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +010076 }
77
Jens Geyerdce22992020-05-16 23:02:27 +020078 public override Task WriteStructBeginAsync(TStruct @struct, CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +010079 {
Jens Geyerdce22992020-05-16 23:02:27 +020080 cancellationToken.ThrowIfCancellationRequested();
81 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +010082 }
83
Jens Geyerdce22992020-05-16 23:02:27 +020084 public override Task WriteStructEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +010085 {
Jens Geyerdce22992020-05-16 23:02:27 +020086 cancellationToken.ThrowIfCancellationRequested();
87 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +010088 }
89
90 public override async Task WriteFieldBeginAsync(TField field, CancellationToken cancellationToken)
91 {
Jens Geyerdce22992020-05-16 23:02:27 +020092 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +010093 await WriteByteAsync((sbyte) field.Type, cancellationToken);
94 await WriteI16Async(field.ID, cancellationToken);
95 }
96
Jens Geyerdce22992020-05-16 23:02:27 +020097 public override Task WriteFieldEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +010098 {
Jens Geyerdce22992020-05-16 23:02:27 +020099 cancellationToken.ThrowIfCancellationRequested();
100 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100101 }
102
103 public override async Task WriteFieldStopAsync(CancellationToken cancellationToken)
104 {
Jens Geyerdce22992020-05-16 23:02:27 +0200105 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100106
107 await WriteByteAsync((sbyte) TType.Stop, cancellationToken);
108 }
109
110 public override async Task WriteMapBeginAsync(TMap map, CancellationToken cancellationToken)
111 {
Jens Geyerdce22992020-05-16 23:02:27 +0200112 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100113
Jens Geyer5a17b132019-05-26 15:53:37 +0200114 PreAllocatedBuffer[0] = (byte)map.KeyType;
115 PreAllocatedBuffer[1] = (byte)map.ValueType;
116 await Trans.WriteAsync(PreAllocatedBuffer, 0, 2, cancellationToken);
117
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100118 await WriteI32Async(map.Count, cancellationToken);
119 }
120
Jens Geyerdce22992020-05-16 23:02:27 +0200121 public override Task WriteMapEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100122 {
Jens Geyerdce22992020-05-16 23:02:27 +0200123 cancellationToken.ThrowIfCancellationRequested();
124 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100125 }
126
127 public override async Task WriteListBeginAsync(TList list, CancellationToken cancellationToken)
128 {
Jens Geyerdce22992020-05-16 23:02:27 +0200129 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100130 await WriteByteAsync((sbyte) list.ElementType, cancellationToken);
131 await WriteI32Async(list.Count, cancellationToken);
132 }
133
Jens Geyerdce22992020-05-16 23:02:27 +0200134 public override Task WriteListEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100135 {
Jens Geyerdce22992020-05-16 23:02:27 +0200136 cancellationToken.ThrowIfCancellationRequested();
137 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100138 }
139
140 public override async Task WriteSetBeginAsync(TSet set, CancellationToken cancellationToken)
141 {
Jens Geyerdce22992020-05-16 23:02:27 +0200142 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100143 await WriteByteAsync((sbyte) set.ElementType, cancellationToken);
144 await WriteI32Async(set.Count, cancellationToken);
145 }
146
Jens Geyerdce22992020-05-16 23:02:27 +0200147 public override Task WriteSetEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100148 {
Jens Geyerdce22992020-05-16 23:02:27 +0200149 cancellationToken.ThrowIfCancellationRequested();
150 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100151 }
152
153 public override async Task WriteBoolAsync(bool b, CancellationToken cancellationToken)
154 {
Jens Geyerdce22992020-05-16 23:02:27 +0200155 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100156 await WriteByteAsync(b ? (sbyte) 1 : (sbyte) 0, cancellationToken);
157 }
158
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100159 public override async Task WriteByteAsync(sbyte b, CancellationToken cancellationToken)
160 {
Jens Geyerdce22992020-05-16 23:02:27 +0200161 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100162
Jens Geyer5a17b132019-05-26 15:53:37 +0200163 PreAllocatedBuffer[0] = (byte)b;
164
165 await Trans.WriteAsync(PreAllocatedBuffer, 0, 1, cancellationToken);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100166 }
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100167 public override async Task WriteI16Async(short i16, CancellationToken cancellationToken)
168 {
Jens Geyerdce22992020-05-16 23:02:27 +0200169 cancellationToken.ThrowIfCancellationRequested();
170
zembord9d958a32019-11-21 13:11:44 +0300171 BinaryPrimitives.WriteInt16BigEndian(PreAllocatedBuffer, i16);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100172
Jens Geyer5a17b132019-05-26 15:53:37 +0200173 await Trans.WriteAsync(PreAllocatedBuffer, 0, 2, cancellationToken);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100174 }
175
176 public override async Task WriteI32Async(int i32, CancellationToken cancellationToken)
177 {
Jens Geyerdce22992020-05-16 23:02:27 +0200178 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100179
zembord9d958a32019-11-21 13:11:44 +0300180 BinaryPrimitives.WriteInt32BigEndian(PreAllocatedBuffer, i32);
Jens Geyer5a17b132019-05-26 15:53:37 +0200181
182 await Trans.WriteAsync(PreAllocatedBuffer, 0, 4, cancellationToken);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100183 }
184
Jens Geyer5a17b132019-05-26 15:53:37 +0200185
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100186 public override async Task WriteI64Async(long i64, CancellationToken cancellationToken)
187 {
Jens Geyerdce22992020-05-16 23:02:27 +0200188 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100189
zembord9d958a32019-11-21 13:11:44 +0300190 BinaryPrimitives.WriteInt64BigEndian(PreAllocatedBuffer, i64);
Jens Geyer5a17b132019-05-26 15:53:37 +0200191
192 await Trans.WriteAsync(PreAllocatedBuffer, 0, 8, cancellationToken);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100193 }
194
195 public override async Task WriteDoubleAsync(double d, CancellationToken cancellationToken)
196 {
Jens Geyerdce22992020-05-16 23:02:27 +0200197 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100198
199 await WriteI64Async(BitConverter.DoubleToInt64Bits(d), cancellationToken);
200 }
201
Jens Geyer5a17b132019-05-26 15:53:37 +0200202
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100203 public override async Task WriteBinaryAsync(byte[] bytes, CancellationToken cancellationToken)
204 {
Jens Geyerdce22992020-05-16 23:02:27 +0200205 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100206
207 await WriteI32Async(bytes.Length, cancellationToken);
208 await Trans.WriteAsync(bytes, 0, bytes.Length, cancellationToken);
209 }
210
Jens Geyer5a17b132019-05-26 15:53:37 +0200211 public override async ValueTask<TMessage> ReadMessageBeginAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100212 {
Jens Geyerdce22992020-05-16 23:02:27 +0200213 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100214
215 var message = new TMessage();
216 var size = await ReadI32Async(cancellationToken);
217 if (size < 0)
218 {
219 var version = (uint) size & VersionMask;
220 if (version != Version1)
221 {
222 throw new TProtocolException(TProtocolException.BAD_VERSION,
223 $"Bad version in ReadMessageBegin: {version}");
224 }
225 message.Type = (TMessageType) (size & 0x000000ff);
226 message.Name = await ReadStringAsync(cancellationToken);
227 message.SeqID = await ReadI32Async(cancellationToken);
228 }
229 else
230 {
231 if (StrictRead)
232 {
233 throw new TProtocolException(TProtocolException.BAD_VERSION,
234 "Missing version in ReadMessageBegin, old client?");
235 }
Jens Geyer5a17b132019-05-26 15:53:37 +0200236 message.Name = (size > 0) ? await ReadStringBodyAsync(size, cancellationToken) : string.Empty;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100237 message.Type = (TMessageType) await ReadByteAsync(cancellationToken);
238 message.SeqID = await ReadI32Async(cancellationToken);
239 }
240 return message;
241 }
242
Jens Geyerdce22992020-05-16 23:02:27 +0200243 public override Task ReadMessageEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100244 {
Jens Geyerdce22992020-05-16 23:02:27 +0200245 cancellationToken.ThrowIfCancellationRequested();
246 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100247 }
248
Jens Geyerdce22992020-05-16 23:02:27 +0200249 public override ValueTask<TStruct> ReadStructBeginAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100250 {
Jens Geyerdce22992020-05-16 23:02:27 +0200251 cancellationToken.ThrowIfCancellationRequested();
252 return new ValueTask<TStruct>(AnonymousStruct);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100253 }
254
Jens Geyerdce22992020-05-16 23:02:27 +0200255 public override Task ReadStructEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100256 {
Jens Geyerdce22992020-05-16 23:02:27 +0200257 cancellationToken.ThrowIfCancellationRequested();
258 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100259 }
260
Jens Geyer5a17b132019-05-26 15:53:37 +0200261 public override async ValueTask<TField> ReadFieldBeginAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100262 {
Jens Geyerdce22992020-05-16 23:02:27 +0200263 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100264
Jens Geyer5a17b132019-05-26 15:53:37 +0200265 var type = (TType)await ReadByteAsync(cancellationToken);
266 if (type == TType.Stop)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100267 {
Jens Geyer5a17b132019-05-26 15:53:37 +0200268 return StopField;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100269 }
270
Jens Geyer5a17b132019-05-26 15:53:37 +0200271 return new TField {
272 Type = type,
273 ID = await ReadI16Async(cancellationToken)
274 };
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100275 }
276
Jens Geyerdce22992020-05-16 23:02:27 +0200277 public override Task ReadFieldEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100278 {
Jens Geyerdce22992020-05-16 23:02:27 +0200279 cancellationToken.ThrowIfCancellationRequested();
280 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100281 }
282
Jens Geyer5a17b132019-05-26 15:53:37 +0200283 public override async ValueTask<TMap> ReadMapBeginAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100284 {
Jens Geyerdce22992020-05-16 23:02:27 +0200285 cancellationToken.ThrowIfCancellationRequested();
286
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100287 var map = new TMap
288 {
289 KeyType = (TType) await ReadByteAsync(cancellationToken),
290 ValueType = (TType) await ReadByteAsync(cancellationToken),
291 Count = await ReadI32Async(cancellationToken)
292 };
Jens Geyer50806452019-11-23 01:55:58 +0100293 CheckReadBytesAvailable(map);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100294 return map;
295 }
296
Jens Geyerdce22992020-05-16 23:02:27 +0200297 public override Task ReadMapEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100298 {
Jens Geyerdce22992020-05-16 23:02:27 +0200299 cancellationToken.ThrowIfCancellationRequested();
300 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100301 }
302
Jens Geyer5a17b132019-05-26 15:53:37 +0200303 public override async ValueTask<TList> ReadListBeginAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100304 {
Jens Geyerdce22992020-05-16 23:02:27 +0200305 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100306
307 var list = new TList
308 {
309 ElementType = (TType) await ReadByteAsync(cancellationToken),
310 Count = await ReadI32Async(cancellationToken)
311 };
Jens Geyer50806452019-11-23 01:55:58 +0100312 CheckReadBytesAvailable(list);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100313 return list;
314 }
315
Jens Geyerdce22992020-05-16 23:02:27 +0200316 public override Task ReadListEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100317 {
Jens Geyerdce22992020-05-16 23:02:27 +0200318 cancellationToken.ThrowIfCancellationRequested();
319 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100320 }
321
Jens Geyer5a17b132019-05-26 15:53:37 +0200322 public override async ValueTask<TSet> ReadSetBeginAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100323 {
Jens Geyerdce22992020-05-16 23:02:27 +0200324 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100325
326 var set = new TSet
327 {
328 ElementType = (TType) await ReadByteAsync(cancellationToken),
329 Count = await ReadI32Async(cancellationToken)
330 };
Jens Geyer50806452019-11-23 01:55:58 +0100331 CheckReadBytesAvailable(set);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100332 return set;
333 }
334
Jens Geyerdce22992020-05-16 23:02:27 +0200335 public override Task ReadSetEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100336 {
Jens Geyerdce22992020-05-16 23:02:27 +0200337 cancellationToken.ThrowIfCancellationRequested();
338 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100339 }
340
Jens Geyer5a17b132019-05-26 15:53:37 +0200341 public override async ValueTask<bool> ReadBoolAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100342 {
Jens Geyerdce22992020-05-16 23:02:27 +0200343 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100344
345 return await ReadByteAsync(cancellationToken) == 1;
346 }
347
Jens Geyer5a17b132019-05-26 15:53:37 +0200348 public override async ValueTask<sbyte> ReadByteAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100349 {
Jens Geyerdce22992020-05-16 23:02:27 +0200350 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100351
Jens Geyer5a17b132019-05-26 15:53:37 +0200352 await Trans.ReadAllAsync(PreAllocatedBuffer, 0, 1, cancellationToken);
353 return (sbyte)PreAllocatedBuffer[0];
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100354 }
355
Jens Geyer5a17b132019-05-26 15:53:37 +0200356 public override async ValueTask<short> ReadI16Async(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100357 {
Jens Geyerdce22992020-05-16 23:02:27 +0200358 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100359
Jens Geyer5a17b132019-05-26 15:53:37 +0200360 await Trans.ReadAllAsync(PreAllocatedBuffer, 0, 2, cancellationToken);
zembord9d958a32019-11-21 13:11:44 +0300361 var result = BinaryPrimitives.ReadInt16BigEndian(PreAllocatedBuffer);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100362 return result;
363 }
364
Jens Geyer5a17b132019-05-26 15:53:37 +0200365 public override async ValueTask<int> ReadI32Async(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100366 {
Jens Geyerdce22992020-05-16 23:02:27 +0200367 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100368
Jens Geyer5a17b132019-05-26 15:53:37 +0200369 await Trans.ReadAllAsync(PreAllocatedBuffer, 0, 4, cancellationToken);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100370
zembord9d958a32019-11-21 13:11:44 +0300371 var result = BinaryPrimitives.ReadInt32BigEndian(PreAllocatedBuffer);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100372
373 return result;
374 }
375
Jens Geyer5a17b132019-05-26 15:53:37 +0200376 public override async ValueTask<long> ReadI64Async(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100377 {
Jens Geyerdce22992020-05-16 23:02:27 +0200378 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100379
Jens Geyer5a17b132019-05-26 15:53:37 +0200380 await Trans.ReadAllAsync(PreAllocatedBuffer, 0, 8, cancellationToken);
zembord9d958a32019-11-21 13:11:44 +0300381 return BinaryPrimitives.ReadInt64BigEndian(PreAllocatedBuffer);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100382 }
383
Jens Geyer5a17b132019-05-26 15:53:37 +0200384 public override async ValueTask<double> ReadDoubleAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100385 {
Jens Geyerdce22992020-05-16 23:02:27 +0200386 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100387
388 var d = await ReadI64Async(cancellationToken);
389 return BitConverter.Int64BitsToDouble(d);
390 }
391
Jens Geyer5a17b132019-05-26 15:53:37 +0200392 public override async ValueTask<byte[]> ReadBinaryAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100393 {
Jens Geyerdce22992020-05-16 23:02:27 +0200394 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100395
396 var size = await ReadI32Async(cancellationToken);
Jens Geyer50806452019-11-23 01:55:58 +0100397 Transport.CheckReadBytesAvailable(size);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100398 var buf = new byte[size];
399 await Trans.ReadAllAsync(buf, 0, size, cancellationToken);
400 return buf;
401 }
402
Jens Geyer5a17b132019-05-26 15:53:37 +0200403 public override async ValueTask<string> ReadStringAsync(CancellationToken cancellationToken)
404 {
Jens Geyerdce22992020-05-16 23:02:27 +0200405 cancellationToken.ThrowIfCancellationRequested();
Jens Geyer5a17b132019-05-26 15:53:37 +0200406
407 var size = await ReadI32Async(cancellationToken);
408 return size > 0 ? await ReadStringBodyAsync(size, cancellationToken) : string.Empty;
409 }
410
411 private async ValueTask<string> ReadStringBodyAsync(int size, CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100412 {
Jens Geyerdce22992020-05-16 23:02:27 +0200413 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100414
Jens Geyer5a17b132019-05-26 15:53:37 +0200415 if (size <= PreAllocatedBuffer.Length)
416 {
417 await Trans.ReadAllAsync(PreAllocatedBuffer, 0, size, cancellationToken);
418 return Encoding.UTF8.GetString(PreAllocatedBuffer, 0, size);
419 }
420
Jens Geyer50806452019-11-23 01:55:58 +0100421 Transport.CheckReadBytesAvailable(size);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100422 var buf = new byte[size];
423 await Trans.ReadAllAsync(buf, 0, size, cancellationToken);
424 return Encoding.UTF8.GetString(buf, 0, buf.Length);
425 }
426
Jens Geyer50806452019-11-23 01:55:58 +0100427 // Return the minimum number of bytes a type will consume on the wire
428 public override int GetMinSerializedSize(TType type)
429 {
430 switch (type)
431 {
432 case TType.Stop: return 0;
433 case TType.Void: return 0;
434 case TType.Bool: return sizeof(byte);
435 case TType.Byte: return sizeof(byte);
436 case TType.Double: return sizeof(double);
437 case TType.I16: return sizeof(short);
438 case TType.I32: return sizeof(int);
439 case TType.I64: return sizeof(long);
440 case TType.String: return sizeof(int); // string length
441 case TType.Struct: return 0; // empty struct
442 case TType.Map: return sizeof(int); // element count
443 case TType.Set: return sizeof(int); // element count
444 case TType.List: return sizeof(int); // element count
445 default: throw new TTransportException(TTransportException.ExceptionType.Unknown, "unrecognized type code");
446 }
447 }
448
Jens Geyer421444f2019-03-20 22:13:25 +0100449 public class Factory : TProtocolFactory
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100450 {
451 protected bool StrictRead;
452 protected bool StrictWrite;
453
454 public Factory()
455 : this(false, true)
456 {
457 }
458
459 public Factory(bool strictRead, bool strictWrite)
460 {
461 StrictRead = strictRead;
462 StrictWrite = strictWrite;
463 }
464
Jens Geyer421444f2019-03-20 22:13:25 +0100465 public override TProtocol GetProtocol(TTransport trans)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100466 {
467 return new TBinaryProtocol(trans, StrictRead, StrictWrite);
468 }
469 }
470 }
Jens Geyer421444f2019-03-20 22:13:25 +0100471}