[util] Add big-endian long msg read/write

And improve the generated code as well (ie, use a code sequence that gcc
recognizes and optimizes to a single 32-bit read and a byte-swap).

nq uses big-endian for its packet headers (arg, though it is consistent
with IP, it's not with the rest of quake).
This commit is contained in:
Bill Currie 2021-04-04 14:47:58 +09:00
parent 59e5592fed
commit afd7b38551
2 changed files with 50 additions and 4 deletions

View file

@ -37,6 +37,7 @@
void MSG_WriteByte (sizebuf_t *sb, int c);
void MSG_WriteShort (sizebuf_t *sb, int c);
void MSG_WriteLong (sizebuf_t *sb, int c);
void MSG_WriteLongBE (sizebuf_t *sb, int c);
void MSG_WriteFloat (sizebuf_t *sb, float f);
void MSG_WriteString (sizebuf_t *sb, const char *s);
void MSG_WriteBytes (sizebuf_t *sb, const void *buf, int len);
@ -108,6 +109,19 @@ int MSG_ReadShort (qmsg_t *msg);
*/
int MSG_ReadLong (qmsg_t *msg);
/** Read a single big-endian long from the message.
Advances the read index.
\param msg The message from which the long will be read.
\return The signed long value or -1 if already at the end of
the message.
\note -1 may be either an error or a value. Check qmsg_t::badread to
differentiate the two cases (false for a value).
\todo Fix?
*/
int MSG_ReadLongBE (qmsg_t *msg);
/** Read a single little-endian float from the message.
Advances the read index.

View file

@ -80,6 +80,18 @@ MSG_WriteLong (sizebuf_t *sb, int c)
*buf = ((unsigned int) c) >> 24;
}
VISIBLE void
MSG_WriteLongBE (sizebuf_t *sb, int c)
{
byte *buf;
buf = SZ_GetSpace (sb, 4);
*buf++ = ((unsigned int) c) >> 24;
*buf++ = (((unsigned int) c) >> 16) & 0xff;
*buf++ = (((unsigned int) c) >> 8) & 0xff;
*buf = ((unsigned int) c) & 0xff;
}
VISIBLE void
MSG_WriteFloat (sizebuf_t *sb, float f)
{
@ -269,10 +281,30 @@ MSG_ReadLong (qmsg_t *msg)
int c;
if (msg->readcount + 4 <= msg->message->cursize) {
c = msg->message->data[msg->readcount]
+ (msg->message->data[msg->readcount + 1] << 8)
+ (msg->message->data[msg->readcount + 2] << 16)
+ (msg->message->data[msg->readcount + 3] << 24);
byte *buf = msg->message->data + msg->readcount;
c = *buf++;
c |= (*buf++) << 8;
c |= (*buf++) << 16;
c |= (*buf) << 24;
msg->readcount += 4;
return c;
}
msg->readcount = msg->message->cursize;
msg->badread = true;
return -1;
}
VISIBLE int
MSG_ReadLongBE (qmsg_t *msg)
{
int c;
if (msg->readcount + 4 <= msg->message->cursize) {
byte *buf = msg->message->data + msg->readcount;
c = (*buf++) << 24;
c |= (*buf++) << 16;
c |= (*buf++) << 8;
c |= *buf;
msg->readcount += 4;
return c;
}