[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