Index: src/mutators.cpp =================================================================== --- src/mutators.cpp (revision 471) +++ src/mutators.cpp (working copy) @@ -151,10 +151,22 @@ bool GET_bool( SEXP x, int index ){ switch( TYPEOF(x) ){ case INTSXP: + if (INTEGER(x)[index] == R_NaInt) { + throwException( "NA boolean values not supported by RProtoBuf", + "CastException" ) ; + } return( (bool)INTEGER(x)[index] ); case REALSXP: + if (REAL(x)[index] == R_NaReal) { + throwException( "NA boolean values not supported by RProtoBuf", + "CastException" ) ; + } return( (bool)REAL(x)[index] ); case LGLSXP: + if (LOGICAL(x)[index] == NA_LOGICAL) { + throwException( "NA boolean values not supported by RProtoBuf", + "CastException" ) ; + } return( (bool)LOGICAL(x)[index] ); case RAWSXP: return( (bool)RAW(x)[index] ) ; Index: inst/unitTests/runit.golden.message.R =================================================================== --- inst/unitTests/runit.golden.message.R (revision 471) +++ inst/unitTests/runit.golden.message.R (working copy) @@ -60,9 +60,18 @@ test <- new(protobuf_unittest.TestAllTypes) test$add("repeated_int32", c(1:5)) checkEquals(test$repeated_int32, c(1:5)) +} - # Prior to RProtoBuf v0.2.5, this was not handled properly. - test.2 <- new(protobuf_unittest.TestAllTypes, - repeated_string=c("foo", "bar")) - checkEquals(test.2$repeated_string, c("foo", "bar")) +test.repeated.bools <- function() { + test <- new(protobuf_unittest.TestAllTypes) + test$add("repeated_bool", c(TRUE, FALSE)) + checkEquals(test$repeated_bool, c(TRUE, FALSE)) + + test$add("repeated_bool", as.integer(c(TRUE, FALSE))) + test$add("repeated_bool", as.numeric(c(TRUE, FALSE))) + + checkEquals(test$repeated_bool, rep(c(TRUE, FALSE), 3)) + + # Verify that we don't silently cast NA into TRUE or FALSE. + checkException(test$add("repeated_bool"), c(TRUE, FALSE, NA)) }