Exemplo n.º 1
0
xmlChar *xml_convert_input(const char *in, const char *encoding) {
	xmlChar *out;
	int ret;
	int size;
	int out_size;
	int temp;
	xmlCharEncodingHandlerPtr handler;
	handler = xmlFindCharEncodingHandler(encoding);
	assert(handler != NULL);
	size = (int)strlen(in) + 1;
	out_size = size * 2 - 1;
	out = (unsigned char *)xmlMalloc((size_t) out_size);
	if (out != NULL) {
		temp = size - 1;
		ret = handler->input(out, &out_size, (const xmlChar *)in, &temp);
		if ((ret < 0) || (temp - size + 1)) {
			xmlFree(out);
			out = 0;
		} else {
			out = (unsigned char *)xmlRealloc(out, out_size + 1);
			out[out_size] = 0;  /*null terminating out */
		}
	}
	return out;
}
Exemplo n.º 2
0
/* wrapper for stats_event, this takes a charset to convert from */
void stats_event_conv(const char *mount, const char *name, const char *value, const char *charset)
{
    const char *metadata = value;
    xmlBufferPtr conv = xmlBufferCreate ();

    if (charset && value)
    {
        xmlCharEncodingHandlerPtr handle = xmlFindCharEncodingHandler (charset);

        if (handle)
        {
            xmlBufferPtr raw = xmlBufferCreate ();
            xmlBufferAdd (raw, (const xmlChar *)value, strlen (value));
            if (xmlCharEncInFunc (handle, conv, raw) > 0)
                metadata = (char *)xmlBufferContent (conv);
            xmlBufferFree (raw);
            xmlCharEncCloseFunc (handle);
        }
        else
            WARN1 ("No charset found for \"%s\"", charset);
    }

    stats_event (mount, name, metadata);
    xmlBufferFree (conv);
}
Exemplo n.º 3
0
/**
 * ConvertInput:
 * @in: string in a given encoding
 * @encoding: the encoding used
 *
 * Converts @in into UTF-8 for processing with libxml2 APIs
 *
 * Returns the converted UTF-8 string, or NULL in case of error.
 */
xmlChar* cpXmlCmdOutput::ConvertInput( const xmlChar* in, const xmlChar* encoding )
{
   xmlChar *out;
   int ret;
   int size;
   int out_size;
   int temp;
   xmlCharEncodingHandlerPtr handler;

   if ( in == 0 )
      return 0;

   handler = xmlFindCharEncodingHandler( (const char *)encoding );

   if ( !handler )
   {
      printf( "ConvertInput: no encoding handler found for '%s'\n", encoding != 0 ? (const char *)encoding : "" );
      return 0;
   }

   size = (int) strlen( (const char*) in ) + 1;
   out_size = size * 2 - 1;
   out = (xmlChar *) xmlMalloc( (size_t) out_size );

   if ( out != 0 )
   {
      temp = size - 1;
      ret = handler->input( out, &out_size, in, &temp );
      if ( ( ret < 0 ) || ( temp - size + 1 ) )
      {
         if ( ret < 0 )
         {
            printf( "ConvertInput: conversion wasn't successful.\n" );
         }
         else
         {
            printf
               ( "ConvertInput: conversion wasn't successful. converted: %i octets.\n",
               temp );
         }

         xmlFree( out );
         out = 0;
      }
      else
      {
         out = (xmlChar *) xmlRealloc( out, out_size + 1 );
         out[out_size] = 0; //null termination
      }
   }
   else
   {
      printf( "ConvertInput: no mem\n" );
   }

   return out;
}
Exemplo n.º 4
0
XMLWrapper::XMLWrapper()
{
	mDocument = NULL;
	mCharEncodingHandler = xmlFindCharEncodingHandler ("UTF8");

	if (!mCharEncodingHandler) {
		/* no encoding handler found */
		std::cerr << "XMLWrapper::XMLWrapper - no encoding handler found" << std::endl;
	}
}
Exemplo n.º 5
0
xsltStylesheetPtr parse_xsl( char* xsl, int iXslType ) {
  xsltStylesheetPtr tParsedXslt   = NULL;
  xmlDocPtr         tXSLDocument  = NULL;
  
  /** Rem: For encoding */
  xmlCharEncodingHandlerPtr encoder = NULL;
  const xmlChar *encoding = NULL;
  
  /** Act: Encoding support */
  xmlInitCharEncodingHandlers( );

  /** Act: Parse XSL */
  if( iXslType == RUBY_XSLT_XSLSRC_TYPE_STR ) {
    tXSLDocument = xmlParseMemory( xsl, strlen( xsl ) );
    if( tXSLDocument == NULL ) {
      rb_raise( eXSLTParsingError, "XSL parsing error" );
      return( NULL );
    }

    tParsedXslt = xsltParseStylesheetDoc( tXSLDocument );
  } else if( iXslType == RUBY_XSLT_XSLSRC_TYPE_FILE ) {
    tParsedXslt = xsltParseStylesheetFile( BAD_CAST xsl );
  }

  if( tParsedXslt == NULL ) {
    rb_raise( eXSLTParsingError, "XSL Stylesheet parsing error" );
    return( NULL );
  }
    
  /** Act: Get encoding */
  XSLT_GET_IMPORT_PTR( encoding, tParsedXslt, encoding )
  encoder = xmlFindCharEncodingHandler((char *)encoding);
  
  if( encoding != NULL ) {
    encoder = xmlFindCharEncodingHandler((char *)encoding);
    if( (encoder != NULL) && (xmlStrEqual((const xmlChar *)encoder->name, (const xmlChar *) "UTF-8")) ) {
      encoder = NULL;
    }
  }
  
  return( tParsedXslt );
}
Exemplo n.º 6
0
static VALUE rxml_node_to_s(int argc, VALUE *argv, VALUE self)
{
  VALUE result = Qnil;
  VALUE options = Qnil;
  xmlNodePtr xnode;
  xmlCharEncodingHandlerPtr encodingHandler;
  xmlOutputBufferPtr output;

  int level = 0;
  int indent = 1;
  const char *xencoding = "UTF-8";

  rb_scan_args(argc, argv, "01", &options);

  if (!NIL_P(options))
  {
    VALUE rencoding, rindent, rlevel;
    Check_Type(options, T_HASH);
    rencoding = rb_hash_aref(options, ID2SYM(rb_intern("encoding")));
    rindent = rb_hash_aref(options, ID2SYM(rb_intern("indent")));
    rlevel = rb_hash_aref(options, ID2SYM(rb_intern("level")));

    if (rindent == Qfalse)
      indent = 0;

    if (rlevel != Qnil)
      level = NUM2INT(rlevel);

    if (rencoding != Qnil)
    {
      xencoding = xmlGetCharEncodingName((xmlCharEncoding)NUM2INT(rencoding));
      if (!xencoding)
        rb_raise(rb_eArgError, "Unknown encoding value: %d", NUM2INT(rencoding));
    }
  }

  encodingHandler = xmlFindCharEncodingHandler(xencoding);
  output = xmlAllocOutputBuffer(encodingHandler);

  xnode = rxml_get_xnode(self);

  xmlNodeDumpOutput(output, xnode->doc, xnode, level, indent, xencoding);
  xmlOutputBufferFlush(output);

  if (output->conv)
    result = rxml_new_cstr((const char*) output->conv->content, xencoding);
  else
    result = rxml_new_cstr((const char*) output->buffer->content, xencoding);

  xmlOutputBufferClose(output);
  
  return result;
}
Exemplo n.º 7
0
/**
 * htmlNodeDumpFileFormat:
 * @out:  the FILE pointer
 * @doc:  the document
 * @cur:  the current node
 * @encoding: the document encoding
 * @format:  should formatting spaces been added
 *
 * Dump an HTML node, recursive behaviour,children are printed too.
 *
 * TODO: if encoding == NULL try to save in the doc encoding
 *
 * returns: the number of byte written or -1 in case of failure.
 */
int
htmlNodeDumpFileFormat(FILE *out, xmlDocPtr doc,
	               xmlNodePtr cur, const char *encoding, int format) {
    xmlOutputBufferPtr buf;
    xmlCharEncodingHandlerPtr handler = NULL;
    int ret;

    xmlInitParser();

    if (encoding != NULL) {
	xmlCharEncoding enc;

	enc = xmlParseCharEncoding(encoding);
	if (enc != XML_CHAR_ENCODING_UTF8) {
	    handler = xmlFindCharEncodingHandler(encoding);
	    if (handler == NULL)
		return(-1);
	}
    }

    /*
     * Fallback to HTML or ASCII when the encoding is unspecified
     */
    if (handler == NULL)
	handler = xmlFindCharEncodingHandler("HTML");
    if (handler == NULL)
	handler = xmlFindCharEncodingHandler("ascii");

    /* 
     * save the content to a temp buffer.
     */
    buf = xmlOutputBufferCreateFile(out, handler);
    if (buf == NULL) return(0);

    htmlNodeDumpFormatOutput(buf, doc, cur, encoding, format);

    ret = xmlOutputBufferClose(buf);
    return(ret);
}
Exemplo n.º 8
0
Arquivo: jsio.c Projeto: atifs/juise
/*
 * Read xmlDocument from server
 */
static xmlDoc *
js_document_read (xmlParserCtxtPtr ctxt, js_session_t *jsp,
			const char *url, const char *encoding, int options)
{
    xmlParserInputBufferPtr input;
    xmlParserInputPtr stream;
    xmlDoc *docp;

    if (jsp == NULL || ctxt == NULL || jsp->js_state == JSS_DEAD)
        return NULL;

    xmlCtxtReset(ctxt);

    input = js_buffer_create(jsp, XML_CHAR_ENCODING_NONE);
    if (input == NULL)
        return NULL;
    input->closecallback = NULL;

    stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
    if (stream == NULL) {
        xmlFreeParserInputBuffer(input);
        return NULL;
    }

    inputPush(ctxt, stream);
    xmlCtxtUseOptions(ctxt, options);

    xmlCharEncodingHandlerPtr hdlr;
    if (encoding && ((hdlr = xmlFindCharEncodingHandler(encoding)) != NULL))
	xmlSwitchToEncoding(ctxt, hdlr);

    if (url != NULL && ctxt->input != NULL && ctxt->input->filename == NULL)
        ctxt->input->filename = (char *) xmlStrdup((const xmlChar *) url);

    /*
     * All right.  The stage is set, time to open the curtain and let
     * the show begin.
     */
    xmlParseDocument(ctxt);

    docp = ctxt->myDoc;
    ctxt->myDoc = NULL;

    if (docp && !ctxt->wellFormed) {
	xmlFreeDoc(docp);
        docp = NULL;
    }

    return docp;
}
Exemplo n.º 9
0
void XMLStream::toStream( xmlDocPtr doc, std::ostream &os )
{
    void *IOContexte = &os;

    const char *encoding="UTF-8";
    int formatWithSpace=1;
    xmlCharEncodingHandlerPtr handler = xmlFindCharEncodingHandler(encoding);
    //xmlCharEncodingHandlerPtr handler = xmlGetCharEncodingHandler(XML_CHAR_ENCODING_UTF8); doesnt work :/

    SLM_ASSERT("handler not instanced", handler);

    //xmlThrDefIndentTreeOutput(4);
    xmlOutputBufferPtr outBuff = xmlOutputBufferCreateIO( streamIOWrite , streamIOClose, IOContexte, handler);
    xmlSaveFormatFileTo( outBuff, doc, encoding, formatWithSpace );
}
Exemplo n.º 10
0
OutputBuffer::OutputBuffer(const std::string & encoding)
{
    xmlCharEncodingHandlerPtr encoder = nullptr;
    if ( !encoding.empty() )
    {
        xmlCharEncoding enc = xmlParseCharEncoding(encoding.c_str());
        if ( enc != XML_CHAR_ENCODING_UTF8 )
        {
            encoder = xmlFindCharEncodingHandler(encoding.c_str());
            if ( encoder == nullptr )
                throw InternalError("Unsupported output encoding: " + encoding);
        }
    }
    
    _buf = xmlOutputBufferCreateIO(OutputBuffer::write_cb, OutputBuffer::close_cb, this, encoder);
    if ( _buf == nullptr )
        throw InternalError("Failed to create xml output buffer");
}
Exemplo n.º 11
0
xmlChar*
PmmFastEncodeString( int charset,
                     const xmlChar *string,
                     const xmlChar *encoding )
{
    xmlCharEncodingHandlerPtr coder = NULL;
    xmlChar *retval = NULL;
    xmlBufferPtr in = NULL, out = NULL;

    if ( charset == XML_CHAR_ENCODING_UTF8 ) {
        /* warn("use UTF8 for encoding ... %s ", string); */
        return xmlStrdup( string );
    }
    else if ( charset == XML_CHAR_ENCODING_ERROR ) {
        /* warn("no standard encoding %s\n", encoding); */
        coder =xmlFindCharEncodingHandler( (const char *)encoding );
    }
    else if ( charset == XML_CHAR_ENCODING_NONE ) {
        xs_warn("PmmFastEncodeString: no encoding found\n");
    }
    else {
        /* warn( "use document encoding %s (%d)", encoding, charset ); */
        coder= xmlGetCharEncodingHandler( charset );
    }

    if ( coder != NULL ) {
        xs_warn("PmmFastEncodeString: coding machine found \n");
        in    = xmlBufferCreate();
        out   = xmlBufferCreate();
        xmlBufferCCat( in, (const char *) string );
        if ( xmlCharEncInFunc( coder, out, in ) >= 0 ) {
            retval = xmlStrdup( out->content );
            /* warn( "encoded string is %s" , retval); */
        }
        else {
            /* warn( "b0rked encoiding!\n"); */
        }

        xmlBufferFree( in );
        xmlBufferFree( out );
        xmlCharEncCloseFunc( coder );
    }
    return retval;
}
Exemplo n.º 12
0
static VALUE rxml_node_to_s(int argc, VALUE *argv, VALUE self)
{
  VALUE options = Qnil;
  xmlNodePtr xnode;
  xmlCharEncodingHandlerPtr encodingHandler;
  xmlOutputBufferPtr output;

  int level = 0;
  int indent = 1;
  const char *encoding = "UTF-8";

  rb_scan_args(argc, argv, "01", &options);

  if (!NIL_P(options))
  {
    VALUE rencoding, rindent, rlevel;
    Check_Type(options, T_HASH);
    rencoding = rb_hash_aref(options, ID2SYM(rb_intern("encoding")));
    rindent = rb_hash_aref(options, ID2SYM(rb_intern("indent")));
    rlevel = rb_hash_aref(options, ID2SYM(rb_intern("level")));

    if (rindent == Qfalse)
      indent = 0;

    if (rlevel != Qnil)
      level = NUM2INT(rlevel);

    if (rencoding != Qnil)
      encoding = RSTRING_PTR(rxml_input_encoding_to_s(cXMLInput, rencoding));
  }

  encodingHandler = xmlFindCharEncodingHandler(encoding);
  output = xmlAllocOutputBuffer(encodingHandler);

  Data_Get_Struct(self, xmlNode, xnode);
  xmlNodeDumpOutput(output, xnode->doc, xnode, level, indent, encoding);
  xmlOutputBufferFlush(output);

  if (output->conv)
    return rb_str_new2((const char*) output->conv->content);
  else
    return rb_str_new2((const char*) output->buffer->content);
}
Exemplo n.º 13
0
xmlChar*
PmmFastDecodeString( int charset,
                     const xmlChar *string,
                     const xmlChar *encoding)
{
    xmlCharEncodingHandlerPtr coder = NULL;
    xmlChar *retval = NULL;
    xmlBufferPtr in = NULL, out = NULL;

    if ( charset == XML_CHAR_ENCODING_UTF8 ) {
        return xmlStrdup( string );
    }
    else if ( charset == XML_CHAR_ENCODING_ERROR ) {
        coder = xmlFindCharEncodingHandler( (const char *) encoding );
    }
    else if ( charset == XML_CHAR_ENCODING_NONE ) {
        xs_warn("PmmFastDecodeString: no encoding found\n");
    }
    else {
        coder= xmlGetCharEncodingHandler( charset );
    }

    if ( coder != NULL ) {
        /* warn( "do encoding %s", string ); */
        in  = xmlBufferCreate();
        out = xmlBufferCreate();

        xmlBufferCat( in, string );
        if ( xmlCharEncOutFunc( coder, out, in ) >= 0 ) {
            retval = xmlCharStrndup((const char *)xmlBufferContent(out), xmlBufferLength(out));
        }
        else {
            xs_warn("PmmFastEncodeString: decoding error\n");
        }

        xmlBufferFree( in );
        xmlBufferFree( out );
        xmlCharEncCloseFunc( coder );
    }
    return retval;
}
Exemplo n.º 14
0
/*
 * call-seq:
 *    context.encoding = XML::Encoding::UTF_8
 *
 * Sets the character encoding for this context.
 */
static VALUE rxml_parser_context_encoding_set(VALUE self, VALUE encoding)
{
  xmlParserCtxtPtr ctxt;
  int result;
  const char* xencoding = xmlGetCharEncodingName((xmlCharEncoding)NUM2INT(encoding));
  xmlCharEncodingHandlerPtr hdlr = xmlFindCharEncodingHandler(xencoding);
  
  if (!hdlr)
    rb_raise(rb_eRuntimeError, "Unknown encoding: %s", encoding);

  Data_Get_Struct(self, xmlParserCtxt, ctxt);
  result = xmlSwitchToEncoding(ctxt, hdlr);

  if (result != 0)
    rxml_raise(&xmlLastError);

  if (ctxt->encoding != NULL)
    xmlFree((xmlChar *) ctxt->encoding);

  ctxt->encoding = xmlStrdup((const xmlChar *) xencoding);
  return self;
}
Exemplo n.º 15
0
char *
rss_utf8_enc (const unsigned char *in, const char *encoding)
{
  static xmlChar out[RSSMAXBUFSIZE * 2];
  int temp = 0;
  int size = 0;
  xmlCharEncodingHandlerPtr handler;

  if (!in)
    return NULL;

  handler = xmlFindCharEncodingHandler (encoding);

  if (!handler)
    return NULL;

  temp = strlen ((const char *) in);
  size = sizeof (out);

  handler->input (out, &size, in, &temp);

  return (char *) out;
}
Exemplo n.º 16
0
 void XMLNode::GetXML(std::string& out_xml_str, const std::string& encoding, bool user_friendly) const {
   out_xml_str.resize(0);
   if (!node_) return;
   if (node_->type != XML_ELEMENT_NODE) return;
   xmlDocPtr doc = node_->doc;
   if (doc == NULL) return;
   xmlCharEncodingHandlerPtr handler = NULL;
   handler = xmlFindCharEncodingHandler(encoding.c_str());
   if (handler == NULL) return;
   std::map<xmlNsPtr,xmlNsPtr> extns;
   CollectExternalNamespaces(node_, extns);
   std::string ns_str;
   NamespacesToString(extns, ns_str);
   out_xml_str.append(ns_str.length(),' ');
   //xmlOutputBufferPtr buf = xmlAllocOutputBuffer(handler);
   xmlOutputBufferPtr buf =
    xmlOutputBufferCreateIO(&write_to_string,&close_string,&out_xml_str,NULL);
   if(buf == NULL) return;
   xmlNodeDumpOutput(buf, doc, node_, 0, user_friendly ? 1 : 0, encoding.c_str());
   xmlOutputBufferFlush(buf);
   //out_xml_str = (char*)(buf->conv ? buf->conv->content : buf->buffer->content);
   xmlOutputBufferClose(buf);
   InsertExternalNamespaces(out_xml_str, ns_str);
 }
Exemplo n.º 17
0
void stats_set_conv (long handle, const char *name, const char *value, const char *charset)
{
    if (charset)
    {
        xmlCharEncodingHandlerPtr encoding = xmlFindCharEncodingHandler (charset);

        if (encoding)
        {
            xmlBufferPtr in = xmlBufferCreate ();
            xmlBufferPtr conv = xmlBufferCreate ();

            xmlBufferCCat (in, value);
            if (xmlCharEncInFunc (encoding, conv, in) > 0)
                stats_set_entity_decode (handle, name, (void*)xmlBufferContent (conv));
            xmlBufferFree (in);
            xmlBufferFree (conv);
            xmlCharEncCloseFunc (encoding);
            return;
        }
        WARN1 ("No charset found for \"%s\"", charset);
        return;
    }
    stats_set_entity_decode (handle, name, value);
}
Exemplo n.º 18
0
void
Server::sendResponse(Context *ctx, XmlDocSharedHelper doc) {
    sendHeaders(ctx);
    if (ctx->response()->suppressBody(ctx->request())) {
        return;
    } 

    xmlCharEncodingHandlerPtr encoder = NULL;
    const std::string &encoding = ctx->documentWriter()->outputEncoding();
    if (!encoding.empty() && 0 != strncasecmp(encoding.c_str(), "utf-8", sizeof("utf-8"))) {
        encoder = xmlFindCharEncodingHandler(encoding.c_str());
    }
    
    xmlOutputBufferPtr buf = xmlOutputBufferCreateIO(writeFunc, closeFunc, ctx, encoder);
    XmlUtils::throwUnless(NULL != buf);

    try {
        ctx->documentWriter()->write(ctx->response(), doc.get(), buf);
    }
    catch(const std::exception &e) {
        xmlOutputBufferClose(buf);
        throw e;
    }
}
Exemplo n.º 19
0
String::C xdoc2buf(Request& r, VXdoc& vdoc, 
					XDocOutputOptions& oo,
					const String* file_spec,
					bool use_source_charset_to_render_and_client_charset_to_write_to_header=false) {
	Charset* render=0;
	Charset* header=0;
	if(use_source_charset_to_render_and_client_charset_to_write_to_header) {
		render=&r.charsets.source();
		header=&r.charsets.client();
	} else {
		header=render=&charsets.get(oo.encoding->change_case(r.charsets.source(), String::CC_UPPER));
	}
	const char* render_encoding=render->NAME_CSTR();
	const char* header_encoding=header->NAME_CSTR();

	xmlCharEncodingHandler *renderer=xmlFindCharEncodingHandler(render_encoding);
	// UTF-8 renderer contains empty input/output converters, 
	// which is wrong for xmlOutputBufferCreateIO
	// while zero renderer goes perfectly 
	if(render->isUTF8())
		renderer=0;

	xmlOutputBuffer_auto_ptr outputBuffer(xmlAllocOutputBuffer(renderer));

	xsltStylesheet_auto_ptr stylesheet(xsltNewStylesheet());
	if(!stylesheet.get())
		throw Exception(0,
			0,
			"xsltNewStylesheet failed");

	#define OOSTRING2STYLE(name) \
		stylesheet->name=oo.name?BAD_CAST xmlMemStrdup((const char*)r.transcode(*oo.name)):0
	#define OOBOOL2STYLE(name) \
		if(oo.name>=0) stylesheet->name=oo.name

	OOSTRING2STYLE(method);
	OOSTRING2STYLE(encoding);
	OOSTRING2STYLE(mediaType);
//	OOSTRING2STYLE(doctypeSystem);
//	OOSTRING2STYLE(doctypePublic);
	OOBOOL2STYLE(indent);
	OOSTRING2STYLE(version);
	OOBOOL2STYLE(standalone);
	OOBOOL2STYLE(omitXmlDeclaration);

	xmlDoc& xmldoc=vdoc.get_xmldoc();
	xmldoc.encoding=BAD_CAST xmlMemStrdup(render_encoding);
	if(header_encoding)
		stylesheet->encoding=BAD_CAST xmlMemStrdup(header_encoding);
	if(xsltSaveResultTo(outputBuffer.get(), &xmldoc, stylesheet.get())<0
		|| xmlHaveGenericErrors())
		throw XmlException(0, r);

	// write out result
	char *gnome_str;
	size_t gnome_length;
#ifdef LIBXML2_NEW_BUFFER
	if(outputBuffer->conv) {
		gnome_length=xmlBufUse(outputBuffer->conv);
		gnome_str=(char *)xmlBufContent(outputBuffer->conv);
	} else {
		gnome_length=xmlOutputBufferGetSize(&(*outputBuffer));
		gnome_str=(char *)xmlOutputBufferGetContent(&(*outputBuffer));
	}
#else
	if(outputBuffer->conv) {
		gnome_length=outputBuffer->conv->use;
		gnome_str=(char *)outputBuffer->conv->content;
	} else {
		gnome_length=outputBuffer->buffer->use;
		gnome_str=(char *)outputBuffer->buffer->content;
	}
#endif

	if(file_spec){
		file_write(r.charsets,
			*file_spec,
			gnome_str,
			gnome_length, 
			true/*as_text*/);
		return String::C(); // actually, we don't need this output at all
	} else
		return String::C(gnome_length ? pa_strdup(gnome_str, gnome_length) : 0, gnome_length);
}
Exemplo n.º 20
0
/**
 * htmlDocDumpMemory:
 * @cur:  the document
 * @mem:  OUT: the memory pointer
 * @size:  OUT: the memory length
 *
 * Dump an HTML document in memory and return the xmlChar * and it's size.
 * It's up to the caller to free the memory.
 */
void
htmlDocDumpMemory(xmlDocPtr cur, xmlChar**mem, int *size) {
    xmlOutputBufferPtr buf;
    xmlCharEncodingHandlerPtr handler = NULL;
    const char *encoding;

    xmlInitParser();

    if ((mem == NULL) || (size == NULL))
        return;
    if (cur == NULL) {
	*mem = NULL;
	*size = 0;
	return;
    }

    encoding = (const char *) htmlGetMetaEncoding(cur);

    if (encoding != NULL) {
	xmlCharEncoding enc;

	enc = xmlParseCharEncoding(encoding);
	if (enc != cur->charset) {
	    if (cur->charset != XML_CHAR_ENCODING_UTF8) {
		/*
		 * Not supported yet
		 */
		*mem = NULL;
		*size = 0;
		return;
	    }

	    handler = xmlFindCharEncodingHandler(encoding);
	    if (handler == NULL) {
		*mem = NULL;
		*size = 0;
		return;
	    }
	} else {
	    handler = xmlFindCharEncodingHandler(encoding);
	}
    }

    /*
     * Fallback to HTML or ASCII when the encoding is unspecified
     */
    if (handler == NULL)
	handler = xmlFindCharEncodingHandler("HTML");
    if (handler == NULL)
	handler = xmlFindCharEncodingHandler("ascii");

    buf = xmlAllocOutputBuffer(handler);
    if (buf == NULL) {
	*mem = NULL;
	*size = 0;
	return;
    }

    htmlDocContentDumpOutput(buf, cur, NULL);
    xmlOutputBufferFlush(buf);
    if (buf->conv != NULL) {
	*size = buf->conv->use;
	*mem = xmlStrndup(buf->conv->content, *size);
    } else {
	*size = buf->buffer->use;
	*mem = xmlStrndup(buf->buffer->content, *size);
    }
    (void)xmlOutputBufferClose(buf);
}