THRIFT-5591 Add uuid type to IDL and implement reference code (+ improved self-tests)
Client: compiler general, netstd, Delphi
Patch: Jens Geyer
diff --git a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/optional_required_default.thrift b/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/optional_required_default.thrift
index 4a38205..bf5a379 100644
--- a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/optional_required_default.thrift
+++ b/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/optional_required_default.thrift
@@ -36,57 +36,63 @@
2: optional double opt_two
3: optional i16 opt_three
4: optional string opt_four
- 5: optional binary opt_five
+ 5: optional uuid opt_five
6: optional list<i32> opt_six
7: optional set<i64> opt_seven
8: optional map<i8,i16> opt_eight
+ 9: optional binary opt_nine
11: required Distance req_one
12: required double req_two
13: required i16 req_three
14: required string req_four
- 15: required binary req_five
+ 15: required uuid req_five
16: required list<i32> req_six
17: required set<i64> req_seven
18: required map<i8,i16> req_eight
+ 19: required binary req_nine
21: Distance def_one
22: double def_two
23: i16 def_three
24: string def_four
- 25: binary def_five
+ 25: uuid def_five
26: list<i32> def_six
27: set<i64> def_seven
28: map<i8,i16> def_eight
-
+ 29: binary def_nine
+
// having default values
31: optional Distance opt_one_with_value = Distance.bar
32: optional double opt_two_with_value = 2.22
33: optional i16 opt_three_with_value = 3
34: optional string opt_four_with_value = "four"
- 35: optional binary opt_five_with_value = "five\t"
+ 35: optional uuid opt_five_with_value = "55555555-5555-5555-5555-000000000000"
36: optional list<i32> opt_six_with_value = [6]
37: optional set<i64> opt_seven_with_value = [7]
38: optional map<i8,i16> opt_eight_with_value = { 8 : 8 }
-
+ 39: optional binary opt_nine_with_value = "nine\t"
+
41: required Distance req_one_with_value = Distance.bar
42: required double req_two_with_value = 2.22
43: required i16 req_three_with_value = 3
44: required string req_four_with_value = "four"
- 45: required binary req_five_with_value = "five"
+ 45: required uuid req_five_with_value = "55555555-5555-5555-5555-000000000000"
46: required list<i32> req_six_with_value = [6]
47: required set<i64> req_seven_with_value = [7]
48: required map<i8,i16> req_eight_with_value = { 8 : 8 }
+ 49: required binary req_nine_with_value = "nine"
51: Distance def_one_with_value = Distance.bar
52: double def_two_with_value = 2.22
53: i16 def_three_with_value = 3
54: string def_four_with_value = "four"
- 55: binary def_five_with_value = "five"
+ 55: uuid def_five_with_value = "55555555-5555-5555-5555-000000000000"
56: list<i32> def_six_with_value = [6]
57: set<i64> def_seven_with_value = [7]
58: map<i8,i16> def_eight_with_value = { 8 : 8 }
+ 59: binary def_nine_with_value = "nine"
90: optional bool last_of_the_mohicans
@@ -124,10 +130,11 @@
402: optional double opt_two
403: optional i16 opt_three
404: optional string opt_four
- 405: optional binary opt_five
+ 405: optional uuid opt_five
406: optional list<i32> opt_six
407: optional set<i64> opt_seven
408: optional map<i8,i16> opt_eight
+ 409: optional binary opt_nine
}
typedef RaceDetails RaceDetails2
diff --git a/lib/netstd/Tests/Thrift.Tests/DataModel/DeepCopy.cs b/lib/netstd/Tests/Thrift.Tests/DataModel/DeepCopy.cs
index afffed5..11b5af4 100644
--- a/lib/netstd/Tests/Thrift.Tests/DataModel/DeepCopy.cs
+++ b/lib/netstd/Tests/Thrift.Tests/DataModel/DeepCopy.cs
@@ -81,16 +81,18 @@
Assert.IsFalse(instance.__isset.opt_six);
Assert.IsFalse(instance.__isset.opt_seven);
Assert.IsFalse(instance.__isset.opt_eight);
+ Assert.IsFalse(instance.__isset.opt_nine);
// set all required to null/default
instance.Req_one = default;
instance.Req_two = default;
instance.Req_three = default;
Assert.IsNotNull(instance.Req_four);
- Assert.IsNotNull(instance.Req_five);
- instance.Req_six = default;
- instance.Req_seven = default;;
+ instance.Req_five = default;
+ instance.Req_six = default;
+ instance.Req_seven = default;
instance.Req_eight = default;
+ Assert.IsNotNull(instance.Req_nine);
// leave non-required fields unset again
Assert.IsFalse(instance.__isset.def_one);
@@ -101,6 +103,7 @@
Assert.IsFalse(instance.__isset.def_six);
Assert.IsFalse(instance.__isset.def_seven);
Assert.IsFalse(instance.__isset.def_eight);
+ Assert.IsFalse(instance.__isset.def_nine);
// these should have IDL defaults set
@@ -112,12 +115,13 @@
Assert.IsTrue(instance.__isset.opt_six_with_value);
Assert.IsTrue(instance.__isset.opt_seven_with_value);
Assert.IsTrue(instance.__isset.opt_eight_with_value);
+ Assert.IsTrue(instance.__isset.opt_nine_with_value);
Assert.AreEqual(instance.Req_one_with_value, (Distance)1);
Assert.AreEqual(instance.Req_two_with_value, 2.22);
Assert.AreEqual(instance.Req_three_with_value, 3);
Assert.AreEqual(instance.Req_four_with_value, "four");
- Assert.AreEqual("five", Encoding.UTF8.GetString(instance.Req_five_with_value!));
+ Assert.AreEqual(new Guid("55555555-5555-5555-5555-000000000000"), instance.Req_five_with_value);
Assert.IsTrue(instance.Req_six_with_value!.Count == 1);
Assert.AreEqual(instance.Req_six_with_value[0], 6 );
@@ -128,6 +132,8 @@
Assert.IsTrue(instance.Req_eight_with_value!.Count == 1);
Assert.IsTrue(instance.Req_eight_with_value[8] == 8);
+ Assert.AreEqual("nine", Encoding.UTF8.GetString(instance.Req_nine_with_value!));
+
Assert.IsTrue(instance.__isset.def_one_with_value);
Assert.IsTrue(instance.__isset.def_two_with_value);
Assert.IsTrue(instance.__isset.def_three_with_value);
@@ -136,6 +142,7 @@
Assert.IsTrue(instance.__isset.def_six_with_value);
Assert.IsTrue(instance.__isset.def_seven_with_value);
Assert.IsTrue(instance.__isset.def_eight_with_value);
+ Assert.IsTrue(instance.__isset.def_nine_with_value);
instance.Last_of_the_mohicans = true;
@@ -180,6 +187,7 @@
instance.Opt_six = ModifyValue(instance.Opt_six);
instance.Opt_seven = ModifyValue(instance.Opt_seven);
instance.Opt_eight = ModifyValue(instance.Opt_eight);
+ instance.Opt_nine = ModifyValue(instance.Opt_nine);
instance.Req_one = ModifyValue(instance.Req_one);
instance.Req_two = ModifyValue(instance.Req_two);
@@ -189,6 +197,7 @@
instance.Req_six = ModifyValue(instance.Req_six);
instance.Req_seven = ModifyValue(instance.Req_seven);
instance.Req_eight = ModifyValue(instance.Req_eight);
+ instance.Req_nine = ModifyValue(instance.Req_nine);
instance.Def_one = ModifyValue(instance.Def_one);
instance.Def_two = ModifyValue(instance.Def_two);
@@ -198,6 +207,7 @@
instance.Def_six = ModifyValue(instance.Def_six);
instance.Def_seven = ModifyValue(instance.Def_seven);
instance.Def_eight = ModifyValue(instance.Def_eight);
+ instance.Def_nine = ModifyValue(instance.Def_nine);
instance.Opt_one_with_value = ModifyValue(instance.Opt_one_with_value);
instance.Opt_two_with_value = ModifyValue(instance.Opt_two_with_value);
@@ -207,6 +217,7 @@
instance.Opt_six_with_value = ModifyValue(instance.Opt_six_with_value);
instance.Opt_seven_with_value = ModifyValue(instance.Opt_seven_with_value);
instance.Opt_eight_with_value = ModifyValue(instance.Opt_eight_with_value);
+ instance.Opt_nine_with_value = ModifyValue(instance.Opt_nine_with_value);
instance.Req_one_with_value = ModifyValue(instance.Req_one_with_value);
instance.Req_two_with_value = ModifyValue(instance.Req_two_with_value);
@@ -216,6 +227,7 @@
instance.Req_six_with_value = ModifyValue(instance.Req_six_with_value);
instance.Req_seven_with_value = ModifyValue(instance.Req_seven_with_value);
instance.Req_eight_with_value = ModifyValue(instance.Req_eight_with_value);
+ instance.Req_nine_with_value = ModifyValue(instance.Req_nine_with_value);
instance.Def_one_with_value = ModifyValue(instance.Def_one_with_value);
instance.Def_two_with_value = ModifyValue(instance.Def_two_with_value);
@@ -225,6 +237,7 @@
instance.Def_six_with_value = ModifyValue(instance.Def_six_with_value);
instance.Def_seven_with_value = ModifyValue(instance.Def_seven_with_value);
instance.Def_eight_with_value = ModifyValue(instance.Def_eight_with_value);
+ instance.Def_nine_with_value = ModifyValue(instance.Def_nine_with_value);
instance.Last_of_the_mohicans = ModifyValue(instance.Last_of_the_mohicans);
@@ -435,6 +448,11 @@
return value + "1";
}
+ private static Guid ModifyValue(Guid value)
+ {
+ return new Guid( ModifyValue(value.ToByteArray()));
+ }
+
private static double ModifyValue(double value)
{
return value + 1.1;
@@ -461,6 +479,7 @@
Assert.IsFalse(TCollections.Equals(first.Opt_six, second.Opt_six));
Assert.IsFalse(TCollections.Equals(first.Opt_seven, second.Opt_seven));
Assert.IsFalse(TCollections.Equals(first.Opt_eight, second.Opt_eight));
+ Assert.IsFalse(TCollections.Equals(first.Opt_nine, second.Opt_nine));
Assert.AreNotEqual(first.Req_one, second.Req_one);
Assert.AreNotEqual(first.Req_two, second.Req_two);
@@ -470,6 +489,7 @@
Assert.IsFalse(TCollections.Equals(first.Req_six, second.Req_six));
Assert.IsFalse(TCollections.Equals(first.Req_seven, second.Req_seven));
Assert.IsFalse(TCollections.Equals(first.Req_eight, second.Req_eight));
+ Assert.IsFalse(TCollections.Equals(first.Req_nine, second.Req_nine));
Assert.AreNotEqual(first.Def_one, second.Def_one);
Assert.AreNotEqual(first.Def_two, second.Def_two);
@@ -479,6 +499,7 @@
Assert.IsFalse(TCollections.Equals(first.Def_six, second.Def_six));
Assert.IsFalse(TCollections.Equals(first.Def_seven, second.Def_seven));
Assert.IsFalse(TCollections.Equals(first.Def_eight, second.Def_eight));
+ Assert.IsFalse(TCollections.Equals(first.Def_nine, second.Def_nine));
Assert.AreNotEqual(first.Opt_one_with_value, second.Opt_one_with_value);
Assert.AreNotEqual(first.Opt_two_with_value, second.Opt_two_with_value);
@@ -488,6 +509,7 @@
Assert.IsFalse(TCollections.Equals(first.Opt_six_with_value, second.Opt_six_with_value));
Assert.IsFalse(TCollections.Equals(first.Opt_seven_with_value, second.Opt_seven_with_value));
Assert.IsFalse(TCollections.Equals(first.Opt_eight_with_value, second.Opt_eight_with_value));
+ Assert.IsFalse(TCollections.Equals(first.Opt_nine_with_value, second.Opt_nine_with_value));
Assert.AreNotEqual(first.Req_one_with_value, second.Req_one_with_value);
Assert.AreNotEqual(first.Req_two_with_value, second.Req_two_with_value);
@@ -497,6 +519,7 @@
Assert.IsFalse(TCollections.Equals(first.Req_six_with_value, second.Req_six_with_value));
Assert.IsFalse(TCollections.Equals(first.Req_seven_with_value, second.Req_seven_with_value));
Assert.IsFalse(TCollections.Equals(first.Req_eight_with_value, second.Req_eight_with_value));
+ Assert.IsFalse(TCollections.Equals(first.Req_nine_with_value, second.Req_nine_with_value));
Assert.AreNotEqual(first.Def_one_with_value, second.Def_one_with_value);
Assert.AreNotEqual(first.Def_two_with_value, second.Def_two_with_value);
@@ -506,6 +529,7 @@
Assert.IsFalse(TCollections.Equals(first.Def_six_with_value, second.Def_six_with_value));
Assert.IsFalse(TCollections.Equals(first.Def_seven_with_value, second.Def_seven_with_value));
Assert.IsFalse(TCollections.Equals(first.Def_eight_with_value, second.Def_eight_with_value));
+ Assert.IsFalse(TCollections.Equals(first.Def_nine_with_value, second.Def_nine_with_value));
Assert.AreNotEqual(first.Last_of_the_mohicans, second.Last_of_the_mohicans);
@@ -539,6 +563,7 @@
Assert.IsTrue(TCollections.Equals(first.Opt_six, second.Opt_six));
Assert.IsTrue(TCollections.Equals(first.Opt_seven, second.Opt_seven));
Assert.IsTrue(TCollections.Equals(first.Opt_eight, second.Opt_eight));
+ Assert.IsTrue(TCollections.Equals(first.Opt_nine, second.Opt_nine));
Assert.AreEqual(first.Req_one, second.Req_one);
Assert.AreEqual(first.Req_two, second.Req_two);
@@ -548,6 +573,7 @@
Assert.IsTrue(TCollections.Equals(first.Req_six, second.Req_six));
Assert.IsTrue(TCollections.Equals(first.Req_seven, second.Req_seven));
Assert.IsTrue(TCollections.Equals(first.Req_eight, second.Req_eight));
+ Assert.IsTrue(TCollections.Equals(first.Req_nine, second.Req_nine));
Assert.AreEqual(first.Def_one, second.Def_one);
Assert.AreEqual(first.Def_two, second.Def_two);
@@ -557,6 +583,7 @@
Assert.IsTrue(TCollections.Equals(first.Def_six, second.Def_six));
Assert.IsTrue(TCollections.Equals(first.Def_seven, second.Def_seven));
Assert.IsTrue(TCollections.Equals(first.Def_eight, second.Def_eight));
+ Assert.IsTrue(TCollections.Equals(first.Def_nine, second.Def_nine));
Assert.AreEqual(first.Opt_one_with_value, second.Opt_one_with_value);
Assert.AreEqual(first.Opt_two_with_value, second.Opt_two_with_value);
@@ -566,6 +593,7 @@
Assert.IsTrue(TCollections.Equals(first.Opt_six_with_value, second.Opt_six_with_value));
Assert.IsTrue(TCollections.Equals(first.Opt_seven_with_value, second.Opt_seven_with_value));
Assert.IsTrue(TCollections.Equals(first.Opt_eight_with_value, second.Opt_eight_with_value));
+ Assert.IsTrue(TCollections.Equals(first.Opt_nine_with_value, second.Opt_nine_with_value));
Assert.AreEqual(first.Req_one_with_value, second.Req_one_with_value);
Assert.AreEqual(first.Req_two_with_value, second.Req_two_with_value);
@@ -575,6 +603,7 @@
Assert.IsTrue(TCollections.Equals(first.Req_six_with_value, second.Req_six_with_value));
Assert.IsTrue(TCollections.Equals(first.Req_seven_with_value, second.Req_seven_with_value));
Assert.IsTrue(TCollections.Equals(first.Req_eight_with_value, second.Req_eight_with_value));
+ Assert.IsTrue(TCollections.Equals(first.Req_nine_with_value, second.Req_nine_with_value));
Assert.AreEqual(first.Def_one_with_value, second.Def_one_with_value);
Assert.AreEqual(first.Def_two_with_value, second.Def_two_with_value);
@@ -584,6 +613,7 @@
Assert.IsTrue(TCollections.Equals(first.Def_six_with_value, second.Def_six_with_value));
Assert.IsTrue(TCollections.Equals(first.Def_seven_with_value, second.Def_seven_with_value));
Assert.IsTrue(TCollections.Equals(first.Def_eight_with_value, second.Def_eight_with_value));
+ Assert.IsTrue(TCollections.Equals(first.Def_nine_with_value, second.Def_nine_with_value));
Assert.AreEqual(first.Last_of_the_mohicans, second.Last_of_the_mohicans);
diff --git a/lib/netstd/Tests/Thrift.Tests/DataModel/NullValuesSet.cs b/lib/netstd/Tests/Thrift.Tests/DataModel/NullValuesSet.cs
index ebc1717..80eacc2 100644
--- a/lib/netstd/Tests/Thrift.Tests/DataModel/NullValuesSet.cs
+++ b/lib/netstd/Tests/Thrift.Tests/DataModel/NullValuesSet.cs
@@ -48,19 +48,19 @@
Assert.IsNull(instance.Def_four);
Assert.IsNull(instance.Opt_four);
- // byte[]
- Assert.IsTrue(instance.__isset.def_five);
- Assert.IsTrue(instance.__isset.opt_five);
- Assert.IsTrue((instance.Req_five == null) || (instance.Req_five.Length == 0));
- Assert.IsNull(instance.Def_five);
- Assert.IsNull(instance.Opt_five);
-
// list<>
Assert.IsTrue(instance.__isset.def_six);
Assert.IsTrue(instance.__isset.opt_six);
Assert.IsNull(instance.Req_six);
Assert.IsNull(instance.Opt_six);
Assert.IsNull(instance.Def_six);
+
+ // byte[]
+ Assert.IsTrue(instance.__isset.def_nine);
+ Assert.IsTrue(instance.__isset.opt_nine);
+ Assert.IsTrue((instance.Req_nine == null) || (instance.Req_nine.Length == 0));
+ Assert.IsNull(instance.Def_nine);
+ Assert.IsNull(instance.Opt_nine);
}
[TestMethod]
@@ -80,27 +80,27 @@
instance.Def_four = null;
instance.Opt_four = null;
- // byte[]
- instance.Req_five = null;
- instance.Def_five = null;
- instance.Opt_five = null;
-
// list<>
instance.Req_six = null;
instance.Opt_six = null;
instance.Def_six = null;
+ // byte[]
+ instance.Req_nine = null;
+ instance.Def_nine = null;
+ instance.Opt_nine = null;
+
// back to normal
#pragma warning restore CS8625
// test the setup
CheckInstance(instance);
- // validate proper null checks , any of these throws if not
+ // validate proper null checks, any of these throws if not
instance.ToString();
instance.GetHashCode();
- // validate proper null checks , any of these throws if not
+ // validate proper null checks, any of these throws if not
var copy = instance.DeepCopy();
CheckInstance(copy);
}
diff --git a/lib/netstd/Thrift/Protocol/Entities/TType.cs b/lib/netstd/Thrift/Protocol/Entities/TType.cs
index 4e922a7..2f3037b 100644
--- a/lib/netstd/Thrift/Protocol/Entities/TType.cs
+++ b/lib/netstd/Thrift/Protocol/Entities/TType.cs
@@ -32,6 +32,7 @@
Struct = 12,
Map = 13,
Set = 14,
- List = 15
+ List = 15,
+ Uuid = 16
}
-}
\ No newline at end of file
+}
diff --git a/lib/netstd/Thrift/Protocol/TBinaryProtocol.cs b/lib/netstd/Thrift/Protocol/TBinaryProtocol.cs
index eee137c..ba2a7ab 100644
--- a/lib/netstd/Thrift/Protocol/TBinaryProtocol.cs
+++ b/lib/netstd/Thrift/Protocol/TBinaryProtocol.cs
@@ -21,6 +21,7 @@
using System.Threading;
using System.Threading.Tasks;
using Thrift.Protocol.Entities;
+using Thrift.Protocol.Utilities;
using Thrift.Transport;
@@ -209,6 +210,14 @@
await Trans.WriteAsync(bytes, 0, bytes.Length, cancellationToken);
}
+ public override async Task WriteUuidAsync(Guid uuid, CancellationToken cancellationToken)
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+
+ var bytes = uuid.SwapByteOrder().ToByteArray();
+ await Trans.WriteAsync(bytes, 0, bytes.Length, cancellationToken);
+ }
+
public override async ValueTask<TMessage> ReadMessageBeginAsync(CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
@@ -401,6 +410,16 @@
return buf;
}
+ public override async ValueTask<Guid> ReadUuidAsync(CancellationToken cancellationToken)
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+
+ Transport.CheckReadBytesAvailable(16); // = sizeof(uuid)
+ var buf = new byte[16];
+ await Trans.ReadAllAsync(buf, 0, 16, cancellationToken);
+ return new Guid(buf).SwapByteOrder();
+ }
+
public override async ValueTask<string> ReadStringAsync(CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
@@ -443,6 +462,7 @@
case TType.Map: return sizeof(int); // element count
case TType.Set: return sizeof(int); // element count
case TType.List: return sizeof(int); // element count
+ case TType.Uuid: return 16; // uuid bytes
default: throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "unrecognized type code");
}
}
diff --git a/lib/netstd/Thrift/Protocol/TCompactProtocol.cs b/lib/netstd/Thrift/Protocol/TCompactProtocol.cs
index 6893ad4..b899d3d 100644
--- a/lib/netstd/Thrift/Protocol/TCompactProtocol.cs
+++ b/lib/netstd/Thrift/Protocol/TCompactProtocol.cs
@@ -24,6 +24,7 @@
using System.Threading;
using System.Threading.Tasks;
using Thrift.Protocol.Entities;
+using Thrift.Protocol.Utilities;
using Thrift.Transport;
@@ -43,8 +44,8 @@
private const byte NoTypeOverride = 0xFF;
// ReSharper disable once InconsistentNaming
- private static readonly byte[] TTypeToCompactType = new byte[16];
- private static readonly TType[] CompactTypeToTType = new TType[13];
+ private static readonly byte[] TTypeToCompactType = new byte[17];
+ private static readonly TType[] CompactTypeToTType = new TType[14];
/// <summary>
/// Used to keep track of the last field for the current and previous structs, so we can do the delta stuff.
@@ -86,18 +87,19 @@
public TCompactProtocol(TTransport trans)
: base(trans)
{
- TTypeToCompactType[(int) TType.Stop] = Types.Stop;
- TTypeToCompactType[(int) TType.Bool] = Types.BooleanTrue;
- TTypeToCompactType[(int) TType.Byte] = Types.Byte;
- TTypeToCompactType[(int) TType.I16] = Types.I16;
- TTypeToCompactType[(int) TType.I32] = Types.I32;
- TTypeToCompactType[(int) TType.I64] = Types.I64;
- TTypeToCompactType[(int) TType.Double] = Types.Double;
- TTypeToCompactType[(int) TType.String] = Types.Binary;
- TTypeToCompactType[(int) TType.List] = Types.List;
- TTypeToCompactType[(int) TType.Set] = Types.Set;
- TTypeToCompactType[(int) TType.Map] = Types.Map;
- TTypeToCompactType[(int) TType.Struct] = Types.Struct;
+ TTypeToCompactType[(int)TType.Stop] = Types.Stop;
+ TTypeToCompactType[(int)TType.Bool] = Types.BooleanTrue;
+ TTypeToCompactType[(int)TType.Byte] = Types.Byte;
+ TTypeToCompactType[(int)TType.I16] = Types.I16;
+ TTypeToCompactType[(int)TType.I32] = Types.I32;
+ TTypeToCompactType[(int)TType.I64] = Types.I64;
+ TTypeToCompactType[(int)TType.Double] = Types.Double;
+ TTypeToCompactType[(int)TType.String] = Types.Binary;
+ TTypeToCompactType[(int)TType.List] = Types.List;
+ TTypeToCompactType[(int)TType.Set] = Types.Set;
+ TTypeToCompactType[(int)TType.Map] = Types.Map;
+ TTypeToCompactType[(int)TType.Struct] = Types.Struct;
+ TTypeToCompactType[(int)TType.Uuid] = Types.Uuid;
CompactTypeToTType[Types.Stop] = TType.Stop;
CompactTypeToTType[Types.BooleanTrue] = TType.Bool;
@@ -112,6 +114,7 @@
CompactTypeToTType[Types.Set] = TType.Set;
CompactTypeToTType[Types.Map] = TType.Map;
CompactTypeToTType[Types.Struct] = TType.Struct;
+ CompactTypeToTType[Types.Uuid] = TType.Uuid;
}
public void Reset()
@@ -395,6 +398,14 @@
await Trans.WriteAsync(bytes, 0, bytes.Length, cancellationToken);
}
+ public override async Task WriteUuidAsync(Guid uuid, CancellationToken cancellationToken)
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+
+ var bytes = uuid.SwapByteOrder().ToByteArray();
+ await Trans.WriteAsync(bytes, 0, bytes.Length, cancellationToken);
+ }
+
public override async Task WriteMapBeginAsync(TMap map, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
@@ -665,6 +676,16 @@
return buf;
}
+ public override async ValueTask<Guid> ReadUuidAsync(CancellationToken cancellationToken)
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+
+ Transport.CheckReadBytesAvailable(16); // = sizeof(uuid)
+ var buf = new byte[16];
+ await Trans.ReadAllAsync(buf, 0, 16, cancellationToken);
+ return new Guid(buf).SwapByteOrder();
+ }
+
public override async ValueTask<TList> ReadListBeginAsync(CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
@@ -792,19 +813,20 @@
{
switch (type)
{
- case TType.Stop: return 0;
- case TType.Void: return 0;
- case TType.Bool: return sizeof(byte);
+ case TType.Stop: return 0;
+ case TType.Void: return 0;
+ case TType.Bool: return sizeof(byte);
case TType.Double: return 8; // uses fixedLongToBytes() which always writes 8 bytes
case TType.Byte: return sizeof(byte);
- case TType.I16: return sizeof(byte); // zigzag
- case TType.I32: return sizeof(byte); // zigzag
- case TType.I64: return sizeof(byte); // zigzag
+ case TType.I16: return sizeof(byte); // zigzag
+ case TType.I32: return sizeof(byte); // zigzag
+ case TType.I64: return sizeof(byte); // zigzag
case TType.String: return sizeof(byte); // string length
- case TType.Struct: return 0; // empty struct
- case TType.Map: return sizeof(byte); // element count
- case TType.Set: return sizeof(byte); // element count
- case TType.List: return sizeof(byte); // element count
+ case TType.Struct: return 0; // empty struct
+ case TType.Map: return sizeof(byte); // element count
+ case TType.Set: return sizeof(byte); // element count
+ case TType.List: return sizeof(byte); // element count
+ case TType.Uuid: return 16; // uuid bytes
default: throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "unrecognized type code");
}
}
@@ -835,6 +857,7 @@
public const byte Set = 0x0A;
public const byte Map = 0x0B;
public const byte Struct = 0x0C;
+ public const byte Uuid = 0x0D;
}
}
}
diff --git a/lib/netstd/Thrift/Protocol/TJSONProtocol.cs b/lib/netstd/Thrift/Protocol/TJSONProtocol.cs
index 8799026..c100d86 100644
--- a/lib/netstd/Thrift/Protocol/TJSONProtocol.cs
+++ b/lib/netstd/Thrift/Protocol/TJSONProtocol.cs
@@ -401,6 +401,10 @@
{
await WriteJsonBase64Async(bytes, cancellationToken);
}
+ public override async Task WriteUuidAsync(Guid uuid, CancellationToken cancellationToken = default)
+ {
+ await WriteStringAsync(uuid.ToString("D"), cancellationToken); // no curly braces
+ }
/// <summary>
/// Read in a JSON string, unescaping as appropriate.. Skip Reading from the
@@ -817,6 +821,11 @@
return await ReadJsonBase64Async(cancellationToken);
}
+ public override async ValueTask<Guid> ReadUuidAsync(CancellationToken cancellationToken = default)
+ {
+ return new Guid( await ReadStringAsync(cancellationToken));
+ }
+
// Return the minimum number of bytes a type will consume on the wire
public override int GetMinSerializedSize(TType type)
{
@@ -835,6 +844,7 @@
case TType.Map: return 2; // empty map
case TType.Set: return 2; // empty set
case TType.List: return 2; // empty list
+ case TType.Uuid: return 36; // "E236974D-F0B0-4E05-8F29-0B455D41B1A1"
default: throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "unrecognized type code");
}
}
diff --git a/lib/netstd/Thrift/Protocol/TProtocol.cs b/lib/netstd/Thrift/Protocol/TProtocol.cs
index cd93833..f2bec60 100644
--- a/lib/netstd/Thrift/Protocol/TProtocol.cs
+++ b/lib/netstd/Thrift/Protocol/TProtocol.cs
@@ -148,6 +148,7 @@
}
public abstract Task WriteBinaryAsync(byte[] bytes, CancellationToken cancellationToken = default);
+ public abstract Task WriteUuidAsync(Guid uuid, CancellationToken cancellationToken = default);
public abstract ValueTask<TMessage> ReadMessageBeginAsync(CancellationToken cancellationToken = default);
@@ -192,5 +193,7 @@
}
public abstract ValueTask<byte[]> ReadBinaryAsync(CancellationToken cancellationToken = default);
+
+ public abstract ValueTask<Guid> ReadUuidAsync(CancellationToken cancellationToken = default);
}
}
diff --git a/lib/netstd/Thrift/Protocol/TProtocolDecorator.cs b/lib/netstd/Thrift/Protocol/TProtocolDecorator.cs
index b032e83..1ea9fb9 100644
--- a/lib/netstd/Thrift/Protocol/TProtocolDecorator.cs
+++ b/lib/netstd/Thrift/Protocol/TProtocolDecorator.cs
@@ -144,6 +144,11 @@
await _wrappedProtocol.WriteBinaryAsync(bytes, cancellationToken);
}
+ public override async Task WriteUuidAsync(Guid uuid, CancellationToken cancellationToken)
+ {
+ await _wrappedProtocol.WriteUuidAsync(uuid, cancellationToken);
+ }
+
public override async ValueTask<TMessage> ReadMessageBeginAsync(CancellationToken cancellationToken)
{
return await _wrappedProtocol.ReadMessageBeginAsync(cancellationToken);
@@ -244,6 +249,11 @@
return await _wrappedProtocol.ReadBinaryAsync(cancellationToken);
}
+ public override async ValueTask<Guid> ReadUuidAsync(CancellationToken cancellationToken)
+ {
+ return await _wrappedProtocol.ReadUuidAsync(cancellationToken);
+ }
+
// Returns the minimum amount of bytes needed to store the smallest possible instance of TType.
public override int GetMinSerializedSize(TType type)
{
diff --git a/lib/netstd/Thrift/Protocol/Utilities/TGuidExtensions.cs b/lib/netstd/Thrift/Protocol/Utilities/TGuidExtensions.cs
new file mode 100644
index 0000000..190ddbb
--- /dev/null
+++ b/lib/netstd/Thrift/Protocol/Utilities/TGuidExtensions.cs
@@ -0,0 +1,82 @@
+// Licensed to the Apache Software Foundation(ASF) under one
+// or more contributor license agreements.See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Text;
+
+namespace Thrift.Protocol.Utilities
+{
+ public static class TGuidExtensions
+ {
+ public static Guid SwapByteOrder(this Guid self)
+ {
+ var bytes = self.ToByteArray();
+
+ // already network order on BigEndian machines
+ if (BitConverter.IsLittleEndian)
+ {
+ SwapBytes(ref bytes[0], ref bytes[3]);
+ SwapBytes(ref bytes[1], ref bytes[2]);
+ SwapBytes(ref bytes[4], ref bytes[5]);
+ SwapBytes(ref bytes[6], ref bytes[7]);
+ }
+
+ return new Guid(bytes);
+ }
+
+ private static void SwapBytes(ref byte one, ref byte two)
+ {
+ var tmp = one;
+ one = two;
+ two = tmp;
+ }
+
+ #region SelfTest
+#if DEBUG
+ static private readonly Guid TEST_GUID = new Guid("{00112233-4455-6677-8899-aabbccddeeff}");
+
+ static TGuidExtensions()
+ {
+ SelfTest();
+ }
+
+ private static void SelfTest()
+ {
+ // host to network
+ var guid = TEST_GUID;
+ guid = guid.SwapByteOrder();
+
+ // validate network order
+ var bytes = guid.ToByteArray();
+ for (var i = 0; i < 10; ++i)
+ {
+ var expected = i * 0x11;
+ Debug.Assert( bytes[i] == expected);
+ }
+
+ // network to host and final validation
+ guid = guid.SwapByteOrder();
+ Debug.Assert(guid.Equals(TEST_GUID));
+ }
+
+#endif
+ #endregion
+
+ }
+}
diff --git a/lib/netstd/Thrift/Protocol/Utilities/TJsonProtocolConstants.cs b/lib/netstd/Thrift/Protocol/Utilities/TJsonProtocolConstants.cs
index 6cc1302..f8c261a 100644
--- a/lib/netstd/Thrift/Protocol/Utilities/TJsonProtocolConstants.cs
+++ b/lib/netstd/Thrift/Protocol/Utilities/TJsonProtocolConstants.cs
@@ -1,4 +1,4 @@
-// Licensed to the Apache Software Foundation(ASF) under one
+// Licensed to the Apache Software Foundation(ASF) under one
// or more contributor license agreements.See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.The ASF licenses this file
@@ -56,6 +56,7 @@
public static readonly byte[] NameMap = { (byte)'m', (byte)'a', (byte)'p' };
public static readonly byte[] NameList = { (byte)'l', (byte)'s', (byte)'t' };
public static readonly byte[] NameSet = { (byte)'s', (byte)'e', (byte)'t' };
+ public static readonly byte[] NameUuid = { (byte)'u', (byte)'i', (byte)'d' };
}
}
-}
\ No newline at end of file
+}
diff --git a/lib/netstd/Thrift/Protocol/Utilities/TJsonProtocolHelper.cs b/lib/netstd/Thrift/Protocol/Utilities/TJsonProtocolHelper.cs
index ff49ebe..67c7bc0 100644
--- a/lib/netstd/Thrift/Protocol/Utilities/TJsonProtocolHelper.cs
+++ b/lib/netstd/Thrift/Protocol/Utilities/TJsonProtocolHelper.cs
@@ -1,4 +1,4 @@
-// Licensed to the Apache Software Foundation(ASF) under one
+// Licensed to the Apache Software Foundation(ASF) under one
// or more contributor license agreements.See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.The ASF licenses this file
@@ -48,6 +48,8 @@
return TJSONProtocolConstants.TypeNames.NameSet;
case TType.List:
return TJSONProtocolConstants.TypeNames.NameList;
+ case TType.Uuid:
+ return TJSONProtocolConstants.TypeNames.NameUuid;
default:
throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "Unrecognized exType");
}
@@ -102,6 +104,9 @@
case (byte) 't':
result = TType.Bool;
break;
+ case (byte)'u':
+ result = TType.Uuid;
+ break;
}
}
if (result == TType.Stop)
@@ -173,4 +178,4 @@
return (byte)((char)val + 'a');
}
}
-}
\ No newline at end of file
+}
diff --git a/lib/netstd/Thrift/Protocol/Utilities/TProtocolUtil.cs b/lib/netstd/Thrift/Protocol/Utilities/TProtocolUtil.cs
index 832e46e..3c8b37a 100644
--- a/lib/netstd/Thrift/Protocol/Utilities/TProtocolUtil.cs
+++ b/lib/netstd/Thrift/Protocol/Utilities/TProtocolUtil.cs
@@ -55,6 +55,9 @@
// Don't try to decode the string, just skip it.
await protocol.ReadBinaryAsync(cancellationToken);
break;
+ case TType.Uuid:
+ await protocol.ReadUuidAsync(cancellationToken);
+ break;
case TType.Struct:
await protocol.ReadStructBeginAsync(cancellationToken);
while (true)