TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
G3D::Any Class Reference

Easy loading and saving of human-readable configuration files. More...

#include <Any.h>

Classes

class  Data
 
class  IndexOutOfBounds
 
class  KeyNotFound
 
union  SimpleValue
 
class  Source
 

Public Types

enum  Type {
  NIL, BOOLEAN, NUMBER, STRING,
  ARRAY, TABLE, EMPTY_CONTAINER
}
 
typedef Array< AnyAnyArray
 
typedef Table< std::string, AnyAnyTable
 

Public Member Functions

 Any ()
 
 Any (TextInput &t)
 
 Any (const Any &x)
 
 Any (double x)
 
 Any (float x)
 
 Any (long x)
 
 Any (int x)
 
 Any (char x)
 
 Any (short x)
 
 Any (bool x)
 
 Any (const std::string &x)
 
 Any (const char *x)
 
 Any (Type t, const std::string &name="", const std::string &brackets="", const char separator= '\0')
 
template<class T >
 Any (const T &v)
 
 ~Any ()
 
Anyoperator= (const Any &x)
 
Anyoperator= (Type t)
 
template<class T >
Anyoperator= (const Array< T > &array)
 
template<class T >
Anyoperator= (const T &v)
 
Type type () const
 
std::string unparse (const TextOutput::Settings &s=TextOutput::Settings()) const
 
std::string unparseJSON (const TextOutput::Settings &s=TextOutput::Settings(), bool allowCoercion=true) const
 
const std::string & comment () const
 
void setComment (const std::string &c)
 
bool isNil () const
 
double number () const
 
float floatValue () const
 
const std::string & string () const
 
bool boolean () const
 
std::string resolveStringAsFilename (bool errorIfNotFound=true) const
 
const std::string & name () const
 
bool nameBeginsWith (const std::string &s) const
 
bool nameBeginsWith (const char *s) const
 
bool nameEquals (const std::string &s) const
 
bool nameEquals (const char *s) const
 
void setName (const std::string &name)
 Set the name used when serializing an ARRAY or TABLE. More...
 
int size () const
 
int length () const
 
const Anyoperator[] (int i) const
 
Anyoperator[] (int i)
 
const Anylast () const
 
Anylast ()
 
const Array< Any > & array () const
 
template<class T0 >
void append (const T0 &v0)
 
template<class T0 , class T1 >
void append (const T0 &v0, const T1 &v1)
 
template<class T0 , class T1 , class T2 >
void append (const T0 &v0, const T1 &v1, const T2 &v2)
 
template<class T0 , class T1 , class T2 , class T3 >
void append (const T0 &v0, const T1 &v1, const T2 &v2, const T3 &v3)
 
const Table< std::string, Any > & table () const
 
const Anyoperator[] (const std::string &key) const
 
const Anyoperator[] (const char *key) const
 
Anyoperator[] (const std::string &key)
 
Anyoperator[] (const char *key)
 
template<class T >
Any get (const std::string &key, const T &defaultVal) const
 
bool containsKey (const std::string &key) const
 
template<class T >
void set (const std::string &key, const T &val)
 
Anynext ()
 
std::string sourceDirectory () const
 
bool operator== (const Any &x) const
 
bool operator== (const std::string &s) const
 
bool operator== (const double &v) const
 
bool operator== (int v) const
 
bool operator== (bool v) const
 
bool operator!= (const Any &x) const
 
bool operator!= (const std::string &s) const
 
bool operator!= (const double &v) const
 
bool operator!= (int v) const
 
bool operator!= (bool v) const
 
 operator int () const
 
 operator uint32 () const
 
 operator float () const
 
 operator double () const
 
 operator bool () const
 
 operator std::string () const
 
 operator char () const
 
 operator uint8 () const
 
 operator int16 () const
 
 operator uint16 () const
 
void resize (int n)
 
void clear ()
 
void load (const std::string &filename)
 
void loadIfExists (const std::string &filename)
 
void save (const std::string &filename) const
 
void serialize (TextOutput &to, bool json=false, bool coerce=false) const
 
void serialize (class BinaryOutput &b) const
 
void deserialize (TextInput &ti)
 
void deserialize (class BinaryInput &b)
 
const Sourcesource () const
 
void remove (const std::string &key)
 
void remove (int index)
 
void verify (bool value, const std::string &message="") const
 
void verifyName (const std::string &n) const
 
void verifyName (const std::string &n, const std::string &m) const
 
void verifyName (const std::string &n, const std::string &m, const std::string &p) const
 
void verifyName (const std::string &n, const std::string &m, const std::string &p, const std::string &q) const
 
void verifyNameBeginsWith (const std::string &n) const
 
void verifyNameBeginsWith (const std::string &n, const std::string &m) const
 
void verifyNameBeginsWith (const std::string &n, const std::string &m, const std::string &p) const
 
void verifyNameBeginsWith (const std::string &n, const std::string &m, const std::string &p, const std::string &q) const
 
void verifyNameBeginsWith (const std::string &n, const std::string &m, const std::string &p, const std::string &q, const std::string &r) const
 
void verifyNameBeginsWith (const std::string &n, const std::string &m, const std::string &p, const std::string &q, const std::string &r, const std::string &s) const
 
void verifyNameBeginsWith (const std::string &n, const std::string &m, const std::string &p, const std::string &q, const std::string &r, const std::string &s, const std::string &t) const
 
void verifyType (Type t) const
 
void verifyType (Type t0, Type t1) const
 
void verifySize (int low, int high) const
 
void verifySize (int s) const
 
template<class T >
 Any (const Array< T > &array, const std::string &name="")
 
template<class T >
void getArray (Array< T > &array) const
 
template<class T >
void getTable (Table< std::string, T > &table) const
 

Static Public Member Functions

static std::string toString (Type t)
 
static Any parse (const std::string &src)
 
static Any fromFile (const std::string &filename)
 

Private Member Functions

void beforeRead () const
 
void beforeWrite ()
 
void dropReference ()
 
void ensureData ()
 
void ensureMutable ()
 
void deserializeBody (TextInput &ti, Token &token)
 
void deserialize (TextInput &ti, Token &token)
 
 Any (const std::string &key, Data *data)
 
bool isPlaceholder () const
 
void _append (const Any &v0)
 
void _append (const Any &v0, const Any &v1)
 
void _append (const Any &v0, const Any &v1, const Any &v2)
 
void _append (const Any &v0, const Any &v1, const Any &v2, const Any &v3)
 
Any _get (const std::string &key, const Any &defaultVal) const
 
void _set (const std::string &key, const Any &val)
 
void _parse (const std::string &src)
 
void deserializeTable (TextInput &ti)
 
void deserializeArray (TextInput &ti, const std::string &term)
 
void become (const Type &t)
 

Static Private Member Functions

static void deserializeComment (TextInput &ti, Token &token, std::string &comment)
 
static void deserializeName (TextInput &ti, Token &token, std::string &name)
 
static void readUntilSeparatorOrClose (TextInput &ti, Token &token)
 

Private Attributes

std::string m_placeholderName
 
Type m_type
 
SimpleValue m_simpleValue
 
Datam_data
 

Static Private Attributes

static const char * PAREN = "()"
 
static const char * BRACKET = "[]"
 
static const char * BRACE = "{}"
 

Detailed Description

Easy loading and saving of human-readable configuration files.

Any encodes typed, structured data and can serialize it to a human readable format that is very similar to the Python language's data syntax, and fully supports Python's data syntax as well. It is well-suited for quickly creating human-readable file formats, especially since deserialization and serialization preserve comments and an Any can tell you what file and line it came from. The syntax allows most C++ editors to properly highlight Any files, and makes it easy to design little ad-hoc C-like languages in configuration files.

The class is designed so that copying Anys generally is fast, even if it is a large array or table. This is because data is shared between copies until it is mutated, at which point an actual copy occurs.

Example

Sample File:

{
   shape = "round",
   // in meters
   radius = 3.7,
   position = Vector3(1.0, -1.0, 0.0),
   video = { format = "RGB8", size = (320, 200)},
   material = #include("rocks.mat")
}

Sample code using Any:

Any x;
x.load("ball.txt");
if (x["shape"].string() == "round") {
    x["density"] = 3;
}
x.save("ball.txt");

The custom serialization format was chosen to be terse, easy for humans to read, and easy for machines to parse. It was specifically chosen over formats like XML, YAML, JSON, S-expressions, and Protocol Buffers, although there is no reason you could not write readers and writers for G3D::Any that support those. Any also currently supports the JSON format.

G3D::Any assumes that structures do not contain cycles; it is an error to create a structure like:

Any x(Any::ARRAY);
x.array().append(x);    // don't do this!

although no exception will be thrown at runtime during that append.

includes

When parsing an Any from a file, the syntax #include(filename) allows subsitution of the contents of filename for any single expression in an Any. The filename is interpreted relative to the file being parsed, and inside of the included file, relative filenames are interpreted with respect to the included file (and so on, recursively for nested inclusion).

Filenames are resolved with System::resolve and then System::findDataFile if not found, so they may contain environment variables.

Parsing

The primary use of Any is to create your own text file formats. The Vector3 constructor is a good example of how to use the Any::verify methods to provide good error checking while parsing such formats:

Vector3::Vector3(const Any& any) {
    any.verifyName("Vector3");
    any.verifyType(Any::TABLE, Any::ARRAY);
    any.verifySize(3);
    if (any.type() == Any::ARRAY) {
        x = any[0];
        y = any[1];
        z = any[2];
    } else {
        // Table
        x = any["x"];
        y = any["y"];
        z = any["z"];
    }
}

It is often convenient to iterate through the table portion using G3D::AnyTableReader.

BNF

Serialized format BNF:

identifier  ::= (letter | "_") (letter | digit | "_")*
identifier-op ::= "::" | "->" | "."

identifier-exp ::= [identifier-op] identifier (identifier-op identifier)*

comment     ::= C++ single or multi-line comments
separator   ::= "," | ";"

number      ::= 
string      ::= 
boolean     ::= "True" | "False"
nil         ::= "Nil"  | "None" 
array       ::= ("(" | "[" | "{") [value (separator value)* [separator] ] (")" | "]" | "}")
pair        ::= (identifier | string) ("=" | ":") value
table       ::= ("(" | "[" | "{") [ pair (separator pair)* [separator] ] (")" | "]" | "}")
named-array ::= identifier-exp array
named-table ::= identifier-exp table
include     ::= "#" "include" "(" string ")"

value       ::= [comment] (nil | number | boolean | string | array | table | named-array | named-table | include)

Except for single-line comments, whitespace is not significant. All parsing is case-insensitive.

The include expression pastes the contents of the named file in as if they appeared in the original source. Note that an include expression can only appear in the locations where a value is expected. This means that it cannot yield more than one element of an array and cannot serve as the pair in a table.

The deserializer allows the substitution of [] or {} for () when writing tuples and ";" for ",". These are convenient when mimicing a programming language, e.g., "[ printf("hello world."); clearScreen();]" parses as an array containing two named arrays within it. The deserializer also allows a trailing comma inside any array or table, which also convenient when commenting out the last element.

The serializer indents four spaces for each level of nesting. Tables are written with the keys in alphabetic order.

See also
G3D::AnyTableReader

Member Typedef Documentation

typedef Table<std::string, Any> G3D::Any::AnyTable

Member Enumeration Documentation

Enumerator
NIL 
BOOLEAN 
NUMBER 
STRING 
ARRAY 
TABLE 
EMPTY_CONTAINER 
Definition: Any.h:187
Definition: Any.h:187
Definition: Any.h:187
Definition: Any.h:187
Definition: Any.h:187
Definition: Any.h:187
Definition: Any.h:187

Constructor & Destructor Documentation

G3D::Any::Any ( const std::string &  key,
Data data 
)
private

Construct an Any that is a proxy for a table fetch from data. This proxy can be copied exactly once on return from operator[].

G3D::Any::Any ( )

NIL constructor

347  : m_type(NIL), m_data(NULL) {
348 }
arena_t NULL
Definition: jemalloc_internal.h:624
Definition: Any.h:187
Type m_type
Definition: Any.h:306
Data * m_data
Definition: Any.h:308

+ Here is the caller graph for this function:

G3D::Any::Any ( TextInput t)
explicit

Deserialize

351  : m_type(NIL), m_data(NULL) {
352  deserialize(t);
353 }
arena_t NULL
Definition: jemalloc_internal.h:624
Definition: Any.h:187
void deserialize(TextInput &ti, Token &token)
Definition: Any.cpp:1233
Type m_type
Definition: Any.h:306
Data * m_data
Definition: Any.h:308

+ Here is the call graph for this function:

G3D::Any::Any ( const Any x)
356  : m_type(NIL), m_data(NULL) {
357  x.beforeRead();
358  *this = x;
359 }
arena_t NULL
Definition: jemalloc_internal.h:624
Definition: Any.h:187
Type m_type
Definition: Any.h:306
Data * m_data
Definition: Any.h:308
G3D::int16 x
Definition: Vector2int16.h:37

+ Here is the call graph for this function:

G3D::Any::Any ( double  x)
explicit

NUMBER constructor

363 }
SimpleValue m_simpleValue
Definition: Any.h:307
arena_t NULL
Definition: jemalloc_internal.h:624
Type m_type
Definition: Any.h:306
Data * m_data
Definition: Any.h:308
Definition: Any.h:187
G3D::int16 x
Definition: Vector2int16.h:37
G3D::Any::Any ( float  x)
explicit
366  : m_type(NUMBER), m_simpleValue(double(x)), m_data(NULL) {
367 }
SimpleValue m_simpleValue
Definition: Any.h:307
arena_t NULL
Definition: jemalloc_internal.h:624
Type m_type
Definition: Any.h:306
Data * m_data
Definition: Any.h:308
Definition: Any.h:187
G3D::int16 x
Definition: Vector2int16.h:37
G3D::Any::Any ( long  x)
explicit

NUMBER constructor

373  : m_type(NUMBER), m_simpleValue((double)x), m_data(NULL) {
374 }
SimpleValue m_simpleValue
Definition: Any.h:307
arena_t NULL
Definition: jemalloc_internal.h:624
Type m_type
Definition: Any.h:306
Data * m_data
Definition: Any.h:308
Definition: Any.h:187
G3D::int16 x
Definition: Vector2int16.h:37
G3D::Any::Any ( int  x)
explicit

NUMBER constructor

376  : m_type(NUMBER), m_simpleValue((double)x), m_data(NULL) {
377 }
SimpleValue m_simpleValue
Definition: Any.h:307
arena_t NULL
Definition: jemalloc_internal.h:624
Type m_type
Definition: Any.h:306
Data * m_data
Definition: Any.h:308
Definition: Any.h:187
G3D::int16 x
Definition: Vector2int16.h:37
G3D::Any::Any ( char  x)
explicit

NUMBER constructor

370  : m_type(NUMBER), m_simpleValue(double(x)), m_data(NULL) {
371 }
SimpleValue m_simpleValue
Definition: Any.h:307
arena_t NULL
Definition: jemalloc_internal.h:624
Type m_type
Definition: Any.h:306
Data * m_data
Definition: Any.h:308
Definition: Any.h:187
G3D::int16 x
Definition: Vector2int16.h:37
G3D::Any::Any ( short  x)
explicit

NUMBER constructor

380  : m_type(NUMBER), m_simpleValue((double)x), m_data(NULL) {
381 }
SimpleValue m_simpleValue
Definition: Any.h:307
arena_t NULL
Definition: jemalloc_internal.h:624
Type m_type
Definition: Any.h:306
Data * m_data
Definition: Any.h:308
Definition: Any.h:187
G3D::int16 x
Definition: Vector2int16.h:37
G3D::Any::Any ( bool  x)
explicit

BOOLEAN constructor

385 }
SimpleValue m_simpleValue
Definition: Any.h:307
arena_t NULL
Definition: jemalloc_internal.h:624
Type m_type
Definition: Any.h:306
Data * m_data
Definition: Any.h:308
G3D::int16 x
Definition: Vector2int16.h:37
Definition: Any.h:187
G3D::Any::Any ( const std::string &  x)
explicit

STRING constructor

389  *(m_data->value.s) = s;
390 }
Value value
Definition: Any.h:246
Type m_type
Definition: Any.h:306
Data * m_data
Definition: Any.h:308
static Data * create(const Data *d)
Definition: Any.cpp:169
std::string * s
Definition: Any.h:234
Definition: Any.h:187
G3D::Any::Any ( const char *  x)
explicit

STRING constructor

393  : m_type(STRING), m_data(NULL) {
394  if (s == NULL) {
395  m_type = NIL;
396  } else {
397  ensureData();
398  *(m_data->value.s) = s;
399  }
400 }
Value value
Definition: Any.h:246
arena_t NULL
Definition: jemalloc_internal.h:624
Definition: Any.h:187
Type m_type
Definition: Any.h:306
void ensureData()
Definition: Any.cpp:1381
Data * m_data
Definition: Any.h:308
std::string * s
Definition: Any.h:234
Definition: Any.h:187

+ Here is the call graph for this function:

G3D::Any::Any ( Type  t,
const std::string &  name = "",
const std::string &  brackets = "",
const char  separator = '\0' 
)
explicit

t must be ARRAY or TABLE

Parameters
bracketsmust be "" (defaults to {} for table, () for array), "[]", "()", or "{}"
separatormust be ';', ',', or '\0' (defaults to ',' for array and ';' for table)
405  : m_type(t), m_data(NULL) {
406  alwaysAssertM(isContainerType(t), "Can only create ARRAY or TABLE from Type enum.");
407 
408  ensureData();
409  if (name != "") {
410  m_data->name = name;
411  }
412 
413  if (brackets == "") {
414  if (t == ARRAY) {
415  m_data->bracket = PAREN;
416  } else {
417  m_data->bracket = BRACE;
418  }
419  } else if (brackets == PAREN) {
420  m_data->bracket = PAREN;
421  } else if (brackets == BRACE) {
422  m_data->bracket = BRACE;
423  } else if (brackets == BRACKET) {
425  } else {
426  alwaysAssertM(false, std::string("illegal brackets: ") + brackets);
427  }
428 
429  if (separator == '\0') {
430  if (t == ARRAY) {
431  m_data->separator = ',';
432  } else {
433  m_data->separator = ';';
434  }
435  } else if (separator == ',' || separator == ';') {
436  m_data->separator = separator;
437  } else {
438  alwaysAssertM(false, std::string("illegal separator: ") + separator);
439  }
440 }
const char * bracket
Definition: Any.h:272
std::string name
Definition: Any.h:250
static bool isContainerType(Any::Type &t)
Definition: Any.cpp:30
arena_t NULL
Definition: jemalloc_internal.h:624
Definition: Any.h:187
Type m_type
Definition: Any.h:306
void ensureData()
Definition: Any.cpp:1381
Data * m_data
Definition: Any.h:308
static const char * BRACKET
Definition: Any.h:227
char separator
Definition: Any.h:275
const std::string & name() const
Definition: Any.cpp:562
static const char * BRACE
Definition: Any.h:228
#define alwaysAssertM(exp, message)
Definition: debugAssert.h:165
static const char * PAREN
Definition: Any.h:226

+ Here is the call graph for this function:

template<class T >
G3D::Any::Any ( const T &  v)
inlineexplicit

Extensible constructor: call the toAny() method of any class.

443  : m_type(NIL), m_data(NULL) {
444  *this = v.toAny();
445  }
arena_t NULL
Definition: jemalloc_internal.h:624
Definition: Any.h:187
Type m_type
Definition: Any.h:306
Data * m_data
Definition: Any.h:308
G3D::Any::~Any ( )
443  {
444  dropReference();
445 }
void dropReference()
Definition: Any.cpp:327

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

template<class T >
G3D::Any::Any ( const Array< T > &  array,
const std::string &  name = "" 
)
inlineexplicit

Assumes that Any(T) is well-defined, e.g., by T defining a T::toAny() method.

830  : m_type(ARRAY), m_data(NULL) {
831  setName(name);
832  resize(array.size());
833  for (int i = 0; i < array.size(); ++i) {
834  (*this)[i] = Any(array[i]);
835  }
836  }
Any()
Definition: Any.cpp:347
void resize(int n)
Definition: Any.cpp:602
arena_t NULL
Definition: jemalloc_internal.h:624
Definition: Any.h:187
Type m_type
Definition: Any.h:306
void setName(const std::string &name)
Set the name used when serializing an ARRAY or TABLE.
Definition: Any.cpp:573
Data * m_data
Definition: Any.h:308
int size() const
Definition: Array.h:430
const std::string & name() const
Definition: Any.cpp:562

+ Here is the call graph for this function:

Member Function Documentation

void G3D::Any::_append ( const Any v0)
private
671  {
672  beforeRead();
673  verifyType(ARRAY);
674  debugAssert(m_data != NULL);
675  if (type() == EMPTY_CONTAINER) {
676  become(ARRAY);
677  }
678  m_data->value.a->append(x0);
679 }
Type type() const
Definition: Any.cpp:505
Value value
Definition: Any.h:246
arena_t NULL
Definition: jemalloc_internal.h:624
Definition: Any.h:187
void verifyType(Type t) const
Definition: Any.cpp:1739
#define debugAssert(exp)
Definition: debugAssert.h:160
Array< Any > * a
Definition: Any.h:235
Data * m_data
Definition: Any.h:308
void beforeRead() const
Definition: Any.cpp:154
Definition: Any.h:187
void become(const Type &t)
Definition: Any.cpp:68

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::Any::_append ( const Any v0,
const Any v1 
)
private
682  {
683  beforeRead();
684  append(x0);
685  append(x1);
686 }
void append(const T0 &v0)
Definition: Any.h:575
void beforeRead() const
Definition: Any.cpp:154

+ Here is the call graph for this function:

void G3D::Any::_append ( const Any v0,
const Any v1,
const Any v2 
)
private
689  {
690  beforeRead();
691  append(x0);
692  append(x1);
693  append(x2);
694 }
void append(const T0 &v0)
Definition: Any.h:575
void beforeRead() const
Definition: Any.cpp:154

+ Here is the call graph for this function:

void G3D::Any::_append ( const Any v0,
const Any v1,
const Any v2,
const Any v3 
)
private
697  {
698  beforeRead();
699  append(x0);
700  append(x1);
701  append(x2);
702  append(x3);
703 }
void append(const T0 &v0)
Definition: Any.h:575
void beforeRead() const
Definition: Any.cpp:154

+ Here is the call graph for this function:

Any G3D::Any::_get ( const std::string &  key,
const Any defaultVal 
) const
private
771  {
772  beforeRead();
773  defaultVal.beforeRead();
774  try {
775  return operator[](x);
776  } catch(KeyNotFound) {
777  return defaultVal;
778  }
779 }
void beforeRead() const
Definition: Any.cpp:154
const Any & operator[](int i) const
Definition: Any.cpp:629
G3D::int16 x
Definition: Vector2int16.h:37

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::Any::_parse ( const std::string &  src)
private
896  {
897  beforeRead();
898  TextInput::Settings settings;
899  getDeserializeSettings(settings);
900 
901  TextInput ti(TextInput::FROM_STRING, src, settings);
902  deserialize(ti);
903 }
void deserialize(TextInput &ti, Token &token)
Definition: Any.cpp:1233
Definition: TextInput.h:575
void beforeRead() const
Definition: Any.cpp:154
static void getDeserializeSettings(TextInput::Settings &settings)
Definition: Any.cpp:862

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::Any::_set ( const std::string &  key,
const Any val 
)
private
758  {
759  beforeRead();
760  v.beforeRead();
761  verifyType(TABLE);
762  debugAssert(m_data != NULL);
763  if ( type() == EMPTY_CONTAINER) {
764  become(TABLE);
765  }
766  Table<std::string, Any>& table = *(m_data->value.t);
767  table.set(k, v);
768 }
Type type() const
Definition: Any.cpp:505
Definition: Any.h:187
Value value
Definition: Any.h:246
const Table< std::string, Any > & table() const
Definition: Any.cpp:706
arena_t NULL
Definition: jemalloc_internal.h:624
AnyTable * t
Definition: Any.h:236
void verifyType(Type t) const
Definition: Any.cpp:1739
#define debugAssert(exp)
Definition: debugAssert.h:160
Data * m_data
Definition: Any.h:308
void beforeRead() const
Definition: Any.cpp:154
Definition: Any.h:187
void become(const Type &t)
Definition: Any.cpp:68

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

template<class T0 >
void G3D::Any::append ( const T0 &  v0)
inline
575  {
576  _append(Any(v0));
577  }
Any()
Definition: Any.cpp:347
void _append(const Any &v0)
Definition: Any.cpp:671

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

template<class T0 , class T1 >
void G3D::Any::append ( const T0 &  v0,
const T1 v1 
)
inline
580  {
581  _append(Any(v0), Any(v1));
582  }
Any()
Definition: Any.cpp:347
void _append(const Any &v0)
Definition: Any.cpp:671

+ Here is the call graph for this function:

template<class T0 , class T1 , class T2 >
void G3D::Any::append ( const T0 &  v0,
const T1 v1,
const T2 v2 
)
inline
585  {
586  _append(Any(v0), Any(v1), Any(v2));
587  }
Any()
Definition: Any.cpp:347
void _append(const Any &v0)
Definition: Any.cpp:671

+ Here is the call graph for this function:

template<class T0 , class T1 , class T2 , class T3 >
void G3D::Any::append ( const T0 &  v0,
const T1 v1,
const T2 v2,
const T3 v3 
)
inline
590  {
591  _append(Any(v0), Any(v1), Any(v2), Any(v3));
592  }
Any()
Definition: Any.cpp:347
void _append(const Any &v0)
Definition: Any.cpp:671

+ Here is the call graph for this function:

const Array< Any > & G3D::Any::array ( ) const

Directly exposes the underlying data structure for an ARRAY.

663  {
664  beforeRead();
665  verifyType(ARRAY);
666  debugAssert(m_data != NULL);
667  return *(m_data->value.a);
668 }
Value value
Definition: Any.h:246
arena_t NULL
Definition: jemalloc_internal.h:624
Definition: Any.h:187
void verifyType(Type t) const
Definition: Any.cpp:1739
#define debugAssert(exp)
Definition: debugAssert.h:160
Array< Any > * a
Definition: Any.h:235
Data * m_data
Definition: Any.h:308
void beforeRead() const
Definition: Any.cpp:154

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::Any::become ( const Type t)
private

Turns an empty container into a table or an array

68  {
69  if ((t == ARRAY) || (t == TABLE)) {
71  m_type = t;
72  m_data->type = m_type;
73  if(t == ARRAY) {
74  m_data->value.a = new AnyArray();
75  } else {
76  m_data->value.t = new AnyTable();
77  }
78  }
79 }
Definition: Any.h:187
Value value
Definition: Any.h:246
Definition: Any.h:187
AnyTable * t
Definition: Any.h:236
Table< std::string, Any > AnyTable
Definition: Any.h:208
Array< Any > AnyArray
Definition: Any.h:207
Type m_type
Definition: Any.h:306
#define debugAssert(exp)
Definition: debugAssert.h:160
Type type
Definition: Any.h:242
Array< Any > * a
Definition: Any.h:235
Data * m_data
Definition: Any.h:308
Definition: Any.h:187

+ Here is the caller graph for this function:

void G3D::Any::beforeRead ( ) const
private

Called before every read operation.

154  {
155  if (isPlaceholder()) {
156  // Tried to read from a placeholder--throw an exception as if
157  // the original operator[] had failed.
158  alwaysAssertM(m_data, "Corrupt placeholder");
159  KeyNotFound e(m_data);
160 
161  e.key = m_placeholderName;
162  e.message = "Key \"" + m_placeholderName + "\" not found in operator[] lookup.";
163 
164  throw e;
165  }
166 }
Data * m_data
Definition: Any.h:308
bool isPlaceholder() const
Definition: Any.h:351
#define alwaysAssertM(exp, message)
Definition: debugAssert.h:165
std::string m_placeholderName
Definition: Any.h:304

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::Any::beforeWrite ( )
private

Called before every write operation to this Any. Wipes the placeholder status and includedFrom entry.

448  {
449  if (isPlaceholder()) {
450  // This is no longer a placeholder
451  m_placeholderName.clear();
452  }
453 
454  if (m_data && ! m_data->includeLine.empty()) {
455  // Forget where this Any was included from...it no
456  // longer matches the contents there.
457  m_data->includeLine = "";
458  }
459 }
Data * m_data
Definition: Any.h:308
bool isPlaceholder() const
Definition: Any.h:351
std::string includeLine
Definition: Any.h:260
std::string m_placeholderName
Definition: Any.h:304

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool G3D::Any::boolean ( ) const
555  {
556  beforeRead();
558  return m_simpleValue.b;
559 }
SimpleValue m_simpleValue
Definition: Any.h:307
void verifyType(Type t) const
Definition: Any.cpp:1739
void beforeRead() const
Definition: Any.cpp:154
bool b
Definition: Any.h:217
Definition: Any.h:187

+ Here is the call graph for this function:

void G3D::Any::clear ( )

Clears all entries. This must be a TABLE or ARRAY

613  {
614  beforeRead();
616  switch (m_type) {
617  case ARRAY:
618  m_data->value.a->clear();
619  break;
620 
621  case TABLE:
622  m_data->value.t->clear();
623  break;
624  default:;
625  }
626 }
Definition: Any.h:187
Value value
Definition: Any.h:246
void clear()
Definition: Table.h:578
Definition: Any.h:187
AnyTable * t
Definition: Any.h:236
void verifyType(Type t) const
Definition: Any.cpp:1739
Type m_type
Definition: Any.h:306
Array< Any > * a
Definition: Any.h:235
Data * m_data
Definition: Any.h:308
void beforeRead() const
Definition: Any.cpp:154

+ Here is the call graph for this function:

const std::string & G3D::Any::comment ( ) const

Comments appear before values when they are in serialized form.

511  {
512  beforeRead();
513 
514  static const std::string blank;
515  if (m_data != NULL) {
516  return m_data->comment;
517  } else {
518  return blank;
519  }
520 }
arena_t NULL
Definition: jemalloc_internal.h:624
std::string comment
Definition: Any.h:248
Data * m_data
Definition: Any.h:308
void beforeRead() const
Definition: Any.cpp:154

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool G3D::Any::containsKey ( const std::string &  key) const

Returns true if this key is in the TABLE. Illegal to call on an object that is not a TABLE.

313  {
314  beforeRead();
315  verifyType(TABLE);
316  if (size() == 0) {
317  //catches the case of an empty container, where value.t is null
318  return false;
319  }
320  Any* a = m_data->value.t->getPointer(x);
321 
322  // Don't return true for placeholder objects
323  return (a != NULL) && (! a->isPlaceholder());
324 }
Definition: Any.h:187
Value * getPointer(const Key &key) const
Definition: Table.h:731
Value value
Definition: Any.h:246
Any()
Definition: Any.cpp:347
arena_t NULL
Definition: jemalloc_internal.h:624
AnyTable * t
Definition: Any.h:236
void verifyType(Type t) const
Definition: Any.cpp:1739
Data * m_data
Definition: Any.h:308
void beforeRead() const
Definition: Any.cpp:154
int size() const
Definition: Any.cpp:580
G3D::int16 x
Definition: Vector2int16.h:37

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::Any::deserialize ( TextInput ti,
Token token 
)
private
1233  {
1234  // Deallocate old data
1235  dropReference();
1236  m_type = NIL;
1237  m_simpleValue.b = false;
1238 
1239  // Skip leading newlines
1240  while (token.type() == Token::NEWLINE) {
1241  token = ti.read();
1242  }
1243 
1244  std::string comment;
1245  if (token.type() == Token::COMMENT) {
1246  deserializeComment(ti, token, comment);
1247  }
1248 
1249  if (token.type() == Token::END) {
1250  // There should never be a comment without an Any following it; even
1251  // if the file ends with some commented out stuff,
1252  // that should not happen after a comma, so we'd never read that
1253  // far in a proper file.
1254  throw ParseError(ti.filename(), token.line(), token.character(),
1255  "File ended without a properly formed Any");
1256  }
1257 
1258  // Do we need to read one more token after the end?
1259  bool needRead = true;
1260 
1261  switch (token.type()) {
1262  case Token::STRING:
1263  m_type = STRING;
1264  ensureData();
1265  *(m_data->value.s) = token.string();
1266  m_data->source.set(ti, token);
1267  break;
1268 
1269  case Token::NUMBER:
1270  m_type = NUMBER;
1271  m_simpleValue.n = token.number();
1272  ensureData();
1273  m_data->source.set(ti, token);
1274  break;
1275 
1276  case Token::BOOLEAN:
1277  m_type = BOOLEAN;
1278  m_simpleValue.b = token.boolean();
1279  ensureData();
1280  m_data->source.set(ti, token);
1281  break;
1282 
1283  case Token::SYMBOL:
1284  // Pragma, Named Array, Named Table, Array, Table, or NIL
1285  if (token.string() == "#") {
1286  // Pragma
1287 
1288  // Currently, "include" is the only pragma allowed
1289  token = ti.read();
1290  if (! ((token.type() == Token::SYMBOL) &&
1291  (token.string() == "include"))) {
1292  throw ParseError(ti.filename(), token.line(), token.character(),
1293  "Expected 'include' pragma after '#'");
1294  }
1295 
1296  ti.readSymbol("(");
1297  // The string typed into the file, which may be relative
1298  const std::string& includeName = ti.readString();
1299 
1300  // Find the include file
1301  const std::string& myPath = FilePath::parent(ti.filename());
1302 
1303  std::string t = FileSystem::resolve(includeName, myPath);
1304 
1305  if (! FileSystem::exists(t)) {
1306  // Try and find the path, starting with the cwd
1307  t = System::findDataFile(includeName);
1308  }
1309 
1310  // Read the included file
1311  load(t);
1312 
1313  // Update the source information
1314  ensureData();
1315  if (! comment.empty()) {
1316  m_data->includeLine = format("\n/* %s */\n", comment.c_str());
1317  }
1318  m_data->includeLine += format("#include(\"%s\")", includeName.c_str());
1319  m_data->source.filename +=
1320  format(" [included from %s:%d(%d)]", ti.filename().c_str(), token.line(), token.character());
1321 
1322  ti.readSymbol(")");
1323 
1324  } else if (toUpper(token.string()) == "NIL" || token.string() == "None") {
1325  // Nothing left to do; we initialized to NIL originally
1326  ensureData();
1327  m_data->source.set(ti, token);
1328  } else if (isValidIdentifier(token.string()) && !isOpen(ti.peek().string()[0]) && ti.peek().string() != "::") {
1329  // Valid unquoted string
1330  m_type = STRING;
1331  ensureData();
1332  *(m_data->value.s) = token.string();
1333  m_data->source.set(ti, token);
1334  } else {
1335  // Array or Table
1336 
1337  // Parse the name
1338  // s must have at least one element or this would not have
1339  // been parsed as a symbol
1340  std::string name;
1341  deserializeName(ti, token, name);
1342  if (token.type() != Token::SYMBOL) {
1343  throw ParseError(ti.filename(), token.line(), token.character(),
1344  "Malformed Any TABLE or ARRAY; must start with [, (, or {");
1345  }
1346 
1347  if (isOpen(token.string()[0])) {
1348  // Array or table
1349  deserializeBody(ti, token);
1350  } else {
1351  throw ParseError(ti.filename(), token.line(), token.character(),
1352  "Malformed Any TABLE or ARRAY; must start with [, (, or {");
1353  }
1354 
1355  if (! name.empty()) {
1356  ensureData();
1357  m_data->name = name;
1358  }
1359  needRead = false;
1360  } // if NIL
1361  break;
1362 
1363  default:
1364  throw ParseError(ti.filename(), token.line(), token.character(),
1365  "Unexpected token");
1366 
1367  } // switch
1368 
1369  if (! comment.empty()) {
1370  ensureData();
1371  m_data->comment = comment;
1372  }
1373 
1374  if (needRead) {
1375  // Array and table already consumed their last token
1376  token = ti.read();
1377  }
1378 }
Definition: TextInput.h:61
Definition: TextInput.h:62
Definition: TextInput.h:57
Value value
Definition: Any.h:246
Definition: TextInput.h:58
std::string name
Definition: Any.h:250
SimpleValue m_simpleValue
Definition: Any.h:307
static bool isOpen(const char c)
Definition: Any.cpp:1195
Definition: TextInput.h:63
Source source
Definition: Any.h:269
static void deserializeComment(TextInput &ti, Token &token, std::string &comment)
Definition: Any.cpp:1178
static void deserializeName(TextInput &ti, Token &token, std::string &name)
Definition: Any.cpp:1206
Definition: TextInput.h:60
void dropReference()
Definition: Any.cpp:327
static bool exists(const std::string &f, bool trustCache=true, bool caseSensitive=true)
Definition: FileSystem.h:401
Definition: Any.h:187
std::string filename
Definition: Any.h:194
Type m_type
Definition: Any.h:306
static std::string parent(const std::string &path)
Definition: FileSystem.cpp:795
double n
Definition: Any.h:218
static std::string findDataFile(const std::string &full, bool exceptionIfNotFound=true, bool caseSensitive=true)
Definition: System.cpp:365
Definition: TextInput.h:59
void ensureData()
Definition: Any.cpp:1381
std::string comment
Definition: Any.h:248
Data * m_data
Definition: Any.h:308
void deserializeBody(TextInput &ti, Token &token)
Definition: Any.cpp:1459
std::string __cdecl format(const char *fmt...) G3D_CHECK_PRINTF_ARGS
std::string toUpper(const std::string &x)
Definition: stringutils.cpp:216
void load(const std::string &filename)
Definition: Any.cpp:906
const std::string & name() const
Definition: Any.cpp:562
bool b
Definition: Any.h:217
static std::string resolve(const std::string &path, const std::string &cwd=currentDirectory())
Definition: FileSystem.h:440
std::string * s
Definition: Any.h:234
Definition: Any.h:187
const std::string & comment() const
Definition: Any.cpp:511
Definition: Any.h:187
void set(const TextInput &ti, const Token &t)
Definition: Any.h:200
std::string includeLine
Definition: Any.h:260
Definition: Any.h:187
bool isValidIdentifier(const std::string &s)
Definition: stringutils.cpp:115

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::Any::deserialize ( TextInput ti)

Parse from a stream.

See also
load, parse
1224  {
1225  beforeRead();
1226  Token token = ti.read();
1227  deserialize(ti, token);
1228  // Restore the last token
1229  ti.push(token);
1230 }
void deserialize(TextInput &ti, Token &token)
Definition: Any.cpp:1233
void beforeRead() const
Definition: Any.cpp:154

+ Here is the call graph for this function:

void G3D::Any::deserialize ( class BinaryInput b)
42  {
43  const int version = b.readInt32();
44  alwaysAssertM(version == 1, "Wrong Any serialization version");
45  _parse(b.readString32());
46 }
#define alwaysAssertM(exp, message)
Definition: debugAssert.h:165
void _parse(const std::string &src)
Definition: Any.cpp:896

+ Here is the call graph for this function:

void G3D::Any::deserializeArray ( TextInput ti,
const std::string &  term 
)
private
void G3D::Any::deserializeBody ( TextInput ti,
Token token 
)
private

Read an unnamed a TABLE or ARRAY. Token should be the open paren token; it is the next token after the close on return. Called from deserialize().

1459  {
1460  char closeSymbol = '\0';
1461  m_type = TABLE;
1462 
1463  const char c = token.string()[0];
1464 
1465  // Chose the appropriate close symbol based on the open symbol
1466  const char* bracket;
1467  if (c == '(') {
1468  bracket = PAREN;
1469  } else if (c == '[') {
1470  bracket = BRACKET;
1471  } else if (c == '{') {
1472  bracket = BRACE;
1473  } else {
1474  debugAssertM(false, "Illegal bracket type");
1475  bracket = PAREN;
1476  }
1477  closeSymbol = bracket[1];
1478 
1479  // We must set the type before we allocate m_data in ensureData().
1480  m_type = findType(ti, closeSymbol);
1481 
1482  // Allocate the underlying data structure
1483  ensureData();
1484  m_data->source.set(ti, token);
1485  m_data->bracket = bracket;
1486 
1488  debugAssert(m_data->separator != '\0');
1489 
1490  // Consume the open token
1491  token = ti.read();
1492 
1493  while (! ((token.type() == Token::SYMBOL) && (token.string()[0] == closeSymbol))) {
1494 
1495  // Read any leading comment. This must be done here (and not in the recursive deserialize
1496  // call) in case the body contains only a comment.
1497  std::string comment;
1498  deserializeComment(ti, token, comment);
1499 
1500  if ((token.type() == Token::SYMBOL) && (token.string()[0] == closeSymbol)) {
1501  // We're done; this catches the case where the container is empty
1502  break;
1503  }
1504 
1505  // Pointer the value being read
1506  Any a;
1507  std::string key;
1508 
1509  if (m_type == TABLE) {
1510  // Read the key
1511  if (token.type() != Token::SYMBOL && token.type() != Token::STRING) {
1512  throw ParseError(ti.filename(), token.line(), token.character(), "Expected a name");
1513  }
1514 
1515  key = token.string();
1516  // Consume everything up to the = sign, returning the "=" sign.
1517  token = ti.readSignificant();
1518 
1519  if ((token.type() != Token::SYMBOL) || ((token.string() != "=") && token.string() != ":")) {
1520  throw ParseError(ti.filename(), token.line(), token.character(), "Expected = or :");
1521  } else {
1522  // Read the next token, which is the value (don't consume comments--we want the value pointed to by a to get those).
1523  token = ti.read();
1524  }
1525  }
1526  a.deserialize(ti, token);
1527 
1528  if (! comment.empty()) {
1529  // Prepend the comment we read earlier
1530  a.ensureData();
1531  a.m_data->comment = trimWhitespace(comment + "\n" + a.m_data->comment);
1532  }
1533 
1534  if (m_type == TABLE) {
1535  set(key, a);
1536  } else {
1537  append(a);
1538  }
1539 
1540  // Read until the separator or close paren, discarding trailing comments and newlines
1541  readUntilSeparatorOrClose(ti, token);
1542 
1543  char s = token.string()[0];
1544 
1545  // Consume the separator
1546  if (isSeparator(s)) {
1547  token = ti.read();
1548  m_data->separator = s;
1549  debugAssert(m_data->separator != '\0');
1550  }
1551  }
1552 
1553  // Consume the close paren (to match other deserialize methods)
1554  token = ti.read();
1555 }
Definition: Any.h:187
const char * bracket
Definition: Any.h:272
Definition: TextInput.h:57
Definition: TextInput.h:58
Any()
Definition: Any.cpp:347
std::string trimWhitespace(const std::string &s)
Definition: stringutils.cpp:288
Source source
Definition: Any.h:269
static void deserializeComment(TextInput &ti, Token &token, std::string &comment)
Definition: Any.cpp:1178
void append(const T0 &v0)
Definition: Any.h:575
#define debugAssertM(exp, message)
Definition: debugAssert.h:161
static void readUntilSeparatorOrClose(TextInput &ti, Token &token)
Definition: Any.cpp:1393
Type m_type
Definition: Any.h:306
static bool isSeparator(char c)
Definition: Any.cpp:1388
#define debugAssert(exp)
Definition: debugAssert.h:160
void ensureData()
Definition: Any.cpp:1381
Type type
Definition: Any.h:242
Data * m_data
Definition: Any.h:308
static const char * BRACKET
Definition: Any.h:227
char separator
Definition: Any.h:275
void set(const std::string &key, const T &val)
Definition: Any.h:651
static Any::Type findType(TextInput &ti, const char closeSymbol)
Definition: Any.cpp:1420
const std::string & comment() const
Definition: Any.cpp:511
void set(const TextInput &ti, const Token &t)
Definition: Any.h:200
static const char * BRACE
Definition: Any.h:228
static const char * PAREN
Definition: Any.h:226

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::Any::deserializeComment ( TextInput ti,
Token token,
std::string &  comment 
)
staticprivate

Called from deserialize()

1178  {
1179  // Parse comments
1180  while (token.type() == Token::COMMENT) {
1181  comment += trimWhitespace(token.string());
1182 
1183  // Allow comments to contain newlines.
1184  do {
1185  token = ti.read();
1186  comment += "\n";
1187  } while (token.type() == Token::NEWLINE);
1188  }
1189 
1191 }
Definition: TextInput.h:61
Definition: TextInput.h:62
std::string trimWhitespace(const std::string &s)
Definition: stringutils.cpp:288
const std::string & comment() const
Definition: Any.cpp:511

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::Any::deserializeName ( TextInput ti,
Token token,
std::string &  name 
)
staticprivate

Read the name of a named Array or Table.

1206  {
1207  debugAssert(token.type() == Token::SYMBOL);
1208  std::string s = token.string();
1209  while (! isOpen(s[0])) {
1210  name += s;
1211 
1212  // Skip newlines and comments
1213  token = ti.readSignificant();
1214 
1215  if (token.type() != Token::SYMBOL) {
1216  throw ParseError(ti.filename(), token.line(), token.character(),
1217  "Expected symbol while parsing Any");
1218  }
1219  s = token.string();
1220  }
1221 }
Definition: TextInput.h:58
static bool isOpen(const char c)
Definition: Any.cpp:1195
#define debugAssert(exp)
Definition: debugAssert.h:160
const std::string & name() const
Definition: Any.cpp:562

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::Any::deserializeTable ( TextInput ti)
private
void G3D::Any::dropReference ( )
private

Decrements the reference count (if there is one). If the reference count is zero after decrement, calls delete on m_data and sets it to NULL.

327  {
328  if (m_data && m_data->referenceCount.decrement() <= 0) {
329  // This was the last reference to the shared data
331  }
332  m_data = NULL;
333 }
AtomicInt32 referenceCount
Definition: Any.h:267
static void destroy(Data *d)
Definition: Any.cpp:274
arena_t NULL
Definition: jemalloc_internal.h:624
int32 decrement()
Definition: AtomicInt32.h:113
Data * m_data
Definition: Any.h:308

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::Any::ensureData ( )
private

Allocate the Data object if it does not exist

1381  {
1382  if (m_data == NULL) {
1384  }
1385 }
arena_t NULL
Definition: jemalloc_internal.h:624
Type m_type
Definition: Any.h:306
Data * m_data
Definition: Any.h:308
static Data * create(const Data *d)
Definition: Any.cpp:169

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::Any::ensureMutable ( )
private

If m_data is not NULL, ensure that it has a unique reference and contains a valid m_data. This has a race condition if two threads are both trying to modify the same Any simultaneously.

336  {
337  if (m_data && (m_data->referenceCount.value() >= 1)) {
338  // Copy the data. We must do this before dropping the reference
339  // to avoid a race condition
340  Data* d = Data::create(m_data);
341  dropReference();
342  m_data = d;
343  }
344 }
AtomicInt32 referenceCount
Definition: Any.h:267
void dropReference()
Definition: Any.cpp:327
Data * m_data
Definition: Any.h:308
int32 value() const
Definition: AtomicInt32.h:67
static Data * create(const Data *d)
Definition: Any.cpp:169
Data
Definition: molten_core.h:69

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

float G3D::Any::floatValue ( ) const
541  {
542  beforeRead();
544  return (float)m_simpleValue.n;
545 }
SimpleValue m_simpleValue
Definition: Any.h:307
void verifyType(Type t) const
Definition: Any.cpp:1739
double n
Definition: Any.h:218
void beforeRead() const
Definition: Any.cpp:154
Definition: Any.h:187

+ Here is the call graph for this function:

Any G3D::Any::fromFile ( const std::string &  filename)
static

Load a new Any from filename.

See also
load, save, loadIfExists
96  {
97  Any a;
98  a.load(filename);
99  return a;
100 }
Any()
Definition: Any.cpp:347

+ Here is the call graph for this function:

template<class T >
Any G3D::Any::get ( const std::string &  key,
const T &  defaultVal 
) const
inline

For a table, returns the element for key x and defaultVal if it does not exist.

642  {
643  return _get(key, Any(defaultVal));
644  }
Any()
Definition: Any.cpp:347
Any _get(const std::string &key, const Any &defaultVal) const
Definition: Any.cpp:771

+ Here is the call graph for this function:

template<class T >
void G3D::Any::getArray ( Array< T > &  array) const
inline

Assumes that T defines T(const Any&)

840  {
841  verifyType(ARRAY);
842  array.resize(size());
843  for (int i = 0; i < array.size(); ++i) {
844  array[i] = T((*this)[i]);
845  }
846  }
void resize(size_t n, bool shrinkIfNecessary=true)
Definition: Array.h:490
Definition: Any.h:187
void verifyType(Type t) const
Definition: Any.cpp:1739
int size() const
Definition: Array.h:430
int size() const
Definition: Any.cpp:580

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

template<class T >
void G3D::Any::getTable ( Table< std::string, T > &  table) const
inline

Assumes that T defines T(const Any&)

850  {
851  verifyType(TABLE);
852  for (Table<std::string, Any>::Iterator it = this->table().begin(); it.isValid(); ++it) {
853  table.set(it.key(), T(it.value()));
854  }
855  }
Definition: Any.h:187
const Table< std::string, Any > & table() const
Definition: Any.cpp:706
void verifyType(Type t) const
Definition: Any.cpp:1739

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool G3D::Any::isNil ( ) const

True if this is the NIL value

530  {
531  beforeRead();
532  return (m_type == NIL);
533 }
Definition: Any.h:187
Type m_type
Definition: Any.h:306
void beforeRead() const
Definition: Any.cpp:154

+ Here is the call graph for this function:

bool G3D::Any::isPlaceholder ( ) const
inlineprivate
351  {
352  return ! m_placeholderName.empty();
353  }
std::string m_placeholderName
Definition: Any.h:304

+ Here is the caller graph for this function:

const Any& G3D::Any::last ( ) const
inline
563  {
564  return (*this)[size() - 1];
565  }
int size() const
Definition: Any.cpp:580

+ Here is the call graph for this function:

Any& G3D::Any::last ( )
inline
567  {
568  return (*this)[size() - 1];
569  }
int size() const
Definition: Any.cpp:580

+ Here is the call graph for this function:

int G3D::Any::length ( ) const
596  {
597  beforeRead();
598  return size();
599 }
void beforeRead() const
Definition: Any.cpp:154
int size() const
Definition: Any.cpp:580

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::Any::load ( const std::string &  filename)

Parse from a file.

See also
deserialize, parse, fromFile, loadIfExists
906  {
907  beforeRead();
908  TextInput::Settings settings;
909  getDeserializeSettings(settings);
910 
911  TextInput ti(FileSystem::resolve(filename), settings);
912  deserialize(ti);
913 }
void deserialize(TextInput &ti, Token &token)
Definition: Any.cpp:1233
void beforeRead() const
Definition: Any.cpp:154
static std::string resolve(const std::string &path, const std::string &cwd=currentDirectory())
Definition: FileSystem.h:440
static void getDeserializeSettings(TextInput::Settings &settings)
Definition: Any.cpp:862

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::Any::loadIfExists ( const std::string &  filename)

Load filename file if it exists, otherwise do not modify this

103  {
104  if (FileSystem::exists(filename)) {
105  load(filename);
106  }
107 }
static bool exists(const std::string &f, bool trustCache=true, bool caseSensitive=true)
Definition: FileSystem.h:401
void load(const std::string &filename)
Definition: Any.cpp:906

+ Here is the call graph for this function:

const std::string & G3D::Any::name ( ) const

If this is named ARRAY or TABLE, returns the name.

562  {
563  beforeRead();
564  static const std::string blank;
565  if (m_data != NULL) {
566  return m_data->name;
567  } else {
568  return blank;
569  }
570 }
std::string name
Definition: Any.h:250
arena_t NULL
Definition: jemalloc_internal.h:624
Data * m_data
Definition: Any.h:308
void beforeRead() const
Definition: Any.cpp:154

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool G3D::Any::nameBeginsWith ( const std::string &  s) const

If this is named ARRAY or TABLE, returns true if the name begins with s. The comparision is case insensitive.

110  {
111  return nameBeginsWith(s.c_str());
112 }
bool nameBeginsWith(const std::string &s) const
Definition: Any.cpp:110
bool G3D::Any::nameBeginsWith ( const char *  s) const

If this is named ARRAY or TABLE, returns true if the name begins with s. The comparision is case insensitive.

126  {
128 
129  const char* n = name().c_str();
130  // Walk through character-by-character
131  while ((*s != '\0') && (*n != '\0')) {
132  if (toLower(*s) != toLower(*n)) {
133  // Mismatch
134  return false;
135  }
136  ++s; ++n;
137  }
138  // Make sure s ran out no later than n
139  return (*s == '\0');
140 }
Definition: Any.h:187
Definition: Any.h:187
void verifyType(Type t) const
Definition: Any.cpp:1739
std::string toLower(const std::string &x)
Definition: stringutils.cpp:223
const std::string & name() const
Definition: Any.cpp:562

+ Here is the call graph for this function:

bool G3D::Any::nameEquals ( const std::string &  s) const

If this is named ARRAY or TABLE, returns true if the name is s. The comparision is case insensitive.

115  {
116  // If std::string has a fast hash compare, use it first
117  return (name() == s) || nameEquals(s.c_str());
118 }
bool nameEquals(const std::string &s) const
Definition: Any.cpp:115
const std::string & name() const
Definition: Any.cpp:562

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool G3D::Any::nameEquals ( const char *  s) const

If this is named ARRAY or TABLE, returns true if the name iss. The comparision is case insensitive.

143  {
145 #ifdef G3D_WINDOWS
146  return stricmp(name().c_str(), s) == 0;
147 #else
148  return strcasecmp(name().c_str(), s) == 0;
149 #endif
150 
151 }
Definition: Any.h:187
Definition: Any.h:187
void verifyType(Type t) const
Definition: Any.cpp:1739
const std::string & name() const
Definition: Any.cpp:562
#define stricmp
Definition: FileSystem.cpp:39

+ Here is the call graph for this function:

Any & G3D::Any::next ( )

for an ARRAY, resizes and returns the last element

641  {
642  beforeRead();
643  verifyType(ARRAY);
644  int n = size();
645  resize(n + 1);
646  return (*this)[n];
647 }
void resize(int n)
Definition: Any.cpp:602
Definition: Any.h:187
void verifyType(Type t) const
Definition: Any.cpp:1739
void beforeRead() const
Definition: Any.cpp:154
int size() const
Definition: Any.cpp:580

+ Here is the call graph for this function:

double G3D::Any::number ( ) const

Throws a ParseError exception if this is not a number

535  {
536  beforeRead();
538  return m_simpleValue.n;
539 }
SimpleValue m_simpleValue
Definition: Any.h:307
void verifyType(Type t) const
Definition: Any.cpp:1739
double n
Definition: Any.h:218
void beforeRead() const
Definition: Any.cpp:154
Definition: Any.h:187

+ Here is the call graph for this function:

G3D::Any::operator bool ( ) const
1582  {
1583  beforeRead();
1584  return boolean();
1585 }
void beforeRead() const
Definition: Any.cpp:154
bool boolean() const
Definition: Any.cpp:555
G3D::Any::operator char ( ) const
inline
707  {
708  return char(int(*this));
709  }
G3D::Any::operator double ( ) const
1576  {
1577  beforeRead();
1578  return number();
1579 }
double number() const
Definition: Any.cpp:535
void beforeRead() const
Definition: Any.cpp:154
G3D::Any::operator float ( ) const
1570  {
1571  beforeRead();
1572  return float(number());
1573 }
double number() const
Definition: Any.cpp:535
void beforeRead() const
Definition: Any.cpp:154
G3D::Any::operator int ( ) const
1558  {
1559  beforeRead();
1560  return iRound(number());
1561 }
int iRound(double fValue)
Definition: g3dmath.h:226
double number() const
Definition: Any.cpp:535
void beforeRead() const
Definition: Any.cpp:154

+ Here is the call graph for this function:

G3D::Any::operator int16 ( ) const
inline
715  {
716  return int16(int(*this));
717  }
int16_t int16
Definition: g3dmath.h:165
G3D::Any::operator std::string ( ) const
1588  {
1589  beforeRead();
1590  return string();
1591 }
const std::string & string() const
Definition: Any.cpp:548
void beforeRead() const
Definition: Any.cpp:154
G3D::Any::operator uint16 ( ) const
inline
719  {
720  return uint16(int(*this));
721  }
uint16_t uint16
Definition: g3dmath.h:166
G3D::Any::operator uint32 ( ) const
1564  {
1565  beforeRead();
1566  return uint32(number() + 0.5);
1567 }
double number() const
Definition: Any.cpp:535
void beforeRead() const
Definition: Any.cpp:154
uint32_t uint32
Definition: g3dmath.h:168
G3D::Any::operator uint8 ( ) const
inline
711  {
712  return uint8(int(*this));
713  }
uint8_t uint8
Definition: g3dmath.h:164
bool G3D::Any::operator!= ( const Any x) const
857  {
858  return ! operator==(x);
859 }
bool operator==(const Any &x) const
Definition: Any.cpp:782
G3D::int16 x
Definition: Vector2int16.h:37

+ Here is the call graph for this function:

bool G3D::Any::operator!= ( const std::string &  s) const
inline
684  {
685  return *this != Any(s);
686  }
Any()
Definition: Any.cpp:347

+ Here is the call graph for this function:

bool G3D::Any::operator!= ( const double &  v) const
inline
688  {
689  return *this != Any(v);
690  }
Any()
Definition: Any.cpp:347

+ Here is the call graph for this function:

bool G3D::Any::operator!= ( int  v) const
inline
692  {
693  return *this != Any(v);
694  }
Any()
Definition: Any.cpp:347

+ Here is the call graph for this function:

bool G3D::Any::operator!= ( bool  v) const
inline
696  {
697  return *this != Any(v);
698  }
Any()
Definition: Any.cpp:347

+ Here is the call graph for this function:

Any & G3D::Any::operator= ( const Any x)

Removes the comment and name

462  {
463  x.beforeRead();
464 
465  if (this == &x) {
466  return *this;
467  }
468 
469  beforeWrite();
470 
471  dropReference();
472 
473  m_type = x.m_type;
474  m_simpleValue = x.m_simpleValue;
475 
476  if (x.m_data != NULL) {
477  x.m_data->referenceCount.increment();
478  m_data = x.m_data;
479  }
480 
481  return *this;
482 }
SimpleValue m_simpleValue
Definition: Any.h:307
arena_t NULL
Definition: jemalloc_internal.h:624
void dropReference()
Definition: Any.cpp:327
void beforeWrite()
Definition: Any.cpp:448
Type m_type
Definition: Any.h:306
Data * m_data
Definition: Any.h:308
G3D::int16 x
Definition: Vector2int16.h:37

+ Here is the call graph for this function:

Any & G3D::Any::operator= ( Type  t)

t must be ARRAY, TABLE, or NIL. Removes the comment and name

485  {
486  switch (t) {
487  case NIL:
488  *this = Any();
489  break;
490 
491  case TABLE: // All 3 cases intentionally fall through
492  case ARRAY:
493  case EMPTY_CONTAINER:
494  *this = Any(t);
495  break;
496 
497  default:
498  alwaysAssertM(false, "Can only assign NIL, TABLE, or ARRAY Type enum.");
499  }
500 
501  return *this;
502 }
Definition: Any.h:187
Any()
Definition: Any.cpp:347
Definition: Any.h:187
Definition: Any.h:187
Definition: Any.h:187
#define alwaysAssertM(exp, message)
Definition: debugAssert.h:165

+ Here is the call graph for this function:

template<class T >
Any& G3D::Any::operator= ( const Array< T > &  array)
inline

Assigns from an array. Assumes that T can be converted to Any. Removes the comment and name

457  {
458  *this = Any::ARRAY;
459  resize(array.size());
460  for (int i = 0; i < array.size(); ++i) {
461  this->operator [](i) = array[i];
462  }
463  return *this;
464  }
void resize(int n)
Definition: Any.cpp:602
Definition: Any.h:187
int size() const
Definition: Array.h:430
const Any & operator[](int i) const
Definition: Any.cpp:629

+ Here is the call graph for this function:

template<class T >
Any& G3D::Any::operator= ( const T &  v)
inline

Removes the comment and name

468  {
469  *this = Any(v);
470  return *this;
471  }
Any()
Definition: Any.cpp:347

+ Here is the call graph for this function:

bool G3D::Any::operator== ( const Any x) const

True if the Anys are exactly equal, ignoring comments. Applies deeply on arrays and tables.

782  {
783  beforeRead();
784  x.beforeRead();
785 
786  if (m_type != x.m_type) {
787  return false;
788  }
789 
790  switch (m_type) {
791  case NIL:
792  return true;
793 
794  case BOOLEAN:
795  return (m_simpleValue.b == x.m_simpleValue.b);
796 
797  case NUMBER:
798  return (m_simpleValue.n == x.m_simpleValue.n);
799 
800  case STRING:
801  debugAssert(m_data != NULL);
802  return (*(m_data->value.s) == *(x.m_data->value.s));
803 
804  case TABLE: {
805  if (size() != x.size()) {
806  return false;
807  }
808  debugAssert(m_data != NULL);
809  if (m_data->name != x.m_data->name) {
810  return false;
811  }
812  const Table<std::string, Any>& table1 = table();
813  const Table<std::string, Any>& table2 = x.table();
814  for (Table<std::string, Any>::Iterator it = table1.begin(); it.isValid(); ++it) {
815  const Any* p2 = table2.getPointer(it->key);
816  if (p2 == NULL) {
817  // Key not found
818  return false;
819  } else if (*p2 != it->value) {
820  // Different value
821  return false;
822  }
823  }
824  return true;
825  }
826 
827  case ARRAY: {
828  if (size() != x.size()) {
829  return false;
830  }
831  debugAssert(m_data != NULL);
832  if (m_data->name != x.m_data->name) {
833  return false;
834  }
835 
836  Array<Any>& cmparray = *( m_data->value.a);
837  Array<Any>& xcmparray = *(x.m_data->value.a);
838 
839  for (int ii = 0; ii < size(); ++ii) {
840  if (cmparray[ii] != xcmparray[ii]) {
841  return false;
842  }
843  }
844  return true;
845  }
846 
847  case EMPTY_CONTAINER:
848  return true;
849  default:
850  alwaysAssertM(false, "Unknown type.");
851  return false;
852  }
853 
854 }
Definition: Any.h:187
Value value
Definition: Any.h:246
Any()
Definition: Any.cpp:347
std::string name
Definition: Any.h:250
const Table< std::string, Any > & table() const
Definition: Any.cpp:706
SimpleValue m_simpleValue
Definition: Any.h:307
arena_t NULL
Definition: jemalloc_internal.h:624
Definition: Any.h:187
Definition: Any.h:187
Type m_type
Definition: Any.h:306
double n
Definition: Any.h:218
#define debugAssert(exp)
Definition: debugAssert.h:160
Array< Any > * a
Definition: Any.h:235
Data * m_data
Definition: Any.h:308
void beforeRead() const
Definition: Any.cpp:154
Definition: Any.h:187
bool b
Definition: Any.h:217
std::string * s
Definition: Any.h:234
int size() const
Definition: Any.cpp:580
Definition: Any.h:187
Definition: Any.h:187
G3D::int16 x
Definition: Vector2int16.h:37
#define alwaysAssertM(exp, message)
Definition: debugAssert.h:165
Definition: Any.h:187

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool G3D::Any::operator== ( const std::string &  s) const
inline
666  {
667  return *this == Any(s);
668  }
Any()
Definition: Any.cpp:347

+ Here is the call graph for this function:

bool G3D::Any::operator== ( const double &  v) const
inline
670  {
671  return *this == Any(v);
672  }
Any()
Definition: Any.cpp:347

+ Here is the call graph for this function:

bool G3D::Any::operator== ( int  v) const
inline
674  {
675  return *this == Any(v);
676  }
Any()
Definition: Any.cpp:347

+ Here is the call graph for this function:

bool G3D::Any::operator== ( bool  v) const
inline
678  {
679  return *this == Any(v);
680  }
Any()
Definition: Any.cpp:347

+ Here is the call graph for this function:

const Any & G3D::Any::operator[] ( int  i) const

For an array, returns the ith element

629  {
630  beforeRead();
631  verifyType(ARRAY);
632  debugAssert(m_data != NULL);
633  Array<Any>& array = *(m_data->value.a);
634  if (i < 0 || i >= array.size()) {
635  throw IndexOutOfBounds(m_data, i, array.size());
636  }
637  return array[i];
638 }
Value value
Definition: Any.h:246
arena_t NULL
Definition: jemalloc_internal.h:624
Definition: Any.h:187
void verifyType(Type t) const
Definition: Any.cpp:1739
#define debugAssert(exp)
Definition: debugAssert.h:160
Array< Any > * a
Definition: Any.h:235
Data * m_data
Definition: Any.h:308
void beforeRead() const
Definition: Any.cpp:154
const Array< Any > & array() const
Definition: Any.cpp:663

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Any & G3D::Any::operator[] ( int  i)
650  {
651  beforeRead();
652  ensureMutable();
653  verifyType(ARRAY);
654  debugAssert(m_data != NULL);
655  Array<Any>& array = *(m_data->value.a);
656  if (i < 0 || i >= array.size()) {
657  throw IndexOutOfBounds(m_data, i, array.size());
658  }
659  return array[i];
660 }
Value value
Definition: Any.h:246
arena_t NULL
Definition: jemalloc_internal.h:624
Definition: Any.h:187
void verifyType(Type t) const
Definition: Any.cpp:1739
#define debugAssert(exp)
Definition: debugAssert.h:160
Array< Any > * a
Definition: Any.h:235
Data * m_data
Definition: Any.h:308
void beforeRead() const
Definition: Any.cpp:154
const Array< Any > & array() const
Definition: Any.cpp:663
void ensureMutable()
Definition: Any.cpp:336

+ Here is the call graph for this function:

const Any & G3D::Any::operator[] ( const std::string &  key) const

For a table, returns the element for key. Throws KeyNotFound exception if the element does not exist.

720  {
721  beforeRead();
722  verifyType(TABLE);
723  debugAssert(m_data != NULL);
724  const Table<std::string, Any>& table = *(m_data->value.t);
725  Any* value = table.getPointer(x);
726  if (value == NULL) {
727  KeyNotFound e(m_data);
728  e.key = x;
729  e.message = "Key not found in operator[] lookup.";
730  throw e;
731  }
732  return *value;
733 }
Definition: Any.h:187
Value value
Definition: Any.h:246
Any()
Definition: Any.cpp:347
const Table< std::string, Any > & table() const
Definition: Any.cpp:706
arena_t NULL
Definition: jemalloc_internal.h:624
AnyTable * t
Definition: Any.h:236
void verifyType(Type t) const
Definition: Any.cpp:1739
#define debugAssert(exp)
Definition: debugAssert.h:160
Data * m_data
Definition: Any.h:308
void beforeRead() const
Definition: Any.cpp:154
const FieldDescriptor value
Definition: descriptor.h:1522
G3D::int16 x
Definition: Vector2int16.h:37

+ Here is the call graph for this function:

const Any& G3D::Any::operator[] ( const char *  key) const
inline
605  {
606  return operator[](std::string(key));
607  }
const Any & operator[](int i) const
Definition: Any.cpp:629

+ Here is the call graph for this function:

Any & G3D::Any::operator[] ( const std::string &  key)

Fetch an element from a table. This can be used as:

a["key"] = value;  (create the key if it did not exist)

or

value = a["key"];  (throw an error if the key did not exist)

Note: In order to cause elements to be correctly created in the first case while still providing "key not found" errors in the second case, the Any returned is a special object that delays the actual fetch until the following assignment or method call. This means that in the event of an error, the exception may be thrown from a line other than the actual fetch. Use the Any::get() or the const Any::operator[]() methods to avoid this behavior and ensure error-checking at fetch time.

736  {
737  beforeRead();
738  ensureMutable();
739  verifyType(TABLE);
740 
741  bool created = false;
742  Any& value = m_data->value.t->getCreate(key, created);
743 
744  if (created) {
745  // The entry was created by this method; do not allow it to be
746  // read before it is written.
747  value.m_placeholderName = key;
748 
749  // Write source data for the value
750  value.ensureData();
751  value.m_data->source = source();
752  }
753 
754  return value;
755 }
Definition: Any.h:187
Value value
Definition: Any.h:246
Any()
Definition: Any.cpp:347
AnyTable * t
Definition: Any.h:236
void verifyType(Type t) const
Definition: Any.cpp:1739
Data * m_data
Definition: Any.h:308
void beforeRead() const
Definition: Any.cpp:154
Value & getCreate(const Key &key)
Definition: Table.h:861
const FieldDescriptor value
Definition: descriptor.h:1522
void ensureMutable()
Definition: Any.cpp:336
const Source & source() const
Definition: Any.cpp:1594

+ Here is the call graph for this function:

Any& G3D::Any::operator[] ( const char *  key)
inline

Fetch an element from a table. This can be used as:

a["key"] = value;  (create the key if it did not exist)

or

value = a["key"];  (throw an error if the key did not exist)

Note: In order to cause elements to be correctly created in the first case while still providing "key not found" errors in the second case, the Any returned is a special object that delays the actual fetch until the following assignment or method call. This means that in the event of an error, the exception may be thrown from a line other than the actual fetch. Use the Any::get() or the const Any::operator[]() methods to avoid this behavior and ensure error-checking at fetch time.

635  {
636  return operator[](std::string(key));
637  }
const Any & operator[](int i) const
Definition: Any.cpp:629

+ Here is the call graph for this function:

Any G3D::Any::parse ( const std::string &  src)
static

Same as deserialize or load, but operates on a string instead of a stream or file.

See also
deserialize, load, unparse
889  {
890  Any a;
891  a._parse(src);
892  return a;
893 }
Any()
Definition: Any.cpp:347

+ Here is the call graph for this function:

void G3D::Any::readUntilSeparatorOrClose ( TextInput ti,
Token token 
)
staticprivate

Read until a separator is consumed or a close paren is hit, and return that token. Considers the passed in token to be the first value read.

1393  {
1394  bool atClose = (token.type() == Token::SYMBOL) && isClose(token.string()[0]);
1395  bool atSeparator = isSeparator(token.string()[0]);
1396 
1397  while (! (atClose || atSeparator)) {
1398  switch (token.type()) {
1399  case Token::NEWLINE:
1400  case Token::COMMENT:
1401  // Consume
1402  token = ti.read();
1403  break;
1404 
1405  default:
1406  throw ParseError(ti.filename(), token.line(), token.character(),
1407  "Expected a comma or close paren");
1408  }
1409 
1410  // Update checks
1411  atSeparator = isSeparator(token.string()[0]);
1412  atClose = (token.type() == Token::SYMBOL) && isClose(token.string()[0]);
1413  }
1414 }
Definition: TextInput.h:61
Definition: TextInput.h:62
Definition: TextInput.h:58
static bool isClose(const char c)
Definition: Any.cpp:1201
static bool isSeparator(char c)
Definition: Any.cpp:1388
static bool atClose(TextInput &t, const std::string name)
Definition: XML.cpp:98

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::Any::remove ( const std::string &  key)

Removes this key from the Any, which must be a table.

82  {
84  ensureMutable();
85  m_data->value.t->remove(key);
86 }
Definition: Any.h:187
Value value
Definition: Any.h:246
AnyTable * t
Definition: Any.h:236
void verifyType(Type t) const
Definition: Any.cpp:1739
bool remove(const Key &key, Key &removedKey, Value &removedValue, bool updateRemoved)
Definition: Table.h:606
Data * m_data
Definition: Any.h:308
void ensureMutable()
Definition: Any.cpp:336

+ Here is the call graph for this function:

void G3D::Any::remove ( int  index)

Removes this key from the Any, which must be an array, and shifts other elements down to maintain order.

89  {
91  ensureMutable();
92  m_data->value.a->remove(i);
93 }
Value value
Definition: Any.h:246
Definition: Any.h:187
void verifyType(Type t) const
Definition: Any.cpp:1739
Array< Any > * a
Definition: Any.h:235
Data * m_data
Definition: Any.h:308
void ensureMutable()
Definition: Any.cpp:336

+ Here is the call graph for this function:

void G3D::Any::resize ( int  n)

Resize to n elements, where new elements are NIL It is an error to call this method if this is not an Any::ARRAY

602  {
603  beforeRead();
604  alwaysAssertM(n >= 0, "Cannot resize less than 0.");
605  verifyType(ARRAY);
606  if (type() == EMPTY_CONTAINER) {
607  become(ARRAY);
608  }
609  m_data->value.a->resize(n);
610 }
Type type() const
Definition: Any.cpp:505
Value value
Definition: Any.h:246
Definition: Any.h:187
void verifyType(Type t) const
Definition: Any.cpp:1739
Array< Any > * a
Definition: Any.h:235
Data * m_data
Definition: Any.h:308
void beforeRead() const
Definition: Any.cpp:154
Definition: Any.h:187
void become(const Type &t)
Definition: Any.cpp:68
#define alwaysAssertM(exp, message)
Definition: debugAssert.h:165

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::string G3D::Any::resolveStringAsFilename ( bool  errorIfNotFound = true) const

If a valid string, takes the string value and creates a fully qualified filename.

The file is searched for the following ways:

  • In the directory from which the Any was loaded.
  • By calling System::findDataFile as you would with other data files.

Strings that begin with '<' and end with '>' are treated as escape sequences and are returned unmodifed.

49  {
51  if ((string().length() > 0) && (string()[0] == '<') && (string()[string().length() - 1] == '>')) {
52  return string();
53  }
54 
55  const std::string& f = FileSystem::resolve(string(), sourceDirectory());
56  if (FileSystem::exists(f)) {
57  return f;
58  } else {
59  const std::string& s = System::findDataFile(string(), errorIfNotFound);
60  if (s.empty()) {
61  return string();
62  } else {
63  return s;
64  }
65  }
66 }
const std::string & string() const
Definition: Any.cpp:548
std::string sourceDirectory() const
Definition: Any.cpp:1604
static bool exists(const std::string &f, bool trustCache=true, bool caseSensitive=true)
Definition: FileSystem.h:401
void verifyType(Type t) const
Definition: Any.cpp:1739
static std::string findDataFile(const std::string &full, bool exceptionIfNotFound=true, bool caseSensitive=true)
Definition: System.cpp:365
static std::string resolve(const std::string &path, const std::string &cwd=currentDirectory())
Definition: FileSystem.h:440
int length() const
Definition: Any.cpp:596
Definition: Any.h:187

+ Here is the call graph for this function:

void G3D::Any::save ( const std::string &  filename) const

Uses the serialize method.

916  {
917  beforeRead();
918  TextOutput::Settings settings;
919  settings.wordWrap = TextOutput::Settings::WRAP_NONE;
920 
921  TextOutput to(filename,settings);
922  serialize(to);
923  to.commit();
924 }
void serialize(TextOutput &to, bool json=false, bool coerce=false) const
Definition: Any.cpp:956
void beforeRead() const
Definition: Any.cpp:154
Definition: TextOutput.h:75

+ Here is the call graph for this function:

void G3D::Any::serialize ( TextOutput to,
bool  json = false,
bool  coerce = false 
) const
956  {
957  beforeRead();
958 
959  if (m_data && ! m_data->includeLine.empty()) {
960  if (json) {
961  if (! coerce) {
962  throw "Could not coerce to JSON";
963  }
964 
965  // Silently fall through
966  } else {
967  // This value came from a #include...preserve it. This includes the comment
968  // if any.
969  to.printf("%s", m_data->includeLine.c_str());
970  return;
971  }
972  }
973 
974  if (m_data && ! m_data->comment.empty()) {
975  if (json) {
976  if (! coerce) {
977  throw "Could not coerce to JSON";
978  }
979  } else {
980  to.printf("\n/* %s */\n", m_data->comment.c_str());
981  }
982  }
983 
984  switch (m_type) {
985  case NIL:
986  if (json) {
987  to.writeSymbol("null");
988  } else {
989  to.writeSymbol("NIL");
990  }
991  break;
992 
993  case BOOLEAN:
994  to.writeBoolean(m_simpleValue.b);
995  break;
996 
997  case NUMBER:
998  if (json) {
999  // Specials have no legal syntax in JSON, so insert values that will parse
1000  // to something close to what we want (there is no good solution for NaN, unfortunately)
1001  if (m_simpleValue.n == inf()) {
1002  to.writeSymbol("1e10000");
1003  } else if (m_simpleValue.n == -inf()) {
1004  to.writeSymbol("-1e10000");
1005  } else if (isNaN(m_simpleValue.n)) {
1006  if (! coerce) {
1007  throw "There is no way to represent NaN in JSON";
1008  }
1009  to.writeSymbol("null");
1010  } else {
1011  to.writeNumber(m_simpleValue.n);
1012  }
1013  } else {
1014  to.writeNumber(m_simpleValue.n);
1015  }
1016  break;
1017 
1018  case STRING:
1019  debugAssert(m_data != NULL);
1020  to.writeString(*(m_data->value.s));
1021  break;
1022 
1023  case TABLE: {
1024  debugAssert(m_data != NULL);
1025  debugAssert(m_data->separator != '\0');
1026 
1027  if (! m_data->name.empty()) {
1028  if (json) {
1029  if (! coerce) {
1030  throw "Could not coerce to JSON";
1031  }
1032  } else {
1033  if (needsQuotes(m_data->name)) {
1034  to.writeString(m_data->name);
1035  } else {
1036  to.writeSymbol(m_data->name);
1037  }
1038  }
1039  }
1040  if (json) {
1041  to.writeSymbol("{");
1042  } else {
1043  to.writeSymbol(m_data->bracket[0]);
1044  }
1045  to.writeNewline();
1046  to.pushIndent();
1047  AnyTable& table = *(m_data->value.t);
1048  Array<std::string> keys;
1049  table.getKeys(keys);
1050  keys.sort();
1051 
1052  for (int i = 0; i < keys.size(); ++i) {
1053 
1054  int prevLine = to.line();
1055  if (needsQuotes(keys[i]) || json) {
1056  to.writeString(keys[i]);
1057  } else {
1058  to.writeSymbol(keys[i]);
1059  }
1060 
1061  if (json) {
1062  to.writeSymbol(":");
1063  } else {
1064  to.writeSymbol("=");
1065  }
1066  table[keys[i]].serialize(to, json, coerce);
1067 
1068  to.deleteSpace();
1069  if (json) {
1070  // Don't put a separator after the last
1071  if (i != keys.size() - 1) {
1072  to.writeSymbol(",");
1073  }
1074  } else {
1075  to.writeSymbol(m_data->separator);
1076  }
1077 
1078  // Skip an extra line between table entries that are longer than a line
1079  if (prevLine != to.line()) {
1080  to.writeNewline();
1081  }
1082 
1083  to.writeNewline();
1084  }
1085 
1086  to.popIndent();
1087  to.writeSymbol(m_data->bracket[1]);
1088  break;
1089  }
1090 
1091  case ARRAY: {
1092  debugAssert(m_data != NULL);
1093  debugAssert(m_data->separator != '\0');
1094 
1095  if (! m_data->name.empty()) {
1096  if (json) {
1097  if (! coerce) {
1098  throw "Could not coerce to JSON";
1099  }
1100  to.writeSymbol("[");
1101  } else {
1102  // For arrays, leave no trailing space between the name and the paren
1103  to.printf("%s%c", m_data->name.c_str(), m_data->bracket[0]);
1104  }
1105  } else {
1106  if (json) {
1107  to.writeSymbol("[");
1108  } else {
1109  to.writeSymbol(m_data->bracket[0]);
1110  }
1111  }
1112  const Array<Any>& array = *(m_data->value.a);
1113  const bool longForm = (array.size() > 0) && ((array[0].type() == ARRAY) || (array[0].type() == TABLE));
1114 
1115  if (longForm) {
1116  to.writeNewline();
1117  }
1118 
1119  to.pushIndent();
1120  for (int ii = 0; ii < size(); ++ii) {
1121  array[ii].serialize(to, json, coerce);
1122  if (ii < size() - 1) {
1123  to.deleteSpace();
1124  if (longForm) {
1125  // Probably a long-form array
1126  if (json) {
1127  to.writeSymbol(",");
1128  } else {
1129  to.writeSymbol(m_data->separator);
1130  }
1131  to.writeNewline();
1132  } else {
1133  // Probably a short-form array
1134  if (json) {
1135  to.writeSymbol(",");
1136  } else {
1137  to.writeSymbol(m_data->separator);
1138  }
1139  }
1140  }
1141 
1142  // Put the close paren on an array right behind the last element
1143  }
1144  to.popIndent();
1145  if (json) {
1146  to.writeSymbol("]");
1147  } else {
1148  to.writeSymbol(m_data->bracket[1]);
1149  }
1150  break;
1151  }
1152 
1153  case EMPTY_CONTAINER: {
1154  debugAssert(m_data != NULL);
1155  debugAssert(m_data->separator != '\0');
1156 
1157  if (json) {
1158  if (! coerce) {
1159  throw "Cannot strictly convert the ambiguous Any empty container to JSON";
1160  }
1161  to.writeSymbols("[", "]");
1162  } else {
1163  if (! m_data->name.empty()) {
1164  // Leave no trailing space between the name and the paren
1165  to.printf("%s%c", m_data->name.c_str(), m_data->bracket[0]);
1166  } else {
1167  to.writeSymbol(m_data->bracket[0]);
1168  }
1169  to.writeSymbol(m_data->bracket[1]);
1170  }
1171  break;
1172  }
1173  }
1174 
1175 }
Type type() const
Definition: Any.cpp:505
Definition: Any.h:187
const char * bracket
Definition: Any.h:272
Value value
Definition: Any.h:246
std::string name
Definition: Any.h:250
const Table< std::string, Any > & table() const
Definition: Any.cpp:706
SimpleValue m_simpleValue
Definition: Any.h:307
bool isNaN(double x)
Definition: g3dmath.cpp:56
arena_t NULL
Definition: jemalloc_internal.h:624
Definition: Any.h:187
AnyTable * t
Definition: Any.h:236
Table< std::string, Any > AnyTable
Definition: Any.h:208
Definition: Any.h:187
double inf()
Definition: g3dmath.cpp:40
Type m_type
Definition: Any.h:306
double n
Definition: Any.h:218
#define debugAssert(exp)
Definition: debugAssert.h:160
std::string comment
Definition: Any.h:248
Array< Any > * a
Definition: Any.h:235
Data * m_data
Definition: Any.h:308
void beforeRead() const
Definition: Any.cpp:154
char separator
Definition: Any.h:275
Definition: Any.h:187
bool b
Definition: Any.h:217
static bool needsQuotes(const std::string &s)
Definition: Any.cpp:927
std::string * s
Definition: Any.h:234
int size() const
Definition: Any.cpp:580
Definition: Any.h:187
Definition: Any.h:187
const Array< Any > & array() const
Definition: Any.cpp:663
std::string includeLine
Definition: Any.h:260
Definition: Any.h:187

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::Any::serialize ( class BinaryOutput b) const
34  {
35  TextOutput::Settings s;
37  b.writeInt32(1);
38  b.writeString32(unparse(s));
39 }
std::string unparse(const TextOutput::Settings &s=TextOutput::Settings()) const
Definition: Any.cpp:881
Definition: TextOutput.h:75

+ Here is the call graph for this function:

template<class T >
void G3D::Any::set ( const std::string &  key,
const T &  val 
)
inline

For a table, assigns the element for key k.

651  {
652  _set(key, Any(val));
653  }
void _set(const std::string &key, const Any &val)
Definition: Any.cpp:758
Any()
Definition: Any.cpp:347

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::Any::setComment ( const std::string &  c)
523  {
524  beforeRead();
525  ensureData();
526  m_data->comment = c;
527 }
void ensureData()
Definition: Any.cpp:1381
std::string comment
Definition: Any.h:248
Data * m_data
Definition: Any.h:308
void beforeRead() const
Definition: Any.cpp:154

+ Here is the call graph for this function:

void G3D::Any::setName ( const std::string &  name)

Set the name used when serializing an ARRAY or TABLE.

Only legal for ARRAY or TABLE. The name must begin with a letter and contain only letters, numbers, underscores and scope operators.

 a2z
 hello
 Foo::bar
 color.red
 this->that
 __x
 

The scope operators "::", "->", and ".", may have spaces around them. The name may not contain parentheses.

573  {
574  beforeRead();
575  ensureData();
576  m_data->name = n;
577 }
std::string name
Definition: Any.h:250
void ensureData()
Definition: Any.cpp:1381
Data * m_data
Definition: Any.h:308
void beforeRead() const
Definition: Any.cpp:154

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int G3D::Any::size ( ) const

Number of elements if this is an ARRAY or TABLE

580  {
581  beforeRead();
583  switch (m_type) {
584  case TABLE:
585  return (int)m_data->value.t->size();
586 
587  case ARRAY:
588  return m_data->value.a->size();
589 
590  default:
591  return 0;
592  }
593 }
Definition: Any.h:187
Value value
Definition: Any.h:246
size_t size() const
Definition: Table.h:589
Definition: Any.h:187
AnyTable * t
Definition: Any.h:236
void verifyType(Type t) const
Definition: Any.cpp:1739
Type m_type
Definition: Any.h:306
Array< Any > * a
Definition: Any.h:235
Data * m_data
Definition: Any.h:308
void beforeRead() const
Definition: Any.cpp:154

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

const Any::Source & G3D::Any::source ( ) const
1594  {
1595  static Source s;
1596  if (m_data) {
1597  return m_data->source;
1598  } else {
1599  return s;
1600  }
1601 }
Source source
Definition: Any.h:269
Data * m_data
Definition: Any.h:308

+ Here is the caller graph for this function:

std::string G3D::Any::sourceDirectory ( ) const

The parent directory of the location from which this Any was loaded. This is useful for interpreting filenames relative to the Any's source location, which may not match the current directory if the Any was from an included file.

1604  {
1605  if (m_data) {
1607  } else {
1608  return "";
1609  }
1610 }
Source source
Definition: Any.h:269
std::string filename
Definition: Any.h:194
static std::string parent(const std::string &path)
Definition: FileSystem.cpp:795
Data * m_data
Definition: Any.h:308

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

const std::string & G3D::Any::string ( ) const
548  {
549  beforeRead();
551  return *(m_data->value.s);
552 }
Value value
Definition: Any.h:246
void verifyType(Type t) const
Definition: Any.cpp:1739
Data * m_data
Definition: Any.h:308
void beforeRead() const
Definition: Any.cpp:154
std::string * s
Definition: Any.h:234
Definition: Any.h:187

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

const Table< std::string, Any > & G3D::Any::table ( ) const

Directly exposes the underlying data structure for table.

See also
G3D::AnyTableReader
706  {
707  beforeRead();
708  verifyType(TABLE);
709  debugAssert(m_data != NULL);
710 
711  if (type() == Any::EMPTY_CONTAINER) {
712  // if empty, m_data->value.t will not be initialized as it is unknown whether this is supposed to be an array or a table
713  static const Table<std::string, Any> emptyTable;
714  return emptyTable;
715  }
716  return *(m_data->value.t);
717 }
Type type() const
Definition: Any.cpp:505
Definition: Any.h:187
Value value
Definition: Any.h:246
arena_t NULL
Definition: jemalloc_internal.h:624
AnyTable * t
Definition: Any.h:236
void verifyType(Type t) const
Definition: Any.cpp:1739
#define debugAssert(exp)
Definition: debugAssert.h:160
Data * m_data
Definition: Any.h:308
void beforeRead() const
Definition: Any.cpp:154
Definition: Any.h:187

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::string G3D::Any::toString ( Type  t)
static
1774  {
1775  switch(t) {
1776  case NIL: return "NIL";
1777  case BOOLEAN: return "BOOLEAN";
1778  case NUMBER: return "NUMBER";
1779  case STRING: return "STRING";
1780  case ARRAY: return "ARRAY";
1781  case TABLE: return "TABLE";
1782  default:
1783  alwaysAssertM(false, "Illegal Any::Type");
1784  return "";
1785  }
1786 }
Definition: Any.h:187
Definition: Any.h:187
Definition: Any.h:187
Definition: Any.h:187
Definition: Any.h:187
#define alwaysAssertM(exp, message)
Definition: debugAssert.h:165
Definition: Any.h:187

+ Here is the caller graph for this function:

Any::Type G3D::Any::type ( ) const
505  {
506  beforeRead();
507  return m_type;
508 }
Type m_type
Definition: Any.h:306
void beforeRead() const
Definition: Any.cpp:154

+ Here is the call graph for this function:

+ Here is the caller graph for this function: