@@ -317,12 +317,12 @@ static int skip_frame(struct tws_ctx *ctx, uint64_t frame_size)
317317 * @param buff Buffer pointer.
318318 * @param buff_size Buffer size.
319319 * @param frm_type Frame type received.
320+ * @param err Output error code: set to a negative value on error, 0 on success.
320321 *
321- * @return Returns frame length if success, a negative number
322- * otherwise.
322+ * @return Returns frame length if success, 0 on error (check @p err).
323323 */
324- int tws_receiveframe (struct tws_ctx * ctx , char * * buff ,
325- size_t * buff_size , int * frm_type )
324+ uint64_t tws_receiveframe (struct tws_ctx * ctx , char * * buff ,
325+ size_t * buff_size , int * frm_type , int * err )
326326{
327327 int ret ;
328328 char * buf ;
@@ -331,9 +331,14 @@ int tws_receiveframe(struct tws_ctx *ctx, char **buff,
331331 uint8_t opcode ;
332332 uint64_t frame_length ;
333333
334+ if (err )
335+ * err = 0 ;
336+
334337 /* Buffer should be valid. */
335- if (!buff || (* buff && !buff_size ))
336- return (-1 );
338+ if (!buff || (* buff && !buff_size )) {
339+ if (err ) * err = -1 ;
340+ return (0 );
341+ }
337342
338343 ret = 0 ;
339344 cur_byte = next_byte (ctx , & ret );
@@ -343,7 +348,8 @@ int tws_receiveframe(struct tws_ctx *ctx, char **buff,
343348 if (opcode == FRM_CLSE )
344349 {
345350 tws_close (ctx );
346- return (-1 );
351+ if (err ) * err = -1 ;
352+ return (0 );
347353 }
348354
349355 frame_length = next_byte (ctx , & ret ) & 0x7F ;
@@ -369,23 +375,29 @@ int tws_receiveframe(struct tws_ctx *ctx, char **buff,
369375 }
370376
371377 /* Check if any error before proceed. */
372- if (ret )
373- return (ret );
378+ if (ret ) {
379+ if (err ) * err = ret ;
380+ return (0 );
381+ }
374382
375383 /*
376384 * If frame is something other than CLSE and TXT/BIN (like PONG
377385 * or CONT), skip.
378386 */
379387 if (opcode != FRM_TXT && opcode != FRM_BIN )
380- if (skip_frame (ctx , frame_length ) < 0 )
381- return (-1 );
388+ if (skip_frame (ctx , frame_length ) < 0 ) {
389+ if (err ) * err = -1 ;
390+ return (0 );
391+ }
382392
383- /* Allocate memory, if needed. */
384- if (* buff_size < frame_length )
393+ /* Allocate memory, if needed (+1 for null terminator, covers 0-length frames) . */
394+ if (* buff_size < frame_length + 1 )
385395 {
386396 buf = realloc (* buff , frame_length + 1 );
387- if (!buf )
388- return (-1 );
397+ if (!buf ) {
398+ if (err ) * err = -1 ;
399+ return (0 );
400+ }
389401 * buff = buf ;
390402 * buff_size = frame_length + 1 ;
391403 }
@@ -396,8 +408,10 @@ int tws_receiveframe(struct tws_ctx *ctx, char **buff,
396408 for (i = 0 ; i < frame_length ; i ++ , buf ++ )
397409 {
398410 cur_byte = next_byte (ctx , & ret );
399- if (cur_byte < 0 )
400- return (ret == 0 ? frame_length : ret );
411+ if (cur_byte < 0 ) {
412+ if (err ) * err = ret ;
413+ return (ret == 0 ? frame_length : 0 );
414+ }
401415
402416 * buf = cur_byte ;
403417 }
@@ -406,5 +420,6 @@ int tws_receiveframe(struct tws_ctx *ctx, char **buff,
406420 /* Fill other infos. */
407421 * frm_type = opcode ;
408422
409- return (ret == 0 ? frame_length : ret );
423+ if (err ) * err = ret ;
424+ return (ret == 0 ? frame_length : 0 );
410425}
0 commit comments