Index: src/libictranslate/ResourceManager.cpp =================================================================== diff -u -N -r3275c48bbd0163b93e9a13c72abb77be85e92c54 -r50fea83cc4ee863edac0fd3960e2249f99c33b03 --- src/libictranslate/ResourceManager.cpp (.../ResourceManager.cpp) (revision 3275c48bbd0163b93e9a13c72abb77be85e92c54) +++ src/libictranslate/ResourceManager.cpp (.../ResourceManager.cpp) (revision 50fea83cc4ee863edac0fd3960e2249f99c33b03) @@ -20,6 +20,7 @@ #include "stdafx.h" #include "ResourceManager.h" #include "../libicpf/cfg.h" +#include "../libicpf/crc32.h" #include #ifdef _DEBUG @@ -30,6 +31,124 @@ #define EMPTY_STRING _t("") +CTranslationItem::CTranslationItem() : + m_pszText(NULL), + m_uiChecksum(0), + m_stTextLength(0) +{ +} + +CTranslationItem::CTranslationItem(const tchar_t* pszText, uint_t uiChecksum) : + m_pszText(NULL), + m_stTextLength(0), + m_uiChecksum(uiChecksum) +{ + if(pszText) + { + m_stTextLength = _tcslen(pszText); + if(m_stTextLength > 0) + { + m_pszText = new tchar_t[m_stTextLength + 1]; + _tcscpy(m_pszText, pszText); + + UnescapeString(); + } + } +} + +CTranslationItem::~CTranslationItem() +{ + Clear(); +} + +CTranslationItem& CTranslationItem::operator=(const CTranslationItem& rSrc) +{ + if(this != &rSrc) + { + Clear(); + if(rSrc.m_pszText) + { + m_stTextLength = rSrc.m_stTextLength; + if(m_stTextLength > 0) + { + m_pszText = new tchar_t[rSrc.m_stTextLength + 1]; + _tcscpy(m_pszText, rSrc.m_pszText); + } + } + m_uiChecksum = rSrc.m_uiChecksum; + } + + return *this; +} + +void CTranslationItem::Clear() +{ + delete [] m_pszText; + m_pszText = NULL; + m_stTextLength = 0; + m_uiChecksum = 0; +} + +void CTranslationItem::CalculateChecksum() +{ + if(m_pszText) + m_uiChecksum = icpf::crc32((const byte_t*)m_pszText, m_stTextLength*sizeof(tchar_t)); + else + m_uiChecksum = 0; +} + +void CTranslationItem::SetText(const tchar_t* pszText) +{ + delete [] m_pszText; + if(pszText) + { + m_stTextLength = _tcslen(pszText); + if(m_stTextLength > 0) + { + m_pszText = new tchar_t[m_stTextLength + 1]; + _tcscpy(m_pszText, pszText); + UnescapeString(); + return; + } + } + + m_pszText = NULL; + m_stTextLength = 0; +} + +void CTranslationItem::UnescapeString() +{ + if(!m_pszText) + return; + + const tchar_t* pszIn = m_pszText; + tchar_t* pszOut = m_pszText; + while (*pszIn != 0) + { + if (*pszIn == _T('\\')) + { + pszIn++; + switch(*pszIn++) + { + case _T('t'): + *pszOut++ = _T('\t'); + break; + case _T('r'): + *pszOut++ = _T('\r'); + break; + case _T('n'): + *pszOut++ = _T('\n'); + break; + default: + *pszOut++ = _T('\\'); + } + } + else + *pszOut++ = *pszIn++; + } + *pszOut = _T('\0'); +} + CLangData::CLangData() : m_pszFilename(NULL), m_pszLngName(NULL), @@ -51,11 +170,6 @@ delete [] m_pszHelpName; delete [] m_pszAuthor; delete [] m_pszVersion; - - for(strings_map::iterator it = m_mStrings.begin(); it != m_mStrings.end(); it++) - { - delete [] (*it).second; - } } void CLangData::Clear() @@ -75,12 +189,7 @@ delete [] m_pszVersion; m_pszVersion = NULL; - for(strings_map::iterator it = m_mStrings.begin(); it != m_mStrings.end(); it++) - { - delete [] (*it).second; - } - m_mStrings.clear(); - m_mChecksums.clear(); + m_mapTranslation.clear(); } CLangData::CLangData(const CLangData& ld) : @@ -212,59 +321,63 @@ } else { + uint_t uiID = 0; + uint_t uiChecksum = 0; + // parse the pszName to get both the string id and checksum const tchar_t* pszChecksum = _tcschr(pszName, _T('[')); if(pszChecksum == NULL) { - TRACE(_T("Warning! Old-style translation string %s; skipping.\n"), pszName); - return; // old-style translation; assume incompatibility - } + TRACE(_T("Warning! Old-style translation string %s.\n"), pszName); - UINT uiID = 0; - UINT uiChecksum = 0; - int iCount = _stscanf(pszName, UIFMT _T("[0x%lx]"), &uiID, &uiChecksum); - if(iCount != 2) + int iCount = _stscanf(pszName, UIFMT, &uiID); + if(iCount != 1) + { + TRACE(_T("Warning! Problem retrieving id from string '%s'\n"), pszName); + return; + } + } + else { - TRACE(_T("Warning! Problem retrieving checksum from string '%s'\n"), pszName); - return; + int iCount = _stscanf(pszName, UIFMT _T("[0x%lx]"), &uiID, &uiChecksum); + if(iCount != 2) + { + TRACE(_T("Warning! Problem retrieving id/checksum from string '%s'\n"), pszName); + return; + } } uint_t uiKey = pLangData->m_uiSectionID << 16 | uiID; + translation_map::iterator itTranslation = pLangData->m_mapTranslation.end(); if(pLangData->m_bUpdating) { // check if the checksum exists and matches - checksum_map::const_iterator itChecksum = pLangData->m_mChecksums.find(uiKey); - if(itChecksum == pLangData->m_mChecksums.end()) + itTranslation = pLangData->m_mapTranslation.find(uiKey); + if(itTranslation == pLangData->m_mapTranslation.end()) { TRACE(_T("Warning! Superfluous entry %lu in processed language file\n"), uiKey); return; // entry not found - probably superfluous entry in the language file } - if((*itChecksum).second != uiChecksum) + if((*itTranslation).second.GetChecksum() != uiChecksum) { TRACE(_T("Warning! Invalid checksum for string ID %lu in processed language file\n"), uiKey); return; // entry has invalid checksum (older version of translation) } - - // check if the entry already exists - strings_map::iterator it = pLangData->m_mStrings.find(uiKey); - if(it != pLangData->m_mStrings.end()) - { - delete [] (*it).second; - pLangData->m_mStrings.erase(it); - } } + else + { + std::pair pairTranslation = pLangData->m_mapTranslation.insert(translation_map::value_type(uiKey, CTranslationItem())); + itTranslation = pairTranslation.first; + } - size_t stLen = _tcslen(pszValue); - tchar_t* pszStr = new tchar_t[stLen + 1]; - _tcscpy(pszStr, pszValue); - - // convert escape strings into escape sequences - CLangData::UnescapeString(pszStr); - - pLangData->m_mStrings.insert(strings_map::value_type(uiKey, pszStr)); - if(!pLangData->m_bUpdating) - pLangData->m_mChecksums.insert(checksum_map::value_type(uiKey, uiChecksum)); + assert(itTranslation != pLangData->m_mapTranslation.end()); + if(itTranslation != pLangData->m_mapTranslation.end()) + { + (*itTranslation).second.SetText(pszValue); + if(!pLangData->m_bUpdating) + (*itTranslation).second.SetChecksum(uiChecksum); + } } } @@ -385,13 +498,21 @@ PCTSTR CLangData::GetString(WORD wHiID, WORD wLoID) { - strings_map::iterator it=m_mStrings.find((wHiID << 16) | wLoID); - if (it != m_mStrings.end()) - return (*it).second; + translation_map::const_iterator it=m_mapTranslation.find((wHiID << 16) | wLoID); + if (it != m_mapTranslation.end()) + return (*it).second.GetText(); else return EMPTY_STRING; } +void CLangData::EnumStrings(PFNENUMCALLBACK pfnCallback, ptr_t pData) +{ + for(translation_map::const_iterator iterTranslation = m_mapTranslation.begin(); iterTranslation != m_mapTranslation.end(); ++iterTranslation) + { + (*pfnCallback)((*iterTranslation).first, &(*iterTranslation).second, pData); + } +} + void CLangData::SetFilename(PCTSTR psz) { if (m_pszFilename)