mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-09-17 21:44:14 +03:00
parser: New input API
Provide a new set of functions to create xmlParserInputs. These can be used for the document entity or from external entity loaders. - Don't require xmlParserInputBuffer. - All functions take a base URI. - All functions take an encoding as string. - xmlNewInputURL also takes a public ID. - xmlNewInputMemory takes a size_t. - Optimization hints for memory buffers. Improve documentation. Only call xmlInitParser before allocating a new parser context. Call xmlCtxtUseOptions as early as possible.
This commit is contained in:
728
HTMLparser.c
728
HTMLparser.c
File diff suppressed because it is too large
Load Diff
@@ -246,6 +246,8 @@ XMLPUBFUN htmlDocPtr
|
|||||||
const char *URL,
|
const char *URL,
|
||||||
const char *encoding,
|
const char *encoding,
|
||||||
int options);
|
int options);
|
||||||
|
XMLPUBFUN htmlDocPtr
|
||||||
|
htmlCtxtParseDocument (htmlParserCtxtPtr ctxt);
|
||||||
XMLPUBFUN htmlDocPtr
|
XMLPUBFUN htmlDocPtr
|
||||||
htmlCtxtReadDoc (xmlParserCtxtPtr ctxt,
|
htmlCtxtReadDoc (xmlParserCtxtPtr ctxt,
|
||||||
const xmlChar *cur,
|
const xmlChar *cur,
|
||||||
|
@@ -1309,6 +1309,8 @@ XMLPUBFUN xmlDocPtr
|
|||||||
const char *URL,
|
const char *URL,
|
||||||
const char *encoding,
|
const char *encoding,
|
||||||
int options);
|
int options);
|
||||||
|
XMLPUBFUN xmlDocPtr
|
||||||
|
xmlCtxtParseDocument (xmlParserCtxtPtr ctxt);
|
||||||
XMLPUBFUN xmlDocPtr
|
XMLPUBFUN xmlDocPtr
|
||||||
xmlCtxtReadDoc (xmlParserCtxtPtr ctxt,
|
xmlCtxtReadDoc (xmlParserCtxtPtr ctxt,
|
||||||
const xmlChar *cur,
|
const xmlChar *cur,
|
||||||
@@ -1342,6 +1344,46 @@ XMLPUBFUN xmlDocPtr
|
|||||||
const char *encoding,
|
const char *encoding,
|
||||||
int options);
|
int options);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* New input API (2.9.13)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define XML_INPUT_BUF_STATIC (1u << 1)
|
||||||
|
#define XML_INPUT_BUF_ZERO_TERMINATED (1u << 2)
|
||||||
|
|
||||||
|
XMLPUBFUN xmlParserInputPtr
|
||||||
|
xmlNewInputURL (xmlParserCtxtPtr ctxt,
|
||||||
|
const char *url,
|
||||||
|
const char *publicId,
|
||||||
|
const char *encoding,
|
||||||
|
int flags);
|
||||||
|
XMLPUBFUN xmlParserInputPtr
|
||||||
|
xmlNewInputMemory (xmlParserCtxtPtr ctxt,
|
||||||
|
const char *filename,
|
||||||
|
const void *mem, size_t size,
|
||||||
|
const char *encoding,
|
||||||
|
int flags);
|
||||||
|
XMLPUBFUN xmlParserInputPtr
|
||||||
|
xmlNewInputString (xmlParserCtxtPtr ctxt,
|
||||||
|
const char *filename,
|
||||||
|
const char *str,
|
||||||
|
const char *encoding,
|
||||||
|
int flags);
|
||||||
|
XMLPUBFUN xmlParserInputPtr
|
||||||
|
xmlNewInputFd (xmlParserCtxtPtr ctxt,
|
||||||
|
const char *filename,
|
||||||
|
int fd,
|
||||||
|
const char *encoding,
|
||||||
|
int flags);
|
||||||
|
XMLPUBFUN xmlParserInputPtr
|
||||||
|
xmlNewInputIO (xmlParserCtxtPtr ctxt,
|
||||||
|
const char *url,
|
||||||
|
xmlInputReadCallback ioRead,
|
||||||
|
xmlInputCloseCallback ioClose,
|
||||||
|
void *ioCtxt,
|
||||||
|
const char *encoding,
|
||||||
|
int flags);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Library wide options
|
* Library wide options
|
||||||
*/
|
*/
|
||||||
|
@@ -17,8 +17,12 @@ xmlNoNetExists(const char *filename);
|
|||||||
XML_HIDDEN int
|
XML_HIDDEN int
|
||||||
xmlParserInputBufferCreateFilenameSafe(const char *URI, xmlCharEncoding enc,
|
xmlParserInputBufferCreateFilenameSafe(const char *URI, xmlCharEncoding enc,
|
||||||
xmlParserInputBufferPtr *out);
|
xmlParserInputBufferPtr *out);
|
||||||
|
|
||||||
XML_HIDDEN xmlParserInputBufferPtr
|
XML_HIDDEN xmlParserInputBufferPtr
|
||||||
xmlParserInputBufferCreateString(const xmlChar *str);
|
xmlNewInputBufferString(const char *str, int flags);
|
||||||
|
XML_HIDDEN xmlParserInputBufferPtr
|
||||||
|
xmlNewInputBufferMemory(const void *mem, size_t size, int flags,
|
||||||
|
xmlCharEncoding enc);
|
||||||
|
|
||||||
#ifdef LIBXML_OUTPUT_ENABLED
|
#ifdef LIBXML_OUTPUT_ENABLED
|
||||||
XML_HIDDEN xmlOutputBufferPtr
|
XML_HIDDEN xmlOutputBufferPtr
|
||||||
|
@@ -83,4 +83,8 @@ xmlParserNsUpdateSax(xmlParserCtxtPtr ctxt, const xmlChar *prefix,
|
|||||||
XML_HIDDEN void *
|
XML_HIDDEN void *
|
||||||
xmlParserNsLookupSax(xmlParserCtxtPtr ctxt, const xmlChar *prefix);
|
xmlParserNsLookupSax(xmlParserCtxtPtr ctxt, const xmlChar *prefix);
|
||||||
|
|
||||||
|
XML_HIDDEN xmlParserInputPtr
|
||||||
|
xmlNewInputPush(xmlParserCtxtPtr ctxt, const char *url,
|
||||||
|
const char *chunk, int size, const char *encoding);
|
||||||
|
|
||||||
#endif /* XML_PARSER_H_PRIVATE__ */
|
#endif /* XML_PARSER_H_PRIVATE__ */
|
||||||
|
@@ -309,23 +309,6 @@ xmlCtxtErr(xmlParserCtxtPtr ctxt, xmlNodePtr node, xmlErrorDomain domain,
|
|||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* xmlErrInternal:
|
|
||||||
* @ctxt: an XML parser context
|
|
||||||
* @msg: the error message
|
|
||||||
* @str: error information
|
|
||||||
*
|
|
||||||
* Handle an internal error
|
|
||||||
*/
|
|
||||||
static void LIBXML_ATTR_FORMAT(2,0)
|
|
||||||
xmlErrInternal(xmlParserCtxtPtr ctxt, const char *msg, const xmlChar * str)
|
|
||||||
{
|
|
||||||
if (ctxt == NULL)
|
|
||||||
return;
|
|
||||||
xmlCtxtErr(ctxt, NULL, XML_FROM_PARSER, XML_ERR_INTERNAL_ERROR,
|
|
||||||
XML_ERR_FATAL, str, NULL, NULL, 0, msg, str);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xmlFatalErr:
|
* xmlFatalErr:
|
||||||
* @ctxt: an XML parser context
|
* @ctxt: an XML parser context
|
||||||
@@ -1084,6 +1067,32 @@ xmlSwitchEncoding(xmlParserCtxtPtr ctxt, xmlCharEncoding enc)
|
|||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlSwitchEncodingName:
|
||||||
|
* @ctxt: the parser context, only for error reporting
|
||||||
|
* @input: the input strea,
|
||||||
|
* @encoding: the encoding name
|
||||||
|
*
|
||||||
|
* Returns 0 in case of success, -1 otherwise
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
xmlSwitchInputEncodingName(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
|
||||||
|
const char *encoding) {
|
||||||
|
xmlCharEncodingHandlerPtr handler;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if (encoding == NULL)
|
||||||
|
return(-1);
|
||||||
|
|
||||||
|
res = xmlOpenCharEncodingHandler(encoding, &handler);
|
||||||
|
if (res != 0) {
|
||||||
|
xmlFatalErr(ctxt, res, encoding);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(xmlSwitchInputEncoding(ctxt, input, handler));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xmlSwitchEncodingName:
|
* xmlSwitchEncodingName:
|
||||||
* @ctxt: the parser context
|
* @ctxt: the parser context
|
||||||
@@ -1101,24 +1110,12 @@ xmlSwitchEncoding(xmlParserCtxtPtr ctxt, xmlCharEncoding enc)
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
xmlSwitchEncodingName(xmlParserCtxtPtr ctxt, const char *encoding) {
|
xmlSwitchEncodingName(xmlParserCtxtPtr ctxt, const char *encoding) {
|
||||||
xmlCharEncodingHandlerPtr handler;
|
return(xmlSwitchInputEncodingName(ctxt, ctxt->input, encoding));
|
||||||
int res;
|
|
||||||
|
|
||||||
if (encoding == NULL)
|
|
||||||
return(-1);
|
|
||||||
|
|
||||||
res = xmlOpenCharEncodingHandler(encoding, &handler);
|
|
||||||
if (res != 0) {
|
|
||||||
xmlFatalErr(ctxt, res, encoding);
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return(xmlSwitchInputEncoding(ctxt, ctxt->input, handler));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xmlSwitchInputEncoding:
|
* xmlSwitchInputEncoding:
|
||||||
* @ctxt: the parser context
|
* @ctxt: the parser context, only for error reporting
|
||||||
* @input: the input stream
|
* @input: the input stream
|
||||||
* @handler: the encoding handler
|
* @handler: the encoding handler
|
||||||
*
|
*
|
||||||
@@ -1467,36 +1464,341 @@ xmlNewInputStream(xmlParserCtxtPtr ctxt) {
|
|||||||
return(input);
|
return(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlNewInputURL:
|
||||||
|
* @ctxt: parser context
|
||||||
|
* @url: filename or URL
|
||||||
|
* @publicId: publid ID from doctype (optional)
|
||||||
|
* @encoding: character encoding (optional)
|
||||||
|
* @flags: unused, pass 0
|
||||||
|
*
|
||||||
|
* Creates a new parser input from the filesystem, the network or
|
||||||
|
* a user-defined resource loader.
|
||||||
|
*
|
||||||
|
* @url is a filename or URL. If if contains the substring "://",
|
||||||
|
* it is assumed to be a Legacy Extended IRI. Otherwise, it is
|
||||||
|
* treated as a filesystem path.
|
||||||
|
*
|
||||||
|
* @publicId is an optional XML public ID, typically from a doctype
|
||||||
|
* declaration. It is used for catalog lookups.
|
||||||
|
*
|
||||||
|
* If @encoding is specified, it will override any encodings found
|
||||||
|
* in XML declarations, text declarations, BOMs, etc. Pass NULL
|
||||||
|
* for auto-detection.
|
||||||
|
*
|
||||||
|
* The following resource loaders will be called if they were
|
||||||
|
* registered (in order of precedence):
|
||||||
|
*
|
||||||
|
* - the global external entity loader set with
|
||||||
|
* xmlSetExternalEntityLoader
|
||||||
|
* - the per-thread xmlParserInputBufferCreateFilenameFunc set with
|
||||||
|
* xmlParserInputBufferCreateFilenameDefault
|
||||||
|
* - the default loader which will return
|
||||||
|
* - the result from a matching global input callback set with
|
||||||
|
* xmlRegisterInputCallbacks
|
||||||
|
* - a HTTP resource if support is compiled in.
|
||||||
|
* - a file opened from the filesystem, with automatic detection
|
||||||
|
* of compressed files if support is compiled in.
|
||||||
|
*
|
||||||
|
* The returned input should be push onto the input stack with
|
||||||
|
* xmlPushInput.
|
||||||
|
*
|
||||||
|
* This function should not be invoked from user-defined resource
|
||||||
|
* loaders to avoid infinite loops.
|
||||||
|
*
|
||||||
|
* Returns a new parser input.
|
||||||
|
*/
|
||||||
|
xmlParserInputPtr
|
||||||
|
xmlNewInputURL(xmlParserCtxtPtr ctxt, const char *url, const char *publicId,
|
||||||
|
const char *encoding, int flags ATTRIBUTE_UNUSED) {
|
||||||
|
xmlParserInputPtr input;
|
||||||
|
|
||||||
|
if ((ctxt == NULL) || (url == NULL))
|
||||||
|
return(NULL);
|
||||||
|
|
||||||
|
input = xmlLoadExternalEntity(url, publicId, ctxt);
|
||||||
|
if (input == NULL)
|
||||||
|
return(NULL);
|
||||||
|
|
||||||
|
if (encoding != NULL)
|
||||||
|
xmlSwitchInputEncodingName(ctxt, input, encoding);
|
||||||
|
|
||||||
|
return(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlNewInputInternal:
|
||||||
|
* @ctxt: parser context
|
||||||
|
* @buf: parser input buffer
|
||||||
|
* @filename: filename or URL
|
||||||
|
* @encoding: character encoding (optional)
|
||||||
|
*
|
||||||
|
* Internal helper function.
|
||||||
|
*
|
||||||
|
* Returns a new parser input.
|
||||||
|
*/
|
||||||
|
static xmlParserInputPtr
|
||||||
|
xmlNewInputInternal(xmlParserCtxtPtr ctxt, xmlParserInputBufferPtr buf,
|
||||||
|
const char *filename, const char *encoding) {
|
||||||
|
xmlParserInputPtr input;
|
||||||
|
|
||||||
|
input = xmlNewInputStream(ctxt);
|
||||||
|
if (input == NULL) {
|
||||||
|
xmlFreeParserInputBuffer(buf);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
input->buf = buf;
|
||||||
|
xmlBufResetInput(input->buf->buffer, input);
|
||||||
|
|
||||||
|
if (filename != NULL) {
|
||||||
|
input->filename = xmlMemStrdup(filename);
|
||||||
|
if (input->filename == NULL) {
|
||||||
|
xmlCtxtErrMemory(ctxt);
|
||||||
|
xmlFreeInputStream(input);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (encoding != NULL) {
|
||||||
|
if (xmlSwitchInputEncodingName(ctxt, input, encoding) < 0) {
|
||||||
|
xmlFreeInputStream(input);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlNewInputMemory:
|
||||||
|
* @ctxt: parser context
|
||||||
|
* @url: base URL (optional)
|
||||||
|
* @mem: pointer to char array
|
||||||
|
* @size: size of array
|
||||||
|
* @encoding: character encoding (optional)
|
||||||
|
* @flags: optimization hints
|
||||||
|
*
|
||||||
|
* Creates a new parser input to read from a memory area.
|
||||||
|
*
|
||||||
|
* @url is used as base to resolve external entities and for
|
||||||
|
* error reporting.
|
||||||
|
*
|
||||||
|
* If the XML_INPUT_BUF_STATIC flag is set, the memory area must
|
||||||
|
* stay unchanged until parsing has finished. This can avoid
|
||||||
|
* temporary copies.
|
||||||
|
*
|
||||||
|
* If the XML_INPUT_BUF_ZERO_TERMINATED flag is set, the memory
|
||||||
|
* area must contain a zero byte after the buffer at position @size.
|
||||||
|
* This can avoid temporary copies.
|
||||||
|
*
|
||||||
|
* Returns a new parser input.
|
||||||
|
*/
|
||||||
|
xmlParserInputPtr
|
||||||
|
xmlNewInputMemory(xmlParserCtxtPtr ctxt, const char *url,
|
||||||
|
const void *mem, size_t size,
|
||||||
|
const char *encoding, int flags) {
|
||||||
|
xmlParserInputBufferPtr buf;
|
||||||
|
|
||||||
|
if ((ctxt == NULL) || (mem == NULL))
|
||||||
|
return(NULL);
|
||||||
|
|
||||||
|
buf = xmlNewInputBufferMemory(mem, size, flags, XML_CHAR_ENCODING_NONE);
|
||||||
|
if (buf == NULL) {
|
||||||
|
xmlCtxtErrMemory(ctxt);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(xmlNewInputInternal(ctxt, buf, url, encoding));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlNewInputString:
|
||||||
|
* @ctxt: parser context
|
||||||
|
* @url: base URL (optional)
|
||||||
|
* @str: zero-terminated string
|
||||||
|
* @encoding: character encoding (optional)
|
||||||
|
* @flags: optimization hints
|
||||||
|
*
|
||||||
|
* Creates a new parser input to read from a zero-terminated string.
|
||||||
|
*
|
||||||
|
* @url is used as base to resolve external entities and for
|
||||||
|
* error reporting.
|
||||||
|
*
|
||||||
|
* If the XML_INPUT_BUF_STATIC flag is set, the string must
|
||||||
|
* stay unchanged until parsing has finished. This can avoid
|
||||||
|
* temporary copies.
|
||||||
|
*
|
||||||
|
* Returns a new parser input.
|
||||||
|
*/
|
||||||
|
xmlParserInputPtr
|
||||||
|
xmlNewInputString(xmlParserCtxtPtr ctxt, const char *url,
|
||||||
|
const char *str, const char *encoding, int flags) {
|
||||||
|
xmlParserInputBufferPtr buf;
|
||||||
|
|
||||||
|
if ((ctxt == NULL) || (str == NULL))
|
||||||
|
return(NULL);
|
||||||
|
|
||||||
|
buf = xmlNewInputBufferString(str, flags);
|
||||||
|
if (buf == NULL) {
|
||||||
|
xmlCtxtErrMemory(ctxt);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(xmlNewInputInternal(ctxt, buf, url, encoding));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlNewInputFd:
|
||||||
|
* @ctxt: parser context
|
||||||
|
* @url: base URL (optional)
|
||||||
|
* @fd: file descriptor
|
||||||
|
* @encoding: character encoding (optional)
|
||||||
|
* @flags: unused, pass 0
|
||||||
|
*
|
||||||
|
* Creates a new parser input to read from a zero-terminated string.
|
||||||
|
*
|
||||||
|
* @url is used as base to resolve external entities and for
|
||||||
|
* error reporting.
|
||||||
|
*
|
||||||
|
* @fd is closed after parsing has finished.
|
||||||
|
*
|
||||||
|
* Returns a new parser input.
|
||||||
|
*/
|
||||||
|
xmlParserInputPtr
|
||||||
|
xmlNewInputFd(xmlParserCtxtPtr ctxt, const char *url,
|
||||||
|
int fd, const char *encoding, int flags ATTRIBUTE_UNUSED) {
|
||||||
|
xmlParserInputBufferPtr buf;
|
||||||
|
|
||||||
|
if ((ctxt == NULL) || (fd < 0))
|
||||||
|
return(NULL);
|
||||||
|
|
||||||
|
buf = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
|
||||||
|
if (buf == NULL) {
|
||||||
|
xmlCtxtErrMemory(ctxt);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(xmlNewInputInternal(ctxt, buf, url, encoding));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlNewInputIO:
|
||||||
|
* @ctxt: parser context
|
||||||
|
* @url: base URL (optional)
|
||||||
|
* @ioRead: read callback
|
||||||
|
* @ioClose: close callback (optional)
|
||||||
|
* @ioCtxt: IO context
|
||||||
|
* @encoding: character encoding (optional)
|
||||||
|
* @flags: unused, pass 0
|
||||||
|
*
|
||||||
|
* Creates a new parser input to read from input callbacks and
|
||||||
|
* cintext.
|
||||||
|
*
|
||||||
|
* @url is used as base to resolve external entities and for
|
||||||
|
* error reporting.
|
||||||
|
*
|
||||||
|
* @ioRead is called to read new data into a provided buffer.
|
||||||
|
* It must return the number of bytes written into the buffer
|
||||||
|
* ot a negative xmlParserErrors code on failure.
|
||||||
|
*
|
||||||
|
* @ioClose is called after parsing has finished.
|
||||||
|
*
|
||||||
|
* @ioCtxt is an opaque pointer passed to the callbacks.
|
||||||
|
*
|
||||||
|
* Returns a new parser input.
|
||||||
|
*/
|
||||||
|
xmlParserInputPtr
|
||||||
|
xmlNewInputIO(xmlParserCtxtPtr ctxt, const char *url,
|
||||||
|
xmlInputReadCallback ioRead, xmlInputCloseCallback ioClose,
|
||||||
|
void *ioCtxt,
|
||||||
|
const char *encoding, int flags ATTRIBUTE_UNUSED) {
|
||||||
|
xmlParserInputBufferPtr buf;
|
||||||
|
|
||||||
|
if ((ctxt == NULL) || (ioRead == NULL))
|
||||||
|
return(NULL);
|
||||||
|
|
||||||
|
buf = xmlAllocParserInputBuffer(XML_CHAR_ENCODING_NONE);
|
||||||
|
if (buf == NULL) {
|
||||||
|
xmlCtxtErrMemory(ctxt);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
buf->context = ioCtxt;
|
||||||
|
buf->readcallback = ioRead;
|
||||||
|
buf->closecallback = ioClose;
|
||||||
|
|
||||||
|
return(xmlNewInputInternal(ctxt, buf, url, encoding));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlNewInputPush:
|
||||||
|
* @ctxt: parser context
|
||||||
|
* @url: base URL (optional)
|
||||||
|
* @chunk: pointer to char array
|
||||||
|
* @size: size of array
|
||||||
|
* @encoding: character encoding (optional)
|
||||||
|
*
|
||||||
|
* Creates a new parser input for a push parser.
|
||||||
|
*
|
||||||
|
* Returns a new parser input.
|
||||||
|
*/
|
||||||
|
xmlParserInputPtr
|
||||||
|
xmlNewInputPush(xmlParserCtxtPtr ctxt, const char *url,
|
||||||
|
const char *chunk, int size, const char *encoding) {
|
||||||
|
xmlParserInputBufferPtr buf;
|
||||||
|
xmlParserInputPtr input;
|
||||||
|
|
||||||
|
buf = xmlAllocParserInputBuffer(XML_CHAR_ENCODING_NONE);
|
||||||
|
if (buf == NULL) {
|
||||||
|
xmlCtxtErrMemory(ctxt);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
input = xmlNewInputInternal(ctxt, buf, url, encoding);
|
||||||
|
if (input == NULL)
|
||||||
|
return(NULL);
|
||||||
|
|
||||||
|
input->flags |= XML_INPUT_PROGRESSIVE;
|
||||||
|
|
||||||
|
if ((size > 0) && (chunk != NULL)) {
|
||||||
|
int res;
|
||||||
|
|
||||||
|
res = xmlParserInputBufferPush(input->buf, size, chunk);
|
||||||
|
xmlBufResetInput(input->buf->buffer, input);
|
||||||
|
if (res < 0) {
|
||||||
|
xmlCtxtErrIO(ctxt, input->buf->error, NULL);
|
||||||
|
xmlFreeInputStream(input);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return(input);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xmlNewIOInputStream:
|
* xmlNewIOInputStream:
|
||||||
* @ctxt: an XML parser context
|
* @ctxt: an XML parser context
|
||||||
* @input: an I/O Input
|
* @input: an I/O Input
|
||||||
* @enc: the charset encoding if known
|
* @enc: the charset encoding if known
|
||||||
*
|
*
|
||||||
|
* DEPRECATED: Use xmlNewInputURL, xmlNewInputMemory, etc.
|
||||||
|
*
|
||||||
* Create a new input stream structure encapsulating the @input into
|
* Create a new input stream structure encapsulating the @input into
|
||||||
* a stream suitable for the parser.
|
* a stream suitable for the parser.
|
||||||
*
|
*
|
||||||
* Returns the new input stream or NULL
|
* Returns the new input stream or NULL
|
||||||
*/
|
*/
|
||||||
xmlParserInputPtr
|
xmlParserInputPtr
|
||||||
xmlNewIOInputStream(xmlParserCtxtPtr ctxt, xmlParserInputBufferPtr input,
|
xmlNewIOInputStream(xmlParserCtxtPtr ctxt, xmlParserInputBufferPtr buf,
|
||||||
xmlCharEncoding enc) {
|
xmlCharEncoding enc) {
|
||||||
xmlParserInputPtr inputStream;
|
const char *encoding;
|
||||||
|
|
||||||
if (input == NULL) return(NULL);
|
if (buf == NULL)
|
||||||
inputStream = xmlNewInputStream(ctxt);
|
return(NULL);
|
||||||
if (inputStream == NULL) {
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
inputStream->filename = NULL;
|
|
||||||
inputStream->buf = input;
|
|
||||||
xmlBufResetInput(inputStream->buf->buffer, inputStream);
|
|
||||||
|
|
||||||
if (enc != XML_CHAR_ENCODING_NONE) {
|
encoding = xmlGetCharEncodingName(enc);
|
||||||
xmlSwitchEncoding(ctxt, enc);
|
return(xmlNewInputInternal(ctxt, buf, NULL, encoding));
|
||||||
}
|
|
||||||
|
|
||||||
return(inputStream);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1518,14 +1820,20 @@ xmlNewEntityInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr ent) {
|
|||||||
return(NULL);
|
return(NULL);
|
||||||
|
|
||||||
if (ent->content != NULL) {
|
if (ent->content != NULL) {
|
||||||
input = xmlNewStringInputStream(ctxt, ent->content);
|
input = xmlNewInputString(ctxt, NULL, (const char *) ent->content,
|
||||||
|
NULL, XML_INPUT_BUF_STATIC);
|
||||||
} else if (ent->URI != NULL) {
|
} else if (ent->URI != NULL) {
|
||||||
input = xmlLoadExternalEntity((char *) ent->URI,
|
input = xmlLoadExternalEntity((char *) ent->URI,
|
||||||
(char *) ent->ExternalID, ctxt);
|
(char *) ent->ExternalID, ctxt);
|
||||||
} else {
|
} else {
|
||||||
input = xmlNewStringInputStream(ctxt, "");
|
input = xmlNewInputMemory(ctxt, NULL, "", 0, NULL,
|
||||||
|
XML_INPUT_BUF_STATIC |
|
||||||
|
XML_INPUT_BUF_ZERO_TERMINATED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (input == NULL)
|
||||||
|
return(NULL);
|
||||||
|
|
||||||
input->entity = ent;
|
input->entity = ent;
|
||||||
|
|
||||||
return(input);
|
return(input);
|
||||||
@@ -1536,35 +1844,18 @@ xmlNewEntityInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr ent) {
|
|||||||
* @ctxt: an XML parser context
|
* @ctxt: an XML parser context
|
||||||
* @buffer: an memory buffer
|
* @buffer: an memory buffer
|
||||||
*
|
*
|
||||||
|
* DEPRECATED: Use xmlNewInputString.
|
||||||
|
*
|
||||||
* Create a new input stream based on a memory buffer.
|
* Create a new input stream based on a memory buffer.
|
||||||
|
*
|
||||||
* Returns the new input stream
|
* Returns the new input stream
|
||||||
*/
|
*/
|
||||||
xmlParserInputPtr
|
xmlParserInputPtr
|
||||||
xmlNewStringInputStream(xmlParserCtxtPtr ctxt, const xmlChar *buffer) {
|
xmlNewStringInputStream(xmlParserCtxtPtr ctxt, const xmlChar *buffer) {
|
||||||
xmlParserInputPtr input;
|
return(xmlNewInputString(ctxt, NULL, (const char *) buffer, NULL, 0));
|
||||||
xmlParserInputBufferPtr buf;
|
|
||||||
|
|
||||||
if (buffer == NULL) {
|
|
||||||
xmlErrInternal(ctxt, "xmlNewStringInputStream string = NULL\n",
|
|
||||||
NULL);
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
buf = xmlParserInputBufferCreateString(buffer);
|
|
||||||
if (buf == NULL) {
|
|
||||||
xmlCtxtErrMemory(ctxt);
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
input = xmlNewInputStream(ctxt);
|
|
||||||
if (input == NULL) {
|
|
||||||
xmlCtxtErrMemory(ctxt);
|
|
||||||
xmlFreeParserInputBuffer(buf);
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
input->buf = buf;
|
|
||||||
xmlBufResetInput(input->buf->buffer, input);
|
|
||||||
return(input);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************
|
/****************************************************************
|
||||||
* *
|
* *
|
||||||
* External entities loading *
|
* External entities loading *
|
||||||
@@ -1716,6 +2007,8 @@ xmlCheckHTTPInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr ret) {
|
|||||||
* @ctxt: an XML parser context
|
* @ctxt: an XML parser context
|
||||||
* @filename: the filename to use as entity
|
* @filename: the filename to use as entity
|
||||||
*
|
*
|
||||||
|
* DEPRECATED: Use xmlNewInputURL.
|
||||||
|
*
|
||||||
* Create a new input stream based on a file or an URL.
|
* Create a new input stream based on a file or an URL.
|
||||||
*
|
*
|
||||||
* Returns the new input stream or NULL in case of error
|
* Returns the new input stream or NULL in case of error
|
||||||
@@ -1891,8 +2184,7 @@ xmlGetExternalEntityLoader(void) {
|
|||||||
* @ID: the Public ID for the entity to load
|
* @ID: the Public ID for the entity to load
|
||||||
* @ctxt: the context in which the entity is called or NULL
|
* @ctxt: the context in which the entity is called or NULL
|
||||||
*
|
*
|
||||||
* Load an external entity, note that the use of this function for
|
* DEPRECATED: Use xmlNewInputURL.
|
||||||
* unparsed entities may generate problems
|
|
||||||
*
|
*
|
||||||
* Returns the xmlParserInputPtr or NULL
|
* Returns the xmlParserInputPtr or NULL
|
||||||
*/
|
*/
|
||||||
@@ -1942,8 +2234,6 @@ xmlInitSAXParserCtxt(xmlParserCtxtPtr ctxt, const xmlSAXHandler *sax,
|
|||||||
if (ctxt == NULL)
|
if (ctxt == NULL)
|
||||||
return(-1);
|
return(-1);
|
||||||
|
|
||||||
xmlInitParser();
|
|
||||||
|
|
||||||
if (ctxt->dict == NULL)
|
if (ctxt->dict == NULL)
|
||||||
ctxt->dict = xmlDictCreate();
|
ctxt->dict = xmlDictCreate();
|
||||||
if (ctxt->dict == NULL)
|
if (ctxt->dict == NULL)
|
||||||
@@ -2210,6 +2500,10 @@ xmlNewParserCtxt(void)
|
|||||||
* Allocate and initialize a new SAX parser context. If userData is NULL,
|
* Allocate and initialize a new SAX parser context. If userData is NULL,
|
||||||
* the parser context will be passed as user data.
|
* the parser context will be passed as user data.
|
||||||
*
|
*
|
||||||
|
* Available since 2.11.0. If you want support older versions,
|
||||||
|
* it's best to invoke xmlNewParserCtxt and set ctxt->sax with
|
||||||
|
* struct assignment.
|
||||||
|
*
|
||||||
* Returns the xmlParserCtxtPtr or NULL if memory allocation failed.
|
* Returns the xmlParserCtxtPtr or NULL if memory allocation failed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -2218,6 +2512,8 @@ xmlNewSAXParserCtxt(const xmlSAXHandler *sax, void *userData)
|
|||||||
{
|
{
|
||||||
xmlParserCtxtPtr ctxt;
|
xmlParserCtxtPtr ctxt;
|
||||||
|
|
||||||
|
xmlInitParser();
|
||||||
|
|
||||||
ctxt = (xmlParserCtxtPtr) xmlMalloc(sizeof(xmlParserCtxt));
|
ctxt = (xmlParserCtxtPtr) xmlMalloc(sizeof(xmlParserCtxt));
|
||||||
if (ctxt == NULL)
|
if (ctxt == NULL)
|
||||||
return(NULL);
|
return(NULL);
|
||||||
|
110
xmlIO.c
110
xmlIO.c
@@ -1913,12 +1913,55 @@ static int
|
|||||||
xmlMemClose(void *vctxt) {
|
xmlMemClose(void *vctxt) {
|
||||||
xmlMemIOCtxt *ctxt = vctxt;
|
xmlMemIOCtxt *ctxt = vctxt;
|
||||||
|
|
||||||
if (ctxt->mem != 0)
|
if (ctxt->mem != NULL)
|
||||||
xmlFree(ctxt->mem);
|
xmlFree(ctxt->mem);
|
||||||
xmlFree(ctxt);
|
xmlFree(ctxt);
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xmlParserInputBufferPtr
|
||||||
|
xmlNewInputBufferMemory(const void *mem, size_t size, int flags,
|
||||||
|
xmlCharEncoding enc) {
|
||||||
|
xmlParserInputBufferPtr ret;
|
||||||
|
xmlMemIOCtxt *ctxt;
|
||||||
|
char *copy = NULL;
|
||||||
|
|
||||||
|
if ((flags & XML_INPUT_BUF_STATIC) == 0) {
|
||||||
|
if (size + 1 == 0)
|
||||||
|
return(NULL);
|
||||||
|
copy = xmlMalloc(size + 1);
|
||||||
|
if (copy == NULL)
|
||||||
|
return(NULL);
|
||||||
|
memcpy(copy, mem, size);
|
||||||
|
copy[size] = 0;
|
||||||
|
|
||||||
|
mem = copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = xmlAllocParserInputBuffer(enc);
|
||||||
|
if (ret == NULL) {
|
||||||
|
xmlFree(copy);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
ctxt = xmlMalloc(sizeof(*ctxt));
|
||||||
|
if (ctxt == NULL) {
|
||||||
|
xmlFreeParserInputBuffer(ret);
|
||||||
|
xmlFree(copy);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
ctxt->mem = copy;
|
||||||
|
ctxt->cur = mem;
|
||||||
|
ctxt->size = size;
|
||||||
|
|
||||||
|
ret->context = ctxt;
|
||||||
|
ret->readcallback = xmlMemRead;
|
||||||
|
ret->closecallback = xmlMemClose;
|
||||||
|
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xmlParserInputBufferCreateMem:
|
* xmlParserInputBufferCreateMem:
|
||||||
* @mem: the memory input
|
* @mem: the memory input
|
||||||
@@ -1940,27 +1983,10 @@ xmlMemClose(void *vctxt) {
|
|||||||
*/
|
*/
|
||||||
xmlParserInputBufferPtr
|
xmlParserInputBufferPtr
|
||||||
xmlParserInputBufferCreateMem(const char *mem, int size, xmlCharEncoding enc) {
|
xmlParserInputBufferCreateMem(const char *mem, int size, xmlCharEncoding enc) {
|
||||||
xmlParserInputBufferPtr buf;
|
if ((mem == NULL) || (size < 0))
|
||||||
xmlMemIOCtxt *ctxt;
|
|
||||||
char *copy;
|
|
||||||
|
|
||||||
if ((size < 0) || (mem == NULL))
|
|
||||||
return(NULL);
|
return(NULL);
|
||||||
|
|
||||||
copy = (char *) xmlStrndup((const xmlChar *) mem, size);
|
return(xmlNewInputBufferMemory(mem, size, 0, enc));
|
||||||
if (copy == NULL)
|
|
||||||
return(NULL);
|
|
||||||
|
|
||||||
buf = xmlParserInputBufferCreateStatic(copy, size, enc);
|
|
||||||
if (buf == NULL) {
|
|
||||||
xmlFree(copy);
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
ctxt = buf->context;
|
|
||||||
ctxt->mem = copy;
|
|
||||||
|
|
||||||
return(buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1984,40 +2010,20 @@ xmlParserInputBufferCreateMem(const char *mem, int size, xmlCharEncoding enc) {
|
|||||||
xmlParserInputBufferPtr
|
xmlParserInputBufferPtr
|
||||||
xmlParserInputBufferCreateStatic(const char *mem, int size,
|
xmlParserInputBufferCreateStatic(const char *mem, int size,
|
||||||
xmlCharEncoding enc) {
|
xmlCharEncoding enc) {
|
||||||
xmlParserInputBufferPtr ret;
|
if ((mem == NULL) || (size < 0))
|
||||||
xmlMemIOCtxt *ctxt;
|
|
||||||
|
|
||||||
if ((size < 0) || (mem == NULL))
|
|
||||||
return(NULL);
|
return(NULL);
|
||||||
|
|
||||||
ret = xmlAllocParserInputBuffer(enc);
|
return(xmlNewInputBufferMemory(mem, size, XML_INPUT_BUF_STATIC, enc));
|
||||||
if (ret == NULL)
|
|
||||||
return(NULL);
|
|
||||||
|
|
||||||
ctxt = xmlMalloc(sizeof(*ctxt));
|
|
||||||
if (ctxt == NULL) {
|
|
||||||
xmlFreeParserInputBuffer(ret);
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
ctxt->mem = NULL;
|
|
||||||
ctxt->cur = mem;
|
|
||||||
ctxt->size = size;
|
|
||||||
|
|
||||||
ret->context = ctxt;
|
|
||||||
ret->readcallback = xmlMemRead;
|
|
||||||
ret->closecallback = xmlMemClose;
|
|
||||||
|
|
||||||
return(ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const xmlChar *str;
|
const char *str;
|
||||||
} xmlStringIOCtxt;
|
} xmlStringIOCtxt;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
xmlStringRead(void *vctxt, char *buf, int size) {
|
xmlStringRead(void *vctxt, char *buf, int size) {
|
||||||
xmlStringIOCtxt *ctxt = vctxt;
|
xmlStringIOCtxt *ctxt = vctxt;
|
||||||
const xmlChar *zero;
|
const char *zero;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
zero = memchr(ctxt->str, 0, size);
|
zero = memchr(ctxt->str, 0, size);
|
||||||
@@ -2035,21 +2041,14 @@ xmlStringClose(void *vctxt) {
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* xmlParserInputBufferCreateString:
|
|
||||||
* @str: a null-terminated string
|
|
||||||
*
|
|
||||||
* Create a buffered parser input for the progressive parsing for the input
|
|
||||||
* from a null-terminated C string.
|
|
||||||
*
|
|
||||||
* Returns the new parser input or NULL
|
|
||||||
*/
|
|
||||||
xmlParserInputBufferPtr
|
xmlParserInputBufferPtr
|
||||||
xmlParserInputBufferCreateString(const xmlChar *str) {
|
xmlNewInputBufferString(const char *str, int flags) {
|
||||||
xmlParserInputBufferPtr ret;
|
xmlParserInputBufferPtr ret;
|
||||||
xmlStringIOCtxt *ctxt;
|
xmlStringIOCtxt *ctxt;
|
||||||
|
|
||||||
if (str == NULL) return(NULL);
|
if ((flags & XML_INPUT_BUF_STATIC) == 0)
|
||||||
|
return(xmlNewInputBufferMemory(str, strlen(str), flags,
|
||||||
|
XML_CHAR_ENCODING_NONE));
|
||||||
|
|
||||||
ret = xmlAllocParserInputBuffer(XML_CHAR_ENCODING_NONE);
|
ret = xmlAllocParserInputBuffer(XML_CHAR_ENCODING_NONE);
|
||||||
if (ret == NULL)
|
if (ret == NULL)
|
||||||
@@ -2060,6 +2059,7 @@ xmlParserInputBufferCreateString(const xmlChar *str) {
|
|||||||
xmlFreeParserInputBuffer(ret);
|
xmlFreeParserInputBuffer(ret);
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
ctxt->str = str;
|
ctxt->str = str;
|
||||||
|
|
||||||
ret->context = ctxt;
|
ret->context = ctxt;
|
||||||
|
@@ -1776,7 +1776,6 @@ static void streamFile(char *filename) {
|
|||||||
int fd = -1;
|
int fd = -1;
|
||||||
struct stat info;
|
struct stat info;
|
||||||
const char *base = NULL;
|
const char *base = NULL;
|
||||||
xmlParserInputBufferPtr input = NULL;
|
|
||||||
|
|
||||||
if (memory) {
|
if (memory) {
|
||||||
if (stat(filename, &info) < 0)
|
if (stat(filename, &info) < 0)
|
||||||
@@ -1928,7 +1927,6 @@ static void streamFile(char *filename) {
|
|||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_MMAP
|
#ifdef HAVE_MMAP
|
||||||
if (memory) {
|
if (memory) {
|
||||||
xmlFreeParserInputBuffer(input);
|
|
||||||
munmap((char *) base, info.st_size);
|
munmap((char *) base, info.st_size);
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user