diff options
Diffstat (limited to 'Source/cm_codecvt.hxx')
-rw-r--r-- | Source/cm_codecvt.hxx | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/Source/cm_codecvt.hxx b/Source/cm_codecvt.hxx index b9b52ec..30c6d54 100644 --- a/Source/cm_codecvt.hxx +++ b/Source/cm_codecvt.hxx @@ -6,7 +6,6 @@ #include "cmConfigure.h" #include <locale> -#include <vector> #include <wchar.h> class codecvt : public std::codecvt<char, char, mbstate_t> @@ -35,21 +34,30 @@ protected: int do_encoding() const throw() CM_OVERRIDE; private: - typedef struct + // The mbstate_t argument to do_out and do_unshift is responsible + // for storing state between calls. We cannot control the type + // since we want to imbue on standard streams. However, we do + // know that it is a trivial type. Define our own type to overlay + // on it safely with no alignment requirements. + struct State { - bool used; - unsigned char totalBytes; - unsigned char bytesLeft; - char bytes[4]; - } State; + // Buffer bytes we have consumed from a partial codepoint. + char partial[3]; - unsigned int findStateId() const; + // Number of bytes we have buffered from a partial codepoint. + unsigned char buffered : 4; + + // Size of the current codepoint in bytes. + unsigned char size : 4; + }; bool m_noconv; - mutable std::vector<State> m_states; - mutable unsigned int m_lastState; #if defined(_WIN32) unsigned int m_codepage; + result Decode(mbstate_t& state, int need, const char*& from_next, + char*& to_next, char* to_end) const; + result DecodePartial(mbstate_t& state, char*& to_next, char* to_end) const; + void BufferPartial(mbstate_t& state, int need, const char*& from_next) const; #endif #endif |