📄 xmlio.c
字号:
* 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++);}#endif /* LIBXML_OUTPUT_ENABLED *//** * xmlRegisterDefaultInputCallbacks: * * Registers the default compiled-in I/O handlers. */voidxmlRegisterDefaultInputCallbacks(void) { if (xmlInputCallbackInitialized) return; xmlRegisterInputCallbacks(xmlFileMatch, xmlFileOpen, xmlFileRead, xmlFileClose);#ifdef HAVE_ZLIB_H xmlRegisterInputCallbacks(xmlGzfileMatch, xmlGzfileOpen, xmlGzfileRead, xmlGzfileClose);#endif /* HAVE_ZLIB_H */#ifdef LIBXML_HTTP_ENABLED xmlRegisterInputCallbacks(xmlIOHTTPMatch, xmlIOHTTPOpen, xmlIOHTTPRead, xmlIOHTTPClose);#endif /* LIBXML_HTTP_ENABLED */#ifdef LIBXML_FTP_ENABLED xmlRegisterInputCallbacks(xmlIOFTPMatch, xmlIOFTPOpen, xmlIOFTPRead, xmlIOFTPClose);#endif /* LIBXML_FTP_ENABLED */ xmlInputCallbackInitialized = 1;}#ifdef LIBXML_OUTPUT_ENABLED/** * xmlRegisterDefaultOutputCallbacks: * * Registers the default compiled-in I/O handlers. */voidxmlRegisterDefaultOutputCallbacks(void) { if (xmlOutputCallbackInitialized) return; xmlRegisterOutputCallbacks(xmlFileMatch, xmlFileOpenW, xmlFileWrite, xmlFileClose);#ifdef LIBXML_HTTP_ENABLED xmlRegisterOutputCallbacks(xmlIOHTTPMatch, xmlIOHTTPDfltOpenW, xmlIOHTTPWrite, xmlIOHTTPClosePut);#endif/********************************* No way a-priori to distinguish between gzipped files from uncompressed ones except opening if existing then closing and saving with same compression ratio ... a pain.#ifdef HAVE_ZLIB_H xmlRegisterOutputCallbacks(xmlGzfileMatch, xmlGzfileOpen, xmlGzfileWrite, xmlGzfileClose);#endif Nor FTP PUT ....#ifdef LIBXML_FTP_ENABLED xmlRegisterOutputCallbacks(xmlIOFTPMatch, xmlIOFTPOpen, xmlIOFTPWrite, xmlIOFTPClose);#endif **********************************/ xmlOutputCallbackInitialized = 1;}#ifdef LIBXML_HTTP_ENABLED/** * xmlRegisterHTTPPostCallbacks: * * By default, libxml submits HTTP output requests using the "PUT" method. * Calling this method changes the HTTP output method to use the "POST" * method instead. * */voidxmlRegisterHTTPPostCallbacks( void ) { /* Register defaults if not done previously */ if ( xmlOutputCallbackInitialized == 0 ) xmlRegisterDefaultOutputCallbacks( ); xmlRegisterOutputCallbacks(xmlIOHTTPMatch, xmlIOHTTPDfltOpenW, xmlIOHTTPWrite, xmlIOHTTPClosePost); return;}#endif#endif /* LIBXML_OUTPUT_ENABLED *//** * xmlAllocParserInputBuffer: * @enc: the charset encoding if known * * Create a buffered parser input for progressive parsing * * Returns the new parser input or NULL */xmlParserInputBufferPtrxmlAllocParserInputBuffer(xmlCharEncoding enc) { xmlParserInputBufferPtr ret; ret = (xmlParserInputBufferPtr) xmlMalloc(sizeof(xmlParserInputBuffer)); if (ret == NULL) { xmlIOErrMemory("creating input buffer"); return(NULL); } memset(ret, 0, (size_t) sizeof(xmlParserInputBuffer)); ret->buffer = xmlBufferCreateSize(2 * xmlDefaultBufferSize); if (ret->buffer == NULL) { xmlFree(ret); return(NULL); } ret->buffer->alloc = XML_BUFFER_ALLOC_DOUBLEIT; ret->encoder = xmlGetCharEncodingHandler(enc); if (ret->encoder != NULL) ret->raw = xmlBufferCreateSize(2 * xmlDefaultBufferSize); else ret->raw = NULL; ret->readcallback = NULL; ret->closecallback = NULL; ret->context = NULL; ret->compressed = -1; ret->rawconsumed = 0; return(ret);}#ifdef LIBXML_OUTPUT_ENABLED/** * xmlAllocOutputBuffer: * @encoder: the encoding converter or NULL * * Create a buffered parser output * * Returns the new parser output or NULL */xmlOutputBufferPtrxmlAllocOutputBuffer(xmlCharEncodingHandlerPtr encoder) { xmlOutputBufferPtr ret; ret = (xmlOutputBufferPtr) xmlMalloc(sizeof(xmlOutputBuffer)); if (ret == NULL) { xmlIOErrMemory("creating output buffer"); return(NULL); } memset(ret, 0, (size_t) sizeof(xmlOutputBuffer)); ret->buffer = xmlBufferCreate(); if (ret->buffer == NULL) { xmlFree(ret); return(NULL); } ret->buffer->alloc = XML_BUFFER_ALLOC_DOUBLEIT; ret->encoder = encoder; if (encoder != NULL) { ret->conv = xmlBufferCreateSize(4000); /* * This call is designed to initiate the encoder state */ xmlCharEncOutFunc(encoder, ret->conv, NULL); } else ret->conv = NULL; ret->writecallback = NULL; ret->closecallback = NULL; ret->context = NULL; ret->written = 0; return(ret);}#endif /* LIBXML_OUTPUT_ENABLED *//** * xmlFreeParserInputBuffer: * @in: a buffered parser input * * Free up the memory used by a buffered parser input */voidxmlFreeParserInputBuffer(xmlParserInputBufferPtr in) { if (in == NULL) return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -