📄 xmlio.c
字号:
** For whatever reason, the CRC and length data are pushed out ** in reverse byte order. So a memcpy can't be used here. */ append_reverse_ulong( buff, buff->crc ); append_reverse_ulong( buff, buff->zctrl.total_in ); zlgth = buff->zctrl.next_out - buff->zbuff; *data_ref = (char *)buff->zbuff; } else { xmlChar msg[500]; xmlStrPrintf(msg, 500, (const xmlChar *) "xmlZMemBuffGetContent: %s - %d\n", "Error flushing zlib buffers. Error code", z_err ); xmlIOErr(XML_IO_WRITE, (const char *) msg); } return ( zlgth );}#endif /* LIBXML_OUTPUT_ENABLED */#endif /* HAVE_ZLIB_H */#ifdef LIBXML_OUTPUT_ENABLED/** * xmlFreeHTTPWriteCtxt * @ctxt: Context to cleanup * * Free allocated memory and reclaim system resources. * * No return value. */static voidxmlFreeHTTPWriteCtxt( xmlIOHTTPWriteCtxtPtr ctxt ){ if ( ctxt->uri != NULL ) xmlFree( ctxt->uri ); if ( ctxt->doc_buff != NULL ) {#ifdef HAVE_ZLIB_H if ( ctxt->compression > 0 ) { xmlFreeZMemBuff( ctxt->doc_buff ); } else#endif { xmlOutputBufferClose( ctxt->doc_buff ); } } xmlFree( ctxt ); return;}#endif /* LIBXML_OUTPUT_ENABLED *//** * xmlIOHTTPMatch: * @filename: the URI for matching * * check if the URI matches an HTTP one * * Returns 1 if matches, 0 otherwise */intxmlIOHTTPMatch (const char *filename) { if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "http://", 7)) return(1); return(0);}/** * xmlIOHTTPOpen: * @filename: the URI for matching * * open an HTTP I/O channel * * Returns an I/O context or NULL in case of error */void *xmlIOHTTPOpen (const char *filename) { return(xmlNanoHTTPOpen(filename, NULL));}#ifdef LIBXML_OUTPUT_ENABLED/** * xmlIOHTTPOpenW: * @post_uri: The destination URI for the document * @compression: The compression desired for the document. * * Open a temporary buffer to collect the document for a subsequent HTTP POST * request. Non-static as is called from the output buffer creation routine. * * Returns an I/O context or NULL in case of error. */void *xmlIOHTTPOpenW(const char *post_uri, int compression){ xmlIOHTTPWriteCtxtPtr ctxt = NULL; if (post_uri == NULL) return (NULL); ctxt = xmlMalloc(sizeof(xmlIOHTTPWriteCtxt)); if (ctxt == NULL) { xmlIOErrMemory("creating HTTP output context"); return (NULL); } (void) memset(ctxt, 0, sizeof(xmlIOHTTPWriteCtxt)); ctxt->uri = (char *) xmlStrdup((const xmlChar *)post_uri); if (ctxt->uri == NULL) { xmlIOErrMemory("copying URI"); xmlFreeHTTPWriteCtxt(ctxt); return (NULL); } /* * ** Since the document length is required for an HTTP post, * ** need to put the document into a buffer. A memory buffer * ** is being used to avoid pushing the data to disk and back. */#ifdef HAVE_ZLIB_H if ((compression > 0) && (compression <= 9)) { ctxt->compression = compression; ctxt->doc_buff = xmlCreateZMemBuff(compression); } else#endif { /* Any character conversions should have been done before this */ ctxt->doc_buff = xmlAllocOutputBuffer(NULL); } if (ctxt->doc_buff == NULL) { xmlFreeHTTPWriteCtxt(ctxt); ctxt = NULL; } return (ctxt);}#endif /* LIBXML_OUTPUT_ENABLED */ #ifdef LIBXML_OUTPUT_ENABLED/** * xmlIOHTTPDfltOpenW * @post_uri: The destination URI for this document. * * Calls xmlIOHTTPOpenW with no compression to set up for a subsequent * HTTP post command. This function should generally not be used as * the open callback is short circuited in xmlOutputBufferCreateFile. * * Returns a pointer to the new IO context. */static void *xmlIOHTTPDfltOpenW( const char * post_uri ) { return ( xmlIOHTTPOpenW( post_uri, 0 ) );}#endif /* LIBXML_OUTPUT_ENABLED *//** * xmlIOHTTPRead: * @context: the I/O context * @buffer: where to drop data * @len: number of bytes to write * * Read @len bytes to @buffer from the I/O channel. * * Returns the number of bytes written */int xmlIOHTTPRead(void * context, char * buffer, int len) { if ((buffer == NULL) || (len < 0)) return(-1); return(xmlNanoHTTPRead(context, &buffer[0], len));}#ifdef LIBXML_OUTPUT_ENABLED/** * xmlIOHTTPWrite * @context: previously opened writing context * @buffer: data to output to temporary buffer * @len: bytes to output * * Collect data from memory buffer into a temporary file for later * processing. * * Returns number of bytes written. */static intxmlIOHTTPWrite( void * context, const char * buffer, int len ) { xmlIOHTTPWriteCtxtPtr ctxt = context; if ( ( ctxt == NULL ) || ( ctxt->doc_buff == NULL ) || ( buffer == NULL ) ) return ( -1 ); if ( len > 0 ) { /* Use gzwrite or fwrite as previously setup in the open call */#ifdef HAVE_ZLIB_H if ( ctxt->compression > 0 ) len = xmlZMemBuffAppend( ctxt->doc_buff, buffer, len ); else#endif len = xmlOutputBufferWrite( ctxt->doc_buff, len, buffer ); if ( len < 0 ) { xmlChar msg[500]; xmlStrPrintf(msg, 500, (const xmlChar *) "xmlIOHTTPWrite: %s\n%s '%s'.\n", "Error appending to internal buffer.", "Error sending document to URI", ctxt->uri ); xmlIOErr(XML_IO_WRITE, (const char *) msg); } } return ( len );}#endif /* LIBXML_OUTPUT_ENABLED *//** * xmlIOHTTPClose: * @context: the I/O context * * Close an HTTP I/O channel * * Returns 0 */intxmlIOHTTPClose (void * context) { xmlNanoHTTPClose(context); return 0;}#ifdef LIBXML_OUTPUT_ENABLED/** * xmlIOHTTCloseWrite * @context: The I/O context * @http_mthd: The HTTP method to be used when sending the data * * Close the transmit HTTP I/O channel and actually send the data. */static intxmlIOHTTPCloseWrite( void * context, const char * http_mthd ) { int close_rc = -1; int http_rtn = 0; int content_lgth = 0; xmlIOHTTPWriteCtxtPtr ctxt = context; char * http_content = NULL; char * content_encoding = NULL; char * content_type = (char *) "text/xml"; void * http_ctxt = NULL; if ( ( ctxt == NULL ) || ( http_mthd == NULL ) ) return ( -1 ); /* Retrieve the content from the appropriate buffer */#ifdef HAVE_ZLIB_H if ( ctxt->compression > 0 ) { content_lgth = xmlZMemBuffGetContent( ctxt->doc_buff, &http_content ); content_encoding = (char *) "Content-Encoding: gzip"; } else#endif { /* Pull the data out of the memory output buffer */ xmlOutputBufferPtr dctxt = ctxt->doc_buff; http_content = (char *)dctxt->buffer->content; content_lgth = dctxt->buffer->use; } if ( http_content == NULL ) { xmlChar msg[500]; xmlStrPrintf(msg, 500, (const xmlChar *) "xmlIOHTTPCloseWrite: %s '%s' %s '%s'.\n", "Error retrieving content.\nUnable to", http_mthd, "data to URI", ctxt->uri ); xmlIOErr(XML_IO_WRITE, (const char *) msg); } else { http_ctxt = xmlNanoHTTPMethod( ctxt->uri, http_mthd, http_content, &content_type, content_encoding, content_lgth ); if ( http_ctxt != NULL ) {#ifdef DEBUG_HTTP /* If testing/debugging - dump reply with request content */ FILE * tst_file = NULL; char buffer[ 4096 ]; char * dump_name = NULL; int avail; xmlGenericError( xmlGenericErrorContext, "xmlNanoHTTPCloseWrite: HTTP %s to\n%s returned %d.\n", http_mthd, ctxt->uri, xmlNanoHTTPReturnCode( http_ctxt ) ); /* ** Since either content or reply may be gzipped, ** dump them to separate files instead of the ** standard error context. */ dump_name = tempnam( NULL, "lxml" ); if ( dump_name != NULL ) { (void)snprintf( buffer, sizeof(buffer), "%s.content", dump_name ); tst_file = fopen( buffer, "wb" ); if ( tst_file != NULL ) { xmlGenericError( xmlGenericErrorContext, "Transmitted content saved in file: %s\n", buffer ); fwrite( http_content, sizeof( char ), content_lgth, tst_file ); fclose( tst_file ); } (void)snprintf( buffer, sizeof(buffer), "%s.reply", dump_name ); tst_file = fopen( buffer, "wb" ); if ( tst_file != NULL ) { xmlGenericError( xmlGenericErrorContext, "Reply content saved in file: %s\n", buffer ); while ( (avail = xmlNanoHTTPRead( http_ctxt, buffer, sizeof( buffer ) )) > 0 ) { fwrite( buffer, sizeof( char ), avail, tst_file ); } fclose( tst_file ); } free( dump_name ); }#endif /* DEBUG_HTTP */ http_rtn = xmlNanoHTTPReturnCode( http_ctxt ); if ( ( http_rtn >= 200 ) && ( http_rtn < 300 ) ) close_rc = 0; else { xmlChar msg[500]; xmlStrPrintf(msg, 500, (const xmlChar *) "xmlIOHTTPCloseWrite: HTTP '%s' of %d %s\n'%s' %s %d\n", http_mthd, content_lgth, "bytes to URI", ctxt->uri, "failed. HTTP return code:", http_rtn ); xmlIOErr(XML_IO_WRITE, (const char *) msg); } xmlNanoHTTPClose( http_ctxt ); xmlFree( content_type ); } } /* Final cleanups */ xmlFreeHTTPWriteCtxt( ctxt ); return ( close_rc );}/** * xmlIOHTTPClosePut * * @context: The I/O context * * Close the transmit HTTP I/O channel and actually send data using a PUT * HTTP method. */static intxmlIOHTTPClosePut( void * ctxt ) { return ( xmlIOHTTPCloseWrite( ctxt, "PUT" ) );}/** * xmlIOHTTPClosePost * * @context: The I/O context * * Close the transmit HTTP I/O channel and actually send data using a POST * HTTP method. */static intxmlIOHTTPClosePost( void * ctxt ) { return ( xmlIOHTTPCloseWrite( ctxt, "POST" ) );}#endif /* LIBXML_OUTPUT_ENABLED */#endif /* LIBXML_HTTP_ENABLED */#ifdef LIBXML_FTP_ENABLED/************************************************************************ * * * I/O for FTP file accesses * * * ************************************************************************//** * xmlIOFTPMatch: * @filename: the URI for matching * * check if the URI matches an FTP one * * Returns 1 if matches, 0 otherwise */intxmlIOFTPMatch (const char *filename) { if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "ftp://", 6)) return(1); return(0);}/** * xmlIOFTPOpen: * @filename: the URI for matching * * open an FTP I/O channel * * Returns an I/O context or NULL in case of error */void *xmlIOFTPOpen (const char *filename) { return(xmlNanoFTPOpen(filename));}/** * xmlIOFTPRead: * @context: the I/O context * @buffer: where to drop data * @len: number of bytes to write * * Read @len bytes to @buffer from the I/O channel. * * Returns the number of bytes written */int xmlIOFTPRead(void * context, char * buffer, int len) { if ((buffer == NULL) || (len < 0)) return(-1); return(xmlNanoFTPRead(context, &buffer[0], len));}/** * xmlIOFTPClose: * @context: the I/O context * * Close an FTP I/O channel * * Returns 0 */intxmlIOFTPClose (void * context) { return ( xmlNanoFTPClose(context) );}#endif /* LIBXML_FTP_ENABLED *//** * xmlRegisterInputCallbacks: * @matchFunc: the xmlInputMatchCallback * @openFunc: the xmlInputOpenCallback * @readFunc: the xmlInputReadCallback * @closeFunc: the xmlInputCloseCallback * * Register a new set of I/O callback for handling parser input. * * Returns the registered handler number or -1 in case of error */intxmlRegisterInputCallbacks(xmlInputMatchCallback matchFunc, xmlInputOpenCallback openFunc, xmlInputReadCallback readFunc, xmlInputCloseCallback closeFunc) { if (xmlInputCallbackNr >= MAX_INPUT_CALLBACK) { return(-1); } xmlInputCallbackTable[xmlInputCallbackNr].matchcallback = matchFunc; xmlInputCallbackTable[xmlInputCallbackNr].opencallback = openFunc; xmlInputCallbackTable[xmlInputCallbackNr].readcallback = readFunc; xmlInputCallbackTable[xmlInputCallbackNr].closecallback = closeFunc; xmlInputCallbackInitialized = 1; return(xmlInputCallbackNr++);}#ifdef LIBXML_OUTPUT_ENABLED/** * xmlRegisterOutputCallbacks: * @matchFunc: the xmlOutputMatchCallback * @openFunc: the xmlOutputOpenCallback * @writeFunc: the xmlOutputWriteCallback * @closeFunc: the xmlOutputCloseCallback * * Register a new set of I/O callback for handling output. * * Returns the registered handler number or -1 in case of error */intxmlRegisterOutputCallbacks(xmlOutputMatchCallback matchFunc, xmlOutputOpenCallback openFunc, xmlOutputWriteCallback writeFunc, xmlOutputCloseCallback closeFunc) { if (xmlOutputCallbackNr >= MAX_INPUT_CALLBACK) { return(-1); } xmlOutputCallbackTable[xmlOutputCallbackNr].matchcallback = matchFunc; xmlOutputCallbackTable[xmlOutputCallbackNr].opencallback = openFunc; xmlOutputCallbackTable[xmlOutputCallbackNr].writecallback = writeFunc; xmlOutputCallbackTable[xmlOutputCallbackNr].closecallback = closeFunc; xmlOutputCallbackInitialized = 1; return(xmlOutputCallbackNr++);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -