/
trilirium
/
Archived_BLC
Обзор
Документация
Войти
/
trilirium
/
Archived_BLC
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
CharCodec.cpp
361 строка
8 KB
Trilirium
repo created OK
22 янв 2026, 16:43
22 янв 2026, 16:43
f05d14b
Код
Авторство
О чём код?
/* + === - === - === - === - === - === - === - === | | CharCodec.cpp | | (Abstract) character stream encoder/decoder interface | + === - === - === - === - === - === - === - === */ // (Abstract codec) struct A_CharCodec { // // Virtuals // // Abstract 'encoder' interface // Returns: number of octets, encoded to '_output' virtual unsigned encoder (char *_output, wchar_t *source_ptr, unsigned source_len) = 0; // Abstract 'decoder' interface // Returns: number of characters, decoded from '_input' virtual unsigned decoder (char const *_input, unsigned input_len, wchar_t *result_buf) = 0; // Get codec info virtual char const *infodef () = 0; // Clone codec virtual A_CharCodec *clone () = 0; // Release codec virtual void release (bool self) = 0; // // Methods // // // Encode source string // source_ptr[source_len] => (result) // char * encode_source (wchar_t *source_ptr, unsigned source_len, char const *_tag) { unsigned count = encoder (0, source_ptr, source_len); if (count) { char *_result = new (_tag) char [count + 1]; encoder (_result, source_ptr, source_len); _result [count] = '\0'; return _result; } return 0; } // encode_source // Encode count calculate unsigned encode_count (wchar_t *source_ptr, unsigned source_len) { return encoder (0, source_ptr, source_len); } // encode_count // // Decode result string // _input[input_len] => (result) // wchar_t * decode_input (char const *_input, unsigned input_len, char const *_tag, unsigned &total) { unsigned count = decoder (_input, input_len, 0); total = count; if (count) { wchar_t *_result = new (_tag) wchar_t [count + 1]; decoder (_input, input_len, _result); _result [count] = L'\0'; return _result; } return 0; } // decode_input // Decode count calculate unsigned decode_count (char const *_input, unsigned input_len) { return decoder (_input, input_len, 0); } // decode_count }; // A_CharCodec // // Char codec: UTF-16 // struct UTF16_Codec : A_CharCodec { bool endian; // big endian? UTF16_Codec (bool endian) { this->endian = endian; } // 'Encoder' interface // Returns: number of octets encoded to '_output' unsigned encoder (char *_output, wchar_t *source_ptr, unsigned source_len) { unsigned len = source_len; if (_output) { while (len --) { wchar_t code = *source_ptr ++; if (endian) { // (big-endian order) *_output ++ = code >> 8; *_output ++ = (char) code; } else { // (little-endian order) *_output ++ = (char) code; *_output ++ = code >> 8; } } // while (len) } // (_output) return len << 1; // (total octets encoded) } // encoder // 'Decoder' interface // Returns: number of characters decoded from '_input' unsigned decoder (char const *_input, unsigned input_len, wchar_t *result_buf) { unsigned len = input_len >> 1; if (result_buf) { while (len --) { wchar_t code; if (endian) { // (big-endian order) code = (unsigned) (*_input ++) << 8; code |= *_input ++ & 0xFF; } else { // (little-endian order) code = *_input ++ & 0xFF; code |= (unsigned) (*_input ++) << 8; } *result_buf ++ = code; } // while (len) } // (result_buf) return input_len >> 1; } // decoder // Clone codec A_CharCodec *clone () { return new ("UTF-16 codec") UTF16_Codec (endian); } // Get codec info char const *infodef () { return endian ? "UTF-16 +" : "UTF-16 -"; } // Release codec void release (bool self) { if (self) delete this; } }; // UTF16_Codec // // Char codec: UTF-8 // struct UTF8_Codec : A_CharCodec { UTF8_Codec () { } // 'Encoder' interface // Returns: number of octets encoded to '_output' unsigned encoder (char *_output, wchar_t *source_ptr, unsigned source_len) { unsigned len = source_len; char *_start = _output; while (len --) { unsigned cval = *source_ptr ++; unsigned shift; char head; if (cval < 0x80) // (1 octet) head = cval, shift = 0; else if (cval < 0x800) // (2 octets) head = ((cval >> (shift = 6))) | 0xc0; else if (cval < 0x10000) // (3 octets) head = ((cval >> (shift = 12))) | 0xe0; // (following useful only for > 16 bit codepoints!) else if (cval < 0x200000) // (4 octets) head = ((cval >> (shift = 18))) | 0xf0; else if (cval < 0x4000000) // (5 octets, not to happen really) head = ((cval >> (shift = 24))) | 0xf8; else if (cval < 0x80000000) // (6 octets, not to happen really) head = ((cval >> (shift = 30))) | 0xfc; else {} // (illegal?) if (_start) { *_output ++ = head; while (shift) *_output ++ = ((cval >> (shift -= 6)) & 0x3f) | 0x80; } else { _output ++; _output += shift / 6; } } // while (len) return _output - _start; } // encoder // 'Decoder' interface // Returns: number of characters decoded from '_input' unsigned decoder (char const *_input, unsigned input_len, wchar_t *result_buf) { wchar_t *_start = result_buf; while (input_len --) { unsigned cval = *_input ++; unsigned extra; if (! (cval & 0x80)) // (1 octet) extra = 0; else if (! (cval & 0x40)) { /* error to signal?? */ } else if (! (cval & 0x20)) // (2 octets) extra = 1, cval &= 0x1f; else if (! (cval & 0x10)) // (3 octets) extra = 2, cval &= 0x0f; else if (! (cval & 0x08)) // (4 octets) extra = 3, cval &= 0x07; else if (! (cval & 0x04)) // (5 octets, not to happen really) extra = 4, cval &= 0x03; else if (! (cval & 0x02)) // (6 octets, not to happen really) extra = 5, cval &= 0x01; // (safety check:) if (extra > input_len) break; input_len -= extra; while (extra --) { cval <<= 6; cval |= *_input ++ & 0x3f; // (check errors?) } if (_start) *result_buf ++ = cval; else result_buf ++; } // while (input_len) return result_buf - _start; } // decoder // Clone codec A_CharCodec *clone () { return new ("UTF-8 codec") UTF8_Codec (); } // Get codec info char const *infodef () { return "UTF-8"; } // Release codec void release (bool self) { if (self) delete this; } }; // UTF8_Codec // // Char codec: Zapper // struct Zapper_Codec : A_CharCodec { char zapch; Zapper_Codec (char zapch) { this->zapch = zapch; } // 'Encoder' interface // Returns: number of octets encoded to '_output' unsigned encoder (char *_output, wchar_t *source_ptr, unsigned source_len) { unsigned len = source_len; while (len --) { unsigned cval = *source_ptr ++; if (_output) *_output ++ = cval >= 0x80 ? zapch : cval; } return source_len; } // encoder // 'Decoder' interface // Returns: number of characters decoded from '_input' unsigned decoder (char const *_input, unsigned input_len, wchar_t *result_buf) { unsigned len = input_len; while (len --) { unsigned cval = *_input ++; if (result_buf) *result_buf ++ = cval; } return input_len; } // decoder // Clone codec A_CharCodec *clone () { return new ("Zapper codec") Zapper_Codec (zapch); } // Get codec info char const *infodef () { return "Zapper"; } // Release codec void release (bool self) { if (self) delete this; } }; // Zapper_Codec // // Wrapper character codec // struct Wrapper_Codec : A_CharCodec { A_CharCodec *_codec; // Constructor Wrapper_Codec (A_CharCodec *codec) { this->_codec = codec; } // // Virtuals // // 'Encoder' interface // Returns: number of octets encoded to '_output' unsigned encoder (char *_output, wchar_t *source_ptr, unsigned source_len) { return _codec->encoder (_output, source_ptr, source_len); } // 'Decoder' interface // Returns: number of characters, decoded from '_input' unsigned decoder (char const *_input, unsigned input_len, wchar_t *result_buf) { return _codec->decoder (_input, input_len, result_buf); } // Get codec info char const *infodef () { return _codec->infodef (); } // Release codec void release (bool self) { if (self) delete this; } }; // Wrapper_Codec