forked from 0ad/0ad
139 lines
3.4 KiB
C++
Executable File
139 lines
3.4 KiB
C++
Executable File
#include "precompiled.h"
|
|
|
|
#include "BufferVariable.h"
|
|
|
|
#include "DataTypes.h"
|
|
#include "CLocale.h"
|
|
|
|
// Hashing functions are currently 32-bit only
|
|
cassert(sizeof(int) == 4);
|
|
cassert(sizeof(double) == 8);
|
|
|
|
using namespace I18n;
|
|
|
|
namespace I18n {
|
|
// These bits don't seem to work without the explicit namespace{}
|
|
|
|
template<> BufferVariable* NewBufferVariable<int>(int v) { return new BufferVariable_int(v); }
|
|
template<> BufferVariable* NewBufferVariable<float>(float v) { return new BufferVariable_double(v); }
|
|
template<> BufferVariable* NewBufferVariable<double>(double v) { return new BufferVariable_double(v); }
|
|
template<> BufferVariable* NewBufferVariable<Noun>(Noun v) { return new BufferVariable_string(v.value); }
|
|
template<> BufferVariable* NewBufferVariable<Name>(Name v) { return new BufferVariable_rawstring(v.value); }
|
|
|
|
//
|
|
// Don't allow plain strings -- people *must* specify whether it's going
|
|
// to be automatically translated (I18n::Noun) or not (I18n::Name/Raw)
|
|
//
|
|
}
|
|
|
|
StrImW BufferVariable_int::ToString(CLocale*)
|
|
{
|
|
wchar_t buffer[16];
|
|
swprintf(buffer, 16, L"%d", value);
|
|
return buffer;
|
|
}
|
|
u32 BufferVariable_int::Hash()
|
|
{
|
|
return (u32)value;
|
|
}
|
|
|
|
|
|
StrImW BufferVariable_double::ToString(CLocale*)
|
|
{
|
|
// TODO: Work out how big the buffer should be
|
|
wchar_t buffer[256];
|
|
swprintf(buffer, 256, L"%f", value);
|
|
return buffer;
|
|
}
|
|
u32 BufferVariable_double::Hash()
|
|
{
|
|
// Add the two four-bytes of the double
|
|
return *((u32*)&value) + *((u32*)&value + 1);
|
|
}
|
|
|
|
|
|
StrImW BufferVariable_string::ToString(CLocale* locale)
|
|
{
|
|
// Attempt noun translations
|
|
const Str nouns = L"nouns";
|
|
const Str wordname (value.str());
|
|
const CLocale::LookupType* word = locale->LookupWord(nouns, wordname);
|
|
// Couldn't find; just return the original word
|
|
if (! word)
|
|
return value;
|
|
|
|
const Str propname = L"singular";
|
|
Str ret;
|
|
if (! locale->LookupProperty(word, propname, ret))
|
|
{
|
|
delete word;
|
|
return value;
|
|
}
|
|
delete word;
|
|
return ret.c_str();
|
|
}
|
|
u32 BufferVariable_string::Hash()
|
|
{
|
|
// Do nothing very clever
|
|
int hash = 0;
|
|
const wchar_t* str = value.str();
|
|
size_t len = wcslen(str);
|
|
for (size_t i = 0; i < len; ++i)
|
|
hash += str[i];
|
|
return hash;
|
|
}
|
|
|
|
StrImW BufferVariable_rawstring::ToString(CLocale*)
|
|
{
|
|
return value;
|
|
}
|
|
u32 BufferVariable_rawstring::Hash()
|
|
{
|
|
int hash = 0;
|
|
const wchar_t* str = value.str();
|
|
size_t len = wcslen(str);
|
|
for (size_t i = 0; i < len; ++i)
|
|
hash += str[i];
|
|
return hash;
|
|
}
|
|
|
|
bool I18n::operator== (BufferVariable& a, BufferVariable& b)
|
|
{
|
|
if (a.Type != b.Type)
|
|
return false;
|
|
|
|
switch (a.Type)
|
|
{
|
|
case vartype_int:
|
|
return *static_cast<BufferVariable_int*>(&a) == *static_cast<BufferVariable_int*>(&b);
|
|
case vartype_double:
|
|
return *static_cast<BufferVariable_double*>(&a) == *static_cast<BufferVariable_double*>(&b);
|
|
case vartype_string:
|
|
return *static_cast<BufferVariable_string*>(&a) == *static_cast<BufferVariable_string*>(&b);
|
|
case vartype_rawstring:
|
|
return *static_cast<BufferVariable_rawstring*>(&a) == *static_cast<BufferVariable_rawstring*>(&b);
|
|
}
|
|
debug_warn("Invalid buffer variable vartype");
|
|
return false;
|
|
}
|
|
|
|
bool BufferVariable_int::operator== (BufferVariable_int& a)
|
|
{
|
|
return a.value == this->value;
|
|
}
|
|
|
|
bool BufferVariable_double::operator== (BufferVariable_double& a)
|
|
{
|
|
return a.value == this->value;
|
|
}
|
|
|
|
bool BufferVariable_string::operator== (BufferVariable_string& a)
|
|
{
|
|
return a.value == this->value;
|
|
}
|
|
|
|
bool BufferVariable_rawstring::operator== (BufferVariable_rawstring& a)
|
|
{
|
|
return a.value == this->value;
|
|
}
|