[Rprotobuf-commits] r595 - in pkg: . src

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Fri Dec 27 02:11:16 CET 2013


Author: murray
Date: 2013-12-27 02:11:16 +0100 (Fri, 27 Dec 2013)
New Revision: 595

Modified:
   pkg/ChangeLog
   pkg/src/mutators.cpp
Log:
Support setting optional and repested int32s from valid decimal
character strings just like we do (by necessity) for int64s.  Give a
stop() error if the string isn't a valid number, as opposed to the
current behavior of crashing R with uncaught exception even when a
valid number is provided.



Modified: pkg/ChangeLog
===================================================================
--- pkg/ChangeLog	2013-12-26 23:42:33 UTC (rev 594)
+++ pkg/ChangeLog	2013-12-27 01:11:16 UTC (rev 595)
@@ -1,5 +1,7 @@
 2013-12-26  Murray Stokely  <murray at FreeBSD.org>
 
+	* src/mutators.cpp: Support setting int32 values with character
+	  vectors of a decimal number, as we do by necessity for int64s.
 	* NAMESPACE: Add missing export for .DollarNames
 	  EnumValueDescriptor to allow completion on that class.
 	* R/00classes.R: Update FileDescriptor '$' dispatch to work

Modified: pkg/src/mutators.cpp
===================================================================
--- pkg/src/mutators.cpp	2013-12-26 23:42:33 UTC (rev 594)
+++ pkg/src/mutators.cpp	2013-12-27 01:11:16 UTC (rev 595)
@@ -83,7 +83,30 @@
 	return 0 ; // -Wall, should not happen since we only call this when we know it works
 }
 
+template<typename ValueType>
+ValueType Int64FromString(const string &value) {
+    std::stringstream ss(value);
+    ValueType ret;
+    if ((ss >> ret).fail() || !(ss>>std::ws).eof()) {
+        string message = "Provided character value '" + value +
+                "' cannot be cast to 64-bit integer.";
+        throwException(message.c_str(), "CastException");
+    }
+    return ret;
+}
 
+template<typename ValueType>
+ValueType Int32FromString(const string &value) {
+    std::stringstream ss(value);
+    ValueType ret;
+    if ((ss >> ret).fail() || !(ss>>std::ws).eof()) {
+        string message = "Provided character value '" + value +
+                "' cannot be cast to 32-bit integer.";
+        throwException(message.c_str(), "CastException");
+    }
+    return ret;
+}
+
 int32 GET_int32( SEXP x, int index ){
 	switch( TYPEOF(x) ){
 		case INTSXP: 
@@ -94,24 +117,14 @@
 			return( (int32)LOGICAL(x)[index] );
 		case RAWSXP:
 			return( (int32)RAW(x)[index] ) ;
+		case STRSXP:
+			return Int32FromString<int32>(CHAR(STRING_ELT(x, index)));
 		default:
 			throwException( "cannot cast SEXP to int32", "CastException" ) ; 
 	}
 	return (int32)0 ; // -Wall, should not happen since we only call this when we know it works
 }
 
-template<typename ValueType>
-ValueType Int64FromString(const string &value) {
-    std::stringstream ss(value);
-    ValueType ret;
-    if ((ss >> ret).fail() || !(ss>>std::ws).eof()) {
-        string message = "Provided character value '" + value +
-                "' cannot be cast to 64-bit integer.";
-        throwException(message.c_str(), "CastException");
-    }
-    return ret;
-}
-
 int64 GET_int64( SEXP x, int index ){
 	switch( TYPEOF(x) ){
 		case INTSXP: 
@@ -140,6 +153,8 @@
 			return( (uint32)LOGICAL(x)[index] );
 		case RAWSXP:
 			return( (uint32)RAW(x)[index] ) ;
+		case STRSXP:
+            return Int32FromString<uint32>(CHAR(STRING_ELT(x, index)));
 		default:
 			throwException( "cannot cast SEXP to uint32", "CastException" ) ; 
 	}
@@ -583,6 +598,7 @@
     					case REALSXP:
     					case LGLSXP:
     					case RAWSXP:	
+						case STRSXP: // For int32, we support chars.
     						{
     							int i = 0;
    								/* in any case, fill the values up to field_size */
@@ -599,6 +615,7 @@
     							
     							break ;
     						}
+
     					default: 
     						{
     							throwException( "Cannot convert to int32", "ConversionException" ) ; 
@@ -652,6 +669,7 @@
     					case REALSXP:
     					case LGLSXP:
     					case RAWSXP:	
+						case STRSXP: // For int32, we support chars.
     						{
     							int i = 0;
 	    						/* in any case, fill the values up to field_size */
@@ -667,6 +685,7 @@
 	    						}
     							break ;
     						}
+
     					default: 
     						throwException( "Cannot convert to uint32", "ConversionException" ) ; 
     				}
@@ -1025,11 +1044,36 @@
 					break ;												\
 				}
 
-			HANDLE_SINGLE_FIELD( CPPTYPE_INT32, Int32, GPB::int32) ;
-			HANDLE_SINGLE_FIELD( CPPTYPE_UINT32, UInt32, GPB::uint32) ;
 			HANDLE_SINGLE_FIELD( CPPTYPE_DOUBLE, Double, double) ;
 			HANDLE_SINGLE_FIELD( CPPTYPE_FLOAT, Float, float) ;
 			HANDLE_SINGLE_FIELD( CPPTYPE_BOOL, Bool, bool) ;
+			case CPPTYPE_INT32 :
+				{
+					if (TYPEOF(value) == STRSXP) {
+						const string int32str = COPYSTRING(CHAR(
+							STRING_ELT(value, 0)));
+						ref->SetInt32(message, field_desc,
+									  Int32FromString<GPB::int32>(int32str));
+						break ;
+					} else {
+						ref->SetInt32( message, field_desc, Rcpp::as<GPB::int32>(value));
+						break;
+					}
+				}
+			case CPPTYPE_UINT32 :
+				{
+					if (TYPEOF(value) == STRSXP) {
+						const string uint32str = COPYSTRING(CHAR(
+							STRING_ELT(value, 0)));
+						ref->SetUInt32(message, field_desc,
+									   Int32FromString<GPB::uint32>(uint32str));
+						break ;
+					} else {
+						ref->SetUInt32( message, field_desc, Rcpp::as<GPB::uint32>(value));
+						break;
+					}
+				}
+
 #ifdef RCPP_HAS_LONG_LONG_TYPES
 			case CPPTYPE_INT64 :
 				{



More information about the Rprotobuf-commits mailing list