Hi Nabeel,
Pls see my inline comments.
Nabeel wrote:
> Sahan Gamage wrote:
>
>> Hi Nabeel,
>>
>> What is this xmlDoc ? Is it libxml2 thing ? If so aren't we adding a
>> hard binding to Axis2C with libxml2 ?
>>
>>
> Yes, xmlDoc is libxml2 specific. But xmlDoc is hidden inside the
> impls of the libxml2 wrapper to prevent hard binding. (if you have a
> look at the public interfaces axis2_xml_reader.h and
> axis2_xml_writer.h you won't find any xmlDoc pointers)
Yes. I saw that. But the problem is where are you going to use it ? At
the point you are using these functions, say foo()is something similar
to this:
void foo()
{
xmlDoc *doc = get_by_some_way();
axis2_xml_reader_t *reader = NULL;
...
reader = axis2_xml_reader_create_for_xml_doc(env, doc);
...
}
This code is pretty dependent on libxml2. So if this is for code for
axis2 as soon as we change the parser (to guththila or to any other pull
parser) the code will break unless we add a hard link dependancy for
libxml2. Isn't it ?
> Only catch is that the new functions are useful only when you are
> using libxml2. If you are using some other xml parser library,
> Guththila for example, you may not want to implement these new
> prototypes in your wrapper.
My understanding is that wrpper is an interface to the common
functionality that every library that it wraps, can provide. So if
guththila can't provide this functionality we are breaking the rules of
wrapper. And the worst thing is we are exposing these libxml2 specific
stuff to the outside world by putting it to the public headers
axis2_xml_reader.h and axis2_xml_writer.h
>
>
> thanks
> -Nabeel
>
>> IMHO the wrapper is there to hide implemention specific (in this case
>> libxml2) details. If we expose the libxml2 things in the wrapper, the
>> idea of the wrapper is not there any more. Please clarify
>>
>> - Sahan
>>
>> Nabeel wrote:
>>
>>
>>
>>> The patch contains -
>>> a new reader that reads a xmlDoc
>>> a new writer that writes to a xmlDoc
>>>
>>> (these methods are used by the php extension to prevent double
>>> serialization when exchanging XML)
>>>
>>> Please apply to svn.
>>>
>>> thanks
>>> -Nabeel
>>>
>>> ------------------------------------------------------------------------
>>>
>>>
>>> Index: modules/xml/parser/libxml2/libxml2_writer_wrapper.c
>>> ===================================================================
>>> --- modules/xml/parser/libxml2/libxml2_writer_wrapper.c (revision
>>> 394906)
>>> +++ modules/xml/parser/libxml2/libxml2_writer_wrapper.c (working
>>> copy)
>>> @@ -34,6 +34,7 @@
>>>
>>> #define AXIS2_LIBXML2_WRITER_MEMORY 1
>>> #define AXIS2_LIBXML2_WRITER_FILE 2
>>> +#define AXIS2_LIBXML2_WRITER_DOC 3
>>>
>>> /************************ structures
>>> *****************************************/
>>>
>>> @@ -56,6 +57,8 @@
>>> xmlTextWriterPtr xml_writer;
>>> xmlBufferPtr buffer;
>>> +
>>> + xmlDocPtr doc;
>>> int writer_type;
>>> @@ -262,6 +265,10 @@
>>> axis2_char_t* AXIS2_CALL
>>> axis2_libxml2_writer_wrapper_get_xml(axis2_xml_writer_t *writer,
>>> axis2_env_t **env);
>>> +
>>> +void* AXIS2_CALL
>>> +axis2_libxml2_writer_wrapper_get_xml_doc(axis2_xml_writer_t *writer,
>>> + axis2_env_t **env);
>>> /*********************** static
>>> functions ************************************/
>>> static axis2_status_t
>>> @@ -658,6 +665,180 @@
>>> return &(writer_impl->writer);
>>> }
>>>
>>> +/*********************** writer create func for file
>>> ***************************/
>>> +
>>> +AXIS2_DECLARE(axis2_xml_writer_t *)
>>> +axis2_xml_writer_create_for_xml_doc(axis2_env_t **env,
>>> + axis2_char_t *encoding,
>>> + int is_prefix_default,
>>> + int compression)
>>> +{
>>> + axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL;
>>> + AXIS2_ENV_CHECK(env, NULL);
>>> + writer_impl = (axis2_libxml2_writer_wrapper_impl_t
>>> *)AXIS2_MALLOC((*env)->allocator,
>>> + sizeof(axis2_libxml2_writer_wrapper_impl_t));
>>> + if(!writer_impl)
>>> + {
>>> + AXIS2_ERROR_SET((*env)->error, AXIS2_ERROR_NO_MEMORY,
>>> AXIS2_FAILURE);
>>> + return NULL;
>>> + }
>>> + + writer_impl->writer.ops = NULL;
>>> + writer_impl->encoding = NULL;
>>> + writer_impl->buffer = NULL;
>>> + writer_impl->in_empty_element = AXIS2_FALSE;
>>> + writer_impl->in_start_element = AXIS2_FALSE;
>>> + writer_impl->stack = NULL;
>>> + writer_impl->uri_prefix_map = NULL;
>>> + writer_impl->default_lang_namespace = NULL;
>>> + + writer_impl->writer_type = AXIS2_LIBXML2_WRITER_DOC;
>>> + writer_impl->compression = compression;
>>> + + + /*writer_impl->buffer = xmlBufferCreate();
>>> + if(writer_impl->buffer == NULL)
>>> + {
>>> + axis2_libxml2_writer_wrapper_free(&(writer_impl->writer),
>>> env);
>>> + AXIS2_ERROR_SET((*env)->error, AXIS2_ERROR_NO_MEMORY,
>>> AXIS2_FAILURE);
>>> + return NULL;
>>> + }*/
>>> + + writer_impl->xml_writer =
>>> /*xmlNewTextWriterMemory(writer_impl->buffer, 0);*/
>>> +
>>> xmlNewTextWriterDoc(&writer_impl->doc, 0);
>>> + if(writer_impl->xml_writer == NULL)
>>> + {
>>> + axis2_libxml2_writer_wrapper_free(&(writer_impl->writer),
>>> env);
>>> + AXIS2_ERROR_SET((*env)->error,
>>> AXIS2_ERROR_CREATING_XML_STREAM_WRITER , AXIS2_FAILURE);
>>> + return NULL;
>>> + }
>>> +
>>> + if(encoding)
>>> + writer_impl->encoding = AXIS2_STRDUP(encoding , env);
>>> + else
>>> + writer_impl->encoding = AXIS2_STRDUP(ENCODING, env);
>>> + + + writer_impl->uri_prefix_map = axis2_hash_make(env);
>>> + if(!(writer_impl->uri_prefix_map))
>>> + {
>>> + axis2_libxml2_writer_wrapper_free(&(writer_impl->writer),
>>> env);
>>> + AXIS2_ERROR_SET((*env)->error, +
>>> AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
>>> + + return NULL;
>>> + }
>>> + writer_impl->stack = axis2_stack_create(env);
>>> + if(!(writer_impl->stack))
>>> + {
>>> + axis2_libxml2_writer_wrapper_free(&(writer_impl->writer),
>>> env);
>>> + AXIS2_ERROR_SET((*env)->error, +
>>> AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
>>> + return NULL;
>>> + }
>>> + +
>>> axis2_libxml2_writer_wrapper_set_default_lang_namespace(&(writer_impl->writer),
>>> env);
>>> + + writer_impl->writer.ops =
>>> (axis2_xml_writer_ops_t*)AXIS2_MALLOC((*env)->allocator,
>>> + sizeof(axis2_xml_writer_ops_t));
>>> + if(!(writer_impl->writer.ops))
>>> + {
>>> + axis2_libxml2_writer_wrapper_free(&(writer_impl->writer),
>>> env);
>>> + AXIS2_ERROR_SET((*env)->error, AXIS2_ERROR_NO_MEMORY,
>>> AXIS2_FAILURE);
>>> + return NULL;
>>> + }
>>> + + /* ops */
>>> + writer_impl->writer.ops->free = +
>>> axis2_libxml2_writer_wrapper_free;
>>> + + writer_impl->writer.ops->write_start_element =
>>> + axis2_libxml2_writer_wrapper_write_start_element;
>>> + +
>>> writer_impl->writer.ops->write_start_element_with_namespace =
>>> +
>>> axis2_libxml2_writer_wrapper_write_start_element_with_namespace;
>>> + +
>>> writer_impl->writer.ops->write_start_element_with_namespace_prefix =
>>> +
>>> axis2_libxml2_writer_wrapper_write_start_element_with_namespace_prefix;
>>> + + writer_impl->writer.ops->write_empty_element =
>>> + axis2_libxml2_writer_wrapper_write_empty_element;
>>> + +
>>> writer_impl->writer.ops->write_empty_element_with_namespace =
>>> +
>>> axis2_libxml2_writer_wrapper_write_empty_element_with_namespace;
>>> + +
>>> writer_impl->writer.ops->write_empty_element_with_namespace_prefix =
>>> +
>>> axis2_libxml2_writer_wrapper_write_empty_element_with_namespace_prefix;
>>> + + writer_impl->writer.ops->write_end_element = +
>>> axis2_libxml2_writer_wrapper_write_end_element;
>>> + + writer_impl->writer.ops->write_end_document =
>>> + axis2_libxml2_writer_wrapper_write_end_document;
>>> + + writer_impl->writer.ops->write_attribute = +
>>> axis2_libxml2_writer_wrapper_write_attribute;
>>> + +
>>> writer_impl->writer.ops->write_attribute_with_namespace =
>>> +
>>> axis2_libxml2_writer_wrapper_write_attribute_with_namespace;
>>> + +
>>> writer_impl->writer.ops->write_attribute_with_namespace_prefix =
>>> +
>>> axis2_libxml2_writer_wrapper_write_attribute_with_namespace_prefix;
>>> + + writer_impl->writer.ops->write_namespace =
>>> + axis2_libxml2_writer_wrapper_write_namespace;
>>> + + writer_impl->writer.ops->write_default_namespace =
>>> + axis2_libxml2_writer_wrapper_write_default_namespace;
>>> + + writer_impl->writer.ops->write_comment =
>>> + axis2_libxml2_writer_wrapper_write_comment;
>>> + +
>>> writer_impl->writer.ops->write_processing_instruction = +
>>> axis2_libxml2_writer_wrapper_write_processing_instruction;
>>> + +
>>> writer_impl->writer.ops->write_processing_instruction_data =
>>> +
>>> axis2_libxml2_writer_wrapper_write_processing_instruction_data;
>>> + + writer_impl->writer.ops->write_cdata =
>>> + axis2_libxml2_writer_wrapper_write_cdata;
>>> + + writer_impl->writer.ops->write_dtd = +
>>> axis2_libxml2_writer_wrapper_write_dtd;
>>> + + writer_impl->writer.ops->write_entity_ref =
>>> + axis2_libxml2_writer_wrapper_write_entity_ref;
>>> + + writer_impl->writer.ops->write_start_document =
>>> + axis2_libxml2_writer_wrapper_write_start_document;
>>> + +
>>> writer_impl->writer.ops->write_start_document_with_version =
>>> +
>>> axis2_libxml2_writer_wrapper_write_start_document_with_version;
>>> + +
>>> writer_impl->writer.ops->write_start_document_with_version_encoding
>>> = +
>>> axis2_libxml2_writer_wrapper_write_start_document_with_version_encoding;
>>>
>>> + + writer_impl->writer.ops->write_characters =
>>> + axis2_libxml2_writer_wrapper_write_characters;
>>> + + writer_impl->writer.ops->get_prefix =
>>> + axis2_libxml2_writer_wrapper_get_prefix;
>>> + + writer_impl->writer.ops->set_prefix = +
>>> axis2_libxml2_writer_wrapper_set_prefix;
>>> + + writer_impl->writer.ops->set_default_prefix =
>>> + axis2_libxml2_writer_wrapper_set_default_prefix;
>>> + + writer_impl->writer.ops->write_encoded =
>>> + axis2_libxml2_writer_wrapper_write_encoded;
>>> + + writer_impl->writer.ops->get_xml =
>>> + axis2_libxml2_writer_wrapper_get_xml_doc;
>>> + + return &(writer_impl->writer);
>>> +}
>>> +
>>> /*******************************************************************************/
>>>
>>> axis2_status_t AXIS2_CALL
>>> axis2_libxml2_writer_wrapper_free(axis2_xml_writer_t *writer,
>>> @@ -1561,6 +1742,26 @@
>>> return output; }
>>>
>>> +void* AXIS2_CALL
>>> +axis2_libxml2_writer_wrapper_get_xml_doc(axis2_xml_writer_t *writer,
>>> + axis2_env_t **env)
>>> +{
>>> + axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL;
>>> + writer_impl = AXIS2_INTF_TO_IMPL(writer);
>>> +
>>> + if(writer_impl->xml_writer)
>>> + {
>>> + xmlFreeTextWriter(writer_impl->xml_writer);
>>> + writer_impl->xml_writer = NULL;
>>> + }
>>> +
>>> + if (writer_impl->writer_type == AXIS2_LIBXML2_WRITER_DOC)
>>> + {
>>> + return (void*)writer_impl->doc;
>>> + }
>>> + return NULL;
>>> +}
>>> +
>>> static axis2_status_t
>>> axis2_libxml2_writer_wrapper_pop_context(axis2_xml_writer_t *writer,
>>> axis2_env_t **env)
>>> Index: modules/xml/parser/libxml2/libxml2_reader_wrapper.c
>>> ===================================================================
>>> --- modules/xml/parser/libxml2/libxml2_reader_wrapper.c (revision
>>> 394906)
>>> +++ modules/xml/parser/libxml2/libxml2_reader_wrapper.c (working
>>> copy)
>>> @@ -555,6 +555,102 @@
>>> return &(wrapper_impl->parser);
>>> }
>>> +
>>> +
>>> +/***************** create function for xmlDoc
>>> ************************/
>>> +AXIS2_DECLARE(axis2_xml_reader_t *)
>>> +axis2_xml_reader_create_for_xml_doc(axis2_env_t **env,
>>> + void *doc)
>>> +{ + axis2_libxml2_reader_wrapper_impl_t *wrapper_impl = NULL;
>>> + + AXIS2_ENV_CHECK( env, NULL);
>>> + + wrapper_impl =
>>> (axis2_libxml2_reader_wrapper_impl_t*)AXIS2_MALLOC((*env)->allocator,
>>> + sizeof(axis2_libxml2_reader_wrapper_impl_t));
>>> + if(!wrapper_impl)
>>> + {
>>> + AXIS2_ERROR_SET((*env)->error, AXIS2_ERROR_NO_MEMORY,
>>> AXIS2_FAILURE);
>>> + return NULL; + }
>>> + wrapper_impl->close_input_callback = NULL;
>>> + wrapper_impl->read_input_callback = NULL;
>>> + wrapper_impl->ctx = NULL;
>>> +
>>> + wrapper_impl->reader = xmlReaderWalker((xmlDocPtr)doc);
>>> +
>>> + if(!(wrapper_impl->reader))
>>> + {
>>> + AXIS2_FREE((*env)->allocator, wrapper_impl);
>>> + AXIS2_ERROR_SET((*env)->error, +
>>> AXIS2_ERROR_CREATING_XML_STREAM_READER, AXIS2_FAILURE);
>>> + return NULL;
>>> + }
>>> +
>>> + /*xmlTextReaderSetErrorHandler(wrapper_impl->reader, +
>>> (xmlTextReaderErrorFunc)axis2_libxml2_reader_wrapper_error_handler,
>>> + (*env));
>>> + */
>>> + wrapper_impl->current_event = -1;
>>> + + axis2_libxml2_reader_wrapper_init_map(wrapper_impl);
>>> + + wrapper_impl->parser.ops = NULL;
>>> + wrapper_impl->parser.ops =
>>> (axis2_xml_reader_ops_t*)AXIS2_MALLOC((*env)->allocator,
>>> + sizeof(axis2_xml_reader_ops_t));
>>> + + if(!(wrapper_impl->parser.ops))
>>> + {
>>> + xmlFreeTextReader(wrapper_impl->reader);
>>> + AXIS2_FREE((*env)->allocator, wrapper_impl);
>>> + AXIS2_ERROR_SET((*env)->error, AXIS2_ERROR_NO_MEMORY,
>>> AXIS2_FAILURE);
>>> + return NULL;
>>> + }
>>> +
>>> +
>>> + wrapper_impl->parser.ops->free =
>>> axis2_libxml2_reader_wrapper_free;
>>> + wrapper_impl->parser.ops->next =
>>> axis2_libxml2_reader_wrapper_next;
>>> + wrapper_impl->parser.ops->xml_free =
>>> axis2_libxml2_reader_wrapper_xml_free;
>>> + + wrapper_impl->parser.ops->get_attribute_count =
>>> + axis2_libxml2_reader_wrapper_get_attribute_count;
>>> + wrapper_impl->parser.ops->get_attribute_name_by_number =
>>> + axis2_libxml2_reader_wrapper_get_attribute_name_by_number;
>>> + wrapper_impl->parser.ops->get_attribute_value_by_number =
>>> + axis2_libxml2_reader_wrapper_get_attribute_value_by_number;
>>> + wrapper_impl->parser.ops->get_attribute_namespace_by_number =
>>> +
>>> axis2_libxml2_reader_wrapper_get_attribute_namespace_by_number;
>>> + wrapper_impl->parser.ops->get_attribute_prefix_by_number =
>>> + axis2_libxml2_reader_wrapper_get_attribute_prefix_by_number;
>>> + + wrapper_impl->parser.ops->get_value =
>>> + axis2_libxml2_reader_wrapper_get_value;
>>> + wrapper_impl->parser.ops->get_prefix =
>>> + axis2_libxml2_reader_wrapper_get_prefix;
>>> + wrapper_impl->parser.ops->get_name =
>>> + axis2_libxml2_reader_wrapper_get_name;
>>> + + + wrapper_impl->parser.ops->get_namespace_count =
>>> + axis2_libxml2_reader_wrapper_get_namespace_count;
>>> + wrapper_impl->parser.ops->get_namespace_prefix_by_number =
>>> + axis2_libxml2_reader_wrapper_get_namespace_prefix_by_number;
>>> + wrapper_impl->parser.ops->get_namespace_uri_by_number =
>>> + axis2_libxml2_reader_wrapper_get_namespace_uri_by_number;
>>> + + wrapper_impl->parser.ops->get_pi_target =
>>> + axis2_libxml2_reader_wrapper_get_pi_target;
>>> + wrapper_impl->parser.ops->get_pi_data =
>>> + axis2_libxml2_reader_wrapper_get_pi_data;
>>> + + wrapper_impl->parser.ops->get_dtd =
>>> + axis2_libxml2_reader_wrapper_get_dtd;
>>> + + wrapper_impl->parser.ops->get_char_set_encoding =
>>> + axis2_libxml2_reader_wrapper_get_char_set_encoding;
>>> +
>>> + return &(wrapper_impl->parser);
>>> +}
>>> /****************** end create functions
>>> ***************************************/
>>>
>>> int AXIS2_CALL
>>> Index: include/axis2_xml_reader.h
>>> ===================================================================
>>> --- include/axis2_xml_reader.h (revision 394906)
>>> +++ include/axis2_xml_reader.h (working copy)
>>> @@ -355,6 +355,9 @@
>>> int size,
>>> const axis2_char_t *encoding);
>>>
>>> +AXIS2_DECLARE(axis2_xml_reader_t *)
>>> +axis2_xml_reader_create_for_xml_doc(axis2_env_t **env,
>>> + void *doc);
>>> /**
>>> * init function initializes the parser */
>>> Index: include/axis2_xml_writer.h
>>> ===================================================================
>>> --- include/axis2_xml_writer.h (revision 394906)
>>> +++ include/axis2_xml_writer.h (working copy)
>>> @@ -464,6 +464,12 @@
>>> int is_prefix_default,
>>> int compression);
>>>
>>> +AXIS2_DECLARE(axis2_xml_writer_t *)
>>> + axis2_xml_writer_create_for_xml_doc(axis2_env_t **env,
>>> + axis2_char_t *encoding,
>>> + int is_prefix_default,
>>> + int compression);
>>> +
>>> /********************** start macros
>>> *******************************************/
>>>
>>> #define AXIS2_XML_WRITER_FREE(writer, env) \
>>>
>>>
>>>
>>
>>
>>
>>
>>
>
>