Make character category data reusable

This shall assist adding/replacing it with Unicode character blocks.

Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
Simon Rozman
2025-11-12 08:43:24 +01:00
parent ec957caf3c
commit a11c4bc79a
4 changed files with 69 additions and 62 deletions

View File

@@ -208,7 +208,7 @@ wxZRColaCharSelect::wxZRColaCharSelect(wxWindow* parent) :
const auto &cc = app->m_cc_db.idxRank[i];
int idx = m_categories->Insert(wxGetTranslation(wxString(cc.name(), cc.name_len()), wxT("ZRCola-zrcdb")), (unsigned int)i);
m_categories->Check(idx);
m_ccOrder.insert(std::make_pair(cc.cat, idx));
m_ccOrder.insert(std::make_pair(cc.id, idx));
}
ResetResults();
@@ -266,9 +266,9 @@ void wxZRColaCharSelect::OnIdle(wxIdleEvent& event)
}
{
// Update character category.
ZRCola::chrcat_db::indexChrCat::size_type cc_start;
if (app->m_cc_db.idxChrCat.find(ZRCola::chrcat_db::chrcat(chr.cat), cc_start)) {
const auto &cat = app->m_cc_db.idxChrCat[cc_start];
ZRCola::chrcat_db::indexChrId::size_type cc_start;
if (app->m_cc_db.idxChrId.find(ZRCola::chrcat_db::chrcls(chr.cat), cc_start)) {
const auto &cat = app->m_cc_db.idxChrId[cc_start];
m_category->SetValue(wxGetTranslation(wxString(cat.name(), cat.name_len()), wxT("ZRCola-zrcdb")));
} else
m_category->SetValue(wxEmptyString);
@@ -344,7 +344,7 @@ void wxZRColaCharSelect::OnIdle(wxIdleEvent& event)
for (size_t i = 0, n = app->m_cc_db.idxRank.size(); i < n; i++) {
const auto &cc = app->m_cc_db.idxRank[i];
if (m_categories->IsChecked((unsigned int)i))
m_searchThread->m_cats.insert(cc.cat);
m_searchThread->m_cats.insert(cc.id);
}
if (m_searchThread->Run() != wxTHREAD_NO_ERROR) {
@@ -823,7 +823,7 @@ void wxPersistentZRColaCharSelect::Save() const
for (size_t i = 0, n = app->m_cc_db.idxRank.size(); i < n; i++) {
const auto &cc = app->m_cc_db.idxRank[i];
wxString name(wxT("category"));
name.Append(cc.cat.data, _countof(cc.cat.data));
name.Append(cc.id.data, _countof(cc.id.data));
SaveValue(name, wnd->m_categories->IsChecked((unsigned int)i));
}
@@ -858,7 +858,7 @@ bool wxPersistentZRColaCharSelect::Restore()
for (size_t i = 0, n = app->m_cc_db.idxRank.size(); i < n; i++) {
const auto &cc = app->m_cc_db.idxRank[i];
wxString name(wxT("category"));
name.Append(cc.cat.data, _countof(cc.cat.data));
name.Append(cc.id.data, _countof(cc.id.data));
bool val;
if (RestoreValue(name, &val))
wnd->m_categories->Check((unsigned int)i, val);

View File

@@ -1079,8 +1079,8 @@ inline ZRCola::chrcat_db& operator<<(_Inout_ ZRCola::chrcat_db &db, _In_ const Z
wxASSERT_MSG(n <= 0xffff, wxT("character category name overflow"));
db.data.push_back((uint16_t)n);
db.data.insert(db.data.end(), rec.name.cbegin(), rec.name.cend());
db.idxChrCat.push_back(idx);
db.idxRank .push_back(idx);
db.idxChrId.push_back(idx);
db.idxRank .push_back(idx);
return db;
}

View File

@@ -813,9 +813,9 @@ int _tmain(int argc, _TCHAR *argv[])
ZRCola::chrcat_db db;
// Preallocate memory.
db.idxChrCat.reserve(count);
db.idxRank .reserve(count);
db.data .reserve(count*4);
db.idxChrId.reserve(count);
db.idxRank .reserve(count);
db.data .reserve(count*4);
// Parse character categories and build index and data.
for (; !ZRCola::DBSource::IsEOF(rs); rs->MoveNext()) {
@@ -836,8 +836,8 @@ int _tmain(int argc, _TCHAR *argv[])
}
// Write character categories to file.
db.idxChrCat.sort();
db.idxRank .sort();
db.idxChrId.sort();
db.idxRank .sort();
dst << ZRCola::chrcat_rec(db);
} else {
_ftprintf(stderr, wxT("%s: error ZCC0019: Error getting character category count from database or too many character categories.\n"), (LPCTSTR)filenameIn.c_str());

View File

@@ -414,44 +414,45 @@ namespace ZRCola {
///
/// Character category database
/// Character classification database template
///
class chrcat_db {
template <typename T_id>
class chrclass_db {
public:
#pragma pack(push)
#pragma pack(2)
///
/// Character category data
/// Character classification data
///
struct chrcat {
struct chrcls {
public:
chrcatid_t cat; ///< Character category ID
uint16_t rank; ///< Character category rank
T_id id; ///< Character classification ID
uint16_t rank; ///< Character classification rank
protected:
uint16_t name_to; ///< Character category name end in \c data
char_t data[]; ///< Character category name
uint16_t name_to; ///< Character classification name end in \c data
char_t data[]; ///< Character classification name
private:
inline chrcat(_In_ const chrcat &other);
inline chrcat& operator=(_In_ const chrcat &other);
inline chrcls(_In_ const chrcls &other);
inline chrcls& operator=(_In_ const chrcls &other);
public:
///
/// Constructs the character category
/// Constructs the character classification
///
/// \param[in] cat Character category ID
/// \param[in] rank Character category rank
/// \param[in] name Character category name
/// \param[in] id Character classification ID
/// \param[in] rank Character classification rank
/// \param[in] name Character classification name
/// \param[in] name_len Number of UTF-16 characters in \p name
///
inline chrcat(
_In_opt_ chrcatid_t cat = chrcatid_t::blank,
_In_opt_ uint16_t rank = 0,
_In_opt_z_count_(name_len) const char_t *name = NULL,
_In_opt_ size_t name_len = 0)
inline chrcls(
_In_opt_ T_id id = T_id::blank,
_In_opt_ uint16_t rank = 0,
_In_opt_z_count_(name_len) const char_t *name = NULL,
_In_opt_ size_t name_len = 0)
{
this->cat = cat;
this->id = id;
this->rank = rank;
this->name_to = static_cast<uint16_t>(name_len);
if (name && name_len) memcpy(this->data, name, sizeof(char_t)*name_len);
@@ -466,9 +467,9 @@ namespace ZRCola {
#pragma pack(pop)
///
/// Character category index
/// Character classification index
///
class indexChrCat : public index<uint16_t, uint32_t, chrcat>
class indexChrId : public index<uint16_t, uint32_t, chrcls>
{
public:
///
@@ -476,7 +477,7 @@ namespace ZRCola {
///
/// \param[in] h Reference to vector holding the data
///
indexChrCat(_In_ std::vector<uint16_t> &h) : index<uint16_t, uint32_t, chrcat>(h) {}
indexChrId(_In_ std::vector<uint16_t> &h) : index<uint16_t, uint32_t, chrcls>(h) {}
///
/// Compares two character categories by ID (for searching)
@@ -489,19 +490,19 @@ namespace ZRCola {
/// - =0 when a == b
/// - >0 when a > b
///
virtual int compare(_In_ const chrcat &a, _In_ const chrcat &b) const
virtual int compare(_In_ const chrcls &a, _In_ const chrcls &b) const
{
if (a.cat < b.cat) return -1;
if (a.cat > b.cat) return 1;
if (a.id < b.id) return -1;
if (a.id > b.id) return 1;
return 0;
}
} idxChrCat; ///< Character category index
} idxChrId; ///< Character classification index
///
/// Rank index
///
class indexRank : public index<uint16_t, uint32_t, chrcat>
class indexRank : public index<uint16_t, uint32_t, chrcls>
{
public:
///
@@ -509,7 +510,7 @@ namespace ZRCola {
///
/// \param[in] h Reference to vector holding the data
///
indexRank(_In_ std::vector<uint16_t> &h) : index<uint16_t, uint32_t, chrcat>(h) {}
indexRank(_In_ std::vector<uint16_t> &h) : index<uint16_t, uint32_t, chrcls>(h) {}
///
/// Compares two character categories by ID (for searching)
@@ -522,7 +523,7 @@ namespace ZRCola {
/// - =0 when a == b
/// - >0 when a > b
///
virtual int compare(_In_ const chrcat &a, _In_ const chrcat &b) const
virtual int compare(_In_ const chrcls &a, _In_ const chrcls &b) const
{
if (a.rank < b.rank) return -1;
if (a.rank > b.rank) return +1;
@@ -533,15 +534,15 @@ namespace ZRCola {
///
/// Compares two character categories by rank (for sorting)
///
/// \param[in] a Pointer to character category
/// \param[in] b Pointer to second character category
/// \param[in] a Pointer to character classification
/// \param[in] b Pointer to second character classification
///
/// \returns
/// - <0 when a < b
/// - =0 when a == b
/// - >0 when a > b
///
virtual int compare_sort(_In_ const chrcat &a, _In_ const chrcat &b) const
virtual int compare_sort(_In_ const chrcls &a, _In_ const chrcls &b) const
{
if (a.rank < b.rank) return -1;
else if (a.rank > b.rank) return +1;
@@ -551,38 +552,38 @@ namespace ZRCola {
}
} idxRank; ///< Rank index
std::vector<uint16_t> data; ///< Character category data
std::vector<uint16_t> data; ///< Character classification data
public:
///
/// Constructs the database
///
inline chrcat_db() : idxChrCat(data), idxRank(data) {}
inline chrclass_db() : idxChrId(data), idxRank(data) {}
///
/// Clears the database
///
inline void clear()
{
idxChrCat.clear();
idxRank .clear();
data .clear();
idxChrId.clear();
idxRank .clear();
data .clear();
}
///
/// Writes character category database to a stream
/// Writes character classification database to a stream
///
/// \param[in] stream Output stream
/// \param[in] db Character category database
/// \param[in] db Character classification database
///
/// \returns The stream \p stream
///
friend std::ostream& operator <<(_In_ std::ostream& stream, _In_ const chrcat_db& db)
friend std::ostream& operator <<(_In_ std::ostream& stream, _In_ const chrclass_db<T_id>& db)
{
// Write character category index.
// Write character classification index.
if (stream.fail()) return stream;
stream << db.idxChrCat;
stream << db.idxChrId;
// Write rank index.
if (stream.fail()) return stream;
@@ -610,17 +611,17 @@ namespace ZRCola {
///
/// Reads character category database from a stream
/// Reads character classification database from a stream
///
/// \param[in ] stream Input stream
/// \param[out] db Character category database
/// \param[out] db Character classification database
///
/// \returns The stream \p stream
///
friend std::istream& operator >>(_In_ std::istream& stream, _Out_ chrcat_db& db)
friend std::istream& operator >>(_In_ std::istream& stream, _Out_ chrclass_db<T_id>& db)
{
// Read character category index.
stream >> db.idxChrCat;
// Read character classification index.
stream >> db.idxChrId;
if (!stream.good()) return stream;
// Read rank index.
@@ -643,6 +644,12 @@ namespace ZRCola {
return stream;
}
};
///
/// Character category database
///
using chrcat_db = chrclass_db<chrcatid_t>;
};
#pragma warning(pop)