[util] Add leb123 signed and unsigned message readers

Needed for parsing dwarf eh_frame data, but I'm sure it will come in
handy for other things.
This commit is contained in:
Bill Currie 2023-12-01 02:55:08 +09:00
parent da9e5d9ff3
commit 52210b8c55
2 changed files with 43 additions and 0 deletions

View file

@ -279,6 +279,9 @@ void MSG_ReadAngle16V (qmsg_t *msg, vec3_t angles);
*/ */
int MSG_ReadUTF8 (qmsg_t *msg); int MSG_ReadUTF8 (qmsg_t *msg);
uint64_t MSG_ReadUleb128 (qmsg_t *msg);
int64_t MSG_ReadSleb128 (qmsg_t *msg);
///@} ///@}
#endif//__QF_msg_h #endif//__QF_msg_h

View file

@ -589,3 +589,43 @@ MSG_ReadUTF8 (qmsg_t *msg)
msg->readcount += buf - start; msg->readcount += buf - start;
return val; return val;
} }
VISIBLE uint64_t
MSG_ReadUleb128 (qmsg_t *msg)
{
if (msg->badread || msg->message->cursize == msg->readcount) {
msg->badread = true;
return -1;
}
uintptr_t res = 0;
unsigned shift = 0;
byte b;
do {
b = MSG_ReadByte (msg);
res |= ((uintptr_t) b & 0x7f) << shift;
shift += 7;
} while (b & 0x80 && !msg->badread);
return res;
}
VISIBLE int64_t
MSG_ReadSleb128 (qmsg_t *msg)
{
if (msg->badread || msg->message->cursize == msg->readcount) {
msg->badread = true;
return -1;
}
intptr_t res = 0;
unsigned shift = 0;
byte b;
do {
b = MSG_ReadByte (msg);
res |= ((intptr_t) b & 0x7f) << shift;
shift += 7;
} while (b & 0x80 && !msg->badread);
constexpr unsigned bits = 8 * sizeof (res);
if (shift < bits) {
res = (res << (bits - shift)) >> (bits - shift);
}
return res;
}