Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * This file is part of libdom.
  3.  * Licensed under the MIT License,
  4.  *                http://www.opensource.org/licenses/mit-license.php
  5.  * Copyright 2007 John-Mark Bell <jmb@netsurf-browser.org>
  6.  * Copyright 2009 Bo Yang <struggleyb.nku@gmail.com>
  7.  */
  8.  
  9. #include <assert.h>
  10. #include <stddef.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13.  
  14. #include <dom/core/attr.h>
  15. #include <dom/core/document.h>
  16. #include <dom/core/node.h>
  17. #include <dom/core/string.h>
  18.  
  19. #include "core/attr.h"
  20. #include "core/document.h"
  21. #include "core/entity_ref.h"
  22. #include "core/node.h"
  23. #include "core/element.h"
  24. #include "utils/utils.h"
  25.  
  26. struct dom_element;
  27.  
  28. /**
  29.  * DOM attribute node
  30.  */
  31. struct dom_attr {
  32.         struct dom_node_internal base;  /**< Base node */
  33.  
  34.         struct dom_type_info *schema_type_info; /**< Type information */
  35.  
  36.         dom_attr_type type;     /**< The type of this attribute */
  37.        
  38.         union {
  39.                 uint32_t lvalue;
  40.                 unsigned short svalue;
  41.                 bool bvalue;
  42.         } value;        /**< The special type value of this attribute */
  43.  
  44.         bool specified; /**< Whether the attribute is specified or default */
  45.  
  46.         bool is_id;     /**< Whether this attribute is a ID attribute */
  47.  
  48.         bool read_only; /**< Whether this attribute is readonly */
  49. };
  50.  
  51. /* The vtable for dom_attr node */
  52. static struct dom_attr_vtable attr_vtable = {
  53.         {
  54.                 {
  55.                         DOM_NODE_EVENT_TARGET_VTABLE,
  56.                 },
  57.                 DOM_NODE_VTABLE_ATTR
  58.         },
  59.         DOM_ATTR_VTABLE
  60. };
  61.  
  62. /* The protected vtable for dom_attr */
  63. static struct dom_node_protect_vtable attr_protect_vtable = {
  64.         DOM_ATTR_PROTECT_VTABLE
  65. };
  66.  
  67.  
  68. /* -------------------------------------------------------------------- */
  69.  
  70. /* Constructor and destructor */
  71.  
  72. /**
  73.  * Create an attribute node
  74.  *
  75.  * \param doc        The owning document
  76.  * \param name       The (local) name of the node to create
  77.  * \param namespace  The namespace URI of the attribute, or NULL
  78.  * \param prefix     The namespace prefix of the attribute, or NULL
  79.  * \param specified  Whether this attribute is specified
  80.  * \param result     Pointer to location to receive created attribute
  81.  * \return DOM_NO_ERR     on success,
  82.  *         DOM_NO_MEM_ERR on memory exhaustion.
  83.  *
  84.  * ::doc and ::name will have their reference counts increased. The
  85.  * caller should make sure that ::name is a valid NCName here.
  86.  *
  87.  * The returned attribute will already be referenced.
  88.  */
  89. dom_exception _dom_attr_create(struct dom_document *doc,
  90.                 dom_string *name, dom_string *namespace,
  91.                 dom_string *prefix, bool specified,
  92.                 struct dom_attr **result)
  93. {
  94.         struct dom_attr *a;
  95.         dom_exception err;
  96.  
  97.         /* Allocate the attribute node */
  98.         a = malloc(sizeof(struct dom_attr));
  99.         if (a == NULL)
  100.                 return DOM_NO_MEM_ERR;
  101.  
  102.         /* Initialise the vtable */
  103.         a->base.base.vtable = &attr_vtable;
  104.         a->base.vtable = &attr_protect_vtable;
  105.  
  106.         /* Initialise the class */
  107.         err = _dom_attr_initialise(a, doc, name, namespace, prefix, specified,
  108.                         result);
  109.         if (err != DOM_NO_ERR) {
  110.                 free(a);
  111.                 return err;
  112.         }
  113.  
  114.         return DOM_NO_ERR;
  115. }
  116.  
  117. /**
  118.  * Initialise a dom_attr
  119.  *
  120.  * \param a          The dom_attr
  121.  * \param doc        The document
  122.  * \param name       The name of this attribute node
  123.  * \param namespace  The namespace of this attribute
  124.  * \param prefix     The prefix
  125.  * \param specified  Whether this node is a specified one
  126.  * \param result     The returned node
  127.  * \return DOM_NO_ERR on success, appropriate dom_exception on failure.
  128.  */
  129. dom_exception _dom_attr_initialise(dom_attr *a,
  130.                 struct dom_document *doc, dom_string *name,
  131.                 dom_string *namespace, dom_string *prefix,
  132.                 bool specified, struct dom_attr **result)
  133. {
  134.         dom_exception err;
  135.  
  136.         err = _dom_node_initialise(&a->base, doc, DOM_ATTRIBUTE_NODE,
  137.                         name, NULL, namespace, prefix);
  138.         if (err != DOM_NO_ERR) {
  139.                 return err;
  140.         }
  141.  
  142.         a->specified = specified;
  143.         a->schema_type_info = NULL;
  144.         a->is_id = false;
  145.         /* The attribute type is unset when it is created */
  146.         a->type = DOM_ATTR_UNSET;
  147.         a->read_only = false;
  148.  
  149.         *result = a;
  150.  
  151.         return DOM_NO_ERR;
  152. }
  153.  
  154. /**
  155.  * The destructor of dom_attr
  156.  *
  157.  * \param attr  The attribute
  158.  */
  159. void _dom_attr_finalise(dom_attr *attr)
  160. {
  161.         /* Now, clean up this node and destroy it */
  162.  
  163.         if (attr->schema_type_info != NULL) {
  164.                 /** \todo destroy schema type info */
  165.         }
  166.  
  167.         _dom_node_finalise(&attr->base);
  168. }
  169.  
  170. /**
  171.  * Destroy an attribute node
  172.  *
  173.  * \param attr  The attribute to destroy
  174.  *
  175.  * The contents of ::attr will be destroyed and ::attr will be freed
  176.  */
  177. void _dom_attr_destroy(struct dom_attr *attr)
  178. {
  179.         _dom_attr_finalise(attr);
  180.  
  181.         free(attr);
  182. }
  183.  
  184. /*-----------------------------------------------------------------------*/
  185. /* Following are our implementation specific APIs */
  186.  
  187. /**
  188.  * Get the Attr Node type
  189.  *
  190.  * \param a  The attribute node
  191.  * \return the type
  192.  */
  193. dom_attr_type dom_attr_get_type(dom_attr *a)
  194. {
  195.         return a->type;
  196. }
  197.  
  198. /**
  199.  * Get the integer value of this attribute
  200.  *
  201.  * \param a      The attribute object
  202.  * \param value  The returned value
  203.  * \return DOM_NO_ERR on success,
  204.  *         DOM_ATTR_WRONG_TYPE_ERR if the attribute node is not a integer
  205.  *                                 attribute
  206.  */
  207. dom_exception dom_attr_get_integer(dom_attr *a, uint32_t *value)
  208. {
  209.         if (a->type != DOM_ATTR_INTEGER)
  210.                 return DOM_ATTR_WRONG_TYPE_ERR;
  211.        
  212.         *value = a->value.lvalue;
  213.  
  214.         return DOM_NO_ERR;
  215. }
  216.  
  217. /**
  218.  * Set the integer value of this attribute
  219.  *
  220.  * \param a      The attribute object
  221.  * \param value  The new value
  222.  * \return DOM_NO_ERR on success,
  223.  *         DOM_ATTR_WRONG_TYPE_ERR if the attribute node is not a integer
  224.  *                                 attribute
  225.  */
  226. dom_exception dom_attr_set_integer(dom_attr *a, uint32_t value)
  227. {
  228.         struct dom_document *doc;
  229.         struct dom_node_internal *ele;
  230.         bool success = true;
  231.         dom_exception err;
  232.  
  233.         /* If this is the first set method, we should fix this attribute
  234.          * type */
  235.         if (a->type == DOM_ATTR_UNSET)
  236.                 a->type = DOM_ATTR_INTEGER;
  237.  
  238.         if (a->type != DOM_ATTR_INTEGER)
  239.                 return DOM_ATTR_WRONG_TYPE_ERR;
  240.        
  241.         if (a->value.lvalue == value)
  242.                 return DOM_NO_ERR;
  243.        
  244.         a->value.lvalue = value;
  245.  
  246.         doc = dom_node_get_owner(a);
  247.         ele = dom_node_get_parent(a);
  248.         err = _dom_dispatch_attr_modified_event(doc, ele, NULL, NULL,
  249.                         (dom_event_target *) a, NULL,
  250.                         DOM_MUTATION_MODIFICATION, &success);
  251.         if (err != DOM_NO_ERR)
  252.                 return err;
  253.        
  254.         success = true;
  255.         err = _dom_dispatch_subtree_modified_event(doc,
  256.                         (dom_event_target *) a, &success);
  257.         return err;
  258. }
  259.  
  260. /**
  261.  * Get the short value of this attribute
  262.  *
  263.  * \param a      The attribute object
  264.  * \param value  The returned value
  265.  * \return DOM_NO_ERR on success,
  266.  *         DOM_ATTR_WRONG_TYPE_ERR if the attribute node is not a short
  267.  *                                 attribute
  268.  */
  269. dom_exception dom_attr_get_short(dom_attr *a, unsigned short *value)
  270. {
  271.         if (a->type != DOM_ATTR_SHORT)
  272.                 return DOM_ATTR_WRONG_TYPE_ERR;
  273.        
  274.         *value = a->value.svalue;
  275.  
  276.         return DOM_NO_ERR;
  277. }
  278.  
  279. /**
  280.  * Set the short value of this attribute
  281.  *
  282.  * \param a      The attribute object
  283.  * \param value  The new value
  284.  * \return DOM_NO_ERR on success,
  285.  *         DOM_ATTR_WRONG_TYPE_ERR if the attribute node is not a short
  286.  *                                 attribute
  287.  */
  288. dom_exception dom_attr_set_short(dom_attr *a, unsigned short value)
  289. {
  290.         struct dom_document *doc;
  291.         struct dom_node_internal *ele;
  292.         bool success = true;
  293.         dom_exception err;
  294.  
  295.         /* If this is the first set method, we should fix this attribute
  296.          * type */
  297.         if (a->type == DOM_ATTR_UNSET)
  298.                 a->type = DOM_ATTR_SHORT;
  299.  
  300.         if (a->type != DOM_ATTR_SHORT)
  301.                 return DOM_ATTR_WRONG_TYPE_ERR;
  302.        
  303.         if (a->value.svalue == value)
  304.                 return DOM_NO_ERR;
  305.        
  306.         a->value.svalue = value;
  307.  
  308.         doc = dom_node_get_owner(a);
  309.         ele = dom_node_get_parent(a);
  310.         err = _dom_dispatch_attr_modified_event(doc, ele, NULL, NULL,
  311.                         (dom_event_target *) a, NULL,
  312.                         DOM_MUTATION_MODIFICATION, &success);
  313.         if (err != DOM_NO_ERR)
  314.                 return err;
  315.        
  316.         success = true;
  317.         err = _dom_dispatch_subtree_modified_event(doc,
  318.                         (dom_event_target *) a, &success);
  319.         return err;
  320. }
  321.  
  322. /**
  323.  * Get the bool value of this attribute
  324.  *
  325.  * \param a      The attribute object
  326.  * \param value  The returned value
  327.  * \return DOM_NO_ERR on success,
  328.  *         DOM_ATTR_WRONG_TYPE_ERR if the attribute node is not a bool
  329.  *                                 attribute
  330.  */
  331. dom_exception dom_attr_get_bool(dom_attr *a, bool *value)
  332. {
  333.         if (a->type != DOM_ATTR_BOOL)
  334.                 return DOM_ATTR_WRONG_TYPE_ERR;
  335.        
  336.         *value = a->value.bvalue;
  337.  
  338.         return DOM_NO_ERR;
  339. }
  340.  
  341. /**
  342.  * Set the bool value of this attribute
  343.  *
  344.  * \param a      The attribute object
  345.  * \param value  The new value
  346.  * \return DOM_NO_ERR on success,
  347.  *         DOM_ATTR_WRONG_TYPE_ERR if the attribute node is not a bool
  348.  *                                 attribute
  349.  */
  350. dom_exception dom_attr_set_bool(dom_attr *a, bool value)
  351. {
  352.         struct dom_document *doc;
  353.         struct dom_node_internal *ele;
  354.         bool success = true;
  355.         dom_exception err;
  356.  
  357.         /* If this is the first set method, we should fix this attribute
  358.          * type */
  359.         if (a->type == DOM_ATTR_UNSET)
  360.                 a->type = DOM_ATTR_BOOL;
  361.  
  362.         if (a->type != DOM_ATTR_BOOL)
  363.                 return DOM_ATTR_WRONG_TYPE_ERR;
  364.        
  365.         if (a->value.bvalue == value)
  366.                 return DOM_NO_ERR;
  367.        
  368.         a->value.bvalue = value;
  369.  
  370.         doc = dom_node_get_owner(a);
  371.         ele = dom_node_get_parent(a);
  372.         err = _dom_dispatch_attr_modified_event(doc, ele, NULL, NULL,
  373.                         (dom_event_target *) a, NULL,
  374.                         DOM_MUTATION_MODIFICATION, &success);
  375.         if (err != DOM_NO_ERR)
  376.                 return err;
  377.        
  378.         success = true;
  379.         err = _dom_dispatch_subtree_modified_event(doc,
  380.                         (dom_event_target *) a, &success);
  381.         return err;
  382. }
  383.  
  384. /**
  385.  * Set the node as a readonly attribute
  386.  *
  387.  * \param a  The attribute
  388.  */
  389. void dom_attr_mark_readonly(dom_attr *a)
  390. {
  391.         a->read_only = true;
  392. }
  393.  
  394. /* -------------------------------------------------------------------- */
  395.  
  396. /* The public virtual functions */
  397.  
  398. /**
  399.  * Retrieve an attribute's name
  400.  *
  401.  * \param attr    Attribute to retrieve name from
  402.  * \param result  Pointer to location to receive result
  403.  * \return DOM_NO_ERR on success, appropriate dom_exception on failure
  404.  *
  405.  * The returned string will have its reference count increased. It is
  406.  * the responsibility of the caller to unref the string once it has
  407.  * finished with it.
  408.  */
  409. dom_exception _dom_attr_get_name(struct dom_attr *attr,
  410.                 dom_string **result)
  411. {
  412.         /* This is the same as nodeName */
  413.         return dom_node_get_node_name(attr, result);
  414. }
  415.  
  416. /**
  417.  * Determine if attribute was specified or default
  418.  *
  419.  * \param attr    Attribute to inspect
  420.  * \param result  Pointer to location to receive result
  421.  * \return DOM_NO_ERR.
  422.  */
  423. dom_exception _dom_attr_get_specified(struct dom_attr *attr, bool *result)
  424. {
  425.         *result = attr->specified;
  426.  
  427.         return DOM_NO_ERR;
  428. }
  429.  
  430. /**
  431.  * Retrieve an attribute's value
  432.  *
  433.  * \param attr    Attribute to retrieve value from
  434.  * \param result  Pointer to location to receive result
  435.  * \return DOM_NO_ERR on success, appropriate dom_exception on failure
  436.  *
  437.  * The returned string will have its reference count increased. It is
  438.  * the responsibility of the caller to unref the string once it has
  439.  * finished with it.
  440.  */
  441. dom_exception _dom_attr_get_value(struct dom_attr *attr,
  442.                 dom_string **result)
  443. {
  444.         struct dom_node_internal *a = (struct dom_node_internal *) attr;
  445.         struct dom_node_internal *c;
  446.         dom_string *value, *temp;
  447.         dom_exception err;
  448.        
  449.         /* Attempt to shortcut for a single text node child with value */
  450.         if ((a->first_child != NULL) &&
  451.             (a->first_child == a->last_child) &&
  452.             (a->first_child->type == DOM_TEXT_NODE) &&
  453.             (a->first_child->value != NULL)) {
  454.                 *result = dom_string_ref(a->first_child->value);
  455.                 return DOM_NO_ERR;
  456.         }
  457.        
  458.         err = dom_string_create(NULL, 0, &value);
  459.         if (err != DOM_NO_ERR) {
  460.                 return err;
  461.         }
  462.  
  463.         /* Force unknown types to strings, if necessary */
  464.         if (attr->type == DOM_ATTR_UNSET && a->first_child != NULL) {
  465.                 attr->type = DOM_ATTR_STRING;
  466.         }
  467.  
  468.         /* If this attribute node is not a string one, we just return an empty
  469.          * string */
  470.         if (attr->type != DOM_ATTR_STRING) {
  471.                 *result = value;
  472.                 return DOM_NO_ERR;
  473.         }
  474.  
  475.         /* Traverse children, building a string representation as we go */
  476.         for (c = a->first_child; c != NULL; c = c->next) {
  477.                 if (c->type == DOM_TEXT_NODE && c->value != NULL) {
  478.                         /* Append to existing value */
  479.                         err = dom_string_concat(value, c->value, &temp);
  480.                         if (err != DOM_NO_ERR) {
  481.                                 dom_string_unref(value);
  482.                                 return err;
  483.                         }
  484.  
  485.                         /* Finished with previous value */
  486.                         dom_string_unref(value);
  487.  
  488.                         /* Claim new value */
  489.                         value = temp;
  490.                 } else if (c->type == DOM_ENTITY_REFERENCE_NODE) {
  491.                         dom_string *tr;
  492.  
  493.                         /* Get textual representation of entity */
  494.                         err = _dom_entity_reference_get_textual_representation(
  495.                                         (struct dom_entity_reference *) c,
  496.                                         &tr);
  497.                         if (err != DOM_NO_ERR) {
  498.                                 dom_string_unref(value);
  499.                                 return err;
  500.                         }
  501.  
  502.                         /* Append to existing value */
  503.                         err = dom_string_concat(value, tr, &temp);
  504.                         if (err != DOM_NO_ERR) {
  505.                                 dom_string_unref(tr);
  506.                                 dom_string_unref(value);
  507.                                 return err;
  508.                         }
  509.  
  510.                         /* No int32_ter need textual representation */
  511.                         dom_string_unref(tr);
  512.  
  513.                         /* Finished with previous value */
  514.                         dom_string_unref(value);
  515.  
  516.                         /* Claim new value */
  517.                         value = temp;
  518.                 }
  519.         }
  520.  
  521.         *result = value;
  522.  
  523.         return DOM_NO_ERR;
  524. }
  525.  
  526. /**
  527.  * Set an attribute's value
  528.  *
  529.  * \param attr   Attribute to retrieve value from
  530.  * \param value  New value for attribute
  531.  * \return DOM_NO_ERR                      on success,
  532.  *         DOM_NO_MODIFICATION_ALLOWED_ERR if attribute is readonly.
  533.  */
  534. dom_exception _dom_attr_set_value(struct dom_attr *attr,
  535.                 dom_string *value)
  536. {
  537.         struct dom_node_internal *a = (struct dom_node_internal *) attr;
  538.         struct dom_node_internal *c, *d;
  539.         struct dom_text *text;
  540.         dom_exception err;
  541.         dom_string *name = NULL;
  542.         dom_string *parsed = NULL;
  543.  
  544.         /* Ensure attribute is writable */
  545.         if (_dom_node_readonly(a))
  546.                 return DOM_NO_MODIFICATION_ALLOWED_ERR;
  547.  
  548.         /* If this is the first set method, we should fix this attribute
  549.          * type */
  550.         if (attr->type == DOM_ATTR_UNSET)
  551.                 attr->type = DOM_ATTR_STRING;
  552.        
  553.         if (attr->type != DOM_ATTR_STRING)
  554.                 return DOM_ATTR_WRONG_TYPE_ERR;
  555.        
  556.         err = _dom_attr_get_name(attr, &name);
  557.         if (err != DOM_NO_ERR)
  558.                 return err;
  559.        
  560.         err = dom_element_parse_attribute(a->parent, name, value, &parsed);
  561.         dom_string_unref(name);
  562.         if (err != DOM_NO_ERR) {
  563.                 return err;
  564.         }
  565.  
  566.         /* Create text node containing new value */
  567.         err = dom_document_create_text_node(a->owner, parsed, &text);
  568.         dom_string_unref(parsed);
  569.         if (err != DOM_NO_ERR)
  570.                 return err;
  571.        
  572.         /* Destroy children of this node */
  573.         for (c = a->first_child; c != NULL; c = d) {
  574.                 d = c->next;
  575.  
  576.                 /* Detach child */
  577.                 c->parent = NULL;
  578.  
  579.                 /* Detach from sibling list */
  580.                 c->previous = NULL;
  581.                 c->next = NULL;
  582.  
  583.                 dom_node_try_destroy(c);
  584.         }
  585.  
  586.         /* And insert the text node as the value */
  587.         ((struct dom_node_internal *) text)->parent = a;
  588.         a->first_child = a->last_child = (struct dom_node_internal *) text;
  589.         dom_node_unref(text);
  590.         dom_node_remove_pending(text);
  591.  
  592.         /* Now the attribute node is specified */
  593.         attr->specified = true;
  594.  
  595.         return DOM_NO_ERR;
  596. }
  597.  
  598. /**
  599.  * Retrieve the owning element of an attribute
  600.  *
  601.  * \param attr    The attribute to extract owning element from
  602.  * \param result  Pointer to location to receive result
  603.  * \return DOM_NO_ERR.
  604.  *
  605.  * The returned node will have its reference count increased. The caller
  606.  * should unref it once it has finished with it.
  607.  */
  608. dom_exception _dom_attr_get_owner(struct dom_attr *attr,
  609.                 struct dom_element **result)
  610. {
  611.         struct dom_node_internal *a = (struct dom_node_internal *) attr;
  612.  
  613.         /* If there is an owning element, increase its reference count */
  614.         if (a->parent != NULL)
  615.                 dom_node_ref(a->parent);
  616.  
  617.         *result = (struct dom_element *) a->parent;
  618.  
  619.         return DOM_NO_ERR;
  620. }
  621.  
  622. /**
  623.  * Retrieve an attribute's type information
  624.  *
  625.  * \param attr    The attribute to extract type information from
  626.  * \param result  Pointer to location to receive result
  627.  * \return DOM_NOT_SUPPORTED_ERR, we don't support this API now.
  628.  *
  629.  * The returned type info will have its reference count increased. The caller
  630.  * should unref it once it has finished with it.
  631.  */
  632. dom_exception _dom_attr_get_schema_type_info(struct dom_attr *attr,
  633.                 struct dom_type_info **result)
  634. {
  635.         UNUSED(attr);
  636.         UNUSED(result);
  637.  
  638.         return DOM_NOT_SUPPORTED_ERR;
  639. }
  640.  
  641. /**
  642.  * Determine if an attribute if of type ID
  643.  *
  644.  * \param attr    The attribute to inspect
  645.  * \param result  Pointer to location to receive result
  646.  * \return DOM_NO_ERR.
  647.  */
  648. dom_exception _dom_attr_is_id(struct dom_attr *attr, bool *result)
  649. {
  650.         *result = attr->is_id;
  651.  
  652.         return DOM_NO_ERR;
  653. }
  654.  
  655. /*------------- The overload virtual functions ------------------------*/
  656.  
  657. /* Overload function of Node, please refer node.c for the detail of this
  658.  * function. */
  659. dom_exception _dom_attr_get_node_value(dom_node_internal *node,
  660.                 dom_string **result)
  661. {
  662.         dom_attr *attr = (dom_attr *) node;
  663.  
  664.         return _dom_attr_get_value(attr, result);
  665. }
  666.  
  667. /* Overload function of Node, please refer node.c for the detail of this
  668.  * function. */
  669. dom_exception _dom_attr_clone_node(dom_node_internal *node, bool deep,
  670.                 dom_node_internal **result)
  671. {
  672.         dom_exception err;
  673.         dom_attr *attr;
  674.  
  675.         /* Discard the warnings */
  676.         UNUSED(deep);
  677.  
  678.         /* Clone an Attr always clone all its children */
  679.         err = _dom_node_clone_node(node, true, result);
  680.         if (err != DOM_NO_ERR)
  681.                 return err;
  682.        
  683.         attr = (dom_attr *) *result;
  684.         /* Clone an Attr always result a specified Attr,
  685.          * see DOM Level 3 Node.cloneNode */
  686.         attr->specified = true;
  687.  
  688.         return DOM_NO_ERR;
  689. }
  690.  
  691. /* Overload function of Node, please refer node.c for the detail of this
  692.  * function. */
  693. dom_exception _dom_attr_set_prefix(dom_node_internal *node,
  694.                 dom_string *prefix)
  695. {
  696.         /* Really I don't know whether there should something
  697.          * special to do here */
  698.         return _dom_node_set_prefix(node, prefix);
  699. }
  700.  
  701. /* Overload function of Node, please refer node.c for the detail of this
  702.  * function. */
  703. dom_exception _dom_attr_lookup_prefix(dom_node_internal *node,
  704.                 dom_string *namespace, dom_string **result)
  705. {
  706.         struct dom_element *owner;
  707.         dom_exception err;
  708.  
  709.         err = dom_attr_get_owner_element(node, &owner);
  710.         if (err != DOM_NO_ERR)
  711.                 return err;
  712.        
  713.         if (owner == NULL) {
  714.                 *result = NULL;
  715.                 return DOM_NO_ERR;
  716.         }
  717.  
  718.         return dom_node_lookup_prefix(owner, namespace, result);
  719. }
  720.  
  721. /* Overload function of Node, please refer node.c for the detail of this
  722.  * function. */
  723. dom_exception _dom_attr_is_default_namespace(dom_node_internal *node,
  724.                 dom_string *namespace, bool *result)
  725. {
  726.         struct dom_element *owner;
  727.         dom_exception err;
  728.  
  729.         err = dom_attr_get_owner_element(node, &owner);
  730.         if (err != DOM_NO_ERR)
  731.                 return err;
  732.        
  733.         if (owner == NULL) {
  734.                 *result = false;
  735.                 return DOM_NO_ERR;
  736.         }
  737.  
  738.         return dom_node_is_default_namespace(owner, namespace, result);
  739. }
  740.  
  741. /* Overload function of Node, please refer node.c for the detail of this
  742.  * function. */
  743. dom_exception _dom_attr_lookup_namespace(dom_node_internal *node,
  744.                 dom_string *prefix, dom_string **result)
  745. {
  746.         struct dom_element *owner;
  747.         dom_exception err;
  748.  
  749.         err = dom_attr_get_owner_element(node, &owner);
  750.         if (err != DOM_NO_ERR)
  751.                 return err;
  752.        
  753.         if (owner == NULL) {
  754.                 *result = NULL;
  755.                 return DOM_NO_ERR;
  756.         }
  757.  
  758.         return dom_node_lookup_namespace(owner, prefix, result);
  759. }
  760.  
  761.  
  762. /*----------------------------------------------------------------------*/
  763.  
  764. /* The protected virtual functions */
  765.  
  766. /* The virtual destroy function of this class */
  767. void __dom_attr_destroy(dom_node_internal *node)
  768. {
  769.         _dom_attr_destroy((dom_attr *) node);
  770. }
  771.  
  772. /* The memory allocator of this class */
  773. dom_exception _dom_attr_copy(dom_node_internal *n, dom_node_internal **copy)
  774. {
  775.         dom_attr *old = (dom_attr *) n;
  776.         dom_attr *a;
  777.         dom_exception err;
  778.        
  779.         a = malloc(sizeof(struct dom_attr));
  780.         if (a == NULL)
  781.                 return DOM_NO_MEM_ERR;
  782.  
  783.         err = dom_node_copy_internal(n, a);
  784.         if (err != DOM_NO_ERR) {
  785.                 free(a);
  786.                 return err;
  787.         }
  788.        
  789.         a->specified = old->specified;
  790.  
  791.         /* TODO: deal with dom_type_info, it get no definition ! */
  792.         a->schema_type_info = NULL;
  793.  
  794.         a->is_id = old->is_id;
  795.  
  796.         a->type = old->type;
  797.  
  798.         a->value = old->value;
  799.  
  800.         /* TODO: is this correct? */
  801.         a->read_only = false;
  802.  
  803.         *copy = (dom_node_internal *) a;
  804.  
  805.         return DOM_NO_ERR;
  806. }
  807.  
  808.  
  809. /**
  810.  * Set/Unset whether this attribute is a ID attribute
  811.  *
  812.  * \param attr   The attribute
  813.  * \param is_id  Whether it is a ID attribute
  814.  */
  815. void _dom_attr_set_isid(struct dom_attr *attr, bool is_id)
  816. {
  817.         attr->is_id = is_id;
  818. }
  819.  
  820. /**
  821.  * Set/Unset whether the attribute is a specified one.
  822.  *
  823.  * \param attr       The attribute node
  824.  * \param specified  Whether this attribute is a specified one
  825.  */
  826. void _dom_attr_set_specified(struct dom_attr *attr, bool specified)
  827. {
  828.         attr->specified = specified;
  829. }
  830.  
  831. /**
  832.  * Whether this attribute node is readonly
  833.  *
  834.  * \param a  The node
  835.  * \return true if this Attr is readonly, false otherwise
  836.  */
  837. bool _dom_attr_readonly(const dom_attr *a)
  838. {
  839.         return a->read_only;
  840. }
  841.  
  842.