/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <axiom_xml_writer.h>

AXIS2_EXTERN void AXIS2_CALL
axiom_xml_writer_free(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env)
{
    (writer)->ops->free(writer, env);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_xml_writer_write_start_element(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * localname)
{
    return (writer)->ops->write_start_element(writer, env, localname);

}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_xml_writer_end_start_element(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env)
{
    return (writer)->ops->end_start_element(writer, env);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_xml_writer_write_start_element_with_namespace(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * localname,
    axis2_char_t * namespace_uri)
{
    return (writer)->ops->write_start_element_with_namespace(writer, env, localname, namespace_uri);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_xml_writer_write_start_element_with_namespace_prefix(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * localname,
    axis2_char_t * namespace_uri,
    axis2_char_t * prefix)
{
    return (writer)->ops->write_start_element_with_namespace_prefix(writer, env, localname,
        namespace_uri, prefix);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_xml_writer_write_empty_element(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * localname)
{
    return (writer)->ops->write_empty_element(writer, env, localname);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_xml_writer_write_empty_element_with_namespace(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * localname,
    axis2_char_t * namespace_uri)
{
    return (writer)->ops->write_empty_element_with_namespace(writer, env, localname, namespace_uri);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_xml_writer_write_empty_element_with_namespace_prefix(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * localname,
    axis2_char_t * namespace_uri,
    axis2_char_t * prefix)
{
    return (writer)->ops->write_empty_element_with_namespace_prefix(writer, env, localname,
        namespace_uri, prefix);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_xml_writer_write_end_element(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env)
{
    return (writer)->ops->write_end_element(writer, env);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_xml_writer_write_end_document(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env)
{
    return (writer)->ops->write_end_document(writer, env);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_xml_writer_write_attribute(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * localname,
    axis2_char_t * value)
{
    return (writer)->ops->write_attribute(writer, env, localname, value);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_xml_writer_write_attribute_with_namespace(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * localname,
    axis2_char_t * value,
    axis2_char_t * namespace_uri)
{
    return (writer)->ops->write_attribute_with_namespace(writer, env, localname, value,
        namespace_uri);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_xml_writer_write_attribute_with_namespace_prefix(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * localname,
    axis2_char_t * value,
    axis2_char_t * namespace_uri,
    axis2_char_t * prefix)
{
    return (writer)->ops->write_attribute_with_namespace_prefix(writer, env, localname, value,
        namespace_uri, prefix);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_xml_writer_write_namespace(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * prefix,
    axis2_char_t * namespace_uri)
{
    return (writer)->ops->write_namespace(writer, env, prefix, namespace_uri);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_xml_writer_write_default_namespace(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * namespace_uri)
{
    return (writer)->ops->write_default_namespace(writer, env, namespace_uri);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_xml_writer_write_comment(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * value)
{
    return (writer)->ops->write_comment(writer, env, value);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_xml_writer_write_processing_instruction(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * target)
{
    return (writer)->ops->write_processing_instruction(writer, env, target);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_xml_writer_write_processing_instruction_data(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * target,
    axis2_char_t * data)
{
    return (writer)->ops->write_processing_instruction_data(writer, env, target, data);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_xml_writer_write_cdata(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * data)
{
    return (writer)->ops->write_cdata(writer, env, data);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_xml_writer_write_dtd(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * dtd)
{
    return (writer)->ops->write_cdata(writer, env, dtd);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_xml_writer_write_entity_ref(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * name)
{
    return (writer)->ops->write_entity_ref(writer, env, name);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_xml_writer_write_start_document(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env)
{
    return (writer)->ops->write_start_document(writer, env);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_xml_writer_write_start_document_with_version(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * version)
{
    return (writer)->ops->write_start_document_with_version(writer, env, version);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_xml_writer_write_start_document_with_version_encoding(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * version,
    axis2_char_t * encoding)
{
    return (writer)->ops->write_start_document_with_version_encoding(writer, env, encoding, version);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_xml_writer_write_characters(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * text)
{
    return (writer)->ops->write_characters(writer, env, text);
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axiom_xml_writer_get_prefix(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * uri)
{
    return (writer)->ops->get_prefix(writer, env, uri);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_xml_writer_set_prefix(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * prefix,
    axis2_char_t * uri)
{
    return (writer)->ops->set_prefix(writer, env, prefix, uri);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_xml_writer_set_default_prefix(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * uri)
{
    return (writer)->ops->set_default_prefix(writer, env, uri);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_xml_writer_write_encoded(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * text,
    int in_attr)
{
    return (writer)->ops->write_encoded(writer, env, text, in_attr);
}

AXIS2_EXTERN void *AXIS2_CALL
axiom_xml_writer_get_xml(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env)
{
    return (writer)->ops->get_xml(writer, env);
}

AXIS2_EXTERN unsigned int AXIS2_CALL
axiom_xml_writer_get_xml_size(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env)
{
    return (writer)->ops->get_xml_size(writer, env);
}

AXIS2_EXTERN int AXIS2_CALL
axiom_xml_writer_get_type(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env)
{
    return (writer)->ops->get_type(writer, env);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_xml_writer_write_raw(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * content)
{
    return (writer)->ops->write_raw(writer, env, content);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_xml_writer_flush(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env)
{
    return (writer)->ops->flush(writer, env);
}
