summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--compiler/cpp/src/thrift/common.cc4
-rw-r--r--compiler/cpp/src/thrift/common.h1
-rw-r--r--compiler/cpp/src/thrift/generate/t_c_glib_generator.cc2
-rw-r--r--compiler/cpp/src/thrift/generate/t_cpp_generator.cc28
-rw-r--r--compiler/cpp/src/thrift/generate/t_d_generator.cc10
-rw-r--r--compiler/cpp/src/thrift/generate/t_dart_generator.cc6
-rw-r--r--compiler/cpp/src/thrift/generate/t_delphi_generator.cc20
-rw-r--r--compiler/cpp/src/thrift/generate/t_erl_generator.cc4
-rw-r--r--compiler/cpp/src/thrift/generate/t_go_generator.cc10
-rw-r--r--compiler/cpp/src/thrift/generate/t_haxe_generator.cc4
-rw-r--r--compiler/cpp/src/thrift/generate/t_java_generator.cc8
-rw-r--r--compiler/cpp/src/thrift/generate/t_javame_generator.cc4
-rw-r--r--compiler/cpp/src/thrift/generate/t_js_generator.cc5
-rw-r--r--compiler/cpp/src/thrift/generate/t_kotlin_generator.cc2
-rw-r--r--compiler/cpp/src/thrift/generate/t_lua_generator.cc2
-rw-r--r--compiler/cpp/src/thrift/generate/t_markdown_generator.cc2
-rw-r--r--compiler/cpp/src/thrift/generate/t_netstd_generator.cc18
-rw-r--r--compiler/cpp/src/thrift/generate/t_ocaml_generator.cc4
-rw-r--r--compiler/cpp/src/thrift/generate/t_perl_generator.cc6
-rw-r--r--compiler/cpp/src/thrift/generate/t_php_generator.cc10
-rw-r--r--compiler/cpp/src/thrift/generate/t_py_generator.cc2
-rw-r--r--compiler/cpp/src/thrift/generate/t_rb_generator.cc2
-rw-r--r--compiler/cpp/src/thrift/generate/t_rs_generator.cc10
-rw-r--r--compiler/cpp/src/thrift/generate/t_st_generator.cc2
-rw-r--r--compiler/cpp/src/thrift/generate/t_swift_generator.cc8
-rw-r--r--compiler/cpp/src/thrift/main.cc6
-rw-r--r--compiler/cpp/src/thrift/parse/t_base_type.h6
-rw-r--r--compiler/cpp/src/thrift/parse/t_const_value.h39
-rw-r--r--compiler/cpp/src/thrift/parse/t_scope.h3
-rw-r--r--compiler/cpp/src/thrift/parse/t_type.h1
-rw-r--r--compiler/cpp/src/thrift/thriftl.ll1
-rw-r--r--compiler/cpp/src/thrift/thrifty.yy6
-rw-r--r--lib/delphi/src/Thrift.Protocol.Compact.pas28
-rw-r--r--lib/delphi/src/Thrift.Protocol.JSON.pas17
-rw-r--r--lib/delphi/src/Thrift.Protocol.pas43
-rw-r--r--lib/delphi/src/Thrift.Utils.pas118
-rw-r--r--lib/delphi/test/TestClient.pas13
-rw-r--r--lib/delphi/test/TestServer.pas7
-rw-r--r--lib/delphi/test/client.dproj24
-rw-r--r--lib/delphi/test/serializer/TestSerializer.Data.pas4
-rw-r--r--lib/delphi/test/serializer/TestSerializer.Tests.pas10
-rw-r--r--lib/delphi/test/server.dproj23
-rw-r--r--lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/optional_required_default.thrift25
-rw-r--r--lib/netstd/Tests/Thrift.Tests/DataModel/DeepCopy.cs38
-rw-r--r--lib/netstd/Tests/Thrift.Tests/DataModel/NullValuesSet.cs28
-rw-r--r--lib/netstd/Thrift/Protocol/Entities/TType.cs5
-rw-r--r--lib/netstd/Thrift/Protocol/TBinaryProtocol.cs20
-rw-r--r--lib/netstd/Thrift/Protocol/TCompactProtocol.cs71
-rw-r--r--lib/netstd/Thrift/Protocol/TJSONProtocol.cs10
-rw-r--r--lib/netstd/Thrift/Protocol/TProtocol.cs3
-rw-r--r--lib/netstd/Thrift/Protocol/TProtocolDecorator.cs10
-rw-r--r--lib/netstd/Thrift/Protocol/Utilities/TGuidExtensions.cs82
-rw-r--r--lib/netstd/Thrift/Protocol/Utilities/TJsonProtocolConstants.cs5
-rw-r--r--lib/netstd/Thrift/Protocol/Utilities/TJsonProtocolHelper.cs9
-rw-r--r--lib/netstd/Thrift/Protocol/Utilities/TProtocolUtil.cs3
-rw-r--r--test/ConstantsDemo.thrift2
-rw-r--r--test/DebugProtoTest.thrift1
-rw-r--r--test/ThriftTest.thrift8
-rw-r--r--test/netstd/Client/TestClient.cs22
-rw-r--r--test/netstd/Server/Server.csproj2
-rw-r--r--test/netstd/Server/TestServer.cs6
62 files changed, 740 insertions, 137 deletions
diff --git a/.gitignore b/.gitignore
index 6278185b2..85b694cad 100644
--- a/.gitignore
+++ b/.gitignore
@@ -201,9 +201,9 @@ project.lock.json
/lib/delphi/*.local
/lib/delphi/*.identcache
/lib/delphi/test/skip/bin
-/lib/delphi/test/serializer/*.dat
+/lib/delphi/test/serializer/**/*.dat
/lib/delphi/test/serializer/bin
-/lib/delphi/test/thrift-testing
+/lib/delphi/test/thrift-testing/*.thrift
/lib/delphi/**/*.identcache
/lib/delphi/**/*.local
/lib/delphi/**/*.dcu
diff --git a/compiler/cpp/src/thrift/common.cc b/compiler/cpp/src/thrift/common.cc
index 6dcd85500..3a28407a4 100644
--- a/compiler/cpp/src/thrift/common.cc
+++ b/compiler/cpp/src/thrift/common.cc
@@ -23,6 +23,7 @@
t_type* g_type_void;
t_type* g_type_string;
t_type* g_type_binary;
+t_type* g_type_uuid;
t_type* g_type_bool;
t_type* g_type_i8;
t_type* g_type_i16;
@@ -35,6 +36,7 @@ void initGlobals() {
g_type_string = new t_base_type("string", t_base_type::TYPE_STRING);
g_type_binary = new t_base_type("string", t_base_type::TYPE_STRING);
((t_base_type*)g_type_binary)->set_binary(true);
+ g_type_uuid = new t_base_type("string", t_base_type::TYPE_UUID);
g_type_bool = new t_base_type("bool", t_base_type::TYPE_BOOL);
g_type_i8 = new t_base_type("i8", t_base_type::TYPE_I8);
g_type_i16 = new t_base_type("i16", t_base_type::TYPE_I16);
@@ -46,6 +48,8 @@ void initGlobals() {
void clearGlobals() {
delete g_type_void;
delete g_type_string;
+ delete g_type_binary;
+ delete g_type_uuid;
delete g_type_bool;
delete g_type_i8;
delete g_type_i16;
diff --git a/compiler/cpp/src/thrift/common.h b/compiler/cpp/src/thrift/common.h
index 06392cda7..059421df1 100644
--- a/compiler/cpp/src/thrift/common.h
+++ b/compiler/cpp/src/thrift/common.h
@@ -29,6 +29,7 @@
extern t_type* g_type_void;
extern t_type* g_type_string;
extern t_type* g_type_binary;
+extern t_type* g_type_uuid;
extern t_type* g_type_bool;
extern t_type* g_type_i8;
extern t_type* g_type_i16;
diff --git a/compiler/cpp/src/thrift/generate/t_c_glib_generator.cc b/compiler/cpp/src/thrift/generate/t_c_glib_generator.cc
index 8cb82c180..4ce9c5fdc 100644
--- a/compiler/cpp/src/thrift/generate/t_c_glib_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_c_glib_generator.cc
@@ -723,6 +723,8 @@ string t_c_glib_generator::type_to_enum(t_type* type) {
return "T_I64";
case t_base_type::TYPE_DOUBLE:
return "T_DOUBLE";
+ default:
+ break;
}
} else if (type->is_enum()) {
return "T_I32";
diff --git a/compiler/cpp/src/thrift/generate/t_cpp_generator.cc b/compiler/cpp/src/thrift/generate/t_cpp_generator.cc
index d9898b7c5..0420e62e7 100644
--- a/compiler/cpp/src/thrift/generate/t_cpp_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_cpp_generator.cc
@@ -689,7 +689,7 @@ void t_cpp_generator::generate_enum_to_string_helper_function(std::ostream& out,
out << tenum->get_name() << "::type&";
}
out << " val) " ;
- scope_up(out);
+ scope_up(out);
out << indent() << "std::map<int, const char*>::const_iterator it = _"
<< tenum->get_name() << "_VALUES_TO_NAMES.find(val);" << endl;
@@ -1221,7 +1221,7 @@ void t_cpp_generator::generate_struct_declaration(ostream& out,
// Declare all fields
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
- generate_java_doc(out, *m_iter);
+ generate_java_doc(out, *m_iter);
indent(out) << declare_field(*m_iter,
false,
(pointers && !(*m_iter)->get_type()->is_xception()),
@@ -2475,11 +2475,11 @@ void t_cpp_generator::generate_service_client(t_service* tservice, string style)
indent_up();
if (style != "Cob") {
f_header_ << indent() << service_name_ << style << "Client" << short_suffix << "(" << prot_ptr
- << " prot";
- if (style == "Concurrent") {
- f_header_ << ", std::shared_ptr< ::apache::thrift::async::TConcurrentClientSyncInfo> sync";
- }
- f_header_ << ") ";
+ << " prot";
+ if (style == "Concurrent") {
+ f_header_ << ", std::shared_ptr< ::apache::thrift::async::TConcurrentClientSyncInfo> sync";
+ }
+ f_header_ << ") ";
if (extends.empty()) {
if (style == "Concurrent") {
@@ -2498,12 +2498,12 @@ void t_cpp_generator::generate_service_client(t_service* tservice, string style)
}
f_header_ << indent() << service_name_ << style << "Client" << short_suffix << "(" << prot_ptr
- << " iprot, " << prot_ptr << " oprot";
- if (style == "Concurrent") {
- f_header_ << ", std::shared_ptr< ::apache::thrift::async::TConcurrentClientSyncInfo> sync";
- }
- f_header_ << ") ";
-
+ << " iprot, " << prot_ptr << " oprot";
+ if (style == "Concurrent") {
+ f_header_ << ", std::shared_ptr< ::apache::thrift::async::TConcurrentClientSyncInfo> sync";
+ }
+ f_header_ << ") ";
+
if (extends.empty()) {
if (style == "Concurrent") {
f_header_ << ": sync_(sync)" << endl;
@@ -4660,6 +4660,8 @@ string t_cpp_generator::type_to_enum(t_type* type) {
return "::apache::thrift::protocol::T_I64";
case t_base_type::TYPE_DOUBLE:
return "::apache::thrift::protocol::T_DOUBLE";
+ default:
+ break;
}
} else if (type->is_enum()) {
return "::apache::thrift::protocol::T_I32";
diff --git a/compiler/cpp/src/thrift/generate/t_d_generator.cc b/compiler/cpp/src/thrift/generate/t_d_generator.cc
index afae5b53d..f9e485642 100644
--- a/compiler/cpp/src/thrift/generate/t_d_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_d_generator.cc
@@ -74,9 +74,9 @@ protected:
// D reserved words are suffixed with an underscore
static string suffix_if_reserved(const string& name) {
- const bool isIn = std::binary_search(std::begin(d_reserved_words), std::end(d_reserved_words), name);
- string ret = isIn ? name + "_" : name;
- return ret;
+ const bool isIn = std::binary_search(std::begin(d_reserved_words), std::end(d_reserved_words), name);
+ string ret = isIn ? name + "_" : name;
+ return ret;
}
void init_generator() override {
@@ -403,8 +403,8 @@ private:
out << indent() << "// Your implementation goes here." << endl << indent() << "writeln(\""
<< suffix_if_reserved((*f_iter)->get_name()) << " called\");" << endl;
- t_type* rt = (*f_iter)->get_returntype();
- if (!rt->is_void()) {
+ t_type* rt = (*f_iter)->get_returntype();
+ if (!rt->is_void()) {
indent(out) << "return typeof(return).init;" << endl;
}
diff --git a/compiler/cpp/src/thrift/generate/t_dart_generator.cc b/compiler/cpp/src/thrift/generate/t_dart_generator.cc
index 65d0f535f..61cd98167 100644
--- a/compiler/cpp/src/thrift/generate/t_dart_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_dart_generator.cc
@@ -2216,6 +2216,8 @@ string t_dart_generator::declare_field(t_field* tfield, bool init) {
case t_base_type::TYPE_DOUBLE:
result += " = 0.0";
break;
+ default:
+ throw "compiler error: unhandled type";
}
} else if (ttype->is_enum()) {
@@ -2297,6 +2299,8 @@ string t_dart_generator::type_to_enum(t_type* type) {
return "TType.I64";
case t_base_type::TYPE_DOUBLE:
return "TType.DOUBLE";
+ default:
+ break;
}
} else if (type->is_enum()) {
return "TType.I32";
@@ -2351,6 +2355,8 @@ std::string t_dart_generator::init_value(t_field* field) {
case t_base_type::TYPE_STRING:
result = "";
break;
+ default:
+ throw "compiler error: unhandled type";
}
return result;
diff --git a/compiler/cpp/src/thrift/generate/t_delphi_generator.cc b/compiler/cpp/src/thrift/generate/t_delphi_generator.cc
index 2d0af119f..f35ffcb99 100644
--- a/compiler/cpp/src/thrift/generate/t_delphi_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_delphi_generator.cc
@@ -1024,6 +1024,7 @@ void t_delphi_generator::init_known_types_list() {
// known base types
types_known[type_name(g_type_string)] = 1;
types_known[type_name(g_type_binary)] = 1;
+ types_known[type_name(g_type_uuid)] = 1;
types_known[type_name(g_type_bool)] = 1;
types_known[type_name(g_type_i8)] = 1;
types_known[type_name(g_type_i16)] = 1;
@@ -1398,6 +1399,9 @@ string t_delphi_generator::render_const_value(ostream& vars,
case t_base_type::TYPE_STRING:
render << "'" << get_escaped_string(value) << "'";
break;
+ case t_base_type::TYPE_UUID:
+ render << "['{" << value->get_uuid() << "}']";
+ break;
case t_base_type::TYPE_BOOL:
render << ((value->get_integer() > 0) ? "True" : "False");
break;
@@ -2709,6 +2713,9 @@ void t_delphi_generator::generate_deserialize_field(ostream& out,
out << "ReadString();";
}
break;
+ case t_base_type::TYPE_UUID:
+ out << "ReadUuid();";
+ break;
case t_base_type::TYPE_BOOL:
out << "ReadBool();";
break;
@@ -2910,6 +2917,9 @@ void t_delphi_generator::generate_serialize_field(ostream& out,
}
out << name << ");";
break;
+ case t_base_type::TYPE_UUID:
+ out << "WriteUuid(" << name << ");";
+ break;
case t_base_type::TYPE_BOOL:
out << "WriteBool(" << name << ");";
break;
@@ -3195,6 +3205,7 @@ string t_delphi_generator::input_arg_prefix(t_type* ttype) {
// these should be const'ed for optimal performamce
case t_base_type::TYPE_STRING: // refcounted pointer
+ case t_base_type::TYPE_UUID: // refcounted pointer
case t_base_type::TYPE_I64: // larger than 32 bit
case t_base_type::TYPE_DOUBLE: // larger than 32 bit
return "const ";
@@ -3247,6 +3258,8 @@ string t_delphi_generator::base_type_name(t_base_type* tbase) {
} else {
return com_types_ ? "System.WideString" : "System.string";
}
+ case t_base_type::TYPE_UUID:
+ return "System.TGuid";
case t_base_type::TYPE_BOOL:
return "System.Boolean";
case t_base_type::TYPE_I8:
@@ -3413,6 +3426,8 @@ string t_delphi_generator::type_to_enum(t_type* type) {
throw "NO T_VOID CONSTRUCT";
case t_base_type::TYPE_STRING:
return "TType.String_";
+ case t_base_type::TYPE_UUID:
+ return "TType.Uuid";
case t_base_type::TYPE_BOOL:
return "TType.Bool_";
case t_base_type::TYPE_I8:
@@ -3461,6 +3476,8 @@ string t_delphi_generator::empty_value(t_type* type) {
} else {
return "''";
}
+ case t_base_type::TYPE_UUID:
+ return "System.TGuid.Empty";
case t_base_type::TYPE_BOOL:
return "False";
case t_base_type::TYPE_I8:
@@ -4065,6 +4082,9 @@ void t_delphi_generator::generate_delphi_struct_tostring_impl(ostream& out,
<< type_name(ttype, false, true, false, false)
<< ">.ToString( System.Ord( Self."
<< prop_name((*f_iter), is_exception) << ")));" << endl;
+ } else if (ttype->is_uuid()) {
+ indent_impl(out) << tmp_sb << ".Append( GUIDToString(Self." << prop_name((*f_iter), is_exception) << "));"
+ << endl;
} else {
indent_impl(out) << tmp_sb << ".Append( Self." << prop_name((*f_iter), is_exception) << ");"
<< endl;
diff --git a/compiler/cpp/src/thrift/generate/t_erl_generator.cc b/compiler/cpp/src/thrift/generate/t_erl_generator.cc
index c06ea437d..1f4fd506d 100644
--- a/compiler/cpp/src/thrift/generate/t_erl_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_erl_generator.cc
@@ -1168,6 +1168,8 @@ string t_erl_generator::type_to_enum(t_type* type) {
return "?tType_I64";
case t_base_type::TYPE_DOUBLE:
return "?tType_DOUBLE";
+ default:
+ break;
}
} else if (type->is_enum()) {
return "?tType_I32";
@@ -1211,6 +1213,8 @@ std::string t_erl_generator::render_type_term(t_type* type,
return "i64";
case t_base_type::TYPE_DOUBLE:
return "double";
+ default:
+ break;
}
} else if (type->is_enum()) {
return "i32";
diff --git a/compiler/cpp/src/thrift/generate/t_go_generator.cc b/compiler/cpp/src/thrift/generate/t_go_generator.cc
index f4b94a455..90f34c8ca 100644
--- a/compiler/cpp/src/thrift/generate/t_go_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_go_generator.cc
@@ -368,6 +368,8 @@ bool t_go_generator::omit_initialization(t_field* tfield) {
} else {
return value->get_double() == 0.;
}
+ default:
+ throw "compiler error: unhandled type";
}
}
return false;
@@ -420,6 +422,8 @@ bool t_go_generator::is_pointer_field(t_field* tfield, bool in_container_value)
case t_base_type::TYPE_I64:
case t_base_type::TYPE_DOUBLE:
return !has_default;
+ default:
+ break;
}
} else if (type->is_enum()) {
return !has_default;
@@ -4057,6 +4061,9 @@ string t_go_generator::type_to_enum(t_type* type) {
case t_base_type::TYPE_DOUBLE:
return "thrift.DOUBLE";
+
+ default:
+ break;
}
} else if (type->is_enum()) {
return "thrift.I32";
@@ -4144,6 +4151,9 @@ string t_go_generator::type_to_go_type_with_opt(t_type* type,
case t_base_type::TYPE_DOUBLE:
return maybe_pointer + "float64";
+
+ default:
+ break;
}
} else if (type->is_enum()) {
return maybe_pointer + publicize(type_name(type));
diff --git a/compiler/cpp/src/thrift/generate/t_haxe_generator.cc b/compiler/cpp/src/thrift/generate/t_haxe_generator.cc
index 757f207f0..fdd21f2a3 100644
--- a/compiler/cpp/src/thrift/generate/t_haxe_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_haxe_generator.cc
@@ -2698,6 +2698,8 @@ string t_haxe_generator::declare_field(t_field* tfield, bool init) {
case t_base_type::TYPE_DOUBLE:
result += " = (double)0";
break;
+ default:
+ throw "unhandled type";
}
} else if (ttype->is_enum()) {
@@ -2805,6 +2807,8 @@ string t_haxe_generator::type_to_enum(t_type* type) {
return "TType.I64";
case t_base_type::TYPE_DOUBLE:
return "TType.DOUBLE";
+ default:
+ break;
}
} else if (type->is_enum()) {
return "TType.I32";
diff --git a/compiler/cpp/src/thrift/generate/t_java_generator.cc b/compiler/cpp/src/thrift/generate/t_java_generator.cc
index 7dfd10f52..743d150fe 100644
--- a/compiler/cpp/src/thrift/generate/t_java_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_java_generator.cc
@@ -1833,6 +1833,8 @@ void t_java_generator::generate_java_struct_parcelable(ostream& out, t_struct* t
break;
case t_base_type::TYPE_VOID:
break;
+ default:
+ throw "compiler error: unhandled type";
}
}
}
@@ -1931,6 +1933,8 @@ void t_java_generator::generate_java_struct_parcelable(ostream& out, t_struct* t
break;
case t_base_type::TYPE_VOID:
break;
+ default:
+ throw "compiler error: unhandled type";
}
}
}
@@ -4666,6 +4670,8 @@ string t_java_generator::declare_field(t_field* tfield, bool init, bool comment)
case t_base_type::TYPE_DOUBLE:
result += " = (double)0";
break;
+ default:
+ throw "compiler error: unhandled type";
}
} else if (ttype->is_enum()) {
result += " = null";
@@ -4843,6 +4849,8 @@ string t_java_generator::type_to_enum(t_type* type) {
return "org.apache.thrift.protocol.TType.I64";
case t_base_type::TYPE_DOUBLE:
return "org.apache.thrift.protocol.TType.DOUBLE";
+ default:
+ throw "compiler error: unhandled type";
}
} else if (type->is_enum()) {
return "org.apache.thrift.protocol.TType.I32";
diff --git a/compiler/cpp/src/thrift/generate/t_javame_generator.cc b/compiler/cpp/src/thrift/generate/t_javame_generator.cc
index b37a43bd0..4da086965 100644
--- a/compiler/cpp/src/thrift/generate/t_javame_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_javame_generator.cc
@@ -2869,6 +2869,8 @@ string t_javame_generator::declare_field(t_field* tfield, bool init) {
case t_base_type::TYPE_DOUBLE:
result += " = (double)0";
break;
+ default:
+ throw "compiler error: unhandled type";
}
} else if (ttype->is_enum()) {
@@ -2951,6 +2953,8 @@ string t_javame_generator::type_to_enum(t_type* type) {
return "TType.I64";
case t_base_type::TYPE_DOUBLE:
return "TType.DOUBLE";
+ default:
+ throw "compiler error: unhandled type";
}
} else if (type->is_enum()) {
return "TType.I32";
diff --git a/compiler/cpp/src/thrift/generate/t_js_generator.cc b/compiler/cpp/src/thrift/generate/t_js_generator.cc
index 5fcac1659..03a307f82 100644
--- a/compiler/cpp/src/thrift/generate/t_js_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_js_generator.cc
@@ -2697,6 +2697,8 @@ string t_js_generator::type_to_enum(t_type* type) {
return "Thrift.Type.I64";
case t_base_type::TYPE_DOUBLE:
return "Thrift.Type.DOUBLE";
+ default:
+ throw "compiler error: unhandled type";
}
} else if (type->is_enum()) {
return "Thrift.Type.I32";
@@ -2745,6 +2747,9 @@ string t_js_generator::ts_get_type(t_type* type) {
break;
case t_base_type::TYPE_VOID:
ts_type = "void";
+ break;
+ default:
+ throw "compiler error: unhandled type";
}
} else if (type->is_enum() || type->is_struct() || type->is_xception()) {
std::string type_name;
diff --git a/compiler/cpp/src/thrift/generate/t_kotlin_generator.cc b/compiler/cpp/src/thrift/generate/t_kotlin_generator.cc
index 3a2afe6d5..3a3543e63 100644
--- a/compiler/cpp/src/thrift/generate/t_kotlin_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_kotlin_generator.cc
@@ -1892,6 +1892,8 @@ string t_kotlin_generator::type_to_enum(t_type* type) {
return "org.apache.thrift.protocol.TType.I64";
case t_base_type::TYPE_DOUBLE:
return "org.apache.thrift.protocol.TType.DOUBLE";
+ default:
+ throw "compiler error: unhandled type";
}
} else if (type->is_enum()) {
return "org.apache.thrift.protocol.TType.I32";
diff --git a/compiler/cpp/src/thrift/generate/t_lua_generator.cc b/compiler/cpp/src/thrift/generate/t_lua_generator.cc
index de3b89011..a4b4a37d3 100644
--- a/compiler/cpp/src/thrift/generate/t_lua_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_lua_generator.cc
@@ -1146,6 +1146,8 @@ string t_lua_generator::type_to_enum(t_type* type) {
return "TType.I64";
case t_base_type::TYPE_DOUBLE:
return "TType.DOUBLE";
+ default:
+ throw "compiler error: unhandled type";
}
} else if (type->is_enum()) {
return "TType.I32";
diff --git a/compiler/cpp/src/thrift/generate/t_markdown_generator.cc b/compiler/cpp/src/thrift/generate/t_markdown_generator.cc
index 17e90f759..0f6aa2227 100644
--- a/compiler/cpp/src/thrift/generate/t_markdown_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_markdown_generator.cc
@@ -199,7 +199,7 @@ void t_markdown_generator::generate_program_toc_row(t_program* tprog) {
string fn_name = (*fn_iter)->get_name();
filling.emplace_back();
fill = &filling.back();
- (*fill)[1] = " [ &bull; " + fn_name + "]("
+ (*fill)[1] = " [ &bull; " + fn_name + "]("
+ make_file_link(fname)
+ "#function-" + str_to_id(name + fn_name) + ")";
}
diff --git a/compiler/cpp/src/thrift/generate/t_netstd_generator.cc b/compiler/cpp/src/thrift/generate/t_netstd_generator.cc
index ad9e57965..547457130 100644
--- a/compiler/cpp/src/thrift/generate/t_netstd_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_netstd_generator.cc
@@ -636,6 +636,9 @@ string t_netstd_generator::render_const_value(ostream& out, string name, t_type*
render << '"' << get_escaped_string(value) << '"';
}
break;
+ case t_base_type::TYPE_UUID:
+ render << "new System.Guid(\"" << get_escaped_string(value) << "\")";
+ break;
case t_base_type::TYPE_BOOL:
render << ((value->get_integer() > 0) ? "true" : "false");
break;
@@ -2703,6 +2706,9 @@ void t_netstd_generator::generate_deserialize_field(ostream& out, t_field* tfiel
out << "ReadStringAsync(" << CANCELLATION_TOKEN_NAME << ");";
}
break;
+ case t_base_type::TYPE_UUID:
+ out << "ReadUuidAsync(" << CANCELLATION_TOKEN_NAME << ");";
+ break;
case t_base_type::TYPE_BOOL:
out << "ReadBoolAsync(" << CANCELLATION_TOKEN_NAME << ");";
break;
@@ -2906,6 +2912,9 @@ void t_netstd_generator::generate_serialize_field(ostream& out, t_field* tfield,
}
out << name << ", " << CANCELLATION_TOKEN_NAME << ");";
break;
+ case t_base_type::TYPE_UUID:
+ out << "WriteUuidAsync(" << nullable_name << ", " << CANCELLATION_TOKEN_NAME << ");";
+ break;
case t_base_type::TYPE_BOOL:
out << "WriteBoolAsync(" << nullable_name << ", " << CANCELLATION_TOKEN_NAME << ");";
break;
@@ -3453,7 +3462,7 @@ string t_netstd_generator::type_name(t_type* ttype, bool with_namespace)
if (ttype->is_set())
{
t_set* tset = static_cast<t_set*>(ttype);
- return "HashSet<" + type_name(tset->get_elem_type()) + ">";
+ return "HashSet<" + type_name(tset->get_elem_type()) + ">";
}
if (ttype->is_list())
@@ -3492,6 +3501,8 @@ string t_netstd_generator::base_type_name(t_base_type* tbase)
} else {
return "string";
}
+ case t_base_type::TYPE_UUID:
+ return "global::System.Guid";
case t_base_type::TYPE_BOOL:
return "bool";
case t_base_type::TYPE_I8:
@@ -3614,6 +3625,9 @@ string t_netstd_generator::initialize_field(t_field* tfield)
return " = null";
}
break;
+ case t_base_type::TYPE_UUID:
+ return " = System.Guid.Empty";
+ break;
case t_base_type::TYPE_BOOL:
return " = false";
break;
@@ -3725,6 +3739,8 @@ string t_netstd_generator::type_to_enum(t_type* type)
throw "NO T_VOID CONSTRUCT";
case t_base_type::TYPE_STRING:
return "TType.String";
+ case t_base_type::TYPE_UUID:
+ return "TType.Uuid";
case t_base_type::TYPE_BOOL:
return "TType.Bool";
case t_base_type::TYPE_I8:
diff --git a/compiler/cpp/src/thrift/generate/t_ocaml_generator.cc b/compiler/cpp/src/thrift/generate/t_ocaml_generator.cc
index 0a961467e..300b5ac71 100644
--- a/compiler/cpp/src/thrift/generate/t_ocaml_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_ocaml_generator.cc
@@ -1698,6 +1698,8 @@ string t_ocaml_generator::type_to_enum(t_type* type) {
return "Protocol.T_I64";
case t_base_type::TYPE_DOUBLE:
return "Protocol.T_DOUBLE";
+ default:
+ throw "compiler error: unhandled type";
}
} else if (type->is_enum()) {
return "Protocol.T_I32";
@@ -1739,6 +1741,8 @@ string t_ocaml_generator::render_ocaml_type(t_type* type) {
return "Int64.t";
case t_base_type::TYPE_DOUBLE:
return "float";
+ default:
+ throw "compiler error: unhandled type";
}
} else if (type->is_enum()) {
return capitalize(((t_enum*)type)->get_name()) + ".t";
diff --git a/compiler/cpp/src/thrift/generate/t_perl_generator.cc b/compiler/cpp/src/thrift/generate/t_perl_generator.cc
index 68bd57f0f..72de69887 100644
--- a/compiler/cpp/src/thrift/generate/t_perl_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_perl_generator.cc
@@ -1003,12 +1003,12 @@ void t_perl_generator::generate_service_rest(t_service* tservice) {
f_service_ << indent() << "my $" << (*a_iter)->get_name() << " = (" << req << ") ? " << req
<< " : undef;" << endl;
/* slist no longer supported
- if (atype->is_string() && ((t_base_type*)atype)->is_string_list()) {
+ if (atype->is_string() && ((t_base_type*)atype)->is_string_list()) {
f_service_ << indent() << "my @" << (*a_iter)->get_name() << " = split(/,/, $"
<< (*a_iter)->get_name() << ");" << endl << indent() << "$"
<< (*a_iter)->get_name() << " = \\@" << (*a_iter)->get_name() << endl;
}
- */
+ */
}
f_service_ << indent() << "return $self->{impl}->" << (*f_iter)->get_name() << "("
<< argument_list((*f_iter)->get_arglist()) << ");" << endl;
@@ -1666,6 +1666,8 @@ string t_perl_generator::type_to_enum(t_type* type) {
return "Thrift::TType::I64";
case t_base_type::TYPE_DOUBLE:
return "Thrift::TType::DOUBLE";
+ default:
+ throw "compiler error: unhandled type";
}
} else if (type->is_enum()) {
return "Thrift::TType::I32";
diff --git a/compiler/cpp/src/thrift/generate/t_php_generator.cc b/compiler/cpp/src/thrift/generate/t_php_generator.cc
index 39968a658..c6e60c82a 100644
--- a/compiler/cpp/src/thrift/generate/t_php_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_php_generator.cc
@@ -62,7 +62,7 @@ public:
validate_ = false;
json_serializable_ = false;
getters_setters_ = false;
-
+
nsglobal_ = ""; // by default global namespace is empty
classmap_ = false;
for (iter = parsed_options.begin(); iter != parsed_options.end(); ++iter) {
@@ -874,8 +874,8 @@ void t_php_generator::generate_reflection_getters(ostringstream& out,
* Generates a setter for the generated private fields
*/
void t_php_generator::generate_reflection_setters(ostringstream& out,
- string field_name,
- string cap_name) {
+ string field_name,
+ string cap_name) {
out << indent() << "public function set" << cap_name << "(" << "$" << field_name << ")" << endl
<< indent() << "{" << endl;
@@ -2798,6 +2798,8 @@ string t_php_generator::type_to_enum(t_type* type) {
return "TType::I64";
case t_base_type::TYPE_DOUBLE:
return "TType::DOUBLE";
+ default:
+ throw "compiler error: unhandled type";
}
} else if (type->is_enum()) {
return "TType::I32";
@@ -2839,6 +2841,8 @@ string t_php_generator::type_to_phpdoc(t_type* type) {
return "int";
case t_base_type::TYPE_DOUBLE:
return "double";
+ default:
+ throw "compiler error: unhandled type";
}
} else if (type->is_enum()) {
return "int";
diff --git a/compiler/cpp/src/thrift/generate/t_py_generator.cc b/compiler/cpp/src/thrift/generate/t_py_generator.cc
index 7f3cae546..33437fd00 100644
--- a/compiler/cpp/src/thrift/generate/t_py_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_py_generator.cc
@@ -2767,6 +2767,8 @@ string t_py_generator::type_to_enum(t_type* type) {
return "TType.I64";
case t_base_type::TYPE_DOUBLE:
return "TType.DOUBLE";
+ default:
+ throw "compiler error: unhandled type";
}
} else if (type->is_enum()) {
return "TType.I32";
diff --git a/compiler/cpp/src/thrift/generate/t_rb_generator.cc b/compiler/cpp/src/thrift/generate/t_rb_generator.cc
index 116ccaaa7..2ec578771 100644
--- a/compiler/cpp/src/thrift/generate/t_rb_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_rb_generator.cc
@@ -1171,6 +1171,8 @@ string t_rb_generator::type_to_enum(t_type* type) {
return "::Thrift::Types::I64";
case t_base_type::TYPE_DOUBLE:
return "::Thrift::Types::DOUBLE";
+ default:
+ throw "compiler error: unhandled type";
}
} else if (type->is_enum()) {
return "::Thrift::Types::I32";
diff --git a/compiler/cpp/src/thrift/generate/t_rs_generator.cc b/compiler/cpp/src/thrift/generate/t_rs_generator.cc
index 6ce402739..5946e1d9a 100644
--- a/compiler/cpp/src/thrift/generate/t_rs_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_rs_generator.cc
@@ -1551,6 +1551,8 @@ void t_rs_generator::render_type_sync_write(const string &type_var, bool type_va
case t_base_type::TYPE_DOUBLE:
f_gen_ << indent() << "o_prot.write_double(" + type_var + ".into())?;" << endl;
return;
+ default:
+ throw "compiler error: unhandled type";
}
} else if (ttype->is_typedef()) {
t_typedef* ttypedef = (t_typedef*) ttype;
@@ -1926,6 +1928,8 @@ void t_rs_generator::render_type_sync_read(const string &type_var, t_type *ttype
case t_base_type::TYPE_DOUBLE:
f_gen_ << indent() << "let " << type_var << " = OrderedFloat::from(i_prot.read_double()?);" << endl;
return;
+ default:
+ throw "compiler error: unhandled type";
}
} else if (ttype->is_typedef()) {
// FIXME: not a fan of separate `is_boxed` parameter
@@ -3025,6 +3029,8 @@ string t_rs_generator::to_rust_type(t_type* ttype) {
return "i64";
case t_base_type::TYPE_DOUBLE:
return "OrderedFloat<f64>";
+ default:
+ throw "compiler error: unhandled type";
}
} else if (ttype->is_typedef()) {
t_typedef* ttypedef = (t_typedef*)ttype;
@@ -3085,6 +3091,8 @@ string t_rs_generator::to_rust_field_type_enum(t_type* ttype) {
return "TType::I64";
case t_base_type::TYPE_DOUBLE:
return "TType::Double";
+ default:
+ throw "compiler error: unhandled type";
}
} else if (ttype->is_enum()) {
return "TType::I32";
@@ -3123,6 +3131,8 @@ string t_rs_generator::opt_in_req_out_value(t_type* ttype) {
return "Some(0)";
case t_base_type::TYPE_DOUBLE:
return "Some(OrderedFloat::from(0.0))";
+ default:
+ throw "compiler error: unhandled type";
}
} else if (ttype->is_enum() || ttype->is_struct() || ttype->is_xception()) {
diff --git a/compiler/cpp/src/thrift/generate/t_st_generator.cc b/compiler/cpp/src/thrift/generate/t_st_generator.cc
index 109adc705..5edb85281 100644
--- a/compiler/cpp/src/thrift/generate/t_st_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_st_generator.cc
@@ -1037,6 +1037,8 @@ string t_st_generator::type_to_enum(t_type* type) {
return "TType i64";
case t_base_type::TYPE_DOUBLE:
return "TType double";
+ default:
+ throw "compiler error: unhandled type";
}
} else if (type->is_enum()) {
return "TType i32";
diff --git a/compiler/cpp/src/thrift/generate/t_swift_generator.cc b/compiler/cpp/src/thrift/generate/t_swift_generator.cc
index d8eb73310..834e31dc8 100644
--- a/compiler/cpp/src/thrift/generate/t_swift_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_swift_generator.cc
@@ -51,7 +51,7 @@ public:
const string& option_string)
: t_oop_generator(program) {
update_keywords();
-
+
(void)option_string;
map<string, string>::const_iterator iter;
@@ -292,7 +292,7 @@ private:
protected:
std::set<std::string> lang_keywords() const override {
- return {};
+ return {};
}
};
@@ -3136,6 +3136,8 @@ string t_swift_generator::type_to_enum(t_type* type, bool qualified) {
return result + "i64";
case t_base_type::TYPE_DOUBLE:
return result + "double";
+ default:
+ throw "compiler error: unhandled type";
}
} else if (type->is_enum()) {
return result + "i32";
@@ -3168,6 +3170,8 @@ string t_swift_generator::type_to_enum(t_type* type, bool qualified) {
return result + "I64";
case t_base_type::TYPE_DOUBLE:
return result + "DOUBLE";
+ default:
+ throw "compiler error: unhandled type";
}
} else if (type->is_enum()) {
return result + "I32";
diff --git a/compiler/cpp/src/thrift/main.cc b/compiler/cpp/src/thrift/main.cc
index c5aa65f32..a07f4295a 100644
--- a/compiler/cpp/src/thrift/main.cc
+++ b/compiler/cpp/src/thrift/main.cc
@@ -738,6 +738,12 @@ void validate_const_rec(std::string name, t_type* type, t_const_value* value) {
throw "type error: const \"" + name + "\" was declared as string";
}
break;
+ case t_base_type::TYPE_UUID:
+ if (value->get_type() != t_const_value::CV_STRING) {
+ throw "type error: const \"" + name + "\" was declared as uuid";
+ }
+ value->get_uuid(); // validates constant
+ break;
case t_base_type::TYPE_BOOL:
if (value->get_type() != t_const_value::CV_INTEGER) {
throw "type error: const \"" + name + "\" was declared as bool";
diff --git a/compiler/cpp/src/thrift/parse/t_base_type.h b/compiler/cpp/src/thrift/parse/t_base_type.h
index 5676f0492..4e5228d54 100644
--- a/compiler/cpp/src/thrift/parse/t_base_type.h
+++ b/compiler/cpp/src/thrift/parse/t_base_type.h
@@ -36,6 +36,7 @@ public:
enum t_base {
TYPE_VOID,
TYPE_STRING,
+ TYPE_UUID,
TYPE_BOOL,
TYPE_I8,
TYPE_I16,
@@ -55,6 +56,8 @@ public:
bool is_bool() const override { return base_ == TYPE_BOOL; }
+ bool is_uuid() const override { return base_ == TYPE_UUID; }
+
void set_binary(bool val) { binary_ = val; }
bool is_binary() const override { return binary_ && (base_ == TYPE_STRING); }
@@ -69,6 +72,9 @@ public:
case TYPE_STRING:
return "string";
break;
+ case TYPE_UUID:
+ return "uuid";
+ break;
case TYPE_BOOL:
return "bool";
break;
diff --git a/compiler/cpp/src/thrift/parse/t_const_value.h b/compiler/cpp/src/thrift/parse/t_const_value.h
index 5b8156f1a..452a90c5b 100644
--- a/compiler/cpp/src/thrift/parse/t_const_value.h
+++ b/compiler/cpp/src/thrift/parse/t_const_value.h
@@ -85,6 +85,17 @@ public:
}
}
+ void set_uuid(std::string val) {
+ validate_uuid(val);
+ valType_ = CV_STRING;
+ stringVal_ = val;
+ }
+
+ std::string get_uuid() const {
+ validate_uuid(stringVal_);
+ return stringVal_;
+ }
+
void set_double(double val) {
valType_ = CV_DOUBLE;
doubleVal_ = val;
@@ -199,6 +210,34 @@ private:
t_enum* enum_;
t_const_value_type valType_;
+
+ void validate_uuid(std::string uuid) const {
+ bool valid = (uuid.length() == 36);
+ const std::string HEXCHARS = std::string("0123456789ABCDEFabcdef");
+
+ // canonical format "01234567-9012-4567-9012-456789012345" expected
+ for( size_t i = 0; valid && (i < uuid.length()); ++i) {
+ switch(i) {
+ case 8:
+ case 13:
+ case 18:
+ case 23:
+ if(uuid[i] != '-') {
+ valid = false;
+ }
+ break;
+ default:
+ if(HEXCHARS.find(uuid[i]) == std::string::npos) {
+ valid = false;
+ }
+ break;
+ }
+ }
+
+ if( ! valid) {
+ throw "invalid uuid " + uuid;
+ }
+ }
};
#endif
diff --git a/compiler/cpp/src/thrift/parse/t_scope.h b/compiler/cpp/src/thrift/parse/t_scope.h
index 17a360f08..71ab4f389 100644
--- a/compiler/cpp/src/thrift/parse/t_scope.h
+++ b/compiler/cpp/src/thrift/parse/t_scope.h
@@ -166,6 +166,9 @@ public:
case t_base_type::TYPE_STRING:
const_val->set_string(constant->get_value()->get_string());
break;
+ case t_base_type::TYPE_UUID:
+ const_val->set_uuid(constant->get_value()->get_uuid());
+ break;
case t_base_type::TYPE_DOUBLE:
const_val->set_double(constant->get_value()->get_double());
break;
diff --git a/compiler/cpp/src/thrift/parse/t_type.h b/compiler/cpp/src/thrift/parse/t_type.h
index 63f99ed87..8dbeb9efc 100644
--- a/compiler/cpp/src/thrift/parse/t_type.h
+++ b/compiler/cpp/src/thrift/parse/t_type.h
@@ -47,6 +47,7 @@ public:
virtual bool is_void() const { return false; }
virtual bool is_base_type() const { return false; }
virtual bool is_string() const { return false; }
+ virtual bool is_uuid() const { return false; }
virtual bool is_binary() const { return false; }
virtual bool is_bool() const { return false; }
virtual bool is_typedef() const { return false; }
diff --git a/compiler/cpp/src/thrift/thriftl.ll b/compiler/cpp/src/thrift/thriftl.ll
index 810a983e0..d60e84645 100644
--- a/compiler/cpp/src/thrift/thriftl.ll
+++ b/compiler/cpp/src/thrift/thriftl.ll
@@ -239,6 +239,7 @@ literal_begin (['\"])
"double" { return tok_double; }
"string" { return tok_string; }
"binary" { return tok_binary; }
+"uuid" { return tok_uuid; }
"slist" {
error_no_longer_supported("slist","string");
}
diff --git a/compiler/cpp/src/thrift/thrifty.yy b/compiler/cpp/src/thrift/thrifty.yy
index a062a0e40..40c2a9373 100644
--- a/compiler/cpp/src/thrift/thrifty.yy
+++ b/compiler/cpp/src/thrift/thrifty.yy
@@ -134,6 +134,7 @@ const int struct_is_union = 1;
%token tok_bool
%token tok_string
%token tok_binary
+%token tok_uuid
%token tok_i8
%token tok_i16
%token tok_i32
@@ -1002,6 +1003,11 @@ SimpleBaseType:
pdebug("BaseType -> tok_binary");
$$ = g_type_binary;
}
+| tok_uuid
+ {
+ pdebug("BaseType -> tok_uuid");
+ $$ = g_type_uuid;
+ }
| tok_bool
{
pdebug("BaseType -> tok_bool");
diff --git a/lib/delphi/src/Thrift.Protocol.Compact.pas b/lib/delphi/src/Thrift.Protocol.Compact.pas
index 3a1dbfd0b..02a19ea80 100644
--- a/lib/delphi/src/Thrift.Protocol.Compact.pas
+++ b/lib/delphi/src/Thrift.Protocol.Compact.pas
@@ -77,7 +77,8 @@ type
LIST = $09,
SET_ = $0A,
MAP = $0B,
- STRUCT = $0C
+ STRUCT = $0C,
+ UUID = $0D
);
private type
@@ -100,7 +101,8 @@ type
Types.STRUCT, // Struct = 12,
Types.MAP, // Map = 13,
Types.SET_, // Set_ = 14,
- Types.LIST // List = 15,
+ Types.LIST, // List = 15,
+ Types.UUID // Uuid = 16
);
tcompactTypeToType : array[Types] of TType = (
@@ -116,7 +118,8 @@ type
TType.List, // LIST
TType.Set_, // SET_
TType.Map, // MAP
- TType.Struct // STRUCT
+ TType.Struct, // STRUCT
+ TType.Uuid // UUID
);
strict private
@@ -173,6 +176,7 @@ type
procedure WriteI64( const i64: Int64); override;
procedure WriteDouble( const dub: Double); override;
procedure WriteBinary( const b: TBytes); overload; override;
+ procedure WriteUuid( const uuid: TGuid); override;
private // unit visible stuff
class function DoubleToInt64Bits( const db : Double) : Int64;
@@ -219,6 +223,7 @@ type
function ReadI64: Int64; override;
function ReadDouble:Double; override;
function ReadBinary: TBytes; overload; override;
+ function ReadUuid: TGuid; override;
private
// Internal Reading methods
@@ -537,6 +542,14 @@ begin
Transport.Write( b);
end;
+procedure TCompactProtocolImpl.WriteUuid( const uuid: TGuid);
+var network : TGuid; // in network order (Big Endian)
+begin
+ ASSERT( SizeOf(uuid) = 16);
+ network := uuid.SwapByteOrder;
+ Transport.Write( @network, 0, SizeOf(network));
+end;
+
procedure TCompactProtocolImpl.WriteMessageEnd;
begin
// nothing to do
@@ -850,6 +863,14 @@ begin
then Transport.ReadAll( result, 0, length);
end;
+function TCompactProtocolImpl.ReadUuid: TGuid;
+var network : TGuid; // in network order (Big Endian)
+begin
+ ASSERT( SizeOf(result) = 16);
+ FTrans.ReadAll( @network, SizeOf(network), 0, SizeOf(network));
+ result := network.SwapByteOrder;
+end;
+
procedure TCompactProtocolImpl.ReadMessageEnd;
begin
@@ -994,6 +1015,7 @@ begin
TType.Map: result := SizeOf(Byte); // element count
TType.Set_: result := SizeOf(Byte); // element count
TType.List: result := SizeOf(Byte); // element count
+ TType.Uuid: result := SizeOf(TGuid);
else
raise TTransportExceptionBadArgs.Create('Unhandled type code');
end;
diff --git a/lib/delphi/src/Thrift.Protocol.JSON.pas b/lib/delphi/src/Thrift.Protocol.JSON.pas
index 52909b778..2a9682ced 100644
--- a/lib/delphi/src/Thrift.Protocol.JSON.pas
+++ b/lib/delphi/src/Thrift.Protocol.JSON.pas
@@ -198,6 +198,7 @@ type
procedure WriteDouble( const d: Double); override;
procedure WriteString( const s: string ); override;
procedure WriteBinary( const b: TBytes); override;
+ procedure WriteUuid( const uuid: TGuid); override;
//
function ReadMessageBegin: TThriftMessage; override;
procedure ReadMessageEnd(); override;
@@ -219,6 +220,7 @@ type
function ReadDouble:Double; override;
function ReadString : string; override;
function ReadBinary: TBytes; override;
+ function ReadUuid: TGuid; override;
strict private
@@ -288,6 +290,7 @@ const
NAME_MAP = 'map';
NAME_LIST = 'lst';
NAME_SET = 'set';
+ NAME_UUID = 'uid';
INVARIANT_CULTURE : TFormatSettings
= ( ThousandSeparator: ',';
@@ -317,6 +320,7 @@ begin
TType.Map: result := NAME_MAP;
TType.Set_: result := NAME_SET;
TType.List: result := NAME_LIST;
+ TType.Uuid: result := NAME_UUID;
else
raise TProtocolExceptionNotImplemented.Create('Unrecognized type ('+IntToStr(Ord(typeID))+')');
end;
@@ -336,6 +340,7 @@ begin
else if name = NAME_MAP then result := TType.Map
else if name = NAME_LIST then result := TType.List
else if name = NAME_SET then result := TType.Set_
+ else if name = NAME_UUID then result := TType.Uuid
else raise TProtocolExceptionNotImplemented.Create('Unrecognized type ('+name+')');
end;
@@ -831,6 +836,11 @@ begin
WriteJSONBase64( b);
end;
+procedure TJSONProtocolImpl.WriteUuid( const uuid: TGuid);
+begin
+ WriteString( Copy( GuidToString(uuid), 2, 36)); // strip off the { braces }
+end;
+
function TJSONProtocolImpl.ReadJSONString( skipContext : Boolean) : TBytes;
var buffer : TThriftMemoryStream;
@@ -1237,6 +1247,12 @@ begin
end;
+function TJSONProtocolImpl.ReadUuid: TGuid;
+begin
+ result := StringToGUID( '{' + ReadString + '}');
+end;
+
+
function TJSONProtocolImpl.GetMinSerializedSize( const aType : TType) : Integer;
// Return the minimum number of bytes a type will consume on the wire
begin
@@ -1254,6 +1270,7 @@ begin
TType.Map: result := 2; // empty map
TType.Set_: result := 2; // empty set
TType.List: result := 2; // empty list
+ TType.Uuid: result := 36; // "E236974D-F0B0-4E05-8F29-0B455D41B1A1"
else
raise TTransportExceptionBadArgs.Create('Unhandled type code');
end;
diff --git a/lib/delphi/src/Thrift.Protocol.pas b/lib/delphi/src/Thrift.Protocol.pas
index 9f2cac8d1..636f20100 100644
--- a/lib/delphi/src/Thrift.Protocol.pas
+++ b/lib/delphi/src/Thrift.Protocol.pas
@@ -49,7 +49,8 @@ type
Struct = 12,
Map = 13,
Set_ = 14,
- List = 15
+ List = 15,
+ Uuid = 16
);
TMessageType = (
@@ -62,7 +63,7 @@ type
const
VALID_TTYPES = [
TType.Stop, TType.Void,
- TType.Bool_, TType.Byte_, TType.Double_, TType.I16, TType.I32, TType.I64, TType.String_,
+ TType.Bool_, TType.Byte_, TType.Double_, TType.I16, TType.I32, TType.I64, TType.String_, TType.Uuid,
TType.Struct, TType.Map, TType.Set_, TType.List
];
@@ -221,6 +222,7 @@ type
procedure WriteAnsiString( const s: AnsiString);
procedure WriteBinary( const b: TBytes); overload;
procedure WriteBinary( const b: IThriftBytes); overload;
+ procedure WriteUuid( const uuid: TGuid);
function ReadMessageBegin: TThriftMessage;
procedure ReadMessageEnd();
@@ -242,6 +244,7 @@ type
function ReadDouble:Double;
function ReadBinary: TBytes; // IMPORTANT: this is NOT safe across module boundaries
function ReadBinaryCOM : IThriftBytes;
+ function ReadUuid: TGuid;
function ReadString: string;
function ReadAnsiString: AnsiString;
@@ -297,6 +300,7 @@ type
procedure WriteString( const s: string ); virtual;
procedure WriteAnsiString( const s: AnsiString); virtual;
procedure WriteBinary( const b: TBytes); overload; virtual; abstract;
+ procedure WriteUuid( const b: TGuid); virtual; abstract;
function ReadMessageBegin: TThriftMessage; virtual; abstract;
procedure ReadMessageEnd(); virtual; abstract;
@@ -317,6 +321,7 @@ type
function ReadI64: Int64; virtual; abstract;
function ReadDouble:Double; virtual; abstract;
function ReadBinary: TBytes; virtual; abstract;
+ function ReadUuid: TGuid; virtual; abstract;
function ReadString: string; virtual;
function ReadAnsiString: AnsiString; virtual;
@@ -415,6 +420,7 @@ type
procedure WriteI64( const i64: Int64); override;
procedure WriteDouble( const d: Double); override;
procedure WriteBinary( const b: TBytes); override;
+ procedure WriteUuid( const uuid: TGuid); override;
function ReadMessageBegin: TThriftMessage; override;
procedure ReadMessageEnd(); override;
@@ -435,6 +441,7 @@ type
function ReadI64: Int64; override;
function ReadDouble:Double; override;
function ReadBinary: TBytes; override;
+ function ReadUuid: TGuid; override;
end;
@@ -479,6 +486,7 @@ type
procedure WriteString( const s: string ); override;
procedure WriteAnsiString( const s: AnsiString); override;
procedure WriteBinary( const b: TBytes); override;
+ procedure WriteUuid( const uuid: TGuid); override;
function ReadMessageBegin: TThriftMessage; override;
procedure ReadMessageEnd(); override;
@@ -499,6 +507,7 @@ type
function ReadI64: Int64; override;
function ReadDouble:Double; override;
function ReadBinary: TBytes; override;
+ function ReadUuid: TGuid; override;
function ReadString: string; override;
function ReadAnsiString: AnsiString; override;
end;
@@ -800,6 +809,7 @@ begin
TType.I64 : prot.ReadI64();
TType.Double_ : prot.ReadDouble();
TType.String_ : prot.ReadBinary();// Don't try to decode the string, just skip it.
+ TType.Uuid : prot.ReadUuid();
// structured types
TType.Struct : begin
@@ -874,6 +884,14 @@ begin
Result := buf;
end;
+function TBinaryProtocolImpl.ReadUuid : TGuid;
+var network : TGuid; // in network order (Big Endian)
+begin
+ ASSERT( SizeOf(result) = 16);
+ FTrans.ReadAll( @network, SizeOf(network), 0, SizeOf(network));
+ result := network.SwapByteOrder;
+end;
+
function TBinaryProtocolImpl.ReadBool: Boolean;
begin
Result := (ReadByte = 1);
@@ -1042,6 +1060,14 @@ begin
if iLen > 0 then FTrans.Write(b, 0, iLen);
end;
+procedure TBinaryProtocolImpl.WriteUuid( const uuid: TGuid);
+var network : TGuid; // in network order (Big Endian)
+begin
+ ASSERT( SizeOf(uuid) = 16);
+ network := uuid.SwapByteOrder;
+ Transport.Write( @network, 0, SizeOf(network));
+end;
+
procedure TBinaryProtocolImpl.WriteBool(b: Boolean);
begin
if b then begin
@@ -1191,6 +1217,7 @@ begin
TType.Map: result := SizeOf(Int32); // element count
TType.Set_: result := SizeOf(Int32); // element count
TType.List: result := SizeOf(Int32); // element count
+ TType.Uuid: result := SizeOf(TGuid);
else
raise TTransportExceptionBadArgs.Create('Unhandled type code');
end;
@@ -1437,6 +1464,12 @@ begin
end;
+procedure TProtocolDecorator.WriteUuid( const uuid: TGuid);
+begin
+ FWrappedProtocol.WriteUuid( uuid);
+end;
+
+
function TProtocolDecorator.ReadMessageBegin: TThriftMessage;
begin
result := FWrappedProtocol.ReadMessageBegin;
@@ -1551,6 +1584,12 @@ begin
end;
+function TProtocolDecorator.ReadUuid: TGuid;
+begin
+ result := FWrappedProtocol.ReadUuid;
+end;
+
+
function TProtocolDecorator.ReadString: string;
begin
result := FWrappedProtocol.ReadString;
diff --git a/lib/delphi/src/Thrift.Utils.pas b/lib/delphi/src/Thrift.Utils.pas
index 4a75af8b7..122653572 100644
--- a/lib/delphi/src/Thrift.Utils.pas
+++ b/lib/delphi/src/Thrift.Utils.pas
@@ -84,11 +84,34 @@ type
class function IsHtmlDoctype( const fourBytes : Integer) : Boolean; static;
end;
+
+ IntegerUtils = class sealed
+ strict private
+ class procedure SwapBytes( var one, two : Byte); static; inline;
+ class procedure Swap2( const pValue : Pointer); static;
+ class procedure Swap4( const pValue : Pointer); static;
+ class procedure Swap8( const pValue : Pointer); static;
+ public
+ class procedure SwapByteOrder( const pValue : Pointer; const size : Integer); overload; static;
+ end;
+
+
+ TGuidHelper = record helper for System.TGuid
+ public
+ function SwapByteOrder : TGuid;
+
+ {$IFDEF Debug}
+ class procedure SelfTest; static;
+ {$ENDIF}
+ end;
+
+
EnumUtils<T> = class sealed
public
class function ToString(const value : Integer) : string; reintroduce; static; inline;
end;
+
StringUtils<T> = class sealed
public
class function ToString(const value : T) : string; reintroduce; static; inline;
@@ -283,6 +306,97 @@ begin
result := (UpCase(pc^) = HTML_BEGIN[3]);
end;
+{ IntegerUtils }
+
+
+class procedure IntegerUtils.SwapBytes( var one, two : Byte);
+var tmp : Byte;
+begin
+ tmp := one;
+ one := two;
+ two := tmp;
+end;
+
+
+class procedure IntegerUtils.Swap2( const pValue : Pointer);
+var pData : PByteArray absolute pValue;
+begin
+ SwapBytes( pData^[0], pData^[1]);
+end;
+
+
+class procedure IntegerUtils.Swap4( const pValue : Pointer);
+var pData : PByteArray absolute pValue;
+begin
+ SwapBytes( pData^[0], pData^[3]);
+ SwapBytes( pData^[1], pData^[2]);
+end;
+
+
+class procedure IntegerUtils.Swap8( const pValue : Pointer);
+var pData : PByteArray absolute pValue;
+begin
+ SwapBytes( pData^[0], pData^[7]);
+ SwapBytes( pData^[1], pData^[6]);
+ SwapBytes( pData^[2], pData^[5]);
+ SwapBytes( pData^[3], pData^[4]);
+end;
+
+
+class procedure IntegerUtils.SwapByteOrder( const pValue : Pointer; const size : Integer);
+begin
+ case size of
+ 2 : Swap2( pValue);
+ 4 : Swap4( pValue);
+ 8 : Swap8( pValue);
+ else
+ raise EArgumentException.Create('Unexpected size');
+ end;
+end;
+
+
+{ TGuidHelper }
+
+
+function TGuidHelper.SwapByteOrder : TGuid;
+// convert to/from network byte order
+// - https://www.ietf.org/rfc/rfc4122.txt
+// - https://stackoverflow.com/questions/10850075/guid-uuid-compatibility-issue-between-net-and-linux
+// - https://lists.gnu.org/archive/html/bug-parted/2002-01/msg00099.html
+begin
+ result := Self;
+
+ IntegerUtils.SwapByteOrder( @result.D1, SizeOf(result.D1));
+ IntegerUtils.SwapByteOrder( @result.D2, SizeOf(result.D2));
+ IntegerUtils.SwapByteOrder( @result.D3, SizeOf(result.D3));
+ //result.D4 = array of byte -> implicitly correct
+end;
+
+
+{$IFDEF Debug}
+class procedure TGuidHelper.SelfTest;
+var guid : TGuid;
+ pBytes : PByteArray;
+ i, expected : Integer;
+const TEST_GUID : TGuid = '{00112233-4455-6677-8899-aabbccddeeff}';
+begin
+ // host to network
+ guid := TEST_GUID;
+ guid := guid.SwapByteOrder;
+
+ // validate network order
+ pBytes := @guid;
+ for i := 0 to $F do begin
+ expected := i * $11;
+ ASSERT( pBytes^[i] = expected);
+ end;
+
+ // network to host and final validation
+ guid := guid.SwapByteOrder;
+ ASSERT( IsEqualGuid( guid, TEST_GUID));
+end;
+{$ENDIF}
+
{$IFDEF Win64}
@@ -378,4 +492,8 @@ begin
end;
+begin
+ {$IFDEF Debug}
+ TGuid.SelfTest;
+ {$ENDIF}
end.
diff --git a/lib/delphi/test/TestClient.pas b/lib/delphi/test/TestClient.pas
index 040f815ce..86235ebaf 100644
--- a/lib/delphi/test/TestClient.pas
+++ b/lib/delphi/test/TestClient.pas
@@ -34,7 +34,7 @@ unit TestClient;
interface
uses
- Windows, SysUtils, Classes, Math, ComObj, ActiveX,
+ Classes, Windows, SysUtils, Math, ActiveX, ComObj,
{$IFDEF SupportsAsync} System.Threading, {$ENDIF}
DateUtils,
Generics.Collections,
@@ -393,6 +393,7 @@ var
i32 : Integer;
i64 : Int64;
binOut,binIn : TBytes;
+ guidIn, guidOut : TGuid;
dub : Double;
o : IXtruct;
o2 : IXtruct2;
@@ -543,6 +544,16 @@ begin
i64 := client.testI64(-34359738368);
Expect( i64 = -34359738368, 'testI64(-34359738368) = ' + IntToStr( i64));
+ guidOut := StringToGUID('{00112233-4455-6677-8899-AABBCCDDEEFF}');
+ Console.WriteLine('testUuid('+GUIDToString(guidOut)+')');
+ try
+ guidIn := client.testUuid(guidOut);
+ Expect( IsEqualGUID(guidIn, guidOut), 'testUuid('+GUIDToString(guidOut)+') = '+GUIDToString(guidIn));
+ except
+ on e:TApplicationException do Console.WriteLine('testUuid(): '+e.Message);
+ on e:Exception do Expect( FALSE, 'testUuid(): Unexpected exception "'+e.ClassName+'": '+e.Message);
+ end;
+
// random binary small
for testsize := Low(TTestSize) to High(TTestSize) do begin
binOut := PrepareBinaryData( TRUE, testsize);
diff --git a/lib/delphi/test/TestServer.pas b/lib/delphi/test/TestServer.pas
index d7cc02694..3ae82a1fc 100644
--- a/lib/delphi/test/TestServer.pas
+++ b/lib/delphi/test/TestServer.pas
@@ -67,6 +67,7 @@ type
function testI64(const thing: Int64): Int64;
function testDouble(const thing: Double): Double;
function testBinary(const thing: TBytes): TBytes;
+ function testUuid(const thing: System.TGuid): System.TGuid;
function testStruct(const thing: IXtruct): IXtruct;
function testNest(const thing: IXtruct2): IXtruct2;
function testMap(const thing: IThriftDictionary<Integer, Integer>): IThriftDictionary<Integer, Integer>;
@@ -150,6 +151,12 @@ begin
Result := thing;
end;
+function TTestServer.TTestHandlerImpl.testUuid(const thing: System.TGuid): System.TGuid;
+begin
+ Console.WriteLine('testUuid('+GUIDToString(thing)+')');
+ Result := thing;
+end;
+
function TTestServer.TTestHandlerImpl.testEnum(thing: TNumberz): TNumberz;
begin
Console.WriteLine('testEnum(' + EnumUtils<TNumberz>.ToString(Ord(thing)) + ')');
diff --git a/lib/delphi/test/client.dproj b/lib/delphi/test/client.dproj
index c57424db1..ae6683d99 100644
--- a/lib/delphi/test/client.dproj
+++ b/lib/delphi/test/client.dproj
@@ -1,22 +1,4 @@
-<!--
- 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.
--->
- <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{F262F488-F81C-4B6E-8694-518C54CBB8F3}</ProjectGuid>
<MainSource>client.dpr</MainSource>
@@ -142,7 +124,9 @@
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"/>
</VersionInfoKeys>
- <Parameters/>
+ <Parameters>
+ <Parameters Name="RunParams">--protocol=compact </Parameters>
+ </Parameters>
</Delphi.Personality>
<Platforms>
<Platform value="Win32">True</Platform>
diff --git a/lib/delphi/test/serializer/TestSerializer.Data.pas b/lib/delphi/test/serializer/TestSerializer.Data.pas
index 4b8cc6696..269e307a6 100644
--- a/lib/delphi/test/serializer/TestSerializer.Data.pas
+++ b/lib/delphi/test/serializer/TestSerializer.Data.pas
@@ -23,6 +23,8 @@ interface
uses
SysUtils,
+ ActiveX,
+ ComObj,
Thrift.Protocol,
Thrift.Collections,
DebugProtoTest;
@@ -193,6 +195,8 @@ begin
// !!
result.setZomg_unicode( UnicodeString( us));
+ result.Rfc4122_uuid := TGuid.Create('{00112233-4455-6677-8899-aabbccddeeff}');
+
{$IF cDebugProtoTest_Option_AnsiStr_Binary}
result.SetBase64('base64');
{$ELSEIF cDebugProtoTest_Option_COM_Types}
diff --git a/lib/delphi/test/serializer/TestSerializer.Tests.pas b/lib/delphi/test/serializer/TestSerializer.Tests.pas
index 443a22d5f..6ed1a48a2 100644
--- a/lib/delphi/test/serializer/TestSerializer.Tests.pas
+++ b/lib/delphi/test/serializer/TestSerializer.Tests.pas
@@ -43,6 +43,7 @@ uses
System_,
DebugProtoTest;
+{$TYPEINFO ON}
type
TFactoryPair = record
@@ -208,6 +209,7 @@ begin
ASSERT( Abs( tested.Double_precision - correct.Double_precision) < 1E-12);
ASSERT( tested.Some_characters = correct.Some_characters);
ASSERT( tested.Zomg_unicode = correct.Zomg_unicode);
+ ASSERT( tested.Rfc4122_uuid = correct.Rfc4122_uuid);
ASSERT( tested.What_who = correct.What_who);
ASSERT( LengthOf(tested.Base64) = LengthOf(correct.Base64));
@@ -303,9 +305,9 @@ end;
class function TTestSerializer.UserFriendlyName( const method : TMethod) : string;
+const NAMES : array[TMethod] of string = ('TBytes','Stream');
begin
- result := EnumUtils<TMethod>.ToString(Ord(method));
- result := StringReplace( result, 'mt_', '', [rfReplaceAll]);
+ result := NAMES[method];
end;
@@ -342,7 +344,7 @@ var serial : TSerializer;
config : IThriftConfiguration;
begin
config := TThriftConfigurationImpl.Create;
- config.MaxMessageSize := 0; // we don't read anything here
+ //config.MaxMessageSize := 0; // we don't read anything here
serial := TSerializer.Create( factory.prot, factory.trans, config);
try
@@ -358,7 +360,7 @@ var serial : TSerializer;
config : IThriftConfiguration;
begin
config := TThriftConfigurationImpl.Create;
- config.MaxMessageSize := 0; // we don't read anything here
+ //config.MaxMessageSize := 0; // we don't read anything here
serial := TSerializer.Create( factory.prot, factory.trans, config);
try
diff --git a/lib/delphi/test/server.dproj b/lib/delphi/test/server.dproj
index 9f7e5c647..151f7ee72 100644
--- a/lib/delphi/test/server.dproj
+++ b/lib/delphi/test/server.dproj
@@ -1,22 +1,4 @@
-<!--
- 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.
--->
- <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{07CEDA3D-0963-40FE-B3C2-0ED4E24DE067}</ProjectGuid>
<MainSource>server.dpr</MainSource>
@@ -140,6 +122,9 @@
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"/>
</VersionInfoKeys>
+ <Parameters>
+ <Parameters Name="RunParams">--protocol=compact </Parameters>
+ </Parameters>
</Delphi.Personality>
<Platforms>
<Platform value="Win32">True</Platform>
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 4a38205dc..bf5a379b1 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 @@ struct RaceDetails
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 @@ union jack {
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 afffed5f6..11b5af4ee 100644
--- a/lib/netstd/Tests/Thrift.Tests/DataModel/DeepCopy.cs
+++ b/lib/netstd/Tests/Thrift.Tests/DataModel/DeepCopy.cs
@@ -81,16 +81,18 @@ namespace Thrift.Tests.DataModel
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 @@ namespace Thrift.Tests.DataModel
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 @@ namespace Thrift.Tests.DataModel
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 @@ namespace Thrift.Tests.DataModel
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 @@ namespace Thrift.Tests.DataModel
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 @@ namespace Thrift.Tests.DataModel
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 @@ namespace Thrift.Tests.DataModel
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 @@ namespace Thrift.Tests.DataModel
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 @@ namespace Thrift.Tests.DataModel
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 @@ namespace Thrift.Tests.DataModel
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 @@ namespace Thrift.Tests.DataModel
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 @@ namespace Thrift.Tests.DataModel
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 @@ namespace Thrift.Tests.DataModel
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 @@ namespace Thrift.Tests.DataModel
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 @@ namespace Thrift.Tests.DataModel
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 @@ namespace Thrift.Tests.DataModel
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 @@ namespace Thrift.Tests.DataModel
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 @@ namespace Thrift.Tests.DataModel
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 @@ namespace Thrift.Tests.DataModel
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 @@ namespace Thrift.Tests.DataModel
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 @@ namespace Thrift.Tests.DataModel
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 @@ namespace Thrift.Tests.DataModel
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 @@ namespace Thrift.Tests.DataModel
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 @@ namespace Thrift.Tests.DataModel
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 ebc171747..80eacc258 100644
--- a/lib/netstd/Tests/Thrift.Tests/DataModel/NullValuesSet.cs
+++ b/lib/netstd/Tests/Thrift.Tests/DataModel/NullValuesSet.cs
@@ -48,19 +48,19 @@ namespace Thrift.Tests.DataModel
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 @@ namespace Thrift.Tests.DataModel
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 4e922a7e7..2f3037b86 100644
--- a/lib/netstd/Thrift/Protocol/Entities/TType.cs
+++ b/lib/netstd/Thrift/Protocol/Entities/TType.cs
@@ -32,6 +32,7 @@ namespace Thrift.Protocol.Entities
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 eee137ca1..ba2a7abbc 100644
--- a/lib/netstd/Thrift/Protocol/TBinaryProtocol.cs
+++ b/lib/netstd/Thrift/Protocol/TBinaryProtocol.cs
@@ -21,6 +21,7 @@ using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Thrift.Protocol.Entities;
+using Thrift.Protocol.Utilities;
using Thrift.Transport;
@@ -209,6 +210,14 @@ namespace Thrift.Protocol
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 @@ namespace Thrift.Protocol
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 @@ namespace Thrift.Protocol
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 6893ad476..b899d3dbc 100644
--- a/lib/netstd/Thrift/Protocol/TCompactProtocol.cs
+++ b/lib/netstd/Thrift/Protocol/TCompactProtocol.cs
@@ -24,6 +24,7 @@ using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Thrift.Protocol.Entities;
+using Thrift.Protocol.Utilities;
using Thrift.Transport;
@@ -43,8 +44,8 @@ namespace Thrift.Protocol
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 @@ namespace Thrift.Protocol
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 @@ namespace Thrift.Protocol
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 @@ namespace Thrift.Protocol
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 @@ namespace Thrift.Protocol
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 @@ namespace Thrift.Protocol
{
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 @@ namespace Thrift.Protocol
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 8799026ba..c100d8627 100644
--- a/lib/netstd/Thrift/Protocol/TJSONProtocol.cs
+++ b/lib/netstd/Thrift/Protocol/TJSONProtocol.cs
@@ -401,6 +401,10 @@ namespace Thrift.Protocol
{
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 @@ namespace Thrift.Protocol
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 @@ namespace Thrift.Protocol
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 cd9383389..f2bec6000 100644
--- a/lib/netstd/Thrift/Protocol/TProtocol.cs
+++ b/lib/netstd/Thrift/Protocol/TProtocol.cs
@@ -148,6 +148,7 @@ namespace Thrift.Protocol
}
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 @@ namespace Thrift.Protocol
}
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 b032e836a..1ea9fb9ae 100644
--- a/lib/netstd/Thrift/Protocol/TProtocolDecorator.cs
+++ b/lib/netstd/Thrift/Protocol/TProtocolDecorator.cs
@@ -144,6 +144,11 @@ namespace Thrift.Protocol
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 @@ namespace Thrift.Protocol
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 000000000..190ddbbc5
--- /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 6cc1302e9..f8c261aa8 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 @@ namespace Thrift.Protocol.Utilities
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 ff49ebe24..67c7bc065 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 @@ namespace Thrift.Protocol.Utilities
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 @@ namespace Thrift.Protocol.Utilities
case (byte) 't':
result = TType.Bool;
break;
+ case (byte)'u':
+ result = TType.Uuid;
+ break;
}
}
if (result == TType.Stop)
@@ -173,4 +178,4 @@ namespace Thrift.Protocol.Utilities
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 832e46e6c..3c8b37ae3 100644
--- a/lib/netstd/Thrift/Protocol/Utilities/TProtocolUtil.cs
+++ b/lib/netstd/Thrift/Protocol/Utilities/TProtocolUtil.cs
@@ -55,6 +55,9 @@ namespace Thrift.Protocol.Utilities
// 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)
diff --git a/test/ConstantsDemo.thrift b/test/ConstantsDemo.thrift
index 204e805b1..e03f0537d 100644
--- a/test/ConstantsDemo.thrift
+++ b/test/ConstantsDemo.thrift
@@ -65,6 +65,8 @@ const map<i32,thing> GEN_WHAT = { 35 : { 'hello' : 325, 'goodbye' : 325352 } }
const set<i32> GEN_SET = [ 235, 235, 53235 ]
+const uuid GEN_UUID = "00000000-4444-CCCC-ffff-0123456789ab"
+
exception Blah {
1: i32 bing }
diff --git a/test/DebugProtoTest.thrift b/test/DebugProtoTest.thrift
index 5d0face4b..3750d8d93 100644
--- a/test/DebugProtoTest.thrift
+++ b/test/DebugProtoTest.thrift
@@ -48,6 +48,7 @@ struct OneOfEach {
12: list<i8> byte_list = [1, 2, 3],
13: list<i16> i16_list = [1,2,3],
14: list<i64> i64_list = [1,2,3]
+ 15: uuid rfc4122_uuid
}
struct Bonk {
diff --git a/test/ThriftTest.thrift b/test/ThriftTest.thrift
index 4a1045fcd..42607cc35 100644
--- a/test/ThriftTest.thrift
+++ b/test/ThriftTest.thrift
@@ -112,6 +112,7 @@ struct CrazyNesting {
// Do not insert line break as test/go/Makefile.am is removing this line with pattern match
3: required list<map<set<i32> (python.immutable = ""), map<i32,set<list<map<Insanity,string>(python.immutable = "")> (python.immutable = "")>>>> list_field,
4: binary binary_field
+ 5: uuid uuid_field
}
union SomeUnion {
@@ -196,6 +197,13 @@ service ThriftTest
binary testBinary(1: binary thing),
/**
+ * Prints 'testUuid("%s")' where '%s' is the uuid given. Note that the uuid byte order should be correct.
+ * @param uuid thing - the uuid to print
+ * @return uuid - returns the uuid 'thing'
+ */
+ uuid testUuid(1: uuid thing),
+
+ /**
* Prints 'testStruct("{%s}")' where thing has been formatted into a string of comma separated values
* @param Xtruct thing - the Xtruct to print
* @return Xtruct - returns the Xtruct 'thing'
diff --git a/test/netstd/Client/TestClient.cs b/test/netstd/Client/TestClient.cs
index 29c0d2ef3..4700de88b 100644
--- a/test/netstd/Client/TestClient.cs
+++ b/test/netstd/Client/TestClient.cs
@@ -588,8 +588,28 @@ namespace ThriftTest
returnCode |= ErrorBaseTypes;
}
+ // testUuid()
+ var uuidOut = new Guid("{00112233-4455-6677-8899-AABBCCDDEEFF}");
+ Console.Write("testUuid({0})", uuidOut);
+ try
+ {
+ var uuidIn = await client.testUuid(uuidOut, MakeTimeoutToken());
+ Console.WriteLine(" = {0}", uuidIn);
+ if (!uuidIn.Equals(uuidOut))
+ {
+ Console.WriteLine("*** FAILED ***");
+ returnCode |= ErrorBaseTypes;
+ }
+ }
+ catch (Thrift.TApplicationException ex)
+ {
+ Console.WriteLine("*** FAILED ***");
+ returnCode |= ErrorBaseTypes;
+ Console.WriteLine(ex.Message + "\n" + ex.StackTrace);
+ }
+
// testBinary()
- foreach(BinaryTestSize binTestCase in Enum.GetValues(typeof(BinaryTestSize)))
+ foreach (BinaryTestSize binTestCase in Enum.GetValues(typeof(BinaryTestSize)))
{
var binOut = PrepareTestData(true, binTestCase);
diff --git a/test/netstd/Server/Server.csproj b/test/netstd/Server/Server.csproj
index 8faad9dc9..0a78e8836 100644
--- a/test/netstd/Server/Server.csproj
+++ b/test/netstd/Server/Server.csproj
@@ -1,4 +1,4 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
<!--
Licensed to the Apache Software Foundation(ASF) under one
or more contributor license agreements.See the NOTICE file
diff --git a/test/netstd/Server/TestServer.cs b/test/netstd/Server/TestServer.cs
index 86072b0a7..71a2a30a1 100644
--- a/test/netstd/Server/TestServer.cs
+++ b/test/netstd/Server/TestServer.cs
@@ -271,6 +271,12 @@ namespace ThriftTest
return Task.FromResult(thing ?? Array.Empty<byte>());
}
+ public Task<Guid> testUuid(Guid thing, CancellationToken cancellationToken)
+ {
+ logger.Invoke("testUuid({0})", thing.ToString("B"));
+ return Task.FromResult(thing);
+ }
+
public Task<Xtruct> testStruct(Xtruct? thing, CancellationToken cancellationToken)
{
logger.Invoke("testStruct({{\"{0}\", {1}, {2}, {3}}})", thing?.String_thing ?? "<null>", thing?.Byte_thing ?? 0, thing?.I32_thing ?? 0, thing?.I64_thing ?? 0);