From 4d00367a631bdcb5b5fd7166cdd277a8d53a9a72 Mon Sep 17 00:00:00 2001 From: bones_was_here Date: Thu, 18 Jan 2024 07:08:16 +1000 Subject: [PATCH] com_msg: optimise string and byte sequence reading Signed-off-by: bones_was_here --- com_msg.c | 30 ++++++++++++++++-------------- common.h | 4 +++- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/com_msg.c b/com_msg.c index fe29579e..aaded00d 100644 --- a/com_msg.c +++ b/com_msg.c @@ -340,32 +340,34 @@ float MSG_ReadBigFloat (sizebuf_t *sb) char *MSG_ReadString (sizebuf_t *sb, char *string, size_t maxstring) { - int c; size_t l = 0; + // read string into sbfer, but only store as many characters as will fit - while ((c = MSG_ReadByte(sb)) > 0) - if (l < maxstring - 1) - string[l++] = c; - string[l] = '\0'; + // if dest buffer is full sb->readcount will still be advanced to end of message string + while ((string[l] = MSG_ReadByte_opt(sb)) != '\0') + if (l < maxstring) + ++l; return string; } size_t MSG_ReadString_len (sizebuf_t *sb, char *string, size_t maxstring) { - int c; size_t l = 0; + // read string into sbfer, but only store as many characters as will fit - while ((c = MSG_ReadByte(sb)) > 0) - if (l < maxstring - 1) - string[l++] = c; - string[l] = '\0'; + // if dest buffer is full sb->readcount will still be advanced to end of message string + while ((string[l] = MSG_ReadByte_opt(sb)) != '\0') + if (l < maxstring) + ++l; return l; } -int MSG_ReadBytes (sizebuf_t *sb, int numbytes, unsigned char *out) +size_t MSG_ReadBytes (sizebuf_t *sb, size_t numbytes, unsigned char *out) { - int l, c; - for (l = 0;l < numbytes && (c = MSG_ReadByte(sb)) != -1;l++) - out[l] = c; + size_t l = 0; + + // when numbytes have been read sb->readcount won't be advanced any further + while (l < numbytes && !sb->badread) + out[l++] = MSG_ReadByte_opt(sb); return l; } diff --git a/common.h b/common.h index e85f43eb..641ed105 100644 --- a/common.h +++ b/common.h @@ -182,10 +182,12 @@ float MSG_ReadBigFloat (sizebuf_t *sb); char *MSG_ReadString (sizebuf_t *sb, char *string, size_t maxstring); /// Same as MSG_ReadString except it returns the number of bytes written to *string excluding the \0 terminator. size_t MSG_ReadString_len (sizebuf_t *sb, char *string, size_t maxstring); -int MSG_ReadBytes (sizebuf_t *sb, int numbytes, unsigned char *out); +size_t MSG_ReadBytes (sizebuf_t *sb, size_t numbytes, unsigned char *out); #define MSG_ReadChar(sb) ((sb)->readcount >= (sb)->cursize ? ((sb)->badread = true, -1) : (signed char)(sb)->data[(sb)->readcount++]) #define MSG_ReadByte(sb) ((sb)->readcount >= (sb)->cursize ? ((sb)->badread = true, -1) : (unsigned char)(sb)->data[(sb)->readcount++]) +/// Same as MSG_ReadByte but with no need to copy twice (first to `int` to check for -1) so each byte can be copied directly to a string[] +#define MSG_ReadByte_opt(sb) ((sb)->readcount >= (sb)->cursize ? ((sb)->badread = true, '\0') : (unsigned char)(sb)->data[(sb)->readcount++]) #define MSG_ReadShort MSG_ReadLittleShort #define MSG_ReadLong MSG_ReadLittleLong #define MSG_ReadFloat MSG_ReadLittleFloat -- 2.39.2