소스 검색

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.
Tim Schumacher 3 년 전
부모
커밋
06f30943ef
2개의 변경된 파일11개의 추가작업 그리고 22개의 파일을 삭제
  1. 10 22
      Userland/Libraries/LibC/wchar.cpp
  2. 1 0
      Userland/Libraries/LibC/wchar.h

+ 10 - 22
Userland/Libraries/LibC/wchar.cpp

@@ -9,19 +9,12 @@
 #include <errno.h>
 #include <wchar.h>
 
-static unsigned int mbstate_stored_bytes(mbstate_t* state)
+static unsigned int mbstate_expected_bytes(mbstate_t* state)
 {
-    for (unsigned int i = 0; i < sizeof(state->bytes); i++) {
-        if (!state->bytes[i]) {
-            return i;
-        }
+    if (state->stored_bytes == 0) {
+        return 0;
     }
 
-    return sizeof(state->bytes);
-}
-
-static unsigned int mbstate_expected_bytes(mbstate_t* state)
-{
     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;

+ 1 - 0
Userland/Libraries/LibC/wchar.h

@@ -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*);