Migration to dynamic translation tables continues...
This commit is contained in:
parent
9d7cd76520
commit
215e03a705
@ -60,9 +60,6 @@
|
|||||||
<ProjectReference Include="..\lib\libZRCola\build\libZRCola.vcxproj">
|
<ProjectReference Include="..\lib\libZRCola\build\libZRCola.vcxproj">
|
||||||
<Project>{3c61929e-7289-4101-8d0a-da22d6e1aea8}</Project>
|
<Project>{3c61929e-7289-4101-8d0a-da22d6e1aea8}</Project>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
<ProjectReference Include="..\lib\stdex\build\stdex.vcxproj">
|
|
||||||
<Project>{518777cc-0a59-4415-a12a-82751ed75343}</Project>
|
|
||||||
</ProjectReference>
|
|
||||||
<ProjectReference Include="..\lib\wxExtend\build\wxExtend.vcxproj">
|
<ProjectReference Include="..\lib\wxExtend\build\wxExtend.vcxproj">
|
||||||
<Project>{a3a36689-ac35-4026-93da-a3ba0c0e767c}</Project>
|
<Project>{a3a36689-ac35-4026-93da-a3ba0c0e767c}</Project>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
@ -32,32 +32,31 @@ ZRCola::DBSource::~DBSource()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ZRCola::DBSource::Open(const wxString& filename)
|
bool ZRCola::DBSource::Open(LPCTSTR _filename)
|
||||||
{
|
{
|
||||||
wxASSERT_MSG(!m_db, wxT("database already open"));
|
wxASSERT_MSG(!m_db, wxT("database already open"));
|
||||||
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
// Create COM object.
|
// Create COM object.
|
||||||
hr = ::CoCreateInstance(CLSID_CADOConnection, NULL, CLSCTX_ALL, IID_IADOConnection, (LPVOID*)&m_db);
|
HRESULT hr = ::CoCreateInstance(CLSID_CADOConnection, NULL, CLSCTX_ALL, IID_IADOConnection, (LPVOID*)&m_db);
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
// Open the database.
|
// Open the database.
|
||||||
std::wstring cn;
|
std::wstring cn;
|
||||||
cn = L"Driver={Microsoft Access Driver (*.mdb)};";
|
cn = L"Driver={Microsoft Access Driver (*.mdb)};";
|
||||||
cn += L"Dbq=";
|
cn += L"Dbq=";
|
||||||
cn += filename.c_str();
|
cn += _filename;
|
||||||
cn += L";Uid=;Pwd=;";
|
cn += L";Uid=;Pwd=;";
|
||||||
hr = m_db->Open(ATL::CComBSTR(cn.c_str()));
|
hr = m_db->Open(ATL::CComBSTR(cn.c_str()));
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
// Database open and ready.
|
// Database open and ready.
|
||||||
|
filename = _filename;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
wxLogMessage(wxT("Could not open database %s (0x%x)."), filename.c_str(), hr);
|
_ftprintf(stderr, wxT("%s: error ZCC0002: Could not open database (0x%x).\n"), (LPCTSTR)_filename, hr);
|
||||||
LogErrors();
|
LogErrors();
|
||||||
}
|
}
|
||||||
m_db.Release();
|
m_db.Release();
|
||||||
} else
|
} else
|
||||||
wxLogMessage(wxT("Creating ADOConnection object failed (0x%x)."), hr);
|
_ftprintf(stderr, wxT("%s: error ZCC0001: Creating ADOConnection object failed (0x%x).\n"), (LPCTSTR)_filename, hr);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -85,7 +84,7 @@ void ZRCola::DBSource::LogErrors() const
|
|||||||
ATL::CComBSTR desc;
|
ATL::CComBSTR desc;
|
||||||
wxVERIFY(SUCCEEDED(err->get_Description(&desc)));
|
wxVERIFY(SUCCEEDED(err->get_Description(&desc)));
|
||||||
|
|
||||||
wxLogMessage(wxT("ADO Error 0x%x: %ls"), num, (BSTR)desc);
|
_ftprintf(stderr, wxT(" error ADO%x: %ls\n"), num, (BSTR)desc);
|
||||||
|
|
||||||
err->Release();
|
err->Release();
|
||||||
}
|
}
|
||||||
@ -96,17 +95,107 @@ void ZRCola::DBSource::LogErrors() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ZRCola::DBSource::SelectCompositions(ATL::CComPtr<ADORecordset> &rs) const
|
bool ZRCola::DBSource::GetUnicodeString(const CComPtr<ADOField>& f, std::wstring& str) const
|
||||||
|
{
|
||||||
|
wxASSERT_MSG(f, wxT("field is empty"));
|
||||||
|
|
||||||
|
CComVariant v;
|
||||||
|
wxVERIFY(SUCCEEDED(f->get_Value(&v)));
|
||||||
|
|
||||||
|
// Parse the field. Must be "xxxx+xxxx+xxxx..." sequence.
|
||||||
|
wxVERIFY(SUCCEEDED(v.ChangeType(VT_BSTR)));
|
||||||
|
str.clear();
|
||||||
|
for (UINT i = 0, n = ::SysStringLen(V_BSTR(&v)); i < n && V_BSTR(&v)[i];) {
|
||||||
|
// Parse Unicode code.
|
||||||
|
UINT j = 0;
|
||||||
|
wchar_t c = 0;
|
||||||
|
for (; i < n && V_BSTR(&v)[i]; i++, j++) {
|
||||||
|
if (L'0' <= V_BSTR(&v)[i] && V_BSTR(&v)[i] <= L'9') c = c*0x10 + (V_BSTR(&v)[i] - L'0');
|
||||||
|
else if (L'A' <= V_BSTR(&v)[i] && V_BSTR(&v)[i] <= L'F') c = c*0x10 + (V_BSTR(&v)[i] - L'A' + 10);
|
||||||
|
else if (L'a' <= V_BSTR(&v)[i] && V_BSTR(&v)[i] <= L'f') c = c*0x10 + (V_BSTR(&v)[i] - L'a' + 10);
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
if (j <= 0 || 4 < j) {
|
||||||
|
CComBSTR fieldname; wxVERIFY(SUCCEEDED(f->get_Name(&fieldname)));
|
||||||
|
_ftprintf(stderr, wxT("%s: error ZCC0020: Syntax error in \"%.*ls\" field (\"%.*ls\"). Unicode code must be one to four hexadecimal characters long.\n"), filename.c_str(), fieldname.Length(), (BSTR)fieldname, n, V_BSTR(&v));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
str += c;
|
||||||
|
|
||||||
|
// Skip delimiter(s) and whitespace.
|
||||||
|
for (; i < n && V_BSTR(&v)[i] && (V_BSTR(&v)[i] == L'+' || iswspace(V_BSTR(&v)[i])); i++);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ZRCola::DBSource::GetUnicodeCharacter(const CComPtr<ADOField>& f, wchar_t& chr) const
|
||||||
|
{
|
||||||
|
wxASSERT_MSG(f, wxT("field is empty"));
|
||||||
|
|
||||||
|
CComVariant v;
|
||||||
|
wxVERIFY(SUCCEEDED(f->get_Value(&v)));
|
||||||
|
|
||||||
|
// Parse the field. Must be exactly one Unicode code.
|
||||||
|
wxVERIFY(SUCCEEDED(v.ChangeType(VT_BSTR)));
|
||||||
|
UINT i = 0, n = ::SysStringLen(V_BSTR(&v));
|
||||||
|
chr = 0;
|
||||||
|
for (; i < n && V_BSTR(&v)[i]; i++) {
|
||||||
|
if (L'0' <= V_BSTR(&v)[i] && V_BSTR(&v)[i] <= L'9') chr = chr*0x10 + (V_BSTR(&v)[i] - L'0');
|
||||||
|
else if (L'A' <= V_BSTR(&v)[i] && V_BSTR(&v)[i] <= L'F') chr = chr*0x10 + (V_BSTR(&v)[i] - L'A' + 10);
|
||||||
|
else if (L'a' <= V_BSTR(&v)[i] && V_BSTR(&v)[i] <= L'f') chr = chr*0x10 + (V_BSTR(&v)[i] - L'a' + 10);
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
if (i <= 0 && 4 < i) {
|
||||||
|
CComBSTR fieldname; wxVERIFY(SUCCEEDED(f->get_Name(&fieldname)));
|
||||||
|
_ftprintf(stderr, wxT("%s: error ZCC0020: Syntax error in \"%.*ls\" field (\"%.*ls\"). Unicode code must be one to four hexadecimal characters long.\n"), filename.c_str(), fieldname.Length(), (BSTR)fieldname, n, V_BSTR(&v));
|
||||||
|
return false;
|
||||||
|
} else if (i != n) {
|
||||||
|
CComBSTR fieldname; wxVERIFY(SUCCEEDED(f->get_Name(&fieldname)));
|
||||||
|
_ftprintf(stderr, wxT("%s: error ZCC0021: Syntax error in \"%.*ls\" field (\"%.*ls\"). Extra trailing characters.\n"), filename.c_str(), fieldname.Length(), (BSTR)fieldname, n, V_BSTR(&v));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ZRCola::DBSource::SelectTranslations(ATL::CComPtr<ADORecordset> &rs) const
|
||||||
{
|
{
|
||||||
// Create a new recordset.
|
// Create a new recordset.
|
||||||
if (rs) rs.Release();
|
if (rs) rs.Release();
|
||||||
wxCHECK(SUCCEEDED(::CoCreateInstance(CLSID_CADORecordset, NULL, CLSCTX_ALL, IID_IADORecordset, (LPVOID*)&rs)), false);
|
wxCHECK(SUCCEEDED(::CoCreateInstance(CLSID_CADORecordset, NULL, CLSCTX_ALL, IID_IADORecordset, (LPVOID*)&rs)), false);
|
||||||
|
|
||||||
// Open it.
|
// Open it.
|
||||||
if (FAILED(rs->Open(ATL::CComVariant(L"SELECT [komb], [znak] FROM [VRS_ReplChar] WHERE [rang_komb]=1 ORDER BY [komb] ASC"), ATL::CComVariant(m_db), adOpenForwardOnly, adLockReadOnly, adCmdText))) {
|
if (FAILED(rs->Open(ATL::CComVariant(L"SELECT [komb], [znak] FROM [VRS_ReplChar] WHERE [rang_komb]=1"), ATL::CComVariant(m_db), adOpenStatic, adLockReadOnly, adCmdText))) {
|
||||||
|
_ftprintf(stderr, wxT("%s: error ZCC0010: Error loading compositions from database. Please make sure the file is ZRCola.zrc compatible.\n"), filename.c_str());
|
||||||
LogErrors();
|
LogErrors();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ZRCola::DBSource::GetTranslation(const ATL::CComPtr<ADORecordset>& rs, ZRCola::DBSource::translation& t) const
|
||||||
|
{
|
||||||
|
wxASSERT_MSG(rs, wxT("recordset is empty"));
|
||||||
|
|
||||||
|
CComPtr<ADOFields> flds;
|
||||||
|
wxVERIFY(SUCCEEDED(rs->get_Fields(&flds)));
|
||||||
|
|
||||||
|
{
|
||||||
|
CComPtr<ADOField> f;
|
||||||
|
wxVERIFY(SUCCEEDED(flds->get_Item(CComVariant(L"komb"), &f)));
|
||||||
|
wxCHECK(GetUnicodeString(f, t.str), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
CComPtr<ADOField> f;
|
||||||
|
wxVERIFY(SUCCEEDED(flds->get_Item(CComVariant(L"znak"), &f)));
|
||||||
|
wxCHECK(GetUnicodeCharacter(f, t.chr), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@ -19,22 +19,32 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <wx/string.h>
|
|
||||||
|
|
||||||
#include <atlbase.h>
|
#include <atlbase.h>
|
||||||
|
|
||||||
#include <adoint.h>
|
#include <adoint.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
namespace ZRCola {
|
namespace ZRCola {
|
||||||
///
|
///
|
||||||
/// Source database
|
/// Source database
|
||||||
///
|
///
|
||||||
class DBSource {
|
class DBSource
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
///
|
||||||
|
/// Translation
|
||||||
|
///
|
||||||
|
class translation {
|
||||||
|
public:
|
||||||
|
wchar_t chr; ///< composed character
|
||||||
|
std::wstring str; ///< decomposed string
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DBSource();
|
DBSource();
|
||||||
virtual ~DBSource();
|
virtual ~DBSource();
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Opens the database
|
/// Opens the database
|
||||||
///
|
///
|
||||||
@ -44,15 +54,73 @@ namespace ZRCola {
|
|||||||
/// - true when open succeeds
|
/// - true when open succeeds
|
||||||
/// - false otherwise
|
/// - false otherwise
|
||||||
///
|
///
|
||||||
bool Open(const wxString& filename);
|
bool Open(LPCTSTR filename);
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Logs errors in database connections
|
/// Logs errors in database connections
|
||||||
///
|
///
|
||||||
void LogErrors() const;
|
void LogErrors() const;
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Returns ordered decomposed to composed character translations
|
/// Is recordset at end
|
||||||
|
///
|
||||||
|
/// \param[out] rs Recordset with results
|
||||||
|
///
|
||||||
|
/// \returns
|
||||||
|
/// - true when at end
|
||||||
|
/// - false otherwise
|
||||||
|
///
|
||||||
|
static inline bool IsEOF(const ATL::CComPtr<ADORecordset>& rs)
|
||||||
|
{
|
||||||
|
VARIANT_BOOL eof = VARIANT_TRUE;
|
||||||
|
return FAILED(rs->get_EOF(&eof)) || eof ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Gets number of records in a recordset
|
||||||
|
///
|
||||||
|
/// \param[out] rs Recordset with results
|
||||||
|
///
|
||||||
|
/// \returns Number of records
|
||||||
|
///
|
||||||
|
static inline size_t GetRecordsetCount(const ATL::CComPtr<ADORecordset>& rs)
|
||||||
|
{
|
||||||
|
ADO_LONGPTR count;
|
||||||
|
return SUCCEEDED(rs->get_RecordCount(&count)) ? count : (size_t)-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Gets encoded Unicode string from ZRCola.zrc database
|
||||||
|
///
|
||||||
|
/// \param[in] f Data field
|
||||||
|
/// \param[out] str Output string
|
||||||
|
///
|
||||||
|
/// \returns
|
||||||
|
/// - true when successful
|
||||||
|
/// - false otherwise
|
||||||
|
///
|
||||||
|
bool GetUnicodeString(const CComPtr<ADOField>& f, std::wstring& str) const;
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Gets encoded Unicode character from ZRCola.zrc database
|
||||||
|
///
|
||||||
|
/// \param[in] f Data field
|
||||||
|
/// \param[out] chr Output character
|
||||||
|
///
|
||||||
|
/// \returns
|
||||||
|
/// - true when successful
|
||||||
|
/// - false otherwise
|
||||||
|
///
|
||||||
|
bool GetUnicodeCharacter(const CComPtr<ADOField>& f, wchar_t& chr) const;
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Returns character translations
|
||||||
///
|
///
|
||||||
/// \param[out] rs Recordset with results
|
/// \param[out] rs Recordset with results
|
||||||
///
|
///
|
||||||
@ -60,9 +128,23 @@ namespace ZRCola {
|
|||||||
/// - true when query succeeds
|
/// - true when query succeeds
|
||||||
/// - false otherwise
|
/// - false otherwise
|
||||||
///
|
///
|
||||||
bool SelectCompositions(ATL::CComPtr<ADORecordset> &rs) const;
|
bool SelectTranslations(ATL::CComPtr<ADORecordset>& rs) const;
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Returns translation data
|
||||||
|
///
|
||||||
|
/// \param[in] rs Recordset with results
|
||||||
|
/// \param[out] t Translation
|
||||||
|
///
|
||||||
|
/// \returns
|
||||||
|
/// - true when succeeded
|
||||||
|
/// - false otherwise
|
||||||
|
///
|
||||||
|
bool GetTranslation(const ATL::CComPtr<ADORecordset>& rs, translation& t) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ATL::CComPtr<ADOConnection> m_db; ///< the database
|
std::basic_string<TCHAR> filename; ///< the database filename
|
||||||
|
ATL::CComPtr<ADOConnection> m_db; ///< the database
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -20,6 +20,62 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
|
||||||
|
|
||||||
|
static inline int CompareBinary(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) break;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int __cdecl CompareCompositionIndex(void *data, const void *a, const void *b)
|
||||||
|
{
|
||||||
|
const wchar_t
|
||||||
|
*chr_a = (const wchar_t*)data + ((const ZRCola::translation_index*)a)->start,
|
||||||
|
*chr_b = (const wchar_t*)data + ((const ZRCola::translation_index*)b)->start;
|
||||||
|
const wchar_t
|
||||||
|
*str_a = chr_a + 1,
|
||||||
|
*str_b = chr_b + 1;
|
||||||
|
size_t
|
||||||
|
count_a = (const wchar_t*)data + ((const ZRCola::translation_index*)a)->end - str_a,
|
||||||
|
count_b = (const wchar_t*)data + ((const ZRCola::translation_index*)b)->end - str_b;
|
||||||
|
|
||||||
|
int r = CompareBinary(str_a, count_a, str_b, count_b);
|
||||||
|
if (r != 0) return r;
|
||||||
|
|
||||||
|
if (*chr_a < *chr_b) return -1;
|
||||||
|
else if (*chr_a > *chr_b) return +1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int __cdecl CompareDecompositionIndex(void *data, const void *a, const void *b)
|
||||||
|
{
|
||||||
|
const wchar_t
|
||||||
|
*chr_a = (const wchar_t*)data + ((const ZRCola::translation_index*)a)->start,
|
||||||
|
*chr_b = (const wchar_t*)data + ((const ZRCola::translation_index*)b)->start;
|
||||||
|
|
||||||
|
if (*chr_a < *chr_b) return -1;
|
||||||
|
else if (*chr_a > *chr_b) return +1;
|
||||||
|
|
||||||
|
const wchar_t
|
||||||
|
*str_a = chr_a + 1,
|
||||||
|
*str_b = chr_b + 1;
|
||||||
|
size_t
|
||||||
|
count_a = (const wchar_t*)data + ((const ZRCola::translation_index*)a)->end - str_a,
|
||||||
|
count_b = (const wchar_t*)data + ((const ZRCola::translation_index*)b)->end - str_b;
|
||||||
|
|
||||||
|
return CompareBinary(str_a, count_a, str_b, count_b);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Main function
|
/// Main function
|
||||||
///
|
///
|
||||||
@ -83,18 +139,97 @@ int _tmain(int argc, _TCHAR *argv[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxFile dst;
|
|
||||||
const wxString& filenameOut = parser.GetParam(1);
|
const wxString& filenameOut = parser.GetParam(1);
|
||||||
if (!dst.Create(filenameOut, true, wxS_IRUSR | wxS_IWUSR | wxS_IRGRP | wxS_IWGRP | wxS_IROTH)) {
|
std::fstream dst((LPCTSTR)filenameOut, std::ios_base::out | std::ios_base::trunc | std::ios_base::binary);
|
||||||
|
if (dst.fail()) {
|
||||||
_ftprintf(stderr, _("Error opening %s output file.\n"), filenameOut.fn_str());
|
_ftprintf(stderr, _("Error opening %s output file.\n"), filenameOut.fn_str());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ATL::CComPtr<ADORecordset> rs_comp;
|
bool has_errors = false;
|
||||||
if (!src.SelectCompositions(rs_comp)) {
|
|
||||||
_ftprintf(stderr, _("Error loading compositions from %s input file. Please make sure the input file is ZRCola.zrc compatible.\n"), filenameIn.fn_str());
|
// Open file ID.
|
||||||
return 1;
|
std::streamoff dst_start = stdex::idrec::open<ZRCola::recordid_t, ZRCola::recordsize_t>(dst, ZRCOLA_DB_ID);
|
||||||
|
|
||||||
|
{
|
||||||
|
// Get translations.
|
||||||
|
ATL::CComPtr<ADORecordset> rs;
|
||||||
|
if (src.SelectTranslations(rs)) {
|
||||||
|
size_t trans_count = src.GetRecordsetCount(rs);
|
||||||
|
if (trans_count < 0xffffffff) { // 4G check (-1 is reserved for error condition)
|
||||||
|
// Allocate memory.
|
||||||
|
std::vector<ZRCola::translation_index> comp_index;
|
||||||
|
comp_index.reserve(trans_count);
|
||||||
|
std::vector<ZRCola::translation_index> decomp_index;
|
||||||
|
decomp_index.reserve(trans_count);
|
||||||
|
std::vector<wchar_t> comp_data;
|
||||||
|
comp_data.reserve(trans_count*4);
|
||||||
|
ZRCola::DBSource::translation trans;
|
||||||
|
|
||||||
|
// Parse translations and build index and data.
|
||||||
|
while (!ZRCola::DBSource::IsEOF(rs)) {
|
||||||
|
// Read translation from the database.
|
||||||
|
if (src.GetTranslation(rs, trans)) {
|
||||||
|
// Add translation to index and data.
|
||||||
|
ZRCola::translation_index ti;
|
||||||
|
ti.start = comp_data.size();
|
||||||
|
comp_data.push_back(trans.chr);
|
||||||
|
for (std::wstring::size_type i = 0, n = trans.str.length(); i < n; i++)
|
||||||
|
comp_data.push_back(trans.str[i]);
|
||||||
|
ti.end = comp_data.size();
|
||||||
|
comp_index.push_back(ti);
|
||||||
|
decomp_index.push_back(ti);
|
||||||
|
} else
|
||||||
|
has_errors = true;
|
||||||
|
|
||||||
|
wxVERIFY(SUCCEEDED(rs->MoveNext()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort indices.
|
||||||
|
qsort_s( comp_index.data(), trans_count, sizeof(ZRCola::translation_index), CompareCompositionIndex , comp_data.data());
|
||||||
|
qsort_s(decomp_index.data(), trans_count, sizeof(ZRCola::translation_index), CompareDecompositionIndex, comp_data.data());
|
||||||
|
|
||||||
|
// Write translations to file.
|
||||||
|
std::streamoff start = stdex::idrec::open<ZRCola::recordid_t, ZRCola::recordsize_t>(dst, ZRCOLA_DB_COMPOSITIONS_ID);
|
||||||
|
{
|
||||||
|
unsigned int _count = trans_count;
|
||||||
|
dst.write((const char*)&_count, sizeof(_count));
|
||||||
|
dst.write((const char*) comp_index.data(), sizeof(__int32)*_count);
|
||||||
|
dst.write((const char*)decomp_index.data(), sizeof(__int32)*_count);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::vector<wchar_t>::size_type count = comp_data.size();
|
||||||
|
if (count <= 0xffffffff) { // 4G check
|
||||||
|
unsigned int _count = (unsigned int)count;
|
||||||
|
dst.write((const char*)&_count, sizeof(_count));
|
||||||
|
dst.write((const char*)comp_data.data(), sizeof(wchar_t)*_count);
|
||||||
|
} else {
|
||||||
|
_ftprintf(stderr, wxT("%s: error ZCC0005: Translation data exceeds 4G.\n"), (LPCTSTR)filenameIn.c_str());
|
||||||
|
has_errors = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stdex::idrec::close<ZRCola::recordid_t, ZRCola::recordsize_t, ZRCOLA_RECORD_ALIGN>(dst, start);
|
||||||
|
} else {
|
||||||
|
_ftprintf(stderr, wxT("%s: error ZCC0004: Error getting translation count from database or too many translations.\n"), (LPCTSTR)filenameIn.c_str());
|
||||||
|
has_errors = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_ftprintf(stderr, wxT("%s: error ZCC0003: Error getting translations from database. Please make sure the file is ZRCola.zrc compatible.\n"), (LPCTSTR)filenameIn.c_str());
|
||||||
|
has_errors = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
stdex::idrec::close<ZRCola::recordid_t, ZRCola::recordsize_t, ZRCOLA_RECORD_ALIGN>(dst, dst_start);
|
||||||
|
|
||||||
|
if (dst.fail()) {
|
||||||
|
_ftprintf(stderr, wxT("Writing to %s output file failed.\n"), (LPCTSTR)filenameOut.c_str());
|
||||||
|
has_errors = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_errors) {
|
||||||
|
dst.close();
|
||||||
|
wxRemoveFile(filenameOut);
|
||||||
|
return 1;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -22,16 +22,23 @@
|
|||||||
#include "../include/zrcola.h"
|
#include "../include/zrcola.h"
|
||||||
#include "dbsource.h"
|
#include "dbsource.h"
|
||||||
|
|
||||||
|
#include <zrcola/compose.h>
|
||||||
|
|
||||||
#include <wx/app.h>
|
#include <wx/app.h>
|
||||||
#include <wx/cmdline.h>
|
#include <wx/cmdline.h>
|
||||||
#include <wx/file.h>
|
|
||||||
#include <wx/intl.h>
|
#include <wx/intl.h>
|
||||||
|
|
||||||
#include <wxex/common.h>
|
#include <wxex/common.h>
|
||||||
#include <wxex/comutils.h>
|
#include <wxex/comutils.h>
|
||||||
|
|
||||||
|
#include <stdex/idrec.h>
|
||||||
|
|
||||||
#include <initguid.h> // GUID helper to prevent LNK2001 errors (unresolved external symbol IID_IADO...)
|
#include <initguid.h> // GUID helper to prevent LNK2001 errors (unresolved external symbol IID_IADO...)
|
||||||
#include <adoint.h>
|
#include <adoint.h>
|
||||||
#include <adoid.h>
|
#include <adoid.h>
|
||||||
|
|
||||||
#include <tchar.h>
|
#include <tchar.h>
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
<ItemDefinitionGroup>
|
<ItemDefinitionGroup>
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<PreprocessorDefinitions>LIBZRCOLA;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>LIBZRCOLA;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<AdditionalIncludeDirectories>..\..\stdex\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -43,11 +43,6 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="..\res\libZRCola.rc" />
|
<ResourceCompile Include="..\res\libZRCola.rc" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\..\stdex\build\stdex.vcxproj">
|
|
||||||
<Project>{518777cc-0a59-4415-a12a-82751ed75343}</Project>
|
|
||||||
</ProjectReference>
|
|
||||||
</ItemGroup>
|
|
||||||
<PropertyGroup Label="Globals">
|
<PropertyGroup Label="Globals">
|
||||||
<ProjectGuid>{3C61929E-7289-4101-8D0A-DA22D6E1AEA8}</ProjectGuid>
|
<ProjectGuid>{3C61929E-7289-4101-8D0A-DA22D6E1AEA8}</ProjectGuid>
|
||||||
<RootNamespace>libZRCola</RootNamespace>
|
<RootNamespace>libZRCola</RootNamespace>
|
||||||
|
@ -35,7 +35,39 @@
|
|||||||
#pragma warning(disable: 4251)
|
#pragma warning(disable: 4251)
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Data records alignment
|
||||||
|
///
|
||||||
|
#define ZRCOLA_RECORD_ALIGN 1
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Database IDs
|
||||||
|
///
|
||||||
|
#define ZRCOLA_DB_ID ((ZRCola::recordid_t)0x0043525a)
|
||||||
|
#define ZRCOLA_DB_COMPOSITIONS_ID ((ZRCola::recordid_t)0x00000001)
|
||||||
|
#define ZRCOLA_DB_DECOMPOSITIONS_ID ((ZRCola::recordid_t)0x00000002)
|
||||||
|
|
||||||
|
|
||||||
namespace ZRCola {
|
namespace ZRCola {
|
||||||
|
typedef unsigned __int32 recordid_t;
|
||||||
|
typedef unsigned __int32 recordsize_t;
|
||||||
|
|
||||||
|
|
||||||
|
#pragma pack(push)
|
||||||
|
#pragma pack(4)
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Translation index
|
||||||
|
///
|
||||||
|
struct translation_index {
|
||||||
|
unsigned __int32 start; ///< Composed character offset
|
||||||
|
unsigned __int32 end; ///< Decomposed string end offset
|
||||||
|
};
|
||||||
|
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Composed-decomposed index transformation mapping
|
/// Composed-decomposed index transformation mapping
|
||||||
///
|
///
|
||||||
|
@ -26,6 +26,15 @@
|
|||||||
|
|
||||||
|
|
||||||
namespace ZRCola {
|
namespace ZRCola {
|
||||||
|
///
|
||||||
|
/// Composition
|
||||||
|
///
|
||||||
|
struct composition {
|
||||||
|
const wchar_t *src; ///< Decomposed string
|
||||||
|
wchar_t dst; ///< Composed character
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Composes string
|
/// Composes string
|
||||||
///
|
///
|
||||||
|
@ -26,6 +26,15 @@
|
|||||||
|
|
||||||
|
|
||||||
namespace ZRCola {
|
namespace ZRCola {
|
||||||
|
///
|
||||||
|
/// Decomposition
|
||||||
|
///
|
||||||
|
struct decomposition {
|
||||||
|
wchar_t src; ///< composed character
|
||||||
|
const wchar_t *dst; ///< decomposed string
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Decomposes string
|
/// Decomposes string
|
||||||
///
|
///
|
||||||
|
@ -26,19 +26,9 @@
|
|||||||
|
|
||||||
|
|
||||||
namespace ZRCola {
|
namespace ZRCola {
|
||||||
struct composition {
|
|
||||||
const wchar_t *src;
|
|
||||||
wchar_t dst;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern const composition* compositions;
|
extern const composition* compositions;
|
||||||
extern const size_t compositionsCount;
|
extern const size_t compositionsCount;
|
||||||
|
|
||||||
struct decomposition {
|
|
||||||
wchar_t src;
|
|
||||||
const wchar_t *dst;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern const decomposition* decompositions;
|
extern const decomposition* decompositions;
|
||||||
extern const size_t decompositionsCount;
|
extern const size_t decompositionsCount;
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit f86db2052780c33fae23815f066c7b71002acdd8
|
Subproject commit 72766c21b2889ac13c94f4645638fe043dfa35d7
|
Loading…
x
Reference in New Issue
Block a user