diff --git a/ZRCola/zrcolaapp.cpp b/ZRCola/zrcolaapp.cpp index 7e84eb2..0083546 100644 --- a/ZRCola/zrcolaapp.cpp +++ b/ZRCola/zrcolaapp.cpp @@ -82,7 +82,7 @@ bool ZRColaApp::OnInit() ZRCola::recordid_t id; if (!stdex::idrec::read_id(dat, id, size)) break; - if (id == ZRCola::translation_rec::id) { + if (id == ZRCola::translation_rec::id()) { dat >> ZRCola::translation_rec(m_t_db); if (dat.good()) { has_translation_data = true; @@ -90,61 +90,61 @@ bool ZRColaApp::OnInit() wxFAIL_MSG(wxT("Error reading translation data from ZRCola.zrcdb.")); m_t_db.clear(); } - } else if (id == ZRCola::transet_rec::id) { + } else if (id == ZRCola::transet_rec::id()) { dat >> ZRCola::transet_rec(m_ts_db); if (!dat.good()) { wxFAIL_MSG(wxT("Error reading translation set data from ZRCola.zrcdb.")); m_ts_db.clear(); } - } else if (id == ZRCola::transeq_rec::id) { + } else if (id == ZRCola::transeq_rec::id()) { dat >> ZRCola::transeq_rec(m_tsq_db); if (!dat.good()) { wxFAIL_MSG(wxT("Error reading translation sequence data from ZRCola.zrcdb.")); m_tsq_db.clear(); } - } else if (id == ZRCola::langchar_rec::id) { + } else if (id == ZRCola::langchar_rec::id()) { dat >> ZRCola::langchar_rec(m_lc_db); if (!dat.good()) { wxFAIL_MSG(wxT("Error reading language character data from ZRCola.zrcdb.")); m_lc_db.clear(); } - } else if (id == ZRCola::language_rec::id) { + } else if (id == ZRCola::language_rec::id()) { dat >> ZRCola::language_rec(m_lang_db); if (!dat.good()) { wxFAIL_MSG(wxT("Error reading language character data from ZRCola.zrcdb.")); m_lang_db.clear(); } - } else if (id == ZRCola::keyseq_rec::id) { + } else if (id == ZRCola::keyseq_rec::id()) { dat >> ZRCola::keyseq_rec(m_ks_db); if (!dat.good()) { wxFAIL_MSG(wxT("Error reading key sequences data from ZRCola.zrcdb.")); m_ks_db.clear(); } - } else if (id == ZRCola::character_rec::id) { + } else if (id == ZRCola::character_rec::id()) { dat >> ZRCola::character_rec(m_chr_db); if (!dat.good()) { wxFAIL_MSG(wxT("Error reading character data from ZRCola.zrcdb.")); m_chr_db.clear(); } - } else if (id == ZRCola::chrcat_rec::id) { + } else if (id == ZRCola::chrcat_rec::id()) { dat >> ZRCola::chrcat_rec(m_cc_db); if (!dat.good()) { wxFAIL_MSG(wxT("Error reading character category data from ZRCola.zrcdb.")); m_cc_db.clear(); } - } else if (id == ZRCola::chrtag_rec::id) { + } else if (id == ZRCola::chrtag_rec::id()) { dat >> ZRCola::chrtag_rec(m_ct_db); if (!dat.good()) { wxFAIL_MSG(wxT("Error reading character tag data from ZRCola.zrcdb.")); m_ct_db.clear(); } - } else if (id == ZRCola::tagname_rec::id) { + } else if (id == ZRCola::tagname_rec::id()) { dat >> ZRCola::tagname_rec(m_tn_db); if (!dat.good()) { wxFAIL_MSG(wxT("Error reading tag name data from ZRCola.zrcdb.")); m_tn_db.clear(); } - } else if (id == ZRCola::highlight_rec::id) { + } else if (id == ZRCola::highlight_rec::id()) { dat >> ZRCola::highlight_rec(m_h_db); if (!dat.good()) { wxFAIL_MSG(wxT("Error reading highlight data from ZRCola.zrcdb.")); diff --git a/ZRColaCompile/dbsource.h b/ZRColaCompile/dbsource.h index 0df7dda..5527dd6 100644 --- a/ZRColaCompile/dbsource.h +++ b/ZRColaCompile/dbsource.h @@ -312,15 +312,8 @@ namespace ZRCola { { inline bool operator()(const std::wstring& _Left, const std::wstring& _Right) const { - size_t - _Left_len = _Left .size(), - _Right_len = _Right.size(); - - int r = _wcsncoll(_Left.c_str(), _Right.c_str(), std::min(_Left_len, _Right_len)); - if (r != 0 ) return r < 0; - else if (_Left_len < _Right_len) return true; - - return false; + auto &coll = std::use_facet>(std::locale()); + return coll.compare(&*_Left.cbegin(), &*_Left.cend(), &*_Right.cbegin(), &*_Right.cend()) < 0; } }; diff --git a/lib/libZRCola/build/Makefile b/lib/libZRCola/build/Makefile new file mode 100644 index 0000000..9313797 --- /dev/null +++ b/lib/libZRCola/build/Makefile @@ -0,0 +1,35 @@ +CPPFLAGS := $(CPPFLAGS) -MMD -MP -I../../stdex/include +ifeq ($(CFG),Debug) +CPPFLAGS := $(CPPFLAGS) -D_DEBUG +CXXFLAGS := -Og +else +CPPFLAGS := $(CPPFLAGS) -DNDEBUG +CXXFLAGS := -O3 +endif + +SRCS := \ + ../src/character.cpp \ + ../src/common.cpp \ + ../src/highlight.cpp \ + ../src/language.cpp \ + ../src/mapping.cpp \ + ../src/pch.cpp \ + ../src/tag.cpp \ + ../src/translate.cpp +OBJS := $(SRCS:%=%.o) +DEPS := $(OBJS:.o=.d) + +../lib/libZRCola.a : ../src/pch.h.gch $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +%.h.gch: %.h + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -x c++-header -o $@ -c $< + +%.cpp.o: %.cpp + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $@ -c $< + +.PHONY: clean +clean: + -rm -r ../src/*.h.gch ../src/*.cpp.o ../lib/libZRCola.a + +-include $(DEPS) diff --git a/lib/libZRCola/include/zrcola/character.h b/lib/libZRCola/include/zrcola/character.h index c33692e..c5e64c7 100644 --- a/lib/libZRCola/include/zrcola/character.h +++ b/lib/libZRCola/include/zrcola/character.h @@ -11,11 +11,12 @@ #include #include #include +#include #include #include -#include #include #include +#include #pragma warning(push) #pragma warning(disable: 4200) @@ -319,14 +320,14 @@ namespace ZRCola { { assert(len <= 0xffff); std::unique_ptr c((character*)new char[sizeof(character) + sizeof(wchar_t)*len]); - c->character::character(chr, len); + new (c.get()) character(chr, len); indexChr::size_type start; return idxChr.find(*c, start) ? idxChr[start].cat : chrcatid_t::blank; } }; - typedef stdex::idrec::record character_rec; + typedef stdex::idrec::record character_rec; /// @@ -462,15 +463,8 @@ namespace ZRCola { if (a.rank < b.rank) return -1; else if (a.rank > b.rank) return +1; - uint16_t - a_name_len = a.name_len(), - b_name_len = b.name_len(); - int r = _wcsncoll(a.name(), b.name(), std::min(a_name_len, b_name_len)); - if (r != 0) return r; - if (a_name_len < b_name_len) return -1; - else if (a_name_len > b_name_len) return +1; - - return 0; + auto &coll = std::use_facet>(std::locale()); + return coll.compare(a.name(), a.name_end(), b.name(), b.name_end()); } } idxRank; ///< Rank index @@ -494,14 +488,10 @@ namespace ZRCola { }; - typedef stdex::idrec::record chrcat_rec; + typedef stdex::idrec::record chrcat_rec; }; -const ZRCola::recordid_t ZRCola::character_rec::id = *(ZRCola::recordid_t*)"CHR"; -const ZRCola::recordid_t ZRCola::chrcat_rec ::id = *(ZRCola::recordid_t*)"CCT"; - - /// /// Reads character database from a stream /// diff --git a/lib/libZRCola/include/zrcola/common.h b/lib/libZRCola/include/zrcola/common.h index 731cbc2..8587f42 100644 --- a/lib/libZRCola/include/zrcola/common.h +++ b/lib/libZRCola/include/zrcola/common.h @@ -8,10 +8,14 @@ #ifdef _WIN32 #define _WINSOCKAPI_ // Prevent inclusion of winsock.h in windows.h. #include -#include #endif +#include #include +#include +#include +#include #include +#include #include #include #include @@ -30,8 +34,15 @@ /// /// Database IDs /// -#define ZRCOLA_DB_ID (*(ZRCola::recordid_t*)"ZRC") +#define ZRCOLA_DB_ID 0x43525a // "ZRC" +#ifdef __GNUC__ +#ifdef __i386__ +#define __cdecl __attribute__((__cdecl__)) +#else +#define __cdecl +#endif +#endif namespace ZRCola { typedef uint32_t recordid_t; @@ -214,6 +225,11 @@ namespace ZRCola { template class index : public std::vector { + typedef std::vector base_t; + + public: + typedef size_t size_type; + protected: std::vector &host; ///< Reference to host data @@ -235,7 +251,7 @@ namespace ZRCola { /// inline const T_el& at(size_type pos) const { - return *reinterpret_cast(&host[std::vector::at(pos)]); + return *reinterpret_cast(&host[base_t::at(pos)]); } @@ -248,7 +264,7 @@ namespace ZRCola { /// inline T_el& at(size_type pos) { - return *reinterpret_cast(&host[std::vector::at(pos)]); + return *reinterpret_cast(&host[base_t::at(pos)]); } @@ -261,7 +277,7 @@ namespace ZRCola { /// inline const T_el& operator[](size_type pos) const { - return *reinterpret_cast(&host[std::vector::operator[](pos)]); + return *reinterpret_cast(&host[base_t::operator[](pos)]); } @@ -274,7 +290,7 @@ namespace ZRCola { /// inline T_el& operator[](size_type pos) { - return *reinterpret_cast(&host[std::vector::operator[](pos)]); + return *reinterpret_cast(&host[base_t::operator[](pos)]); } @@ -283,7 +299,7 @@ namespace ZRCola { /// inline void sort() { - qsort_s(data(), size(), sizeof(T_idx), compare_s, this); + qsort_s(base_t::data(), base_t::size(), sizeof(T_idx), compare_s, this); } @@ -334,21 +350,21 @@ namespace ZRCola { bool find(_In_ const T_el &el, _Out_ size_type &start, _Out_ size_type &end) const { // Start with the full search area. - for (start = 0, end = size(); start < end; ) { - size_type m = (start + end) / 2; + for (start = 0, end = base_t::size(); start < end; ) { + auto m = (start + end) / 2; int r = compare(el, at(m)); if (r < 0) end = m; else if (r > 0) start = m + 1; else { // Narrow the search area on the left to start at the first element in the run. - for (size_type end2 = m; start < end2;) { - size_type m2 = (start + end2) / 2; + for (auto end2 = m; start < end2;) { + auto m2 = (start + end2) / 2; if (compare(el, at(m2)) <= 0) end2 = m2; else start = m2 + 1; } // Narrow the search area on the right to end at the first element not in the run. - for (size_type start2 = m + 1; start2 < end;) { - size_type m2 = (start2 + end) / 2; + for (auto start2 = m + 1; start2 < end;) { + auto m2 = (start2 + end) / 2; if (0 <= compare(el, at(m2))) start2 = m2 + 1; else end = m2; } @@ -373,14 +389,14 @@ namespace ZRCola { { // Start with the full search area. size_t end; - for (start = 0, end = size(); start < end; ) { - size_type m = (start + end) / 2; + for (start = 0, end = base_t::size(); start < end; ) { + auto m = (start + end) / 2; int r = compare(el, at(m)); if (r < 0) end = m; else if (r > 0) start = m + 1; else { // Narrow the search area on the left to start at the first element in the run. - for (size_type end2 = m; start < end2;) { + for (auto end2 = m; start < end2;) { m = (start + end2) / 2; if (compare(el, at(m)) <= 0) end2 = m; else start = m + 1; } @@ -410,8 +426,10 @@ namespace ZRCola { template class textindex : public std::vector< mappair_t > { - public: typedef std::vector< mappair_t > base_t; + + public: + typedef size_t size_type; std::vector keys; ///< Key data std::vector values; ///< Index values @@ -447,15 +465,15 @@ namespace ZRCola { /// _Success_(return) bool find(_In_count_(key_len) const T_key *key, _In_ size_t key_len, _Out_ const T_val **val, _Out_ size_t *val_len) const { - for (size_type start = 0, end = size(); start < end; ) { - size_type m = (start + end) / 2; + for (size_type start = 0, end = base_t::size(); start < end; ) { + auto m = (start + end) / 2; int r = compare(key, key_len, m); if (r < 0) end = m; else if (r > 0) start = m + 1; else { // Get values at position m. - start = base_t::at(m ).idx_val; - *val_len = (m < size() ? base_t::at(m + 1).idx_val : values.size()) - start; + start = base_t::at(m ).idx_val; + *val_len = (m < base_t::size() ? base_t::at(m + 1).idx_val : values.size()) - start; *val = &values.at(start); return true; } @@ -468,11 +486,11 @@ namespace ZRCola { inline int compare(_In_count_(key_len) const T_key *key, _In_ size_t key_len, size_type pos) const { // Get key at position pos. - size_type pos_next = pos + 1; + auto pos_next = pos + 1; size_t - start = base_t::at(pos ).idx_key, - key2_len = (pos_next < size() ? base_t::at(pos_next).idx_key : keys.size()) - start; - std::vector::const_pointer key2 = &keys.at(start); + start = base_t::at(pos ).idx_key, + key2_len = (pos_next < base_t::size() ? base_t::at(pos_next).idx_key : keys.size()) - start; + auto key2 = &keys.at(start); // Compare keys. int r = memcmp(key, key2, sizeof(T_key)*std::min(key_len, key2_len)); @@ -488,7 +506,7 @@ namespace ZRCola { /// /// Source-destination index transformation mapping /// - class __declspec(novtable) mapping { + struct mapping { public: size_t src; ///< Character index in source string size_t dst; ///< Character index in destination string @@ -553,16 +571,7 @@ namespace ZRCola { /// The function does not treat \\0 characters as terminators for performance reasons. /// Therefore \p count_a and \p count_b must represent exact string lengths. /// - inline int CompareString(_In_ const wchar_t *str_a, _In_ size_t count_a, _In_ const wchar_t *str_b, _In_ size_t count_b) - { - for (size_t i = 0; ; i++) { - if (i >= count_a && i >= count_b) return 0; - else if (i >= count_a && i < count_b) return -1; - else if (i < count_a && i >= count_b) return +1; - else if (str_a[i] < str_b[i]) return -1; - else if (str_a[i] > str_b[i]) return +1; - } - } + int CompareString(_In_ const wchar_t* str_a, _In_ size_t count_a, _In_ const wchar_t* str_b, _In_ size_t count_b); /// /// Generates and returns Unicode representation of the string using hexadecimal codes. @@ -571,21 +580,7 @@ namespace ZRCola { /// \param[in] count Number of characters in string \p str /// \param[in] sep Separator /// - inline std::string GetUnicodeDumpA(_In_ const wchar_t *str, _In_ size_t count, _In_z_ const char *sep = "+") - { - std::string out; - size_t dump_len_max = strlen(sep) + 4 + 1; - char *dump; - std::unique_ptr dump_obj(dump = new char[dump_len_max]); - if (count && str[0]) { - size_t i = 0; - out.insert(out.end(), dump, dump + _snprintf(dump, dump_len_max, "%04X", str[i++])); - while (i < count && str[i]) - out.insert(out.end(), dump, dump + _snprintf(dump, dump_len_max, "%s%04X", sep, str[i++])); - } - - return out; - } + std::string GetUnicodeDumpA(_In_z_count_(count) const wchar_t* str, _In_ size_t count, _In_z_ const char* sep = "+"); /// /// Generates and returns Unicode representation of the string using hexadecimal codes. @@ -594,21 +589,7 @@ namespace ZRCola { /// \param[in] count Number of characters in string \p str /// \param[in] sep Separator /// - inline std::wstring GetUnicodeDumpW(_In_ const wchar_t *str, _In_ size_t count, _In_z_ const wchar_t *sep = L"+") - { - std::wstring out; - size_t dump_len_max = wcslen(sep) + 4 + 1; - wchar_t *dump; - std::unique_ptr dump_obj(dump = new wchar_t[dump_len_max]); - if (count && str[0]) { - size_t i = 0; - out.insert(out.end(), dump, dump + _snwprintf(dump, dump_len_max, L"%04X", str[i++])); - while (i < count && str[i]) - out.insert(out.end(), dump, dump + _snwprintf(dump, dump_len_max, L"%s%04X", sep, str[i++])); - } - - return out; - } + std::wstring GetUnicodeDumpW(_In_z_count_(count) const wchar_t* str, _In_ size_t count, _In_z_ const wchar_t* sep = L"+"); #ifdef _UNICODE #define GetUnicodeDump GetUnicodeDumpW @@ -709,7 +690,8 @@ inline std::ostream& operator <<(_In_ std::ostream& stream, _In_ const ZRCola::t // Write index data. if (stream.fail()) return stream; - stream.write((const char*)idx.data(), sizeof(ZRCola::textindex::value_type)*static_cast(count)); + auto idx_data = idx.data(); + stream.write((const char*)idx_data, sizeof(*idx_data)*static_cast(count)); // Write key count. auto key_count = idx.keys.size(); @@ -726,7 +708,8 @@ inline std::ostream& operator <<(_In_ std::ostream& stream, _In_ const ZRCola::t // Write key data. if (stream.fail()) return stream; - stream.write((const char*)idx.keys.data(), sizeof(std::vector::value_type)*static_cast(count)); + auto idx_keys_data = idx.keys.data(); + stream.write((const char*)idx_keys_data, sizeof(*idx_keys_data)*static_cast(count)); // Write value count. auto value_count = idx.values.size(); @@ -743,7 +726,8 @@ inline std::ostream& operator <<(_In_ std::ostream& stream, _In_ const ZRCola::t // Write value data. if (stream.fail()) return stream; - stream.write((const char*)idx.values.data(), sizeof(std::vector::value_type)*static_cast(count)); + auto idx_values_data = idx.values.data(); + stream.write((const char*)idx_values_data, sizeof(*idx_values_data)*static_cast(count)); return stream; } @@ -772,7 +756,8 @@ inline std::istream& operator >>(_In_ std::istream& stream, _Out_ ZRCola::textin if (count) { // Read text index. idx.resize(count); - stream.read((char*)idx.data(), sizeof(ZRCola::textindex::value_type)*static_cast(count)); + auto p = idx.data(); + stream.read((char*)p, sizeof(*p)*static_cast(count)); if (!stream.good()) return stream; } else idx.clear(); @@ -784,7 +769,8 @@ inline std::istream& operator >>(_In_ std::istream& stream, _Out_ ZRCola::textin if (count) { // Read keys. idx.keys.resize(count); - stream.read((char*)idx.keys.data(), sizeof(std::vector::value_type)*static_cast(count)); + auto p = idx.keys.data(); + stream.read((char*)p, sizeof(*p)*static_cast(count)); if (!stream.good()) return stream; } else idx.keys.clear(); @@ -796,7 +782,8 @@ inline std::istream& operator >>(_In_ std::istream& stream, _Out_ ZRCola::textin if (count) { // Read values. idx.values.resize(count); - stream.read((char*)idx.values.data(), sizeof(std::vector::value_type)*static_cast(count)); + auto p = idx.values.data(); + stream.read((char*)p, sizeof(*p)*static_cast(count)); } else idx.values.clear(); diff --git a/lib/libZRCola/include/zrcola/highlight.h b/lib/libZRCola/include/zrcola/highlight.h index 78086e6..eba6bde 100644 --- a/lib/libZRCola/include/zrcola/highlight.h +++ b/lib/libZRCola/include/zrcola/highlight.h @@ -166,13 +166,10 @@ namespace ZRCola { }; - typedef stdex::idrec::record highlight_rec; + typedef stdex::idrec::record highlight_rec; }; -const ZRCola::recordid_t ZRCola::highlight_rec::id = *(ZRCola::recordid_t*)"HGH"; - - /// /// Writes highlight database to a stream /// diff --git a/lib/libZRCola/include/zrcola/language.h b/lib/libZRCola/include/zrcola/language.h index 98cf2a4..a43474e 100644 --- a/lib/libZRCola/include/zrcola/language.h +++ b/lib/libZRCola/include/zrcola/language.h @@ -181,7 +181,7 @@ namespace ZRCola { }; - typedef stdex::idrec::record langchar_rec; + typedef stdex::idrec::record langchar_rec; /// @@ -284,14 +284,10 @@ namespace ZRCola { }; - typedef stdex::idrec::record language_rec; + typedef stdex::idrec::record language_rec; }; -const ZRCola::recordid_t ZRCola::langchar_rec::id = *(ZRCola::recordid_t*)"L-C"; -const ZRCola::recordid_t ZRCola::language_rec::id = *(ZRCola::recordid_t*)"LNG"; - - /// /// Writes language character database to a stream /// diff --git a/lib/libZRCola/include/zrcola/tag.h b/lib/libZRCola/include/zrcola/tag.h index 9c269c2..73332a5 100644 --- a/lib/libZRCola/include/zrcola/tag.h +++ b/lib/libZRCola/include/zrcola/tag.h @@ -214,7 +214,7 @@ namespace ZRCola { }; - typedef stdex::idrec::record chrtag_rec; + typedef stdex::idrec::record chrtag_rec; /// @@ -230,7 +230,7 @@ namespace ZRCola { struct tagname { public: tagid_t tag; ///< Tag ID - LCID locale; ///< Locale ID + uint32_t locale; ///< Locale ID protected: uint16_t name_to; ///< Tag name end in \c data @@ -250,10 +250,10 @@ namespace ZRCola { /// \param[in] name_len Number of UTF-16 characters in \p name /// inline tagname( - _In_opt_ tagid_t tag = 0, - _In_opt_ LCID locale = MAKELCID(MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), SORT_DEFAULT), - _In_opt_z_count_(name_len) const wchar_t *name = NULL, - _In_opt_ size_t name_len = 0) + _In_opt_ tagid_t tag = 0, + _In_opt_ uint32_t locale = 0, + _In_opt_z_count_(name_len) const wchar_t *name = NULL, + _In_opt_ size_t name_len = 0) { this->tag = tag; this->locale = locale; @@ -285,14 +285,26 @@ namespace ZRCola { /// The function does not treat \\0 characters as terminators for performance reasons. /// Therefore \p count_a and \p count_b must represent exact string lengths. /// - static inline int CompareName(LCID locale, const wchar_t *str_a, uint16_t count_a, const wchar_t *str_b, uint16_t count_b) + static inline int CompareName(_In_ uint32_t locale, _In_z_count_(count_a) const wchar_t *str_a, _In_ uint16_t count_a, _In_z_count_(count_b) const wchar_t *str_b, _In_ uint16_t count_b) { +#ifdef _WIN32 switch (::CompareString(locale, SORT_STRINGSORT | NORM_IGNORECASE, str_a, count_a, str_b, count_b)) { case CSTR_LESS_THAN : return -1; case CSTR_EQUAL : return 0; case CSTR_GREATER_THAN: return 1; default : assert(0); return -1; } +#else + assert(0); // TODO: 1. Should honour locale. 2. Should use ICU for lowercase conversion. + std::wstring + a(str_a, count_a), + b(str_b, count_b); + auto tolower = [](wchar_t c){ return std::towlower(c); }; + std::transform(a.begin(), a.end(), a.begin(), tolower); + std::transform(b.begin(), b.end(), b.begin(), tolower); + auto &coll = std::use_facet>(std::locale()); + return coll.compare(&*a.cbegin(), &*a.cend(), &*b.cbegin(), &*b.cend()); +#endif } }; #pragma pack(pop) @@ -423,18 +435,14 @@ namespace ZRCola { /// \param[in ] fn_abort Pointer to function to periodically test for search cancellation /// \param[in ] cookie Cookie for \p fn_abort call /// - bool Search(_In_z_ const wchar_t *str, _In_ LCID locale, _Inout_ std::map &hits, _In_opt_ bool (__cdecl *fn_abort)(void *cookie) = NULL, _In_opt_ void *cookie = NULL) const; + bool Search(_In_z_ const wchar_t *str, _In_ uint32_t locale, _Inout_ std::map &hits, _In_opt_ bool (__cdecl *fn_abort)(void *cookie) = NULL, _In_opt_ void *cookie = NULL) const; }; - typedef stdex::idrec::record tagname_rec; + typedef stdex::idrec::record tagname_rec; }; -const ZRCola::recordid_t ZRCola::chrtag_rec ::id = *(ZRCola::recordid_t*)"C-T"; -const ZRCola::recordid_t ZRCola::tagname_rec::id = *(ZRCola::recordid_t*)"TGN"; - - /// /// Writes character tag database to a stream /// diff --git a/lib/libZRCola/include/zrcola/translate.h b/lib/libZRCola/include/zrcola/translate.h index 2343001..1f5c179 100644 --- a/lib/libZRCola/include/zrcola/translate.h +++ b/lib/libZRCola/include/zrcola/translate.h @@ -320,7 +320,7 @@ namespace ZRCola { }; - typedef stdex::idrec::record translation_rec; + typedef stdex::idrec::record translation_rec; /// @@ -436,7 +436,7 @@ namespace ZRCola { }; - typedef stdex::idrec::record transet_rec; + typedef stdex::idrec::record transet_rec; /// @@ -585,15 +585,8 @@ namespace ZRCola { if (a.rank < b.rank) return -1; else if (a.rank > b.rank) return +1; - uint16_t - a_name_len = a.name_len(), - b_name_len = b.name_len(); - int r = _wcsncoll(a.name(), b.name(), std::min(a_name_len, b_name_len)); - if (r != 0) return r; - if (a_name_len < b_name_len) return -1; - else if (a_name_len > b_name_len) return +1; - - return 0; + auto &coll = std::use_facet>(std::locale()); + return coll.compare(a.name(), a.name_end(), b.name(), b.name_end()); } } idxRank; ///< Rank index @@ -617,15 +610,10 @@ namespace ZRCola { }; - typedef stdex::idrec::record transeq_rec; + typedef stdex::idrec::record transeq_rec; }; -const ZRCola::recordid_t ZRCola::translation_rec::id = *(ZRCola::recordid_t*)"TRN"; -const ZRCola::recordid_t ZRCola::transet_rec ::id = *(ZRCola::recordid_t*)"TSE"; -const ZRCola::recordid_t ZRCola::transeq_rec ::id = *(ZRCola::recordid_t*)"TSQ"; - - /// /// Writes translation database to a stream /// diff --git a/lib/libZRCola/lib/.gitignore b/lib/libZRCola/lib/.gitignore new file mode 100644 index 0000000..77b9a76 --- /dev/null +++ b/lib/libZRCola/lib/.gitignore @@ -0,0 +1 @@ +/libZRCola.a diff --git a/lib/libZRCola/src/.gitignore b/lib/libZRCola/src/.gitignore new file mode 100644 index 0000000..9e482be --- /dev/null +++ b/lib/libZRCola/src/.gitignore @@ -0,0 +1,4 @@ +/*.h.gch +/*.h.d +/*.cpp.d +/*.cpp.o diff --git a/lib/libZRCola/src/common.cpp b/lib/libZRCola/src/common.cpp index 8703b03..1a3dff1 100644 --- a/lib/libZRCola/src/common.cpp +++ b/lib/libZRCola/src/common.cpp @@ -7,3 +7,78 @@ const ZRCola::langid_t ZRCola::langid_t::blank = {}; + + +_Use_decl_annotations_ +int ZRCola::CompareString(const wchar_t* str_a, size_t count_a, const wchar_t* str_b, size_t count_b) +{ + for (size_t i = 0; ; i++) { + if (i >= count_a && i >= count_b) return 0; + else if (i >= count_a && i < count_b) return -1; + else if (i < count_a && i >= count_b) return +1; + else if (str_a[i] < str_b[i]) return -1; + else if (str_a[i] > str_b[i]) return +1; + } +} + + +_Use_decl_annotations_ +inline std::string ZRCola::GetUnicodeDumpA(const wchar_t* str, size_t count, const char* sep) +{ + std::string out; + size_t sep_len = strlen(sep); + size_t dump_len_max = sep_len + 8 + 1; + char* dump; + std::unique_ptr dump_obj(dump = new char[dump_len_max]); + if (count && str[0]) { + size_t i = 0; + static const char error[] = "????"; + int n = snprintf(dump, dump_len_max, "%04X", str[i++]); + if (n >= 0) + out.insert(out.end(), dump, dump + n); + else + out.insert(out.end(), error, error + std::size(error) - 1); + while (i < count && str[i]) { + n = snprintf(dump, dump_len_max, "%s%04X", sep, str[i++]); + if (n >= 0) + out.insert(out.end(), dump, dump + n); + else { + out.insert(out.end(), sep, sep + sep_len); + out.insert(out.end(), error, error + std::size(error) - 1); + } + } + } + + return out; +} + + +_Use_decl_annotations_ +std::wstring ZRCola::GetUnicodeDumpW(const wchar_t* str, size_t count, const wchar_t* sep) +{ + std::wstring out; + size_t sep_len = wcslen(sep); + size_t dump_len_max = sep_len + 8 + 1; + wchar_t* dump; + std::unique_ptr dump_obj(dump = new wchar_t[dump_len_max]); + if (count && str[0]) { + size_t i = 0; + static const wchar_t error[] = L"????"; + int n = swprintf(dump, dump_len_max, L"%04X", str[i++]); + if (n >= 0) + out.insert(out.end(), dump, dump + n); + else + out.insert(out.end(), error, error + std::size(error) - 1); + while (i < count && str[i]) { + n = swprintf(dump, dump_len_max, L"%s%04X", sep, str[i++]); + if (n >= 0) + out.insert(out.end(), dump, dump + n); + else { + out.insert(out.end(), sep, sep + sep_len); + out.insert(out.end(), error, error + std::size(error) - 1); + } + } + } + + return out; +} diff --git a/lib/libZRCola/src/language.cpp b/lib/libZRCola/src/language.cpp index 3831c6d..17c4a78 100644 --- a/lib/libZRCola/src/language.cpp +++ b/lib/libZRCola/src/language.cpp @@ -62,7 +62,7 @@ bool ZRCola::langchar_db::IsLocalCharacter(_In_ const wchar_t *chr, _In_ const w size_t n = chr_end - chr; assert(n <= 0xffff); std::unique_ptr lc((langchar*)new char[sizeof(langchar) + sizeof(wchar_t)*n]); - lc->langchar::langchar(lang, chr, n); + new (lc.get()) langchar(lang, chr, n); indexChr::size_type start; return idxChr.find(*lc, start); } diff --git a/lib/libZRCola/src/tag.cpp b/lib/libZRCola/src/tag.cpp index aeeeb4c..e7b3923 100644 --- a/lib/libZRCola/src/tag.cpp +++ b/lib/libZRCola/src/tag.cpp @@ -37,7 +37,7 @@ bool ZRCola::chrtag_db::Search(_In_ const std::map &tags, _In } -bool ZRCola::tagname_db::Search(_In_z_ const wchar_t *str, _In_ LCID locale, _Inout_ std::map &hits, _In_opt_ bool (__cdecl *fn_abort)(void *cookie), _In_opt_ void *cookie) const +bool ZRCola::tagname_db::Search(_In_z_ const wchar_t *str, _In_ uint32_t locale, _Inout_ std::map &hits, _In_opt_ bool (__cdecl *fn_abort)(void *cookie), _In_opt_ void *cookie) const { assert(str); @@ -82,7 +82,7 @@ bool ZRCola::tagname_db::Search(_In_z_ const wchar_t *str, _In_ LCID locale, _In // Find the name. std::unique_ptr tn(reinterpret_cast(new char[sizeof(tagname) + sizeof(wchar_t)*name.length()])); - tn->tagname::tagname(0, locale, name.data(), name.length()); + new (tn.get()) tagname(0, locale, name.data(), name.length()); size_t start, end; if (idxName.find(*tn, start, end)) { // The name was found. diff --git a/lib/libZRColaUI/include/zrcolaui/chargroup.h b/lib/libZRColaUI/include/zrcolaui/chargroup.h index b337822..0a44ad3 100644 --- a/lib/libZRColaUI/include/zrcolaui/chargroup.h +++ b/lib/libZRColaUI/include/zrcolaui/chargroup.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -147,15 +148,8 @@ namespace ZRCola { if (a.rank < b.rank) return -1; else if (a.rank > b.rank) return +1; - uint16_t - a_name_len = a.name_len(), - b_name_len = b.name_len(); - int r = _wcsncoll(a.name(), b.name(), std::min(a_name_len, b_name_len)); - if (r != 0) return r; - if (a_name_len < b_name_len) return -1; - else if (a_name_len > b_name_len) return +1; - - return 0; + auto &coll = std::use_facet>(std::locale()); + return coll.compare(a.name(), a.name_end(), b.name(), b.name_end()); } } idxRank; ///< Rank index @@ -169,13 +163,10 @@ namespace ZRCola { }; - typedef stdex::idrec::record chrgrp_rec; + typedef stdex::idrec::record chrgrp_rec; }; -const ZRCola::recordid_t ZRCola::chrgrp_rec::id = *(ZRCola::recordid_t*)"CGR"; - - /// /// Writes character group database to a stream /// diff --git a/lib/libZRColaUI/include/zrcolaui/keyboard.h b/lib/libZRColaUI/include/zrcolaui/keyboard.h index 65ddaed..6c5630c 100644 --- a/lib/libZRColaUI/include/zrcolaui/keyboard.h +++ b/lib/libZRColaUI/include/zrcolaui/keyboard.h @@ -273,13 +273,10 @@ namespace ZRCola { }; - typedef stdex::idrec::record keyseq_rec; + typedef stdex::idrec::record keyseq_rec; }; -const ZRCola::recordid_t ZRCola::keyseq_rec::id = *(ZRCola::recordid_t*)"KEY"; - - /// /// Writes key sequence database to a stream /// diff --git a/lib/stdex b/lib/stdex index 09d0f34..857b0b3 160000 --- a/lib/stdex +++ b/lib/stdex @@ -1 +1 @@ -Subproject commit 09d0f347e807c2cb15726f3f4ff38cdc641d72c9 +Subproject commit 857b0b36c0381a244055a57df67d6ca371ac1b58