From 63d787d9e963969ff42811c2f61dbd78dc1c3a9c Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 5 May 2005 00:27:04 +0000 Subject: [PATCH] add MSG_WriteUTF8 and MSG_ReadUTF8 to handle 31 bit values nicely for future protocol extensions. Equivalent to MSG_*Byte or MSG_*Char. Use MSG_ReadString and MSG_WriteString with the appropriate libc functions for utf8 strings. --- include/QF/msg.h | 2 ++ libs/util/msg.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) diff --git a/include/QF/msg.h b/include/QF/msg.h index b43181334..167fd89c3 100644 --- a/include/QF/msg.h +++ b/include/QF/msg.h @@ -49,6 +49,7 @@ void MSG_WriteCoordAngleV (sizebuf_t *sb, const vec3_t coord, void MSG_WriteAngle (sizebuf_t *sb, float angle); void MSG_WriteAngleV (sizebuf_t *sb, const vec3_t angles); void MSG_WriteAngle16 (sizebuf_t *sb, float angle16); +void MSG_WriteUTF8 (sizebuf_t *sb, unsigned utf8); typedef struct msg_s { int readcount; @@ -73,6 +74,7 @@ float MSG_ReadAngle (qmsg_t *msg); void MSG_ReadCoordAngleV (qmsg_t *msg, vec3_t coord, vec3_t angles); void MSG_ReadAngleV (qmsg_t *msg, vec3_t angles); float MSG_ReadAngle16 (qmsg_t *msg); +int MSG_ReadUTF8 (qmsg_t *msg); //@} //@} diff --git a/libs/util/msg.c b/libs/util/msg.c index 83e0f1d81..5a7b4a1b9 100644 --- a/libs/util/msg.c +++ b/libs/util/msg.c @@ -165,6 +165,45 @@ MSG_WriteAngle16 (sizebuf_t *sb, float angle16) MSG_WriteShort (sb, (int) (angle16 * (65536.0 / 360.0)) & 65535); } +void +MSG_WriteUTF8 (sizebuf_t *sb, unsigned utf8) +{ + byte *buf; + int count; + + if (utf8 & 0x80000000) { + return; // invalid (FIXME die?) + } else if (utf8 & 0x7c000000) { + buf = SZ_GetSpace (sb, count = 6); + *buf = 0xfc | ((utf8 & 0x40000000) >> 30); // 1 bit + utf8 <<= 2; + } else if (utf8 & 0x03e00000) { + buf = SZ_GetSpace (sb, count = 5); + *buf = 0xf8 | ((utf8 & 0x30000000) >> 28); // 2 bits + utf8 <<= 4; + } else if (utf8 & 0x001f0000) { + buf = SZ_GetSpace (sb, count = 4); + *buf = 0xf0 | ((utf8 & 0x001c0000) >> 18); // 3 bits + utf8 <<= 14; + } else if (utf8 & 0x0000f800) { + buf = SZ_GetSpace (sb, count = 3); + *buf = 0xe0 | ((utf8 & 0x0000f000) >> 12); // 4 bits + utf8 <<= 20; + } else if (utf8 & 0x00000780) { + buf = SZ_GetSpace (sb, count = 2); + *buf = 0xc0 | ((utf8 & 0x00000780) >> 7); // 5 bits + utf8 <<= 25; + } else { + buf = SZ_GetSpace (sb, count = 1); + *buf = utf8; + return; + } + while (--count) { + *buf++ = 0x80 | ((utf8 & 0xfc000000) >> 26); + utf8 <<= 6; + } +} + // reading functions ========================================================== void @@ -343,3 +382,58 @@ MSG_ReadAngle16 (qmsg_t *msg) { return MSG_ReadShort (msg) * (360.0 / 65536.0); } + +int +MSG_ReadUTF8 (qmsg_t *msg) +{ + byte *buf, *start, c; + int val = 0, count; + + if (msg->badread || msg->message->cursize == msg->readcount) { + msg->badread = true; + return -1; + } + buf = start = msg->message->data + msg->readcount; + + c = *buf++; + if (c < 0x80) { + val = c; + count = 1; + } else if (c < 0xc0) { + msg->badread = true; + return -1; + } else if (c < 0xe0) { + count = 2; + val = c & 0x1f; + } else if (c < 0xf0) { + count = 3; + val = c & 0x0f; + } else if (c < 0xf8) { + count = 4; + val = c & 0x07; + } else if (c < 0xfc) { + count = 5; + val = c & 0x03; + } else if (c < 0xfe) { + count = 6; + val = c & 0x01; + } else { + msg->badread = true; + return -1; + } + if (count > (msg->message->cursize - msg->readcount)) { + msg->badread = true; + return -1; + } + while (--count) { + c = *buf++; + if ((c & 0xc0) != 0x80) { + msg->badread = true; + return -1; + } + val <<= 6; + val |= c & 0x3f; + } + msg->readcount += buf - start; + return val; +}