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
//===============================================================
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
string escape(string v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int i = 0;
Toshihiro Shimizu 890ddd
	for (;;) {
Toshihiro Shimizu 890ddd
		i = v.find_first_of("\\\'\"", i);
Toshihiro Shimizu 890ddd
		if (i == (int)string::npos)
Toshihiro Shimizu 890ddd
			break;
Toshihiro Shimizu 890ddd
		string h = "\\" + v[i];
Toshihiro Shimizu 890ddd
		v.insert(i, "\\");
Toshihiro Shimizu 890ddd
		i = i + 2;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return v;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===============================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void writeCompressedFile(TFilePath dst, const string &str)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void readCompressedFile(string &str, TFilePath src)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TFileStatus status(src);
Toshihiro Shimizu 890ddd
	if (!status.doesExist())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	size_t in_len = status.getSize();
Toshihiro Shimizu 890ddd
	char *in = (char *)malloc(in_len);
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		Tifstream is(src);
Toshihiro Shimizu 890ddd
		is.read((char *)in, in_len);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	LZ4F_decompressionContext_t lz4dctx;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	LZ4F_errorCode_t err = LZ4F_createDecompressionContext(&lz4dctx, LZ4F_VERSION);
Toshihiro Shimizu 890ddd
	if (LZ4F_isError(err))
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	size_t in_len_read = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	size_t out_len = 1000000, out_len_written, out_len_moved = 0;
Toshihiro Shimizu 890ddd
	void *out = (void *)malloc(out_len);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	while (in_len_read < in_len) {
Toshihiro Shimizu 890ddd
		out_len_written = out_len;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		size_t remaining = LZ4F_decompress(lz4dctx, out, &out_len_written, in, &in_len, NULL);
Toshihiro Shimizu 890ddd
		if (LZ4F_isError(remaining))
Toshihiro Shimizu 890ddd
			break;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		str.resize(out_len_moved + out_len_written);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		memcpy((void *)(str.c_str() + out_len_moved), (void *)out, out_len_written);
Toshihiro Shimizu 890ddd
		out_len_moved += out_len_written;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	LZ4F_freeDecompressionContext(lz4dctx);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	free(in);
Toshihiro Shimizu 890ddd
	free(out);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
// TODO: Unify with tcodec.cpp's version
Toshihiro Shimizu 890ddd
bool lz4decompress(LZ4F_decompressionContext_t lz4dctx,
Toshihiro Shimizu 890ddd
				   char *out, size_t *out_len_res,
Toshihiro Shimizu 890ddd
				   const char *in, size_t in_len)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	size_t out_len = *out_len_res,
Toshihiro Shimizu 890ddd
		   in_read, out_written;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	*out_len_res = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	while (in_len) {
Toshihiro Shimizu 890ddd
		out_written = out_len;
Toshihiro Shimizu 890ddd
		in_read = in_len;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		size_t res = LZ4F_decompress(
Toshihiro Shimizu 890ddd
			lz4dctx, (void *)out, &out_written, (const void *)in, &in_read, NULL);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (LZ4F_isError(res))
Toshihiro Shimizu 890ddd
			return false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		*out_len_res += out_written;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		out += out_written;
Toshihiro Shimizu 890ddd
		out_len -= out_written;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		in += in_read;
Toshihiro Shimizu 890ddd
		in_len -= in_read;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
} // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===============================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class StreamTag
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	string m_name;
Toshihiro Shimizu 890ddd
	std::map<string, string=""> m_attributes;</string,>
Toshihiro Shimizu 890ddd
	enum Type { BeginTag,
Toshihiro Shimizu 890ddd
				EndTag,
Toshihiro Shimizu 890ddd
				BeginEndTag };
Toshihiro Shimizu 890ddd
	Type m_type;
Toshihiro Shimizu 890ddd
	StreamTag() : m_type(BeginTag) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	operator bool() const { return m_name != ""; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void dump()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		cout << "name = '" << m_name << "'" << endl;
Toshihiro Shimizu 890ddd
		cout << "type = ";
Toshihiro Shimizu 890ddd
		switch (m_type) {
Toshihiro Shimizu 890ddd
		case BeginTag:
Toshihiro Shimizu 890ddd
			cout << "begin Tag";
Toshihiro Shimizu 890ddd
			break;
Toshihiro Shimizu 890ddd
		case EndTag:
Toshihiro Shimizu 890ddd
			cout << "end Tag";
Toshihiro Shimizu 890ddd
			break;
Toshihiro Shimizu 890ddd
		case BeginEndTag:
Toshihiro Shimizu 890ddd
			cout << "begin/end Tag";
Toshihiro Shimizu 890ddd
			break;
Toshihiro Shimizu 890ddd
		default:
Toshihiro Shimizu 890ddd
			cout << "**bad Tag**";
Toshihiro Shimizu 890ddd
			break;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		cout << endl;
Toshihiro Shimizu 890ddd
		std::map<string, string="">::iterator it;</string,>
Toshihiro Shimizu 890ddd
		for (it = m_attributes.begin(); it != m_attributes.end(); ++it) {
Toshihiro Shimizu 890ddd
			cout << " '" << it->first << "' = '" << it->second << "'" << endl;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class TPersistFactory
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	typedef std::map<string, *="" tpersistdeclaration=""> Table;</string,>
Toshihiro Shimizu 890ddd
	static TPersistFactory *m_factory;
Toshihiro Shimizu 890ddd
	Table m_table;
Toshihiro Shimizu 890ddd
	TPersistFactory() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	static TPersistFactory *instance()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (!m_factory)
Toshihiro Shimizu 890ddd
			m_factory = new TPersistFactory;
Toshihiro Shimizu 890ddd
		return m_factory;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	void add(string name, TPersistDeclaration *decl)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_table[name] = decl;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	TPersist *create(string name)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		Table::iterator it = m_table.find(name);
Toshihiro Shimizu 890ddd
		if (it != m_table.end())
Toshihiro Shimizu 890ddd
			return (it->second)->create();
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			return 0;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TPersistFactory *TPersistFactory::m_factory = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TPersistDeclaration::TPersistDeclaration(const string &id)
Toshihiro Shimizu 890ddd
	: m_id(id)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TPersistFactory::instance()->add(id, this);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===============================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TPersist *TPersist::create(const string &name)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return TPersistFactory::instance()->create(name);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===============================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class TOStream::Imp
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	ostream *m_os;
Toshihiro Shimizu 890ddd
	bool m_chanOwner;
Toshihiro Shimizu 890ddd
	bool m_compressed;
kogaki 5bbc3c
	ostrstream m_ostrstream;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	vector<string> m_tagStack;</string>
Toshihiro Shimizu 890ddd
	int m_tab;
Toshihiro Shimizu 890ddd
	bool m_justStarted;
Toshihiro Shimizu 890ddd
	typedef map<tpersist *,="" int=""> PersistTable;</tpersist>
Toshihiro Shimizu 890ddd
	PersistTable m_table;
Toshihiro Shimizu 890ddd
	int m_maxId;
Toshihiro Shimizu 890ddd
	TFilePath m_filepath;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Imp() : m_os(0), m_chanOwner(false), m_tab(0), m_justStarted(true), m_maxId(0), m_compressed(false) {}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TOStream::TOStream(const TFilePath &fp, bool compressed)
Toshihiro Shimizu 890ddd
	: m_imp(new Imp)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_imp->m_filepath = fp;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (compressed) {
kogaki 5bbc3c
		m_imp->m_os = &m_imp->m_ostrstream;
Toshihiro Shimizu 890ddd
		m_imp->m_compressed = true;
Toshihiro Shimizu 890ddd
		m_imp->m_chanOwner = false;
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		std::auto_ptr<tofstream> os(new Tofstream(fp));</tofstream>
Toshihiro Shimizu 890ddd
		m_imp->m_os = os->isOpen() ? os.release() : 0;
Toshihiro Shimizu 890ddd
		m_imp->m_chanOwner = true;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_imp->m_justStarted = true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 262a92
TOStream::TOStream(std::shared_ptr<imp> imp)</imp>
Shinya Kitaoka 262a92
	: m_imp(std::move(imp))
Toshihiro Shimizu 890ddd
{
shun_iwasawa fe7dd3
	assert(!m_imp->m_tagStack.empty());
Toshihiro Shimizu 890ddd
	ostream &os = *m_imp->m_os;
Shinya Kitaoka 5f2af0
	if (!m_imp->m_justStarted)
Toshihiro Shimizu 890ddd
		cr();
Toshihiro Shimizu 890ddd
	os << "<" << m_imp->m_tagStack.back() << ">";
Toshihiro Shimizu 890ddd
	m_imp->m_tab++;
Toshihiro Shimizu 890ddd
	cr();
Toshihiro Shimizu 890ddd
	m_imp->m_justStarted = true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 5f2af0
TOStream::TOStream(TOStream&& that)
Shinya Kitaoka 5f2af0
	: m_imp(std::move(that.m_imp))
Shinya Kitaoka 5f2af0
{
Shinya Kitaoka 5f2af0
}
Shinya Kitaoka 5f2af0
Shinya Kitaoka 5f2af0
TOStream& TOStream::operator = (TOStream && that)
Shinya Kitaoka 5f2af0
{
Shinya Kitaoka 5f2af0
	if (this != &that) {
Shinya Kitaoka 5f2af0
		this->m_imp = std::move(that.m_imp);
Shinya Kitaoka 5f2af0
	}
Shinya Kitaoka 5f2af0
	return *this;
Shinya Kitaoka 5f2af0
}
Shinya Kitaoka 5f2af0
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TOStream::~TOStream()
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 5f2af0
	if (!m_imp) {
Shinya Kitaoka 5f2af0
		return;
Shinya Kitaoka 5f2af0
	}
Toshihiro Shimizu 890ddd
	try {
Toshihiro Shimizu 890ddd
		if (!m_imp->m_tagStack.empty()) {
Toshihiro Shimizu 890ddd
			string tagName = m_imp->m_tagStack.back();
Toshihiro Shimizu 890ddd
			m_imp->m_tagStack.pop_back();
Toshihiro Shimizu 890ddd
			assert(tagName != "");
Toshihiro Shimizu 890ddd
			ostream &os = *m_imp->m_os;
Toshihiro Shimizu 890ddd
			m_imp->m_tab--;
Toshihiro Shimizu 890ddd
			if (!m_imp->m_justStarted)
Toshihiro Shimizu 890ddd
				cr();
Toshihiro Shimizu 890ddd
			os << "";
Toshihiro Shimizu 890ddd
			cr();
Toshihiro Shimizu 890ddd
			m_imp->m_justStarted = true;
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			if (m_imp->m_compressed) {
kogaki 5bbc3c
				const void *in = (const void *)m_imp->m_ostrstream.str();
Toshihiro Shimizu 890ddd
				size_t in_len = strlen((char *)in);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				size_t out_len = LZ4F_compressFrameBound(in_len, NULL);
Toshihiro Shimizu 890ddd
				void *out = malloc(out_len);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				out_len = LZ4F_compressFrame(out, out_len, in, in_len, NULL);
Toshihiro Shimizu 890ddd
				if (!LZ4F_isError(out_len)) {
Toshihiro Shimizu 890ddd
					Tofstream os(m_imp->m_filepath);
Toshihiro Shimizu 890ddd
					// TNZC <lunghezza dati="" decompress=""> <lunghezza compresso="" dati=""> <dati compressi=""></dati></lunghezza></lunghezza>
Toshihiro Shimizu 890ddd
					os.write("TABc", 4);
Toshihiro Shimizu 890ddd
					TINT32 v;
Toshihiro Shimizu 890ddd
					v = 0x0A0B0C0D;
Toshihiro Shimizu 890ddd
					os.write((char *)&v, sizeof v);
Toshihiro Shimizu 890ddd
					v = in_len;
Toshihiro Shimizu 890ddd
					os.write((char *)&v, sizeof v);
Toshihiro Shimizu 890ddd
					v = out_len;
Toshihiro Shimizu 890ddd
					os.write((char *)&v, sizeof v);
Toshihiro Shimizu 890ddd
					os.write((char *)out, out_len);
kogaki 5bbc3c
kogaki 5bbc3c
					m_imp->m_ostrstream.freeze(0);
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				free(out);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			if (m_imp->m_chanOwner)
Toshihiro Shimizu 890ddd
				delete m_imp->m_os;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	} catch (...) {
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TFilePath TOStream::getFilePath()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_imp->m_filepath;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TFilePath TOStream::getRepositoryPath()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TFilePath fp = m_imp->m_filepath;
Toshihiro Shimizu 890ddd
	return fp.getParentDir() + (fp.getName() + "_files");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TOStream &TOStream::operator<<(int v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	*(m_imp->m_os) << v << " ";
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
Toshihiro Shimizu 890ddd
TOStream &TOStream::operator<<(double v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (areAlmostEqual(v, 0)) //con valori molto piccoli (es. 1.4e-310) non riesce a rileggerli!
Toshihiro Shimizu 890ddd
		v = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	*(m_imp->m_os) << v << " ";
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
Toshihiro Shimizu 890ddd
TOStream &TOStream::operator<<(string v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	ostream &os = *(m_imp->m_os);
Toshihiro Shimizu 890ddd
	int len = v.length();
Toshihiro Shimizu 890ddd
	if (len == 0) {
Toshihiro Shimizu 890ddd
		os << "\"\""
Toshihiro Shimizu 890ddd
		   << " ";
Toshihiro Shimizu 890ddd
		m_imp->m_justStarted = false;
Toshihiro Shimizu 890ddd
		return *this;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	int i;
Toshihiro Shimizu 890ddd
	for (i = 0; i < len; i++)
Toshihiro Shimizu 890ddd
		if (!iswalnum(v[i]) && v[i] != '_' && v[i] != '%')
Toshihiro Shimizu 890ddd
			break;
Toshihiro Shimizu 890ddd
	if (i == len)
Toshihiro Shimizu 890ddd
		os << v << " ";
Toshihiro Shimizu 890ddd
	else {
Toshihiro Shimizu 890ddd
		os << '"' << escape(v) << '"';
Toshihiro Shimizu 890ddd
	}
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
Toshihiro Shimizu 890ddd
TOStream &TOStream::operator<<(QString _v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	string v = _v.toStdString();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	ostream &os = *(m_imp->m_os);
Toshihiro Shimizu 890ddd
	int len = v.length();
Toshihiro Shimizu 890ddd
	if (len == 0) {
Toshihiro Shimizu 890ddd
		os << "\"\""
Toshihiro Shimizu 890ddd
		   << " ";
Toshihiro Shimizu 890ddd
		m_imp->m_justStarted = false;
Toshihiro Shimizu 890ddd
		return *this;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	int i;
Toshihiro Shimizu 890ddd
	for (i = 0; i < len; i++)
Toshihiro Shimizu 890ddd
		if (!iswalnum(v[i]) && v[i] != '_' && v[i] != '%')
Toshihiro Shimizu 890ddd
			break;
Toshihiro Shimizu 890ddd
	if (i == len)
Toshihiro Shimizu 890ddd
		os << v << " ";
Toshihiro Shimizu 890ddd
	else {
Toshihiro Shimizu 890ddd
		os << '"' << escape(v) << '"';
Toshihiro Shimizu 890ddd
	}
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
Toshihiro Shimizu 890ddd
TOStream &TOStream::operator<<(wstring v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return operator<<(toString(v));
Toshihiro Shimizu 890ddd
	/*
Toshihiro Shimizu 890ddd
  ostream &os = *(m_imp->m_os);
Toshihiro Shimizu 890ddd
  int len = v.length();
Toshihiro Shimizu 890ddd
  if(len==0)
Toshihiro Shimizu 890ddd
  {
Toshihiro Shimizu 890ddd
    os << "\"" << "\"" << " "; 
Toshihiro Shimizu 890ddd
    m_imp->m_justStarted = false;
Toshihiro Shimizu 890ddd
    return *this;
Toshihiro Shimizu 890ddd
  }
Toshihiro Shimizu 890ddd
  int i;
Toshihiro Shimizu 890ddd
  for(i=0;i
Toshihiro Shimizu 890ddd
    if(!iswalnum(v[i]) && v[i]!=L'_')
Toshihiro Shimizu 890ddd
      break;
Toshihiro Shimizu 890ddd
  if(i==len)
Toshihiro Shimizu 890ddd
    {
Toshihiro Shimizu 890ddd
     os << v;
Toshihiro Shimizu 890ddd
     os << " ";
Toshihiro Shimizu 890ddd
    }
Toshihiro Shimizu 890ddd
  else
Toshihiro Shimizu 890ddd
    {
Toshihiro Shimizu 890ddd
     os.put('"');
Toshihiro Shimizu 890ddd
     for(i=0;i
Toshihiro Shimizu 890ddd
       if(iswalnum(v[i]))
Toshihiro Shimizu 890ddd
         os.put((char)v[i]);
Toshihiro Shimizu 890ddd
       else if(v[i]=='"')
Toshihiro Shimizu 890ddd
         os << "\\\"";
Toshihiro Shimizu 890ddd
       else if(v[i]=='\n')
Toshihiro Shimizu 890ddd
         os << "\\n";
Toshihiro Shimizu 890ddd
       else if(iswprint(v[i]))
Toshihiro Shimizu 890ddd
         os << v[i];
Toshihiro Shimizu 890ddd
       else 
Toshihiro Shimizu 890ddd
         {os.put('\\'); os << (int)v[i];}
Toshihiro Shimizu 890ddd
     os << "\" ";
Toshihiro Shimizu 890ddd
    }
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
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TOStream &TOStream::operator<<(const TFilePath &v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return operator<<(v.getWideString());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TOStream &TOStream::operator<<(const TPixel32 &v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	ostream &os = *(m_imp->m_os);
Toshihiro Shimizu 890ddd
	os << (int)v.r << " " << (int)v.g << " " << (int)v.b << " " << (int)v.m << " ";
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
Toshihiro Shimizu 890ddd
TOStream &TOStream::operator<<(const TPixel64 &v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	ostream &os = *(m_imp->m_os);
Toshihiro Shimizu 890ddd
	os << (int)v.r << " " << (int)v.g << " " << (int)v.b << " " << (int)v.m << " ";
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
Toshihiro Shimizu 890ddd
void TOStream::cr()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	*(m_imp->m_os) << endl;
Toshihiro Shimizu 890ddd
	for (int i = 0; i < m_imp->m_tab; i++)
Toshihiro Shimizu 890ddd
		*(m_imp->m_os) << "  ";
Toshihiro Shimizu 890ddd
	m_imp->m_justStarted = false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TOStream::operator bool() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return (m_imp->m_os && *m_imp->m_os);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
TOStream TOStream::child(string tagName)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assert(tagName != "");
Toshihiro Shimizu 890ddd
	m_imp->m_tagStack.push_back(tagName);
Shinya Kitaoka 5f2af0
	return TOStream(m_imp);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TOStream::openChild(string tagName)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assert(tagName != "");
Toshihiro Shimizu 890ddd
	m_imp->m_tagStack.push_back(tagName);
Toshihiro Shimizu 890ddd
	if (m_imp->m_justStarted == false)
Toshihiro Shimizu 890ddd
		cr();
Toshihiro Shimizu 890ddd
	*(m_imp->m_os) << "<" << m_imp->m_tagStack.back() << ">";
Toshihiro Shimizu 890ddd
	m_imp->m_tab++;
Toshihiro Shimizu 890ddd
	cr();
Toshihiro Shimizu 890ddd
	m_imp->m_justStarted = true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TOStream::openChild(string tagName, const map<string, string=""> &attributes)</string,>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assert(tagName != "");
Toshihiro Shimizu 890ddd
	m_imp->m_tagStack.push_back(tagName);
Toshihiro Shimizu 890ddd
	if (m_imp->m_justStarted == false)
Toshihiro Shimizu 890ddd
		cr();
Toshihiro Shimizu 890ddd
	*(m_imp->m_os) << "<" << m_imp->m_tagStack.back();
Toshihiro Shimizu 890ddd
	for (std::map<string, string="">::const_iterator it = attributes.begin();</string,>
Toshihiro Shimizu 890ddd
		 it != attributes.end(); ++it) {
Toshihiro Shimizu 890ddd
		*(m_imp->m_os) << " " << it->first
Toshihiro Shimizu 890ddd
					   << "=\"" << escape(it->second) << "\"";
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	*(m_imp->m_os) << ">";
Toshihiro Shimizu 890ddd
	m_imp->m_tab++;
Toshihiro Shimizu 890ddd
	cr();
Toshihiro Shimizu 890ddd
	m_imp->m_justStarted = true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TOStream::closeChild()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assert(!m_imp->m_tagStack.empty());
Toshihiro Shimizu 890ddd
	string tagName = m_imp->m_tagStack.back();
Toshihiro Shimizu 890ddd
	m_imp->m_tagStack.pop_back();
Toshihiro Shimizu 890ddd
	assert(tagName != "");
Toshihiro Shimizu 890ddd
	//ostream &os = *m_imp->m_os; //os non e' usato
Toshihiro Shimizu 890ddd
	m_imp->m_tab--;
Toshihiro Shimizu 890ddd
	if (!m_imp->m_justStarted)
Toshihiro Shimizu 890ddd
		cr();
Toshihiro Shimizu 890ddd
	*(m_imp->m_os) << "";
Toshihiro Shimizu 890ddd
	cr();
Toshihiro Shimizu 890ddd
	m_imp->m_justStarted = true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TOStream::openCloseChild(string tagName, const map<string, string=""> &attributes)</string,>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assert(tagName != "");
Toshihiro Shimizu 890ddd
	// m_imp->m_tagStack.push_back(tagName);
Toshihiro Shimizu 890ddd
	if (m_imp->m_justStarted == false)
Toshihiro Shimizu 890ddd
		cr();
Toshihiro Shimizu 890ddd
	*(m_imp->m_os) << "<" << tagName;
Toshihiro Shimizu 890ddd
	for (std::map<string, string="">::const_iterator it = attributes.begin();</string,>
Toshihiro Shimizu 890ddd
		 it != attributes.end(); ++it) {
Toshihiro Shimizu 890ddd
		*(m_imp->m_os) << " " << it->first
Toshihiro Shimizu 890ddd
					   << "=\"" << escape(it->second) << "\"";
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	*(m_imp->m_os) << "/>";
Toshihiro Shimizu 890ddd
	//m_imp->m_tab++;
Toshihiro Shimizu 890ddd
	cr();
Toshihiro Shimizu 890ddd
	m_imp->m_justStarted = true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TOStream &TOStream::operator<<(TPersist &v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	v.saveData(*this);
Toshihiro Shimizu 890ddd
	return *this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TOStream &TOStream::operator<<(TPersist *v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	Imp::PersistTable::iterator it = m_imp->m_table.find(v);
Toshihiro Shimizu 890ddd
	if (it != m_imp->m_table.end()) {
Toshihiro Shimizu 890ddd
		*(m_imp->m_os) << "<" << v->getStreamTag() << " id='" << it->second << "'/>";
Toshihiro Shimizu 890ddd
		m_imp->m_justStarted = false;
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		int id = ++m_imp->m_maxId;
Toshihiro Shimizu 890ddd
		m_imp->m_table[v] = id;
Toshihiro Shimizu 890ddd
		*(m_imp->m_os) << "<" << v->getStreamTag() << " id='" << id << "'>";
Toshihiro Shimizu 890ddd
		m_imp->m_tab++;
Toshihiro Shimizu 890ddd
		cr();
Toshihiro Shimizu 890ddd
		v->saveData(*this);
Toshihiro Shimizu 890ddd
		m_imp->m_tab--;
Toshihiro Shimizu 890ddd
		cr();
Toshihiro Shimizu 890ddd
		*(m_imp->m_os) << "getStreamTag() << ">";
Toshihiro Shimizu 890ddd
		cr();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return *this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TOStream::checkStatus() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_imp->m_os)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_imp->m_os->flush();
Toshihiro Shimizu 890ddd
	return m_imp->m_os->rdstate() == ios_base::goodbit;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===============================================================
Toshihiro Shimizu 890ddd
/*! 
Toshihiro Shimizu 890ddd
	This class contains TIStream's attributes.
Toshihiro Shimizu 890ddd
	It is created by memory allocation in the TIStream's constructor.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
class TIStream::Imp
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	istream *m_is;
Toshihiro Shimizu 890ddd
	bool m_chanOwner;
Toshihiro Shimizu 890ddd
	int m_line;
Toshihiro Shimizu 890ddd
	string m_strbuffer;
Toshihiro Shimizu 890ddd
	bool m_compressed;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	vector<string> m_tagStack;</string>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	typedef map<int, *="" tpersist=""> PersistTable;</int,>
Toshihiro Shimizu 890ddd
	PersistTable m_table;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	StreamTag m_currentTag;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TFilePath m_filepath;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	VersionNumber m_versionNumber;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Imp() : m_is(0), m_chanOwner(false), m_line(0), m_compressed(false), m_versionNumber(0, 0) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// update m_line if necessary; returns -e if eof
Toshihiro Shimizu 890ddd
	int getNextChar();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	inline void skipBlanks();
Toshihiro Shimizu 890ddd
	bool matchTag();
Toshihiro Shimizu 890ddd
	inline bool match(char c);
Toshihiro Shimizu 890ddd
	bool matchIdent(string &ident);
Toshihiro Shimizu 890ddd
	bool matchValue(string &value);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void skipCurrentTag();
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TFilePath TIStream::getFilePath()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_imp->m_filepath;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TFilePath TIStream::getRepositoryPath()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TFilePath fp = m_imp->m_filepath;
Toshihiro Shimizu 890ddd
	return fp.getParentDir() + (fp.getName() + "_files");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int TIStream::Imp::getNextChar()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	char c;
Toshihiro Shimizu 890ddd
	m_is->get(c);
Toshihiro Shimizu 890ddd
	if (m_is->eof())
Toshihiro Shimizu 890ddd
		return -1;
Toshihiro Shimizu 890ddd
	if (c == '\r')
Toshihiro Shimizu 890ddd
		m_line++;
Toshihiro Shimizu 890ddd
	return c;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TIStream::Imp::skipBlanks()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	istream &is = *m_is;
Toshihiro Shimizu 890ddd
	istream::int_type c;
Toshihiro Shimizu 890ddd
	while (c = is.peek(), (isspace(c) || c == '\r'))
Toshihiro Shimizu 890ddd
		getNextChar();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TIStream::Imp::match(char c)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_is->peek() == c) {
Toshihiro Shimizu 890ddd
		getNextChar();
Toshihiro Shimizu 890ddd
		return true;
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TIStream::Imp::matchIdent(string &ident)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	istream &is = *m_is;
Toshihiro Shimizu 890ddd
	if (!isalnum(is.peek()))
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	ident = "";
Toshihiro Shimizu 890ddd
	char c;
Toshihiro Shimizu 890ddd
	is.get(c);
Toshihiro Shimizu 890ddd
	ident.append(1, c);
Toshihiro Shimizu 890ddd
	while (c = is.peek(), isalnum(c) || c == '_' || c == '.' || c == '-') {
Toshihiro Shimizu 890ddd
		is.get(c);
Toshihiro Shimizu 890ddd
		ident.append(1, c);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TIStream::Imp::matchValue(string &str)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	istream &is = *m_is;
Toshihiro Shimizu 890ddd
	char quote = is.peek();
Toshihiro Shimizu 890ddd
	char c;
Toshihiro Shimizu 890ddd
	if (!is || (quote != '\'' && quote != '\"'))
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	is.get(c);
Toshihiro Shimizu 890ddd
	str = "";
Toshihiro Shimizu 890ddd
	for (;;) {
Toshihiro Shimizu 890ddd
		is.get(c);
Toshihiro Shimizu 890ddd
		if (!is)
Toshihiro Shimizu 890ddd
			throw TException("expected '\"'");
Toshihiro Shimizu 890ddd
		if (c == quote)
Toshihiro Shimizu 890ddd
			break;
Toshihiro Shimizu 890ddd
		if (c == '\\') {
Toshihiro Shimizu 890ddd
			is.get(c);
Toshihiro Shimizu 890ddd
			if (!is)
Toshihiro Shimizu 890ddd
				throw TException("unexpected EOF");
Toshihiro Shimizu 890ddd
			if (c != '\'' && c != '\"' && c != '\\')
Toshihiro Shimizu 890ddd
				throw TException("bad escape sequence");
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		str.append(1, c);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (c != quote)
Toshihiro Shimizu 890ddd
		throw TException("missing '\"'");
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TIStream::Imp::matchTag()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_currentTag)
Toshihiro Shimizu 890ddd
		return true;
Toshihiro Shimizu 890ddd
	StreamTag &tag = m_currentTag;
Toshihiro Shimizu 890ddd
	tag = StreamTag();
Toshihiro Shimizu 890ddd
	skipBlanks();
Toshihiro Shimizu 890ddd
	if (!match('<'))
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	skipBlanks();
Toshihiro Shimizu 890ddd
	if (match('!')) {
Toshihiro Shimizu 890ddd
		skipBlanks();
Toshihiro Shimizu 890ddd
		if (!match('-') || !match('-'))
Toshihiro Shimizu 890ddd
			throw TException("expected '
Toshihiro Shimizu 890ddd
		istream &is = *m_is;
Toshihiro Shimizu 890ddd
		char c;
Toshihiro Shimizu 890ddd
		int status = 1;
Toshihiro Shimizu 890ddd
		while (status != 0 && is.get(c))
Toshihiro Shimizu 890ddd
			switch (status) {
Toshihiro Shimizu 890ddd
			case 1:
Toshihiro Shimizu 890ddd
				if (c == '-')
Toshihiro Shimizu 890ddd
					status = 2;
Toshihiro Shimizu 890ddd
				break;
Toshihiro Shimizu 890ddd
			case 2:
Toshihiro Shimizu 890ddd
				if (c == '-')
Toshihiro Shimizu 890ddd
					status = 3;
Toshihiro Shimizu 890ddd
				else
Toshihiro Shimizu 890ddd
					status = 1;
Toshihiro Shimizu 890ddd
				break;
Toshihiro Shimizu 890ddd
			case 3:
Toshihiro Shimizu 890ddd
				if (c == '>')
Toshihiro Shimizu 890ddd
					status = 0;
Toshihiro Shimizu 890ddd
				else if (c == '-') {
Toshihiro Shimizu 890ddd
				} else
Toshihiro Shimizu 890ddd
					status = 1;
Toshihiro Shimizu 890ddd
				break;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		return matchTag();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (match('/')) {
Toshihiro Shimizu 890ddd
		tag.m_type = StreamTag::EndTag;
Toshihiro Shimizu 890ddd
		skipBlanks();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!matchIdent(tag.m_name))
Toshihiro Shimizu 890ddd
		throw TException("expected identifier");
Toshihiro Shimizu 890ddd
	skipBlanks();
Toshihiro Shimizu 890ddd
	for (;;) {
Toshihiro Shimizu 890ddd
		if (match('>'))
Toshihiro Shimizu 890ddd
			break;
Toshihiro Shimizu 890ddd
		if (match('/')) {
Toshihiro Shimizu 890ddd
			tag.m_type = StreamTag::BeginEndTag;
Toshihiro Shimizu 890ddd
			skipBlanks();
Toshihiro Shimizu 890ddd
			if (match('>'))
Toshihiro Shimizu 890ddd
				break;
Toshihiro Shimizu 890ddd
			throw TException("expected '>'");
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		string name;
Toshihiro Shimizu 890ddd
		if (!matchIdent(name))
Toshihiro Shimizu 890ddd
			throw TException("expected identifier");
Toshihiro Shimizu 890ddd
		skipBlanks();
Toshihiro Shimizu 890ddd
		if (match('=')) {
Toshihiro Shimizu 890ddd
			string value;
Toshihiro Shimizu 890ddd
			skipBlanks();
Toshihiro Shimizu 890ddd
			if (!matchValue(value))
Toshihiro Shimizu 890ddd
				throw TException("expected value");
Toshihiro Shimizu 890ddd
			tag.m_attributes[name] = value;
Toshihiro Shimizu 890ddd
			skipBlanks();
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TIStream::Imp::skipCurrentTag()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_currentTag.m_type == StreamTag::BeginEndTag)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	istream &is = *m_is;
Toshihiro Shimizu 890ddd
	int level = 1;
Toshihiro Shimizu 890ddd
	int c;
Toshihiro Shimizu 890ddd
	for (;;) {
Toshihiro Shimizu 890ddd
		if (is.eof())
Toshihiro Shimizu 890ddd
			break; //unexpected eof
Toshihiro Shimizu 890ddd
		c = is.peek();
Toshihiro Shimizu 890ddd
		if (c != '<') {
Toshihiro Shimizu 890ddd
			getNextChar();
Toshihiro Shimizu 890ddd
			continue;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		// tag found
Toshihiro Shimizu 890ddd
		c = getNextChar();
Toshihiro Shimizu 890ddd
		if (c < 0)
Toshihiro Shimizu 890ddd
			break;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		c = getNextChar();
Toshihiro Shimizu 890ddd
		if (c < 0)
Toshihiro Shimizu 890ddd
			break;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (c == '/') {
Toshihiro Shimizu 890ddd
			// end tag
Toshihiro Shimizu 890ddd
			do
Toshihiro Shimizu 890ddd
				c = getNextChar();
Toshihiro Shimizu 890ddd
			while (c >= 0 && c != '>');
Toshihiro Shimizu 890ddd
			if (c < 0)
Toshihiro Shimizu 890ddd
				break; //unexpected eof
Toshihiro Shimizu 890ddd
			if (--level <= 0) {
Toshihiro Shimizu 890ddd
				// m_currentTag.m_type = StreamTag::EndTag;
Toshihiro Shimizu 890ddd
				m_tagStack.pop_back();
Toshihiro Shimizu 890ddd
				m_currentTag = StreamTag();
Toshihiro Shimizu 890ddd
				break;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			// tag
Toshihiro Shimizu 890ddd
			int oldC;
Toshihiro Shimizu 890ddd
			do {
Toshihiro Shimizu 890ddd
				oldC = c;
Toshihiro Shimizu 890ddd
				c = getNextChar();
Toshihiro Shimizu 890ddd
			} while (c >= 0 && c != '>');
Toshihiro Shimizu 890ddd
			if (c < 0)
Toshihiro Shimizu 890ddd
				break; //unexpected eof
Toshihiro Shimizu 890ddd
			if (oldC != '/')
Toshihiro Shimizu 890ddd
				level++;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TIStream::TIStream(const TFilePath &fp)
Toshihiro Shimizu 890ddd
	: m_imp(new Imp)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_imp->m_filepath = fp;
Toshihiro Shimizu 890ddd
	m_imp->m_is = new Tifstream(fp);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_imp->m_is->peek() == 'T') // non comincia con '<' dev'essere compresso
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		bool swapForEndianess = false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		auto_ptr<std::istream> is(m_imp->m_is);</std::istream>
Toshihiro Shimizu 890ddd
		m_imp->m_is = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		char magicBuffer[4];
Toshihiro Shimizu 890ddd
		is->read(magicBuffer, 4);
Toshihiro Shimizu 890ddd
		string magic(magicBuffer, 4);
Toshihiro Shimizu 890ddd
		size_t in_len, out_len;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (magic == "TNZC") {
Toshihiro Shimizu 890ddd
			// Tab3.0 beta
Toshihiro Shimizu 890ddd
			is->read((char *)&out_len, sizeof out_len);
Toshihiro Shimizu 890ddd
			is->read((char *)&in_len, sizeof in_len);
Toshihiro Shimizu 890ddd
		} else if (magic == "TABc") {
Toshihiro Shimizu 890ddd
			TINT32 v;
Toshihiro Shimizu 890ddd
			is->read((char *)&v, sizeof v);
Toshihiro Shimizu 890ddd
			printf("magic = %08X\n", v);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (v == 0x0A0B0C0D)
Toshihiro Shimizu 890ddd
				swapForEndianess = false;
Toshihiro Shimizu 890ddd
			else if (v == 0x0D0C0B0A)
Toshihiro Shimizu 890ddd
				swapForEndianess = true;
Toshihiro Shimizu 890ddd
			else {
Toshihiro Shimizu 890ddd
				swapForEndianess = true;
Toshihiro Shimizu 890ddd
				printf("UH OH!\n");
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			is->read((char *)&v, sizeof v);
Toshihiro Shimizu 890ddd
			out_len = swapForEndianess ? swapTINT32(v) : v;
Toshihiro Shimizu 890ddd
			is->read((char *)&v, sizeof v);
Toshihiro Shimizu 890ddd
			in_len = swapForEndianess ? swapTINT32(v) : v;
Toshihiro Shimizu 890ddd
		} else
Toshihiro Shimizu 890ddd
			throw TException("Bad magic number");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (in_len <= 0 || in_len > 100000000) // 100M di tnzfile (compresso) sembrano proprio esagerati
Toshihiro Shimizu 890ddd
			throw TException("Corrupted file");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		LZ4F_decompressionContext_t lz4dctx;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		LZ4F_errorCode_t err = LZ4F_createDecompressionContext(&lz4dctx, LZ4F_VERSION);
Toshihiro Shimizu 890ddd
		if (LZ4F_isError(err))
Toshihiro Shimizu 890ddd
			throw TException("Couldn't decompress file");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		char *in = (char *)malloc(in_len);
Toshihiro Shimizu 890ddd
		is->read((char *)in, in_len);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_imp->m_strbuffer.resize(out_len + 1000); // per prudenza
Toshihiro Shimizu 890ddd
		char *out = (char *)m_imp->m_strbuffer.c_str();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		size_t check_len = out_len;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//size_t remaining = LZ4F_decompress(lz4dctx, out, &out_len, in, &in_len, NULL);
Toshihiro Shimizu 890ddd
		bool ok = lz4decompress(lz4dctx, out, &out_len, in, in_len);
Toshihiro Shimizu 890ddd
		LZ4F_freeDecompressionContext(lz4dctx);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		free(in);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (!ok)
Toshihiro Shimizu 890ddd
			throw TException("Couldn't decompress file");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (check_len != out_len)
Toshihiro Shimizu 890ddd
			throw TException("corrupted file");
Toshihiro Shimizu 890ddd
kogaki 5bbc3c
		m_imp->m_is = new istrstream((char *)out, out_len);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	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
Toshihiro Shimizu 890ddd
TIStream::~TIStream()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_imp->m_chanOwner)
Toshihiro Shimizu 890ddd
		delete m_imp->m_is;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TIStream &TIStream::operator>>(int &v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	*(m_imp->m_is) >> v;
Toshihiro Shimizu 890ddd
	return *this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TIStream &TIStream::operator>>(double &v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	*(m_imp->m_is) >> v;
Toshihiro Shimizu 890ddd
	return *this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TIStream &TIStream::operator>>(wstring &v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	string s;
Toshihiro Shimizu 890ddd
	operator>>(s);
Toshihiro Shimizu 890ddd
	v = toWideString(s);
Toshihiro Shimizu 890ddd
	return *this;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*
Toshihiro Shimizu 890ddd
  int len = s.length();
Toshihiro Shimizu 890ddd
  for(int i=0;i
Toshihiro Shimizu 890ddd
    {
Toshihiro Shimizu 890ddd
     if(s[i] != '&')
Toshihiro Shimizu 890ddd
       {v.append(1, (wchar_t)s[i]);i++;}
Toshihiro Shimizu 890ddd
     else if(s.substr(i, 5) == "&")
Toshihiro Shimizu 890ddd
       {v.append(1, L'&');i+=5;}
Toshihiro Shimizu 890ddd
     else if(i+1
Toshihiro Shimizu 890ddd
       {
Toshihiro Shimizu 890ddd
        int c = 0;
Toshihiro Shimizu 890ddd
        i+=2;
Toshihiro Shimizu 890ddd
        while(i
Toshihiro Shimizu 890ddd
          {
Toshihiro Shimizu 890ddd
           c = c*10+s[i]-'0';
Toshihiro Shimizu 890ddd
           i++;
Toshihiro Shimizu 890ddd
          }
Toshihiro Shimizu 890ddd
        if(i
Toshihiro Shimizu 890ddd
        v.append(1, (wchar_t)c);
Toshihiro Shimizu 890ddd
       }
Toshihiro Shimizu 890ddd
     else
Toshihiro Shimizu 890ddd
       {
Toshihiro Shimizu 890ddd
        i++;
Toshihiro Shimizu 890ddd
       }
Toshihiro Shimizu 890ddd
    }
Toshihiro Shimizu 890ddd
  return *this;
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TIStream &TIStream::operator>>(string &v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	istream &is = *(m_imp->m_is);
Toshihiro Shimizu 890ddd
	v = "";
Toshihiro Shimizu 890ddd
	m_imp->skipBlanks();
Toshihiro Shimizu 890ddd
	char c;
Toshihiro Shimizu 890ddd
	is.get(c);
Toshihiro Shimizu 890ddd
	if (c == '\"') {
Toshihiro Shimizu 890ddd
		is.get(c);
Toshihiro Shimizu 890ddd
		while (is && c != '"') {
Toshihiro Shimizu 890ddd
			if (c == '\\') {
Toshihiro Shimizu 890ddd
				is.get(c);
Toshihiro Shimizu 890ddd
				if (!is)
Toshihiro Shimizu 890ddd
					throw TException("unexpected EOF");
Toshihiro Shimizu 890ddd
				if (c == '"')
Toshihiro Shimizu 890ddd
					v.append(1, '"');
Toshihiro Shimizu 890ddd
				else if (c == '\\')
Toshihiro Shimizu 890ddd
					v.append(1, '\\');
Toshihiro Shimizu 890ddd
				else if (c == '\'')
Toshihiro Shimizu 890ddd
					v.append(1, '\'');
Toshihiro Shimizu 890ddd
				else {
Toshihiro Shimizu 890ddd
					v.append(1, '\\');
Toshihiro Shimizu 890ddd
					v.append(1, c);
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			} else
Toshihiro Shimizu 890ddd
				v.append(1, c);
Toshihiro Shimizu 890ddd
			is.get(c);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		v.append(1, c);
Toshihiro Shimizu 890ddd
		while (c = is.peek(), isalnum(c) || c == '_' || c == '&' || c == '#' || c == ';' || c == '%') {
Toshihiro Shimizu 890ddd
			is.get(c);
Toshihiro Shimizu 890ddd
			v.append(1, c);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return *this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TIStream &TIStream::operator>>(QString &v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	istream &is = *(m_imp->m_is);
Toshihiro Shimizu 890ddd
	v = "";
Toshihiro Shimizu 890ddd
	m_imp->skipBlanks();
Toshihiro Shimizu 890ddd
	char c;
Toshihiro Shimizu 890ddd
	is.get(c);
Toshihiro Shimizu 890ddd
	if (c == '\"') {
Toshihiro Shimizu 890ddd
		is.get(c);
Toshihiro Shimizu 890ddd
		while (is && c != '"') {
Toshihiro Shimizu 890ddd
			if (c == '\\') {
Toshihiro Shimizu 890ddd
				is.get(c);
Toshihiro Shimizu 890ddd
				if (!is)
Toshihiro Shimizu 890ddd
					throw TException("unexpected EOF");
Toshihiro Shimizu 890ddd
				if (c == '"')
Toshihiro Shimizu 890ddd
					v.append('"');
Toshihiro Shimizu 890ddd
				else if (c == '\\')
Toshihiro Shimizu 890ddd
					v.append('\\');
Toshihiro Shimizu 890ddd
				else if (c == '\'')
Toshihiro Shimizu 890ddd
					v.append('\'');
Toshihiro Shimizu 890ddd
				else {
Toshihiro Shimizu 890ddd
					v.append('\\');
Toshihiro Shimizu 890ddd
					v.append(c);
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			} else
Toshihiro Shimizu 890ddd
				v.append(c);
Toshihiro Shimizu 890ddd
			is.get(c);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		v.append(c);
Toshihiro Shimizu 890ddd
		while (c = is.peek(), isalnum(c) || c == '_' || c == '&' || c == '#' || c == ';' || c == '%') {
Toshihiro Shimizu 890ddd
			is.get(c);
Toshihiro Shimizu 890ddd
			v.append(c);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return *this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
string TIStream::getString()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	istream &is = *(m_imp->m_is);
Toshihiro Shimizu 890ddd
	string v = "";
Toshihiro Shimizu 890ddd
	m_imp->skipBlanks();
Toshihiro Shimizu 890ddd
	char c = is.peek();
Toshihiro Shimizu 890ddd
	while (c != '<') {
Toshihiro Shimizu 890ddd
		is.get(c);
Toshihiro Shimizu 890ddd
		c = is.peek();
Toshihiro Shimizu 890ddd
		if (!is)
Toshihiro Shimizu 890ddd
			throw TException("unexpected EOF");
Toshihiro Shimizu 890ddd
		v.append(1, c);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return v;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TIStream &TIStream::operator>>(TPixel32 &v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	istream &is = *(m_imp->m_is);
Toshihiro Shimizu 890ddd
	int r, g, b, m;
Toshihiro Shimizu 890ddd
	is >> r;
Toshihiro Shimizu 890ddd
	is >> g;
Toshihiro Shimizu 890ddd
	is >> b;
Toshihiro Shimizu 890ddd
	is >> m;
Toshihiro Shimizu 890ddd
	v.r = r;
Toshihiro Shimizu 890ddd
	v.g = g;
Toshihiro Shimizu 890ddd
	v.b = b;
Toshihiro Shimizu 890ddd
	v.m = m;
Toshihiro Shimizu 890ddd
	return *this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TIStream &TIStream::operator>>(TPixel64 &v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	istream &is = *(m_imp->m_is);
Toshihiro Shimizu 890ddd
	int r, g, b, m;
Toshihiro Shimizu 890ddd
	is >> r;
Toshihiro Shimizu 890ddd
	is >> g;
Toshihiro Shimizu 890ddd
	is >> b;
Toshihiro Shimizu 890ddd
	is >> m;
Toshihiro Shimizu 890ddd
	v.r = r;
Toshihiro Shimizu 890ddd
	v.g = g;
Toshihiro Shimizu 890ddd
	v.b = b;
Toshihiro Shimizu 890ddd
	v.m = m;
Toshihiro Shimizu 890ddd
	return *this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TIStream &TIStream::operator>>(TFilePath &v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	istream &is = *(m_imp->m_is);
Toshihiro Shimizu 890ddd
	string s;
Toshihiro Shimizu 890ddd
	char c;
Toshihiro Shimizu 890ddd
	m_imp->skipBlanks();
Toshihiro Shimizu 890ddd
	is.get(c);
Toshihiro Shimizu 890ddd
	if (c == '"') {
Toshihiro Shimizu 890ddd
		is.get(c);
Toshihiro Shimizu 890ddd
		while (is && c != '"') {
Toshihiro Shimizu 890ddd
			//if(c=='\\')
Toshihiro Shimizu 890ddd
			//   is.get(c);
Toshihiro Shimizu 890ddd
			s.append(1, c);
Toshihiro Shimizu 890ddd
			is.get(c);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		// il filepath non e' fra virgolette:
Toshihiro Shimizu 890ddd
		// puo' contenere solo caratteri alfanumerici, % e _
Toshihiro Shimizu 890ddd
		s.append(1, c);
Toshihiro Shimizu 890ddd
		while (is) {
Toshihiro Shimizu 890ddd
			c = is.peek();
Toshihiro Shimizu 890ddd
			if (!isalnum(c) && c != '%' && c != '_')
Toshihiro Shimizu 890ddd
				break;
Toshihiro Shimizu 890ddd
			is.get(c);
Toshihiro Shimizu 890ddd
			s.append(1, c);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	v = TFilePath(s);
Toshihiro Shimizu 890ddd
	return *this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TIStream &TIStream::operator>>(TPersist &v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	v.loadData(*this);
Toshihiro Shimizu 890ddd
	return *this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TIStream &TIStream::operator>>(TPersist *&v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_imp->matchTag() ||
Toshihiro Shimizu 890ddd
		m_imp->m_currentTag.m_type == StreamTag::EndTag) {
Toshihiro Shimizu 890ddd
		throw TException("expected begin tag");
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	StreamTag tag = m_imp->m_currentTag;
Toshihiro Shimizu 890ddd
	m_imp->m_currentTag = StreamTag();
Toshihiro Shimizu 890ddd
	string tagName = tag.m_name;
Toshihiro Shimizu 890ddd
	std::map<string, string="">::iterator it;</string,>
Toshihiro Shimizu 890ddd
	int id = -1;
Toshihiro Shimizu 890ddd
	it = tag.m_attributes.find("id");
Toshihiro Shimizu 890ddd
	if (it != tag.m_attributes.end())
Toshihiro Shimizu 890ddd
		id = atoi(it->second.c_str());
Toshihiro Shimizu 890ddd
	//cout << "tagname = " << tagName << " id = " << id << endl;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Imp::PersistTable::iterator pit = m_imp->m_table.find(id);
Toshihiro Shimizu 890ddd
	if (pit == m_imp->m_table.end()) {
Toshihiro Shimizu 890ddd
		v = TPersistFactory::instance()->create(tagName);
Toshihiro Shimizu 890ddd
		if (!v)
Toshihiro Shimizu 890ddd
			throw TException("unable to create a persistent '" + tagName + "'");
Toshihiro Shimizu 890ddd
		m_imp->m_table[id] = v;
Toshihiro Shimizu 890ddd
		if (tag.m_type != StreamTag::BeginTag)
Toshihiro Shimizu 890ddd
			throw TException("expected begin tag");
Toshihiro Shimizu 890ddd
		m_imp->m_tagStack.push_back(tag.m_name);
Toshihiro Shimizu 890ddd
		v->loadData(*this);
Toshihiro Shimizu 890ddd
		m_imp->matchTag();
Toshihiro Shimizu 890ddd
		if (!m_imp->m_currentTag ||
Toshihiro Shimizu 890ddd
			m_imp->m_currentTag.m_type != StreamTag::EndTag)
Toshihiro Shimizu 890ddd
			throw TException("expected end tag");
Toshihiro Shimizu 890ddd
		if (m_imp->m_currentTag.m_name != m_imp->m_tagStack.back())
Toshihiro Shimizu 890ddd
			throw TException("end tag mismatch");
Toshihiro Shimizu 890ddd
		m_imp->m_tagStack.pop_back();
Toshihiro Shimizu 890ddd
		m_imp->m_currentTag = StreamTag();
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		v = pit->second;
Toshihiro Shimizu 890ddd
		if (tag.m_type != StreamTag::BeginEndTag)
Toshihiro Shimizu 890ddd
			throw TException("expected begin/end tag");
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return *this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TIStream::matchEndTag()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_imp->m_tagStack.empty())
Toshihiro Shimizu 890ddd
		throw TException("tag stack emtpy");
Toshihiro Shimizu 890ddd
	if (!m_imp->matchTag())
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	if (m_imp->m_currentTag.m_type != StreamTag::EndTag)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	if (m_imp->m_currentTag.m_name != m_imp->m_tagStack.back())
Toshihiro Shimizu 890ddd
		throw TException("end tag mismatch");
Toshihiro Shimizu 890ddd
	m_imp->m_tagStack.pop_back();
Toshihiro Shimizu 890ddd
	m_imp->m_currentTag = StreamTag();
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TIStream::eos()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_imp->matchTag())
Toshihiro Shimizu 890ddd
		return m_imp->m_currentTag.m_type == StreamTag::EndTag;
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		return !(*m_imp->m_is);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TIStream::matchTag(string &tagName)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_imp->matchTag())
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	if (m_imp->m_currentTag.m_type == StreamTag::EndTag)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	tagName = m_imp->m_currentTag.m_name;
Toshihiro Shimizu 890ddd
	m_imp->m_currentTag.m_name = "";
Toshihiro Shimizu 890ddd
	if (m_imp->m_currentTag.m_type != StreamTag::BeginEndTag)
Toshihiro Shimizu 890ddd
		m_imp->m_tagStack.push_back(tagName);
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
string TIStream::getTagAttribute(string name) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	StreamTag &tag = m_imp->m_currentTag;
Toshihiro Shimizu 890ddd
	std::map<string, string="">::const_iterator it = tag.m_attributes.find(name);</string,>
Toshihiro Shimizu 890ddd
	if (it == tag.m_attributes.end())
Toshihiro Shimizu 890ddd
		return "";
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		return it->second;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TIStream::getTagParam(string paramName, string &value)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_imp->m_tagStack.empty())
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	StreamTag &tag = m_imp->m_currentTag;
Toshihiro Shimizu 890ddd
	std::map<string, string="">::const_iterator it = tag.m_attributes.find(paramName);</string,>
Toshihiro Shimizu 890ddd
	if (it == tag.m_attributes.end())
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	value = it->second;
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TIStream::getTagParam(string paramName, int &value)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	string svalue;
Toshihiro Shimizu 890ddd
	if (!getTagParam(paramName, svalue))
Toshihiro Shimizu 890ddd
		return false;
kogaki 5bbc3c
	istrstream is(svalue.c_str(), svalue.length());
Toshihiro Shimizu 890ddd
	value = 0;
Toshihiro Shimizu 890ddd
	is >> value;
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TIStream::isBeginEndTag()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_imp->m_currentTag.m_type == StreamTag::BeginEndTag;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TIStream::openChild(string &tagName)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_imp->matchTag())
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	if (m_imp->m_currentTag.m_type != StreamTag::BeginTag)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	tagName = m_imp->m_currentTag.m_name;
Toshihiro Shimizu 890ddd
	m_imp->m_currentTag.m_name = "";
Toshihiro Shimizu 890ddd
	m_imp->m_tagStack.push_back(tagName);
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TIStream::closeChild()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!matchEndTag()) {
Toshihiro Shimizu 890ddd
		string tagName;
Toshihiro Shimizu 890ddd
		if (!m_imp->m_tagStack.empty())
Toshihiro Shimizu 890ddd
			tagName = m_imp->m_tagStack.back();
Toshihiro Shimizu 890ddd
		if (tagName != "")
Toshihiro Shimizu 890ddd
			throw TException("Expected \"" + tagName + "\" end tag");
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			throw TException("expected EndTag");
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TIStream::match(char c) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_imp->skipBlanks();
Toshihiro Shimizu 890ddd
	if (m_imp->m_is->peek() != c)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	m_imp->m_is->get(c);
Toshihiro Shimizu 890ddd
	if (c == '\r')
Toshihiro Shimizu 890ddd
		m_imp->m_line++;
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TIStream::operator bool() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return (m_imp->m_is && *m_imp->m_is);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int TIStream::getLine() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_imp->m_line + 1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
VersionNumber TIStream::getVersion() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_imp->m_versionNumber;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TIStream::setVersion(const VersionNumber &version)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_imp->m_versionNumber = version;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TIStream::skipCurrentTag()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_imp->skipCurrentTag();
Toshihiro Shimizu 890ddd
}