YSTest: NLS.cpp 源文件

YSTest PreAlpha_b700_20160611 The YSLib Test Project

- 首页
- 相关页面
- 模块
- 命名空间
- 类
- 文件

- 文件列表
- 文件成员

NLS.cpp
浏览该文件的文档.
1 /*
2 © 2014-2016 FrankHB.
3
4 This file is part of the YSLib project, and may only be used,
5 modified, and distributed under the terms of the YSLib project
6 license, LICENSE.TXT. By continuing to use, modify, or distribute
7 this file you indicate that you have read the license and
8 understand and accept it fully.
9 */
10
29 #include "YCLib/YModules.h"
30 #include YFM_YCLib_Platform
31 #if YCL_Win32
32 # include YFM_Win32_YCLib_NLS // for map;
33 # include YFM_Win32_YCLib_Registry // for FetchRegistryString;
34 # include <ystdex/base.h> // for ystdex::noncopyable, ystdex::nonmovable;
35 # include YFM_YCLib_MemoryMapping // for platform::MappedFile;
36 # include <ystdex/algorithm.hpp> // for ystdex::trivially_copy_n;
37 # include <ystdex/container.hpp> // for ystdex::try_emplace;
38
39 using namespace YSLib;
40 using namespace Drawing;
41 #endif
42
43 namespace platform_ex
44 {
45
46 #if YCL_Win32
47
48 inline namespace Windows
49 {
50
52 YB_NONNULL(1) std::wstring
53 FetchNLSItemFromRegistry(const wchar_t* name)
54 {
55 return FetchRegistryString(HKEY_LOCAL_MACHINE,
56 L"System\\CurrentControlSet\\Control\\Nls\\CodePage", name);
57 }
58
59
61 namespace
62 {
63
64 yconstexpr const size_t MAXIMUM_LEADBYTES(12);
65
66 struct NLS_FILE_HEADER
67 {
68 unsigned short HeaderSize;
69 unsigned short CodePage;
70 unsigned short MaximumCharacterSize;
71 unsigned short DefaultChar;
72 unsigned short UniDefaultChar;
73 unsigned short TransDefaultChar;
74 unsigned short TransUniDefaultChar;
75 byte LeadByte[MAXIMUM_LEADBYTES];
76 };
77
78 struct CPTABLEINFO
79 {
80 unsigned short CodePage;
81 unsigned short MaximumCharacterSize;
82 unsigned short DefaultChar;
83 unsigned short UniDefaultChar;
84 unsigned short TransDefaultChar;
85 unsigned short TransUniDefaultChar;
86 unsigned short DBCSCodePage;
87 byte LeadByte[MAXIMUM_LEADBYTES];
88 unsigned short* MultiByteTable;
89 void* WideCharTable;
90 unsigned short* DBCSRanges;
91 unsigned short* DBCSOffsets;
92 };
93
94
95 class NLSTableEntry : private noncopyable, private nonmovable
96 {
97 private:
98 unique_ptr<platform::MappedFile> p_mapped;
99 CPTABLEINFO table;
100
101 public:
102 NLSTableEntry(int);
103 DefGetter(const ynothrow, const CPTABLEINFO&, Table, table)
104 };
105
106 NLSTableEntry::NLSTableEntry(int cp)
107 : p_mapped(new platform::MappedFile(WCSToMBCS(FetchSystemPath()
108 + FetchCPFileNameFromRegistry(cp))))
109 {
110 const auto base(reinterpret_cast<unsigned short*>(p_mapped->GetPtr()));
111 auto& header(*reinterpret_cast<NLS_FILE_HEADER*>(base));
112
113 yunseq(
114 table.CodePage = header.CodePage,
115 table.MaximumCharacterSize = header.MaximumCharacterSize,
116 table.DefaultChar = header.DefaultChar,
117 table.UniDefaultChar = header.UniDefaultChar,
118 table.TransDefaultChar = header.TransDefaultChar,
119 table.TransUniDefaultChar = header.TransUniDefaultChar,
120 ystdex::trivially_copy_n(header.LeadByte, 1, table.LeadByte),
121 // NOTE: Offset to wide char table is after the header, then the multibyte
122 // table (256 wide characters) .
123 table.WideCharTable = base + header.HeaderSize + 1
124 + base[header.HeaderSize],
125 table.MultiByteTable = base + header.HeaderSize + 1
126 );
127 // NOTE: Glyph table (256 wide characters) is probably present.
128 table.DBCSRanges = table.MultiByteTable + 256 + 1;
129 if(table.MultiByteTable[256])
130 table.DBCSRanges += 256;
131 table.DBCSOffsets = (table.DBCSCodePage = *table.DBCSRanges)
132 ? table.DBCSRanges + 1 : nullptr;
133 }
134
135
136 mutex NLSCacheMutex;
138 map<int, NLSTableEntry> NLSCache;
139
140 } // unnamed namespace;
141
142 const unsigned short*
143 FetchDBCSOffset(int cp) ynothrow
144 {
145 return TryInvoke([=]{
146 lock_guard<mutex> lck(NLSCacheMutex);
147 // TODO: Enable concurrent initialization using 'call_once', etc?
148 auto& tbl(ystdex::try_emplace(NLSCache, cp, cp).first
149 ->second.GetTable());
150
151 return tbl.DBCSCodePage ? tbl.DBCSOffsets : nullptr;
152 });
153 }
154
155 } // inline namespace Windows;
156
157 #endif
158
159 } // namespace platform_ex;
160
yconstexpr
#define yconstexpr
指定编译时常量表达式。
Definition: ydef.h:653
ynothrow
#define ynothrow
YSLib 无异常抛出保证：若支持 noexcept 关键字， 指定特定的 noexcept 异常规范。
Definition: ydef.h:740
ystdex::try_emplace
std::pair< typename _tAssocCon::iterator, bool > try_emplace(_tAssocCon &con, _tKey &&k, _tParams &&...args)
Definition: container.hpp:1170
platform::KeyCodes::DS::L
Definition: Keys.h:227
NPL::A1::name
ctx const string & name
Definition: NPLA1.h:248
YSLib
YSLib 命名空间。
Definition: AndroidHost.h:45
DefGetter
#define DefGetter(_q, _t, _n,...)
Definition: YBaseMacro.h:240
YSLib::ynothrow
YB_PURE const _type size_t n ynothrow
Definition: YCoreUtilities.h:168
YSLib::TryInvoke
ystdex::result_of_t< _fCallable &&(_tParams &&...)> TryInvoke(_fCallable &&f, _tParams &&...args) ynothrow
调用函数并试图返回。
Definition: YException.h:185
container.hpp
通用容器操作。
platform
默认平台命名空间。
Definition: Container.h:47
base.h
基类实用设施。
std
Definition: memory.hpp:1100
platform::containers::wstring
basic_string< wchar_t > wstring
Definition: Container.h:108
yunseq
#define yunseq
无序列依赖表达式组求值。
Definition: ydef.h:996
platform_ex
平台扩展命名空间。
Definition: Android.h:45
platform_ex::Windows::WCSToMBCS
YF_API string WCSToMBCS(wstring_view, unsigned=CP_ACP)
Drawing
YModules.h
YSLib::YB_NONNULL
YF_API YB_NONNULL(1, 2) ValueNode LoadNPLA1File(const char *disp
载入 NPLA1 配置文件。
ystdex::byte
unsigned char byte
字节类型。
Definition: ydef.h:808
platform_ex::Windows::FetchSystemPath
YF_API wstring FetchSystemPath(size_t=MAX_PATH)
取系统目录路径。
ystdex::trivially_copy_n
_type * trivially_copy_n(const _type *first, size_t n, _type *result)
复制不覆盖的序列。
Definition: algorithm.hpp:388
algorithm.hpp
泛型算法。