first commit
This commit is contained in:
224
include/framework/metafile/nml.h
Normal file
224
include/framework/metafile/nml.h
Normal file
@ -0,0 +1,224 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __NMETALANG__
|
||||
#define __NMETALANG__
|
||||
|
||||
|
||||
#include "data/nvariant.h"
|
||||
#include "container/nlist.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
namespace IO { class Handle; }
|
||||
|
||||
namespace NML {
|
||||
class Tag;
|
||||
class File;
|
||||
|
||||
static const int version = 1;
|
||||
|
||||
/// Metatag.
|
||||
class Tag
|
||||
{
|
||||
friend struct Parser;
|
||||
friend class File;
|
||||
|
||||
protected:
|
||||
|
||||
/// Locate a tag through its path.
|
||||
static Tag *GetTagEx(const List <Tag *> &tag, const char *path, const File *root = 0, bool verbose = false);
|
||||
|
||||
List <Tag *> tags;
|
||||
|
||||
Variant value;
|
||||
|
||||
public:
|
||||
|
||||
NPLACEMENT_NEW(Metatag)
|
||||
|
||||
String name;
|
||||
|
||||
/// Get this tag parent by exploring a given tag hierarchy.
|
||||
Tag *GetParent(Tag *) const;
|
||||
|
||||
/// Get value.
|
||||
Variant &GetValue() { return value; }
|
||||
const Variant &GetValue() const { return value; }
|
||||
|
||||
/// Remove a child tag from this tag.
|
||||
bool RemoveTag(Tag *t) { return tags.Remove(t); }
|
||||
/// Delete all child tags.
|
||||
uint DeleteChildren(const char *filter = 0);
|
||||
/// Get child count.
|
||||
uint GetChildCount() const { return tags.GetCount(); }
|
||||
/// Return the tag children list.
|
||||
const List <Tag *> &GetTags() const { return tags; }
|
||||
|
||||
/// Add child to tag.
|
||||
Tag *AddChild(Tag *);
|
||||
Tag *AddChild(const char *);
|
||||
Tag *AddChild(const char *, bool);
|
||||
Tag *AddChild(const char *, int);
|
||||
Tag *AddChild(const char *, uint);
|
||||
Tag *AddChild(const char *, float);
|
||||
Tag *AddChild(const char *, const char *);
|
||||
Tag *AddChild(const char *, void *, size_t);
|
||||
|
||||
/// Return tag child.
|
||||
Tag *GetTag(const char *path, const File * = 0, bool verbose = false) const;
|
||||
/// Return the tag at a given path only if it matches the required type.
|
||||
Tag *GetTypedTag(const char *path, Variant::Type, const File * = 0, bool verbose = false) const;
|
||||
|
||||
bool GetBool() const { bool v; if (value.Get(v)) return v; return false; }
|
||||
int GetInteger() const { return value.i_value; }
|
||||
uint GetUnsigned() const { return value.u_value; }
|
||||
const char *GetString() const { return value.s_value; }
|
||||
float GetReal() const { return value.f_value; }
|
||||
|
||||
void SetBool(bool v) { value = v; }
|
||||
void SetInteger(int v) { value = v; }
|
||||
void SetUnsigned(uint v) { value = v; }
|
||||
void SetString(const char *v) { value = v; }
|
||||
void SetReal(float v) { value = v; }
|
||||
|
||||
Variant::Type GetType() const { return value.GetType(); }
|
||||
|
||||
/// Clone a tag and optionally recurse and clone its children.
|
||||
bool Clone(const Tag &src, bool recursive = true);
|
||||
/// Clone this tag and optionally recurse and clone its children.
|
||||
Tag *Clone(bool recursive = true) const;
|
||||
|
||||
/// Free the tag data, set its type to nVariant::VariantNone.
|
||||
void Free();
|
||||
|
||||
Tag() {}
|
||||
Tag(const char *n) : name(n) {}
|
||||
Tag(const char *n, bool v) : name(n), value(v) {}
|
||||
Tag(const char *n, int v) : name(n), value(v) {}
|
||||
Tag(const char *n, uint v) : name(n), value(v) {}
|
||||
Tag(const char *n, float v) : name(n), value(v) {}
|
||||
Tag(const char *n, const char *v) : name(n), value(v) {}
|
||||
Tag(const char *n, void *data, size_t size) : name(n), value(data, size) {}
|
||||
|
||||
~Tag();
|
||||
};
|
||||
|
||||
/*!
|
||||
@short Meta file.
|
||||
|
||||
A metafile contain the whole database in memory.
|
||||
This class is not meant to be used with heavy databases.
|
||||
|
||||
Tags can be accessed using tag paths. A tag path is formatted as follow:
|
||||
"root:node:...:tag;".
|
||||
|
||||
@note The closing hyphen is not required but warnings will be sent to the
|
||||
log if you don't use it. The node delimiter ':' can be repeated any
|
||||
number of time between nodes with no effect (eg: ":::node1::node2:;").
|
||||
By definition a file is a node tag and cannot have a value.
|
||||
|
||||
@author Emmanuel Julien (ejulien@gsworks.fr)
|
||||
*/
|
||||
class File
|
||||
{
|
||||
friend struct Parser;
|
||||
|
||||
public:
|
||||
|
||||
enum Binary
|
||||
{
|
||||
Binary_UU = 0, ///< UUEncoded.
|
||||
Binary_yEnc ///< yEncoded.
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
List <Tag *> tags;
|
||||
Binary binary_method; ///< Binary encoding method.
|
||||
|
||||
public:
|
||||
|
||||
String name;
|
||||
|
||||
/// Get the file ASCII binary encoding method.
|
||||
Binary GetBinaryMethod() const { return binary_method; }
|
||||
|
||||
const List <Tag *> &GetTags() const { return tags; }
|
||||
|
||||
uint GetRootCount() const { return tags.GetCount(); }
|
||||
|
||||
void Clear() { ListDeleteAllPtr(Tag *, tags); }
|
||||
bool isEmpty() const { return asbool(GetRootCount() == 0); }
|
||||
|
||||
/// Add a root tag to the file.
|
||||
Tag *AddRoot(Tag *);
|
||||
Tag *AddRoot(const char *);
|
||||
Tag *AddRoot(const char *, bool);
|
||||
Tag *AddRoot(const char *, int);
|
||||
Tag *AddRoot(const char *, float);
|
||||
Tag *AddRoot(const char *, const char *);
|
||||
Tag *AddRoot(const char *, void *, size_t);
|
||||
|
||||
/// Unlink a root tag from file.
|
||||
bool UnlinkRoot(Tag *);
|
||||
|
||||
/// Return the tag at a given path.
|
||||
Tag *GetTag(const char *path, bool verbose = false) const
|
||||
{ return Tag::GetTagEx(tags, path, this, verbose); }
|
||||
|
||||
/// Return the tag at a given path only if it match the required type.
|
||||
Tag *GetTypedTag(const char *path, Variant::Type, bool verbose = false) const;
|
||||
|
||||
bool GetBool(const char *path, bool _default = false, bool verbose = false) const;
|
||||
int GetInteger(const char *path, int _default = -1, bool verbose = false) const;
|
||||
float GetReal(const char *path, float _default = -1.f, bool verbose = false) const;
|
||||
const char *GetString(const char *path, const char *_default = 0, bool verbose = false) const;
|
||||
|
||||
/// Duplicate the structure of a source file into this file.
|
||||
void Import(const File &, bool clear_before_import = true);
|
||||
/// Clone a file and all its tags.
|
||||
File *Clone() const;
|
||||
|
||||
void Free();
|
||||
|
||||
File() : binary_method(Binary_yEnc) {}
|
||||
~File();
|
||||
};
|
||||
|
||||
/*!
|
||||
@short Meta file parser.
|
||||
@author Emmanuel Julien (ejulien@gsworks.fr)
|
||||
*/
|
||||
struct Parser
|
||||
{
|
||||
static const char *ParseTagPreprocessorDirective(Tag &tag, const char *s, const char *e);
|
||||
|
||||
static bool IsMetafile(const char *);
|
||||
|
||||
static bool SaveBinaryTag(IO::Handle &, const Tag &, File::Binary = File::Binary_yEnc);
|
||||
static bool SaveTag(IO::Handle &, const Tag &, File::Binary = File::Binary_yEnc, uint idt = 0);
|
||||
|
||||
static bool ParseTag(Tag &, const char *s, const char *e, const char **r = 0);
|
||||
|
||||
static bool LoadFromMemory(const char *, size_t, File &);
|
||||
static File *Load(const char *, bool verbose = true);
|
||||
static bool Load(const char *, File &, bool verbose = true);
|
||||
|
||||
static bool Save(IO::Handle &, const File &);
|
||||
static bool Save(const char *, const File &);
|
||||
static bool SaveBinary(IO::Handle &, const File &);
|
||||
static bool SaveBinary(const char *, const File &);
|
||||
};
|
||||
|
||||
#define NMLTagForeach(__I__, __T__) ListForeachPtr(GS::NML::Tag *, __I__, (__T__).GetTags())
|
||||
#define NMLFileForeach(__I__, __F__) ListForeachPtr(GS::NML::Tag *, __I__, (__F__).GetTags())
|
||||
|
||||
} // NML
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __NMETALANG__
|
||||
60
include/framework/metafile/nml_object.h
Normal file
60
include/framework/metafile/nml_object.h
Normal file
@ -0,0 +1,60 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __NMETAOBJECT__
|
||||
#define __NMETAOBJECT__
|
||||
|
||||
|
||||
#include "metafile/nml.h"
|
||||
#include "reflection/c_refl.h"
|
||||
|
||||
|
||||
/*!
|
||||
@short Serialization helper.
|
||||
@author Emmanuel Julien (ejulien@gsworks.fr)
|
||||
*/
|
||||
namespace GS {
|
||||
namespace NML {
|
||||
|
||||
template <class T> bool LoadFromFile(T &object, File &file)
|
||||
{
|
||||
return file.isEmpty() ? false : object.FromMetaTag(*file.GetTags()[0]);
|
||||
}
|
||||
template <class T> bool LoadFromFile(T &object, const char *path, bool verbose = true)
|
||||
{
|
||||
File file;
|
||||
file.name = path;
|
||||
if (!Parser::Load(path, file, verbose))
|
||||
return false;
|
||||
return LoadFromFile(object, file);
|
||||
}
|
||||
|
||||
template <class T> bool SaveToFile(T &object, File &file)
|
||||
{
|
||||
file.Clear();
|
||||
return file.AddRoot(object.AsMetaTag()) ? true : false;
|
||||
}
|
||||
template <class T> bool SaveToFile(T &object, const char *path)
|
||||
{
|
||||
File file;
|
||||
file.name = path;
|
||||
if (!SaveToFile(object, file))
|
||||
return false;
|
||||
|
||||
return Parser::Save(path, file);
|
||||
}
|
||||
|
||||
bool GenericObjectFromMetaTag(Tag &, void *obj, Reflection::Property *obj_prop);
|
||||
Tag *GenericObjectToMetaTag(Tag *, const void *obj, Reflection::Property *obj_prop);
|
||||
|
||||
bool GenericObjectFromMetaFile(const char *, void *obj, Reflection::Property *obj_prop, const char *root_name = 0);
|
||||
bool GenericObjectToMetaFile(const char *, const void *obj, Reflection::Property *obj_prop, const char *root_name = 0);
|
||||
|
||||
} // NML
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __NMETAOBJECT__
|
||||
28
include/framework/metafile/nml_string.h
Normal file
28
include/framework/metafile/nml_string.h
Normal file
@ -0,0 +1,28 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __NMETAFILE_TO_STRING__
|
||||
#define __NMETAFILE_TO_STRING__
|
||||
|
||||
|
||||
namespace GS {
|
||||
class String;
|
||||
|
||||
namespace NML {
|
||||
class Tag;
|
||||
class File;
|
||||
|
||||
bool TagToString(const Tag &, String &);
|
||||
bool TagFromString(const String &, Tag &);
|
||||
|
||||
bool FileToString(const File &, String &);
|
||||
bool FileFromString(const String &, File &);
|
||||
|
||||
} // NML
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __NMETAFILE_TO_STRING__
|
||||
Reference in New Issue
Block a user