Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tstream.h"
Toshihiro Shimizu 890ddd
#include "tpersist.h"
Toshihiro Shimizu 890ddd
#include "tfilepath_io.h"
Toshihiro Shimizu 890ddd
#include "tconvert.h"
Toshihiro Shimizu 890ddd
#include "tsystem.h"
Toshihiro Shimizu 890ddd
#include "tutil.h"
Toshihiro Shimizu 890ddd
roentgen 19af1b
#if defined(LZ4_STATIC)
Toshihiro Shimizu 890ddd
#include "lz4frame_static.h"
roentgen 19af1b
#else
roentgen 19af1b
#include "lz4frame.h"
roentgen 19af1b
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <sstream></sstream>
Campbell Barton 40cabe
#include <memory></memory>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
using namespace std;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===============================================================
Shinya Kitaoka 120a6e
namespace {
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
string escape(string v) {
Shinya Kitaoka 120a6e
  int i = 0;
Shinya Kitaoka 120a6e
  for (;;) {
manongjohn e82b20
// Removing escaping of apostrophe from Windows and OSX as it's not needed and
manongjohn e82b20
// causes problems
Rozhuk Ivan ac51ab
#if defined(LINUX) || defined(FREEBSD)
Shinya Kitaoka 120a6e
    i = v.find_first_of("\\\'\"", i);
manongjohn 20c961
#else
manongjohn 20c961
    i = v.find_first_of("\\\"", i);
manongjohn 20c961
#endif
Shinya Kitaoka 120a6e
    if (i == (int)string::npos) break;
Shinya Kitaoka 120a6e
    string h = "\\" + v[i];
Shinya Kitaoka 120a6e
    v.insert(i, "\\");
Shinya Kitaoka 120a6e
    i = i + 2;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return v;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===============================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void writeCompressedFile(TFilePath dst, const std::string &str) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void readCompressedFile(string &str, TFilePath src) {
Shinya Kitaoka 120a6e
  TFileStatus status(src);
Shinya Kitaoka 120a6e
  if (!status.doesExist()) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  size_t in_len = status.getSize();
Shinya Kitaoka 120a6e
  char *in      = (char *)malloc(in_len);
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    Tifstream is(src);
Shinya Kitaoka 120a6e
    is.read((char *)in, in_len);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  LZ4F_decompressionContext_t lz4dctx;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  LZ4F_errorCode_t err =
Shinya Kitaoka 120a6e
      LZ4F_createDecompressionContext(&lz4dctx, LZ4F_VERSION);
Shinya Kitaoka 120a6e
  if (LZ4F_isError(err)) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  size_t in_len_read = 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  size_t out_len = 1000000, out_len_written, out_len_moved = 0;
Shinya Kitaoka 120a6e
  void *out = (void *)malloc(out_len);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  while (in_len_read < in_len) {
Shinya Kitaoka 120a6e
    out_len_written = out_len;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    size_t remaining =
Shinya Kitaoka 120a6e
        LZ4F_decompress(lz4dctx, out, &out_len_written, in, &in_len, NULL);
Shinya Kitaoka 120a6e
    if (LZ4F_isError(remaining)) break;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    str.resize(out_len_moved + out_len_written);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    memcpy((void *)(str.c_str() + out_len_moved), (void *)out, out_len_written);
Shinya Kitaoka 120a6e
    out_len_moved += out_len_written;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  LZ4F_freeDecompressionContext(lz4dctx);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  free(in);
Shinya Kitaoka 120a6e
  free(out);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
// TODO: Unify with tcodec.cpp's version
Shinya Kitaoka 120a6e
bool lz4decompress(LZ4F_decompressionContext_t lz4dctx, char *out,
Shinya Kitaoka 120a6e
                   size_t *out_len_res, const char *in, size_t in_len) {
Shinya Kitaoka 120a6e
  size_t out_len = *out_len_res, in_read, out_written;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  *out_len_res = 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  while (in_len) {
Shinya Kitaoka 120a6e
    out_written = out_len;
Shinya Kitaoka 120a6e
    in_read     = in_len;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    size_t res = LZ4F_decompress(lz4dctx, (void *)out, &out_written,
Shinya Kitaoka 120a6e
                                 (const void *)in, &in_read, NULL);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (LZ4F_isError(res)) return false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    *out_len_res += out_written;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    out += out_written;
Shinya Kitaoka 120a6e
    out_len -= out_written;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    in += in_read;
Shinya Kitaoka 120a6e
    in_len -= in_read;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===============================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class StreamTag {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  string m_name;
Shinya Kitaoka 120a6e
  std::map<std::string, string=""> m_attributes;</std::string,>
Shinya Kitaoka 120a6e
  enum Type { BeginTag, EndTag, BeginEndTag };
Shinya Kitaoka 120a6e
  Type m_type;
Shinya Kitaoka 120a6e
  StreamTag() : m_type(BeginTag) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  operator bool() const { return m_name != ""; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void dump() {
Shinya Kitaoka 120a6e
    cout << "name = '" << m_name << "'" << endl;
Shinya Kitaoka 120a6e
    cout << "type = ";
Shinya Kitaoka 120a6e
    switch (m_type) {
Shinya Kitaoka 120a6e
    case BeginTag:
Shinya Kitaoka 120a6e
      cout << "begin Tag";
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case EndTag:
Shinya Kitaoka 120a6e
      cout << "end Tag";
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case BeginEndTag:
Shinya Kitaoka 120a6e
      cout << "begin/end Tag";
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    default:
Shinya Kitaoka 120a6e
      cout << "**bad Tag**";
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    cout << endl;
Shinya Kitaoka 120a6e
    std::map<std::string, string="">::iterator it;</std::string,>
Shinya Kitaoka 120a6e
    for (it = m_attributes.begin(); it != m_attributes.end(); ++it) {
Shinya Kitaoka 120a6e
      cout << " '" << it->first << "' = '" << it->second << "'" << endl;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class TPersistFactory {
Shinya Kitaoka 120a6e
  typedef std::map<std::string, *="" tpersistdeclaration=""> Table;</std::string,>
Shinya Kitaoka 120a6e
  static TPersistFactory *m_factory;
Shinya Kitaoka 120a6e
  Table m_table;
Shinya Kitaoka 120a6e
  TPersistFactory() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  static TPersistFactory *instance() {
Shinya Kitaoka 120a6e
    if (!m_factory) m_factory = new TPersistFactory;
Shinya Kitaoka 120a6e
    return m_factory;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  void add(string name, TPersistDeclaration *decl) { m_table[name] = decl; }
Shinya Kitaoka 120a6e
  TPersist *create(string name) {
Shinya Kitaoka 120a6e
    Table::iterator it = m_table.find(name);
Shinya Kitaoka 120a6e
    if (it != m_table.end())
Shinya Kitaoka 120a6e
      return (it->second)->create();
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      return 0;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TPersistFactory *TPersistFactory::m_factory = 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TPersistDeclaration::TPersistDeclaration(const std::string &id) : m_id(id) {
Shinya Kitaoka 120a6e
  TPersistFactory::instance()->add(id, this);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===============================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TPersist *TPersist::create(const std::string &name) {
Shinya Kitaoka 120a6e
  return TPersistFactory::instance()->create(name);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===============================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class TOStream::Imp {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  ostream *m_os;
Shinya Kitaoka 120a6e
  bool m_chanOwner;
Shinya Kitaoka 120a6e
  bool m_compressed;
Shinya Kitaoka 120a6e
  ostringstream m_ostringstream;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  vector<std::string> m_tagStack;</std::string>
Shinya Kitaoka 120a6e
  int m_tab;
Shinya Kitaoka 120a6e
  bool m_justStarted;
Shinya Kitaoka 120a6e
  typedef map<tpersist *,="" int=""> PersistTable;</tpersist>
Shinya Kitaoka 120a6e
  PersistTable m_table;
Shinya Kitaoka 120a6e
  int m_maxId;
Shinya Kitaoka 120a6e
  TFilePath m_filepath;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  Imp()
Shinya Kitaoka 120a6e
      : m_os(0)
Shinya Kitaoka 120a6e
      , m_chanOwner(false)
Shinya Kitaoka 120a6e
      , m_tab(0)
Shinya Kitaoka 120a6e
      , m_justStarted(true)
Shinya Kitaoka 120a6e
      , m_maxId(0)
Shinya Kitaoka 120a6e
      , m_compressed(false) {}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TOStream::TOStream(const TFilePath &fp, bool compressed) : m_imp(new Imp) {
Shinya Kitaoka 120a6e
  m_imp->m_filepath = fp;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (compressed) {
Shinya Kitaoka 120a6e
    m_imp->m_os         = &m_imp->m_ostringstream;
Shinya Kitaoka 120a6e
    m_imp->m_compressed = true;
Shinya Kitaoka 120a6e
    m_imp->m_chanOwner  = false;
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 2a7129
    std::unique_ptr<tofstream> os(new Tofstream(fp));</tofstream>
Shinya Kitaoka 120a6e
    m_imp->m_os        = os->isOpen() ? os.release() : 0;
Shinya Kitaoka 120a6e
    m_imp->m_chanOwner = true;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_imp->m_justStarted = true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TOStream::TOStream(std::shared_ptr<imp> imp) : m_imp(std::move(imp)) {</imp>
Shinya Kitaoka 120a6e
  assert(!m_imp->m_tagStack.empty());
Shinya Kitaoka 120a6e
  ostream &os = *m_imp->m_os;
Shinya Kitaoka 120a6e
  if (!m_imp->m_justStarted) cr();
Shinya Kitaoka 120a6e
  os << "<" << m_imp->m_tagStack.back() << ">";
Shinya Kitaoka 120a6e
  m_imp->m_tab++;
Shinya Kitaoka 120a6e
  cr();
Shinya Kitaoka 120a6e
  m_imp->m_justStarted = true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TOStream::TOStream(TOStream &&that) : m_imp(std::move(that.m_imp)) {}
Shinya Kitaoka 5f2af0
Shinya Kitaoka 120a6e
TOStream &TOStream::operator=(TOStream &&that) {
Shinya Kitaoka 120a6e
  if (this != &that) {
Shinya Kitaoka 120a6e
    this->m_imp = std::move(that.m_imp);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return *this;
Shinya Kitaoka 5f2af0
}
Shinya Kitaoka 5f2af0
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TOStream::~TOStream() {
Shinya Kitaoka 120a6e
  if (!m_imp) {
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  try {
Shinya Kitaoka 120a6e
    if (!m_imp->m_tagStack.empty()) {
Shinya Kitaoka 120a6e
      string tagName = m_imp->m_tagStack.back();
Shinya Kitaoka 120a6e
      m_imp->m_tagStack.pop_back();
Shinya Kitaoka 120a6e
      assert(tagName != "");
Shinya Kitaoka 120a6e
      ostream &os = *m_imp->m_os;
Shinya Kitaoka 120a6e
      m_imp->m_tab--;
Shinya Kitaoka 120a6e
      if (!m_imp->m_justStarted) cr();
Shinya Kitaoka 120a6e
      os << "";
Shinya Kitaoka 120a6e
      cr();
Shinya Kitaoka 120a6e
      m_imp->m_justStarted = true;
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      if (m_imp->m_compressed) {
Shinya Kitaoka 120a6e
        std::string tmp = m_imp->m_ostringstream.str();
Shinya Kitaoka 120a6e
        const void *in  = (const void *)tmp.c_str();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        size_t in_len = strlen((char *)in);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        size_t out_len = LZ4F_compressFrameBound(in_len, NULL);
Shinya Kitaoka 120a6e
        void *out      = malloc(out_len);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        out_len = LZ4F_compressFrame(out, out_len, in, in_len, NULL);
Shinya Kitaoka 120a6e
        if (!LZ4F_isError(out_len)) {
Shinya Kitaoka 120a6e
          Tofstream os(m_imp->m_filepath);
Shinya Kitaoka 120a6e
          // TNZC <lunghezza dati="" decompress=""> <lunghezza compresso="" dati=""> </lunghezza></lunghezza>
Shinya Kitaoka 120a6e
          // compressi>
Shinya Kitaoka 120a6e
          os.write("TABc", 4);
Shinya Kitaoka 120a6e
          TINT32 v;
Shinya Kitaoka 120a6e
          v = 0x0A0B0C0D;
Shinya Kitaoka 120a6e
          os.write((char *)&v, sizeof v);
Shinya Kitaoka 120a6e
          v = in_len;
Shinya Kitaoka 120a6e
          os.write((char *)&v, sizeof v);
Shinya Kitaoka 120a6e
          v = out_len;
Shinya Kitaoka 120a6e
          os.write((char *)&v, sizeof v);
Shinya Kitaoka 120a6e
          os.write((char *)out, out_len);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        free(out);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      if (m_imp->m_chanOwner) delete m_imp->m_os;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } catch (...) {
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TFilePath TOStream::getFilePath() { return m_imp->m_filepath; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TFilePath TOStream::getRepositoryPath() {
Shinya Kitaoka 120a6e
  TFilePath fp = m_imp->m_filepath;
Shinya Kitaoka 120a6e
  return fp.getParentDir() + (fp.getName() + "_files");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TOStream &TOStream::operator<<(int v) {
Shinya Kitaoka 120a6e
  *(m_imp->m_os) << v << " ";
Shinya Kitaoka 120a6e
  m_imp->m_justStarted = false;
Shinya Kitaoka 120a6e
  return *this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TOStream &TOStream::operator<<(double v) {
Shinya Kitaoka 120a6e
  if (areAlmostEqual(v, 0))  // con valori molto piccoli (es. 1.4e-310) non
Shinya Kitaoka 120a6e
                             // riesce a rileggerli!
Shinya Kitaoka 120a6e
    v = 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  *(m_imp->m_os) << v << " ";
Shinya Kitaoka 120a6e
  m_imp->m_justStarted = false;
Shinya Kitaoka 120a6e
  return *this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TOStream &TOStream::operator<<(string v) {
Shinya Kitaoka 120a6e
  ostream &os = *(m_imp->m_os);
Shinya Kitaoka 120a6e
  int len     = v.length();
Shinya Kitaoka 120a6e
  if (len == 0) {
Shinya Kitaoka 120a6e
    os << "\"\""
Shinya Kitaoka 120a6e
       << " ";
Shinya Kitaoka 120a6e
    m_imp->m_justStarted = false;
Shinya Kitaoka 120a6e
    return *this;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  for (i = 0; i < len; i++)
manongjohn e82b20
    if ((!iswalnum(v[i]) && v[i] != '_' && v[i] != '%') ||
manongjohn e82b20
        v[i] < 32      // Less than ASCII for SPACE
manongjohn e82b20
        || v[i] > 126  // Greater than ASCII for ~
manongjohn e82b20
        )
manongjohn e82b20
      break;
Shinya Kitaoka 120a6e
  if (i == len)
Shinya Kitaoka 120a6e
    os << v << " ";
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    os << '"' << escape(v) << '"';
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  m_imp->m_justStarted = false;
Shinya Kitaoka 120a6e
  return *this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TOStream &TOStream::operator<<(QString _v) {
Shinya Kitaoka 120a6e
  string v = _v.toStdString();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  ostream &os = *(m_imp->m_os);
Shinya Kitaoka 120a6e
  int len     = v.length();
Shinya Kitaoka 120a6e
  if (len == 0) {
Shinya Kitaoka 120a6e
    os << "\"\""
Shinya Kitaoka 120a6e
       << " ";
Toshihiro Shimizu 890ddd
    m_imp->m_justStarted = false;
Toshihiro Shimizu 890ddd
    return *this;
Toshihiro Shimizu 890ddd
  }
Toshihiro Shimizu 890ddd
  int i;
Shinya Kitaoka 120a6e
  for (i = 0; i < len; i++)
manongjohn e82b20
    if ((!iswalnum(v[i]) && v[i] != '_' && v[i] != '%') ||
manongjohn e82b20
        v[i] < 32      // Less than ASCII for SPACE
manongjohn e82b20
        || v[i] > 126  // Greater than ASCII for ~
manongjohn e82b20
        )
manongjohn e82b20
      break;
Shinya Kitaoka 120a6e
  if (i == len)
Shinya Kitaoka 120a6e
    os << v << " ";
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    os << '"' << escape(v) << '"';
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
  m_imp->m_justStarted = false;
Toshihiro Shimizu 890ddd
  return *this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TOStream &TOStream::operator<<(std::wstring v) {
Shinya Kitaoka 120a6e
  return operator<<(::to_string(v));
Shinya Kitaoka 120a6e
  /*
Shinya Kitaoka 120a6e
ostream &os = *(m_imp->m_os);
Shinya Kitaoka 120a6e
int len = v.length();
Shinya Kitaoka 120a6e
if(len==0)
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
os << "\"" << "\"" << " ";
Shinya Kitaoka 120a6e
m_imp->m_justStarted = false;
Shinya Kitaoka 120a6e
return *this;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
int i;
Shinya Kitaoka 120a6e
for(i=0;i
Shinya Kitaoka 120a6e
if(!iswalnum(v[i]) && v[i]!=L'_')
Shinya Kitaoka 120a6e
break;
Shinya Kitaoka 120a6e
if(i==len)
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
os << v;
Shinya Kitaoka 120a6e
os << " ";
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
else
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
os.put('"');
Shinya Kitaoka 120a6e
for(i=0;i
Shinya Kitaoka 120a6e
 if(iswalnum(v[i]))
Shinya Kitaoka 120a6e
   os.put((char)v[i]);
Shinya Kitaoka 120a6e
 else if(v[i]=='"')
Shinya Kitaoka 120a6e
   os << "\\\"";
Shinya Kitaoka 120a6e
 else if(v[i]=='\n')
Shinya Kitaoka 120a6e
   os << "\\n";
Shinya Kitaoka 120a6e
 else if(iswprint(v[i]))
Shinya Kitaoka 120a6e
   os << v[i];
Shinya Kitaoka 120a6e
 else
Shinya Kitaoka 120a6e
   {os.put('\\'); os << (int)v[i];}
Shinya Kitaoka 120a6e
os << "\" ";
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
m_imp->m_justStarted = false;
Shinya Kitaoka 120a6e
return *this;
Shinya Kitaoka 120a6e
*/
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TOStream &TOStream::operator<<(const TFilePath &v) {
Shinya Kitaoka 120a6e
  return operator<<(v.getWideString());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TOStream &TOStream::operator<<(const TPixel32 &v) {
Shinya Kitaoka 120a6e
  ostream &os = *(m_imp->m_os);
Shinya Kitaoka 120a6e
  os << (int)v.r << " " << (int)v.g << " " << (int)v.b << " " << (int)v.m
Shinya Kitaoka 120a6e
     << " ";
Shinya Kitaoka 120a6e
  m_imp->m_justStarted = false;
Shinya Kitaoka 120a6e
  return *this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TOStream &TOStream::operator<<(const TPixel64 &v) {
Shinya Kitaoka 120a6e
  ostream &os = *(m_imp->m_os);
Shinya Kitaoka 120a6e
  os << (int)v.r << " " << (int)v.g << " " << (int)v.b << " " << (int)v.m
Shinya Kitaoka 120a6e
     << " ";
Shinya Kitaoka 120a6e
  m_imp->m_justStarted = false;
Shinya Kitaoka 120a6e
  return *this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TOStream::cr() {
Shinya Kitaoka 120a6e
  *(m_imp->m_os) << endl;
shun-iwasawa e3d315
  for (int i = 0; i < m_imp->m_tab; i++) *(m_imp->m_os) << "  ";
Shinya Kitaoka 120a6e
  m_imp->m_justStarted = false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
TOStream::operator bool() const { return (m_imp->m_os && *m_imp->m_os); }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//---------------------------------------------------------------
Shinya Kitaoka 120a6e
TOStream TOStream::child(string tagName) {
Shinya Kitaoka 120a6e
  assert(tagName != "");
Shinya Kitaoka 120a6e
  m_imp->m_tagStack.push_back(tagName);
Shinya Kitaoka 120a6e
  return TOStream(m_imp);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TOStream::openChild(string tagName) {
Shinya Kitaoka 120a6e
  assert(tagName != "");
Shinya Kitaoka 120a6e
  m_imp->m_tagStack.push_back(tagName);
Shinya Kitaoka 120a6e
  if (m_imp->m_justStarted == false) cr();
Shinya Kitaoka 120a6e
  *(m_imp->m_os) << "<" << m_imp->m_tagStack.back() << ">";
Shinya Kitaoka 120a6e
  m_imp->m_tab++;
Shinya Kitaoka 120a6e
  cr();
Shinya Kitaoka 120a6e
  m_imp->m_justStarted = true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TOStream::openChild(string tagName,
Shinya Kitaoka 120a6e
                         const map<std::string, string=""> &attributes) {</std::string,>
Shinya Kitaoka 120a6e
  assert(tagName != "");
Shinya Kitaoka 120a6e
  m_imp->m_tagStack.push_back(tagName);
Shinya Kitaoka 120a6e
  if (m_imp->m_justStarted == false) cr();
Shinya Kitaoka 120a6e
  *(m_imp->m_os) << "<" << m_imp->m_tagStack.back();
Shinya Kitaoka 120a6e
  for (std::map<std::string, string="">::const_iterator it = attributes.begin();</std::string,>
Shinya Kitaoka 120a6e
       it != attributes.end(); ++it) {
Shinya Kitaoka 120a6e
    *(m_imp->m_os) << " " << it->first << "=\"" << escape(it->second) << "\"";
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  *(m_imp->m_os) << ">";
Shinya Kitaoka 120a6e
  m_imp->m_tab++;
Shinya Kitaoka 120a6e
  cr();
Shinya Kitaoka 120a6e
  m_imp->m_justStarted = true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TOStream::closeChild() {
Shinya Kitaoka 120a6e
  assert(!m_imp->m_tagStack.empty());
Shinya Kitaoka 120a6e
  string tagName = m_imp->m_tagStack.back();
Shinya Kitaoka 120a6e
  m_imp->m_tagStack.pop_back();
Shinya Kitaoka 120a6e
  assert(tagName != "");
Shinya Kitaoka 120a6e
  // ostream &os = *m_imp->m_os; //os non e' usato
Shinya Kitaoka 120a6e
  m_imp->m_tab--;
Shinya Kitaoka 120a6e
  if (!m_imp->m_justStarted) cr();
Shinya Kitaoka 120a6e
  *(m_imp->m_os) << "";
Shinya Kitaoka 120a6e
  cr();
Shinya Kitaoka 120a6e
  m_imp->m_justStarted = true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TOStream::openCloseChild(string tagName,
Shinya Kitaoka 120a6e
                              const map<std::string, string=""> &attributes) {</std::string,>
Shinya Kitaoka 120a6e
  assert(tagName != "");
Shinya Kitaoka 120a6e
  // m_imp->m_tagStack.push_back(tagName);
Shinya Kitaoka 120a6e
  if (m_imp->m_justStarted == false) cr();
Shinya Kitaoka 120a6e
  *(m_imp->m_os) << "<" << tagName;
Shinya Kitaoka 120a6e
  for (std::map<std::string, string="">::const_iterator it = attributes.begin();</std::string,>
Shinya Kitaoka 120a6e
       it != attributes.end(); ++it) {
Shinya Kitaoka 120a6e
    *(m_imp->m_os) << " " << it->first << "=\"" << escape(it->second) << "\"";
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  *(m_imp->m_os) << "/>";
Shinya Kitaoka 120a6e
  // m_imp->m_tab++;
Shinya Kitaoka 120a6e
  cr();
Shinya Kitaoka 120a6e
  m_imp->m_justStarted = true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TOStream &TOStream::operator<<(TPersist &v) {
Shinya Kitaoka 120a6e
  v.saveData(*this);
Shinya Kitaoka 120a6e
  return *this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TOStream &TOStream::operator<<(TPersist *v) {
Shinya Kitaoka 120a6e
  Imp::PersistTable::iterator it = m_imp->m_table.find(v);
Shinya Kitaoka 120a6e
  if (it != m_imp->m_table.end()) {
Shinya Kitaoka 120a6e
    *(m_imp->m_os) << "<" << v->getStreamTag() << " id='" << it->second
Shinya Kitaoka 120a6e
                   << "'/>";
Shinya Kitaoka 120a6e
    m_imp->m_justStarted = false;
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    int id            = ++m_imp->m_maxId;
Shinya Kitaoka 120a6e
    m_imp->m_table[v] = id;
Shinya Kitaoka 120a6e
    *(m_imp->m_os) << "<" << v->getStreamTag() << " id='" << id << "'>";
Shinya Kitaoka 120a6e
    m_imp->m_tab++;
Shinya Kitaoka 120a6e
    cr();
Shinya Kitaoka 120a6e
    v->saveData(*this);
Shinya Kitaoka 120a6e
    m_imp->m_tab--;
Shinya Kitaoka 120a6e
    cr();
Shinya Kitaoka 120a6e
    *(m_imp->m_os) << "getStreamTag() << ">";
Shinya Kitaoka 120a6e
    cr();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return *this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TOStream::checkStatus() const {
Shinya Kitaoka 120a6e
  if (!m_imp->m_os) return false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_imp->m_os->flush();
Shinya Kitaoka 120a6e
  return m_imp->m_os->rdstate() == ios_base::goodbit;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
shun-iwasawa e3d315
std::string TOStream::getCurrentTagName() {
shun-iwasawa e3d315
  return (m_imp->m_tagStack.empty()) ? "" : m_imp->m_tagStack.back();
shun-iwasawa e3d315
}
shun-iwasawa e3d315
Toshihiro Shimizu 890ddd
//===============================================================
tomosu 516280
/*!
Shinya Kitaoka 120a6e
        This class contains TIStream's attributes.
Shinya Kitaoka 120a6e
        It is created by memory allocation in the TIStream's constructor.
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
class TIStream::Imp {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  istream *m_is;
Shinya Kitaoka 120a6e
  bool m_chanOwner;
Shinya Kitaoka 120a6e
  int m_line;
Shinya Kitaoka 120a6e
  string m_strbuffer;
Shinya Kitaoka 120a6e
  bool m_compressed;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  vector<std::string> m_tagStack;</std::string>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  typedef map<int, *="" tpersist=""> PersistTable;</int,>
Shinya Kitaoka 120a6e
  PersistTable m_table;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  StreamTag m_currentTag;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TFilePath m_filepath;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  VersionNumber m_versionNumber;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  Imp()
Shinya Kitaoka 120a6e
      : m_is(0)
Shinya Kitaoka 120a6e
      , m_chanOwner(false)
Shinya Kitaoka 120a6e
      , m_line(0)
Shinya Kitaoka 120a6e
      , m_compressed(false)
Shinya Kitaoka 120a6e
      , m_versionNumber(0, 0) {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // update m_line if necessary; returns -e if eof
Shinya Kitaoka 120a6e
  int getNextChar();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  inline void skipBlanks();
Shinya Kitaoka 120a6e
  bool matchTag();
Shinya Kitaoka 120a6e
  inline bool match(char c);
Shinya Kitaoka 120a6e
  bool matchIdent(string &ident);
Shinya Kitaoka 120a6e
  bool matchValue(string &value);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void skipCurrentTag();
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TFilePath TIStream::getFilePath() { return m_imp->m_filepath; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TFilePath TIStream::getRepositoryPath() {
Shinya Kitaoka 120a6e
  TFilePath fp = m_imp->m_filepath;
Shinya Kitaoka 120a6e
  return fp.getParentDir() + (fp.getName() + "_files");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TIStream::Imp::getNextChar() {
Shinya Kitaoka 120a6e
  char c;
Shinya Kitaoka 120a6e
  m_is->get(c);
Shinya Kitaoka 120a6e
  if (m_is->eof()) return -1;
Shinya Kitaoka 120a6e
  if (c == '\r') m_line++;
Shinya Kitaoka 120a6e
  return c;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TIStream::Imp::skipBlanks() {
Shinya Kitaoka 120a6e
  istream &is = *m_is;
Shinya Kitaoka 120a6e
  istream::int_type c;
Shinya Kitaoka 120a6e
  while (c = is.peek(), (isspace(c) || c == '\r')) getNextChar();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TIStream::Imp::match(char c) {
Shinya Kitaoka 120a6e
  if (m_is->peek() == c) {
Shinya Kitaoka 120a6e
    getNextChar();
Shinya Kitaoka 120a6e
    return true;
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TIStream::Imp::matchIdent(string &ident) {
Shinya Kitaoka 120a6e
  istream &is = *m_is;
Shinya Kitaoka 120a6e
  if (!isalnum(is.peek())) return false;
Shinya Kitaoka 120a6e
  ident = "";
Shinya Kitaoka 120a6e
  char c;
Shinya Kitaoka 120a6e
  is.get(c);
Shinya Kitaoka 120a6e
  ident.append(1, c);
Shinya Kitaoka 120a6e
  while (c = is.peek(), isalnum(c) || c == '_' || c == '.' || c == '-') {
Shinya Kitaoka 120a6e
    is.get(c);
Shinya Kitaoka 120a6e
    ident.append(1, c);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TIStream::Imp::matchValue(string &str) {
Shinya Kitaoka 120a6e
  istream &is = *m_is;
Shinya Kitaoka 120a6e
  char quote  = is.peek();
Shinya Kitaoka 120a6e
  char c;
Shinya Kitaoka 120a6e
  if (!is || (quote != '\'' && quote != '\"')) return false;
Shinya Kitaoka 120a6e
  is.get(c);
Shinya Kitaoka 120a6e
  str = "";
Shinya Kitaoka 120a6e
  for (;;) {
Shinya Kitaoka 120a6e
    is.get(c);
Shinya Kitaoka 120a6e
    if (!is) throw TException("expected '\"'");
Shinya Kitaoka 120a6e
    if (c == quote) break;
Shinya Kitaoka 120a6e
    if (c == '\\') {
Shinya Kitaoka 120a6e
      is.get(c);
Shinya Kitaoka 120a6e
      if (!is) throw TException("unexpected EOF");
Shinya Kitaoka 120a6e
      if (c != '\'' && c != '\"' && c != '\\')
Shinya Kitaoka 120a6e
        throw TException("bad escape sequence");
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    str.append(1, c);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (c != quote) throw TException("missing '\"'");
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TIStream::Imp::matchTag() {
Shinya Kitaoka 120a6e
  if (m_currentTag) return true;
Shinya Kitaoka 120a6e
  StreamTag &tag = m_currentTag;
Shinya Kitaoka 120a6e
  tag            = StreamTag();
Shinya Kitaoka 120a6e
  skipBlanks();
Shinya Kitaoka 120a6e
  if (!match('<')) return false;
Shinya Kitaoka 120a6e
  skipBlanks();
Shinya Kitaoka 120a6e
  if (match('!')) {
Shinya Kitaoka 120a6e
    skipBlanks();
Shinya Kitaoka 120a6e
    if (!match('-') || !match('-')) throw TException("expected '
Shinya Kitaoka 120a6e
    istream &is = *m_is;
Shinya Kitaoka 120a6e
    char c;
Shinya Kitaoka 120a6e
    int status = 1;
Shinya Kitaoka 120a6e
    while (status != 0 && is.get(c)) switch (status) {
Shinya Kitaoka 120a6e
      case 1:
Shinya Kitaoka 120a6e
        if (c == '-') status = 2;
Shinya Kitaoka 120a6e
        break;
Shinya Kitaoka 120a6e
      case 2:
Shinya Kitaoka 120a6e
        if (c == '-')
Shinya Kitaoka 120a6e
          status = 3;
Shinya Kitaoka 120a6e
        else
Shinya Kitaoka 120a6e
          status = 1;
Shinya Kitaoka 120a6e
        break;
Shinya Kitaoka 120a6e
      case 3:
Shinya Kitaoka 120a6e
        if (c == '>')
Shinya Kitaoka 120a6e
          status = 0;
Shinya Kitaoka 120a6e
        else if (c == '-') {
Shinya Kitaoka 120a6e
        } else
Shinya Kitaoka 120a6e
          status = 1;
Shinya Kitaoka 120a6e
        break;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    return matchTag();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (match('/')) {
Shinya Kitaoka 120a6e
    tag.m_type = StreamTag::EndTag;
Shinya Kitaoka 120a6e
    skipBlanks();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!matchIdent(tag.m_name)) throw TException("expected identifier");
Shinya Kitaoka 120a6e
  skipBlanks();
Shinya Kitaoka 120a6e
  for (;;) {
Shinya Kitaoka 120a6e
    if (match('>')) break;
Shinya Kitaoka 120a6e
    if (match('/')) {
Shinya Kitaoka 120a6e
      tag.m_type = StreamTag::BeginEndTag;
Shinya Kitaoka 120a6e
      skipBlanks();
Shinya Kitaoka 120a6e
      if (match('>')) break;
Shinya Kitaoka 120a6e
      throw TException("expected '>'");
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    string name;
Shinya Kitaoka 120a6e
    if (!matchIdent(name)) throw TException("expected identifier");
Shinya Kitaoka 120a6e
    skipBlanks();
Shinya Kitaoka 120a6e
    if (match('=')) {
Shinya Kitaoka 120a6e
      string value;
Shinya Kitaoka 120a6e
      skipBlanks();
Shinya Kitaoka 120a6e
      if (!matchValue(value)) throw TException("expected value");
Shinya Kitaoka 120a6e
      tag.m_attributes[name] = value;
Shinya Kitaoka 120a6e
      skipBlanks();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TIStream::Imp::skipCurrentTag() {
Shinya Kitaoka 120a6e
  if (m_currentTag.m_type == StreamTag::BeginEndTag) return;
Shinya Kitaoka 120a6e
  istream &is = *m_is;
Shinya Kitaoka 120a6e
  int level   = 1;
Shinya Kitaoka 120a6e
  int c;
Shinya Kitaoka 120a6e
  for (;;) {
Shinya Kitaoka 120a6e
    if (is.eof()) break;  // unexpected eof
Shinya Kitaoka 120a6e
    c = is.peek();
Shinya Kitaoka 120a6e
    if (c != '<') {
Shinya Kitaoka 120a6e
      getNextChar();
Shinya Kitaoka 120a6e
      continue;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // tag found
Shinya Kitaoka 120a6e
    c = getNextChar();
Shinya Kitaoka 120a6e
    if (c < 0) break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    c = getNextChar();
Shinya Kitaoka 120a6e
    if (c < 0) break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (c == '/') {
Shinya Kitaoka 120a6e
      // end tag
Shinya Kitaoka 120a6e
      do
Shinya Kitaoka 120a6e
        c = getNextChar();
Shinya Kitaoka 120a6e
      while (c >= 0 && c != '>');
Shinya Kitaoka 120a6e
      if (c < 0) break;  // unexpected eof
Shinya Kitaoka 120a6e
      if (--level <= 0) {
Shinya Kitaoka 120a6e
        // m_currentTag.m_type = StreamTag::EndTag;
Shinya Kitaoka 120a6e
        m_tagStack.pop_back();
Shinya Kitaoka 120a6e
        m_currentTag = StreamTag();
Shinya Kitaoka 120a6e
        break;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      // tag
Shinya Kitaoka 120a6e
      int oldC;
Shinya Kitaoka 120a6e
      do {
Shinya Kitaoka 120a6e
        oldC = c;
Shinya Kitaoka 120a6e
        c    = getNextChar();
Shinya Kitaoka 120a6e
      } while (c >= 0 && c != '>');
Shinya Kitaoka 120a6e
      if (c < 0) break;  // unexpected eof
Shinya Kitaoka 120a6e
      if (oldC != '/') level++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TIStream::TIStream(const TFilePath &fp) : m_imp(new Imp) {
Shinya Kitaoka 120a6e
  m_imp->m_filepath = fp;
Shinya Kitaoka 120a6e
  m_imp->m_is       = new Tifstream(fp);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_imp->m_is->peek() == 'T')  // non comincia con '<' dev'essere compresso
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    bool swapForEndianess = false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 2a7129
    unique_ptr<std::istream> is(m_imp->m_is);</std::istream>
Shinya Kitaoka 120a6e
    m_imp->m_is = 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    char magicBuffer[4];
Shinya Kitaoka 120a6e
    is->read(magicBuffer, 4);
Shinya Kitaoka 120a6e
    string magic(magicBuffer, 4);
Shinya Kitaoka 120a6e
    size_t in_len, out_len;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (magic == "TNZC") {
Shinya Kitaoka 120a6e
      // Tab3.0 beta
Shinya Kitaoka 120a6e
      is->read((char *)&out_len, sizeof out_len);
Shinya Kitaoka 120a6e
      is->read((char *)&in_len, sizeof in_len);
Shinya Kitaoka 120a6e
    } else if (magic == "TABc") {
Shinya Kitaoka 120a6e
      TINT32 v;
Shinya Kitaoka 120a6e
      is->read((char *)&v, sizeof v);
Shinya Kitaoka 120a6e
      printf("magic = %08X\n", v);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      if (v == 0x0A0B0C0D)
Shinya Kitaoka 120a6e
        swapForEndianess = false;
Shinya Kitaoka 120a6e
      else if (v == 0x0D0C0B0A)
Shinya Kitaoka 120a6e
        swapForEndianess = true;
Shinya Kitaoka 120a6e
      else {
Shinya Kitaoka 120a6e
        swapForEndianess = true;
Shinya Kitaoka 120a6e
        printf("UH OH!\n");
Shinya Kitaoka 120a6e
      }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      is->read((char *)&v, sizeof v);
Shinya Kitaoka 120a6e
      out_len = swapForEndianess ? swapTINT32(v) : v;
Shinya Kitaoka 120a6e
      is->read((char *)&v, sizeof v);
Shinya Kitaoka 120a6e
      in_len = swapForEndianess ? swapTINT32(v) : v;
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      throw TException("Bad magic number");
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (in_len <= 0 || in_len > 100000000)  // 100M di tnzfile (compresso)
Shinya Kitaoka 120a6e
                                            // sembrano proprio esagerati
Shinya Kitaoka 120a6e
      throw TException("Corrupted file");
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    LZ4F_decompressionContext_t lz4dctx;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    LZ4F_errorCode_t err =
Shinya Kitaoka 120a6e
        LZ4F_createDecompressionContext(&lz4dctx, LZ4F_VERSION);
Shinya Kitaoka 120a6e
    if (LZ4F_isError(err)) throw TException("Couldn't decompress file");
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    char *in = (char *)malloc(in_len);
Shinya Kitaoka 120a6e
    is->read((char *)in, in_len);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    m_imp->m_strbuffer.resize(out_len + 1000);  // per prudenza
Shinya Kitaoka 120a6e
    char *out = (char *)m_imp->m_strbuffer.c_str();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    size_t check_len = out_len;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    // size_t remaining = LZ4F_decompress(lz4dctx, out, &out_len, in, &in_len,
Shinya Kitaoka 120a6e
    // NULL);
Shinya Kitaoka 120a6e
    bool ok = lz4decompress(lz4dctx, out, &out_len, in, in_len);
Shinya Kitaoka 120a6e
    LZ4F_freeDecompressionContext(lz4dctx);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    free(in);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (!ok) throw TException("Couldn't decompress file");
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (check_len != out_len) throw TException("corrupted file");
Toshihiro Shimizu 890ddd
MichaƂ Janiszewski 7a49c6
    m_imp->m_is = new istringstream(std::string(out, out_len));
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_imp->m_chanOwner = true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
TIStream::TIStream(istream &is)
Toshihiro Shimizu 890ddd
         : m_imp(new Imp)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
  m_imp->m_is = &is;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TIStream::~TIStream() {
Shinya Kitaoka 120a6e
  if (m_imp->m_chanOwner) delete m_imp->m_is;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TIStream &TIStream::operator>>(int &v) {
Shinya Kitaoka 120a6e
  *(m_imp->m_is) >> v;
Shinya Kitaoka 120a6e
  return *this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TIStream &TIStream::operator>>(double &v) {
Shinya Kitaoka 120a6e
  *(m_imp->m_is) >> v;
Shinya Kitaoka 120a6e
  return *this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TIStream &TIStream::operator>>(std::wstring &v) {
Shinya Kitaoka 120a6e
  string s;
Shinya Kitaoka 120a6e
  operator>>(s);
Shinya Kitaoka 120a6e
  v = ::to_wstring(s);
Shinya Kitaoka 120a6e
  return *this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TIStream &TIStream::operator>>(string &v) {
Shinya Kitaoka 120a6e
  istream &is = *(m_imp->m_is);
Shinya Kitaoka 120a6e
  v           = "";
Shinya Kitaoka 120a6e
  m_imp->skipBlanks();
Shinya Kitaoka 120a6e
  char c;
Shinya Kitaoka 120a6e
  is.get(c);
Shinya Kitaoka 120a6e
  if (c == '\"') {
Shinya Kitaoka 120a6e
    is.get(c);
Shinya Kitaoka 120a6e
    while (is && c != '"') {
Shinya Kitaoka 120a6e
      if (c == '\\') {
Shinya Kitaoka 120a6e
        is.get(c);
Shinya Kitaoka 120a6e
        if (!is) throw TException("unexpected EOF");
Shinya Kitaoka 120a6e
        if (c == '"')
Shinya Kitaoka 120a6e
          v.append(1, '"');
Shinya Kitaoka 120a6e
        else if (c == '\\')
Shinya Kitaoka 120a6e
          v.append(1, '\\');
Shinya Kitaoka 120a6e
        else if (c == '\'')
Shinya Kitaoka 120a6e
          v.append(1, '\'');
Shinya Kitaoka 120a6e
        else {
Shinya Kitaoka 120a6e
          v.append(1, '\\');
Shinya Kitaoka 120a6e
          v.append(1, c);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      } else
Shinya Kitaoka 120a6e
        v.append(1, c);
Shinya Kitaoka 120a6e
      is.get(c);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    v.append(1, c);
Shinya Kitaoka 120a6e
    while (c = is.peek(), isalnum(c) || c == '_' || c == '&' || c == '#' ||
Shinya Kitaoka 120a6e
                              c == ';' || c == '%') {
Shinya Kitaoka 120a6e
      is.get(c);
Shinya Kitaoka 120a6e
      v.append(1, c);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return *this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TIStream &TIStream::operator>>(QString &v) {
Shinya Kitaoka 120a6e
  istream &is = *(m_imp->m_is);
Shinya Kitaoka 120a6e
  v           = "";
Shinya Kitaoka 120a6e
  m_imp->skipBlanks();
Shinya Kitaoka 120a6e
  char c;
Shinya Kitaoka 120a6e
  is.get(c);
Shinya Kitaoka 120a6e
  if (c == '\"') {
Shinya Kitaoka 120a6e
    is.get(c);
Shinya Kitaoka 120a6e
    while (is && c != '"') {
Shinya Kitaoka 120a6e
      if (c == '\\') {
Shinya Kitaoka 120a6e
        is.get(c);
Shinya Kitaoka 120a6e
        if (!is) throw TException("unexpected EOF");
Shinya Kitaoka 120a6e
        if (c == '"')
Shinya Kitaoka 120a6e
          v.append('"');
Shinya Kitaoka 120a6e
        else if (c == '\\')
Shinya Kitaoka 120a6e
          v.append('\\');
Shinya Kitaoka 120a6e
        else if (c == '\'')
Shinya Kitaoka 120a6e
          v.append('\'');
Shinya Kitaoka 120a6e
        else {
Shinya Kitaoka 120a6e
          v.append('\\');
Shinya Kitaoka 120a6e
          v.append(c);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      } else
Shinya Kitaoka 120a6e
        v.append(c);
Shinya Kitaoka 120a6e
      is.get(c);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    v.append(c);
Shinya Kitaoka 120a6e
    while (c = is.peek(), isalnum(c) || c == '_' || c == '&' || c == '#' ||
Shinya Kitaoka 120a6e
                              c == ';' || c == '%') {
Shinya Kitaoka 120a6e
      is.get(c);
Shinya Kitaoka 120a6e
      v.append(c);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return *this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
string TIStream::getString() {
Shinya Kitaoka 120a6e
  istream &is = *(m_imp->m_is);
Shinya Kitaoka 120a6e
  string v    = "";
Shinya Kitaoka 120a6e
  m_imp->skipBlanks();
Shinya Kitaoka 120a6e
  char c = is.peek();
Shinya Kitaoka 120a6e
  while (c != '<') {
Shinya Kitaoka 120a6e
    is.get(c);
Shinya Kitaoka 120a6e
    c = is.peek();
Shinya Kitaoka 120a6e
    if (!is) throw TException("unexpected EOF");
Shinya Kitaoka 120a6e
    v.append(1, c);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return v;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TIStream &TIStream::operator>>(TPixel32 &v) {
Shinya Kitaoka 120a6e
  istream &is = *(m_imp->m_is);
Shinya Kitaoka 120a6e
  int r, g, b, m;
Shinya Kitaoka 120a6e
  is >> r;
Shinya Kitaoka 120a6e
  is >> g;
Shinya Kitaoka 120a6e
  is >> b;
Shinya Kitaoka 120a6e
  is >> m;
Shinya Kitaoka 120a6e
  v.r = r;
Shinya Kitaoka 120a6e
  v.g = g;
Shinya Kitaoka 120a6e
  v.b = b;
Shinya Kitaoka 120a6e
  v.m = m;
Shinya Kitaoka 120a6e
  return *this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TIStream &TIStream::operator>>(TPixel64 &v) {
Shinya Kitaoka 120a6e
  istream &is = *(m_imp->m_is);
Shinya Kitaoka 120a6e
  int r, g, b, m;
Shinya Kitaoka 120a6e
  is >> r;
Shinya Kitaoka 120a6e
  is >> g;
Shinya Kitaoka 120a6e
  is >> b;
Shinya Kitaoka 120a6e
  is >> m;
Shinya Kitaoka 120a6e
  v.r = r;
Shinya Kitaoka 120a6e
  v.g = g;
Shinya Kitaoka 120a6e
  v.b = b;
Shinya Kitaoka 120a6e
  v.m = m;
Shinya Kitaoka 120a6e
  return *this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TIStream &TIStream::operator>>(TFilePath &v) {
Shinya Kitaoka 120a6e
  istream &is = *(m_imp->m_is);
Shinya Kitaoka 120a6e
  string s;
Shinya Kitaoka 120a6e
  char c;
Shinya Kitaoka 120a6e
  m_imp->skipBlanks();
Shinya Kitaoka 120a6e
  is.get(c);
Shinya Kitaoka 120a6e
  if (c == '"') {
Shinya Kitaoka 120a6e
    is.get(c);
manongjohn 6ea45d
    bool escapeChar = false;
manongjohn e82b20
    // If processing double-quote ("), if it's escaped, keep reading.
manongjohn 6ea45d
    while (is && (c != '"' || escapeChar)) {
Shinya Kitaoka 120a6e
      // if(c=='\\')
Shinya Kitaoka 120a6e
      //   is.get(c);
manongjohn 6ea45d
      if (c == '\\' && !escapeChar)
manongjohn 6ea45d
        escapeChar = true;
manongjohn e82b20
      else
manongjohn 6ea45d
        escapeChar = false;
Shinya Kitaoka 120a6e
      s.append(1, c);
Shinya Kitaoka 120a6e
      is.get(c);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    // il filepath non e' fra virgolette:
Shinya Kitaoka 120a6e
    // puo' contenere solo caratteri alfanumerici, % e _
Shinya Kitaoka 120a6e
    s.append(1, c);
Shinya Kitaoka 120a6e
    while (is) {
Shinya Kitaoka 120a6e
      c = is.peek();
Shinya Kitaoka 120a6e
      if (!isalnum(c) && c != '%' && c != '_') break;
Shinya Kitaoka 120a6e
      is.get(c);
Shinya Kitaoka 120a6e
      s.append(1, c);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  v = TFilePath(s);
Shinya Kitaoka 120a6e
  return *this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TIStream &TIStream::operator>>(TPersist &v) {
Shinya Kitaoka 120a6e
  v.loadData(*this);
Shinya Kitaoka 120a6e
  return *this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TIStream &TIStream::operator>>(TPersist *&v) {
Shinya Kitaoka 120a6e
  if (!m_imp->matchTag() || m_imp->m_currentTag.m_type == StreamTag::EndTag) {
Shinya Kitaoka 120a6e
    throw TException("expected begin tag");
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  StreamTag tag       = m_imp->m_currentTag;
Shinya Kitaoka 120a6e
  m_imp->m_currentTag = StreamTag();
Shinya Kitaoka 120a6e
  string tagName      = tag.m_name;
Shinya Kitaoka 120a6e
  std::map<std::string, string="">::iterator it;</std::string,>
shun-iwasawa e3d315
  int id = -1;
shun-iwasawa e3d315
  it     = tag.m_attributes.find("id");
Shinya Kitaoka 120a6e
  if (it != tag.m_attributes.end()) id = atoi(it->second.c_str());
Shinya Kitaoka 120a6e
  // cout << "tagname = " << tagName << " id = " << id << endl;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  Imp::PersistTable::iterator pit = m_imp->m_table.find(id);
Shinya Kitaoka 120a6e
  if (pit == m_imp->m_table.end()) {
Shinya Kitaoka 120a6e
    v = TPersistFactory::instance()->create(tagName);
Shinya Kitaoka 120a6e
    if (!v) throw TException("unable to create a persistent '" + tagName + "'");
Shinya Kitaoka 120a6e
    m_imp->m_table[id] = v;
Shinya Kitaoka 120a6e
    if (tag.m_type != StreamTag::BeginTag)
Shinya Kitaoka 120a6e
      throw TException("expected begin tag");
Shinya Kitaoka 120a6e
    m_imp->m_tagStack.push_back(tag.m_name);
Shinya Kitaoka 120a6e
    v->loadData(*this);
Shinya Kitaoka 120a6e
    m_imp->matchTag();
Shinya Kitaoka 120a6e
    if (!m_imp->m_currentTag || m_imp->m_currentTag.m_type != StreamTag::EndTag)
Shinya Kitaoka 120a6e
      throw TException("expected end tag");
Shinya Kitaoka 120a6e
    if (m_imp->m_currentTag.m_name != m_imp->m_tagStack.back())
Shinya Kitaoka 120a6e
      throw TException("end tag mismatch");
Shinya Kitaoka 120a6e
    m_imp->m_tagStack.pop_back();
Shinya Kitaoka 120a6e
    m_imp->m_currentTag = StreamTag();
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    v = pit->second;
Shinya Kitaoka 120a6e
    if (tag.m_type != StreamTag::BeginEndTag)
Shinya Kitaoka 120a6e
      throw TException("expected begin/end tag");
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return *this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TIStream::matchEndTag() {
luz paz 6454c4
  if (m_imp->m_tagStack.empty()) throw TException("tag stack empty");
Shinya Kitaoka 120a6e
  if (!m_imp->matchTag()) return false;
Shinya Kitaoka 120a6e
  if (m_imp->m_currentTag.m_type != StreamTag::EndTag) return false;
Shinya Kitaoka 120a6e
  if (m_imp->m_currentTag.m_name != m_imp->m_tagStack.back())
Shinya Kitaoka 120a6e
    throw TException("end tag mismatch");
Shinya Kitaoka 120a6e
  m_imp->m_tagStack.pop_back();
Shinya Kitaoka 120a6e
  m_imp->m_currentTag = StreamTag();
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TIStream::eos() {
Shinya Kitaoka 120a6e
  if (m_imp->matchTag())
Shinya Kitaoka 120a6e
    return m_imp->m_currentTag.m_type == StreamTag::EndTag;
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    return !(*m_imp->m_is);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TIStream::matchTag(string &tagName) {
Shinya Kitaoka 120a6e
  if (!m_imp->matchTag()) return false;
Shinya Kitaoka 120a6e
  if (m_imp->m_currentTag.m_type == StreamTag::EndTag) return false;
Shinya Kitaoka 120a6e
  tagName                    = m_imp->m_currentTag.m_name;
Shinya Kitaoka 120a6e
  m_imp->m_currentTag.m_name = "";
Shinya Kitaoka 120a6e
  if (m_imp->m_currentTag.m_type != StreamTag::BeginEndTag)
Shinya Kitaoka 120a6e
    m_imp->m_tagStack.push_back(tagName);
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
string TIStream::getTagAttribute(string name) const {
Shinya Kitaoka 120a6e
  StreamTag &tag = m_imp->m_currentTag;
Shinya Kitaoka 120a6e
  std::map<std::string, string="">::const_iterator it =</std::string,>
Shinya Kitaoka 120a6e
      tag.m_attributes.find(name);
Shinya Kitaoka 120a6e
  if (it == tag.m_attributes.end())
Shinya Kitaoka 120a6e
    return "";
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    return it->second;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TIStream::getTagParam(string paramName, string &value) {
Shinya Kitaoka 120a6e
  if (m_imp->m_tagStack.empty()) return false;
Shinya Kitaoka 120a6e
  StreamTag &tag = m_imp->m_currentTag;
Shinya Kitaoka 120a6e
  std::map<std::string, string="">::const_iterator it =</std::string,>
Shinya Kitaoka 120a6e
      tag.m_attributes.find(paramName);
Shinya Kitaoka 120a6e
  if (it == tag.m_attributes.end()) return false;
Shinya Kitaoka 120a6e
  value = it->second;
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TIStream::getTagParam(string paramName, int &value) {
Shinya Kitaoka 120a6e
  string svalue;
Shinya Kitaoka 120a6e
  if (!getTagParam(paramName, svalue)) return false;
MichaƂ Janiszewski 7a49c6
  istringstream is(svalue);
Shinya Kitaoka 120a6e
  value = 0;
Shinya Kitaoka 120a6e
  is >> value;
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TIStream::isBeginEndTag() {
Shinya Kitaoka 120a6e
  return m_imp->m_currentTag.m_type == StreamTag::BeginEndTag;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TIStream::openChild(string &tagName) {
Shinya Kitaoka 120a6e
  if (!m_imp->matchTag()) return false;
Shinya Kitaoka 120a6e
  if (m_imp->m_currentTag.m_type != StreamTag::BeginTag) return false;
Shinya Kitaoka 120a6e
  tagName                    = m_imp->m_currentTag.m_name;
Shinya Kitaoka 120a6e
  m_imp->m_currentTag.m_name = "";
Shinya Kitaoka 120a6e
  m_imp->m_tagStack.push_back(tagName);
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TIStream::closeChild() {
Shinya Kitaoka 120a6e
  if (!matchEndTag()) {
Shinya Kitaoka 120a6e
    string tagName;
Shinya Kitaoka 120a6e
    if (!m_imp->m_tagStack.empty()) tagName = m_imp->m_tagStack.back();
Shinya Kitaoka 120a6e
    if (tagName != "")
Shinya Kitaoka 120a6e
      throw TException("Expected \"" + tagName + "\" end tag");
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      throw TException("expected EndTag");
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TIStream::match(char c) const {
Shinya Kitaoka 120a6e
  m_imp->skipBlanks();
Shinya Kitaoka 120a6e
  if (m_imp->m_is->peek() != c) return false;
Shinya Kitaoka 120a6e
  m_imp->m_is->get(c);
Shinya Kitaoka 120a6e
  if (c == '\r') m_imp->m_line++;
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TIStream::operator bool() const { return (m_imp->m_is && *m_imp->m_is); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TIStream::getLine() const { return m_imp->m_line + 1; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
VersionNumber TIStream::getVersion() const { return m_imp->m_versionNumber; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TIStream::setVersion(const VersionNumber &version) {
Shinya Kitaoka 120a6e
  m_imp->m_versionNumber = version;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TIStream::skipCurrentTag() { m_imp->skipCurrentTag(); }
shun-iwasawa e3d315
shun-iwasawa e3d315
//---------------------------------------------------------------
shun-iwasawa e3d315
shun-iwasawa e3d315
std::string TIStream::getCurrentTagName() { return m_imp->m_tagStack.back(); }