[Rprotobuf-commits] r481 - in pkg: . R inst inst/unitTests man src

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Tue Sep 25 04:58:01 CEST 2012


Author: murray
Date: 2012-09-25 04:58:01 +0200 (Tue, 25 Sep 2012)
New Revision: 481

Modified:
   pkg/ChangeLog
   pkg/R/00classes.R
   pkg/R/has.R
   pkg/inst/NEWS.Rd
   pkg/inst/unitTests/runit.golden.message.R
   pkg/man/has.Rd
   pkg/src/wrapper_Message.cpp
Log:
Distinguish between non-existant and not-set fields in a message with
has().  Update docs and tests.



Modified: pkg/ChangeLog
===================================================================
--- pkg/ChangeLog	2012-09-21 23:19:25 UTC (rev 480)
+++ pkg/ChangeLog	2012-09-25 02:58:01 UTC (rev 481)
@@ -1,3 +1,12 @@
+2012-09-24  Murray Stokely  <mstokely at google.com>
+
+	* R/has.R: Distinguish between non-existant and not-set fields in
+	  a message by returning NULL in the former case.
+	* R/00classes.R: Idem
+	* src/wrapper_Message.cpp (rprotobuf): Idem
+	* inst/unitTests/runit.golden.message.R (test.has): Add test.
+	* man/has.Rd: Add example of the above.
+
 2012-09-21  Murray Stokely  <murray at FreeBSD.org>
 
 	* Fix a bug causing segfaults in containing_type().

Modified: pkg/R/00classes.R
===================================================================
--- pkg/R/00classes.R	2012-09-21 23:19:25 UTC (rev 480)
+++ pkg/R/00classes.R	2012-09-25 02:58:01 UTC (rev 481)
@@ -152,7 +152,7 @@
 setMethod("$", "Message", function(x, name) {
 	
 	switch( name, 
-		"has" = function( ... )      .Call( "Message__has_field"     , x at pointer, ..., PACKAGE = "RProtoBuf"), 
+		"has" = function( ... ) has(x, ...),
 		"clone" = function( ... )    .Call( "Message__clone"         , x at pointer, ..., PACKAGE = "RProtoBuf"), 
 		"isInitialized" = function() .Call( "Message__is_initialized", x at pointer,      PACKAGE = "RProtoBuf"),    
 		"descriptor" = function()    .Call( "Message__descriptor"     , x at pointer,      PACKAGE = "RProtoBuf" ), 
@@ -535,4 +535,3 @@
 	standardGeneric( "enum_type" )
 })
 # }}}
-

Modified: pkg/R/has.R
===================================================================
--- pkg/R/has.R	2012-09-21 23:19:25 UTC (rev 480)
+++ pkg/R/has.R	2012-09-25 02:58:01 UTC (rev 481)
@@ -3,7 +3,10 @@
 	standardGeneric( "has" )
 } )
 ._has_message <- function( object, name, ...){
-	.Call( "Message__has_field", object at pointer, name, PACKAGE = "RProtoBuf" )
+	if (!.Call( "Message__field_exists", object at pointer, name, PACKAGE = "RProtoBuf" )) {
+		return(NULL)
+	} else {
+		return(.Call( "Message__has_field", object at pointer, name, PACKAGE = "RProtoBuf" ))
+	}
 }
 setMethod( "has", "Message", ._has_message )
-

Modified: pkg/inst/NEWS.Rd
===================================================================
--- pkg/inst/NEWS.Rd	2012-09-21 23:19:25 UTC (rev 480)
+++ pkg/inst/NEWS.Rd	2012-09-25 02:58:01 UTC (rev 481)
@@ -4,14 +4,15 @@
 
 \section{Changes in version 0.2.6 (2012-xx-yy)}{
   \itemize{
-    \item Applied three more patches by Murray to
+    \item Applied several more patches by Murray to
     \itemize{
       \item correct '_' and '__' mismatches in wrapper calls
       \item update a few manual pages for style, and add examples
       \item fix a bug where NAs were silently treated as TRUE for logical/bool types
       \item fix a bug that caused crashes when adding vectors to optional fields
       \item fix bugs in readASCII that returned empty protocol buffers when the file or connection could not be opened
-      \item add a unit test for this new check
+      \item distinguish between non-existant and not-set fieldswith has() by returning NULL in the former case.
+      \item add unit tests for all of the above.
     }
   }
 }

Modified: pkg/inst/unitTests/runit.golden.message.R
===================================================================
--- pkg/inst/unitTests/runit.golden.message.R	2012-09-21 23:19:25 UTC (rev 480)
+++ pkg/inst/unitTests/runit.golden.message.R	2012-09-25 02:58:01 UTC (rev 481)
@@ -81,3 +81,14 @@
 	test <- new(protobuf_unittest.TestAllTypes)
 	checkException(test$optional_int32 <- 1:10)
 }
+
+# Versions of RProtoBuf <= 0.2.5 did not distinguish between non-existant
+# and not-set fields with has().
+test.has <- function(){
+	test <- new(protobuf_unittest.TestAllTypes)
+	test$add("repeated_int32", c(1:5))
+	checkTrue( has(test, "repeated_int32"))
+	checkTrue( test$has("repeated_int32"))
+	checkTrue( is.null(test$has("nonexistant")))
+	checkTrue( !test$has("optional_int32"))
+}

Modified: pkg/man/has.Rd
===================================================================
--- pkg/man/has.Rd	2012-09-21 23:19:25 UTC (rev 480)
+++ pkg/man/has.Rd	2012-09-25 02:58:01 UTC (rev 481)
@@ -16,6 +16,9 @@
 For repeated fields, a call to the \code{FieldSize}
 method is issued, and the message is declared to have 
 the field if the size is greater than 0.
+
+\code{NULL} is returned if the descriptor for the message does not
+contain the given field at all.
 }
 \section{Methods}{
 	\describe{
@@ -29,8 +32,11 @@
 
 test <- new(protobuf_unittest.TestAllTypes)
 test$has("optional_int32")
-
+# FALSE
 test$add("repeated_int32", 1:10)
 test$has("repeated_int32")
+# TRUE
+test$has("nonexistant")
+# NULL
 }
 \keyword{methods}

Modified: pkg/src/wrapper_Message.cpp
===================================================================
--- pkg/src/wrapper_Message.cpp	2012-09-21 23:19:25 UTC (rev 480)
+++ pkg/src/wrapper_Message.cpp	2012-09-25 02:58:01 UTC (rev 481)
@@ -72,11 +72,26 @@
 }
 
 /**
- * TRUE if the message has the field name
+ * TRUE if the message has the specified field name.
+ * FALSE otherwise.
  *
+ *
  * @param xp external pointer to the Message
  * @param name name of the field
  */
+RCPP_FUNCTION_2(bool, METHOD(field_exists), Rcpp::XPtr<GPB::Message> message, std::string name ){
+	const GPB::Descriptor* desc = message->GetDescriptor(); 
+	const GPB::FieldDescriptor* field_desc = desc->FindFieldByName( name ) ;
+	return (field_desc != NULL);
+}
+
+/**
+ * TRUE if the message has the field name and it is populated.
+ * FALSE otherwise.
+ *
+ * @param xp external pointer to the Message
+ * @param name name of the field
+ */
 RCPP_FUNCTION_2(bool, METHOD(has_field), Rcpp::XPtr<GPB::Message> message, std::string name ){
 
 	const GPB::Descriptor* desc = message->GetDescriptor(); 
@@ -1203,4 +1218,3 @@
 	#undef METHOD
 
 }
-



More information about the Rprotobuf-commits mailing list