blob: 7feb698b458d840da55f5caaed40719ad06e4f02 [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();
Philip Lee2d2790f2022-09-15 12:43:03 +0100256 Transport.ResetConsumedMessageSize();
Jens Geyerdce22992020-05-16 23:02:27 +0200257 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100258 }
259
Jens Geyerdce22992020-05-16 23:02:27 +0200260 public override ValueTask<TStruct> ReadStructBeginAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100261 {
Jens Geyerdce22992020-05-16 23:02:27 +0200262 cancellationToken.ThrowIfCancellationRequested();
263 return new ValueTask<TStruct>(AnonymousStruct);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100264 }
265
Jens Geyerdce22992020-05-16 23:02:27 +0200266 public override Task ReadStructEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100267 {
Jens Geyerdce22992020-05-16 23:02:27 +0200268 cancellationToken.ThrowIfCancellationRequested();
269 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100270 }
271
Jens Geyer5a17b132019-05-26 15:53:37 +0200272 public override async ValueTask<TField> ReadFieldBeginAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100273 {
Jens Geyerdce22992020-05-16 23:02:27 +0200274 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100275
Jens Geyer5a17b132019-05-26 15:53:37 +0200276 var type = (TType)await ReadByteAsync(cancellationToken);
277 if (type == TType.Stop)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100278 {
Jens Geyer5a17b132019-05-26 15:53:37 +0200279 return StopField;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100280 }
281
Jens Geyer5a17b132019-05-26 15:53:37 +0200282 return new TField {
283 Type = type,
284 ID = await ReadI16Async(cancellationToken)
285 };
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100286 }
287
Jens Geyerdce22992020-05-16 23:02:27 +0200288 public override Task ReadFieldEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100289 {
Jens Geyerdce22992020-05-16 23:02:27 +0200290 cancellationToken.ThrowIfCancellationRequested();
291 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100292 }
293
Jens Geyer5a17b132019-05-26 15:53:37 +0200294 public override async ValueTask<TMap> ReadMapBeginAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100295 {
Jens Geyerdce22992020-05-16 23:02:27 +0200296 cancellationToken.ThrowIfCancellationRequested();
297
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100298 var map = new TMap
299 {
300 KeyType = (TType) await ReadByteAsync(cancellationToken),
301 ValueType = (TType) await ReadByteAsync(cancellationToken),
302 Count = await ReadI32Async(cancellationToken)
303 };
Jens Geyer50806452019-11-23 01:55:58 +0100304 CheckReadBytesAvailable(map);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100305 return map;
306 }
307
Jens Geyerdce22992020-05-16 23:02:27 +0200308 public override Task ReadMapEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100309 {
Jens Geyerdce22992020-05-16 23:02:27 +0200310 cancellationToken.ThrowIfCancellationRequested();
311 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100312 }
313
Jens Geyer5a17b132019-05-26 15:53:37 +0200314 public override async ValueTask<TList> ReadListBeginAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100315 {
Jens Geyerdce22992020-05-16 23:02:27 +0200316 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100317
318 var list = new TList
319 {
320 ElementType = (TType) await ReadByteAsync(cancellationToken),
321 Count = await ReadI32Async(cancellationToken)
322 };
Jens Geyer50806452019-11-23 01:55:58 +0100323 CheckReadBytesAvailable(list);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100324 return list;
325 }
326
Jens Geyerdce22992020-05-16 23:02:27 +0200327 public override Task ReadListEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100328 {
Jens Geyerdce22992020-05-16 23:02:27 +0200329 cancellationToken.ThrowIfCancellationRequested();
330 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100331 }
332
Jens Geyer5a17b132019-05-26 15:53:37 +0200333 public override async ValueTask<TSet> ReadSetBeginAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100334 {
Jens Geyerdce22992020-05-16 23:02:27 +0200335 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100336
337 var set = new TSet
338 {
339 ElementType = (TType) await ReadByteAsync(cancellationToken),
340 Count = await ReadI32Async(cancellationToken)
341 };
Jens Geyer50806452019-11-23 01:55:58 +0100342 CheckReadBytesAvailable(set);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100343 return set;
344 }
345
Jens Geyerdce22992020-05-16 23:02:27 +0200346 public override Task ReadSetEndAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100347 {
Jens Geyerdce22992020-05-16 23:02:27 +0200348 cancellationToken.ThrowIfCancellationRequested();
349 return Task.CompletedTask;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100350 }
351
Jens Geyer5a17b132019-05-26 15:53:37 +0200352 public override async ValueTask<bool> ReadBoolAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100353 {
Jens Geyerdce22992020-05-16 23:02:27 +0200354 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100355
356 return await ReadByteAsync(cancellationToken) == 1;
357 }
358
Jens Geyer5a17b132019-05-26 15:53:37 +0200359 public override async ValueTask<sbyte> ReadByteAsync(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, 1, cancellationToken);
364 return (sbyte)PreAllocatedBuffer[0];
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100365 }
366
Jens Geyer5a17b132019-05-26 15:53:37 +0200367 public override async ValueTask<short> ReadI16Async(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100368 {
Jens Geyerdce22992020-05-16 23:02:27 +0200369 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100370
Jens Geyer5a17b132019-05-26 15:53:37 +0200371 await Trans.ReadAllAsync(PreAllocatedBuffer, 0, 2, cancellationToken);
zembord9d958a32019-11-21 13:11:44 +0300372 var result = BinaryPrimitives.ReadInt16BigEndian(PreAllocatedBuffer);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100373 return result;
374 }
375
Jens Geyer5a17b132019-05-26 15:53:37 +0200376 public override async ValueTask<int> ReadI32Async(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, 4, cancellationToken);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100381
zembord9d958a32019-11-21 13:11:44 +0300382 var result = BinaryPrimitives.ReadInt32BigEndian(PreAllocatedBuffer);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100383
384 return result;
385 }
386
Jens Geyer5a17b132019-05-26 15:53:37 +0200387 public override async ValueTask<long> ReadI64Async(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
Jens Geyer5a17b132019-05-26 15:53:37 +0200391 await Trans.ReadAllAsync(PreAllocatedBuffer, 0, 8, cancellationToken);
zembord9d958a32019-11-21 13:11:44 +0300392 return BinaryPrimitives.ReadInt64BigEndian(PreAllocatedBuffer);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100393 }
394
Jens Geyer5a17b132019-05-26 15:53:37 +0200395 public override async ValueTask<double> ReadDoubleAsync(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 d = await ReadI64Async(cancellationToken);
400 return BitConverter.Int64BitsToDouble(d);
401 }
402
Jens Geyer5a17b132019-05-26 15:53:37 +0200403 public override async ValueTask<byte[]> ReadBinaryAsync(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100404 {
Jens Geyerdce22992020-05-16 23:02:27 +0200405 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100406
407 var size = await ReadI32Async(cancellationToken);
Jens Geyer50806452019-11-23 01:55:58 +0100408 Transport.CheckReadBytesAvailable(size);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100409 var buf = new byte[size];
410 await Trans.ReadAllAsync(buf, 0, size, cancellationToken);
411 return buf;
412 }
413
Jens Geyer62445c12022-06-29 00:00:00 +0200414 public override async ValueTask<Guid> ReadUuidAsync(CancellationToken cancellationToken)
415 {
416 cancellationToken.ThrowIfCancellationRequested();
417
418 Transport.CheckReadBytesAvailable(16); // = sizeof(uuid)
419 var buf = new byte[16];
420 await Trans.ReadAllAsync(buf, 0, 16, cancellationToken);
421 return new Guid(buf).SwapByteOrder();
422 }
423
Jens Geyer5a17b132019-05-26 15:53:37 +0200424 public override async ValueTask<string> ReadStringAsync(CancellationToken cancellationToken)
425 {
Jens Geyerdce22992020-05-16 23:02:27 +0200426 cancellationToken.ThrowIfCancellationRequested();
Jens Geyer5a17b132019-05-26 15:53:37 +0200427
428 var size = await ReadI32Async(cancellationToken);
429 return size > 0 ? await ReadStringBodyAsync(size, cancellationToken) : string.Empty;
430 }
431
432 private async ValueTask<string> ReadStringBodyAsync(int size, CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100433 {
Jens Geyerdce22992020-05-16 23:02:27 +0200434 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100435
Jens Geyer5a17b132019-05-26 15:53:37 +0200436 if (size <= PreAllocatedBuffer.Length)
437 {
438 await Trans.ReadAllAsync(PreAllocatedBuffer, 0, size, cancellationToken);
439 return Encoding.UTF8.GetString(PreAllocatedBuffer, 0, size);
440 }
441
Jens Geyer50806452019-11-23 01:55:58 +0100442 Transport.CheckReadBytesAvailable(size);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100443 var buf = new byte[size];
444 await Trans.ReadAllAsync(buf, 0, size, cancellationToken);
445 return Encoding.UTF8.GetString(buf, 0, buf.Length);
446 }
447
Jens Geyer50806452019-11-23 01:55:58 +0100448 // Return the minimum number of bytes a type will consume on the wire
449 public override int GetMinSerializedSize(TType type)
450 {
451 switch (type)
452 {
453 case TType.Stop: return 0;
454 case TType.Void: return 0;
455 case TType.Bool: return sizeof(byte);
456 case TType.Byte: return sizeof(byte);
457 case TType.Double: return sizeof(double);
458 case TType.I16: return sizeof(short);
459 case TType.I32: return sizeof(int);
460 case TType.I64: return sizeof(long);
461 case TType.String: return sizeof(int); // string length
462 case TType.Struct: return 0; // empty struct
463 case TType.Map: return sizeof(int); // element count
464 case TType.Set: return sizeof(int); // element count
465 case TType.List: return sizeof(int); // element count
Jens Geyer62445c12022-06-29 00:00:00 +0200466 case TType.Uuid: return 16; // uuid bytes
Jens Geyer0d128322021-02-25 09:42:52 +0100467 default: throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "unrecognized type code");
Jens Geyer50806452019-11-23 01:55:58 +0100468 }
469 }
470
Jens Geyer421444f2019-03-20 22:13:25 +0100471 public class Factory : TProtocolFactory
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100472 {
473 protected bool StrictRead;
474 protected bool StrictWrite;
475
476 public Factory()
477 : this(false, true)
478 {
479 }
480
481 public Factory(bool strictRead, bool strictWrite)
482 {
483 StrictRead = strictRead;
484 StrictWrite = strictWrite;
485 }
486
Jens Geyer421444f2019-03-20 22:13:25 +0100487 public override TProtocol GetProtocol(TTransport trans)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100488 {
489 return new TBinaryProtocol(trans, StrictRead, StrictWrite);
490 }
491 }
492 }
Jens Geyer421444f2019-03-20 22:13:25 +0100493}