OSDN Git Service

fix for cygwin build
[meshio/meshio.git] / src / text.h
1 #ifndef MESH_IO_TEXT_H_INCLUDED
2 #define MESH_IO_TEXT_H_INCLUDED
3
4 //#include "binary.h"
5 #include "la.h"
6 #include "color.h"
7 #include <string>
8 #include <iostream>
9 #include <vector>
10 #include <stdlib.h>
11 #include <cstring>
12
13 #if defined(_WIN32)
14 #include <windows.h>
15 #else
16 #include <iconv.h>
17 #endif
18
19 namespace meshio {
20
21   class cstr
22   {
23     const char *begin_;
24     const char *end_;
25
26   public:
27     cstr()
28       : begin_(0), end_(0)
29     {}
30
31     cstr(const char *begin, const char *end)
32       : begin_(begin), end_(end)
33     { }
34
35     bool operator==(const char *rhs)const
36     {
37       const char *l=begin_;
38       for(const char *r=rhs; *r; ++r, ++l){
39         if(l==end_){
40           return false;
41         }
42         if(*l!=*r){
43           return false;
44         }
45       }
46       return l==end_;
47     }
48
49     bool operator!=(const char *rhs)const
50     {
51       return !(*this==rhs);
52     }
53
54     bool include(char c)const
55     {
56       for(const char *l=begin_; l!=end_; ++l){
57         if(*l==c){
58           return true;
59         }
60       }
61       return false;
62     }
63
64     bool startswith(const char *rhs)
65     {
66       const char *r=rhs;
67       for(const char *l=begin_; l!=end_ && *r!='\0'; ++l, ++r){
68         if(*l!=*r){
69           return false;
70         }
71       }
72       return true;
73     }
74
75     bool empty()const
76     {
77       return begin_==end_;
78     }
79
80     std::string str()const{ return std::string(begin_, end_); }
81     const char* begin()const{ return begin_; }
82     const char* end()const{ return end_; }
83     std::pair<const char*, const char*> range()const{ 
84       return std::make_pair(begin_, end_); 
85     }
86
87     template<typename IsTrim>
88       cstr &trim(IsTrim isTrim){
89         while(begin_!=end_ && isTrim(*begin_)){
90           begin_++;
91         }
92         while(end_!=begin_ && isTrim(end_[-1])){
93           end_--;
94         }
95         return *this;
96       }
97   };
98 #ifndef SWIG
99   inline std::ostream &operator<<(std::ostream &os, const cstr &rhs)
100   {
101     return os << rhs.str();
102   }
103 #endif
104
105   template<int LENGTH>
106     class fixed_string
107     {
108       char begin_[LENGTH];
109       char *end_;
110     public:
111       fixed_string()
112         : end_(begin_)
113       {
114         begin_[0]='\0';;
115       }
116       fixed_string(const std::string &str)
117         : end_(begin_)
118       {
119         assign(str);
120       }
121       fixed_string& operator=(const std::string &src)
122       {
123         assign(src);
124         return *this;
125       }
126       void assign(const std::string &src)
127       {
128         if(src.empty()){
129           return;
130         }
131         std::string::const_iterator it=src.begin();
132         int i;
133         for(i=0; 
134             i<LENGTH && it!=src.end(); 
135             ++i, ++it)
136         {
137           begin_[i]=*it;
138         }
139         if(i<LENGTH)
140         {
141           begin_[i]='\0';
142         }
143       }
144       size_t size()const { return LENGTH; }
145       char *begin() { return begin_; }
146       const char *begin() const { return begin_; }
147       std::string str() const
148       {
149         const char *end=begin_;
150         for(; end!=end_ && *end!='\0'; ++end){
151         }
152         return std::string(
153             static_cast<const char*>(begin_), 
154             static_cast<const char*>(end));
155       }
156     };
157 #ifndef SWIG
158   template<int LENGTH>
159     inline std::ostream &operator<<(std::ostream &os, const fixed_string<LENGTH> &rhs)
160     {
161       return os << rhs.str();
162     }
163 #endif
164
165 #if defined(_MSC_VER)
166   inline std::wstring to_WideChar(UINT uCodePage, const std::string &text)
167   {
168     int size=MultiByteToWideChar(uCodePage, 0, text.c_str(), -1, NULL, 0);
169     std::vector<wchar_t> buf(size);
170     size=MultiByteToWideChar(uCodePage, 0, text.c_str(), -1, &buf[0], buf.size());
171     return std::wstring(buf.begin(), buf.begin()+size);
172   }
173
174   inline std::string to_MultiByte(UINT uCodePage, const std::wstring &text)
175   {
176     int size=WideCharToMultiByte(uCodePage, 0, text.c_str(), -1, NULL, 0, 0, NULL);
177     std::vector<char> buf(size);
178     size=WideCharToMultiByte(uCodePage, 0, text.c_str(), -1, &buf[0], buf.size(), 0, NULL);
179     return std::string(buf.begin(), buf.begin()+size);
180   }
181
182   inline std::wstring cp932_to_unicode(const std::string &text)
183   {
184     return to_WideChar(CP_OEMCP, text);
185   }
186
187   inline std::string cp932_to_utf8(const std::string &text)
188   {
189     return to_MultiByte(CP_UTF8, to_WideChar(CP_OEMCP, text));
190   }
191
192 #else
193   inline std::wstring to_unicode(const char *text, const char *fromcode)
194   {
195     const char* tocode="WCHAR_T";
196     iconv_t cd=iconv_open(tocode, fromcode);
197     if(cd==(iconv_t)-1){
198       std::cerr << "fail to iconv_open: " << fromcode << " --> " << tocode << std::endl;
199       return L"";
200     }
201
202     // inbuf
203     size_t inbytesleft=std::strlen(text);
204     char *inbuf=const_cast<char*>(text);
205     // outbuf
206     std::vector<wchar_t> buf;
207     size_t pos=0;
208     size_t outbytesleft=0;
209
210     while(inbytesleft){
211       buf.resize(buf.size()+inbytesleft);
212       wchar_t *woutbuf=&buf[pos];
213       outbytesleft=(buf.size()-pos)*sizeof(wchar_t);
214       int ret=iconv(cd, &inbuf, &inbytesleft, (char**)&woutbuf, &outbytesleft);
215       if(ret==-1){
216         std::cerr << "fail to iconv" <<  std::endl;
217         return L"";
218       }
219       pos=woutbuf-&buf[0];
220     }
221     if(outbytesleft==0){
222       buf.push_back('\0');
223     }
224     iconv_close(cd);
225
226     return &buf[0];
227   }
228
229   inline std::wstring cp932_to_unicode(const std::string &text)
230   {
231     return to_unicode(text.c_str(), "CP932");
232   }
233 #endif
234
235   inline std::wstring trim(const std::wstring &src){
236     std::wstring::const_iterator end=src.begin();
237     for(; end!=src.end(); ++end){
238       if(*end==L'\0'){
239         break;
240       }
241     }
242     return std::wstring(src.begin(), end);
243   }
244
245 } // namespace meshio
246 #endif // MESH_IO_TEXT_H_INCLUDED