aboutsummaryrefslogtreecommitdiff
path: root/dep/src/g3dlite/Any.cpp
diff options
context:
space:
mode:
authorXanadu <none@none>2010-07-20 02:49:28 +0200
committerXanadu <none@none>2010-07-20 02:49:28 +0200
commit79622802f397258ee0f34327ba3ae6977ca3e7ff (patch)
tree1868946c234ab9ee256a6b7766a15713eae94235 /dep/src/g3dlite/Any.cpp
parent7dd2dc91816ab8b3bc3b99a1b1c99c7ea314d5a8 (diff)
parentf906976837502fa5aa81b982b901d1509f5aa0c4 (diff)
Merge. Revision history for source files should be all back now.
--HG-- branch : trunk rename : sql/CMakeLists.txt => sql/tools/CMakeLists.txt rename : src/server/game/Pools/PoolHandler.cpp => src/server/game/Pools/PoolMgr.cpp rename : src/server/game/Pools/PoolHandler.h => src/server/game/Pools/PoolMgr.h rename : src/server/game/PrecompiledHeaders/NixCorePCH.cpp => src/server/game/PrecompiledHeaders/gamePCH.cpp rename : src/server/game/PrecompiledHeaders/NixCorePCH.h => src/server/game/PrecompiledHeaders/gamePCH.h
Diffstat (limited to 'dep/src/g3dlite/Any.cpp')
-rw-r--r--dep/src/g3dlite/Any.cpp1237
1 files changed, 0 insertions, 1237 deletions
diff --git a/dep/src/g3dlite/Any.cpp b/dep/src/g3dlite/Any.cpp
deleted file mode 100644
index de4d32e83ea..00000000000
--- a/dep/src/g3dlite/Any.cpp
+++ /dev/null
@@ -1,1237 +0,0 @@
-/**
- @file Any.cpp
-
- @author Morgan McGuire
- @author Shawn Yarbrough
-
- @created 2006-06-11
- @edited 2009-11-15
-
- Copyright 2000-2009, Morgan McGuire.
- All rights reserved.
- */
-
-#include "G3D/Any.h"
-#include "G3D/TextOutput.h"
-#include "G3D/TextInput.h"
-#include "G3D/stringutils.h"
-#include <deque>
-#include <iostream>
-
-namespace G3D {
-
-void Any::beforeRead() const {
- if (isPlaceholder()) {
- // Tried to read from a placeholder--throw an exception as if
- // the original operator[] had failed.
- KeyNotFound e;
- alwaysAssertM(m_data, "Corrupt placeholder");
-
- e.filename = m_data->source.filename;
- e.line = m_data->source.line;
- e.character = m_data->source.character;
- e.key = m_placeholderName;
- e.message =
- "This exception may have been thrown later than "
- "the actual operator[] invocation.";
-
- throw e;
- }
-}
-
-
-Any::Data* Any::Data::create(const Data* d) {
- Data* p = create(d->type);
-
- p->comment = d->comment;
- p->name = d->name;
-
- switch (d->type) {
- case NONE:
- case BOOLEAN:
- case NUMBER:
- // No clone needed
- break;
-
- case STRING:
- *(p->value.s) = *(d->value.s);
- break;
-
- case ARRAY:
- *(p->value.a) = *(d->value.a);
- break;
-
- case TABLE:
- *(p->value.t) = *(d->value.t);
- // Note that placeholders may be copied; that is ok--they are still
- // just placeholders.
- break;
- }
-
- return p;
-}
-
-
-Any::Data* Any::Data::create(Any::Type t) {
- size_t s = sizeof(Data);
-
- switch (t) {
- case NONE:
- case BOOLEAN:
- case NUMBER:
- // No extra space needed
- break;
-
- case STRING:
- s += sizeof(std::string);
- break;
-
- case ARRAY:
- s += sizeof(AnyArray);
- break;
-
- case TABLE:
- s += sizeof(AnyTable);
- break;
- }
-
- // Allocate the data object
- Data* p = new (MemoryManager::create()->alloc(s)) Data(t);
-
- // Create the (empyt) value object at the end of the Data object
- switch (t) {
- case NONE:
- case BOOLEAN:
- case NUMBER:
- // No value
- break;
-
- case STRING:
- p->value.s = new (p + 1) std::string();
- break;
-
- case ARRAY:
- p->value.a = new (p + 1) AnyArray();
- break;
-
- case TABLE:
- p->value.t = new (p + 1) AnyTable();
- break;
- }
-
- return p;
-}
-
-
-void Any::Data::destroy(Data* d) {
- if (d != NULL) {
- d->~Data();
- MemoryManager::create()->free(d);
- }
-}
-
-
-Any::Data::~Data() {
- debugAssertM(referenceCount.value() <= 0, "Deleted while still referenced.");
-
- // Destruct but do not deallocate children
- switch (type) {
- case STRING:
- debugAssert(value.s != NULL);
- value.s->~basic_string();
- break;
-
- case ARRAY:
- debugAssert(value.a != NULL);
- value.a->~Array();
- break;
-
- case TABLE:
- debugAssert(value.t != NULL);
- value.t->~Table();
- break;
-
- default:
- // All other types should have a NULL value pointer (i.e., they were used just for name and comment fields)
- debugAssertM(value.s == NULL, "Corrupt Any::Data::Value");
- }
-
- value.s = NULL;
-}
-
-
-//////////////////////////////////////////////////////////////
-
-bool Any::containsKey(const std::string& x) const {
- beforeRead();
- verifyType(TABLE);
-
- Any* a = m_data->value.t->getPointer(x);
-
- // Don't return true for placeholder objects
- return (a != NULL) && (! a->isPlaceholder());
-}
-
-
-void Any::dropReference() {
- if (m_data && m_data->referenceCount.decrement() <= 0) {
- // This was the last reference to the shared data
- Data::destroy(m_data);
- }
- m_data = NULL;
-}
-
-
-void Any::ensureMutable() {
- if (m_data && (m_data->referenceCount.value() >= 1)) {
- // Copy the data. We must do this before dropping the reference
- // to avoid a race condition
- Data* d = Data::create(m_data);
- dropReference();
- m_data = d;
- }
-}
-
-
-Any::Any() : m_type(NONE), m_data(NULL) {
-}
-
-
-Any::Any(TextInput& t) : m_type(NONE), m_data(NULL) {
- deserialize(t);
-}
-
-
-Any::Any(const Any& x) : m_type(NONE), m_data(NULL) {
- x.beforeRead();
- *this = x;
-}
-
-
-Any::Any(double x) : m_type(NUMBER), m_simpleValue(x), m_data(NULL) {
-}
-
-
-#ifdef G3D_32BIT
-Any::Any(int64 x) : m_type(NUMBER), m_simpleValue((double)x), m_data(NULL) {
-}
-#endif // G3D_32BIT
-
-
-Any::Any(long x) : m_type(NUMBER), m_simpleValue((double)x), m_data(NULL) {
-}
-
-
-Any::Any(int x) : m_type(NUMBER), m_simpleValue((double)x), m_data(NULL) {
-}
-
-
-Any::Any(short x) : m_type(NUMBER), m_simpleValue((double)x), m_data(NULL) {
-}
-
-
-Any::Any(bool x) : m_type(BOOLEAN), m_simpleValue(x), m_data(NULL) {
-}
-
-
-Any::Any(const std::string& s) : m_type(STRING), m_data(Data::create(STRING)) {
- *(m_data->value.s) = s;
-}
-
-
-Any::Any(const char* s) : m_type(STRING), m_data(NULL) {
- if (s == NULL) {
- m_type = NONE;
- } else {
- ensureData();
- *(m_data->value.s) = s;
- }
-}
-
-
-Any::Any(Type t, const std::string& name) : m_type(t), m_data(NULL) {
- alwaysAssertM(t == ARRAY || t == TABLE, "Can only create ARRAY or TABLE from Type enum.");
-
- ensureData();
- if (name != "") {
- m_data->name = name;
- }
-}
-
-
-Any::~Any() {
- dropReference();
-}
-
-
-void Any::beforeWrite() {
- if (isPlaceholder()) {
- // This is no longer a placeholder
- m_placeholderName = "";
- }
-}
-
-Any& Any::operator=(const Any& x) {
- x.beforeRead();
-
- if (this == &x) {
- return *this;
- }
-
- beforeWrite();
-
- dropReference();
-
- m_type = x.m_type;
- m_simpleValue = x.m_simpleValue;
-
- if (x.m_data != NULL) {
- x.m_data->referenceCount.increment();
- m_data = x.m_data;
- }
-
- return *this;
-}
-
-
-Any& Any::operator=(double x) {
- *this = Any(x);
- return *this;
-}
-
-
-Any& Any::operator=(int x) {
- return (*this = Any(x));
-}
-
-
-Any& Any::operator=(bool x) {
- *this = Any(x);
- return *this;
-}
-
-
-Any& Any::operator=(const std::string& x) {
- *this = Any(x);
- return *this;
-}
-
-
-Any& Any::operator=(const char* x) {
- *this = Any(x);
- return *this;
-}
-
-
-Any& Any::operator=(Type t) {
- switch (t) {
- case NONE:
- *this = Any();
- break;
-
- case TABLE:
- case ARRAY:
- *this = Any(t);
- break;
-
- default:
- alwaysAssertM(false, "Can only assign NONE, TABLE, or ARRAY Type enum.");
- }
-
- return *this;
-}
-
-
-Any::Type Any::type() const {
- beforeRead();
- return m_type;
-}
-
-
-const std::string& Any::comment() const {
- beforeRead();
-
- static const std::string blank;
- if (m_data != NULL) {
- return m_data->comment;
- } else {
- return blank;
- }
-}
-
-
-void Any::setComment(const std::string& c) {
- beforeRead();
- ensureData();
- m_data->comment = c;
-}
-
-
-bool Any::isNone() const {
- beforeRead();
- return (m_type == NONE);
-}
-
-
-double Any::number() const {
- beforeRead();
- verifyType(NUMBER);
- return m_simpleValue.n;
-}
-
-
-const std::string& Any::string() const {
- beforeRead();
- verifyType(STRING);
- return *(m_data->value.s);
-}
-
-
-bool Any::boolean() const {
- beforeRead();
- verifyType(BOOLEAN);
- return m_simpleValue.b;
-}
-
-
-const std::string& Any::name() const {
- beforeRead();
- static const std::string blank;
- if (m_data != NULL) {
- return m_data->name;
- } else {
- return blank;
- }
-}
-
-
-void Any::setName(const std::string& n) {
- beforeRead();
- ensureData();
- m_data->name = n;
-}
-
-
-int Any::size() const {
- beforeRead();
- verifyType(ARRAY, TABLE);
- switch (m_type) {
- case TABLE:
- return m_data->value.t->size();
-
- case ARRAY:
- return m_data->value.a->size();
-
- default:;
- return 0;
- } // switch (m_type)
-}
-
-
-int Any::length() const {
- beforeRead();
- return size();
-}
-
-
-void Any::resize(int n) {
- beforeRead();
- alwaysAssertM(n >= 0, "Cannot resize less than 0.");
- verifyType(ARRAY);
- m_data->value.a->resize(n);
-}
-
-
-void Any::clear() {
- beforeRead();
- verifyType(ARRAY, TABLE);
- switch (m_type) {
- case ARRAY:
- m_data->value.a->clear();
- break;
-
- case TABLE:
- m_data->value.t->clear();
- break;
-
- default:;
- }
-}
-
-
-const Any& Any::operator[](int i) const {
- beforeRead();
- verifyType(ARRAY);
- debugAssert(m_data != NULL);
- Array<Any>& array = *(m_data->value.a);
- return array[i];
-}
-
-
-Any& Any::next() {
- beforeRead();
- verifyType(ARRAY);
- int n = size();
- resize(n + 1);
- return (*this)[n];
-}
-
-
-Any& Any::operator[](int i) {
- beforeRead();
- verifyType(ARRAY);
- debugAssert(m_data != NULL);
- Array<Any>& array = *(m_data->value.a);
- return array[i];
-}
-
-
-const Array<Any>& Any::array() const {
- beforeRead();
- verifyType(ARRAY);
- debugAssert(m_data != NULL);
- return *(m_data->value.a);
-}
-
-
-void Any::append(const Any& x0) {
- beforeRead();
- verifyType(ARRAY);
- debugAssert(m_data != NULL);
- m_data->value.a->append(x0);
-}
-
-
-void Any::append(const Any& x0, const Any& x1) {
- beforeRead();
- append(x0);
- append(x1);
-}
-
-
-void Any::append(const Any& x0, const Any& x1, const Any& x2) {
- beforeRead();
- append(x0);
- append(x1);
- append(x2);
-}
-
-
-void Any::append(const Any& x0, const Any& x1, const Any& x2, const Any& x3) {
- beforeRead();
- append(x0);
- append(x1);
- append(x2);
- append(x3);
-}
-
-
-const Table<std::string, Any>& Any::table() const {
- beforeRead();
- verifyType(TABLE);
- debugAssert(m_data != NULL);
- return *(m_data->value.t);
-}
-
-
-const Any& Any::operator[](const std::string& x) const {
- beforeRead();
- verifyType(TABLE);
- debugAssert(m_data != NULL);
- const Table<std::string, Any>& table = *(m_data->value.t);
- Any* value = table.getPointer(x);
- if (value == NULL) {
- KeyNotFound e;
- if (m_data) {
- e.filename = m_data->source.filename;
- e.line = m_data->source.line;
- e.character = m_data->source.character;
- }
- e.key = x;
- throw e;
- }
- return *value;
-}
-
-
-Any& Any::operator[](const std::string& key) {
- beforeRead();
- verifyType(TABLE);
-
- bool created = false;
- Any& value = m_data->value.t->getCreate(key, created);
-
- if (created) {
- // The entry was created by this method; do not allow it to be
- // read before it is written.
- value.m_placeholderName = key;
-
- // Write source data for the value
- value.ensureData();
- value.m_data->source = source();
- }
-
- return value;
-}
-
-
-void Any::set(const std::string& k, const Any& v) {
- beforeRead();
- v.beforeRead();
- verifyType(TABLE);
- debugAssert(m_data != NULL);
- Table<std::string, Any>& table = *(m_data->value.t);
- table.set(k, v);
-}
-
-
-const Any& Any::get(const std::string& x, const Any& defaultVal) const {
- beforeRead();
- defaultVal.beforeRead();
- try {
- return operator[](x);
- } catch(KeyNotFound) {
- return defaultVal;
- }
-}
-
-
-bool Any::operator==(const Any& x) const {
- beforeRead();
- x.beforeRead();
- if (m_type != x.m_type) {
- return false;
- }
-
- switch (m_type) {
- case NONE:
- return true;
-
- case BOOLEAN:
- return (m_simpleValue.b == x.m_simpleValue.b);
-
- case NUMBER:
- return (m_simpleValue.n == x.m_simpleValue.n);
-
- case STRING:
- debugAssert(m_data != NULL);
- return (*(m_data->value.s) == *(x.m_data->value.s));
-
- case TABLE: {
- if (size() != x.size()) {
- return false;
- }
- debugAssert(m_data != NULL);
- if (m_data->name != x.m_data->name) {
- return false;
- }
- Table<std::string, Any>& cmptable = *( m_data->value.t);
- Table<std::string, Any>& xcmptable = *(x.m_data->value.t);
- for (Table<std::string,Any>::Iterator it1 = cmptable.begin(), it2 = xcmptable.begin();
- it1 != cmptable.end() && it2 != xcmptable.end();
- ++it1, ++it2) {
- if (*it1 != *it2) {
- return false;
- }
- }
- return true;
- }
-
- case ARRAY: {
- if (size() != x.size()) {
- return false;
- }
- debugAssert(m_data != NULL);
- if (m_data->name != x.m_data->name) {
- return false;
- }
-
- Array<Any>& cmparray = *( m_data->value.a);
- Array<Any>& xcmparray = *(x.m_data->value.a);
-
- for (int ii = 0; ii < size(); ++ii) {
- if (cmparray[ii] != xcmparray[ii]) {
- return false;
- }
- }
- return true;
- }
-
- default:
- alwaysAssertM(false, "Unknown type.");
- return false;
- } // switch (m_type)
-
-}
-
-
-bool Any::operator!=(const Any& x) const {
- beforeRead();
- x.beforeRead();
- return !operator==(x);
-}
-
-
-static void getDeserializeSettings(TextInput::Settings& settings) {
- settings.cppBlockComments = true;
- settings.cppLineComments = true;
- settings.otherLineComments = true;
- settings.otherCommentCharacter = '#';
- settings.generateCommentTokens = true;
- settings.singleQuotedStrings = false;
- settings.msvcSpecials = false;
- settings.caseSensitive = false;
-}
-
-
-std::string Any::unparse() const {
- beforeRead();
- TextOutput::Settings settings;
- TextOutput to(settings);
- serialize(to);
- return to.commitString();
-}
-
-
-void Any::parse(const std::string& src) {
- beforeRead();
- TextInput::Settings settings;
- getDeserializeSettings(settings);
-
- TextInput ti(TextInput::FROM_STRING, src, settings);
- deserialize(ti);
-}
-
-
-void Any::load(const std::string& filename) {
- beforeRead();
- TextInput::Settings settings;
- getDeserializeSettings(settings);
-
- TextInput ti(filename, settings);
- deserialize(ti);
-}
-
-
-void Any::save(const std::string& filename) const {
- beforeRead();
- TextOutput::Settings settings;
- settings.wordWrap = TextOutput::Settings::WRAP_NONE;
-
- TextOutput to(filename,settings);
- serialize(to);
- to.commit();
-}
-
-
-static bool needsQuotes(const std::string& s) {
- if (! isLetter(s[0]) && (s[0] != '_')) {
- return true;
- }
-
- for (int i = 0; i < (int)s.length(); ++i) {
- char c = s[i];
-
- // peek character
- char p = (i == (int)s.length() - 1) ? '_' : s[i + 1];
-
- // Identify separators
- if ((c == '-' && p == '>') ||
- (c == ':' && p == ':')) {
- // Skip over this symbol
- ++i;
- continue;
- }
-
- if (! isDigit(c) && ! isLetter(c) & (c != '.')) {
- // This is an illegal character for an identifier, so we need quotes
- return true;
- }
- }
-
- return false;
-}
-
-
-// TODO: if the output will fit on one line, compress tables and arrays into a single line
-void Any::serialize(TextOutput& to) const {
- beforeRead();
- if (m_data && ! m_data->comment.empty()) {
- to.printf("\n/* %s */\n", m_data->comment.c_str());
- }
-
- switch (m_type) {
- case NONE:
- to.writeSymbol("NONE");
- break;
-
- case BOOLEAN:
- to.writeBoolean(m_simpleValue.b);
- break;
-
- case NUMBER:
- to.writeNumber(m_simpleValue.n);
- break;
-
- case STRING:
- debugAssert(m_data != NULL);
- to.writeString(*(m_data->value.s));
- break;
-
- case TABLE: {
- debugAssert(m_data != NULL);
- if (! m_data->name.empty()) {
- if (needsQuotes(m_data->name)) {
- to.writeString(m_data->name);
- } else {
- to.writeSymbol(m_data->name);
- }
- }
- to.writeSymbol("{");
- to.writeNewline();
- to.pushIndent();
- AnyTable& table = *(m_data->value.t);
- Array<std::string> keys;
- table.getKeys(keys);
- keys.sort();
-
- for (int i = 0; i < keys.size(); ++i) {
-
- to.writeSymbol(keys[i]);
- to.writeSymbol("=");
- table[keys[i]].serialize(to);
-
- if (i < keys.size() - 1) {
- to.writeSymbol(",");
- }
- to.writeNewline();
-
- // Skip a line between table entries
- to.writeNewline();
- }
-
- to.popIndent();
- to.writeSymbol("}");
- break;
- }
-
- case ARRAY: {
- debugAssert(m_data != NULL);
- if (! m_data->name.empty()) {
- // For arrays, leave no trailing space between the name and the paren
- to.writeSymbol(format("%s(", m_data->name.c_str()));
- } else {
- to.writeSymbol("(");
- }
- to.writeNewline();
- to.pushIndent();
- Array<Any>& array = *(m_data->value.a);
- for (int ii = 0; ii < size(); ++ii) {
- array[ii].serialize(to);
- if (ii < size() - 1) {
- to.writeSymbol(",");
- to.writeNewline();
- }
-
- // Put the close paren on an array right behind the last element
- }
- to.popIndent();
- to.writeSymbol(")");
- break;
- }
- }
-}
-
-
-void Any::deserializeComment(TextInput& ti, Token& token, std::string& comment) {
- // Parse comments
- while (token.type() == Token::COMMENT) {
- comment += trimWhitespace(token.string()) + "\n";
-
- // Allow comments to contain newlines.
- do {
- token = ti.read();
- comment += "\n";
- } while (token.type() == Token::NEWLINE);
- }
-
- comment = trimWhitespace(comment);
-}
-
-/** True if \a c is an open paren of some form */
-static bool isOpen(const char c) {
- return c == '(' || c == '[' || c == '{';
-}
-
-
-/** True if \a c is an open paren of some form */
-static bool isClose(const char c) {
- return c == ')' || c == ']' || c == '}';
-}
-
-
-/** True if \a s is a C++ name operator */
-static bool isNameOperator(const std::string& s) {
- return s == "." || s == "::" || s == "->";
-}
-
-
-void Any::deserializeName(TextInput& ti, Token& token, std::string& name) {
- debugAssert(token.type() == Token::SYMBOL);
- std::string s = token.string();
- while (! isOpen(s[0])) {
- name += s;
-
- // Skip newlines and comments
- token = ti.readSignificant();
-
- if (token.type() != Token::SYMBOL) {
- throw ParseError(ti.filename(), token.line(), token.character(),
- "Expected symbol while parsing Any");
- }
- s = token.string();
- }
-}
-
-
-void Any::deserialize(TextInput& ti) {
- beforeRead();
- Token token = ti.read();
- deserialize(ti, token);
- // Restore the last token
- ti.push(token);
-}
-
-
-void Any::deserialize(TextInput& ti, Token& token) {
- // Deallocate old data
- dropReference();
- m_type = NONE;
- m_simpleValue.b = false;
-
- // Skip leading newlines
- while (token.type() == Token::NEWLINE) {
- token = ti.read();
- }
-
- std::string comment;
- if (token.type() == Token::COMMENT) {
- deserializeComment(ti, token, comment);
- }
-
- if (token.type() == Token::END) {
- // There should never be a comment without an Any following it; even
- // if the file ends with some commented out stuff,
- // that should not happen after a comma, so we'd never read that
- // far in a proper file.
- throw ParseError(ti.filename(), token.line(), token.character(),
- "File ended without a properly formed Any");
- }
-
- switch (token.type()) {
- case Token::STRING:
- m_type = STRING;
- ensureData();
- *(m_data->value.s) = token.string();
- m_data->source.set(ti, token);
- break;
-
- case Token::NUMBER:
- m_type = NUMBER;
- m_simpleValue.n = token.number();
- ensureData();
- m_data->source.set(ti, token);
- break;
-
- case Token::BOOLEAN:
- m_type = BOOLEAN;
- m_simpleValue.b = token.boolean();
- ensureData();
- m_data->source.set(ti, token);
- break;
-
- case Token::SYMBOL:
- // Named Array, Named Table, Array, Table, or NONE
- if (toUpper(token.string()) == "NONE") {
- // Nothing left to do; we initialized to NONE originally
- ensureData();
- m_data->source.set(ti, token);
- } else {
- // Array or Table
-
- // Parse the name
-
- // s must have at least one element or this would not have
- // been parsed as a symbol
- std::string name;
- deserializeName(ti, token, name);
- if (token.type() != Token::SYMBOL) {
- throw ParseError(ti.filename(), token.line(), token.character(),
- "Malformed Any TABLE or ARRAY; must start with [, (, or {");
- }
-
- if (isOpen(token.string()[0])) {
- // Array or table
- deserializeBody(ti, token);
- } else {
- throw ParseError(ti.filename(), token.line(), token.character(),
- "Malformed Any TABLE or ARRAY; must start with [, (, or {");
- }
-
- if (! name.empty()) {
- ensureData();
- m_data->name = name;
- }
- } // if NONE
- break;
-
- default:
- throw ParseError(ti.filename(), token.line(), token.character(),
- "Unexpected token");
-
- } // switch
-
- if (! comment.empty()) {
- ensureData();
- m_data->comment = comment;
- }
-
- if (m_type != ARRAY && m_type != TABLE) {
- // Array and table already consumed their last token
- token = ti.read();
- }
-}
-
-
-void Any::ensureData() {
- if (m_data == NULL) {
- m_data = Data::create(m_type);
- }
-}
-
-
-static bool isSeparator(char c) {
- return c == ',' || c == ';';
-}
-
-
-void Any::readUntilCommaOrClose(TextInput& ti, Token& token) {
- while (! ((token.type() == Token::SYMBOL) &&
- (isClose(token.string()[0])) ||
- isSeparator(token.string()[0]))) {
- switch (token.type()) {
- case Token::NEWLINE:
- case Token::COMMENT:
- // Consume
- token = ti.read();
- break;
-
- default:
- throw ParseError(ti.filename(), token.line(), token.character(),
- "Expected a comma or close paren");
- }
- }
-}
-
-
-void Any::deserializeBody(TextInput& ti, Token& token) {
- char closeSymbol = '}';
- m_type = TABLE;
-
- const char c = token.string()[0];
-
- if (c != '{') {
- m_type = ARRAY;
- // Chose the appropriate close symbol
- closeSymbol = (c == '(') ? ')' : ']';
- }
-
- // Allocate the underlying data structure
- ensureData();
- m_data->source.set(ti, token);
-
- // Consume the open token
- token = ti.read();
-
- while (! ((token.type() == Token::SYMBOL) && (token.string()[0] == closeSymbol))) {
-
- // Read any leading comment. This must be done here (and not in the recursive deserialize
- // call) in case the body contains only a comment.
- std::string comment;
- deserializeComment(ti, token, comment);
-
- if ((token.type() == Token::SYMBOL) && (token.string()[0] == closeSymbol)) {
- // We're done; this catches the case where the array is empty
- break;
- }
-
- // Pointer the value being read
- Any a = NULL;
- std::string key;
-
- if (m_type == TABLE) {
- // Read the key
- if (token.type() != Token::SYMBOL && token.type() != Token::STRING) {
- throw ParseError(ti.filename(), token.line(), token.character(), "Expected a name");
- }
-
- key = token.string();
- // Consume everything up to the = sign
- token = ti.readSignificant();
-
- if ((token.type() != Token::SYMBOL) || (token.string() != "=")) {
- throw ParseError(ti.filename(), token.line(), token.character(), "Expected =");
- } else {
- // Consume (don't consume comments--we want the value pointed to by a to get those).
- token = ti.read();
- }
- }
- a.deserialize(ti, token);
-
- if (! comment.empty()) {
- // Prepend the comment we read earlier
- a.ensureData();
- a.m_data->comment = trimWhitespace(comment + "\n" + a.m_data->comment);
- }
-
- if (m_type == TABLE) {
- set(key, a);
- } else {
- append(a);
- }
-
- // Read until the comma or close paren, discarding trailing comments and newlines
- readUntilCommaOrClose(ti, token);
-
- // Consume the comma
- if (isSeparator(token.string()[0])) {
- token = ti.read();
- }
- }
-
- // Consume the close paren (to match other deserialize methods)
- token = ti.read();
-}
-
-
-Any::operator int() const {
- beforeRead();
- return iRound(number());
-}
-
-
-Any::operator float() const {
- beforeRead();
- return float(number());
-}
-
-
-Any::operator double() const {
- beforeRead();
- return number();
-}
-
-
-Any::operator bool() const {
- beforeRead();
- return boolean();
-}
-
-
-Any::operator std::string() const {
- beforeRead();
- return string();
-}
-
-
-const Any::Source& Any::source() const {
- static Source s;
- if (m_data) {
- return m_data->source;
- } else {
- return s;
- }
-}
-
-
-void Any::verify(bool value, const std::string& message) const {
- beforeRead();
- if (! value) {
- ParseError p;
- if (m_data) {
- p.filename = m_data->source.filename;
- p.line = m_data->source.line;
- p.character = m_data->source.character;
- }
-
- if (name().empty()) {
- p.message = "Parse error";
- } else {
- p.message = "Parse error while reading the contents of " + name();
- }
-
- if (! message.empty()) {
- p.message = p.message + ": " + message;
- }
-
- throw p;
- }
-}
-
-
-void Any::verifyName(const std::string& n) const {
- beforeRead();
- verify(beginsWith(toUpper(name()), toUpper(n)), "Name must begin with " + n);
-}
-
-
-void Any::verifyType(Type t) const {
- beforeRead();
- if (type() != t) {
- verify(false, "Must have type " + toString(t));
- }
-}
-
-
-void Any::verifyType(Type t0, Type t1) const {
- beforeRead();
- if (type() != t0 && type() != t1) {
- verify(false, "Must have type " + toString(t0) + " or " + toString(t1));
- }
-}
-
-
-void Any::verifySize(int low, int high) const {
- beforeRead();
- verifyType(ARRAY, TABLE);
- if (size() < low || size() > high) {
- verify(false, format("Size must be between %d and %d", low, high));
- }
-}
-
-
-void Any::verifySize(int s) const {
- beforeRead();
- verifyType(ARRAY, TABLE);
- if (size() != s) {
- verify(false, format("Size must be %d", s));
- }
-}
-
-
-std::string Any::toString(Type t) {
- switch(t) {
- case NONE: return "NONE";
- case BOOLEAN: return "BOOLEAN";
- case NUMBER: return "NUMBER";
- case STRING: return "STRING";
- case ARRAY: return "ARRAY";
- case TABLE: return "TABLE";
- default:
- alwaysAssertM(false, "Illegal Any::Type");
- return "";
- }
-}
-
-} // namespace G3D
-