[Rprotobuf-commits] r735 - in pkg: . R inst/unitTests src
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Thu Jan 9 22:11:39 CET 2014
Author: murray
Date: 2014-01-09 22:11:39 +0100 (Thu, 09 Jan 2014)
New Revision: 735
Modified:
pkg/ChangeLog
pkg/R/00classes.R
pkg/R/read.R
pkg/inst/unitTests/runit.addressbook.R
pkg/src/wrapper_Descriptor.cpp
Log:
Add a logical argument 'partial' to readASCII that allows one to read
in incomplete message types in ASCII format.
Modified: pkg/ChangeLog
===================================================================
--- pkg/ChangeLog 2014-01-09 14:56:40 UTC (rev 734)
+++ pkg/ChangeLog 2014-01-09 21:11:39 UTC (rev 735)
@@ -1,3 +1,10 @@
+2014-01-09 Murray Stokely <mstokely at google.com>
+
+ * R/read.R: Add a logical argument 'partial' to readASCII that
+ accepts uninitialized message fragments.
+ * src/wrapper_Descriptor.cpp (rprotobuf): Idem
+ * inst/unitTests/runit.addressbook.R (test.ascii): Add tests for above.
+
2014-01-04 Murray Stokely <mstokely at google.com>
* R/wrapper_CodedInputStream.R: Accept numeric size arguments for
Modified: pkg/R/00classes.R
===================================================================
--- pkg/R/00classes.R 2014-01-09 14:56:40 UTC (rev 734)
+++ pkg/R/00classes.R 2014-01-09 21:11:39 UTC (rev 735)
@@ -203,7 +203,7 @@
switch( name,
"new" = function( ... ) newProto( x, ... ) ,
"read" = function( input ) read( x, input ) ,
- "readASCII" = function( input ) readASCII( x, input ),
+ "readASCII" = function(input, ...) readASCII(x, input, ...),
"toString" = function(...) toString(x, ...) ,
"as.character" = function(...) as.character(x, ...) ,
"as.list" = function(...) as.list(x, ...) ,
Modified: pkg/R/read.R
===================================================================
--- pkg/R/read.R 2014-01-09 14:56:40 UTC (rev 734)
+++ pkg/R/read.R 2014-01-09 21:11:39 UTC (rev 735)
@@ -29,24 +29,28 @@
-setGeneric( "readASCII", function( descriptor, input ){
+setGeneric( "readASCII", function( descriptor, input, partial=FALSE ){
standardGeneric( "readASCII" )
} )
setMethod( "readASCII", c( descriptor = "Descriptor" , input = "character" ),
-function(descriptor, input ){
- .Call( "Descriptor__readASCIIFromString", descriptor at pointer, input, PACKAGE = "RProtoBuf" )
+function(descriptor, input, partial=FALSE){
+ stopifnot(is.logical(partial), length(partial) == 1)
+ .Call( "Descriptor__readASCIIFromString", descriptor at pointer, input,
+ partial, PACKAGE = "RProtoBuf" )
} )
setMethod( "readASCII", c( descriptor = "Descriptor" ),
-function( descriptor, input ){
+function( descriptor, input, partial=FALSE){
+ stopifnot(is.logical(partial), length(partial) == 1)
if( !inherits( input, "connection" ) ){
stop( "can only read from connections" )
}
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" )
+ message <- .Call( "Descriptor__readASCIIFromConnection", descriptor at pointer, input,
+ partial, PACKAGE = "RProtoBuf" )
if( !wasopen ) close( input )
message
} )
Modified: pkg/inst/unitTests/runit.addressbook.R
===================================================================
--- pkg/inst/unitTests/runit.addressbook.R 2014-01-09 14:56:40 UTC (rev 734)
+++ pkg/inst/unitTests/runit.addressbook.R 2014-01-09 21:11:39 UTC (rev 735)
@@ -66,4 +66,16 @@
# Verify that we get an exception if we forget the file() and thus treat the
# path as a protobuf string.
checkException( readASCII( tutorial.AddressBook, out.file2))
+
+ incomplete.msg <- new(tutorial.Person, name="Murray", email="murray at stokely.org")
+ tmp.file <- tempfile()
+ writeLines(as.character(incomplete.msg), file(tmp.file))
+
+ checkTrue(!incomplete.msg$isInitialized())
+ # Verify we normally get an exception if we try to read an incomplete ASCII protocol buffer
+ checkException( tutorial.Person$readASCII(file(tmp.file)))
+
+ # Verify we can however read it if we set partial=TRUE.
+ new.msg <- tutorial.Person$readASCII(file(tmp.file), TRUE)
+ checkEquals(incomplete.msg$name, new.msg$name)
}
Modified: pkg/src/wrapper_Descriptor.cpp
===================================================================
--- pkg/src/wrapper_Descriptor.cpp 2014-01-09 14:56:40 UTC (rev 734)
+++ pkg/src/wrapper_Descriptor.cpp 2014-01-09 21:11:39 UTC (rev 735)
@@ -173,18 +173,31 @@
return (S4_Message(message));
}
-RPB_FUNCTION_2(S4_Message, METHOD(readASCIIFromString), Rcpp::XPtr<GPB::Descriptor> desc,
- std::string input) {
+RPB_FUNCTION_3(S4_Message, METHOD(readASCIIFromString), Rcpp::XPtr<GPB::Descriptor> desc,
+ std::string input, bool partial) {
GPB::Message* message = PROTOTYPE(desc);
- if (GPB::TextFormat::ParseFromString(input, message)) {
- return (S4_Message(message));
+ if (partial) {
+ // Allow partial messages where object is not fully initialized
+ GPB::TextFormat::Parser parser;
+ parser.AllowPartialMessage(partial);
+ if (parser.ParseFromString(input, message)) {
+ return (S4_Message(message));
+ } else {
+ throw std::range_error("Could not parse ASCII protocol buffer from text string."
+ " Consider setting partial=TRUE");
+ }
} else {
- throw std::range_error("Could not parse ASCII protocol buffer from text string.");
+ // Default parser requires fully initialized ascii messages.
+ if (GPB::TextFormat::ParseFromString(input, message)) {
+ return (S4_Message(message));
+ } else {
+ throw std::range_error("Could not parse ASCII protocol buffer from text string.");
+ }
}
}
RPB_FUNCTION_2(S4_Message, METHOD(readASCIIFromConnection), Rcpp::XPtr<GPB::Descriptor> desc,
- int conn_id) {
+ int conn_id, bool partial) {
RconnectionCopyingInputStream wrapper(conn_id);
GPB::io::CopyingInputStreamAdaptor stream(&wrapper);
@@ -193,14 +206,23 @@
if (!message) {
throw std::range_error("could not call factory->GetPrototype(desc)->New()");
}
- if (!GPB::TextFormat::Parse(&stream, message)) {
- throw std::range_error("Could not parse ASCII protocol buffer.");
+ if (partial) {
+ // Allow partial messages where object is not fully initialized
+ GPB::TextFormat::Parser parser;
+ parser.AllowPartialMessage(partial);
+ if (!parser.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.");
+ // Default parser requires fully initialized ascii messages.
+ if (!GPB::TextFormat::Parse(&stream, message)) {
+ throw std::range_error("Could not parse ASCII protocol buffer.");
}
- return (S4_Message(message));
}
+ 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