@@ -1207,9 +1207,11 @@ impl<'a, A: AsRef<[u8]>> TxReader<'a, A> {
1207
1207
}
1208
1208
}
1209
1209
1210
- /// Looks for zero or more NOP pads followed by either :
1210
+ /// Looks for zero or more NOP pads followed by any of these :
1211
1211
/// * an annotated value
1212
1212
/// * a value
1213
+ /// * the end of the stream
1214
+ /// * (at the top level) an Ion version marker starting a new stream
1213
1215
#[ inline]
1214
1216
fn read_sequence_item (
1215
1217
& mut self ,
@@ -1218,7 +1220,8 @@ impl<'a, A: AsRef<[u8]>> TxReader<'a, A> {
1218
1220
if type_descriptor. is_nop ( ) {
1219
1221
if let Some ( item) = self . consume_nop_padding ( & mut type_descriptor) ? {
1220
1222
// We may encounter the end of the file or container while reading NOP padding,
1221
- // in which case `item` will be RawStreamItem::Nothing.
1223
+ // in which case `item` will be RawStreamItem::Nothing. At the top level, it is
1224
+ // possible to encounter an IVM at the end of the NOP pad.
1222
1225
return Ok ( item) ;
1223
1226
}
1224
1227
// Note that if `consume_nop_padding` reads NOP bytes but doesn't hit EOF, it will
@@ -1361,6 +1364,9 @@ impl<'a, A: AsRef<[u8]>> TxReader<'a, A> {
1361
1364
return Ok ( Some ( RawStreamItem :: Nothing ) ) ;
1362
1365
}
1363
1366
* type_descriptor = self . tx_buffer . peek_type_descriptor ( ) ?;
1367
+ if type_descriptor. is_ivm_start ( ) {
1368
+ return self . read_ivm ( ) . map ( Some ) ;
1369
+ }
1364
1370
}
1365
1371
Ok ( None )
1366
1372
}
@@ -1947,6 +1953,29 @@ mod tests {
1947
1953
Ok ( ( ) )
1948
1954
}
1949
1955
1956
+ #[ test]
1957
+ fn ivm_after_nop ( ) -> IonResult < ( ) > {
1958
+ let data = & [
1959
+ 0xE0 , 0x01 , 0x00 , 0xEA , // IVM
1960
+ 0x00 , // 1-byte NOP
1961
+ 0x01 , 0xff , // 2-byte NOP
1962
+ 0xE0 , 0x01 , 0x00 , 0xEA , // IVM
1963
+ 0x83 , 0x66 , 0x6f , 0x6f , // "foo"
1964
+ 0x02 , 0xff , 0xff , // 3-byte NOP
1965
+ ] ; // Empty string
1966
+ let mut reader = RawBinaryReader :: new ( data) ;
1967
+ let item = reader. next ( ) ?;
1968
+ assert_eq ! ( item, RawStreamItem :: VersionMarker ( 1 , 0 ) ) ;
1969
+ let item = reader. next ( ) ?;
1970
+ assert_eq ! ( item, RawStreamItem :: VersionMarker ( 1 , 0 ) ) ;
1971
+ let item = reader. next ( ) ?;
1972
+ assert_eq ! ( item, RawStreamItem :: Value ( IonType :: String ) ) ;
1973
+ assert_eq ! ( reader. read_str( ) ?, "foo" ) ;
1974
+ let item = reader. next ( ) ?;
1975
+ assert_eq ! ( item, RawStreamItem :: Nothing ) ;
1976
+ Ok ( ( ) )
1977
+ }
1978
+
1950
1979
#[ test]
1951
1980
fn debug ( ) -> IonResult < ( ) > {
1952
1981
let data = & [
0 commit comments