source: cpp/common/Convert.cpp @ 371

Last change on this file since 371 was 294, checked in by Maciej Komosinski, 10 years ago

Converted string no longer includes trailing 0 (which prevented string concatenations)

  • Property svn:eol-style set to native
File size: 5.0 KB
RevLine 
[286]1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
2// Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
3// See LICENSE.txt for details.
[122]4
[109]5#include "Convert.h"
6
7#include <sstream>
8
9#if defined __ANDROID__ || defined __BORLANDC__
[247]10#include <ctype.h> //toupper, tolower
[109]11#endif
12
13#ifdef SHP
[247]14#include <cstdlib>
[109]15#else
[247]16#include <stdlib.h>
[109]17#endif
18
19#include <stdio.h>
20
21
[247]22int Convert::toInt(string s) { return atoi(s.c_str()); }
23float Convert::toFloat(string s) { return (float)atof(s.c_str()); }
24string Convert::toLowerCase(string s) { std::transform(s.begin(), s.end(), s.begin(), ::tolower);  return s; }
25string Convert::toUpperCase(string s) { std::transform(s.begin(), s.end(), s.begin(), ::toupper);  return s; }
26char Convert::toLowerCase(char c) { return (char)tolower(c); }
27char Convert::toUpperCase(char c) { return (char)toupper(c); }
[109]28
[247]29template<class T> const char* printf_format_for(const T& value) { return "unknown type"; }
30template<> const char* printf_format_for(const unsigned int& value) { return "%u"; }
31template<> const char* printf_format_for(const int& value) { return "%d"; }
32template<> const char* printf_format_for(const short& value) { return "%d"; }
33template<> const char* printf_format_for(const float& value) { return "%g"; }
34template<> const char* printf_format_for(const double& value) { return "%g"; }
[109]35
36template<class T> string Convert::_toString(const T& value)
37{
[247]38        char buf[30];
39        sprintf(buf, printf_format_for(value), value);
40        return string(buf);
41        /*
42        #ifndef MULTITHREADED
[109]43        static
[247]44        #endif
[109]45        std::ostringstream oss; //pod VS tworzenie go trwa dlugo nawet w wersji release (szczegolnie jak np konwertuje sie cos setki tysiecy razy)
46        //dlatego robimy go raz (static) i potem tylko czyscimy
47        //ciekawostka: kiedy nie byl static, czasy wykonania bogatego w konwersje kawa³ka kodu oscylowa³y w trybie debug
48        //(5.5s lub 55s) a w release zawsze 57s. Po uzyciu static czas tego samego kodu jest zawsze debug: 0.72s release: 0.33s
49        oss.clear(); //clear error flag
50        oss.str(""); //set empty string
[247]51        oss << value;
52        return oss.str();
53        */
[109]54}
55
[247]56string Convert::toString(unsigned int v) { return _toString(v); }
57string Convert::toString(int v) { return _toString(v); }
58string Convert::toString(short v) { return _toString(v); }
59string Convert::toString(float v) { return _toString(v); }
60string Convert::toString(double v) { return _toString(v); }
[109]61
[247]62uint32_t Convert::hexToInt(const string& col)
63{
64        uint32_t value;
65        std::istringstream iss(col);
66        iss >> std::hex >> value;
67        return value;
68}
69
[109]70#ifdef MULTITHREADED
71//jezeli jest tu a nie jako static w funkcji, to inicjalizacja
72//nastapi na samym poczatku (w nieprzewidywalnym momencie, ale nie szkodzi(?))
73//gdyby byla w funkcji to teoretycznie dwa watki moglyby wejsc
74//do niej rownoczesnie i zaczac inicjalizacje po czym jeden korzystalby
75//z mutexa gdy drugi dalej by go inicjalizowal
76#include "threads.h"
[247]77static pthread_mutex_t fix_unsafe_mutex = PTHREAD_MUTEX_INITIALIZER;
[109]78#endif
79
80struct tm Convert::localtime(const time_t &timep)
81{
82#ifndef MULTITHREADED
83
[247]84        return *::localtime(&timep);
[109]85
86#else
87
[247]88        struct tm ret;
[109]89
90#if defined LINUX // || android?
[247]91        return *::localtime_r(&timep,&ret);
[257]92#elif defined _WIN32 && !defined __BORLANDC__
[247]93        ::localtime_s(&ret, &timep);
94        return ret;
[109]95#else //borland?
[247]96        pthread_mutex_lock(&fix_unsafe_mutex);
97        ret=*::localtime(&timep);
98        pthread_mutex_unlock(&fix_unsafe_mutex);
99        return ret;
[109]100#endif
101
102#endif
103}
104
105string Convert::asctime(const struct tm &tm)
106{
[247]107        char *ret;
[109]108#ifndef MULTITHREADED
109
[247]110        ret=::asctime(&tm);
[109]111
112#else //MULTITHREADED
113
[247]114        char buf[26];
[109]115#if defined LINUX // || android?
[247]116        ret=::asctime_r(&tm,buf);
[257]117#elif defined _WIN32 && !defined __BORLANDC__
[247]118        asctime_s(buf, sizeof(buf), &tm);
119        ret = buf;
[109]120#else //borland?
[247]121        pthread_mutex_lock(&fix_unsafe_mutex);
122        strcpy(buf,::asctime(&tm));
123        ret=buf;
124        pthread_mutex_unlock(&fix_unsafe_mutex);
[109]125#endif
126#endif
127
[247]128        return string(ret, 24); //24 znaki z pominieciem ostatniego \n
[109]129}
[281]130
131string Convert::wstrToUtf8(const wchar_t *str)
132{
133        if (str == NULL) return "";
134        string res;
135        wchar_t *wcp = (wchar_t*)str;
136        while (*wcp != 0)
137        {
138                int c = *wcp;
139                if (c < 0x80) res += c;
140                else if (c < 0x800) { res += 192 + c / 64; res += 128 + c % 64; }
141                else if (c - 0xd800u < 0x800) res += "<ERROR-CHAR>";
142                else if (c < 0x10000) { res += 224 + c / 4096; res += 128 + c / 64 % 64; res += 128 + c % 64; }
143                else if (c < 0x110000) { res += 240 + c / 262144; res += 128 + c / 4096 % 64; res += 128 + c / 64 % 64; res += 128 + c % 64; }
144                else res += "<ERROR-CHAR>";
145                wcp++;
146        }
147        return res;
148}
149
150#ifdef _WIN32
151wstring Convert::utf8ToUtf16(const char *str)
152{
153        wstring wstr;
154        int nOffset = 0;
[294]155        int nDataLen = strlen(str); //ending \0 is not converted, but resize() below sets the proper length of wstr
[281]156        int nLenWide = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)(str + nOffset),
157                (int)(nDataLen - nOffset), NULL, 0);
158        wstr.resize(nLenWide);
159        if (MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)(str + nOffset),
160                (int)(nDataLen - nOffset),
161                &wstr[0], nLenWide) != nLenWide)
162        {
163                //ASSERT(false); //some conversion error
[294]164                return wstr + L"<UTF8_CONV_ERROR>";
[281]165        }
166        return wstr;
167}
168#endif
Note: See TracBrowser for help on using the repository browser.