1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-14 09:24:57 +00:00

LibC: Manually count stored bytes in mbstate_t

This is probably a bit faster than constantly having to look through all
stored bytes. It also helps when we are trying to store actual null
bytes.
This commit is contained in:
Tim Schumacher 2021-09-19 13:31:16 +02:00 committed by Brian Gianforcaro
parent 3c807402b3
commit 06f30943ef
2 changed files with 12 additions and 23 deletions

View file

@ -9,19 +9,12 @@
#include <errno.h>
#include <wchar.h>
static unsigned int mbstate_stored_bytes(mbstate_t* state)
{
for (unsigned int i = 0; i < sizeof(state->bytes); i++) {
if (!state->bytes[i]) {
return i;
}
}
return sizeof(state->bytes);
}
static unsigned int mbstate_expected_bytes(mbstate_t* state)
{
if (state->stored_bytes == 0) {
return 0;
}
unsigned char first = state->bytes[0];
// Single-byte sequences have their first bit unset
@ -218,7 +211,7 @@ size_t mbrtowc(wchar_t* pwc, const char* s, size_t n, mbstate_t* state)
// If s is nullptr, check if the state contains a complete multibyte character
if (s == nullptr) {
if (mbstate_expected_bytes(state) == mbstate_stored_bytes(state)) {
if (mbstate_expected_bytes(state) == mbstate->stored_bytes) {
*state = {};
return 0;
} else {
@ -234,11 +227,10 @@ size_t mbrtowc(wchar_t* pwc, const char* s, size_t n, mbstate_t* state)
}
size_t consumed_bytes = 0;
size_t stored_bytes = mbstate_stored_bytes(state);
// Fill the first byte if we haven't done that yet
if (state->bytes[0] == 0) {
state->bytes[0] = s[0];
if (state->stored_bytes == 0) {
state->bytes[state->stored_bytes++] = s[0];
consumed_bytes++;
}
@ -251,9 +243,7 @@ size_t mbrtowc(wchar_t* pwc, const char* s, size_t n, mbstate_t* state)
return -1;
}
size_t needed_bytes = expected_bytes - stored_bytes;
while (consumed_bytes < needed_bytes) {
while (state->stored_bytes < expected_bytes) {
if (consumed_bytes == n) {
// No complete multibyte character
return -2;
@ -269,7 +259,7 @@ size_t mbrtowc(wchar_t* pwc, const char* s, size_t n, mbstate_t* state)
return -1;
}
state->bytes[mbstate_stored_bytes(state)] = c;
state->bytes[state->stored_bytes++] = c;
consumed_bytes++;
}
@ -331,10 +321,8 @@ int mbsinit(const mbstate_t* state)
return 1;
}
for (unsigned char byte : state->bytes) {
if (byte) {
return 0;
}
if (state->stored_bytes != 0) {
return 0;
}
return 1;

View file

@ -21,6 +21,7 @@ typedef unsigned long int wctype_t;
// A zero-initialized mbstate_t struct must be a valid initial state.
typedef struct {
unsigned char bytes[4];
unsigned int stored_bytes;
} mbstate_t;
size_t wcslen(const wchar_t*);