/* marshaling-burffer.c -- Marshaling Buffer library. Created on: 2008/11/28 11:45:58 ~yas/dsys/highscore/tcp/marshaling-burffer.c */ #include /* fprintf(), stderr */ #include /* malloc() */ #include /* htonl(), htons() */ #include /* memcpy() */ #include "marshaling-burffer.h" int marbuf_init( marbuf_t *mb, size_t buflen ) { if( (mb->mb_buf = malloc(buflen)) == NULL ) { return( 0 ); } mb->mb_buflen = buflen; mb->mb_bytes = 0; mb->mb_current = mb->mb_buf; } void marbuf_final( marbuf_t *mb ) { free( mb->mb_buf ); mb->mb_buf = 0; mb->mb_buflen = 0; mb->mb_bytes = 0; mb->mb_current = 0; } int marbuf_receive_message( marbuf_t *mb, int socket ) { uint32_t msglen, msglen_net ; if( read(socket,&msglen_net,sizeof(msglen_net)) != sizeof(msglen_net) ) { perror("read"); return( -1 ); } msglen = ntohl( msglen_net ); if( msglen > mb->mb_buflen ) { fprintf(stderr,"message too large %d > %d\n", msglen, mb->mb_buflen ); return( -1 ); } if( read(socket,mb->mb_buf,msglen) != msglen ) { perror("read"); return( -1 ); } mb->mb_bytes = msglen; mb->mb_current = mb->mb_buf; return( msglen ); } int marbuf_send_message( marbuf_t *mb, int socket ) { uint32_t msglen, msglen_net ; msglen = mb->mb_bytes; msglen_net = htonl(msglen); if( write(socket,&msglen_net,sizeof(msglen_net)) != sizeof(msglen_net) ) { perror("write"); return( -1 ); } if( write(socket,mb->mb_buf,msglen) != msglen ) { perror("read"); return( -1 ); } mb->mb_bytes = 0; mb->mb_current = mb->mb_buf; return( msglen ); } int marbuf_marshal_int( marbuf_t *mb, int data ) { uint32_t data_net ; if( mb->mb_bytes + sizeof(data_net) > mb->mb_buflen ) return( 0 ); data_net = htonl( data ); memcpy( mb->mb_current, &data_net, sizeof(data_net) ); mb->mb_current += sizeof(data_net); mb->mb_bytes += sizeof(data_net); return( 1 ); } int marbuf_unmarshal_int( marbuf_t *mb, int *datap ) { uint32_t data_net ; if( mb->mb_bytes + sizeof(data_net) > mb->mb_buflen ) return( 0 ); memcpy( &data_net, mb->mb_current, sizeof(data_net) ); *datap = ntohl( data_net ); mb->mb_current += sizeof(data_net); mb->mb_bytes += sizeof(data_net); return( 1 ); } int marbuf_marshal_byte_array( marbuf_t *mb, char data[], int data_len ) { if( mb->mb_bytes + data_len > mb->mb_buflen ) return( 0 ); memcpy( mb->mb_current, data, data_len ); mb->mb_current += data_len; mb->mb_bytes += data_len; return( 1 ); } int marbuf_unmarshal_byte_array( marbuf_t *mb, char data[], int data_len ) { if( mb->mb_bytes + data_len > mb->mb_buflen ) return( 0 ); memcpy( data, mb->mb_current, data_len ); mb->mb_current += data_len; mb->mb_bytes += data_len; return( 1 ); }