]> git.rm.cloudns.org Git - xonotic/darkplaces.git/commitdiff
com_msg: optimise string and byte sequence reading
authorbones_was_here <bones_was_here@xonotic.au>
Wed, 17 Jan 2024 21:08:16 +0000 (07:08 +1000)
committerbones_was_here <bones_was_here@xonotic.au>
Sun, 21 Jan 2024 11:08:46 +0000 (21:08 +1000)
Signed-off-by: bones_was_here <bones_was_here@xonotic.au>
com_msg.c
common.h

index fe29579ed07c3acc78f4a8fa8e537440b1492935..aaded00d3fc84d2699eeadb51d6d282e125509f4 100644 (file)
--- 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;
 }
 
index e85f43eb9ebd9dca8fc5631adacbe15d41d9f753..641ed1051cd3664dec0dcf52f6a26582fb4dd8ae 100644 (file)
--- 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