📄 win32codingsystem.cxx
字号:
// Copyright (c) 1996 James Clark// See the file COPYING for copying permission.#ifdef __GNUG__#pragma implementation#endif#include "splib.h"#ifdef SP_MULTI_BYTE#include <windows.h>#include <io.h>#include "Win32CodingSystem.h"#include "Boolean.h"#include "macros.h"#ifdef SP_NAMESPACEnamespace SP_NAMESPACE {#endifclass SingleByteWin32Decoder : public Decoder {public: SingleByteWin32Decoder(unsigned int codePage, Char defaultChar); size_t decode(Char *to, const char *from, size_t fromLen, const char **rest); Boolean convertOffset(unsigned long &offset) const;private: Char map_[256];};class MultiByteWin32Decoder : public Decoder {public: MultiByteWin32Decoder(unsigned int codePage, Char defaultChar, unsigned char *leadByte); size_t decode(Char *to, const char *from, size_t fromLen, const char **rest);private: unsigned int codePage_; Char defaultChar_; PackedBoolean isLeadByte_[256];};class Win32Encoder : public Encoder {public: Win32Encoder(unsigned int codePage); ~Win32Encoder(); void output(const Char *, size_t, OutputByteStream *);private: char *buf_; size_t bufLen_; unsigned int codePage_;};Win32CodingSystem::Win32CodingSystem(unsigned int codePage, Char defaultChar): codePage_(codePage), defaultChar_(defaultChar){}Win32CodingSystem::Win32CodingSystem(SpecialCodePage codePage, Char defaultChar): defaultChar_(defaultChar){ if (codePage == codePageAnsi) codePage_ = GetACP(); else codePage_ = GetOEMCP();}Boolean Win32CodingSystem::isValid() const{ return IsValidCodePage(codePage_);}Encoder *Win32CodingSystem::makeEncoder() const{ return new Win32Encoder(codePage_);}Decoder *Win32CodingSystem::makeDecoder() const{ CPINFO info; if (GetCPInfo(codePage_, &info) && info.MaxCharSize > 1) return new MultiByteWin32Decoder(codePage_, defaultChar_, info.LeadByte); else return new SingleByteWin32Decoder(codePage_, defaultChar_);}SingleByteWin32Decoder::SingleByteWin32Decoder(unsigned int codePage, Char defaultChar){ for (int i = 0; i < 256; i++) { char c = i; if (MultiByteToWideChar(codePage, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, &c, 1, map_ + i, 1) == 0) map_[i] = defaultChar; }}size_t SingleByteWin32Decoder::decode(Char *to, const char *from, size_t fromLen, const char **rest){ for (size_t n = fromLen; n > 0; n--) *to++ = map_[(unsigned char)*from++]; // zero extend *rest = from; return fromLen;}Boolean SingleByteWin32Decoder::convertOffset(unsigned long &) const{ return 1;}MultiByteWin32Decoder::MultiByteWin32Decoder(unsigned int codePage, Char defaultChar, unsigned char *leadByte): defaultChar_(defaultChar), codePage_(codePage){ for (int i = 0; i < 256; i++) isLeadByte_[i] = 0; for (int i = 0; i < MAX_LEADBYTES; i += 2) { if (leadByte[i] == 0 && leadByte[i + 1] == 0) break; int lim = leadByte[i + 1]; for (int j = leadByte[i]; j < lim; j++) isLeadByte_[j] = 1; }}size_t MultiByteWin32Decoder::decode(Char *to, const char *from, size_t fromLen, const char **rest){ size_t i; for (i = fromLen; i > 0; i--) if (!isLeadByte_[(unsigned char)from[i - 1]]) break; if ((fromLen - i) & 1) fromLen--; int count = MultiByteToWideChar(codePage_, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, from, fromLen, to, fromLen); if (count) { *rest = from + fromLen; return count; } Char *start = to; // Try it character by character. while (fromLen > 0) { int nBytes = 1 + isLeadByte_[(unsigned char)*from]; ASSERT(nBytes <= fromLen); if (MultiByteToWideChar(codePage_, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, from, nBytes, to, 1) != 1) *to = defaultChar_; from += nBytes; fromLen -= nBytes; to++; } *rest = from; return to - start;}Win32Encoder::Win32Encoder(unsigned int codePage): codePage_(codePage), buf_(0), bufLen_(0){}Win32Encoder::~Win32Encoder(){ delete [] buf_;}void Win32Encoder::output(const Char *s, size_t n, OutputByteStream *sb){ if (n == 0) return; if (n*2 > bufLen_) { delete [] buf_; bufLen_ = n*2; buf_ = new char[bufLen_]; } int nBytes = WideCharToMultiByte(codePage_, 0, s, n, buf_, bufLen_, 0, 0); if (nBytes) sb->sputn(buf_, nBytes);}#ifdef SP_NAMESPACE}#endif#else /* not SP_MULTI_BYTE */#ifndef __GNUG__static char non_empty_translation_unit; // sigh#endif#endif /* not SP_MULTI_BYTE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -