aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChris Smith <cjs@google.com>2013-07-22 09:00:43 +0100
committerChris Smith <cjs@google.com>2013-07-23 19:13:36 +0100
commit0f2ca89132ab81441f7eb351c7a053a8c8d9d1c3 (patch)
treed30df349a57d0279cb3ff8b8b34459f3ebf22669 /src
parenta400007ed570bbcc638c05c59727b3527238ec70 (diff)
downloadexternal_protobuf-0f2ca89132ab81441f7eb351c7a053a8c8d9d1c3.zip
external_protobuf-0f2ca89132ab81441f7eb351c7a053a8c8d9d1c3.tar.gz
external_protobuf-0f2ca89132ab81441f7eb351c7a053a8c8d9d1c3.tar.bz2
Allow NaN/+inf/-inf defaults in micro/nano.
Adds support for default values of NaN, infinity and negative infinity for floats and doubles in both the nano and micro java compiler. Change-Id: Ibc43e5ebb073e51d9a8181f3aa23b72e10015dca
Diffstat (limited to 'src')
-rw-r--r--src/google/protobuf/compiler/javamicro/javamicro_helpers.cc29
-rw-r--r--src/google/protobuf/compiler/javanano/javanano_helpers.cc29
-rw-r--r--src/google/protobuf/compiler/javanano/javanano_primitive_field.cc39
-rw-r--r--src/google/protobuf/unittest_micro.proto7
-rw-r--r--src/google/protobuf/unittest_nano.proto7
5 files changed, 103 insertions, 8 deletions
diff --git a/src/google/protobuf/compiler/javamicro/javamicro_helpers.cc b/src/google/protobuf/compiler/javamicro/javamicro_helpers.cc
index c23080e..e406a0e 100644
--- a/src/google/protobuf/compiler/javamicro/javamicro_helpers.cc
+++ b/src/google/protobuf/compiler/javamicro/javamicro_helpers.cc
@@ -32,6 +32,7 @@
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
+#include <limits>
#include <vector>
#include <google/protobuf/compiler/javamicro/javamicro_helpers.h>
@@ -344,10 +345,30 @@ string DefaultValue(const Params& params, const FieldDescriptor* field) {
case FieldDescriptor::CPPTYPE_UINT64:
return SimpleItoa(static_cast<int64>(field->default_value_uint64())) +
"L";
- case FieldDescriptor::CPPTYPE_DOUBLE:
- return SimpleDtoa(field->default_value_double()) + "D";
- case FieldDescriptor::CPPTYPE_FLOAT:
- return SimpleFtoa(field->default_value_float()) + "F";
+ case FieldDescriptor::CPPTYPE_DOUBLE: {
+ double value = field->default_value_double();
+ if (value == numeric_limits<double>::infinity()) {
+ return "Double.POSITIVE_INFINITY";
+ } else if (value == -numeric_limits<double>::infinity()) {
+ return "Double.NEGATIVE_INFINITY";
+ } else if (value != value) {
+ return "Double.NaN";
+ } else {
+ return SimpleDtoa(value) + "D";
+ }
+ }
+ case FieldDescriptor::CPPTYPE_FLOAT: {
+ float value = field->default_value_float();
+ if (value == numeric_limits<float>::infinity()) {
+ return "Float.POSITIVE_INFINITY";
+ } else if (value == -numeric_limits<float>::infinity()) {
+ return "Float.NEGATIVE_INFINITY";
+ } else if (value != value) {
+ return "Float.NaN";
+ } else {
+ return SimpleFtoa(value) + "F";
+ }
+ }
case FieldDescriptor::CPPTYPE_BOOL:
return field->default_value_bool() ? "true" : "false";
case FieldDescriptor::CPPTYPE_STRING:
diff --git a/src/google/protobuf/compiler/javanano/javanano_helpers.cc b/src/google/protobuf/compiler/javanano/javanano_helpers.cc
index 80ee7a0..2564a58 100644
--- a/src/google/protobuf/compiler/javanano/javanano_helpers.cc
+++ b/src/google/protobuf/compiler/javanano/javanano_helpers.cc
@@ -32,6 +32,7 @@
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
+#include <limits>
#include <vector>
#include <google/protobuf/compiler/javanano/javanano_helpers.h>
@@ -422,10 +423,30 @@ string DefaultValue(const Params& params, const FieldDescriptor* field) {
case FieldDescriptor::CPPTYPE_UINT64:
return SimpleItoa(static_cast<int64>(field->default_value_uint64())) +
"L";
- case FieldDescriptor::CPPTYPE_DOUBLE:
- return SimpleDtoa(field->default_value_double()) + "D";
- case FieldDescriptor::CPPTYPE_FLOAT:
- return SimpleFtoa(field->default_value_float()) + "F";
+ case FieldDescriptor::CPPTYPE_DOUBLE: {
+ double value = field->default_value_double();
+ if (value == numeric_limits<double>::infinity()) {
+ return "Double.POSITIVE_INFINITY";
+ } else if (value == -numeric_limits<double>::infinity()) {
+ return "Double.NEGATIVE_INFINITY";
+ } else if (value != value) {
+ return "Double.NaN";
+ } else {
+ return SimpleDtoa(value) + "D";
+ }
+ }
+ case FieldDescriptor::CPPTYPE_FLOAT: {
+ float value = field->default_value_float();
+ if (value == numeric_limits<float>::infinity()) {
+ return "Float.POSITIVE_INFINITY";
+ } else if (value == -numeric_limits<float>::infinity()) {
+ return "Float.NEGATIVE_INFINITY";
+ } else if (value != value) {
+ return "Float.NaN";
+ } else {
+ return SimpleFtoa(value) + "F";
+ }
+ }
case FieldDescriptor::CPPTYPE_BOOL:
return field->default_value_bool() ? "true" : "false";
case FieldDescriptor::CPPTYPE_STRING:
diff --git a/src/google/protobuf/compiler/javanano/javanano_primitive_field.cc b/src/google/protobuf/compiler/javanano/javanano_primitive_field.cc
index a8afe94..987a103 100644
--- a/src/google/protobuf/compiler/javanano/javanano_primitive_field.cc
+++ b/src/google/protobuf/compiler/javanano/javanano_primitive_field.cc
@@ -33,6 +33,7 @@
// Sanjay Ghemawat, Jeff Dean, and others.
#include <map>
+#include <math.h>
#include <string>
#include <google/protobuf/compiler/javanano/javanano_primitive_field.h>
@@ -174,6 +175,38 @@ int FixedSize(FieldDescriptor::Type type) {
return -1;
}
+// Returns true if the field has a default value equal to NaN.
+bool IsDefaultNaN(const FieldDescriptor* field) {
+ switch (field->type()) {
+ case FieldDescriptor::TYPE_INT32 : return false;
+ case FieldDescriptor::TYPE_UINT32 : return false;
+ case FieldDescriptor::TYPE_SINT32 : return false;
+ case FieldDescriptor::TYPE_FIXED32 : return false;
+ case FieldDescriptor::TYPE_SFIXED32: return false;
+ case FieldDescriptor::TYPE_INT64 : return false;
+ case FieldDescriptor::TYPE_UINT64 : return false;
+ case FieldDescriptor::TYPE_SINT64 : return false;
+ case FieldDescriptor::TYPE_FIXED64 : return false;
+ case FieldDescriptor::TYPE_SFIXED64: return false;
+ case FieldDescriptor::TYPE_FLOAT :
+ return isnan(field->default_value_float());
+ case FieldDescriptor::TYPE_DOUBLE :
+ return isnan(field->default_value_double());
+ case FieldDescriptor::TYPE_BOOL : return false;
+ case FieldDescriptor::TYPE_STRING : return false;
+ case FieldDescriptor::TYPE_BYTES : return false;
+ case FieldDescriptor::TYPE_ENUM : return false;
+ case FieldDescriptor::TYPE_GROUP : return false;
+ case FieldDescriptor::TYPE_MESSAGE : return false;
+
+ // No default because we want the compiler to complain if any new
+ // types are added.
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return false;
+}
+
// Return true if the type is a that has variable length
// for instance String's.
bool IsVariableLenType(JavaType type) {
@@ -308,6 +341,9 @@ GenerateSerializationCode(io::Printer* printer) const {
} else if (IsReferenceType(GetJavaType(descriptor_))) {
printer->Print(variables_,
"if (!this.$name$.equals($default$)) {\n");
+ } else if (IsDefaultNaN(descriptor_)) {
+ printer->Print(variables_,
+ "if (!$capitalized_type$.isNaN(this.$name$)) {\n");
} else {
printer->Print(variables_,
"if (this.$name$ != $default$) {\n");
@@ -332,6 +368,9 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
} else if (IsReferenceType(GetJavaType(descriptor_))) {
printer->Print(variables_,
"if (!this.$name$.equals($default$)) {\n");
+ } else if (IsDefaultNaN(descriptor_)) {
+ printer->Print(variables_,
+ "if (!$capitalized_type$.isNaN(this.$name$)) {\n");
} else {
printer->Print(variables_,
"if (this.$name$ != $default$) {\n");
diff --git a/src/google/protobuf/unittest_micro.proto b/src/google/protobuf/unittest_micro.proto
index 3d7fcd2..e6b4618 100644
--- a/src/google/protobuf/unittest_micro.proto
+++ b/src/google/protobuf/unittest_micro.proto
@@ -133,6 +133,13 @@ message TestAllTypesMicro {
optional string default_string = 74 [default = "hello"];
optional bytes default_bytes = 75 [default = "world"];
+ optional float default_float_inf = 96 [default = inf];
+ optional float default_float_neg_inf = 97 [default = -inf];
+ optional float default_float_nan = 98 [default = nan];
+ optional double default_double_inf = 99 [default = inf];
+ optional double default_double_neg_inf = 100 [default = -inf];
+ optional double default_double_nan = 101 [default = nan];
+
optional NestedEnum default_nested_enum = 81 [default = BAR];
optional ForeignEnumMicro default_foreign_enum = 82
[default = FOREIGN_MICRO_BAR];
diff --git a/src/google/protobuf/unittest_nano.proto b/src/google/protobuf/unittest_nano.proto
index e9a0d83..1a6ba26 100644
--- a/src/google/protobuf/unittest_nano.proto
+++ b/src/google/protobuf/unittest_nano.proto
@@ -142,6 +142,13 @@ message TestAllTypesNano {
optional string default_string_nonascii = 76 [default = "dünya"];
optional bytes default_bytes_nonascii = 77 [default = "dünyab"];
+ optional float default_float_inf = 97 [default = inf];
+ optional float default_float_neg_inf = 98 [default = -inf];
+ optional float default_float_nan = 99 [default = nan];
+ optional double default_double_inf = 100 [default = inf];
+ optional double default_double_neg_inf = 101 [default = -inf];
+ optional double default_double_nan = 102 [default = nan];
+
optional NestedEnum default_nested_enum = 81 [default = BAR];
optional ForeignEnumNano default_foreign_enum = 82
[default = FOREIGN_NANO_BAR];