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;
}
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