#ifndef MESH_IO_TEXT_H_INCLUDED
#define MESH_IO_TEXT_H_INCLUDED
-#include "binary.h"
+//#include "binary.h"
#include "la.h"
#include "color.h"
#include <string>
#include <iostream>
+#include <vector>
#include <stdlib.h>
#include <cstring>
-#ifdef _WIN32
+#if defined(_WIN32)
#include <windows.h>
#else
#include <iconv.h>
#endif
namespace meshio {
-namespace text {
-/**
- * \8eQ\8fÆ\83I\83\93\83\8a\81[\82Ì\8aÈ\88Õ\95¶\8e\9a\97ñ\83N\83\89\83X
- */
-class cstr
-{
- const char *begin_;
- const char *end_;
-
-public:
- cstr()
- : begin_(0), end_(0)
- {}
-
- cstr(const char *begin, const char *end)
- : begin_(begin), end_(end)
- { }
-
- bool operator==(const char *rhs)const
- {
- const char *l=begin_;
- for(const char *r=rhs; *r; ++r, ++l){
- if(l==end_){
- return false;
- }
- if(*l!=*r){
- return false;
- }
- }
- return l==end_;
- }
-
- bool operator!=(const char *rhs)const
- {
- return !(*this==rhs);
- }
-
- bool include(char c)const
- {
- for(const char *l=begin_; l!=end_; ++l){
- if(*l==c){
- return true;
- }
- }
- return false;
- }
-
- bool startswith(const char *rhs)
- {
- const char *r=rhs;
- for(const char *l=begin_; l!=end_ && *r!='\0'; ++l, ++r){
- if(*l!=*r){
- return false;
- }
- }
- return true;
- }
-
- bool empty()const
- {
- return begin_==end_;
- }
-
- std::string str()const{ return std::string(begin_, end_); }
- const char* begin()const{ return begin_; }
- const char* end()const{ return end_; }
- std::pair<const char*, const char*> range()const{
- return std::make_pair(begin_, end_);
- }
-
- template<typename IsTrim>
- cstr &trim(IsTrim isTrim){
- while(begin_!=end_ && isTrim(*begin_)){
- begin_++;
- }
- while(end_!=begin_ && isTrim(end_[-1])){
- end_--;
- }
- return *this;
- }
-};
-inline std::ostream &operator<<(std::ostream &os, const cstr &rhs)
-{
- return os << rhs.str();
-}
-
-struct IsCRLF
-{
- bool operator()(char byte)const
- {
- switch(byte)
- {
- case '\n':
- case '\r': // fall through
- return true;
-
- default:
- return false;
- }
- }
-};
-
-struct IsWhiteSpace
-{
- bool operator()(char byte)const
- {
- switch(byte)
- {
- case ' ':
- case '\t': // fall through
- return true;
-
- default:
- return false;
- }
- }
-};
-
-struct IsEmpty
-{
- bool operator()(cstr line)const
- {
- return line.empty();
- }
-};
-
-template<class DELIMITER=IsCRLF,
- class TRIM=IsWhiteSpace,
- class LINESKIP=IsEmpty>
- class LineReader
-{
- binary::IReader &reader_;
- unsigned int lineCount_;
- std::vector<char> buf_;
- bool isEnd_;
-
-public:
- LineReader(binary::IReader &reader)
- : reader_(reader), lineCount_(0), isEnd_(false)
- {
- }
-
- cstr getLine()
- {
- while(!isEnd_){
- fill_();
- cstr line;
- if(!buf_.empty()){
- line=trim_();
- }
- if(LINESKIP()(line)){
- continue;
- }
- ++lineCount_;
- return line;
- }
- return cstr();
- }
-
- unsigned int getLineCount()const
- {
- return lineCount_;
- }
-
- bool isEnd()const
- {
- return isEnd_;
- }
-
-private:
- void fill_()
- {
- buf_.clear();
- // skip delimeter
- while(char byte=reader_.getChar()){
- if(DELIMITER()(byte)){
- continue;
- }
- buf_.push_back(byte);
- break;
- }
- while(char byte=reader_.getChar()){
- if(DELIMITER()(byte)){
- break;
- }
- buf_.push_back(byte);
- }
- if(buf_.empty()){
- isEnd_=true;
- return;
- }
- }
-
- cstr trim_()
- {
- if(buf_.empty()){
- return cstr();
- }
-
- size_t front=0;
- while(true){
- if(front>=buf_.size()){
- return cstr();
- }
- if(!TRIM()(buf_[front])){
- break;
- }
- ++front;
- }
-
- size_t back=buf_.size()-1;
- for(; back>=0; --back){
- if(!TRIM()(buf_[back])){
- break;
- }
- }
- assert(front<=back);
- return cstr(&buf_[0]+front, &buf_[0]+back+1);
- }
-};
-
-template<class DELIMITER=IsWhiteSpace>
-class LineSplitter
-{
- cstr line_;
-
-public:
- LineSplitter(cstr line)
- : line_(line)
- {
- }
-
- cstr get()
- {
- const char* head=0;
- const char* tail=0;
- const char *current=line_.begin();
- for(; current!=line_.end();){
- for(; current!=line_.end(); ++current){
- if(!DELIMITER()(*current)){
- head=current;
- break;
- }
- }
- if(head){
- for(; current!=line_.end(); ++current){
- if(DELIMITER()(*current)){
- break;
- }
- }
- tail=current;
- }
- if(tail){
- break;
- }
- }
- if(!tail){
- return cstr();
- }
- line_=cstr(tail+1, line_.end());
- return cstr(head, tail);
- }
-
- int getInt()
- {
- return atoi(get().begin());
- }
-
- float getFloat()
- {
- return static_cast<float>(atof(get().begin()));
- }
-
- la::Vector2 getVector2()
- {
- float x=getFloat();
- float y=getFloat();
- return la::Vector2(x, y);
- }
-
- la::Vector3 getVector3()
- {
- float x=getFloat();
- float y=getFloat();
- float z=getFloat();
- return la::Vector3(x, y, z);
- }
-
- la::Vector4 getVector4()
- {
- float x=getFloat();
- float y=getFloat();
- float z=getFloat();
- float w=getFloat();
- return la::Vector4(x, y, z, w);
- }
-
- color::fRGBA getFloatRGBA()
- {
- float r=getFloat();
- float g=getFloat();
- float b=getFloat();
- float a=getFloat();
- return color::fRGBA(r, g, b, a);
- }
-
- color::bRGBA getByteRGBA()
- {
- int r=getInt();
- int g=getInt();
- int b=getInt();
- int a=getInt();
- return color::bRGBA(r, g, b, a);
- }
-
- cstr getQuated()
- {
- const char *begin=line_.begin();
- for(; begin!=line_.end(); ++begin){
- if(*begin=='"'){
- break;
- }
- }
- begin++;
- assert(begin<=line_.end());
+ class cstr
+ {
+ const char *begin_;
+ const char *end_;
+
+ public:
+ cstr()
+ : begin_(0), end_(0)
+ {}
+
+ cstr(const char *begin, const char *end)
+ : begin_(begin), end_(end)
+ { }
+
+ bool operator==(const char *rhs)const
+ {
+ const char *l=begin_;
+ for(const char *r=rhs; *r; ++r, ++l){
+ if(l==end_){
+ return false;
+ }
+ if(*l!=*r){
+ return false;
+ }
+ }
+ return l==end_;
+ }
- const char *c=begin+1;
- for(; c!=line_.end(); ++c){
- if(*c=='"'){
- break;
- }
- }
+ bool operator!=(const char *rhs)const
+ {
+ return !(*this==rhs);
+ }
- cstr token=cstr(begin, c);
+ bool include(char c)const
+ {
+ for(const char *l=begin_; l!=end_; ++l){
+ if(*l==c){
+ return true;
+ }
+ }
+ return false;
+ }
- // advance
- line_=cstr(c+1, line_.end());
+ bool startswith(const char *rhs)
+ {
+ const char *r=rhs;
+ for(const char *l=begin_; l!=end_ && *r!='\0'; ++l, ++r){
+ if(*l!=*r){
+ return false;
+ }
+ }
+ return true;
+ }
- return token;
- }
-};
+ bool empty()const
+ {
+ return begin_==end_;
+ }
-inline void copyStringAndFillZero(char *dst, const std::string &src)
-{
- size_t i=0;
- for(; i<src.size(); ++i)
- {
- dst[i]=src[i];
- if(src[i]=='\0'){
- break;
- }
- }
- for(; i<src.size(); ++i)
- {
- dst[i]='\0';
- }
-}
+ std::string str()const{ return std::string(begin_, end_); }
+ const char* begin()const{ return begin_; }
+ const char* end()const{ return end_; }
+ std::pair<const char*, const char*> range()const{
+ return std::make_pair(begin_, end_);
+ }
-#ifdef _WIN32
-inline std::wstring to_WideChar(UINT uCodePage, const std::string &text)
-{
- int size=MultiByteToWideChar(uCodePage, 0, text.c_str(), -1, NULL, 0);
- std::vector<wchar_t> buf(size);
- size=MultiByteToWideChar(uCodePage, 0, text.c_str(), -1, &buf[0], buf.size());
- return std::wstring(buf.begin(), buf.begin()+size);
-}
+ template<typename IsTrim>
+ cstr &trim(IsTrim isTrim){
+ while(begin_!=end_ && isTrim(*begin_)){
+ begin_++;
+ }
+ while(end_!=begin_ && isTrim(end_[-1])){
+ end_--;
+ }
+ return *this;
+ }
+ };
+#ifndef SWIG
+ inline std::ostream &operator<<(std::ostream &os, const cstr &rhs)
+ {
+ return os << rhs.str();
+ }
+#endif
-inline std::string to_MultiByte(UINT uCodePage, const std::wstring &text)
-{
- int size=WideCharToMultiByte(uCodePage, 0, text.c_str(), -1, NULL, 0, 0, NULL);
- std::vector<char> buf(size);
- size=WideCharToMultiByte(uCodePage, 0, text.c_str(), -1, &buf[0], buf.size(), 0, NULL);
- return std::string(buf.begin(), buf.begin()+size);
-}
+ template<int LENGTH>
+ class fixed_string
+ {
+ char begin_[LENGTH];
+ char *end_;
+ public:
+ fixed_string()
+ : end_(begin_)
+ {
+ begin_[0]='\0';;
+ }
+ fixed_string(const std::string &str)
+ : end_(begin_)
+ {
+ assign(str);
+ }
+ fixed_string& operator=(const std::string &src)
+ {
+ assign(src);
+ return *this;
+ }
+ void assign(const std::string &src)
+ {
+ if(src.empty()){
+ return;
+ }
+ std::string::const_iterator it=src.begin();
+ int i;
+ for(i=0;
+ i<LENGTH && it!=src.end();
+ ++i, ++it)
+ {
+ begin_[i]=*it;
+ }
+ if(i<LENGTH)
+ {
+ begin_[i]='\0';
+ }
+ }
+ size_t size()const { return LENGTH; }
+ char *begin() { return begin_; }
+ const char *begin() const { return begin_; }
+ std::string str() const
+ {
+ const char *end=begin_;
+ for(; end!=end_ && *end!='\0'; ++end){
+ }
+ return std::string(
+ static_cast<const char*>(begin_),
+ static_cast<const char*>(end));
+ }
+ };
+#ifndef SWIG
+ template<int LENGTH>
+ inline std::ostream &operator<<(std::ostream &os, const fixed_string<LENGTH> &rhs)
+ {
+ return os << rhs.str();
+ }
+#endif
-inline std::wstring cp932_to_unicode(const std::string &text)
-{
+#if defined(_MSC_VER)
+ inline std::wstring to_WideChar(UINT uCodePage, const std::string &text)
+ {
+ int size=MultiByteToWideChar(uCodePage, 0, text.c_str(), -1, NULL, 0);
+ std::vector<wchar_t> buf(size);
+ size=MultiByteToWideChar(uCodePage, 0, text.c_str(), -1, &buf[0], buf.size());
+ return std::wstring(buf.begin(), buf.begin()+size);
+ }
+
+ inline std::string to_MultiByte(UINT uCodePage, const std::wstring &text)
+ {
+ int size=WideCharToMultiByte(uCodePage, 0, text.c_str(), -1, NULL, 0, 0, NULL);
+ std::vector<char> buf(size);
+ size=WideCharToMultiByte(uCodePage, 0, text.c_str(), -1, &buf[0], buf.size(), 0, NULL);
+ return std::string(buf.begin(), buf.begin()+size);
+ }
+
+ inline std::wstring cp932_to_unicode(const std::string &text)
+ {
return to_WideChar(CP_OEMCP, text);
-}
+ }
-inline std::string cp932_to_utf8(const std::string &text)
-{
- return to_MultiByte(CP_UTF8, to_WideChar(CP_OEMCP, text));
-}
+ inline std::string cp932_to_utf8(const std::string &text)
+ {
+ return to_MultiByte(CP_UTF8, to_WideChar(CP_OEMCP, text));
+ }
#else
-inline std::wstring to_unicode(const char *text, const char *fromcode)
-{
+ inline std::wstring to_unicode(const char *text, const char *fromcode)
+ {
const char* tocode="WCHAR_T";
iconv_t cd=iconv_open(tocode, fromcode);
if(cd==(iconv_t)-1){
- std::cerr << "fail to iconv_open: " << fromcode << " --> " << tocode << std::endl;
- return L"";
+ std::cerr << "fail to iconv_open: " << fromcode << " --> " << tocode << std::endl;
+ return L"";
}
// inbuf
size_t outbytesleft=0;
while(inbytesleft){
- buf.resize(buf.size()+inbytesleft);
- wchar_t *woutbuf=&buf[pos];
- outbytesleft=(buf.size()-pos)*sizeof(wchar_t);
- int ret=iconv(cd, &inbuf, &inbytesleft, (char**)&woutbuf, &outbytesleft);
- if(ret==-1){
- std::cerr << "fail to iconv" << std::endl;
- return L"";
- }
- pos=woutbuf-&buf[0];
+ buf.resize(buf.size()+inbytesleft);
+ wchar_t *woutbuf=&buf[pos];
+ outbytesleft=(buf.size()-pos)*sizeof(wchar_t);
+ int ret=iconv(cd, &inbuf, &inbytesleft, (char**)&woutbuf, &outbytesleft);
+ if(ret==-1){
+ std::cerr << "fail to iconv" << std::endl;
+ return L"";
+ }
+ pos=woutbuf-&buf[0];
}
if(outbytesleft==0){
- buf.push_back('\0');
+ buf.push_back('\0');
}
iconv_close(cd);
return &buf[0];
-}
+ }
-inline std::wstring cp932_to_unicode(const std::string &text)
-{
+ inline std::wstring cp932_to_unicode(const std::string &text)
+ {
return to_unicode(text.c_str(), "CP932");
-}
-
+ }
#endif
-inline std::wstring trim(const std::wstring &src){
- std::wstring::const_iterator end=src.begin();
- for(; end!=src.end(); ++end){
- if(*end==L'\0'){
- break;
- }
- }
- return std::wstring(src.begin(), end);
-}
+ inline std::wstring trim(const std::wstring &src){
+ std::wstring::const_iterator end=src.begin();
+ for(; end!=src.end(); ++end){
+ if(*end==L'\0'){
+ break;
+ }
+ }
+ return std::wstring(src.begin(), end);
+ }
-} // namespace text
} // namespace meshio
#endif // MESH_IO_TEXT_H_INCLUDED