Initial release

This commit is contained in:
civ
2026-08-16 18:24:52 +07:00
commit 876886a39a
13244 changed files with 2353959 additions and 0 deletions
@@ -0,0 +1,242 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../lib/vstguibase.h"
#if VSTGUI_ENABLE_XML_PARSER
#include "cstream.h"
#include "icontentprovider.h"
/// @cond ignore
#if VSTGUI_USE_SYSTEM_EXPAT
#include <expat.h>
#else
#define XML_STATIC 1
#define XML_NS 0
#define XML_DTD 0
#define XML_CONTEXT_BYTES 1024
#define XML_LARGE_SIZE 1
#ifdef BYTEORDER
#define OLD_BYTEORDER = BYTEORDER
#undef BYTEORDER
#endif
#if MAC && defined (__BIG_ENDIAN__)
#define BYTEORDER 4321
#else
#define BYTEORDER 1234
#endif
#define HAVE_MEMMOVE
namespace VSTGUI {
namespace Xml {
#include "../thirdparty/expat/expat.h"
}}
#endif // VSTGUI_USE_SYSTEM_EXPAT
#include "xmlparser.h"
#include <algorithm>
namespace VSTGUI {
namespace Xml {
//------------------------------------------------------------------------
struct Parser::Impl
{
XML_ParserStruct* parser {nullptr};
IHandler* handler {nullptr};
};
//------------------------------------------------------------------------
static void XMLCALL gStartElementHandler (void* userData, const char* name, const char** atts)
{
auto parser = static_cast<Parser*> (userData);
IHandler* handler = parser ? parser->getHandler () : nullptr;
if (handler)
handler->startXmlElement (parser, name, atts);
}
//------------------------------------------------------------------------
static void XMLCALL gEndElementHandler (void* userData, const char* name)
{
auto parser = static_cast<Parser*> (userData);
IHandler* handler = parser ? parser->getHandler () : nullptr;
if (handler)
handler->endXmlElement (parser, name);
}
//------------------------------------------------------------------------
static void XMLCALL gCharacterDataHandler (void* userData, const char* s, int len)
{
auto parser = static_cast<Parser*> (userData);
IHandler* handler = parser ? parser->getHandler () : nullptr;
if (handler)
handler->xmlCharData (parser, (const int8_t*)s, len);
}
//------------------------------------------------------------------------
static void XMLCALL gCommentHandler (void* userData, const char* string)
{
auto parser = static_cast<Parser*> (userData);
IHandler* handler = parser ? parser->getHandler () : nullptr;
if (handler)
handler->xmlComment (parser, string);
}
//-----------------------------------------------------------------------------
Parser::Parser ()
{
pImpl = std::unique_ptr<Impl> (new Impl ());
pImpl->parser = XML_ParserCreate ("UTF-8");
}
//-----------------------------------------------------------------------------
Parser::~Parser () noexcept
{
if (pImpl->parser)
XML_ParserFree (pImpl->parser);
}
//-----------------------------------------------------------------------------
IHandler* Parser::getHandler () const
{
return pImpl->handler;
}
//-----------------------------------------------------------------------------
bool Parser::parse (IContentProvider* provider, IHandler* handler)
{
if (provider == nullptr || handler == nullptr)
return false;
pImpl->handler = handler;
XML_SetUserData (pImpl->parser, this);
XML_SetStartElementHandler (pImpl->parser, gStartElementHandler);
XML_SetEndElementHandler (pImpl->parser, gEndElementHandler);
XML_SetCharacterDataHandler (pImpl->parser, gCharacterDataHandler);
XML_SetCommentHandler (pImpl->parser, gCommentHandler);
static const uint32_t kBufferSize = 0x8000;
provider->rewind ();
while (true)
{
void* buffer = XML_GetBuffer (pImpl->parser, kBufferSize);
if (buffer == nullptr)
{
pImpl->handler = nullptr;
return false;
}
uint32_t bytesRead = provider->readRawData ((int8_t*)buffer, kBufferSize);
if (bytesRead == kStreamIOError)
bytesRead = 0;
XML_Status status = XML_ParseBuffer (pImpl->parser, static_cast<int> (bytesRead), bytesRead == 0);
switch (status)
{
case XML_STATUS_ERROR:
{
XML_Error error = XML_GetErrorCode (pImpl->parser);
if (error == XML_ERROR_JUNK_AFTER_DOC_ELEMENT) // that's ok
{
pImpl->handler = nullptr;
return true;
}
#if DEBUG
XML_Size currentLineNumber = XML_GetCurrentLineNumber (pImpl->parser);
DebugPrint ("XML Parser Error on line: %d\n", currentLineNumber);
DebugPrint ("%s\n", XML_ErrorString (XML_GetErrorCode (pImpl->parser)));
int offset, size;
const char* inputContext = XML_GetInputContext (pImpl->parser, &offset, &size);
if (inputContext)
{
int pos = offset;
while (offset > 0 && pos - offset < 20)
{
if (inputContext[offset] == '\n')
{
offset++;
break;
}
offset--;
}
for (int i = offset; i < size && i - offset < 40; i++)
{
if (inputContext[i] == '\n')
break;
if (inputContext[i] == '\t')
DebugPrint (" ");
else
DebugPrint ("%c", inputContext[i]);
}
DebugPrint ("\n");
for (int i = offset; i < pos; i++)
{
DebugPrint (" ");
}
DebugPrint ("^\n");
}
#endif
pImpl->handler = nullptr;
return false;
}
case XML_STATUS_SUSPENDED:
{
pImpl->handler = nullptr;
return true;
}
default:
break;
}
if (bytesRead == 0)
break;
}
pImpl->handler = nullptr;
return true;
}
//-----------------------------------------------------------------------------
bool Parser::stop ()
{
XML_StopParser (pImpl->parser, false);
return true;
}
//------------------------------------------------------------------------
}} // namespaces
#if !VSTGUI_USE_SYSTEM_EXPAT
//------------------------------------------------------------------------
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconversion"
#pragma clang diagnostic ignored "-Wshadow"
#endif
namespace VSTGUI {
namespace Xml {
#include "../thirdparty/expat/xmltok.c"
#include "../thirdparty/expat/xmlrole.c"
#include "../thirdparty/expat/xmlparse.c"
}}
#ifdef OLD_BYTEORDER
#undef BYTEORDER
#define BYTEORDER = OLD_BYTEORDER
#endif
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#endif
/// @endcond
#endif // VSTGUI_ENABLE_XML_PARSER