From f61facf4e79caec3593a8bdcd7b0d243997d3a76 Mon Sep 17 00:00:00 2001 From: Rune Date: Fri, 6 Mar 2026 16:05:04 +0100 Subject: [PATCH] add code --- .gitignore | 5 + .gitmodules | 3 + BeefProj.toml | 11 + BeefSpace.toml | 6 + Setup/.gitignore | 3 + Setup/BeefProj.toml | 66 +++ Setup/BeefSpace.toml | 6 + Setup/BeefSpace_Lock.toml | 11 + Setup/src/Program.bf | 315 +++++++++++ libexpat | 1 + src/Expat.bf | 1054 ++++++++++++++++++++++++++++++++++++ src/Wrapper.bf | 1072 +++++++++++++++++++++++++++++++++++++ 12 files changed, 2553 insertions(+) create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 BeefProj.toml create mode 100644 BeefSpace.toml create mode 100644 Setup/.gitignore create mode 100644 Setup/BeefProj.toml create mode 100644 Setup/BeefSpace.toml create mode 100644 Setup/BeefSpace_Lock.toml create mode 100644 Setup/src/Program.bf create mode 160000 libexpat create mode 100644 src/Expat.bf create mode 100644 src/Wrapper.bf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..697f7db --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +build +expat_config/* +recovery +BeefSpace_User.toml +CxxBuilderPath.txt \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..00db6d1 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "libexpat"] + path = libexpat + url = https://github.com/libexpat/libexpat.git diff --git a/BeefProj.toml b/BeefProj.toml new file mode 100644 index 0000000..910a60f --- /dev/null +++ b/BeefProj.toml @@ -0,0 +1,11 @@ +FileVersion = 1 +Dependencies = {corlib = "*", corlib = "*"} + +[Project] +Name = "Expat" +TargetType = "BeefLib" +StartupObject = "Expat.Program" + +[Configs.Debug.Win64] +LibPaths = ["$(BuildDir)/libexpat.lib"] +PreBuildCmds = ["ReadFile(\"$(ProjectDir)/CxxBuilderPath.txt\", \"CxxBuilderPath\")", "Execute(\"$(Var CxxBuilderPath) *.c -- \\\"src=$(ProjectDir)/libexpat/expat/lib\\\" \\\"builddir=$(BuildDir)\\\" target=$(TargetTriple) \\\"cflags=-I$(ProjectDir)/expat_config\\\" output=libexpat\")"] diff --git a/BeefSpace.toml b/BeefSpace.toml new file mode 100644 index 0000000..62404f3 --- /dev/null +++ b/BeefSpace.toml @@ -0,0 +1,6 @@ +FileVersion = 1 +Projects = {Expat = {Path = "."}} +ExtraPlatforms = ["Linux32", "Linux64", "macOS"] + +[Workspace] +StartupProject = "Expat" diff --git a/Setup/.gitignore b/Setup/.gitignore new file mode 100644 index 0000000..28765bb --- /dev/null +++ b/Setup/.gitignore @@ -0,0 +1,3 @@ +build +recovery +BeefSpace_User.toml diff --git a/Setup/BeefProj.toml b/Setup/BeefProj.toml new file mode 100644 index 0000000..79b3c6b --- /dev/null +++ b/Setup/BeefProj.toml @@ -0,0 +1,66 @@ +FileVersion = 1 +Dependencies = {corlib = "*", "Cpp2Beef.git" = {Git = "https://git.unicon-gmbh.de/BeefBindings/Cpp2Beef.git"}} + +[Project] +Name = "Expat.Setup" +StartupObject = "Expat.Setup.Program" + +[Configs.Debug.Win32] +PostBuildCmds = ["cp $(ProjectDir Cpp2Beef.git)/CxxBuilder/dist/CxxBuilderPath.txt $(WorkspaceDir)/../CxxBuilderPath.txt"] + +[Configs.Debug.Win64] +PostBuildCmds = ["cp $(ProjectDir Cpp2Beef.git)/CxxBuilder/dist/CxxBuilderPath.txt $(WorkspaceDir)/../CxxBuilderPath.txt"] + +[Configs.Debug.Linux32] +PostBuildCmds = ["cp $(ProjectDir Cpp2Beef.git)/CxxBuilder/dist/CxxBuilderPath.txt $(WorkspaceDir)/../CxxBuilderPath.txt"] + +[Configs.Debug.Linux64] +PostBuildCmds = ["cp $(ProjectDir Cpp2Beef.git)/CxxBuilder/dist/CxxBuilderPath.txt $(WorkspaceDir)/../CxxBuilderPath.txt"] + +[Configs.Debug.macOS] +PostBuildCmds = ["cp $(ProjectDir Cpp2Beef.git)/CxxBuilder/dist/CxxBuilderPath.txt $(WorkspaceDir)/../CxxBuilderPath.txt"] + +[Configs.Release.Win32] +PostBuildCmds = ["cp $(ProjectDir Cpp2Beef.git)/CxxBuilder/dist/CxxBuilderPath.txt $(WorkspaceDir)/../CxxBuilderPath.txt"] + +[Configs.Release.Win64] +PostBuildCmds = ["cp $(ProjectDir Cpp2Beef.git)/CxxBuilder/dist/CxxBuilderPath.txt $(WorkspaceDir)/../CxxBuilderPath.txt"] + +[Configs.Release.Linux32] +PostBuildCmds = ["cp $(ProjectDir Cpp2Beef.git)/CxxBuilder/dist/CxxBuilderPath.txt $(WorkspaceDir)/../CxxBuilderPath.txt"] + +[Configs.Release.Linux64] +PostBuildCmds = ["cp $(ProjectDir Cpp2Beef.git)/CxxBuilder/dist/CxxBuilderPath.txt $(WorkspaceDir)/../CxxBuilderPath.txt"] + +[Configs.Release.macOS] +PostBuildCmds = ["cp $(ProjectDir Cpp2Beef.git)/CxxBuilder/dist/CxxBuilderPath.txt $(WorkspaceDir)/../CxxBuilderPath.txt"] + +[Configs.Paranoid.Win32] +PostBuildCmds = ["cp $(ProjectDir Cpp2Beef.git)/CxxBuilder/dist/CxxBuilderPath.txt $(WorkspaceDir)/../CxxBuilderPath.txt"] + +[Configs.Paranoid.Win64] +PostBuildCmds = ["cp $(ProjectDir Cpp2Beef.git)/CxxBuilder/dist/CxxBuilderPath.txt $(WorkspaceDir)/../CxxBuilderPath.txt"] + +[Configs.Paranoid.Linux32] +PostBuildCmds = ["cp $(ProjectDir Cpp2Beef.git)/CxxBuilder/dist/CxxBuilderPath.txt $(WorkspaceDir)/../CxxBuilderPath.txt"] + +[Configs.Paranoid.Linux64] +PostBuildCmds = ["cp $(ProjectDir Cpp2Beef.git)/CxxBuilder/dist/CxxBuilderPath.txt $(WorkspaceDir)/../CxxBuilderPath.txt"] + +[Configs.Paranoid.macOS] +PostBuildCmds = ["cp $(ProjectDir Cpp2Beef.git)/CxxBuilder/dist/CxxBuilderPath.txt $(WorkspaceDir)/../CxxBuilderPath.txt"] + +[Configs.Test.Win32] +PostBuildCmds = ["cp $(ProjectDir Cpp2Beef.git)/CxxBuilder/dist/CxxBuilderPath.txt $(WorkspaceDir)/../CxxBuilderPath.txt"] + +[Configs.Test.Win64] +PostBuildCmds = ["cp $(ProjectDir Cpp2Beef.git)/CxxBuilder/dist/CxxBuilderPath.txt $(WorkspaceDir)/../CxxBuilderPath.txt"] + +[Configs.Test.Linux32] +PostBuildCmds = ["cp $(ProjectDir Cpp2Beef.git)/CxxBuilder/dist/CxxBuilderPath.txt $(WorkspaceDir)/../CxxBuilderPath.txt"] + +[Configs.Test.Linux64] +PostBuildCmds = ["cp $(ProjectDir Cpp2Beef.git)/CxxBuilder/dist/CxxBuilderPath.txt $(WorkspaceDir)/../CxxBuilderPath.txt"] + +[Configs.Test.macOS] +PostBuildCmds = ["cp $(ProjectDir Cpp2Beef.git)/CxxBuilder/dist/CxxBuilderPath.txt $(WorkspaceDir)/../CxxBuilderPath.txt"] diff --git a/Setup/BeefSpace.toml b/Setup/BeefSpace.toml new file mode 100644 index 0000000..84b3b66 --- /dev/null +++ b/Setup/BeefSpace.toml @@ -0,0 +1,6 @@ +FileVersion = 1 +Projects = {"Expat.Setup" = {Path = "."}, "Cpp2Beef.git" = {Git = "https://git.unicon-gmbh.de/BeefBindings/Cpp2Beef.git"}} +ExtraPlatforms = ["Linux32", "Linux64", "macOS"] + +[Workspace] +StartupProject = "Expat.Setup" diff --git a/Setup/BeefSpace_Lock.toml b/Setup/BeefSpace_Lock.toml new file mode 100644 index 0000000..a56cab9 --- /dev/null +++ b/Setup/BeefSpace_Lock.toml @@ -0,0 +1,11 @@ +FileVersion = 1 + +[Locks."Clang-C.git".Git] +URL = "https://git.unicon-gmbh.de/BeefBindings/Clang-C.git" +Tag = "" +Hash = "86db0167f15d08a63a91a19e46f983a5511bac1a" + +[Locks."Cpp2Beef.git".Git] +URL = "https://git.unicon-gmbh.de/BeefBindings/Cpp2Beef.git" +Tag = "" +Hash = "3590478b20da32b54f523780b5de819c27b95a47" diff --git a/Setup/src/Program.bf b/Setup/src/Program.bf new file mode 100644 index 0000000..39ec4d0 --- /dev/null +++ b/Setup/src/Program.bf @@ -0,0 +1,315 @@ +using System; +using System.IO; +using System.Collections; +using System.Diagnostics; + +using Cpp2Beef; +using LibClang; + +namespace Expat.Setup; + +class ExpatGenerator : Cpp2BeefGenerator, this(Span args) +{ + protected override Span Args => args; + protected override Flags Flags => .None; + + StreamWriter writter = new .()..Create("../src/Expat.bf")..Write(""" + // This file was generated by Cpp2Beef + + using System; + using System.Interop; + + namespace Expat; + + static class XML + { + public typealias Char = c_char; + public typealias LChar = c_char; + public typealias Index = c_long; + public typealias Size = c_ulong; + + public struct Bool : c_uchar + { + public static operator bool(Self b) => b != FALSE; + public static operator Self(bool b) => b ? TRUE : FALSE; + } + } + + + """) ~ delete _; + + protected override System.IO.StreamWriter GetWriterForHeader(StringView header) + { + return header.EndsWith("expat.h") ? writter : null; + } + + protected override void WriteToken(CXToken token) + { + if (GetTokenSpelling!(token) == "XML_Bool") + str.Append("Bool"); + else + base.WriteToken(token); + } + + protected override Block GetCursorBlock(CXCursor cursor) + { + return .CustomBlock("XML"); + } + + protected override void HandleCursor(CXCursor cursor) + { + switch (cursor.kind) + { + case .MacroDefinition: + let spelling = GetCursorSpelling!(cursor); + if (spelling.StartsWith("XML_STATUS_") || spelling.StartsWith("XML_GetError")) + return; + case .TypedefDecl: + let spelling = GetCursorSpelling!(cursor); + if (spelling == "XML_Bool") + return; + if (spelling == "XML_Parser") + { + BeginCursor(cursor); + str.Append("public struct Parser : int {}"); + return; + } + default: + } + base.HandleCursor(cursor); + } + + protected override void GetNameInBindings(LibClang.CXCursor cursor, String outString) + { + GetNameInBindingsStatic(cursor, outString, scope () => base.GetNameInBindings(cursor, outString)); + } + + public static void GetNameInBindingsStatic(LibClang.CXCursor cursor, String outString, delegate void() fallback) + { + var spelling = GetCursorSpelling!(cursor); + switch (cursor.kind) + { + case .EnumConstantDecl: + switch (GetCursorSpelling!(Clang.GetCursorSemanticParent(cursor))) + { + case "XML_Status": spelling.RemoveFromStart("XML_STATUS_".Length); + case "XML_Error": spelling.RemoveFromStart("XML_ERROR_".Length); + case "XML_Content_Type": spelling.RemoveFromStart("XML_CTYPE_".Length); + case "XML_Content_Quant": spelling.RemoveFromStart("XML_CQUANT_".Length); + case "XML_ParamEntityParsing": spelling.RemoveFromStart("XML_PARAM_ENTITY_PARSING_".Length); + case "XML_FeatureEnum": spelling.RemoveFromStart("XML_FEATURE_".Length); + } + bool upper = true; + for (let c in spelling) + if (c == '_') upper = true; + else if (upper) { outString.Append(c.ToUpper); upper = false; } + else outString.Append(c.ToLower); + default: + if (!spelling.StartsWith("XML_")) + { + fallback(); + return; + } + spelling.RemoveFromStart(4); + outString.Append(spelling); + } + } +} + +class ExpatWrapperGenerator : Cpp2BeefGenerator, this(Span args) +{ + protected override Span Args => args; + protected override Flags Flags => .None; + + BumpAllocator alloc = new .() ~ delete _; + + StreamWriter writer = new:alloc .()..Create("../src/Wrapper.bf")..Write(""" + // This file was generated by Expat.Setup + + using System; + using System.Interop; + + namespace Expat; + + class XmlParser + { + private XML.Parser handle ~ XML.ParserFree(_); + public Result ParserInitResult => handle == default ? .Err : .Ok; + + + """); + + List<(StringView name, StringView args, int numArgs)> handlers = new:alloc .(16); + + protected override StreamWriter GetWriterForHeader(StringView header) + { + return header.EndsWith("expat.h") ? writer : null; + } + + protected override Block GetCursorBlock(CXCursor cursor) + { + return .NoBlock; + } + + protected override void GetNameInBindings(LibClang.CXCursor cursor, String outString) + { + outString.Append("XML."); + ExpatGenerator.GetNameInBindingsStatic(cursor, outString, scope () => + { + outString.Length -= 4; + base.GetNameInBindings(cursor, outString); + }); + } + + protected override void HandleCursor(CXCursor cursor) + { + switch (cursor.kind) + { + case .FunctionDecl: + var spelling = GetCursorSpelling!(cursor); + if (spelling.StartsWith("XML_") && spelling != "XML_ParserFree") + spelling.RemoveFromStart(4); + else + return; + + void WriteArgList(uint32 start) + { + uint32 i = start; + for (; i < (.)Clang.Cursor_GetNumArguments(cursor); i++) + { + if (i > start) str.Append(", "); + Compiler.Identifier.GetSourceName(GetCursorSpelling!(Clang.Cursor_GetArgument(cursor, i)), str); + } + } + + if (spelling.StartsWith("ParserCreate")) + { + BeginCursor(cursor); + str.Append("[Inline] public this("); + Method_Parameters(cursor); + str.Append(") { handle = XML.", spelling, "("); + WriteArgList(0); + str.Append("); InitHandlers(); }"); + return; + } + + if (Clang.Cursor_GetNumArguments(cursor) < 1 || GetTypeSpelling!(Clang.GetCursorType(Clang.Cursor_GetArgument(cursor, 0))) != "XML_Parser") + return; + + BeginCursor(cursor); + str.Append("[Inline] public "); + Type(Clang.GetCursorResultType(cursor)); + str.Append(' '); + if (spelling.Contains("Parser")) + { + Flush(); + str.Append(spelling); + str.Replace("Parser", ""); + } + else + str.Append(spelling); + str.Append('('); + int index = str.Length; + Method_Parameters(cursor); + int length = str.IndexOf(','); + if (length >= 0) + str.Remove(index, length - index + 2); + else + str.RemoveToEnd(index); + str.Append(") => XML.", spelling, "(handle"); + if (length >= 0) str.Append(", "); + WriteArgList(1); + str.Append(");"); + + case .TypedefDecl: + var spelling = GetCursorSpelling!(cursor); + let type = Clang.GetTypedefDeclUnderlyingType(cursor); + let proto = Clang.GetPointeeType(type); + if (spelling.StartsWith("XML_") && type.kind == .Pointer && (proto.kind == .FunctionProto || proto.kind == .FunctionNoProto)) + spelling.RemoveFromStart(4); + else + return; + + Flush(); + WriteFunctionProtoParams(proto, ScopeTokenize!(cursor, unit)); + StringView args; + { + args = scope String(str); + str.Clear(); + if (!args.StartsWith("(void* userData")) + return; + args.RemoveFromStart("(void* userData".Length); + if (args.StartsWith(',')) + args.RemoveFromStart(", ".Length); + args = new:alloc String(args); + } + + handlers.Add((new:alloc String(spelling), args, Clang.GetNumArgTypes(proto) - 1)); + BeginCursor(cursor); + str.Append("public virtual "); + let result = Clang.GetResultType(proto); + Type(result); + str.Append(" ", spelling, "(", args, result.kind == .Void ? " {}" : " => default;"); + + default: + } + } + + protected override void PostGeneration() + { + str.Append(""" + + + private void InitHandlers() + { + SetUserData(Internal.UnsafeCastToPtr(this)); + + """); + for (let handler in handlers) + { + str.Append("\t\tSet", handler.name, "((userData"); + for (let i < handler.numArgs) + { + str.Append(", "); + str.Append('a' + i); + } + str.Append(") => ((Self)Internal.UnsafeCastToObject(userData)).", handler.name, "("); + for (let i < handler.numArgs) + { + if (i != 0) str.Append(", "); + str.Append('a' + i); + } + str.Append("));\n"); + } + str.Append(""" + } + } + """); + Flush(); + } +} + +class Program +{ + [CLink] static extern int32 system(char8*); + static mixin RunCommand(char8* cmd) + { + Console.WriteLine($"> {StringView(cmd)}"); + int32 rcode = system(cmd); + if (rcode != 0) + return rcode; + } + + public static int Main(String[] args) + { + RunCommand!("git -C .. submodule update"); + + char8*[?] clangArgs = .("--language=c", "-I../libexpat/expat/lib", "-DXMLCALL="); + { scope ExpatGenerator(clangArgs).Generate("../libexpat/expat/lib/expat.h", null); } + { scope ExpatWrapperGenerator(clangArgs).Generate("../libexpat/expat/lib/expat.h", null); } + + Directory.CreateDirectory("../expat_config"); + RunCommand!("cmake -S ../libexpat/expat -B ../expat_config -GNinja"); + return 0; + } +} \ No newline at end of file diff --git a/libexpat b/libexpat new file mode 160000 index 0000000..f5c2890 --- /dev/null +++ b/libexpat @@ -0,0 +1 @@ +Subproject commit f5c2890d8ff91f88a018173d293a9bd02f76389e diff --git a/src/Expat.bf b/src/Expat.bf new file mode 100644 index 0000000..869032e --- /dev/null +++ b/src/Expat.bf @@ -0,0 +1,1054 @@ +// This file was generated by Cpp2Beef + +using System; +using System.Interop; + +namespace Expat; + +static class XML +{ + public typealias Char = c_char; + public typealias LChar = c_char; + public typealias Index = c_long; + public typealias Size = c_ulong; + + public struct Bool : c_uchar + { + public static operator bool(Self b) => b != FALSE; + public static operator Self(bool b) => b ? TRUE : FALSE; + } +} + +extension XML +{ +/* + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 1997-2000 Thai Open Source Software Center Ltd + Copyright (c) 2000 Clark Cooper + Copyright (c) 2000-2005 Fred L. Drake, Jr. + Copyright (c) 2001-2002 Greg Stein + Copyright (c) 2002-2016 Karl Waclawek + Copyright (c) 2016-2026 Sebastian Pipping + Copyright (c) 2016 Cristian Rodríguez + Copyright (c) 2016 Thomas Beutlich + Copyright (c) 2017 Rhodri James + Copyright (c) 2022 Thijs Schreijer + Copyright (c) 2023 Hanno Böck + Copyright (c) 2023 Sony Corporation / Snild Dolkow + Copyright (c) 2024 Taichi Haradaguchi <20001722@ymail.ne.jp> + Copyright (c) 2025 Matthew Fernandez + Licensed under the MIT license: + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to permit + persons to whom the Software is furnished to do so, subject to the + following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + + +public const let Expat_INCLUDED = 1; + + + + + + + + +[CRepr] public struct ParserStruct; +public struct Parser : int {} + + +public const let TRUE = ((Bool)1); +public const let FALSE = ((Bool)0); + +/* The XML_Status enum gives the possible return values for several + API functions. The preprocessor #defines are included so this + stanza can be added to code that still needs to support older + versions of Expat 1.95.x: + + #ifndef XML_STATUS_OK + #define XML_STATUS_OK 1 + #define XML_STATUS_ERROR 0 + #endif + + Otherwise, the #define hackery is quite ugly and would have been + dropped. +*/ +[AllowDuplicates] public enum Status : c_int { + Error = 0, + + Ok = 1, + + Suspended = 2, + +} + +[AllowDuplicates] public enum Error : c_int { + None, + NoMemory, + Syntax, + NoElements, + InvalidToken, + UnclosedToken, + PartialChar, + TagMismatch, + DuplicateAttribute, + JunkAfterDocElement, + ParamEntityRef, + UndefinedEntity, + RecursiveEntityRef, + AsyncEntity, + BadCharRef, + BinaryEntityRef, + AttributeExternalEntityRef, + MisplacedXmlPi, + UnknownEncoding, + IncorrectEncoding, + UnclosedCdataSection, + ExternalEntityHandling, + NotStandalone, + UnexpectedState, + EntityDeclaredInPe, + FeatureRequiresXmlDtd, + CantChangeFeatureOnceParsing, + /* Added in 1.95.7. */ + UnboundPrefix, + /* Added in 1.95.8. */ + UndeclaringPrefix, + IncompletePe, + XmlDecl, + TextDecl, + Publicid, + Suspended, + NotSuspended, + Aborted, + Finished, + SuspendPe, + /* Added in 2.0. */ + ReservedPrefixXml, + ReservedPrefixXmlns, + ReservedNamespaceUri, + /* Added in 2.2.1. */ + InvalidArgument, + /* Added in 2.3.0. */ + NoBuffer, + /* Added in 2.4.0. */ + AmplificationLimitBreach, + /* Added in 2.6.4. */ + NotStarted, +} + +[AllowDuplicates] public enum Content_Type : c_int { + Empty = 1, + Any, + Mixed, + Name, + Choice, + Seq, +} + +[AllowDuplicates] public enum Content_Quant : c_int { + None, + Opt, + Rep, + Plus, +} + +/* If type == XML_CTYPE_EMPTY or XML_CTYPE_ANY, then quant will be + XML_CQUANT_NONE, and the other fields will be zero or NULL. + If type == XML_CTYPE_MIXED, then quant will be NONE or REP and + numchildren will contain number of elements that may be mixed in + and children point to an array of XML_Content cells that will be + all of XML_CTYPE_NAME type with no quantification. + + If type == XML_CTYPE_NAME, then the name points to the name, and + the numchildren field will be zero and children will be NULL. The + quant fields indicates any quantifiers placed on the name. + + CHOICE and SEQ will have name NULL, the number of children in + numchildren and children will point, recursively, to an array + of XML_Content cells. + + The EMPTY, ANY, and MIXED types will only occur at top level. +*/ + +public typealias Content = cp; + +[CRepr] public struct cp { + public Content_Type type; + public Content_Quant quant; + public Char* name; + public c_uint numchildren; + public Content* children; +} + +/* This is called for an element declaration. See above for + description of the model argument. It's the user code's responsibility + to free model when finished with it. See XML_FreeContentModel. + There is no need to free the model from the handler, it can be kept + around and freed at a later stage. +*/ +public function void ElementDeclHandler(void* userData, Char* name, Content* model); + + +[LinkName("XML_SetElementDeclHandler")] public static extern void SetElementDeclHandler(Parser parser, ElementDeclHandler eldecl); + +/* The Attlist declaration handler is called for *each* attribute. So + a single Attlist declaration with multiple attributes declared will + generate multiple calls to this handler. The "default" parameter + may be NULL in the case of the "#IMPLIED" or "#REQUIRED" + keyword. The "isrequired" parameter will be true and the default + value will be NULL in the case of "#REQUIRED". If "isrequired" is + true and default is non-NULL, then this is a "#FIXED" default. +*/ +public function void AttlistDeclHandler(void* userData, Char* elname, Char* attname, Char* att_type, Char* dflt, c_int isrequired); + + +[LinkName("XML_SetAttlistDeclHandler")] public static extern void SetAttlistDeclHandler(Parser parser, AttlistDeclHandler attdecl); + +/* The XML declaration handler is called for *both* XML declarations + and text declarations. The way to distinguish is that the version + parameter will be NULL for text declarations. The encoding + parameter may be NULL for XML declarations. The standalone + parameter will be -1, 0, or 1 indicating respectively that there + was no standalone parameter in the declaration, that it was given + as no, or that it was given as yes. +*/ +public function void XmlDeclHandler(void* userData, Char* version, Char* encoding, c_int standalone); + + +[LinkName("XML_SetXmlDeclHandler")] public static extern void SetXmlDeclHandler(Parser parser, XmlDeclHandler xmldecl); + +[CRepr] public struct Memory_Handling_Suite { + public function void*(c_size size) malloc_fcn; + public function void*(void* ptr, c_size size) realloc_fcn; + public function void(void* ptr) free_fcn; +} + +/* Constructs a new parser; encoding is the encoding specified by the + external protocol or NULL if there is none specified. +*/ + +[LinkName("XML_ParserCreate")] public static extern Parser ParserCreate(Char* encoding); + +/* Constructs a new parser and namespace processor. Element type + names and attribute names that belong to a namespace will be + expanded; unprefixed attribute names are never expanded; unprefixed + element type names are expanded only if there is a default + namespace. The expanded name is the concatenation of the namespace + URI, the namespace separator character, and the local part of the + name. If the namespace separator is '\0' then the namespace URI + and the local part will be concatenated without any separator. + It is a programming error to use the separator '\0' with namespace + triplets (see XML_SetReturnNSTriplet). + If a namespace separator is chosen that can be part of a URI or + part of an XML name, splitting an expanded name back into its + 1, 2 or 3 original parts on application level in the element handler + may end up vulnerable, so these are advised against; sane choices for + a namespace separator are e.g. '\n' (line feed) and '|' (pipe). + + Note that Expat does not validate namespace URIs (beyond encoding) + against RFC 3986 today (and is not required to do so with regard to + the XML 1.0 namespaces specification) but it may start doing that + in future releases. Before that, an application using Expat must + be ready to receive namespace URIs containing non-URI characters. +*/ + +[LinkName("XML_ParserCreateNS")] public static extern Parser ParserCreateNS(Char* encoding, Char namespaceSeparator); + +/* Constructs a new parser using the memory management suite referred to + by memsuite. If memsuite is NULL, then use the standard library memory + suite. If namespaceSeparator is non-NULL it creates a parser with + namespace processing as described above. The character pointed at + will serve as the namespace separator. + + All further memory operations used for the created parser will come from + the given suite. +*/ + +[LinkName("XML_ParserCreate_MM")] public static extern Parser ParserCreate_MM(Char* encoding, Memory_Handling_Suite* memsuite, Char* namespaceSeparator); + +/* Prepare a parser object to be reused. This is particularly + valuable when memory allocation overhead is disproportionately high, + such as when a large number of small documents need to be parsed. + All handlers are cleared from the parser, except for the + unknownEncodingHandler. The parser's external state is re-initialized + except for the values of ns and ns_triplets. + + Added in Expat 1.95.3. +*/ + +[LinkName("XML_ParserReset")] public static extern Bool ParserReset(Parser parser, Char* encoding); + +/* atts is array of name/value pairs, terminated by 0; + names and values are 0 terminated. +*/ +public function void StartElementHandler(void* userData, Char* name, Char** atts); + +public function void EndElementHandler(void* userData, Char* name); + +/* s is not 0 terminated. */ +public function void CharacterDataHandler(void* userData, Char* s, c_int len); + +/* target and data are 0 terminated */ +public function void ProcessingInstructionHandler(void* userData, Char* target, Char* data); + +/* data is 0 terminated */ +public function void CommentHandler(void* userData, Char* data); + +public function void StartCdataSectionHandler(void* userData); +public function void EndCdataSectionHandler(void* userData); + +/* This is called for any characters in the XML document for which + there is no applicable handler. This includes both characters that + are part of markup which is of a kind that is not reported + (comments, markup declarations), or characters that are part of a + construct which could be reported but for which no handler has been + supplied. The characters are passed exactly as they were in the XML + document except that they will be encoded in UTF-8 or UTF-16. + Line boundaries are not normalized. Note that a byte order mark + character is not passed to the default handler. There are no + guarantees about how characters are divided between calls to the + default handler: for example, a comment might be split between + multiple calls. +*/ +public function void DefaultHandler(void* userData, Char* s, c_int len); + +/* This is called for the start of the DOCTYPE declaration, before + any DTD or internal subset is parsed. +*/ +public function void StartDoctypeDeclHandler(void* userData, Char* doctypeName, Char* sysid, Char* pubid, c_int has_internal_subset); + +/* This is called for the end of the DOCTYPE declaration when the + closing > is encountered, but after processing any external + subset. +*/ +public function void EndDoctypeDeclHandler(void* userData); + +/* This is called for entity declarations. The is_parameter_entity + argument will be non-zero if the entity is a parameter entity, zero + otherwise. + + For internal entities (), value will + be non-NULL and systemId, publicID, and notationName will be NULL. + The value string is NOT null-terminated; the length is provided in + the value_length argument. Since it is legal to have zero-length + values, do not use this argument to test for internal entities. + + For external entities, value will be NULL and systemId will be + non-NULL. The publicId argument will be NULL unless a public + identifier was provided. The notationName argument will have a + non-NULL value only for unparsed entity declarations. + + Note that is_parameter_entity can't be changed to XML_Bool, since + that would break binary compatibility. +*/ +public function void EntityDeclHandler(void* userData, Char* entityName, c_int is_parameter_entity, Char* value, c_int value_length, Char* @base, Char* systemId, Char* publicId, Char* notationName); + + +[LinkName("XML_SetEntityDeclHandler")] public static extern void SetEntityDeclHandler(Parser parser, EntityDeclHandler handler); + +/* OBSOLETE -- OBSOLETE -- OBSOLETE + This handler has been superseded by the EntityDeclHandler above. + It is provided here for backward compatibility. + + This is called for a declaration of an unparsed (NDATA) entity. + The base argument is whatever was set by XML_SetBase. The + entityName, systemId and notationName arguments will never be + NULL. The other arguments may be. +*/ +public function void UnparsedEntityDeclHandler(void* userData, Char* entityName, Char* @base, Char* systemId, Char* publicId, Char* notationName); + +/* This is called for a declaration of notation. The base argument is + whatever was set by XML_SetBase. The notationName will never be + NULL. The other arguments can be. +*/ +public function void NotationDeclHandler(void* userData, Char* notationName, Char* @base, Char* systemId, Char* publicId); + +/* When namespace processing is enabled, these are called once for + each namespace declaration. The call to the start and end element + handlers occur between the calls to the start and end namespace + declaration handlers. For an xmlns attribute, prefix will be + NULL. For an xmlns="" attribute, uri will be NULL. +*/ +public function void StartNamespaceDeclHandler(void* userData, Char* prefix, Char* uri); + +public function void EndNamespaceDeclHandler(void* userData, Char* prefix); + +/* This is called if the document is not standalone, that is, it has an + external subset or a reference to a parameter entity, but does not + have standalone="yes". If this handler returns XML_STATUS_ERROR, + then processing will not continue, and the parser will return a + XML_ERROR_NOT_STANDALONE error. + If parameter entity parsing is enabled, then in addition to the + conditions above this handler will only be called if the referenced + entity was actually read. +*/ +public function c_int NotStandaloneHandler(void* userData); + +/* This is called for a reference to an external parsed general + entity. The referenced entity is not automatically parsed. The + application can parse it immediately or later using + XML_ExternalEntityParserCreate. + + The parser argument is the parser parsing the entity containing the + reference; it can be passed as the parser argument to + XML_ExternalEntityParserCreate. The systemId argument is the + system identifier as specified in the entity declaration; it will + not be NULL. + + The base argument is the system identifier that should be used as + the base for resolving systemId if systemId was relative; this is + set by XML_SetBase; it may be NULL. + + The publicId argument is the public identifier as specified in the + entity declaration, or NULL if none was specified; the whitespace + in the public identifier will have been normalized as required by + the XML spec. + + The context argument specifies the parsing context in the format + expected by the context argument to XML_ExternalEntityParserCreate; + context is valid only until the handler returns, so if the + referenced entity is to be parsed later, it must be copied. + context is NULL only when the entity is a parameter entity. + + The handler should return XML_STATUS_ERROR if processing should not + continue because of a fatal error in the handling of the external + entity. In this case the calling parser will return an + XML_ERROR_EXTERNAL_ENTITY_HANDLING error. + + Note that unlike other handlers the first argument is the parser, + not userData. +*/ +public function c_int ExternalEntityRefHandler(Parser parser, Char* context, Char* @base, Char* systemId, Char* publicId); + +/* This is called in two situations: + 1) An entity reference is encountered for which no declaration + has been read *and* this is not an error. + 2) An internal entity reference is read, but not expanded, because + XML_SetDefaultHandler has been called. + Note: skipped parameter entities in declarations and skipped general + entities in attribute values cannot be reported, because + the event would be out of sync with the reporting of the + declarations or attribute values +*/ +public function void SkippedEntityHandler(void* userData, Char* entityName, c_int is_parameter_entity); + +/* This structure is filled in by the XML_UnknownEncodingHandler to + provide information to the parser about encodings that are unknown + to the parser. + + The map[b] member gives information about byte sequences whose + first byte is b. + + If map[b] is c where c is >= 0, then b by itself encodes the + Unicode scalar value c. + + If map[b] is -1, then the byte sequence is malformed. + + If map[b] is -n, where n >= 2, then b is the first byte of an + n-byte sequence that encodes a single Unicode scalar value. + + The data member will be passed as the first argument to the convert + function. + + The convert function is used to convert multibyte sequences; s will + point to a n-byte sequence where map[(unsigned char)*s] == -n. The + convert function must return the Unicode scalar value represented + by this byte sequence or -1 if the byte sequence is malformed. + + The convert function may be NULL if the encoding is a single-byte + encoding, that is if map[b] >= -1 for all bytes b. + + When the parser is finished with the encoding, then if release is + not NULL, it will call release passing it the data member; once + release has been called, the convert function will not be called + again. + + Expat places certain restrictions on the encodings that are supported + using this mechanism. + + 1. Every ASCII character that can appear in a well-formed XML document, + other than the characters + + $@\^`{}~ + + must be represented by a single byte, and that byte must be the + same byte that represents that character in ASCII. + + 2. No character may require more than 4 bytes to encode. + + 3. All characters encoded must have Unicode scalar values <= + 0xFFFF, (i.e., characters that would be encoded by surrogates in + UTF-16 are not allowed). Note that this restriction doesn't + apply to the built-in support for UTF-8 and UTF-16. + + 4. No Unicode character may be encoded by more than one distinct + sequence of bytes. +*/ +[CRepr] public struct Encoding { + public c_int[256] map; + public void* data; + public function c_int(void* data, c_char* s) convert; + public function void(void* data) release; +} + +/* This is called for an encoding that is unknown to the parser. + + The encodingHandlerData argument is that which was passed as the + second argument to XML_SetUnknownEncodingHandler. + + The name argument gives the name of the encoding as specified in + the encoding declaration. + + If the callback can provide information about the encoding, it must + fill in the XML_Encoding structure, and return XML_STATUS_OK. + Otherwise it must return XML_STATUS_ERROR. + + If info does not describe a suitable encoding, then the parser will + return an XML_ERROR_UNKNOWN_ENCODING error. +*/ +public function c_int UnknownEncodingHandler(void* encodingHandlerData, Char* name, Encoding* info); + + +[LinkName("XML_SetElementHandler")] public static extern void SetElementHandler(Parser parser, StartElementHandler start, EndElementHandler end); + + +[LinkName("XML_SetStartElementHandler")] public static extern void SetStartElementHandler(Parser parser, StartElementHandler handler); + + +[LinkName("XML_SetEndElementHandler")] public static extern void SetEndElementHandler(Parser parser, EndElementHandler handler); + + +[LinkName("XML_SetCharacterDataHandler")] public static extern void SetCharacterDataHandler(Parser parser, CharacterDataHandler handler); + + +[LinkName("XML_SetProcessingInstructionHandler")] public static extern void SetProcessingInstructionHandler(Parser parser, ProcessingInstructionHandler handler); + +[LinkName("XML_SetCommentHandler")] public static extern void SetCommentHandler(Parser parser, CommentHandler handler); + + +[LinkName("XML_SetCdataSectionHandler")] public static extern void SetCdataSectionHandler(Parser parser, StartCdataSectionHandler start, EndCdataSectionHandler end); + + +[LinkName("XML_SetStartCdataSectionHandler")] public static extern void SetStartCdataSectionHandler(Parser parser, StartCdataSectionHandler start); + + +[LinkName("XML_SetEndCdataSectionHandler")] public static extern void SetEndCdataSectionHandler(Parser parser, EndCdataSectionHandler end); + +/* This sets the default handler and also inhibits expansion of + internal entities. These entity references will be passed to the + default handler, or to the skipped entity handler, if one is set. +*/ + +[LinkName("XML_SetDefaultHandler")] public static extern void SetDefaultHandler(Parser parser, DefaultHandler handler); + +/* This sets the default handler but does not inhibit expansion of + internal entities. The entity reference will not be passed to the + default handler. +*/ + +[LinkName("XML_SetDefaultHandlerExpand")] public static extern void SetDefaultHandlerExpand(Parser parser, DefaultHandler handler); + + +[LinkName("XML_SetDoctypeDeclHandler")] public static extern void SetDoctypeDeclHandler(Parser parser, StartDoctypeDeclHandler start, EndDoctypeDeclHandler end); + + +[LinkName("XML_SetStartDoctypeDeclHandler")] public static extern void SetStartDoctypeDeclHandler(Parser parser, StartDoctypeDeclHandler start); + + +[LinkName("XML_SetEndDoctypeDeclHandler")] public static extern void SetEndDoctypeDeclHandler(Parser parser, EndDoctypeDeclHandler end); + + +[LinkName("XML_SetUnparsedEntityDeclHandler")] public static extern void SetUnparsedEntityDeclHandler(Parser parser, UnparsedEntityDeclHandler handler); + + +[LinkName("XML_SetNotationDeclHandler")] public static extern void SetNotationDeclHandler(Parser parser, NotationDeclHandler handler); + + +[LinkName("XML_SetNamespaceDeclHandler")] public static extern void SetNamespaceDeclHandler(Parser parser, StartNamespaceDeclHandler start, EndNamespaceDeclHandler end); + + +[LinkName("XML_SetStartNamespaceDeclHandler")] public static extern void SetStartNamespaceDeclHandler(Parser parser, StartNamespaceDeclHandler start); + + +[LinkName("XML_SetEndNamespaceDeclHandler")] public static extern void SetEndNamespaceDeclHandler(Parser parser, EndNamespaceDeclHandler end); + + +[LinkName("XML_SetNotStandaloneHandler")] public static extern void SetNotStandaloneHandler(Parser parser, NotStandaloneHandler handler); + + +[LinkName("XML_SetExternalEntityRefHandler")] public static extern void SetExternalEntityRefHandler(Parser parser, ExternalEntityRefHandler handler); + +/* If a non-NULL value for arg is specified here, then it will be + passed as the first argument to the external entity ref handler + instead of the parser object. +*/ + +[LinkName("XML_SetExternalEntityRefHandlerArg")] public static extern void SetExternalEntityRefHandlerArg(Parser parser, void* arg); + + +[LinkName("XML_SetSkippedEntityHandler")] public static extern void SetSkippedEntityHandler(Parser parser, SkippedEntityHandler handler); + + +[LinkName("XML_SetUnknownEncodingHandler")] public static extern void SetUnknownEncodingHandler(Parser parser, UnknownEncodingHandler handler, void* encodingHandlerData); + +/* This can be called within a handler for a start element, end + element, processing instruction or character data. It causes the + corresponding markup to be passed to the default handler. +*/ + +[LinkName("XML_DefaultCurrent")] public static extern void DefaultCurrent(Parser parser); + +/* If do_nst is non-zero, and namespace processing is in effect, and + a name has a prefix (i.e. an explicit namespace qualifier) then + that name is returned as a triplet in a single string separated by + the separator character specified when the parser was created: URI + + sep + local_name + sep + prefix. + + If do_nst is zero, then namespace information is returned in the + default manner (URI + sep + local_name) whether or not the name + has a prefix. + + Note: Calling XML_SetReturnNSTriplet after XML_Parse or + XML_ParseBuffer has no effect. +*/ + + +[LinkName("XML_SetReturnNSTriplet")] public static extern void SetReturnNSTriplet(Parser parser, c_int do_nst); + +/* This value is passed as the userData argument to callbacks. */ + +[LinkName("XML_SetUserData")] public static extern void SetUserData(Parser parser, void* userData); + +/* Returns the last value set by XML_SetUserData or NULL. */ + + +/* This is equivalent to supplying an encoding argument to + XML_ParserCreate. On success XML_SetEncoding returns non-zero, + zero otherwise. + Note: Calling XML_SetEncoding after XML_Parse or XML_ParseBuffer + has no effect and returns XML_STATUS_ERROR. +*/ + +[LinkName("XML_SetEncoding")] public static extern Status SetEncoding(Parser parser, Char* encoding); + +/* If this function is called, then the parser will be passed as the + first argument to callbacks instead of userData. The userData will + still be accessible using XML_GetUserData. +*/ + +[LinkName("XML_UseParserAsHandlerArg")] public static extern void UseParserAsHandlerArg(Parser parser); + +/* If useDTD == XML_TRUE is passed to this function, then the parser + will assume that there is an external subset, even if none is + specified in the document. In such a case the parser will call the + externalEntityRefHandler with a value of NULL for the systemId + argument (the publicId and context arguments will be NULL as well). + Note: For the purpose of checking WFC: Entity Declared, passing + useDTD == XML_TRUE will make the parser behave as if the document + had a DTD with an external subset. + Note: If this function is called, then this must be done before + the first call to XML_Parse or XML_ParseBuffer, since it will + have no effect after that. Returns + XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING. + Note: If the document does not have a DOCTYPE declaration at all, + then startDoctypeDeclHandler and endDoctypeDeclHandler will not + be called, despite an external subset being parsed. + Note: If XML_DTD is not defined when Expat is compiled, returns + XML_ERROR_FEATURE_REQUIRES_XML_DTD. + Note: If parser == NULL, returns XML_ERROR_INVALID_ARGUMENT. +*/ + +[LinkName("XML_UseForeignDTD")] public static extern Error UseForeignDTD(Parser parser, Bool useDTD); + +/* Sets the base to be used for resolving relative URIs in system + identifiers in declarations. Resolving relative identifiers is + left to the application: this value will be passed through as the + base argument to the XML_ExternalEntityRefHandler, + XML_NotationDeclHandler and XML_UnparsedEntityDeclHandler. The base + argument will be copied. Returns XML_STATUS_ERROR if out of memory, + XML_STATUS_OK otherwise. +*/ + +[LinkName("XML_SetBase")] public static extern Status SetBase(Parser parser, Char* @base); + + +[LinkName("XML_GetBase")] public static extern Char* GetBase(Parser parser); + +/* Returns the number of the attribute/value pairs passed in last call + to the XML_StartElementHandler that were specified in the start-tag + rather than defaulted. Each attribute/value pair counts as 2; thus + this corresponds to an index into the atts array passed to the + XML_StartElementHandler. Returns -1 if parser == NULL. +*/ + +[LinkName("XML_GetSpecifiedAttributeCount")] public static extern c_int GetSpecifiedAttributeCount(Parser parser); + +/* Returns the index of the ID attribute passed in the last call to + XML_StartElementHandler, or -1 if there is no ID attribute or + parser == NULL. Each attribute/value pair counts as 2; thus this + corresponds to an index into the atts array passed to the + XML_StartElementHandler. +*/ + +[LinkName("XML_GetIdAttributeIndex")] public static extern c_int GetIdAttributeIndex(Parser parser); + + +/* Source file byte offsets for the start and end of attribute names and values. + The value indices are exclusive of surrounding quotes; thus in a UTF-8 source + file an attribute value of "blah" will yield: + info->valueEnd - info->valueStart = 4 bytes. +*/ + + /* Offset to beginning of the attribute name. */ + /* Offset after the attribute name's last byte. */ + /* Offset to beginning of the attribute value. */ + /* Offset after the attribute value's last byte. */ + + +/* Returns an array of XML_AttrInfo structures for the attribute/value pairs + passed in last call to the XML_StartElementHandler that were specified + in the start-tag rather than defaulted. Each attribute/value pair counts + as 1; thus the number of entries in the array is + XML_GetSpecifiedAttributeCount(parser) / 2. +*/ + + + + +/* Parses some input. Returns XML_STATUS_ERROR if a fatal error is + detected. The last call to XML_Parse must have isFinal true; len + may be zero for this call (or any other). + + Though the return values for these functions has always been + described as a Boolean value, the implementation, at least for the + 1.95.x series, has always returned exactly one of the XML_Status + values. +*/ + +[LinkName("XML_Parse")] public static extern Status Parse(Parser parser, c_char* s, c_int len, c_int isFinal); + + +[LinkName("XML_GetBuffer")] public static extern void* GetBuffer(Parser parser, c_int len); + + +[LinkName("XML_ParseBuffer")] public static extern Status ParseBuffer(Parser parser, c_int len, c_int isFinal); + +/* Stops parsing, causing XML_Parse() or XML_ParseBuffer() to return. + Must be called from within a call-back handler, except when aborting + (resumable = 0) an already suspended parser. Some call-backs may + still follow because they would otherwise get lost. Examples: + - endElementHandler() for empty elements when stopped in + startElementHandler(), + - endNameSpaceDeclHandler() when stopped in endElementHandler(), + and possibly others. + + Can be called from most handlers, including DTD related call-backs, + except when parsing an external parameter entity and resumable != 0. + Returns XML_STATUS_OK when successful, XML_STATUS_ERROR otherwise. + Possible error codes: + - XML_ERROR_SUSPENDED: when suspending an already suspended parser. + - XML_ERROR_FINISHED: when the parser has already finished. + - XML_ERROR_SUSPEND_PE: when suspending while parsing an external PE. + + When resumable != 0 (true) then parsing is suspended, that is, + XML_Parse() and XML_ParseBuffer() return XML_STATUS_SUSPENDED. + Otherwise, parsing is aborted, that is, XML_Parse() and XML_ParseBuffer() + return XML_STATUS_ERROR with error code XML_ERROR_ABORTED. + + *Note*: + This will be applied to the current parser instance only, that is, if + there is a parent parser then it will continue parsing when the + externalEntityRefHandler() returns. It is up to the implementation of + the externalEntityRefHandler() to call XML_StopParser() on the parent + parser (recursively), if one wants to stop parsing altogether. + + When suspended, parsing can be resumed by calling XML_ResumeParser(). +*/ + +[LinkName("XML_StopParser")] public static extern Status StopParser(Parser parser, Bool resumable); + +/* Resumes parsing after it has been suspended with XML_StopParser(). + Must not be called from within a handler call-back. Returns same + status codes as XML_Parse() or XML_ParseBuffer(). + Additional error code XML_ERROR_NOT_SUSPENDED possible. + + *Note*: + This must be called on the most deeply nested child parser instance + first, and on its parent parser only after the child parser has finished, + to be applied recursively until the document entity's parser is restarted. + That is, the parent parser will not resume by itself and it is up to the + application to call XML_ResumeParser() on it at the appropriate moment. +*/ + +[LinkName("XML_ResumeParser")] public static extern Status ResumeParser(Parser parser); + +[AllowDuplicates] public enum Parsing : c_int { XmlInitialized, XmlParsing, XmlFinished, XmlSuspended, } + +[CRepr] public struct ParsingStatus { + public Parsing parsing; + public Bool finalBuffer; +} + +/* Returns status of parser with respect to being initialized, parsing, + finished, or suspended and processing the final buffer. + XXX XML_Parse() and XML_ParseBuffer() should return XML_ParsingStatus, + XXX with XML_FINISHED_OK or XML_FINISHED_ERROR replacing XML_FINISHED +*/ + +[LinkName("XML_GetParsingStatus")] public static extern void GetParsingStatus(Parser parser, ParsingStatus* status); + +/* Creates an XML_Parser object that can parse an external general + entity; context is a '\0'-terminated string specifying the parse + context; encoding is a '\0'-terminated string giving the name of + the externally specified encoding, or NULL if there is no + externally specified encoding. The context string consists of a + sequence of tokens separated by formfeeds (\f); a token consisting + of a name specifies that the general entity of the name is open; a + token of the form prefix=uri specifies the namespace for a + particular prefix; a token of the form =uri specifies the default + namespace. This can be called at any point after the first call to + an ExternalEntityRefHandler so longer as the parser has not yet + been freed. The new parser is completely independent and may + safely be used in a separate thread. The handlers and userData are + initialized from the parser argument. Returns NULL if out of memory. + Otherwise returns a new XML_Parser object. +*/ + +[LinkName("XML_ExternalEntityParserCreate")] public static extern Parser ExternalEntityParserCreate(Parser parser, Char* context, Char* encoding); + +[AllowDuplicates] public enum ParamEntityParsing : c_int { + Never, + UnlessStandalone, + Always, +} + +/* Controls parsing of parameter entities (including the external DTD + subset). If parsing of parameter entities is enabled, then + references to external parameter entities (including the external + DTD subset) will be passed to the handler set with + XML_SetExternalEntityRefHandler. The context passed will be 0. + + Unlike external general entities, external parameter entities can + only be parsed synchronously. If the external parameter entity is + to be parsed, it must be parsed during the call to the external + entity ref handler: the complete sequence of + XML_ExternalEntityParserCreate, XML_Parse/XML_ParseBuffer and + XML_ParserFree calls must be made during this call. After + XML_ExternalEntityParserCreate has been called to create the parser + for the external parameter entity (context must be 0 for this + call), it is illegal to make any calls on the old parser until + XML_ParserFree has been called on the newly created parser. + If the library has been compiled without support for parameter + entity parsing (ie without XML_DTD being defined), then + XML_SetParamEntityParsing will return 0 if parsing of parameter + entities is requested; otherwise it will return non-zero. + Note: If XML_SetParamEntityParsing is called after XML_Parse or + XML_ParseBuffer, then it has no effect and will always return 0. + Note: If parser == NULL, the function will do nothing and return 0. +*/ + +[LinkName("XML_SetParamEntityParsing")] public static extern c_int SetParamEntityParsing(Parser parser, ParamEntityParsing parsing); + +/* Sets the hash salt to use for internal hash calculations. + Helps in preventing DoS attacks based on predicting hash + function behavior. This must be called before parsing is started. + Returns 1 if successful, 0 when called after parsing has started. + Note: If parser == NULL, the function will do nothing and return 0. +*/ + +[LinkName("XML_SetHashSalt")] public static extern c_int SetHashSalt(Parser parser, c_ulong hash_salt); + +/* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then + XML_GetErrorCode returns information about the error. +*/ + +[LinkName("XML_GetErrorCode")] public static extern Error GetErrorCode(Parser parser); + +/* These functions return information about the current parse + location. They may be called from any callback called to report + some parse event; in this case the location is the location of the + first of the sequence of characters that generated the event. When + called from callbacks generated by declarations in the document + prologue, the location identified isn't as neatly defined, but will + be within the relevant markup. When called outside of the callback + functions, the position indicated will be just past the last parse + event (regardless of whether there was an associated callback). + + They may also be called after returning from a call to XML_Parse + or XML_ParseBuffer. If the return value is XML_STATUS_ERROR then + the location is the location of the character at which the error + was detected; otherwise the location is the location of the last + parse event, as described above. + + Note: XML_GetCurrentLineNumber and XML_GetCurrentColumnNumber + return 0 to indicate an error. + Note: XML_GetCurrentByteIndex returns -1 to indicate an error. +*/ +[LinkName("XML_GetCurrentLineNumber")] public static extern Size GetCurrentLineNumber(Parser parser); +[LinkName("XML_GetCurrentColumnNumber")] public static extern Size GetCurrentColumnNumber(Parser parser); +[LinkName("XML_GetCurrentByteIndex")] public static extern Index GetCurrentByteIndex(Parser parser); + +/* Return the number of bytes in the current event. + Returns 0 if the event is in an internal entity. +*/ + +[LinkName("XML_GetCurrentByteCount")] public static extern c_int GetCurrentByteCount(Parser parser); + +/* If XML_CONTEXT_BYTES is >=1, returns the input buffer, sets + the integer pointed to by offset to the offset within this buffer + of the current parse position, and sets the integer pointed to by size + to the size of this buffer (the number of input bytes). Otherwise + returns a NULL pointer. Also returns a NULL pointer if a parse isn't + active. + + NOTE: The character pointer returned should not be used outside + the handler that makes the call. +*/ + +[LinkName("XML_GetInputContext")] public static extern c_char* GetInputContext(Parser parser, c_int* offset, c_int* size); + +/* For backwards compatibility with previous versions. */ + + + + +/* Frees the content model passed to the element declaration handler */ + +[LinkName("XML_FreeContentModel")] public static extern void FreeContentModel(Parser parser, Content* model); + +/* Exposing the memory handling functions used in Expat */ + + + +[LinkName("XML_MemMalloc")] public static extern void* MemMalloc(Parser parser, c_size size); + + + +[LinkName("XML_MemRealloc")] public static extern void* MemRealloc(Parser parser, void* ptr, c_size size); + + +[LinkName("XML_MemFree")] public static extern void MemFree(Parser parser, void* ptr); + +/* Frees memory used by the parser. */ + +[LinkName("XML_ParserFree")] public static extern void ParserFree(Parser parser); + +/* Returns a string describing the error. */ + +[LinkName("XML_ErrorString")] public static extern LChar* ErrorString(Error code); + +/* Return a string containing the version number of this expat */ + +[LinkName("XML_ExpatVersion")] public static extern LChar* ExpatVersion(); + +[CRepr] public struct Expat_Version { + public c_int major; + public c_int minor; + public c_int micro; +} + +/* Return an XML_Expat_Version structure containing numeric version + number information for this version of expat. +*/ + +[LinkName("XML_ExpatVersionInfo")] public static extern Expat_Version ExpatVersionInfo(); + +/* Added in Expat 1.95.5. */ +[AllowDuplicates] public enum FeatureEnum : c_int { + End = 0, + Unicode, + UnicodeWcharT, + Dtd, + ContextBytes, + MinSize, + SizeofXmlChar, + SizeofXmlLchar, + Ns, + LargeSize, + AttrInfo, + /* Added in Expat 2.4.0. */ + BillionLaughsAttackProtectionMaximumAmplificationDefault, + BillionLaughsAttackProtectionActivationThresholdDefault, + /* Added in Expat 2.6.0. */ + Ge, + /* Added in Expat 2.7.2. */ + AllocTrackerMaximumAmplificationDefault, + AllocTrackerActivationThresholdDefault, + /* Additional features must be added to the end of this enum. */ +} + +[CRepr] public struct Feature { + public FeatureEnum feature; + public LChar* name; + public c_long value; +} + + +[LinkName("XML_GetFeatureList")] public static extern Feature* GetFeatureList(); + + +/* Added in Expat 2.4.0 for XML_DTD defined and + * added in Expat 2.6.0 for XML_GE == 1. */ + + + + +/* Added in Expat 2.4.0 for XML_DTD defined and + * added in Expat 2.6.0 for XML_GE == 1. */ + + + + +/* Added in Expat 2.7.2. */ + + + + +/* Added in Expat 2.7.2. */ + + + + + +/* Added in Expat 2.6.0. */ + +[LinkName("XML_SetReparseDeferralEnabled")] public static extern Bool SetReparseDeferralEnabled(Parser parser, Bool enabled); + +/* Expat follows the semantic versioning convention. + See https://semver.org +*/ +public const let MAJOR_VERSION = 2; +public const let MINOR_VERSION = 7; +public const let MICRO_VERSION = 4; +} + + + + + + + +/* not Expat_INCLUDED */ \ No newline at end of file diff --git a/src/Wrapper.bf b/src/Wrapper.bf new file mode 100644 index 0000000..5e790ae --- /dev/null +++ b/src/Wrapper.bf @@ -0,0 +1,1072 @@ +// This file was generated by Expat.Setup + +using System; +using System.Interop; + +namespace Expat; + +class XmlParser +{ + private XML.Parser handle ~ XML.ParserFree(_); + public Result ParserInitResult => handle == default ? .Err : .Ok; + +/* + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 1997-2000 Thai Open Source Software Center Ltd + Copyright (c) 2000 Clark Cooper + Copyright (c) 2000-2005 Fred L. Drake, Jr. + Copyright (c) 2001-2002 Greg Stein + Copyright (c) 2002-2016 Karl Waclawek + Copyright (c) 2016-2026 Sebastian Pipping + Copyright (c) 2016 Cristian Rodríguez + Copyright (c) 2016 Thomas Beutlich + Copyright (c) 2017 Rhodri James + Copyright (c) 2022 Thijs Schreijer + Copyright (c) 2023 Hanno Böck + Copyright (c) 2023 Sony Corporation / Snild Dolkow + Copyright (c) 2024 Taichi Haradaguchi <20001722@ymail.ne.jp> + Copyright (c) 2025 Matthew Fernandez + Licensed under the MIT license: + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to permit + persons to whom the Software is furnished to do so, subject to the + following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + + + + + + + + + + + + + + + + + + +/* The XML_Status enum gives the possible return values for several + API functions. The preprocessor #defines are included so this + stanza can be added to code that still needs to support older + versions of Expat 1.95.x: + + #ifndef XML_STATUS_OK + #define XML_STATUS_OK 1 + #define XML_STATUS_ERROR 0 + #endif + + Otherwise, the #define hackery is quite ugly and would have been + dropped. +*/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + /* Added in 1.95.7. */ + + /* Added in 1.95.8. */ + + + + + + + + + + + /* Added in 2.0. */ + + + + /* Added in 2.2.1. */ + + /* Added in 2.3.0. */ + + /* Added in 2.4.0. */ + + /* Added in 2.6.4. */ + + + + + + + + + + + + + + + + + + + +/* If type == XML_CTYPE_EMPTY or XML_CTYPE_ANY, then quant will be + XML_CQUANT_NONE, and the other fields will be zero or NULL. + If type == XML_CTYPE_MIXED, then quant will be NONE or REP and + numchildren will contain number of elements that may be mixed in + and children point to an array of XML_Content cells that will be + all of XML_CTYPE_NAME type with no quantification. + + If type == XML_CTYPE_NAME, then the name points to the name, and + the numchildren field will be zero and children will be NULL. The + quant fields indicates any quantifiers placed on the name. + + CHOICE and SEQ will have name NULL, the number of children in + numchildren and children will point, recursively, to an array + of XML_Content cells. + + The EMPTY, ANY, and MIXED types will only occur at top level. +*/ + + + + + + + + + + + +/* This is called for an element declaration. See above for + description of the model argument. It's the user code's responsibility + to free model when finished with it. See XML_FreeContentModel. + There is no need to free the model from the handler, it can be kept + around and freed at a later stage. +*/ +public virtual void ElementDeclHandler(XML.Char* name, XML.Content* model) {} + + +[Inline] public void SetElementDeclHandler(XML.ElementDeclHandler eldecl) => XML.SetElementDeclHandler(handle, eldecl); + +/* The Attlist declaration handler is called for *each* attribute. So + a single Attlist declaration with multiple attributes declared will + generate multiple calls to this handler. The "default" parameter + may be NULL in the case of the "#IMPLIED" or "#REQUIRED" + keyword. The "isrequired" parameter will be true and the default + value will be NULL in the case of "#REQUIRED". If "isrequired" is + true and default is non-NULL, then this is a "#FIXED" default. +*/ +public virtual void AttlistDeclHandler(XML.Char* elname, XML.Char* attname, XML.Char* att_type, XML.Char* dflt, c_int isrequired) {} + + +[Inline] public void SetAttlistDeclHandler(XML.AttlistDeclHandler attdecl) => XML.SetAttlistDeclHandler(handle, attdecl); + +/* The XML declaration handler is called for *both* XML declarations + and text declarations. The way to distinguish is that the version + parameter will be NULL for text declarations. The encoding + parameter may be NULL for XML declarations. The standalone + parameter will be -1, 0, or 1 indicating respectively that there + was no standalone parameter in the declaration, that it was given + as no, or that it was given as yes. +*/ +public virtual void XmlDeclHandler(XML.Char* version, XML.Char* encoding, c_int standalone) {} + + +[Inline] public void SetXmlDeclHandler(XML.XmlDeclHandler xmldecl) => XML.SetXmlDeclHandler(handle, xmldecl); + + + + + + + +/* Constructs a new parser; encoding is the encoding specified by the + external protocol or NULL if there is none specified. +*/ + +[Inline] public this(XML.Char* encoding) { handle = XML.ParserCreate(encoding); InitHandlers(); } + +/* Constructs a new parser and namespace processor. Element type + names and attribute names that belong to a namespace will be + expanded; unprefixed attribute names are never expanded; unprefixed + element type names are expanded only if there is a default + namespace. The expanded name is the concatenation of the namespace + URI, the namespace separator character, and the local part of the + name. If the namespace separator is '\0' then the namespace URI + and the local part will be concatenated without any separator. + It is a programming error to use the separator '\0' with namespace + triplets (see XML_SetReturnNSTriplet). + If a namespace separator is chosen that can be part of a URI or + part of an XML name, splitting an expanded name back into its + 1, 2 or 3 original parts on application level in the element handler + may end up vulnerable, so these are advised against; sane choices for + a namespace separator are e.g. '\n' (line feed) and '|' (pipe). + + Note that Expat does not validate namespace URIs (beyond encoding) + against RFC 3986 today (and is not required to do so with regard to + the XML 1.0 namespaces specification) but it may start doing that + in future releases. Before that, an application using Expat must + be ready to receive namespace URIs containing non-URI characters. +*/ + +[Inline] public this(XML.Char* encoding, XML.Char namespaceSeparator) { handle = XML.ParserCreateNS(encoding, namespaceSeparator); InitHandlers(); } + +/* Constructs a new parser using the memory management suite referred to + by memsuite. If memsuite is NULL, then use the standard library memory + suite. If namespaceSeparator is non-NULL it creates a parser with + namespace processing as described above. The character pointed at + will serve as the namespace separator. + + All further memory operations used for the created parser will come from + the given suite. +*/ + +[Inline] public this(XML.Char* encoding, XML.Memory_Handling_Suite* memsuite, XML.Char* namespaceSeparator) { handle = XML.ParserCreate_MM(encoding, memsuite, namespaceSeparator); InitHandlers(); } + +/* Prepare a parser object to be reused. This is particularly + valuable when memory allocation overhead is disproportionately high, + such as when a large number of small documents need to be parsed. + All handlers are cleared from the parser, except for the + unknownEncodingHandler. The parser's external state is re-initialized + except for the values of ns and ns_triplets. + + Added in Expat 1.95.3. +*/ + +[Inline] public XML.Bool Reset(XML.Char* encoding) => XML.ParserReset(handle, encoding); + +/* atts is array of name/value pairs, terminated by 0; + names and values are 0 terminated. +*/ +public virtual void StartElementHandler(XML.Char* name, XML.Char** atts) {} + +public virtual void EndElementHandler(XML.Char* name) {} + +/* s is not 0 terminated. */ +public virtual void CharacterDataHandler(XML.Char* s, c_int len) {} + +/* target and data are 0 terminated */ +public virtual void ProcessingInstructionHandler(XML.Char* target, XML.Char* data) {} + +/* data is 0 terminated */ +public virtual void CommentHandler(XML.Char* data) {} + +public virtual void StartCdataSectionHandler() {} +public virtual void EndCdataSectionHandler() {} + +/* This is called for any characters in the XML document for which + there is no applicable handler. This includes both characters that + are part of markup which is of a kind that is not reported + (comments, markup declarations), or characters that are part of a + construct which could be reported but for which no handler has been + supplied. The characters are passed exactly as they were in the XML + document except that they will be encoded in UTF-8 or UTF-16. + Line boundaries are not normalized. Note that a byte order mark + character is not passed to the default handler. There are no + guarantees about how characters are divided between calls to the + default handler: for example, a comment might be split between + multiple calls. +*/ +public virtual void DefaultHandler(XML.Char* s, c_int len) {} + +/* This is called for the start of the DOCTYPE declaration, before + any DTD or internal subset is parsed. +*/ +public virtual void StartDoctypeDeclHandler(XML.Char* doctypeName, XML.Char* sysid, XML.Char* pubid, c_int has_internal_subset) {} + +/* This is called for the end of the DOCTYPE declaration when the + closing > is encountered, but after processing any external + subset. +*/ +public virtual void EndDoctypeDeclHandler() {} + +/* This is called for entity declarations. The is_parameter_entity + argument will be non-zero if the entity is a parameter entity, zero + otherwise. + + For internal entities (), value will + be non-NULL and systemId, publicID, and notationName will be NULL. + The value string is NOT null-terminated; the length is provided in + the value_length argument. Since it is legal to have zero-length + values, do not use this argument to test for internal entities. + + For external entities, value will be NULL and systemId will be + non-NULL. The publicId argument will be NULL unless a public + identifier was provided. The notationName argument will have a + non-NULL value only for unparsed entity declarations. + + Note that is_parameter_entity can't be changed to XML_Bool, since + that would break binary compatibility. +*/ +public virtual void EntityDeclHandler(XML.Char* entityName, c_int is_parameter_entity, XML.Char* value, c_int value_length, XML.Char* @base, XML.Char* systemId, XML.Char* publicId, XML.Char* notationName) {} + + +[Inline] public void SetEntityDeclHandler(XML.EntityDeclHandler handler) => XML.SetEntityDeclHandler(handle, handler); + +/* OBSOLETE -- OBSOLETE -- OBSOLETE + This handler has been superseded by the EntityDeclHandler above. + It is provided here for backward compatibility. + + This is called for a declaration of an unparsed (NDATA) entity. + The base argument is whatever was set by XML_SetBase. The + entityName, systemId and notationName arguments will never be + NULL. The other arguments may be. +*/ +public virtual void UnparsedEntityDeclHandler(XML.Char* entityName, XML.Char* @base, XML.Char* systemId, XML.Char* publicId, XML.Char* notationName) {} + +/* This is called for a declaration of notation. The base argument is + whatever was set by XML_SetBase. The notationName will never be + NULL. The other arguments can be. +*/ +public virtual void NotationDeclHandler(XML.Char* notationName, XML.Char* @base, XML.Char* systemId, XML.Char* publicId) {} + +/* When namespace processing is enabled, these are called once for + each namespace declaration. The call to the start and end element + handlers occur between the calls to the start and end namespace + declaration handlers. For an xmlns attribute, prefix will be + NULL. For an xmlns="" attribute, uri will be NULL. +*/ +public virtual void StartNamespaceDeclHandler(XML.Char* prefix, XML.Char* uri) {} + +public virtual void EndNamespaceDeclHandler(XML.Char* prefix) {} + +/* This is called if the document is not standalone, that is, it has an + external subset or a reference to a parameter entity, but does not + have standalone="yes". If this handler returns XML_STATUS_ERROR, + then processing will not continue, and the parser will return a + XML_ERROR_NOT_STANDALONE error. + If parameter entity parsing is enabled, then in addition to the + conditions above this handler will only be called if the referenced + entity was actually read. +*/ +public virtual c_int NotStandaloneHandler() => default; + +/* This is called for a reference to an external parsed general + entity. The referenced entity is not automatically parsed. The + application can parse it immediately or later using + XML_ExternalEntityParserCreate. + + The parser argument is the parser parsing the entity containing the + reference; it can be passed as the parser argument to + XML_ExternalEntityParserCreate. The systemId argument is the + system identifier as specified in the entity declaration; it will + not be NULL. + + The base argument is the system identifier that should be used as + the base for resolving systemId if systemId was relative; this is + set by XML_SetBase; it may be NULL. + + The publicId argument is the public identifier as specified in the + entity declaration, or NULL if none was specified; the whitespace + in the public identifier will have been normalized as required by + the XML spec. + + The context argument specifies the parsing context in the format + expected by the context argument to XML_ExternalEntityParserCreate; + context is valid only until the handler returns, so if the + referenced entity is to be parsed later, it must be copied. + context is NULL only when the entity is a parameter entity. + + The handler should return XML_STATUS_ERROR if processing should not + continue because of a fatal error in the handling of the external + entity. In this case the calling parser will return an + XML_ERROR_EXTERNAL_ENTITY_HANDLING error. + + Note that unlike other handlers the first argument is the parser, + not userData. +*/ + + + + + + +/* This is called in two situations: + 1) An entity reference is encountered for which no declaration + has been read *and* this is not an error. + 2) An internal entity reference is read, but not expanded, because + XML_SetDefaultHandler has been called. + Note: skipped parameter entities in declarations and skipped general + entities in attribute values cannot be reported, because + the event would be out of sync with the reporting of the + declarations or attribute values +*/ +public virtual void SkippedEntityHandler(XML.Char* entityName, c_int is_parameter_entity) {} + +/* This structure is filled in by the XML_UnknownEncodingHandler to + provide information to the parser about encodings that are unknown + to the parser. + + The map[b] member gives information about byte sequences whose + first byte is b. + + If map[b] is c where c is >= 0, then b by itself encodes the + Unicode scalar value c. + + If map[b] is -1, then the byte sequence is malformed. + + If map[b] is -n, where n >= 2, then b is the first byte of an + n-byte sequence that encodes a single Unicode scalar value. + + The data member will be passed as the first argument to the convert + function. + + The convert function is used to convert multibyte sequences; s will + point to a n-byte sequence where map[(unsigned char)*s] == -n. The + convert function must return the Unicode scalar value represented + by this byte sequence or -1 if the byte sequence is malformed. + + The convert function may be NULL if the encoding is a single-byte + encoding, that is if map[b] >= -1 for all bytes b. + + When the parser is finished with the encoding, then if release is + not NULL, it will call release passing it the data member; once + release has been called, the convert function will not be called + again. + + Expat places certain restrictions on the encodings that are supported + using this mechanism. + + 1. Every ASCII character that can appear in a well-formed XML document, + other than the characters + + $@\^`{}~ + + must be represented by a single byte, and that byte must be the + same byte that represents that character in ASCII. + + 2. No character may require more than 4 bytes to encode. + + 3. All characters encoded must have Unicode scalar values <= + 0xFFFF, (i.e., characters that would be encoded by surrogates in + UTF-16 are not allowed). Note that this restriction doesn't + apply to the built-in support for UTF-8 and UTF-16. + + 4. No Unicode character may be encoded by more than one distinct + sequence of bytes. +*/ + + + + + + + +/* This is called for an encoding that is unknown to the parser. + + The encodingHandlerData argument is that which was passed as the + second argument to XML_SetUnknownEncodingHandler. + + The name argument gives the name of the encoding as specified in + the encoding declaration. + + If the callback can provide information about the encoding, it must + fill in the XML_Encoding structure, and return XML_STATUS_OK. + Otherwise it must return XML_STATUS_ERROR. + + If info does not describe a suitable encoding, then the parser will + return an XML_ERROR_UNKNOWN_ENCODING error. +*/ + + + + + +[Inline] public void SetElementHandler(XML.StartElementHandler start, XML.EndElementHandler end) => XML.SetElementHandler(handle, start, end); + + +[Inline] public void SetStartElementHandler(XML.StartElementHandler handler) => XML.SetStartElementHandler(handle, handler); + + +[Inline] public void SetEndElementHandler(XML.EndElementHandler handler) => XML.SetEndElementHandler(handle, handler); + + +[Inline] public void SetCharacterDataHandler(XML.CharacterDataHandler handler) => XML.SetCharacterDataHandler(handle, handler); + + +[Inline] public void SetProcessingInstructionHandler(XML.ProcessingInstructionHandler handler) => XML.SetProcessingInstructionHandler(handle, handler); + +[Inline] public void SetCommentHandler(XML.CommentHandler handler) => XML.SetCommentHandler(handle, handler); + + +[Inline] public void SetCdataSectionHandler(XML.StartCdataSectionHandler start, XML.EndCdataSectionHandler end) => XML.SetCdataSectionHandler(handle, start, end); + + +[Inline] public void SetStartCdataSectionHandler(XML.StartCdataSectionHandler start) => XML.SetStartCdataSectionHandler(handle, start); + + +[Inline] public void SetEndCdataSectionHandler(XML.EndCdataSectionHandler end) => XML.SetEndCdataSectionHandler(handle, end); + +/* This sets the default handler and also inhibits expansion of + internal entities. These entity references will be passed to the + default handler, or to the skipped entity handler, if one is set. +*/ + +[Inline] public void SetDefaultHandler(XML.DefaultHandler handler) => XML.SetDefaultHandler(handle, handler); + +/* This sets the default handler but does not inhibit expansion of + internal entities. The entity reference will not be passed to the + default handler. +*/ + +[Inline] public void SetDefaultHandlerExpand(XML.DefaultHandler handler) => XML.SetDefaultHandlerExpand(handle, handler); + + +[Inline] public void SetDoctypeDeclHandler(XML.StartDoctypeDeclHandler start, XML.EndDoctypeDeclHandler end) => XML.SetDoctypeDeclHandler(handle, start, end); + + +[Inline] public void SetStartDoctypeDeclHandler(XML.StartDoctypeDeclHandler start) => XML.SetStartDoctypeDeclHandler(handle, start); + + +[Inline] public void SetEndDoctypeDeclHandler(XML.EndDoctypeDeclHandler end) => XML.SetEndDoctypeDeclHandler(handle, end); + + +[Inline] public void SetUnparsedEntityDeclHandler(XML.UnparsedEntityDeclHandler handler) => XML.SetUnparsedEntityDeclHandler(handle, handler); + + +[Inline] public void SetNotationDeclHandler(XML.NotationDeclHandler handler) => XML.SetNotationDeclHandler(handle, handler); + + +[Inline] public void SetNamespaceDeclHandler(XML.StartNamespaceDeclHandler start, XML.EndNamespaceDeclHandler end) => XML.SetNamespaceDeclHandler(handle, start, end); + + +[Inline] public void SetStartNamespaceDeclHandler(XML.StartNamespaceDeclHandler start) => XML.SetStartNamespaceDeclHandler(handle, start); + + +[Inline] public void SetEndNamespaceDeclHandler(XML.EndNamespaceDeclHandler end) => XML.SetEndNamespaceDeclHandler(handle, end); + + +[Inline] public void SetNotStandaloneHandler(XML.NotStandaloneHandler handler) => XML.SetNotStandaloneHandler(handle, handler); + + +[Inline] public void SetExternalEntityRefHandler(XML.ExternalEntityRefHandler handler) => XML.SetExternalEntityRefHandler(handle, handler); + +/* If a non-NULL value for arg is specified here, then it will be + passed as the first argument to the external entity ref handler + instead of the parser object. +*/ + +[Inline] public void SetExternalEntityRefHandlerArg(void* arg) => XML.SetExternalEntityRefHandlerArg(handle, arg); + + +[Inline] public void SetSkippedEntityHandler(XML.SkippedEntityHandler handler) => XML.SetSkippedEntityHandler(handle, handler); + + +[Inline] public void SetUnknownEncodingHandler(XML.UnknownEncodingHandler handler, void* encodingHandlerData) => XML.SetUnknownEncodingHandler(handle, handler, encodingHandlerData); + +/* This can be called within a handler for a start element, end + element, processing instruction or character data. It causes the + corresponding markup to be passed to the default handler. +*/ + +[Inline] public void DefaultCurrent() => XML.DefaultCurrent(handle); + +/* If do_nst is non-zero, and namespace processing is in effect, and + a name has a prefix (i.e. an explicit namespace qualifier) then + that name is returned as a triplet in a single string separated by + the separator character specified when the parser was created: URI + + sep + local_name + sep + prefix. + + If do_nst is zero, then namespace information is returned in the + default manner (URI + sep + local_name) whether or not the name + has a prefix. + + Note: Calling XML_SetReturnNSTriplet after XML_Parse or + XML_ParseBuffer has no effect. +*/ + + +[Inline] public void SetReturnNSTriplet(c_int do_nst) => XML.SetReturnNSTriplet(handle, do_nst); + +/* This value is passed as the userData argument to callbacks. */ + +[Inline] public void SetUserData(void* userData) => XML.SetUserData(handle, userData); + +/* Returns the last value set by XML_SetUserData or NULL. */ + + +/* This is equivalent to supplying an encoding argument to + XML_ParserCreate. On success XML_SetEncoding returns non-zero, + zero otherwise. + Note: Calling XML_SetEncoding after XML_Parse or XML_ParseBuffer + has no effect and returns XML_STATUS_ERROR. +*/ + +[Inline] public XML.Status SetEncoding(XML.Char* encoding) => XML.SetEncoding(handle, encoding); + +/* If this function is called, then the parser will be passed as the + first argument to callbacks instead of userData. The userData will + still be accessible using XML_GetUserData. +*/ + +[Inline] public void UseAsHandlerArg() => XML.UseParserAsHandlerArg(handle); + +/* If useDTD == XML_TRUE is passed to this function, then the parser + will assume that there is an external subset, even if none is + specified in the document. In such a case the parser will call the + externalEntityRefHandler with a value of NULL for the systemId + argument (the publicId and context arguments will be NULL as well). + Note: For the purpose of checking WFC: Entity Declared, passing + useDTD == XML_TRUE will make the parser behave as if the document + had a DTD with an external subset. + Note: If this function is called, then this must be done before + the first call to XML_Parse or XML_ParseBuffer, since it will + have no effect after that. Returns + XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING. + Note: If the document does not have a DOCTYPE declaration at all, + then startDoctypeDeclHandler and endDoctypeDeclHandler will not + be called, despite an external subset being parsed. + Note: If XML_DTD is not defined when Expat is compiled, returns + XML_ERROR_FEATURE_REQUIRES_XML_DTD. + Note: If parser == NULL, returns XML_ERROR_INVALID_ARGUMENT. +*/ + +[Inline] public XML.Error UseForeignDTD(XML.Bool useDTD) => XML.UseForeignDTD(handle, useDTD); + +/* Sets the base to be used for resolving relative URIs in system + identifiers in declarations. Resolving relative identifiers is + left to the application: this value will be passed through as the + base argument to the XML_ExternalEntityRefHandler, + XML_NotationDeclHandler and XML_UnparsedEntityDeclHandler. The base + argument will be copied. Returns XML_STATUS_ERROR if out of memory, + XML_STATUS_OK otherwise. +*/ + +[Inline] public XML.Status SetBase(XML.Char* @base) => XML.SetBase(handle, @base); + + +[Inline] public XML.Char* GetBase() => XML.GetBase(handle); + +/* Returns the number of the attribute/value pairs passed in last call + to the XML_StartElementHandler that were specified in the start-tag + rather than defaulted. Each attribute/value pair counts as 2; thus + this corresponds to an index into the atts array passed to the + XML_StartElementHandler. Returns -1 if parser == NULL. +*/ + +[Inline] public c_int GetSpecifiedAttributeCount() => XML.GetSpecifiedAttributeCount(handle); + +/* Returns the index of the ID attribute passed in the last call to + XML_StartElementHandler, or -1 if there is no ID attribute or + parser == NULL. Each attribute/value pair counts as 2; thus this + corresponds to an index into the atts array passed to the + XML_StartElementHandler. +*/ + +[Inline] public c_int GetIdAttributeIndex() => XML.GetIdAttributeIndex(handle); + + +/* Source file byte offsets for the start and end of attribute names and values. + The value indices are exclusive of surrounding quotes; thus in a UTF-8 source + file an attribute value of "blah" will yield: + info->valueEnd - info->valueStart = 4 bytes. +*/ + + /* Offset to beginning of the attribute name. */ + /* Offset after the attribute name's last byte. */ + /* Offset to beginning of the attribute value. */ + /* Offset after the attribute value's last byte. */ + + +/* Returns an array of XML_AttrInfo structures for the attribute/value pairs + passed in last call to the XML_StartElementHandler that were specified + in the start-tag rather than defaulted. Each attribute/value pair counts + as 1; thus the number of entries in the array is + XML_GetSpecifiedAttributeCount(parser) / 2. +*/ + + + + +/* Parses some input. Returns XML_STATUS_ERROR if a fatal error is + detected. The last call to XML_Parse must have isFinal true; len + may be zero for this call (or any other). + + Though the return values for these functions has always been + described as a Boolean value, the implementation, at least for the + 1.95.x series, has always returned exactly one of the XML_Status + values. +*/ + +[Inline] public XML.Status Parse(c_char* s, c_int len, c_int isFinal) => XML.Parse(handle, s, len, isFinal); + + +[Inline] public void* GetBuffer(c_int len) => XML.GetBuffer(handle, len); + + +[Inline] public XML.Status ParseBuffer(c_int len, c_int isFinal) => XML.ParseBuffer(handle, len, isFinal); + +/* Stops parsing, causing XML_Parse() or XML_ParseBuffer() to return. + Must be called from within a call-back handler, except when aborting + (resumable = 0) an already suspended parser. Some call-backs may + still follow because they would otherwise get lost. Examples: + - endElementHandler() for empty elements when stopped in + startElementHandler(), + - endNameSpaceDeclHandler() when stopped in endElementHandler(), + and possibly others. + + Can be called from most handlers, including DTD related call-backs, + except when parsing an external parameter entity and resumable != 0. + Returns XML_STATUS_OK when successful, XML_STATUS_ERROR otherwise. + Possible error codes: + - XML_ERROR_SUSPENDED: when suspending an already suspended parser. + - XML_ERROR_FINISHED: when the parser has already finished. + - XML_ERROR_SUSPEND_PE: when suspending while parsing an external PE. + + When resumable != 0 (true) then parsing is suspended, that is, + XML_Parse() and XML_ParseBuffer() return XML_STATUS_SUSPENDED. + Otherwise, parsing is aborted, that is, XML_Parse() and XML_ParseBuffer() + return XML_STATUS_ERROR with error code XML_ERROR_ABORTED. + + *Note*: + This will be applied to the current parser instance only, that is, if + there is a parent parser then it will continue parsing when the + externalEntityRefHandler() returns. It is up to the implementation of + the externalEntityRefHandler() to call XML_StopParser() on the parent + parser (recursively), if one wants to stop parsing altogether. + + When suspended, parsing can be resumed by calling XML_ResumeParser(). +*/ + +[Inline] public XML.Status Stop(XML.Bool resumable) => XML.StopParser(handle, resumable); + +/* Resumes parsing after it has been suspended with XML_StopParser(). + Must not be called from within a handler call-back. Returns same + status codes as XML_Parse() or XML_ParseBuffer(). + Additional error code XML_ERROR_NOT_SUSPENDED possible. + + *Note*: + This must be called on the most deeply nested child parser instance + first, and on its parent parser only after the child parser has finished, + to be applied recursively until the document entity's parser is restarted. + That is, the parent parser will not resume by itself and it is up to the + application to call XML_ResumeParser() on it at the appropriate moment. +*/ + +[Inline] public XML.Status Resume() => XML.ResumeParser(handle); + + + + + + + + +/* Returns status of parser with respect to being initialized, parsing, + finished, or suspended and processing the final buffer. + XXX XML_Parse() and XML_ParseBuffer() should return XML_ParsingStatus, + XXX with XML_FINISHED_OK or XML_FINISHED_ERROR replacing XML_FINISHED +*/ + +[Inline] public void GetParsingStatus(XML.ParsingStatus* status) => XML.GetParsingStatus(handle, status); + +/* Creates an XML_Parser object that can parse an external general + entity; context is a '\0'-terminated string specifying the parse + context; encoding is a '\0'-terminated string giving the name of + the externally specified encoding, or NULL if there is no + externally specified encoding. The context string consists of a + sequence of tokens separated by formfeeds (\f); a token consisting + of a name specifies that the general entity of the name is open; a + token of the form prefix=uri specifies the namespace for a + particular prefix; a token of the form =uri specifies the default + namespace. This can be called at any point after the first call to + an ExternalEntityRefHandler so longer as the parser has not yet + been freed. The new parser is completely independent and may + safely be used in a separate thread. The handlers and userData are + initialized from the parser argument. Returns NULL if out of memory. + Otherwise returns a new XML_Parser object. +*/ + +[Inline] public XML.Parser ExternalEntityCreate(XML.Char* context, XML.Char* encoding) => XML.ExternalEntityParserCreate(handle, context, encoding); + + + + + + + +/* Controls parsing of parameter entities (including the external DTD + subset). If parsing of parameter entities is enabled, then + references to external parameter entities (including the external + DTD subset) will be passed to the handler set with + XML_SetExternalEntityRefHandler. The context passed will be 0. + + Unlike external general entities, external parameter entities can + only be parsed synchronously. If the external parameter entity is + to be parsed, it must be parsed during the call to the external + entity ref handler: the complete sequence of + XML_ExternalEntityParserCreate, XML_Parse/XML_ParseBuffer and + XML_ParserFree calls must be made during this call. After + XML_ExternalEntityParserCreate has been called to create the parser + for the external parameter entity (context must be 0 for this + call), it is illegal to make any calls on the old parser until + XML_ParserFree has been called on the newly created parser. + If the library has been compiled without support for parameter + entity parsing (ie without XML_DTD being defined), then + XML_SetParamEntityParsing will return 0 if parsing of parameter + entities is requested; otherwise it will return non-zero. + Note: If XML_SetParamEntityParsing is called after XML_Parse or + XML_ParseBuffer, then it has no effect and will always return 0. + Note: If parser == NULL, the function will do nothing and return 0. +*/ + +[Inline] public c_int SetParamEntityParsing(XML.ParamEntityParsing parsing) => XML.SetParamEntityParsing(handle, parsing); + +/* Sets the hash salt to use for internal hash calculations. + Helps in preventing DoS attacks based on predicting hash + function behavior. This must be called before parsing is started. + Returns 1 if successful, 0 when called after parsing has started. + Note: If parser == NULL, the function will do nothing and return 0. +*/ + +[Inline] public c_int SetHashSalt(c_ulong hash_salt) => XML.SetHashSalt(handle, hash_salt); + +/* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then + XML_GetErrorCode returns information about the error. +*/ + +[Inline] public XML.Error GetErrorCode() => XML.GetErrorCode(handle); + +/* These functions return information about the current parse + location. They may be called from any callback called to report + some parse event; in this case the location is the location of the + first of the sequence of characters that generated the event. When + called from callbacks generated by declarations in the document + prologue, the location identified isn't as neatly defined, but will + be within the relevant markup. When called outside of the callback + functions, the position indicated will be just past the last parse + event (regardless of whether there was an associated callback). + + They may also be called after returning from a call to XML_Parse + or XML_ParseBuffer. If the return value is XML_STATUS_ERROR then + the location is the location of the character at which the error + was detected; otherwise the location is the location of the last + parse event, as described above. + + Note: XML_GetCurrentLineNumber and XML_GetCurrentColumnNumber + return 0 to indicate an error. + Note: XML_GetCurrentByteIndex returns -1 to indicate an error. +*/ +[Inline] public XML.Size GetCurrentLineNumber() => XML.GetCurrentLineNumber(handle); +[Inline] public XML.Size GetCurrentColumnNumber() => XML.GetCurrentColumnNumber(handle); +[Inline] public XML.Index GetCurrentByteIndex() => XML.GetCurrentByteIndex(handle); + +/* Return the number of bytes in the current event. + Returns 0 if the event is in an internal entity. +*/ + +[Inline] public c_int GetCurrentByteCount() => XML.GetCurrentByteCount(handle); + +/* If XML_CONTEXT_BYTES is >=1, returns the input buffer, sets + the integer pointed to by offset to the offset within this buffer + of the current parse position, and sets the integer pointed to by size + to the size of this buffer (the number of input bytes). Otherwise + returns a NULL pointer. Also returns a NULL pointer if a parse isn't + active. + + NOTE: The character pointer returned should not be used outside + the handler that makes the call. +*/ + +[Inline] public c_char* GetInputContext(c_int* offset, c_int* size) => XML.GetInputContext(handle, offset, size); + +/* For backwards compatibility with previous versions. */ + + + + +/* Frees the content model passed to the element declaration handler */ + +[Inline] public void FreeContentModel(XML.Content* model) => XML.FreeContentModel(handle, model); + +/* Exposing the memory handling functions used in Expat */ + + + +[Inline] public void* MemMalloc(c_size size) => XML.MemMalloc(handle, size); + + + +[Inline] public void* MemRealloc(void* ptr, c_size size) => XML.MemRealloc(handle, ptr, size); + + +[Inline] public void MemFree(void* ptr) => XML.MemFree(handle, ptr); + +/* Frees memory used by the parser. */ + + + +/* Returns a string describing the error. */ + + + +/* Return a string containing the version number of this expat */ + + + + + + + + + +/* Return an XML_Expat_Version structure containing numeric version + number information for this version of expat. +*/ + + + +/* Added in Expat 1.95.5. */ + + + + + + + + + + + + + /* Added in Expat 2.4.0. */ + + + /* Added in Expat 2.6.0. */ + + /* Added in Expat 2.7.2. */ + + + /* Additional features must be added to the end of this enum. */ + + + + + + + + + + + + +/* Added in Expat 2.4.0 for XML_DTD defined and + * added in Expat 2.6.0 for XML_GE == 1. */ + + + + +/* Added in Expat 2.4.0 for XML_DTD defined and + * added in Expat 2.6.0 for XML_GE == 1. */ + + + + +/* Added in Expat 2.7.2. */ + + + + +/* Added in Expat 2.7.2. */ + + + + + +/* Added in Expat 2.6.0. */ + +[Inline] public XML.Bool SetReparseDeferralEnabled(XML.Bool enabled) => XML.SetReparseDeferralEnabled(handle, enabled); + + private void InitHandlers() + { + SetUserData(Internal.UnsafeCastToPtr(this)); + SetElementDeclHandler((userData, a, b) => ((Self)Internal.UnsafeCastToObject(userData)).ElementDeclHandler(a, b)); + SetAttlistDeclHandler((userData, a, b, c, d, e) => ((Self)Internal.UnsafeCastToObject(userData)).AttlistDeclHandler(a, b, c, d, e)); + SetXmlDeclHandler((userData, a, b, c) => ((Self)Internal.UnsafeCastToObject(userData)).XmlDeclHandler(a, b, c)); + SetStartElementHandler((userData, a, b) => ((Self)Internal.UnsafeCastToObject(userData)).StartElementHandler(a, b)); + SetEndElementHandler((userData, a) => ((Self)Internal.UnsafeCastToObject(userData)).EndElementHandler(a)); + SetCharacterDataHandler((userData, a, b) => ((Self)Internal.UnsafeCastToObject(userData)).CharacterDataHandler(a, b)); + SetProcessingInstructionHandler((userData, a, b) => ((Self)Internal.UnsafeCastToObject(userData)).ProcessingInstructionHandler(a, b)); + SetCommentHandler((userData, a) => ((Self)Internal.UnsafeCastToObject(userData)).CommentHandler(a)); + SetStartCdataSectionHandler((userData) => ((Self)Internal.UnsafeCastToObject(userData)).StartCdataSectionHandler()); + SetEndCdataSectionHandler((userData) => ((Self)Internal.UnsafeCastToObject(userData)).EndCdataSectionHandler()); + SetDefaultHandler((userData, a, b) => ((Self)Internal.UnsafeCastToObject(userData)).DefaultHandler(a, b)); + SetStartDoctypeDeclHandler((userData, a, b, c, d) => ((Self)Internal.UnsafeCastToObject(userData)).StartDoctypeDeclHandler(a, b, c, d)); + SetEndDoctypeDeclHandler((userData) => ((Self)Internal.UnsafeCastToObject(userData)).EndDoctypeDeclHandler()); + SetEntityDeclHandler((userData, a, b, c, d, e, f, g, h) => ((Self)Internal.UnsafeCastToObject(userData)).EntityDeclHandler(a, b, c, d, e, f, g, h)); + SetUnparsedEntityDeclHandler((userData, a, b, c, d, e) => ((Self)Internal.UnsafeCastToObject(userData)).UnparsedEntityDeclHandler(a, b, c, d, e)); + SetNotationDeclHandler((userData, a, b, c, d) => ((Self)Internal.UnsafeCastToObject(userData)).NotationDeclHandler(a, b, c, d)); + SetStartNamespaceDeclHandler((userData, a, b) => ((Self)Internal.UnsafeCastToObject(userData)).StartNamespaceDeclHandler(a, b)); + SetEndNamespaceDeclHandler((userData, a) => ((Self)Internal.UnsafeCastToObject(userData)).EndNamespaceDeclHandler(a)); + SetNotStandaloneHandler((userData) => ((Self)Internal.UnsafeCastToObject(userData)).NotStandaloneHandler()); + SetSkippedEntityHandler((userData, a, b) => ((Self)Internal.UnsafeCastToObject(userData)).SkippedEntityHandler(a, b)); + } +} + +/* Expat follows the semantic versioning convention. + See https://semver.org +*/ + + + + + + + + +/* not Expat_INCLUDED */ \ No newline at end of file