You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Code/Tools/CryCommonTools/XMLWriter.h

186 lines
5.2 KiB
C++

/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_CRYCOMMONTOOLS_XMLWRITER_H
#define CRYINCLUDE_CRYCOMMONTOOLS_XMLWRITER_H
#pragma once
#include "Exceptions.h"
#include <cstdio>
#include <vector>
#include <cassert>
class IXMLSink
{
public:
// Define an exception type to throw when file opening fails.
struct OpenFailedErrorTag {};
typedef Exception<OpenFailedErrorTag> OpenFailedError;
virtual void Write(const char* text) = 0;
};
class XMLFileSink
: public IXMLSink
{
public:
XMLFileSink(const string& name);
~XMLFileSink();
virtual void Write(const char* text);
private:
FILE* m_file;
};
class XMLWriter
{
public:
XMLWriter(IXMLSink* sink);
class Element
{
public:
Element(XMLWriter& writer, const string& name, bool output = true);
~Element();
template <typename T>
void Attribute(const string& name, const T& value);
void Child(const string& name, const string& value);
void Content(const string& text);
void ContentLine(const string& text);
template <typename T>
void ContentArrayElement(const T& value);
void ContentArrayFloat24(const float floatBuffer[24], const int entryCount);
void WriteDirectText(const char* text)
{
if (!isParent)
{
isParent = true;
if (m_output)
{
m_writer.CloseElement(m_name, false);
}
}
m_writer.WriteDirectText(text);
}
private:
XMLWriter& m_writer;
string m_name;
bool isParent;
bool m_output;
};
void WriteDirectText(const char* text)
{
m_sink->Write(text);
}
private:
void IncreaseIndentation();
void DecreaseIndentation();
void BeginElement(const string& name);
void EndElement(const string& name);
void CloseElement(const string& name, bool newLine);
void CloseLeafElement(const string& name);
void WriteAttribute(const string& name, const string& value);
static void SerializeAttribute(char* buffer, size_t bufferSize, const string& value);
static void SerializeAttribute(char* buffer, size_t bufferSize, float value);
static void SerializeAttribute(char* buffer, size_t bufferSize, int value);
static void SerializeArrayElement(char* buffer, size_t bufferSize, float value);
static void SerializeArrayElement(char* buffer, size_t bufferSize, const string& value);
static void SerializeArrayElement(char* buffer, size_t bufferSize, int value);
void WriteContent(const string& text);
void WriteContentLine(const string& text);
void WriteText(const char* format, ...);
IXMLSink* m_sink;
int m_indentationSize;
std::vector<Element*> m_elements;
bool m_newLine;
};
template <typename T>
void XMLWriter::Element::Attribute(const string& name, const T& value)
{
assert(!isParent);
char buffer[1024];
XMLWriter::SerializeAttribute(buffer, sizeof(buffer), value);
if (m_output)
{
m_writer.WriteAttribute(name, buffer);
}
}
template <typename T>
void XMLWriter::Element::ContentArrayElement(const T& value)
{
if (!m_output)
{
return;
}
if (!isParent)
{
isParent = true;
m_writer.CloseElement(m_name, false);
}
char buffer[1024] = {' ', 0};
XMLWriter::SerializeArrayElement(buffer + 1, sizeof(buffer) - 1, value);
m_writer.WriteDirectText(buffer);
}
inline void XMLWriter::Element::ContentArrayFloat24(const float floatBuffer[24], const int entryCount)
{
if (!m_output)
{
return;
}
if (!isParent)
{
isParent = true;
m_writer.CloseElement(m_name, false);
}
char buffer[2048];
if (entryCount == 24)
{
sprintf_s(buffer, " %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e",
floatBuffer[0], floatBuffer[1], floatBuffer[2], floatBuffer[3], floatBuffer[4], floatBuffer[5], floatBuffer[6], floatBuffer[7],
floatBuffer[8], floatBuffer[9], floatBuffer[10], floatBuffer[11], floatBuffer[12], floatBuffer[13], floatBuffer[14], floatBuffer[15],
floatBuffer[16], floatBuffer[17], floatBuffer[18], floatBuffer[19], floatBuffer[20], floatBuffer[21], floatBuffer[22], floatBuffer[23]);
m_writer.WriteDirectText(buffer);
}
else
{
for (int i = 0; i < entryCount; i++)
{
char buffer[1024];
sprintf_s(buffer, " %.10e", floatBuffer[i]);
m_writer.WriteDirectText(buffer);
}
}
}
#endif // CRYINCLUDE_CRYCOMMONTOOLS_XMLWRITER_H