112 lines
2.7 KiB
C++
112 lines
2.7 KiB
C++
/* -----------------------------------------------------------------------------
|
|
GSFramework
|
|
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
|
----------------------------------------------------------------------------- */
|
|
|
|
|
|
#include <cstring>
|
|
#include "metafile/nml.h"
|
|
#include "filesystem/io_handle.h"
|
|
#include "filesystem/filesystem.h"
|
|
#include "platform.h"
|
|
#include "log/log.h"
|
|
|
|
using namespace GS;
|
|
using namespace GS::NML;
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
bool Parser::SaveBinaryTag(IO::Handle &out, const Tag &tag, File::Binary method)
|
|
{
|
|
const Variant &v = tag.GetValue();
|
|
|
|
if (v.GetType() != Variant::VariantNone)
|
|
{
|
|
out.Write <ushort> ((ushort)tag.name.Len());
|
|
out.Write((void *)tag.name.c_str(), tag.name.Len());
|
|
}
|
|
else
|
|
__ERR__(__LOG_W__ << "Ignoring invalid metatag '" << tag.name << "'.\n", true)
|
|
|
|
// Store tag start size/type.
|
|
out.Write <uchar> ((uchar)v.GetType());
|
|
|
|
size_t tag_length_pos = out.Tell();
|
|
switch (v.GetType())
|
|
{
|
|
case Variant::VariantNone:
|
|
case Variant::VariantBinary:
|
|
case Variant::VariantString:
|
|
out.Write <int> (-1);
|
|
break;
|
|
|
|
default: break;
|
|
}
|
|
|
|
switch (v.GetType())
|
|
{
|
|
case Variant::VariantNone:
|
|
NMLTagForeach(child, tag)
|
|
if (!SaveBinaryTag(out, *child, method))
|
|
return false;
|
|
break;
|
|
|
|
case Variant::VariantBinary:
|
|
out.Write(tag.GetValue().GetBinaryBuffer(), tag.GetValue().GetBinarySize());
|
|
break;
|
|
|
|
case Variant::VariantInteger:
|
|
out.Write <int> (tag.GetInteger());
|
|
break;
|
|
|
|
case Variant::VariantFloat:
|
|
out.Write <float> (tag.GetReal());
|
|
break;
|
|
|
|
case Variant::VariantString:
|
|
out.Write(tag.GetString(), std::strlen(tag.GetString()));
|
|
break;
|
|
|
|
default:
|
|
__ERR__(__LOG_E__ << "No method to output tag '" << tag.name << "' type.\n", false)
|
|
}
|
|
|
|
switch (v.GetType())
|
|
{
|
|
case Variant::VariantNone:
|
|
case Variant::VariantBinary:
|
|
case Variant::VariantString:
|
|
{
|
|
size_t tag_end_pos = out.Tell();
|
|
out.Seek(tag_length_pos, IO::Base::SeekStart);
|
|
out.Write <int> (tag_end_pos - tag_length_pos);
|
|
out.Seek(tag_end_pos, IO::Base::SeekStart);
|
|
}
|
|
break;
|
|
|
|
default: break;
|
|
}
|
|
return true;
|
|
}
|
|
bool Parser::SaveBinary(IO::Handle &h, const File &file)
|
|
{
|
|
h.Write((const void *)"<BML=1.0>\n", 10);
|
|
NMLFileForeach(tag, file)
|
|
if (!SaveBinaryTag(h, *tag, file.GetBinaryMethod()))
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
bool Parser::SaveBinary(const char *uri, const File &file)
|
|
{
|
|
if (!uri)
|
|
return false;
|
|
|
|
AutoPtr <IO::Handle> handle;
|
|
if (!(handle = Platform::Get().io->Open(uri, IO::ModeWrite)))
|
|
__ERR__(__LOG_E__ << "Failed to open metafile output '" << uri << "'.\n", false)
|
|
|
|
return SaveBinary(*handle, file);
|
|
}
|
|
//------------------------------------------------------------------------------
|