/* * This file is part of libdom. * Licensed under the MIT License, * http://www.opensource.org/licenses/mit-license.php * Copyright 2007 John-Mark Bell * Copyright 2007 James Shaw * Copyright 2009 Bo Yang */ #include #include #include "core/string.h" #include "core/document_type.h" #include "core/namednodemap.h" #include "core/node.h" #include "utils/utils.h" #include "utils/namespace.h" /** * DOM DocumentType node */ struct dom_document_type { dom_node_internal base; /**< Base node */ dom_string *public_id; /**< Doctype public ID */ dom_string *system_id; /**< Doctype system ID */ }; static struct dom_document_type_vtable document_type_vtable = { { { DOM_NODE_EVENT_TARGET_VTABLE }, DOM_NODE_VTABLE }, DOM_DOCUMENT_TYPE_VTABLE }; static struct dom_node_protect_vtable dt_protect_vtable = { DOM_DT_PROTECT_VTABLE }; /*----------------------------------------------------------------------*/ /* Constructors and destructors */ /** * Create a document type node * * \param qname The qualified name of the document type * \param public_id The external subset public identifier * \param system_id The external subset system identifier * \param alloc Memory (de)allocation function * \param pw Pointer to client-specific private data * \param doctype Pointer to location to receive result * \return DOM_NO_ERR on success, DOM_NO_MEM_ERR on memory exhaustion. * * The doctype will be referenced, so the client need not do so * explicitly. The client must unref the doctype once it has * finished with it. */ dom_exception _dom_document_type_create(dom_string *qname, dom_string *public_id, dom_string *system_id, dom_document_type **doctype) { dom_document_type *result; dom_exception err; /* Create node */ result = malloc(sizeof(dom_document_type)); if (result == NULL) return DOM_NO_MEM_ERR; /* Initialise the vtable */ result->base.base.vtable = &document_type_vtable; result->base.vtable = &dt_protect_vtable; err = _dom_document_type_initialise(result, qname, public_id, system_id); if (err != DOM_NO_ERR) { free(result); return err; } *doctype = result; return DOM_NO_ERR; } /** * Destroy a DocumentType node * * \param doctype The DocumentType node to destroy * * The contents of ::doctype will be destroyed and ::doctype will be freed. */ void _dom_document_type_destroy(dom_node_internal *doctypenode) { dom_document_type *doctype = (dom_document_type *) doctypenode; /* Finalise base class */ _dom_document_type_finalise(doctype); /* Free doctype */ free(doctype); } /* Initialise this document_type */ dom_exception _dom_document_type_initialise(dom_document_type *doctype, dom_string *qname, dom_string *public_id, dom_string *system_id) { dom_string *prefix, *localname; dom_exception err; err = _dom_namespace_split_qname(qname, &prefix, &localname); if (err != DOM_NO_ERR) return err; /* TODO: I should figure out how the namespaceURI can be got */ /* Initialise base node */ err = _dom_node_initialise(&doctype->base, NULL, DOM_DOCUMENT_TYPE_NODE, localname, NULL, NULL, prefix); if (err != DOM_NO_ERR) { dom_string_unref(prefix); dom_string_unref(localname); return err; } /* Get public and system IDs */ if (public_id != NULL) dom_string_ref(public_id); doctype->public_id = public_id; if (system_id != NULL) dom_string_ref(system_id); doctype->system_id = system_id; if (prefix != NULL) dom_string_unref(prefix); if (localname != NULL) dom_string_unref(localname); return DOM_NO_ERR; } /* The destructor function of dom_document_type */ void _dom_document_type_finalise(dom_document_type *doctype) { if (doctype->public_id != NULL) dom_string_unref(doctype->public_id); if (doctype->system_id != NULL) dom_string_unref(doctype->system_id); assert(doctype->base.owner != NULL || doctype->base.user_data == NULL); _dom_node_finalise(&doctype->base); } /*----------------------------------------------------------------------*/ /* Virtual functions */ /** * Retrieve a document type's name * * \param doc_type Document type to retrieve name from * \param result Pointer to location to receive result * \return DOM_NO_ERR. * * The returned string will have its reference count increased. It is * the responsibility of the caller to unref the string once it has * finished with it. * * We don't support this API now, so this function call should always * return DOM_NOT_SUPPORTED_ERR. */ dom_exception _dom_document_type_get_name(dom_document_type *doc_type, dom_string **result) { return dom_node_get_node_name(doc_type, result); } /** * Retrieve a document type's entities * * \param doc_type Document type to retrieve entities from * \param result Pointer to location to receive result * \return DOM_NO_ERR. * * The returned map will have its reference count increased. It is * the responsibility of the caller to unref the map once it has * finished with it. * * We don't support this API now, so this function call should always * return DOM_NOT_SUPPORTED_ERR. */ dom_exception _dom_document_type_get_entities( dom_document_type *doc_type, dom_namednodemap **result) { UNUSED(doc_type); UNUSED(result); return DOM_NOT_SUPPORTED_ERR; } /** * Retrieve a document type's notations * * \param doc_type Document type to retrieve notations from * \param result Pointer to location to receive result * \return DOM_NO_ERR. * * The returned map will have its reference count increased. It is * the responsibility of the caller to unref the map once it has * finished with it. * * We don't support this API now, so this function call should always * return DOM_NOT_SUPPORTED_ERR. */ dom_exception _dom_document_type_get_notations( dom_document_type *doc_type, dom_namednodemap **result) { UNUSED(doc_type); UNUSED(result); return DOM_NOT_SUPPORTED_ERR; } /** * Retrieve a document type's public id * * \param doc_type Document type to retrieve public id from * \param result Pointer to location to receive result * \return DOM_NO_ERR. * * The returned string will have its reference count increased. It is * the responsibility of the caller to unref the string once it has * finished with it. * * We don't support this API now, so this function call should always * return DOM_NOT_SUPPORTED_ERR. */ dom_exception _dom_document_type_get_public_id( dom_document_type *doc_type, dom_string **result) { UNUSED(doc_type); UNUSED(result); return DOM_NOT_SUPPORTED_ERR; } /** * Retrieve a document type's system id * * \param doc_type Document type to retrieve system id from * \param result Pointer to location to receive result * \return DOM_NO_ERR. * * The returned string will have its reference count increased. It is * the responsibility of the caller to unref the string once it has * finished with it. * * We don't support this API now, so this function call should always * return DOM_NOT_SUPPORTED_ERR. */ dom_exception _dom_document_type_get_system_id( dom_document_type *doc_type, dom_string **result) { UNUSED(doc_type); UNUSED(result); return DOM_NOT_SUPPORTED_ERR; } /** * Retrieve a document type's internal subset * * \param doc_type Document type to retrieve internal subset from * \param result Pointer to location to receive result * \return DOM_NO_ERR. * * The returned string will have its reference count increased. It is * the responsibility of the caller to unref the string once it has * finished with it. * * We don't support this API now, so this function call should always * return DOM_NOT_SUPPORTED_ERR. */ dom_exception _dom_document_type_get_internal_subset( dom_document_type *doc_type, dom_string **result) { UNUSED(doc_type); UNUSED(result); return DOM_NOT_SUPPORTED_ERR; } /*-----------------------------------------------------------------------*/ /* Overload protected virtual functions */ /* The virtual destroy function of this class */ void _dom_dt_destroy(dom_node_internal *node) { _dom_document_type_destroy(node); } /* The copy constructor of this class */ dom_exception _dom_dt_copy(dom_node_internal *old, dom_node_internal **copy) { UNUSED(old); UNUSED(copy); return DOM_NOT_SUPPORTED_ERR; }