From 2383a42347176aa04fc8a67a83ffa9def4c706de Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Wed, 11 Jul 2012 20:50:42 +0200 Subject: Rewritten model loading - written new implementation of CModelFile (old CModFile) - added stringutils and ioutils in src/common - removed old CModel (model viewer) --- src/common/ioutils.h | 81 ++++++++++++++++++++++++ src/common/stringutils.cpp | 149 +++++++++++++++++++++++++++++++++++++++++++++ src/common/stringutils.h | 77 +++++++++++++++++++++++ 3 files changed, 307 insertions(+) create mode 100644 src/common/ioutils.h create mode 100644 src/common/stringutils.cpp create mode 100644 src/common/stringutils.h (limited to 'src/common') diff --git a/src/common/ioutils.h b/src/common/ioutils.h new file mode 100644 index 0000000..f17c961 --- /dev/null +++ b/src/common/ioutils.h @@ -0,0 +1,81 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2012, Polish Portal of Colobot (PPC) +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// ioutils.h + +#pragma once + + +#include + + +namespace IOUtils { + +//! Writes a binary number to output stream +/** + \c T is a numeric type (int, unsigned int, etc.) + \c N is number of bytes + Write order is little-endian */ +template +void WriteBinary(T value, std::ostream &ostr) +{ + for (int i = 0; i < N; ++i) + { + unsigned char byte = (value >> (i*8)) & 0xFF; + ostr.write((char*)&byte, 1); + } +} + +//! Reads a binary number from input stream +/** + \c T is a numeric type (int, unsigned int, etc.) + \c N is number of bytes + Read order is little-endian */ +template +T ReadBinary(std::istream &istr) +{ + T value = 0; + for (int i = 0; i < N; ++i) + { + unsigned char byte = 0; + istr.read((char*)&byte, 1); + value |= byte << (i*8); + } + return value; +} + +//! Writes a binary 32-bit float to output stream +/** + Write order is little-endian + NOTE: code is probably not portable as there are platforms with other float representations. */ +void WriteBinaryFloat(float value, std::ostream &ostr) +{ + unsigned int iValue = *( (unsigned int*)( (void*)(&value) ) ); + IOUtils::WriteBinary<4, unsigned int>(iValue, ostr); +} + +//! Reads a binary 32-bit float from input stream +/** + Read order is little-endian + NOTE: code is probably not portable as there are platforms with other float representations. */ +float ReadBinaryFloat(std::istream &istr) +{ + unsigned int iValue = IOUtils::ReadBinary<4, unsigned int>(istr); + float result = *( (float*)( (void*)(&iValue) ) ); + return result; +} + +}; // namespace IOUtils diff --git a/src/common/stringutils.cpp b/src/common/stringutils.cpp new file mode 100644 index 0000000..9a7aa61 --- /dev/null +++ b/src/common/stringutils.cpp @@ -0,0 +1,149 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2012, Polish Portal of Colobot (PPC) +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// stringutils.cpp + +#include "stringutils.h" + + +std::string StrUtils::Replace(const std::string &str, const std::string &oldStr, const std::string &newStr) +{ + std::string result = str; + size_t pos = 0; + while ((pos = str.find(oldStr, pos)) != std::string::npos) + { + result.replace(pos, oldStr.length(), newStr); + pos += newStr.length(); + } + return result; +} + +std::string StrUtils::UnicodeCharToUtf8(unsigned int ch) +{ + std::string result; + if (ch < 0x0080) + { + result += (char)(ch); + } + else if (ch < 0x0800) + { + char ch1 = 0xC0 | ((ch & 0x07C0) >> 6); + char ch2 = 0x80 | (ch & 0x3F); + result += ch1; + result += ch2; + } + else + { + char ch1 = 0xE0 | ((ch & 0xF000) >> 12); + char ch2 = 0x80 | ((ch & 0x07C0) >> 6); + char ch3 = 0x80 | (ch & 0x3F); + result += ch1; + result += ch2; + result += ch3; + } + return result; +} + +std::string StrUtils::UnicodeStringToUtf8(const std::wstring &str) +{ + std::string result; + for (unsigned int i = 0; i < str.size(); ++i) + result += StrUtils::UnicodeCharToUtf8((unsigned int)str[i]); + + return result; +} + +unsigned int StrUtils::Utf8CharToUnicode(const std::string &ch) +{ + if (ch.empty()) + return 0; + + unsigned int result = 0; + if ((ch[0] & 0x80) == 0) + { + if (ch.size() == 1) + result = (unsigned int)ch[0]; + } + else if ((ch[0] & 0xC0) == 0xC0) + { + if (ch.size() == 2) + { + unsigned int ch1 = (ch[0] & 0x1F) << 6; + unsigned int ch2 = (ch[1] & 0x3F); + result = ch1 | ch2; + } + } + else + { + if (ch.size() == 3) + { + unsigned int ch1 = (ch[0] & 0xF0) << 12; + unsigned int ch2 = (ch[1] & 0xC0) << 6; + unsigned int ch3 = (ch[2] & 0xC0); + result = ch1 | ch2 | ch3; + } + } + + return result; +} + +std::wstring StrUtils::Utf8StringToUnicode(const std::string &str) +{ + std::wstring result; + unsigned int pos = 0; + while (pos < str.size()) + { + int len = StrUtils::Utf8CharSizeAt(str, pos); + if (len == 0) + break; + + std::string ch = str.substr(pos, len); + result += (wchar_t)(StrUtils::Utf8CharToUnicode(ch)); + pos += len; + } + return result; +} + +int StrUtils::Utf8CharSizeAt(const std::string &str, unsigned int pos) +{ + if (pos >= str.size()) + return 0; + + if ((str[pos] & 0x80) == 0) + return 1; + else if ((str[pos] & 0xC0) == 0xC0) + return 2; + else + return 3; + + return 0; +} + +size_t StrUtils::Utf8StringLength(const std::string &str) +{ + size_t result = 0; + for (unsigned int i = 0; i < str.size(); ++i) + { + char ch = str[i]; + if ((ch & 0x80) == 0) + ++result; + else if ((ch & 0xC0) == 0xC0) + result += 2; + else + result += 3; + } + return result; +} diff --git a/src/common/stringutils.h b/src/common/stringutils.h new file mode 100644 index 0000000..a0cae70 --- /dev/null +++ b/src/common/stringutils.h @@ -0,0 +1,77 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2012, Polish Portal of Colobot (PPC) +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// stringutils.h + +#pragma once + + +#include +#include + +namespace StrUtils { + +//! Converts a value to string +/** If given, \a ok is set to true/false on success/failure. + Warning: To avoid unnecessary problems, *always* give full template qualifier e.g. ToString\ */ +template +std::string ToString(T value, bool *ok = NULL) +{ + std::ostringstream s; + s << value; + if (ok != NULL) + *ok = !s.fail(); + return s.str(); +} + +//! Converts a value to string +/** If given, \a ok is set to true/false on success/failure. + Warning: To avoid unnecessary problems, *always* give full template qualifier e.g. FromString\ */ +template +T FromString(const std::string &str, bool *ok = NULL) +{ + std::istringstream s; + s.str(str); + T value; + s >> value; + if (ok != NULL) + *ok = !s.fail(); + return value; +} + +//! Returns a string with every occurence of \a oldStr in \a str replaced to \a newStr +std::string Replace(const std::string &str, const std::string &oldStr, const std::string &newStr); + + +//! Converts a wide Unicode char to a single UTF-8 encoded char +std::string UnicodeCharToUtf8(unsigned int ch); + +//! Converts a wide Unicode string to a UTF-8 encoded string +std::string UnicodeStringToUtf8(const std::wstring &str); + +//! Converts a UTF-8 encoded single character to wide Unicode char +unsigned int Utf8CharToUnicode(const std::string &ch); + +//! Converts a UTF-8 encoded string to wide Unicode string +std::wstring Utf8StringToUnicode(const std::string &str); + +//! Returns the size in bytes of UTF-8 character at given \a pos in a UTF-8 \a str +int Utf8CharSizeAt(const std::string &str, unsigned int pos); + +//! Returns the length in characters of UTF-8 string \a str +size_t Utf8StringLength(const std::string &str); + +}; // namespace StrUtil -- cgit v1.2.3-1-g7c22