#ifndef ILOCALIZE_H #define ILOCALIZE_H #ifdef _WIN32 #pragma once #endif #include "IAppSystem.h" #include "KeyValues.h" #if !defined(_WCHAR_T_DEFINED) && !defined(GNUC) typedef unsigned short wchar_t; #define _WCHAR_T_DEFINED #endif typedef unsigned long StringIndex_t; const unsigned long INVALID_LOCALIZE_STRING_INDEX = (StringIndex_t)-1; abstract_class ILocalize { public: virtual bool AddFile(const char* fileName, const char* pPathID = NULL, bool bIncludeFallbackSearchPaths = false) = 0; virtual void RemoveAll() = 0; virtual wchar_t* Find(char const* tokenName) = 0; virtual StringIndex_t FindIndex(const char* tokenName) = 0; virtual const char* GetNameByIndex(StringIndex_t index) = 0; virtual wchar_t* GetValueByIndex(StringIndex_t index) = 0; virtual StringIndex_t GetFirstStringIndex() = 0; virtual StringIndex_t GetNextStringIndex(StringIndex_t index) = 0; virtual void AddString(const char* tokenName, wchar_t* unicodeString, const char* fileName) = 0; virtual void SetValueByIndex(StringIndex_t index, wchar_t* newValue) = 0; virtual bool SaveToFile(const char* fileName) = 0; virtual int GetLocalizationFileCount() = 0; virtual const char* GetLocalizationFileName(int index) = 0; virtual const char* GetFileNameByIndex(StringIndex_t index) = 0; virtual void ReloadLocalizationFiles() = 0; virtual const char* FindAsUTF8(const char* pchTokenName) = 0; virtual void ConstructString(OUT_Z_BYTECAP(unicodeBufferSizeInBytes) wchar_t* unicodeOutput, int unicodeBufferSizeInBytes, const char* tokenName, KeyValues* localizationVariables) = 0; virtual void ConstructString(OUT_Z_BYTECAP(unicodeBufferSizeInBytes) wchar_t* unicodeOutput, int unicodeBufferSizeInBytes, StringIndex_t unlocalizedTextSymbol, KeyValues* localizationVariables) = 0; static int ConvertANSIToUnicode(const char* ansi, OUT_Z_BYTECAP(unicodeBufferSizeInBytes) wchar_t* unicode, int unicodeBufferSizeInBytes); static int ConvertUnicodeToANSI(const wchar_t* unicode, OUT_Z_BYTECAP(ansiBufferSize) char* ansi, int ansiBufferSize); template < typename T > static void ConstructString(OUT_Z_BYTECAP(unicodeBufferSizeInBytes) T* unicodeOuput, int unicodeBufferSizeInBytes, const T* formatString, int numFormatParameters, ...) { va_list argList; va_start(argList, numFormatParameters); ConstructStringVArgsInternal(unicodeOuput, unicodeBufferSizeInBytes, formatString, numFormatParameters, argList); va_end(argList); } template < typename T > static void ConstructStringVArgs(OUT_Z_BYTECAP(unicodeBufferSizeInBytes) T* unicodeOuput, int unicodeBufferSizeInBytes, const T* formatString, int numFormatParameters, va_list argList) { ConstructStringVArgsInternal(unicodeOuput, unicodeBufferSizeInBytes, formatString, numFormatParameters, argList); } template < typename T > static void ConstructString(OUT_Z_BYTECAP(unicodeBufferSizeInBytes) T* unicodeOutput, int unicodeBufferSizeInBytes, const T* formatString, KeyValues* localizationVariables) { ConstructStringKeyValuesInternal(unicodeOutput, unicodeBufferSizeInBytes, formatString, localizationVariables); } private: static void ConstructStringVArgsInternal(OUT_Z_BYTECAP(unicodeBufferSizeInBytes) char* unicodeOutput, int unicodeBufferSizeInBytes, const char* formatString, int numFormatParameters, va_list argList); static void ConstructStringVArgsInternal(OUT_Z_BYTECAP(unicodeBufferSizeInBytes) wchar_t* unicodeOutput, int unicodeBufferSizeInBytes, const wchar_t* formatString, int numFormatParameters, va_list argList); static void ConstructStringKeyValuesInternal(OUT_Z_BYTECAP(unicodeBufferSizeInBytes) char* unicodeOutput, int unicodeBufferSizeInBytes, const char* formatString, KeyValues* localizationVariables); static void ConstructStringKeyValuesInternal(OUT_Z_BYTECAP(unicodeBufferSizeInBytes) wchar_t* unicodeOutput, int unicodeBufferSizeInBytes, const wchar_t* formatString, KeyValues* localizationVariables); }; #ifdef GC typedef char locchar_t; #define loc_snprintf Q_snprintf #define loc_sprintf_safe V_sprintf_safe #define loc_sncat Q_strncat #define loc_scat_safe V_strcat_safe #define loc_sncpy Q_strncpy #define loc_scpy_safe V_strcpy_safe #define loc_strlen Q_strlen #define LOCCHAR( x ) x #else typedef wchar_t locchar_t; #define loc_snprintf V_snwprintf #define loc_sprintf_safe V_swprintf_safe #define loc_sncat V_wcsncat #define loc_scat_safe V_wcscat_safe #define loc_sncpy Q_wcsncpy #define loc_scpy_safe V_wcscpy_safe #define loc_strlen Q_wcslen #define LOCCHAR(x) L ## x #endif template < typename T > class TypedKeyValuesStringHelper { public: static const T* Read(KeyValues* pKeyValues, const char* pKeyName, const T* pDefaultValue); static void Write(KeyValues* pKeyValues, const char* pKeyName, const T* pValue); }; template < > class TypedKeyValuesStringHelper { public: static const char* Read(KeyValues* pKeyValues, const char* pKeyName, const char* pDefaultValue) { return pKeyValues->GetString(pKeyName, pDefaultValue); } static void Write(KeyValues* pKeyValues, const char* pKeyName, const char* pValue) { pKeyValues->SetString(pKeyName, pValue); } }; template < > class TypedKeyValuesStringHelper { public: static const wchar_t* Read(KeyValues* pKeyValues, const char* pKeyName, const wchar_t* pDefaultValue) { return pKeyValues->GetWString(pKeyName, pDefaultValue); } static void Write(KeyValues* pKeyValues, const char* pKeyName, const wchar_t* pValue) { pKeyValues->SetWString(pKeyName, pValue); } }; template < typename T > class CLocalizedStringArg; template < typename T > class CLocalizedStringArgStringImpl { public: enum { kIsValid = true }; CLocalizedStringArgStringImpl(const locchar_t* pStr) : m_pStr(pStr) { } const locchar_t* GetLocArg() const { Assert(m_pStr); return m_pStr; } private: const locchar_t* m_pStr; }; template < typename T > class CLocalizedStringArg : public CLocalizedStringArgStringImpl { public: CLocalizedStringArg(const locchar_t* pStr) : CLocalizedStringArgStringImpl(pStr) { } }; template < typename T > class CLocalizedStringArgPrintfImpl { public: enum { kIsValid = true }; CLocalizedStringArgPrintfImpl(T value, const locchar_t* loc_Format) { loc_snprintf(m_cBuffer, kBufferSize, loc_Format, value); } const locchar_t* GetLocArg() const { return m_cBuffer; } private: enum { kBufferSize = 128, }; locchar_t m_cBuffer[kBufferSize]; }; template < > class CLocalizedStringArg : public CLocalizedStringArgPrintfImpl { public: CLocalizedStringArg(uint16 unValue) : CLocalizedStringArgPrintfImpl(unValue, LOCCHAR("%u")) { } }; template < > class CLocalizedStringArg : public CLocalizedStringArgPrintfImpl { public: CLocalizedStringArg(uint32 unValue) : CLocalizedStringArgPrintfImpl(unValue, LOCCHAR("%u")) { } }; template < > class CLocalizedStringArg : public CLocalizedStringArgPrintfImpl { public: CLocalizedStringArg(uint64 unValue) : CLocalizedStringArgPrintfImpl(unValue, LOCCHAR("%llu")) { } }; template < > class CLocalizedStringArg : public CLocalizedStringArgPrintfImpl { public: CLocalizedStringArg(float fValue) : CLocalizedStringArgPrintfImpl(fValue, fabsf(fValue) <= FLT_EPSILON || fabsf(fValue) >= 1.0f ? LOCCHAR("%.0f") : LOCCHAR("%.1f")) { } }; class CConstructLocalizedString { public: template < typename T > CConstructLocalizedString(const locchar_t* loc_Format, T arg0) { COMPILE_TIME_ASSERT(CLocalizedStringArg::kIsValid); m_loc_Buffer[0] = '\0'; if (loc_Format) { ::ILocalize::ConstructString(m_loc_Buffer, sizeof(m_loc_Buffer), loc_Format, 1, CLocalizedStringArg(arg0).GetLocArg()); } } template < typename T, typename U > CConstructLocalizedString(const locchar_t* loc_Format, T arg0, U arg1) { COMPILE_TIME_ASSERT(CLocalizedStringArg::kIsValid); COMPILE_TIME_ASSERT(CLocalizedStringArg::kIsValid); m_loc_Buffer[0] = '\0'; if (loc_Format) { ::ILocalize::ConstructString(m_loc_Buffer, sizeof(m_loc_Buffer), loc_Format, 2, CLocalizedStringArg(arg0).GetLocArg(), CLocalizedStringArg(arg1).GetLocArg()); } } template < typename T, typename U, typename V > CConstructLocalizedString(const locchar_t* loc_Format, T arg0, U arg1, V arg2) { COMPILE_TIME_ASSERT(CLocalizedStringArg::kIsValid); COMPILE_TIME_ASSERT(CLocalizedStringArg::kIsValid); COMPILE_TIME_ASSERT(CLocalizedStringArg::kIsValid); m_loc_Buffer[0] = '\0'; if (loc_Format) { ::ILocalize::ConstructString(m_loc_Buffer, sizeof(m_loc_Buffer), loc_Format, 3, CLocalizedStringArg(arg0).GetLocArg(), CLocalizedStringArg(arg1).GetLocArg(), CLocalizedStringArg(arg2).GetLocArg()); } } template < typename T, typename U, typename V, typename W > CConstructLocalizedString(const locchar_t* loc_Format, T arg0, U arg1, V arg2, W arg3) { COMPILE_TIME_ASSERT(CLocalizedStringArg::kIsValid); COMPILE_TIME_ASSERT(CLocalizedStringArg::kIsValid); COMPILE_TIME_ASSERT(CLocalizedStringArg::kIsValid); COMPILE_TIME_ASSERT(CLocalizedStringArg::kIsValid); m_loc_Buffer[0] = '\0'; if (loc_Format) { ::ILocalize::ConstructString(m_loc_Buffer, sizeof(m_loc_Buffer), loc_Format, 4, CLocalizedStringArg(arg0).GetLocArg(), CLocalizedStringArg(arg1).GetLocArg(), CLocalizedStringArg(arg2).GetLocArg(), CLocalizedStringArg(arg3).GetLocArg()); } } template < typename T, typename U, typename V, typename W, typename X, typename Y > CConstructLocalizedString(const locchar_t* loc_Format, T arg0, U arg1, V arg2, W arg3, X arg4, Y arg5) { COMPILE_TIME_ASSERT(CLocalizedStringArg::kIsValid); COMPILE_TIME_ASSERT(CLocalizedStringArg::kIsValid); COMPILE_TIME_ASSERT(CLocalizedStringArg::kIsValid); COMPILE_TIME_ASSERT(CLocalizedStringArg::kIsValid); COMPILE_TIME_ASSERT(CLocalizedStringArg::kIsValid); COMPILE_TIME_ASSERT(CLocalizedStringArg::kIsValid); m_loc_Buffer[0] = '\0'; if (loc_Format) { ::ILocalize::ConstructString(m_loc_Buffer, sizeof(m_loc_Buffer), loc_Format, 6, CLocalizedStringArg(arg0).GetLocArg(), CLocalizedStringArg(arg1).GetLocArg(), CLocalizedStringArg(arg2).GetLocArg(), CLocalizedStringArg(arg3).GetLocArg(), CLocalizedStringArg(arg4).GetLocArg(), CLocalizedStringArg(arg5).GetLocArg()); } } template < typename T, typename U, typename V, typename W, typename X, typename Y, typename Z > CConstructLocalizedString(const locchar_t* loc_Format, T arg0, U arg1, V arg2, W arg3, X arg4, Y arg5, Z arg6) { COMPILE_TIME_ASSERT(CLocalizedStringArg::kIsValid); COMPILE_TIME_ASSERT(CLocalizedStringArg::kIsValid); COMPILE_TIME_ASSERT(CLocalizedStringArg::kIsValid); COMPILE_TIME_ASSERT(CLocalizedStringArg::kIsValid); COMPILE_TIME_ASSERT(CLocalizedStringArg::kIsValid); COMPILE_TIME_ASSERT(CLocalizedStringArg::kIsValid); COMPILE_TIME_ASSERT(CLocalizedStringArg::kIsValid); m_loc_Buffer[0] = '\0'; if (loc_Format) { ::ILocalize::ConstructString(m_loc_Buffer, sizeof(m_loc_Buffer), loc_Format, 7, CLocalizedStringArg(arg0).GetLocArg(), CLocalizedStringArg(arg1).GetLocArg(), CLocalizedStringArg(arg2).GetLocArg(), CLocalizedStringArg(arg3).GetLocArg(), CLocalizedStringArg(arg4).GetLocArg(), CLocalizedStringArg(arg5).GetLocArg(), CLocalizedStringArg(arg6).GetLocArg()); } } CConstructLocalizedString(const locchar_t* loc_Format, KeyValues* pKeyValues) { m_loc_Buffer[0] = '\0'; if (loc_Format && pKeyValues) { ::ILocalize::ConstructString(m_loc_Buffer, sizeof(m_loc_Buffer), loc_Format, pKeyValues); } } operator const locchar_t* () const { return m_loc_Buffer; } private: enum { kBufferSize = 512, }; locchar_t m_loc_Buffer[kBufferSize]; }; namespace vgui { class ILocalize : public ::ILocalize { }; } #define VGUI_LOCALIZE_INTERFACE_VERSION "VGUI_Localize005" #endif