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

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Sat Aug 18 23:41:42 CEST 2012


Author: edd
Date: 2012-08-18 23:41:41 +0200 (Sat, 18 Aug 2012)
New Revision: 476

Added:
   pkg/inst/unitTests/runit.FieldDescriptor.R
Modified:
   pkg/ChangeLog
   pkg/NAMESPACE
   pkg/R/read.R
   pkg/R/wrapper_FieldDescriptor.R
   pkg/inst/unitTests/runit.addressbook.R
   pkg/inst/unitTests/runit.import.R
   pkg/man/is_extension.Rd
   pkg/man/label.Rd
   pkg/man/number.Rd
   pkg/man/readASCII.Rd
   pkg/man/type.Rd
   pkg/src/RconnectionCopyingInputStream.cpp
   pkg/src/RconnectionCopyingInputStream.h
   pkg/src/wrapper_Descriptor.cpp
Log:
two more patches by Murray


Modified: pkg/ChangeLog
===================================================================
--- pkg/ChangeLog	2012-08-09 18:33:44 UTC (rev 475)
+++ pkg/ChangeLog	2012-08-18 21:41:41 UTC (rev 476)
@@ -1,7 +1,17 @@
+2012-08-18  Dirk Eddelbuettel  <edd at debian.org>
+
+	* Applied two more patches by Murray and Karl:
+	  - Make readASCII() more robust to error conditions; adds tests to
+	    catch them.
+	  - Correct type(), cpp_type(), and label() methods when
+	    as.string=TRUE; add unit tests for these methods, add examples to
+	    the Rd files for these methods, and adds type and cpp_type to the
+	    NAMESPACE file where they were previously absent.
+
 2012-08-09  Dirk Eddelbuettel  <edd at debian.org>
 
 	* Applied two more patches by Murray:
-	  - R/wrapper_FielDescriptor.R: correct more '_' and '__' mismatches 
+	  - R/wrapper_FielDescriptor.R: correct more '_' and '__' mismatches
 	  - man/*: update manual pages for style, add examples
 	  - src/mutators.cpp: add tests for NA in boolean vectors
 	  - inst/unitTests/runit.golden.message.R: add unit test
@@ -21,7 +31,7 @@
 
 	* /man/add.Rd: Add patch by Murray for stylistic improvement and
 	added examples
-	
+
 	* inst/NEWS.Rd: Converted NEWS file to .Rd format
 
 	* DESCRIPTION: Changed Maintainer: to single person per CRAN Policy

Modified: pkg/NAMESPACE
===================================================================
--- pkg/NAMESPACE	2012-08-09 18:33:44 UTC (rev 475)
+++ pkg/NAMESPACE	2012-08-18 21:41:41 UTC (rev 476)
@@ -48,7 +48,7 @@
 	"is_extension", "number", "label",
 	"is_required", "is_repeated", "is_optional",
 	"has_default_value", "default_value",
-	"message_type", "enum_type",
+	"message_type", "enum_type", "type", "cpp_type",
 
 	# EnumDescriptor
 	"value_count", "value",
@@ -103,4 +103,3 @@
 exportPattern( "^LABEL_" )
 
 # export( run_unit_tests )
-

Modified: pkg/R/read.R
===================================================================
--- pkg/R/read.R	2012-08-09 18:33:44 UTC (rev 475)
+++ pkg/R/read.R	2012-08-18 21:41:41 UTC (rev 476)
@@ -18,9 +18,9 @@
 	if( !inherits( input, "connection" ) ){ 
 		stop( "can only read from connections" )
 	}
-	sc <- summary( input )
-	wasopen <- identical( sc[["opened"]], "opened" )
-	if( !wasopen ) open( input )
+	wasopen <- identical( summary(input)[["opened"]], "opened" )
+	if( !wasopen ) open( input, "rb")
+        stopifnot(summary(input)[["text"]] == "binary")
 	message <- .Call( "Descriptor__readMessageFromConnection", descriptor at pointer, input, PACKAGE = "RProtoBuf" )
 	if( !wasopen ) close( input )
 	message
@@ -43,9 +43,9 @@
 	if( !inherits( input, "connection" ) ){ 
 		stop( "can only read from connections" )
 	}
-	sc <- summary( input )
-	wasopen <- identical( sc[["opened"]], "opened" )
-	if( !wasopen ) open( input )
+	wasopen <- identical( summary(input)[["opened"]], "opened" )
+	if( !wasopen ) open( input, "rb" )
+        stopifnot(summary(input)[["text"]] == "binary")
 	message <- .Call( "Descriptor__readASCIIFromConnection", descriptor at pointer, input, PACKAGE = "RProtoBuf" )
 	if( !wasopen ) close( input )
 	message

Modified: pkg/R/wrapper_FieldDescriptor.R
===================================================================
--- pkg/R/wrapper_FieldDescriptor.R	2012-08-09 18:33:44 UTC (rev 475)
+++ pkg/R/wrapper_FieldDescriptor.R	2012-08-18 21:41:41 UTC (rev 476)
@@ -32,14 +32,17 @@
 TYPE_SINT32   <- 17L
 TYPE_SINT64   <- 18L
 
-.TYPES <- ls( pattern = "^TYPE_" )
-
 setGeneric( "type", function(object, as.string = FALSE){
 	standardGeneric( "type" )
 } )
 setMethod( "type", "FieldDescriptor", function(object, as.string = FALSE){
 	type <- .Call( "FieldDescriptor__type", object at pointer, PACKAGE = "RProtoBuf" )
-	if( as.string ) .TYPES[type] else type
+	if( as.string ) {
+                .TYPES <- sapply(ls( "package:RProtoBuf", pattern="^TYPE_" ), get)
+                names(which(.TYPES == type))
+        } else {
+                type
+        }
 } )
 
 
@@ -53,27 +56,35 @@
 CPPTYPE_ENUM <- 8L
 CPPTYPE_STRING <- 9L
 CPPTYPE_MESSAGE <- 10L
-.CPPTYPES <- ls( pattern = "^CPPTYPE_" )
 
 setGeneric( "cpp_type", function(object, as.string = FALSE ){
 	standardGeneric( "cpp_type" )
 } )
 setMethod( "cpp_type", "FieldDescriptor", function(object, as.string = FALSE){
 	cpptype <- .Call( "FieldDescriptor__cpp_type", object at pointer, PACKAGE = "RProtoBuf" )
-	if( as.string ) .CPPTYPES[cpptype] else cpptype
+	if( as.string ) {
+                .CPPTYPES <- sapply(ls( "package:RProtoBuf", pattern="^CPPTYPE_" ), get)
+                names(which(.CPPTYPES == cpptype))
+        } else {
+                cpptype
+        }
 } )
 
 LABEL_OPTIONAL <- 1L
 LABEL_REQUIRED <- 2L
 LABEL_REPEATED <- 3L
-.LABELS <-  ls( pattern = "^LABEL_" )
 
 setGeneric( "label", function(object, as.string = FALSE ){
 	standardGeneric( "label" )
 } )
 setMethod( "label", "FieldDescriptor", function(object, as.string = FALSE){
 	lab <- .Call( "FieldDescriptor__label", object at pointer, PACKAGE = "RProtoBuf" )
-	if( as.string ) .LABELS[lab] else lab
+	if( as.string ) {
+                .LABELS <- sapply(ls( "package:RProtoBuf", pattern="^LABEL_" ), get)
+                names(which(.LABELS == lab))
+        } else {
+                lab
+        }
 } )
 
 setGeneric( "is_repeated", function(object ){

Added: pkg/inst/unitTests/runit.FieldDescriptor.R
===================================================================
--- pkg/inst/unitTests/runit.FieldDescriptor.R	                        (rev 0)
+++ pkg/inst/unitTests/runit.FieldDescriptor.R	2012-08-18 21:41:41 UTC (rev 476)
@@ -0,0 +1,58 @@
+# Copyright 2012 Google Inc.
+# Author: Murray Stokely
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+test.FieldDescriptor.class <- function() {
+  proto.file <- system.file( "proto", "addressbook.proto", package = "RProtoBuf" )
+  Person <- P( "tutorial.Person", file = proto.file )
+
+  # field descriptor object
+  checkTrue(!is.null(Person$email))
+
+  # debug string
+  checkTrue(nchar(as.character( Person$email )) > 1)
+
+  # default values
+  checkTrue(!has_default_value(Person$id))
+  checkTrue(has_default_value(Person$PhoneNumber$type))
+
+  checkEquals(default_value(Person$PhoneNumber$type), 1)
+  checkEquals(default_value(Person$id), 0)
+
+  # Get the types of field descriptors
+  checkEquals(type(Person$id), TYPE_INT32)
+  checkEquals(type(Person$id, TRUE), "TYPE_INT32")
+  checkEquals(cpp_type(Person$email), CPPTYPE_STRING)
+  checkEquals(cpp_type(Person$email, TRUE), "CPPTYPE_STRING")
+
+  # Get the label of a field descriptor
+  checkEquals(label(Person$id), LABEL_REQUIRED)
+  checkEquals(label(Person$id, TRUE), "LABEL_REQUIRED")
+  checkEquals(label(Person$email), LABEL_OPTIONAL)
+  checkEquals(label(Person$email, TRUE), "LABEL_OPTIONAL")
+
+  # Test if a field is optional
+  checkTrue(is_required(Person$id))
+  checkTrue(!is_optional(Person$id))
+  checkTrue(!is_repeated(Person$id))
+
+  checkTrue(!is_required(Person$email))
+  checkTrue(is_optional(Person$email))
+  checkTrue(!is_repeated(Person$email))
+
+  # Return the class of a message field
+  checkTrue(inherits(message_type(Person$phone), "Descriptor"))
+}

Modified: pkg/inst/unitTests/runit.addressbook.R
===================================================================
--- pkg/inst/unitTests/runit.addressbook.R	2012-08-09 18:33:44 UTC (rev 475)
+++ pkg/inst/unitTests/runit.addressbook.R	2012-08-18 21:41:41 UTC (rev 476)
@@ -35,7 +35,27 @@
     out.file <- tempfile()
     writeLines( as.character(book), file(out.file))
 
-    # Verify we can read back in the message from a text file.
+    # Verify that we can read back in the message from a text file.
     book2 <- readASCII( tutorial.AddressBook, file(out.file, "rb"))
     checkEquals(as.character(book), as.character(book2) )
+
+    # Verify that we can read in messages from unopened connections.
+    book3 <- readASCII( tutorial.AddressBook, file(out.file))
+    checkEquals(as.character(book), as.character(book3) )
+
+    # Verify that we get an exception if we try to read from a text connection.
+    # (better than silently getting an empty proto.)
+    book4 <- checkException( readASCII( tutorial.AddressBook, file(out.file, "rt"))
+
+    # Verify that we get an exception if the file is not readable.
+    old.mode <- file.info(out.file)[["mode"]])
+    Sys.chmod(out.file, "0000")
+    book5 <- checkException( readASCII( tutorial.AddressBook, file(out.file, "rb")))
+    # Set the permissions back to ensure the file is cleaned up properly.
+    Sys.chmod(out.file, old.mode)
+
+    # Verify that we get an exception if the file is not parseable.
+    out.file2 <- tempfile()
+    writeLines("jibberish", file(out.file2))
+    book6 <- checkException( readASCII( tutorial.AddressBook, file(out.file2)))
 }

Modified: pkg/inst/unitTests/runit.import.R
===================================================================
--- pkg/inst/unitTests/runit.import.R	2012-08-09 18:33:44 UTC (rev 475)
+++ pkg/inst/unitTests/runit.import.R	2012-08-18 21:41:41 UTC (rev 476)
@@ -15,6 +15,6 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 test.import <- function() {
-  # Verify we get a graceful errorr ather than segfault.
+  # Verify that we get a graceful error rather than a segfault.
   checkException(readProtoFiles("/etc/hosts"))
 }

Modified: pkg/man/is_extension.Rd
===================================================================
--- pkg/man/is_extension.Rd	2012-08-09 18:33:44 UTC (rev 475)
+++ pkg/man/is_extension.Rd	2012-08-18 21:41:41 UTC (rev 476)
@@ -9,4 +9,8 @@
 The method is implemented for the \linkS4class{FieldDescriptor} class
 }
 \keyword{methods}
-
+\examples{
+proto.file <- system.file( "proto", "addressbook.proto", package = "RProtoBuf" )
+Person <- P( "tutorial.Person", file = proto.file )
+is_extension(Person$id)
+}

Modified: pkg/man/label.Rd
===================================================================
--- pkg/man/label.Rd	2012-08-09 18:33:44 UTC (rev 475)
+++ pkg/man/label.Rd	2012-08-18 21:41:41 UTC (rev 476)
@@ -9,10 +9,26 @@
 
 \title{Gets the label of a field}
 \description{
-Gets the label of a field
+Gets the label of a field (optional, required, or repeated).
 }
+\arguments{
+  \item{object}{A \linkS4class{FieldDescriptor} object.}
+  \item{as.string}{If true, print a string representation of the type.}
+}
 \seealso{
 The method is implemented for the \linkS4class{FieldDescriptor} class
 }
 \keyword{methods}
-
+\examples{
+proto.file <- system.file( "proto", "addressbook.proto", package = "RProtoBuf" )
+Person <- P( "tutorial.Person", file = proto.file )
+label(Person$id)
+label(Person$email)
+label(Person$phone)
+label(Person$id, TRUE)
+label(Person$email, TRUE)
+label(Person$phone, TRUE)
+LABEL_OPTIONAL
+LABEL_REQUIRED
+LABEL_REPEATED
+}

Modified: pkg/man/number.Rd
===================================================================
--- pkg/man/number.Rd	2012-08-09 18:33:44 UTC (rev 475)
+++ pkg/man/number.Rd	2012-08-18 21:41:41 UTC (rev 476)
@@ -9,4 +9,10 @@
 The method is implemented for the \linkS4class{FieldDescriptor} class
 }
 \keyword{methods}
-
+\examples{
+proto.file <- system.file( "proto", "addressbook.proto", package = "RProtoBuf" )
+Person <- P( "tutorial.Person", file = proto.file )
+number(Person$id)
+number(Person$email)
+as.character(Person)
+}

Modified: pkg/man/readASCII.Rd
===================================================================
--- pkg/man/readASCII.Rd	2012-08-09 18:33:44 UTC (rev 475)
+++ pkg/man/readASCII.Rd	2012-08-18 21:41:41 UTC (rev 476)
@@ -31,9 +31,12 @@
 out.file <- tempfile()
 writeLines( as.character(message), file(out.file))
 
-# Verify we can read back in the message from a text file.
+# Verify that we can read back in the message from a text file.
 message2 <- readASCII( tutorial.AddressBook, file(out.file, "rb"))
 
+# Verify that we can read back in the message from an unopened file.
+message3 <- readASCII( tutorial.AddressBook, file(out.file))
+
 \dontshow{
 stopifnot( identical( message, message2) )
 }

Modified: pkg/man/type.Rd
===================================================================
--- pkg/man/type.Rd	2012-08-09 18:33:44 UTC (rev 475)
+++ pkg/man/type.Rd	2012-08-18 21:41:41 UTC (rev 476)
@@ -40,7 +40,19 @@
 \description{
 Gets the type or the C++ type of a field
 }
+\arguments{
+  \item{object}{A \linkS4class{FieldDescriptor} object.}
+  \item{as.string}{If true, print a string representation of the type.}
+}
 \seealso{
 The method is implemented for the \linkS4class{FieldDescriptor} class
 }
 \keyword{methods}
+\examples{
+proto.file <- system.file( "proto", "addressbook.proto", package = "RProtoBuf" )
+Person <- P( "tutorial.Person", file = proto.file )
+type(Person$id)
+type(Person$id, as.string=TRUE)
+cpp_type(Person$email)
+cpp_type(Person$email, TRUE)
+}

Modified: pkg/src/RconnectionCopyingInputStream.cpp
===================================================================
--- pkg/src/RconnectionCopyingInputStream.cpp	2012-08-09 18:33:44 UTC (rev 475)
+++ pkg/src/RconnectionCopyingInputStream.cpp	2012-08-18 21:41:41 UTC (rev 476)
@@ -2,9 +2,11 @@
 #include "RconnectionCopyingInputStream.h"
 
 namespace rprotobuf{
-	
+	/* N.B. connection must be opened in binary mode due to call
+	 * to readBin below. */
 	RconnectionCopyingInputStream::RconnectionCopyingInputStream(int id) : 
-		connection_id(id){}
+                connection_id(id),
+                failure(false) {}
 	
 	/** 
 	 * call readBin to read size bytes from R
@@ -15,18 +17,19 @@
 	 * @return the number of bytes actually read
 	 */
 	int	RconnectionCopyingInputStream::Read(void * buffer, int size){
-		
 		Rcpp::Language call( "readBin", connection_id, Rcpp::RawVector(0), size ) ;
 		Rcpp::RawVector res ;
 		try{
-			res = call.eval(); 
+			res = call.eval();
 		}  catch( ... ){
-			return 0 ;
+			/* Failed to read anything from the connection,
+			 * could have been permissions, or connection opened
+			 * in the wrong type, etc. */
+                        failure = true;
+			return -1 ;
 		}
 		int len = res.size() ;
 		memcpy( buffer, reinterpret_cast<const void*>(res.begin()), len) ;
 		return len ;
 	}
-	
 }
-

Modified: pkg/src/RconnectionCopyingInputStream.h
===================================================================
--- pkg/src/RconnectionCopyingInputStream.h	2012-08-09 18:33:44 UTC (rev 475)
+++ pkg/src/RconnectionCopyingInputStream.h	2012-08-18 21:41:41 UTC (rev 476)
@@ -8,9 +8,11 @@
 			RconnectionCopyingInputStream( int id );
 	
 			int Read(void * buffer, int size) ;
+			bool Failure() { return(failure); }
 	
 		private: 
 			int connection_id ;
+			bool failure;
 } ;
 
 } // namespace rprotobuf

Modified: pkg/src/wrapper_Descriptor.cpp
===================================================================
--- pkg/src/wrapper_Descriptor.cpp	2012-08-09 18:33:44 UTC (rev 475)
+++ pkg/src/wrapper_Descriptor.cpp	2012-08-18 21:41:41 UTC (rev 476)
@@ -179,8 +179,14 @@
 	if( !message ){
 		throw std::range_error( "could not call factory->GetPrototype(desc)->New()" ) ; 
 	}
-	GPB::TextFormat::Parse( &stream, message ) ;
-	return( S4_Message( message ) ) ;
+        if (!GPB::TextFormat::Parse( &stream, message ) ) {
+		throw std::range_error("Could not parse ASCII protocol buffer.");
+        } else {
+                if (wrapper.Failure()) {
+			throw std::range_error("Could not read ASCII protocol buffer.");
+                }
+                return( S4_Message( message ) );
+        }
 }
 
 #undef METHOD



More information about the Rprotobuf-commits mailing list