[Rprotobuf-commits] r393 - /

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Tue Oct 12 22:45:33 CEST 2010


Author: edd
Date: 2010-10-12 22:45:33 +0200 (Tue, 12 Oct 2010)
New Revision: 393

Added:
   patch_by_Kort_rprotobuf_r392.diff
Log:
checking in raw diff file for patch by Koert adding raw support

Added: patch_by_Kort_rprotobuf_r392.diff
===================================================================
--- patch_by_Kort_rprotobuf_r392.diff	                        (rev 0)
+++ patch_by_Kort_rprotobuf_r392.diff	2010-10-12 20:45:33 UTC (rev 393)
@@ -0,0 +1,347 @@
+Index: pkg/src/extractors.cpp
+===================================================================
+--- pkg/src/extractors.cpp	(revision 392)
++++ pkg/src/extractors.cpp	(working copy)
+@@ -51,7 +51,7 @@
+ 	case TYPE : \
+ 		return Rcpp::wrap( RepeatedFieldImporter<DATATYPE>(ref, *message, fieldDesc) ) ; \
+ 
+-		HANDLE_REPEATED_FIELD(CPPTYPE_INT32, GPB::int32) ;
++			HANDLE_REPEATED_FIELD(CPPTYPE_INT32, GPB::int32) ;
+     		HANDLE_REPEATED_FIELD(CPPTYPE_INT64, GPB::int64) ;
+     		HANDLE_REPEATED_FIELD(CPPTYPE_UINT32 , GPB::uint32) ;
+     		HANDLE_REPEATED_FIELD(CPPTYPE_UINT64 , GPB::uint64) ;
+@@ -59,10 +59,24 @@
+     		HANDLE_REPEATED_FIELD(CPPTYPE_FLOAT, float) ;
+     		HANDLE_REPEATED_FIELD(CPPTYPE_BOOL, bool) ;
+     		HANDLE_REPEATED_FIELD(CPPTYPE_ENUM, enum_field ) ;
+-    		HANDLE_REPEATED_FIELD(CPPTYPE_STRING, std::string ) ;
+     		HANDLE_REPEATED_FIELD(CPPTYPE_MESSAGE, message_field ) ;
+ #undef HANDLE_REPEATED_FIELD
+ 
++		case CPPTYPE_STRING:
++			if (fieldDesc->type() == TYPE_STRING) {
++				return Rcpp::wrap( RepeatedFieldImporter<std::string>(ref, *message, fieldDesc) ) ;
++			} else if (fieldDesc->type() == TYPE_BYTES) {
++				int field_size = ref->FieldSize( *message, fieldDesc ) ;
++				Rcpp::List res(field_size);
++				for (int i=0; i<field_size; i++) {
++					std::string s = ref->GetRepeatedString(*message, fieldDesc, i);
++					res[i] =  Rcpp::wrap(std::vector<Rbyte>(s.begin(), s.end()));
++				}
++				return res;
++			} else {
++				throwException( "unknown field type with CPP_TYPE STRING", "ConversionException" ) ;
++			}
++
+     	}
+     	
+     } else {
+@@ -81,14 +95,22 @@
+ 		HANDLE_SINGLE_FIELD( CPPTYPE_DOUBLE, Double );
+ 		HANDLE_SINGLE_FIELD( CPPTYPE_FLOAT, Float );
+ 		HANDLE_SINGLE_FIELD( CPPTYPE_BOOL, Bool );
+-		HANDLE_SINGLE_FIELD( CPPTYPE_STRING, String );
+ #undef HANDLE_SINGLE_FIELD
+ 
++		case CPPTYPE_STRING:
++			if (fieldDesc->type() == TYPE_STRING) {
++				return Rcpp::wrap( ref->GetString(*message, fieldDesc) );
++			} else if (fieldDesc->type() == TYPE_BYTES) {
++				std::string s = ref->GetString(*message, fieldDesc);
++				return Rcpp::wrap(std::vector<Rbyte>(s.begin(), s.end()));
++			} else {
++				throwException( "unknown field type with CPP_TYPE STRING", "ConversionException" ) ;			   
++			}
+ 		case CPPTYPE_ENUM : 
+-    			return Rcpp::wrap( ref->GetEnum( *message, fieldDesc )->number() ) ;
++			return Rcpp::wrap( ref->GetEnum( *message, fieldDesc )->number() ) ;
+     		
+-    		case CPPTYPE_MESSAGE:
+-    			return S4_Message( CLONE( &ref->GetMessage( *message, fieldDesc ) ) ) ;
++   		case CPPTYPE_MESSAGE:
++			return S4_Message( CLONE( &ref->GetMessage( *message, fieldDesc ) ) ) ;
+     			break ;
+     	}
+     }
+Index: pkg/src/mutators.cpp
+===================================================================
+--- pkg/src/mutators.cpp	(revision 392)
++++ pkg/src/mutators.cpp	(working copy)
+@@ -152,18 +152,24 @@
+ 	return "" ; // -Wall, should not happen since we only call this when we know it works
+ }
+ 
+-/**
+- * calls the R function charToRaw to convert raw into a string
+- *
+- * @param raw raw vector
+- * @return a string (STRSXP)
+- */
+-/* FIXME: maybe we don't need to go back to R for this */
+-SEXP rawToString( SEXP raw){
+-	SEXP call = PROTECT( Rf_lang2( Rf_install("charToRaw"), raw ) ) ;
+-	SEXP res = PROTECT( Rf_eval( call, R_GlobalEnv ) );
+-	UNPROTECT( 2 ) ; /* res, call */
+-	return res ;
++std::string GET_bytes( SEXP x, int index ){
++	switch( TYPEOF(x)) {
++		case RAWSXP:
++			if (index == 0) {
++				return(std::string((const char *) RAW(x), (size_t) LENGTH(x)));
++			} else {
++				throwException( "cannot cast SEXP to bytes", "CastException" ) ;
++			}
++		case VECSXP:
++			if (TYPEOF(VECTOR_ELT(x, index)) == RAWSXP) {
++				return(std::string((const char *) RAW(VECTOR_ELT(x, index)), (size_t) LENGTH(VECTOR_ELT(x, index))));
++			} else {
++				throwException( "cannot cast SEXP to bytes", "CastException" ) ;
++			}
++		default:
++			throwException( "cannot cast SEXP to bytes", "CastException" ) ;
++	}
++	return "" ; // -Wall, should not happen since we only call this when we know it works
+ }
+ 
+ /**
+@@ -189,6 +195,25 @@
+ 	return _TRUE_ ;
+ }
+ 
++/**
++ * indicates if this is a list of raws
++ * 
++ * @param x a list (VECSXP)
++ * @return TRUE if all objects are instances of RAWSXP
++ */
++Rboolean allAreRaws( SEXP x) {
++		
++	if( TYPEOF(x) != VECSXP ) return _FALSE_ ;
++	
++	int n = LENGTH(x) ;
++	SEXP current ;
++	for( int i=0; i<n; i++){
++		current = VECTOR_ELT( x, i) ;
++		/* not a RAWSXP */
++		if( TYPEOF(current) != RAWSXP ) return _FALSE_ ;
++	}
++	return _TRUE_ ;
++}
+ 
+ /**
+  * check that all the values contained in value are suitable for the 
+@@ -345,7 +370,9 @@
+ 				value_size = 1 ; /* we will store the message payload */
+ 			} else if( TYPEOF(value) == VECSXP && allAreMessages( value ) ){
+ 				value_size = LENGTH(value) ;
+-			} else{
++			} else if( TYPEOF(value) == VECSXP && allAreRaws( value ) ){
++				value_size = LENGTH(value) ;
++			} else {
+ 				throwException( "cannot convert to string", "ConversionException" ) ;
+ 			}
+ 		}
+@@ -744,8 +771,20 @@
+     						} 
+     					case RAWSXP:
+     						{
+-    							ref->SetRepeatedString( message, field_desc, 0, COPYSTRING( CHAR(STRING_ELT(rawToString(value),0 )) ) ) ;
+-    						}
++    							/* in any case, fill the values up to field_size */
++								int i = 0;
++								for ( ; i<field_size; i++) {
++									ref->SetRepeatedString( message, field_desc, i, GET_bytes(value, 0)) ;
++								}
++								
++								/* then add some if needed */
++								if( value_size > field_size ){
++									for( ; i<value_size; i++) {
++										ref->AddString( message, field_desc, GET_bytes(value, 0)) ;
++									}
++								}
++								break;
++							}
+     					case S4SXP:
+     						{
+     							/* check if value is a message */
+@@ -759,28 +798,43 @@
+     						}
+     					case VECSXP:
+     						{
+-    							// we know it is a list of messages because it 
++    							// we know it is a list of messages or raws because it 
+     							// has been tested above
+-    							
+-    							// FIXME: we should probably use SerializeToString 
+-    							//        as indicated in the protobuf api documentation
+-    							//        http://code.google.com/apis/protocolbuffers/docs/reference/cpp/google.protobuf.message_lite.html#MessageLite.SerializeAsString.details
+-    							GPB::Message* __mess ;
+-    							
+-    							/* in any case, fill the values up to field_size */
+-    							int i = 0;
+-			    				for( ; i<field_size; i++){
+-			    					__mess = GET_MESSAGE_POINTER_FROM_S4( VECTOR_ELT( value, i ) ); 
+-			    					ref->SetRepeatedString( message, field_desc, i, __mess->SerializeAsString() ) ;
+-			    				}
+-			    				
+-			    				/* then add some if needed */
+-			    				if( value_size > field_size ){
+-			    					for( ; i<value_size; i++){
+-			    						__mess = GET_MESSAGE_POINTER_FROM_S4( VECTOR_ELT( value, i ) ); 
+-			    						ref->AddString( message, field_desc, __mess->SerializeAsString() ) ;
+-			    					}
+-			    				}
++						        if (LENGTH(value) > 0 && TYPEOF(VECTOR_ELT(value, 0)) == RAWSXP ) {
++									/* in any case, fill the values up to field_size */
++									int i = 0;
++									for( ; i<field_size; i++) {
++										ref->SetRepeatedString( message, field_desc, i, GET_bytes(value,i )) ;
++									}
++									
++									/* then add some if needed */
++									if( value_size > field_size ) {
++										for( ; i<value_size; i++){
++											ref->AddString( message, field_desc, GET_bytes(value,i )) ;
++										}
++									}
++								} else {
++									// FIXME: we should probably use SerializeToString 
++									//        as indicated in the protobuf api documentation
++									//        http://code.google.com/apis/protocolbuffers/docs/reference/cpp/google.protobuf.message_lite.html#MessageLite.SerializeAsString.details
++									GPB::Message* __mess ;
++									
++									/* in any case, fill the values up to field_size */
++									int i = 0;
++									for( ; i<field_size; i++){
++										__mess = GET_MESSAGE_POINTER_FROM_S4( VECTOR_ELT( value, i ) ); 
++										ref->SetRepeatedString( message, field_desc, i, __mess->SerializeAsString() ) ;
++									}
++									
++									/* then add some if needed */
++									if( value_size > field_size ){
++										for( ; i<value_size; i++){
++											__mess = GET_MESSAGE_POINTER_FROM_S4( VECTOR_ELT( value, i ) ); 
++											ref->AddString( message, field_desc, __mess->SerializeAsString() ) ;
++										}
++									}
++									
++								}
+ 			    				break ;
+     							
+     						}
+@@ -936,7 +990,7 @@
+     						}
+     					case RAWSXP:
+     						{
+-    							ref->SetString(message, field_desc, COPYSTRING( CHAR(STRING_ELT( rawToString( value ) ,0 )) ) ) ;
++    							ref->SetString(message, field_desc,  GET_bytes(value, 0)) ;
+     							break ;
+     						}
+     					case S4SXP:
+Index: pkg/src/rprotobuf.h
+===================================================================
+--- pkg/src/rprotobuf.h	(revision 392)
++++ pkg/src/rprotobuf.h	(working copy)
+@@ -59,7 +59,7 @@
+ 
+ 
+ /* uncomment for debugging */
+-// #define RPB_DEBUG
++#define RPB_DEBUG
+ 
+ #ifdef RPB_DEBUG
+ #define RPB_DEBUG_BEGIN(__WHAT__) Rprintf( "<" #__WHAT__ ">\n" ) ;
+@@ -138,6 +138,7 @@
+ RcppExport uint64 GET_uint64( SEXP, int ) ;
+ RcppExport bool GET_bool( SEXP, int) ;
+ RcppExport std::string GET_stdstring( SEXP, int ) ;
++RcppExport std::string GET_bytes( SEXP, int ) ;
+ RcppExport void CHECK_values_for_enum( GPB::FieldDescriptor*, SEXP) ;
+ RcppExport void CHECK_messages( GPB::FieldDescriptor*, SEXP) ;
+ 
+Index: pkg/src/wrapper_Message.cpp
+===================================================================
+--- pkg/src/wrapper_Message.cpp	(revision 392)
++++ pkg/src/wrapper_Message.cpp	(working copy)
+@@ -840,7 +840,6 @@
+ 				
+      			// {{{ string
+ 				case TYPE_STRING:
+-    			case TYPE_BYTES:
+     				{
+     					if( TYPEOF(values) == STRSXP ){ 
+     						for( int i=0 ; i<value_size; i++){
+@@ -852,6 +851,22 @@
+     					break ; 
+     				}
+ 				// }}}
++
++     			// {{{ bytes
++    			case TYPE_BYTES:
++    				{
++						if( TYPEOF(values) == RAWSXP ){
++							ref->AddString( message, field_desc, GET_bytes(values,0 )) ;
++						} else if( TYPEOF(values) == VECSXP ){ 
++							for( int i=0 ; i<value_size; i++) {
++								ref->AddString( message, field_desc, GET_bytes(values,i )) ;
++				    		}
++    					} else{
++    						throwException( "Cannot convert to bytes", "ConversionException" ) ;
++    					}
++    					break ; 
++    				}
++				// }}}
+     			
+ 				// {{{ message
+     			case TYPE_MESSAGE:
+@@ -983,7 +998,6 @@
+ 					return res; 
+ 				}
+ 			case TYPE_STRING:
+-	    	case TYPE_BYTES:
+ 	    		{
+ 	    			const GPB::Reflection* ref = message->GetReflection() ; 
+ 	    			Rcpp::CharacterVector res(n) ;
+@@ -992,6 +1006,16 @@
+     				}
+     			    return res ;
+ 	    		}
++	    	case TYPE_BYTES:
++	    		{
++	    			const GPB::Reflection* ref = message->GetReflection() ; 
++	    			Rcpp::List res(n) ;
++	    			for( int i=0; i<n; i++){
++						std::string s = ref->GetRepeatedString( *message, field_desc, index[i] );
++	    				res[i] = std::vector<Rbyte>(s.begin(), s.end());
++    				}
++    			    return res ;
++	    		}
+ 	    	case TYPE_MESSAGE:
+     		case TYPE_GROUP:
+     			{
+@@ -1101,7 +1125,6 @@
+ 						break ;
+ 					}
+ 				case TYPE_STRING:
+-	    		case TYPE_BYTES:
+ 	    			{
+ 	    				
+ 	    				for( int i=0; i<n; i++){
+@@ -1111,6 +1134,16 @@
+ 						}
+ 						break ;
+ 	    			}
++	    		case TYPE_BYTES:
++	    			{
++	    				
++	    				for( int i=0; i<n; i++){
++							ref->SetRepeatedString( message, field_desc, 
++								index[i], 
++								GET_bytes( values, i ) ) ;
++						}
++						break ;
++	    			}
+ 	    		case TYPE_ENUM :
+ 	    			{
+ 	    				CHECK_values_for_enum( field_desc, values ) ;



More information about the Rprotobuf-commits mailing list