Re: [xml] context reuse for push parser



I have updated my function:

static int xmlCtxtInitPushParser(xmlParserCtxtPtr ctxt, const char
*chunk, int size, const char *filename, xmlCharEncoding enc)
{
  xmlParserInputPtr inputStream;
  xmlParserInputBufferPtr buf;
                                                                                
  if (enc == XML_CHAR_ENCODING_NONE && (chunk != NULL) && (size >= 4))
    enc = xmlDetectCharEncoding((const xmlChar *) chunk, size);
                                                                                
  buf = xmlAllocParserInputBuffer(enc);
  if (buf == NULL) return 1;
                                                                                
  if (ctxt == NULL) {
    xmlFreeParserInputBuffer(buf);
    return 1;
  }
                                                                                
  xmlCtxtReset(ctxt);
                                                                                
  if (ctxt->pushTab == NULL) {
    if ((ctxt->pushTab = (void **) xmlMalloc(ctxt->nameMax * 3 *
sizeof(xmlChar
*))) == NULL)
    {
      xmlFreeParserInputBuffer(buf);
      return 1;
    }
  }
                                                                                
  if (filename == NULL) {
    ctxt->directory = NULL;
  } else {
    ctxt->directory = xmlParserGetDirectory(filename);
  }
                                                                                
  inputStream = xmlNewInputStream(ctxt);
  if (inputStream == NULL) {
    xmlFreeParserInputBuffer(buf);
    return 1;
  }
                                                                                
  if (filename == NULL)
    inputStream->filename = NULL;
  else
    inputStream->filename = (char *)
      xmlCanonicPath((const xmlChar *) filename);
  inputStream->buf = buf;
  inputStream->base = inputStream->buf->buffer->content;
  inputStream->cur = inputStream->buf->buffer->content;
  inputStream->end =
    &inputStream->buf->buffer->content[inputStream->buf->buffer->use];
                                                                                
  inputPush(ctxt, inputStream);
                                                                                
  if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
      (ctxt->input->buf != NULL))  {
    int base = ctxt->input->base - ctxt->input->buf->buffer->content;
    int cur = ctxt->input->cur - ctxt->input->base;
                                                                                
    xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
                                                                                
    ctxt->input->base = ctxt->input->buf->buffer->content + base;
    ctxt->input->cur = ctxt->input->base + cur;
    ctxt->input->end =
      &ctxt->input->buf->buffer->content[ctxt->input->buf->buffer->use];
#ifdef DEBUG_PUSH
    xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
#endif
  }
                                                                                
  if (enc != XML_CHAR_ENCODING_NONE) {
    xmlSwitchEncoding(ctxt, enc);
  }
                                                                                
  return 0;
}


On Wed, Oct 22, 2003 at 08:06:35AM +0100, Graham Bennett wrote:
On Tue, Oct 21, 2003 at 05:58:45PM -0400, Daniel Veillard wrote:
On Tue, Oct 21, 2003 at 10:19:43PM +0100, Graham Bennett wrote:
Hi all,

I added the following function to enable me to reuse the parser context
using the push parser.  It corresponds to xmlCreatePushParserCtxt, but
takes an existing context.  Not sure if it's generally useful but it
seems to work for my code.

  Okay might make a good addition to the new parser interfaces.

[ snip ]

  if (ctxt == NULL) {
    xmlErrMemory(NULL, "No parser context\n");

  Hum, this isn't really a memory error. It's an API use error, I would rather
make the function return 0 in case of success and -1 in case of error, and
return -1 in that case (and check on function entry).

Yep sounds better.  I'm sure a lot of it needs to be cleaned up, I just
did the bare minimum to get it working.
 
    xmlFreeParserInputBuffer(buf);
    return;
  }

  xmlCtxtReset(ctxt);

  ctxt->pushTab = (void **) xmlMalloc(ctxt->nameMax * 3 * sizeof(xmlChar
*));

  Hum, you're likely to memleak there. ctxt->pushTab is probably not NULL,

Oops yes, that's wrong :)

[ snip ]

  if (enc != XML_CHAR_ENCODING_NONE) {
    xmlSwitchEncoding(ctxt, enc);
  }

  maybe an extra encoding passed as a const char * is needed. C.f. 
section F.2. of the spec:
   http://www.w3.org/TR/REC-xml#sec-guessing-with-ext-info
in that case the context encoding overrides the one fine in the XML
declaration or autodetected by xmlDetectCharEncoding() which implement
the F.1. detection algorithm.
 
Sounds reasonable.  In my case I think I'd always want to autodetect it,
but still it would be useful.

  it's a good idea, that could be reused within the xmlreader code.

Ok cool.

Thanks,

Graham.

-- 
Graham Bennett
_______________________________________________
xml mailing list, project page  http://xmlsoft.org/
xml gnome org
http://mail.gnome.org/mailman/listinfo/xml

-- 
Graham Bennett



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]