📄 xmlio.c
字号:
xmlParserInputBufferPtr ret; ret = (xmlParserInputBufferPtr) xmlMalloc(sizeof(xmlParserInputBuffer)); if (ret == NULL) { fprintf(stderr, "xmlAllocParserInputBuffer : out of memory!\n"); return(NULL); } memset(ret, 0, (size_t) sizeof(xmlParserInputBuffer)); ret->buffer = xmlBufferCreate(); if (ret->buffer == NULL) { xmlFree(ret); return(NULL); } ret->buffer->alloc = XML_BUFFER_ALLOC_DOUBLEIT; ret->encoder = xmlGetCharEncodingHandler(enc); ret->readcallback = NULL; ret->closecallback = NULL; ret->context = NULL; return(ret);}/** * xmlFreeParserInputBuffer: * @in: a buffered parser input * * Free up the memory used by a buffered parser input */voidxmlFreeParserInputBuffer(xmlParserInputBufferPtr in) { if (in->buffer != NULL) { xmlBufferFree(in->buffer); in->buffer = NULL; } if (in->closecallback != NULL) { in->closecallback(in->context); } memset(in, 0xbe, (size_t) sizeof(xmlParserInputBuffer)); xmlFree(in);}/** * xmlParserInputBufferCreateFilename: * @URI: a C string containing the URI or filename * @enc: the charset encoding if known * * Create a buffered parser input for the progressive parsing of a file * If filename is "-' then we use stdin as the input. * Automatic support for ZLIB/Compress compressed document is provided * by default if found at compile-time. * Do an encoding check if enc == XML_CHAR_ENCODING_NONE * * Returns the new parser input or NULL */xmlParserInputBufferPtrxmlParserInputBufferCreateFilename(const char *URI, xmlCharEncoding enc) { xmlParserInputBufferPtr ret; int i; void *context = NULL; if (xmlInputCallbackInitialized == 0) xmlRegisterDefaultInputCallbacks(); if (URI == NULL) return(NULL); /* * Try to find one of the input accept method accepting taht scheme * Go in reverse to give precedence to user defined handlers. */ for (i = xmlInputCallbackNr - 1;i >= 0;i--) { if ((xmlInputCallbackTable[i].matchcallback != NULL) && (xmlInputCallbackTable[i].matchcallback(URI) != 0)) { context = xmlInputCallbackTable[i].opencallback(URI); if (context != NULL) break; } } if (context == NULL) {#ifdef DEBUG_INPUT fprintf(stderr, "No input filter matching \"%s\"\n", URI);#endif return(NULL); } /* * Allocate the Input buffer front-end. */ ret = xmlAllocParserInputBuffer(enc); if (ret != NULL) { ret->context = context; ret->readcallback = xmlInputCallbackTable[i].readcallback; ret->closecallback = xmlInputCallbackTable[i].closecallback; } return(ret);}/** * xmlParserInputBufferCreateFile: * @file: a FILE* * @enc: the charset encoding if known * * Create a buffered parser input for the progressive parsing of a FILE * * buffered C I/O * * Returns the new parser input or NULL */xmlParserInputBufferPtrxmlParserInputBufferCreateFile(FILE *file, xmlCharEncoding enc) { xmlParserInputBufferPtr ret; if (xmlInputCallbackInitialized == 0) xmlRegisterDefaultInputCallbacks(); if (file == NULL) return(NULL); ret = xmlAllocParserInputBuffer(enc); if (ret != NULL) { ret->context = file; ret->readcallback = xmlFileRead; ret->closecallback = xmlFileClose; } return(ret);}/** * xmlParserInputBufferCreateFd: * @fd: a file descriptor number * @enc: the charset encoding if known * * Create a buffered parser input for the progressive parsing for the input * from a file descriptor * * Returns the new parser input or NULL */xmlParserInputBufferPtrxmlParserInputBufferCreateFd(int fd, xmlCharEncoding enc) { xmlParserInputBufferPtr ret; if (fd < 0) return(NULL); ret = xmlAllocParserInputBuffer(enc); if (ret != NULL) { ret->context = (void *) fd; ret->readcallback = xmlFdRead; ret->closecallback = xmlFdClose; } return(ret);}/** * xmlParserInputBufferCreateIO: * @ioread: an I/O read function * @ioclose: an I/O close function * @ioctx: an I/O handler * @enc: the charset encoding if known * * Create a buffered parser input for the progressive parsing for the input * from a file descriptor * * Returns the new parser input or NULL */xmlParserInputBufferPtrxmlParserInputBufferCreateIO(xmlInputReadCallback ioread, xmlInputCloseCallback ioclose, void *ioctx, xmlCharEncoding enc) { xmlParserInputBufferPtr ret; if (ioread == NULL) return(NULL); ret = xmlAllocParserInputBuffer(enc); if (ret != NULL) { ret->context = (void *) ioctx; ret->readcallback = ioread; ret->closecallback = ioclose; } return(ret);}/** * xmlParserInputBufferPush: * @in: a buffered parser input * @buf: an char array * @len: the size in bytes of the array. * * Push the content of the arry in the input buffer * This routine handle the I18N transcoding to internal UTF-8 * This is used when operating the parser in progressive (push) mode. * * Returns the number of chars read and stored in the buffer, or -1 * in case of error. */intxmlParserInputBufferPush(xmlParserInputBufferPtr in, int len, const char *buf) { int nbchars = 0; if (len < 0) return(0); if (in->encoder != NULL) { xmlChar *buffer; int processed = len; buffer = (xmlChar *) xmlMalloc((len + 1) * 2 * sizeof(xmlChar)); if (buffer == NULL) { fprintf(stderr, "xmlParserInputBufferGrow : out of memory !\n"); return(-1); } nbchars = in->encoder->input(buffer, (len + 1) * 2 * sizeof(xmlChar), (xmlChar *) buf, &processed); /* * TODO : we really need to have something atomic or the * encoder must report the number of bytes read */ if (nbchars < 0) { fprintf(stderr, "xmlParserInputBufferPush: encoder error\n"); xmlFree(buffer); return(-1); } if (processed != len) { fprintf(stderr, "TODO xmlParserInputBufferPush: processed != len\n"); xmlFree(buffer); return(-1); } buffer[nbchars] = 0; xmlBufferAdd(in->buffer, (xmlChar *) buffer, nbchars); xmlFree(buffer); } else { nbchars = len; xmlBufferAdd(in->buffer, (xmlChar *) buf, nbchars); }#ifdef DEBUG_INPUT fprintf(stderr, "I/O: pushed %d chars, buffer %d/%d\n", nbchars, in->buffer->use, in->buffer->size);#endif return(nbchars);}/** * xmlParserInputBufferGrow: * @in: a buffered parser input * @len: indicative value of the amount of chars to read * * Grow up the content of the input buffer, the old data are preserved * This routine handle the I18N transcoding to internal UTF-8 * This routine is used when operating the parser in normal (pull) mode * TODO: one should be able to remove one extra copy * * Returns the number of chars read and stored in the buffer, or -1 * in case of error. */intxmlParserInputBufferGrow(xmlParserInputBufferPtr in, int len) { char *buffer = NULL; int res = 0; int nbchars = 0; int buffree; if ((len <= MINLEN) && (len != 4)) len = MINLEN; buffree = in->buffer->size - in->buffer->use; if (buffree <= 0) { fprintf(stderr, "xmlParserInputBufferGrow : buffer full !\n"); return(0); } if (len > buffree) len = buffree; buffer = xmlMalloc((len + 1) * sizeof(char)); if (buffer == NULL) { fprintf(stderr, "xmlParserInputBufferGrow : out of memory !\n"); return(-1); } /* * Call the read method for this I/O type. */ if (in->readcallback != NULL) { res = in->readcallback(in->context, &buffer[0], len); } else { fprintf(stderr, "xmlParserInputBufferGrow : no input !\n"); xmlFree(buffer); return(-1); } if (res == 0) { xmlFree(buffer); return(0); } if (res < 0) { perror ("read error"); xmlFree(buffer); return(-1); } if (in->encoder != NULL) { xmlChar *buf; int wrote = res; buf = (xmlChar *) xmlMalloc((res + 1) * 2 * sizeof(xmlChar)); if (buf == NULL) { fprintf(stderr, "xmlParserInputBufferGrow : out of memory !\n"); xmlFree(buffer); return(-1); } nbchars = in->encoder->input(buf, (res + 1) * 2 * sizeof(xmlChar), BAD_CAST buffer, &wrote); buf[nbchars] = 0; xmlBufferAdd(in->buffer, (xmlChar *) buf, nbchars); xmlFree(buf); /* * Check that the encoder was able to process the full input */ if (wrote != res) { fprintf(stderr, "TODO : xmlParserInputBufferGrow wrote %d != res %d\n", wrote, res); /* * TODO !!! * Need to keep the unprocessed input in a buffer in->unprocessed */ } } else { nbchars = res; buffer[nbchars] = 0; xmlBufferAdd(in->buffer, (xmlChar *) buffer, nbchars); }#ifdef DEBUG_INPUT fprintf(stderr, "I/O: read %d chars, buffer %d/%d\n", nbchars, in->buffer->use, in->buffer->size);#endif xmlFree(buffer); return(nbchars);}/** * xmlParserInputBufferRead: * @in: a buffered parser input * @len: indicative value of the amount of chars to read * * Refresh the content of the input buffer, the old data are considered * consumed * This routine handle the I18N transcoding to internal UTF-8 * * Returns the number of chars read and stored in the buffer, or -1 * in case of error. */intxmlParserInputBufferRead(xmlParserInputBufferPtr in, int len) { /* xmlBufferEmpty(in->buffer); */ if (in->readcallback != NULL) return(xmlParserInputBufferGrow(in, len)); else return(0);}/* * xmlParserGetDirectory: * @filename: the path to a file * * lookup the directory for that file * * Returns a new allocated string containing the directory, or NULL. */char *xmlParserGetDirectory(const char *filename) { char *ret = NULL; char dir[1024]; char *cur; char sep = '/'; if (xmlInputCallbackInitialized == 0) xmlRegisterDefaultInputCallbacks(); if (filename == NULL) return(NULL);#ifdef WIN32 sep = '\\';#endif strncpy(dir, filename, 1023); dir[1023] = 0; cur = &dir[strlen(dir)]; while (cur > dir) { if (*cur == sep) break; cur --; } if (*cur == sep) { if (cur == dir) dir[1] = 0; else *cur = 0; ret = xmlMemStrdup(dir); } else { if (getcwd(dir, 1024) != NULL) { dir[1023] = 0; ret = xmlMemStrdup(dir); } } return(ret);}/**************************************************************** * * * External entities loading * * * ****************************************************************//* * xmlDefaultExternalEntityLoader: * @URL: the URL for the entity to load * @ID: the System ID for the entity to load * @ctxt: the context in which the entity is called or NULL * * By default we don't load external entitites, yet. * * Returns a new allocated xmlParserInputPtr, or NULL. */staticxmlParserInputPtrxmlDefaultExternalEntityLoader(const char *URL, const char *ID, xmlParserCtxtPtr ctxt) { xmlParserInputPtr ret = NULL;#ifdef DEBUG_EXTERNAL_ENTITIES fprintf(stderr, "xmlDefaultExternalEntityLoader(%s, xxx)\n", URL);#endif if (URL == NULL) { if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) ctxt->sax->warning(ctxt, "failed to load external entity \"%s\"\n", ID); return(NULL); } ret = xmlNewInputFromFile(ctxt, URL); if (ret == NULL) { if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) ctxt->sax->warning(ctxt, "failed to load external entity \"%s\"\n", URL); } return(ret);}static xmlExternalEntityLoader xmlCurrentExternalEntityLoader = xmlDefaultExternalEntityLoader;/* * xmlSetExternalEntityLoader: * @f: the new entity resolver function * * Changes the defaultexternal entity resolver function for the application */voidxmlSetExternalEntityLoader(xmlExternalEntityLoader f) { xmlCurrentExternalEntityLoader = f;}/* * xmlGetExternalEntityLoader: * * Get the default external entity resolver function for the application * * Returns the xmlExternalEntityLoader function pointer */xmlExternalEntityLoaderxmlGetExternalEntityLoader(void) { return(xmlCurrentExternalEntityLoader);}/* * xmlLoadExternalEntity: * @URL: the URL for the entity to load * @ID: the System ID for the entity to load * @ctxt: the context in which the entity is called or NULL * * Load an external entity, note that the use of this function for * unparsed entities may generate problems * TODO: a more generic External entitiy API must be designed * * Returns the xmlParserInputPtr or NULL */xmlParserInputPtrxmlLoadExternalEntity(const char *URL, const char *ID, xmlParserCtxtPtr ctxt) { return(xmlCurrentExternalEntityLoader(URL, ID, ctxt));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -