Skip to content

Commit

Permalink
Merge pull request lestrrat-go#69 from lestrrat-go/topic/with-uri
Browse files Browse the repository at this point in the history
allow ways to specify path/uri when parsing XSD
  • Loading branch information
lestrrat authored Nov 23, 2020
2 parents a52d2c7 + 4681c5b commit e6d9de6
Show file tree
Hide file tree
Showing 15 changed files with 817 additions and 8 deletions.
51 changes: 45 additions & 6 deletions clib/clib.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ package clib
#include <libxml/xpathInternals.h>
#include <libxml/c14n.h>
#include <libxml/xmlschemas.h>
#include <libxml/schemasInternals.h>
static inline void MY_nilErrorHandler(void *ctx, const char *msg, ...) {}
Expand Down Expand Up @@ -343,6 +344,7 @@ import (
"unsafe"

"github.com/lestrrat-go/libxml2/internal/debug"
"github.com/lestrrat-go/libxml2/internal/option"
"github.com/pkg/errors"
)

Expand Down Expand Up @@ -465,7 +467,14 @@ func ReportErrors(b bool) {
}

func xmlCtxtLastError(ctx PtrSource) error {
e := C.MY_xmlCtxtLastError(unsafe.Pointer(ctx.Pointer()))
return xmlCtxtLastErrorRaw(ctx.Pointer())
}

func xmlCtxtLastErrorRaw(ctx uintptr) error {
e := C.MY_xmlCtxtLastError(unsafe.Pointer(ctx))
if e == nil {
return errors.New(`unknown error`)
}
msg := strings.TrimSuffix(C.GoString(e.message), "\n")
return errors.Errorf("Entity: line %v: parser error : %v", e.line, msg)
}
Expand Down Expand Up @@ -2116,11 +2125,41 @@ func XMLTextData(n PtrSource) string {
return xmlCharToString(nptr.content)
}

func XMLSchemaParse(buf []byte) (uintptr, error) {
parserCtx := C.xmlSchemaNewMemParserCtxt(
(*C.char)(unsafe.Pointer(&buf[0])),
C.int(len(buf)),
)
func XMLSchemaParse(buf []byte, options ...option.Interface) (uintptr, error) {
var uri string
var encoding string
var coptions int
for _, opt := range options {
switch opt.Name() {
case option.OptKeyWithURI:
uri = opt.Value().(string)
}
}

docctx := C.xmlCreateMemoryParserCtxt((*C.char)(unsafe.Pointer(&buf[0])), C.int(len(buf)))
if docctx == nil {
return 0, errors.New("error creating doc parser")
}

var curi *C.char
if uri != "" {
curi = C.CString(uri)
defer C.free(unsafe.Pointer(curi))
}

var cencoding *C.char
if encoding != "" {
cencoding = C.CString(encoding)
defer C.free(unsafe.Pointer(cencoding))
}

doc := C.xmlCtxtReadMemory(docctx, (*C.char)(unsafe.Pointer(&buf[0])), C.int(len(buf)), curi, cencoding, C.int(coptions))
if doc == nil {
return 0, errors.Errorf("failed to read schema from memory: %v",
xmlCtxtLastErrorRaw(uintptr(unsafe.Pointer(docctx))))
}

parserCtx := C.xmlSchemaNewDocParserCtxt((*C.xmlDoc)(unsafe.Pointer(doc)))
if parserCtx == nil {
return 0, errors.New("failed to create parser")
}
Expand Down
5 changes: 5 additions & 0 deletions internal/option/interface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package option

const (
OptKeyWithURI = `with-uri`
)
25 changes: 25 additions & 0 deletions internal/option/option.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package option

type Interface interface {
Name() string
Value() interface{}
}

type Option struct {
name string
value interface{}
}

func New(name string, value interface{}) *Option {
return &Option{
name: name,
value: value,
}
}

func (o *Option) Name() string {
return o.name
}
func (o *Option) Value() interface{} {
return o.value
}
18 changes: 18 additions & 0 deletions test/go_libxml2_local.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" ?>
<libxml2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlsoft.org/"
xsi:schemaLocation="http://xmlsoft.org/ ./schema/projects/go_libxml2_local.xsd">

<sub attrReq="foo" attrOpt="bar">
<nestedInclude hashType="sha1">4cfcf843c66979eb1df2bd0c52817edb753a52ba</nestedInclude>
</sub>
<sub attrReq="foo2">
<sub2>this is a test string only.</sub2>
<nestedInclude hashType="sha512">be218408a748759fb98363593b8f544eb054171bced856ca98bd972823dec0b07b205453fc3c46f23c934d0959f1e05b609c011b6ada84a7050ad7c910b24bf1</nestedInclude>
</sub>
<sub attrReq="foo3" attrBoolNoDef="false">
<sub2>foobar</sub2>
<nestedInclude hashType="md5">f7b34871a562283ee92bbda00485eb45</nestedInclude>
</sub>

</libxml2>
18 changes: 18 additions & 0 deletions test/go_libxml2_remote.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" ?>
<libxml2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlsoft.org/"
xsi:schemaLocation="http://xmlsoft.org/ http://schema.xml.r00t2.io/projects/go_libxml2.xsd">

<sub attrReq="foo" attrOpt="bar">
<nestedInclude hashType="sha1">4cfcf843c66979eb1df2bd0c52817edb753a52ba</nestedInclude>
</sub>
<sub attrReq="foo2">
<sub2>this is a test string only.</sub2>
<nestedInclude hashType="sha512">be218408a748759fb98363593b8f544eb054171bced856ca98bd972823dec0b07b205453fc3c46f23c934d0959f1e05b609c011b6ada84a7050ad7c910b24bf1</nestedInclude>
</sub>
<sub attrReq="foo3" attrBoolNoDef="false">
<sub2>foobar</sub2>
<nestedInclude hashType="md5">f7b34871a562283ee92bbda00485eb45</nestedInclude>
</sub>

</libxml2>
76 changes: 76 additions & 0 deletions test/schema/lib/types/cksum.xsd
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
attributeFormDefault="unqualified">

<xs:include schemaLocation="./std.xsd"/>
<xs:include schemaLocation="./net.xsd"/>
<xs:include schemaLocation="./unix.xsd"/>

<xs:simpleType name="t_cksum_algo">
<!-- Geared towards python. -->
<!-- tuple(sorted(list(hashlib.algorithms_available.union(set(('adler32', 'crc32')))))) -->
<xs:restriction base="xs:string">
<xs:enumeration value="adler32"/>
<xs:enumeration value="blake2b"/>
<xs:enumeration value="blake2s"/>
<xs:enumeration value="crc32"/>
<xs:enumeration value="md4"/>
<xs:enumeration value="md5"/>
<xs:enumeration value="md5-sha1"/>
<xs:enumeration value="mdc2"/>
<xs:enumeration value="ripemd160"/>
<xs:enumeration value="sha1"/>
<xs:enumeration value="sha224"/>
<xs:enumeration value="sha256"/>
<xs:enumeration value="sha384"/>
<xs:enumeration value="sha3_224"/>
<xs:enumeration value="sha3_256"/>
<xs:enumeration value="sha3_384"/>
<xs:enumeration value="sha3_512"/>
<xs:enumeration value="sha512"/>
<xs:enumeration value="sha512_224"/>
<xs:enumeration value="sha512_256"/>
<xs:enumeration value="shake_128"/>
<xs:enumeration value="shake_256"/>
<xs:enumeration value="sm3"/>
<xs:enumeration value="whirlpool"/>
<xs:whiteSpace value="collapse"/>
</xs:restriction>
</xs:simpleType>

<xs:complexType name="t_cksum_file">
<xs:simpleContent>
<xs:extension base="t_net_generic_resource">
<xs:attribute name="hashType" use="required" type="t_cksum_algo"/>
<xs:attribute name="fileType" use="required" type="t_cksum_file_filetype"/>
<xs:attribute name="filePath" use="optional" type="t_unix_filepath"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>

<xs:simpleType name="t_cksum_file_filetype">
<xs:restriction base="xs:string">
<xs:enumeration value="gnu"/>
<xs:enumeration value="bsd"/>
<xs:whiteSpace value="collapse"/>
</xs:restriction>
</xs:simpleType>

<xs:complexType name="t_cksum_hash">
<xs:simpleContent>
<xs:extension base="t_std_nonempty">
<xs:attribute name="hashType" use="required" type="t_cksum_algo"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>

<xs:complexType name="t_cksum_verify">
<xs:choice minOccurs="1" maxOccurs="unbounded">
<xs:element name="checksum" minOccurs="0" maxOccurs="unbounded" type="t_cksum_hash">
</xs:element>
<xs:element name="checksumFile" minOccurs="0" maxOccurs="unbounded" type="t_cksum_file"/>
</xs:choice>
</xs:complexType>

</xs:schema>
Loading

0 comments on commit e6d9de6

Please sign in to comment.