1- use std:: io:: { IoResult , IoError , OtherIoError , MemReader } ;
1+ use std:: io:: { IoResult , IoError , OtherIoError , ByRefReader } ;
2+ use std:: io:: util:: LimitReader ;
23use std:: mem;
34
45use io:: Timeout ;
@@ -273,7 +274,7 @@ pub trait ReadMessage {
273274 fn read_message ( & mut self ) -> IoResult < BackendMessage > ;
274275}
275276
276- impl < R : Reader +Timeout > ReadMessage for R {
277+ impl < R : Buffer +Timeout > ReadMessage for R {
277278 fn read_message ( & mut self ) -> IoResult < BackendMessage > {
278279 // The first byte read is a bit complex to make
279280 // Notifications::next_block_for work.
@@ -286,25 +287,25 @@ impl<R: Reader+Timeout> ReadMessage for R {
286287
287288 // subtract size of length value
288289 let len = try!( self . read_be_u32 ( ) ) as uint - mem:: size_of :: < i32 > ( ) ;
289- let mut buf = MemReader :: new ( try! ( self . read_exact ( len ) ) ) ;
290+ let mut rdr = LimitReader :: new ( self . by_ref ( ) , len ) ;
290291
291292 let ret = match ident {
292293 b'1' => ParseComplete ,
293294 b'2' => BindComplete ,
294295 b'3' => CloseComplete ,
295296 b'A' => NotificationResponse {
296- pid : try!( buf . read_be_u32 ( ) ) ,
297- channel : try!( buf . read_cstr ( ) ) ,
298- payload : try!( buf . read_cstr ( ) )
297+ pid : try!( rdr . read_be_u32 ( ) ) ,
298+ channel : try!( rdr . read_cstr ( ) ) ,
299+ payload : try!( rdr . read_cstr ( ) )
299300 } ,
300- b'C' => CommandComplete { tag : try!( buf . read_cstr ( ) ) } ,
301- b'D' => try!( read_data_row ( & mut buf ) ) ,
302- b'E' => ErrorResponse { fields : try!( read_fields ( & mut buf ) ) } ,
301+ b'C' => CommandComplete { tag : try!( rdr . read_cstr ( ) ) } ,
302+ b'D' => try!( read_data_row ( & mut rdr ) ) ,
303+ b'E' => ErrorResponse { fields : try!( read_fields ( & mut rdr ) ) } ,
303304 b'G' => {
304- let format = try!( buf . read_u8 ( ) ) ;
305+ let format = try!( rdr . read_u8 ( ) ) ;
305306 let mut column_formats = vec ! [ ] ;
306- for _ in range ( 0 , try!( buf . read_be_u16 ( ) ) ) {
307- column_formats. push ( try!( buf . read_be_u16 ( ) ) ) ;
307+ for _ in range ( 0 , try!( rdr . read_be_u16 ( ) ) ) {
308+ column_formats. push ( try!( rdr . read_be_u16 ( ) ) ) ;
308309 }
309310 CopyInResponse {
310311 format : format,
@@ -313,31 +314,38 @@ impl<R: Reader+Timeout> ReadMessage for R {
313314 }
314315 b'I' => EmptyQueryResponse ,
315316 b'K' => BackendKeyData {
316- process_id : try!( buf . read_be_u32 ( ) ) ,
317- secret_key : try!( buf . read_be_u32 ( ) )
317+ process_id : try!( rdr . read_be_u32 ( ) ) ,
318+ secret_key : try!( rdr . read_be_u32 ( ) )
318319 } ,
319320 b'n' => NoData ,
320- b'N' => NoticeResponse { fields : try!( read_fields ( & mut buf ) ) } ,
321- b'R' => try!( read_auth_message ( & mut buf ) ) ,
321+ b'N' => NoticeResponse { fields : try!( read_fields ( & mut rdr ) ) } ,
322+ b'R' => try!( read_auth_message ( & mut rdr ) ) ,
322323 b's' => PortalSuspended ,
323324 b'S' => ParameterStatus {
324- parameter : try!( buf . read_cstr ( ) ) ,
325- value : try!( buf . read_cstr ( ) )
325+ parameter : try!( rdr . read_cstr ( ) ) ,
326+ value : try!( rdr . read_cstr ( ) )
326327 } ,
327- b't' => try!( read_parameter_description ( & mut buf ) ) ,
328- b'T' => try!( read_row_description ( & mut buf ) ) ,
329- b'Z' => ReadyForQuery { _state : try!( buf . read_u8 ( ) ) } ,
328+ b't' => try!( read_parameter_description ( & mut rdr ) ) ,
329+ b'T' => try!( read_row_description ( & mut rdr ) ) ,
330+ b'Z' => ReadyForQuery { _state : try!( rdr . read_u8 ( ) ) } ,
330331 ident => return Err ( IoError {
331332 kind : OtherIoError ,
332333 desc : "Unexpected message tag" ,
333334 detail : Some ( format ! ( "got {}" , ident) ) ,
334335 } )
335336 } ;
337+ if rdr. limit ( ) != 0 {
338+ return Err ( IoError {
339+ kind : OtherIoError ,
340+ desc : "didn't read entire message" ,
341+ detail : None ,
342+ } ) ;
343+ }
336344 Ok ( ret)
337345 }
338346}
339347
340- fn read_fields ( buf : & mut MemReader ) -> IoResult < Vec < ( u8 , String ) > > {
348+ fn read_fields < R : Buffer > ( buf : & mut R ) -> IoResult < Vec < ( u8 , String ) > > {
341349 let mut fields = vec ! [ ] ;
342350 loop {
343351 let ty = try!( buf. read_u8 ( ) ) ;
@@ -351,7 +359,7 @@ fn read_fields(buf: &mut MemReader) -> IoResult<Vec<(u8, String)>> {
351359 Ok ( fields)
352360}
353361
354- fn read_data_row ( buf : & mut MemReader ) -> IoResult < BackendMessage > {
362+ fn read_data_row < R : Buffer > ( buf : & mut R ) -> IoResult < BackendMessage > {
355363 let len = try!( buf. read_be_i16 ( ) ) as uint ;
356364 let mut values = Vec :: with_capacity ( len) ;
357365
@@ -366,7 +374,7 @@ fn read_data_row(buf: &mut MemReader) -> IoResult<BackendMessage> {
366374 Ok ( DataRow { row : values } )
367375}
368376
369- fn read_auth_message ( buf : & mut MemReader ) -> IoResult < BackendMessage > {
377+ fn read_auth_message < R : Buffer > ( buf : & mut R ) -> IoResult < BackendMessage > {
370378 Ok ( match try!( buf. read_be_i32 ( ) ) {
371379 0 => AuthenticationOk ,
372380 2 => AuthenticationKerberosV5 ,
@@ -387,7 +395,7 @@ fn read_auth_message(buf: &mut MemReader) -> IoResult<BackendMessage> {
387395 } )
388396}
389397
390- fn read_parameter_description ( buf : & mut MemReader ) -> IoResult < BackendMessage > {
398+ fn read_parameter_description < R : Buffer > ( buf : & mut R ) -> IoResult < BackendMessage > {
391399 let len = try!( buf. read_be_i16 ( ) ) as uint ;
392400 let mut types = Vec :: with_capacity ( len) ;
393401
@@ -398,7 +406,7 @@ fn read_parameter_description(buf: &mut MemReader) -> IoResult<BackendMessage> {
398406 Ok ( ParameterDescription { types : types } )
399407}
400408
401- fn read_row_description ( buf : & mut MemReader ) -> IoResult < BackendMessage > {
409+ fn read_row_description < R : Buffer > ( buf : & mut R ) -> IoResult < BackendMessage > {
402410 let len = try!( buf. read_be_i16 ( ) ) as uint ;
403411 let mut types = Vec :: with_capacity ( len) ;
404412
0 commit comments