Annotation of win32/gnome/gdome2-x.x.x/libgdome/gdomecore/gdome-xml-cdata.c, revision 1.1

1.1     ! paf         1: /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */
        !             2: /* gdome-xml-cdata.c
        !             3:  *
        !             4:  * Copyright (C) 1999 Raph Levien <raph@acm.org>
        !             5:  * Copyright (C) 2000 Mathieu Lacage <mathieu@gnu.org>
        !             6:  * Copyright (C) 2001 Paolo Casarini <paolo@casarini.org>
        !             7:  *
        !             8:  * This library is free software; you can redistribute it and/or
        !             9:  * modify it under the terms of the GNU Lesser General Public
        !            10:  * License as published by the Free Software Foundation; either
        !            11:  * version 2.1 of the License, or (at your option) any later version.
        !            12:  * 
        !            13:  * This library is distributed in the hope that it will be useful,
        !            14:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            15:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
        !            16:  * Lesser General Public License for more details.
        !            17:  * 
        !            18:  * You should have received a copy of the GNU Lesser General Public
        !            19:  * License along with this library; if not, write to the Free Software
        !            20:  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
        !            21:  */
        !            22: 
        !            23: #include <stdlib.h>
        !            24: #include <string.h>
        !            25: #include <glib.h>
        !            26: #include "gdome.h"
        !            27: #include "gdome-events.h"
        !            28: #include <libxml/tree.h>
        !            29: #include <libxml/parser.h>
        !            30: #include <libxml/xmlmemory.h>
        !            31: #include "gdome-evt-event.h"
        !            32: #include "gdome-evt-mevent.h"
        !            33: #include "gdome-xml-util.h"
        !            34: #include "gdome-xml-xmlutil.h"
        !            35: #include "gdome-xml-str.h"
        !            36: #include "gdome-xml-node.h"
        !            37: #include "gdome-xml-cdata.h"
        !            38: #include "gdome-xml-document.h"
        !            39: 
        !            40: const GdomeCharacterDataVtab gdome_xml_cd_vtab = {
        !            41:   {
        !            42:    gdome_xml_n_ref,
        !            43:    gdome_xml_n_unref,
        !            44:    gdome_xml_cd_query_interface,
        !            45:     gdome_xml_n_nodeName,
        !            46:     gdome_xml_n_nodeValue,
        !            47:     gdome_xml_n_set_nodeValue,
        !            48:     gdome_xml_n_nodeType,
        !            49:    gdome_xml_n_parentNode,
        !            50:     gdome_xml_n_childNodes,
        !            51:     gdome_xml_n_firstChild,
        !            52:     gdome_xml_n_lastChild,
        !            53:     gdome_xml_n_previousSibling,
        !            54:     gdome_xml_n_nextSibling,
        !            55:     gdome_xml_n_attributes,
        !            56:     gdome_xml_n_ownerDocument,
        !            57:     gdome_xml_n_insertBefore,
        !            58:     gdome_xml_n_replaceChild,
        !            59:     gdome_xml_n_removeChild,
        !            60:     gdome_xml_n_appendChild,
        !            61:     gdome_xml_n_hasChildNodes,
        !            62:     gdome_xml_n_cloneNode,
        !            63:     gdome_xml_n_normalize,
        !            64:     gdome_xml_n_isSupported,
        !            65:     gdome_xml_n_namespaceURI,
        !            66:     gdome_xml_n_prefix,
        !            67:     gdome_xml_n_set_prefix,
        !            68:     gdome_xml_n_localName,
        !            69:     gdome_xml_n_hasAttributes,
        !            70:     gdome_xml_n_addEventListener,
        !            71:     gdome_xml_n_removeEventListener,
        !            72:     gdome_xml_n_dispatchEvent,
        !            73:     gdome_xml_n_subTreeDispatchEvent
        !            74:   },
        !            75:   gdome_xml_cd_data,
        !            76:   gdome_xml_cd_set_data,
        !            77:   gdome_xml_cd_length,
        !            78:   gdome_xml_cd_substringData,
        !            79:   gdome_xml_cd_appendData,
        !            80:   gdome_xml_cd_insertData,
        !            81:   gdome_xml_cd_deleteData,
        !            82:   gdome_xml_cd_replaceData
        !            83: };
        !            84: 
        !            85: /*
        !            86:  * Some helper functions to work with UTF-8 string as they were UTF-16 string
        !            87:  *                                  BEGIN
        !            88:  */
        !            89: 
        !            90: /**
        !            91:  * gdome_utf16Length:
        !            92:  * @utf8str:  The UTF-8 string
        !            93:  *
        !            94:  * Returns: the length of the string speciefied in UTF-16 units.
        !            95:  */
        !            96: gulong
        !            97: gdome_utf16Length (xmlChar *utf8str) {
        !            98:  gulong len = 0L, i;
        !            99:  char c;
        !           100: 
        !           101:  for (i = 0L; (c = utf8str[i]) != '\0'; i++)
        !           102:    if ((c & 0xf8) == 0xf0)               /* FIXME: I'm not sure this is */
        !           103:      len += 2L;                          /*        correct.             */
        !           104:    else if ((c & 0xc0) != 0x80)
        !           105:      len++;
        !           106: 
        !           107:  return len;
        !           108: }
        !           109: 
        !           110: /**
        !           111:  * gdome_utf16Offeset:
        !           112:  * @utf8str:  The UTF-8 string
        !           113:  * @utf16offset:  The UTF-16 offset to find
        !           114:  * @utf8offset:  The pointer where place the resulted UTF-8 offset
        !           115:  *
        !           116:  * Sets the UTF-8 offset of the UTF-16 offset specified in @utf8offset.
        !           117:  * Returns: TRUE if @utf16offset is found, FALSE if it's out of range.
        !           118:  */
        !           119: gboolean
        !           120: gdome_utf16Offset (xmlChar *utf8str, gulong utf16offset, gulong *utf8offset) {
        !           121:  gulong len = 0L, i;
        !           122:  char c;
        !           123: 
        !           124:  for (i = 0L; len < utf16offset && (c = utf8str[i]) != '\0'; i++)
        !           125:    if ((c & 0xf8) == 0xf0)                 /* FIXME: I'm not sure this is */
        !           126:      len += 2L;                            /*        correct              */
        !           127:    else if ((c & 0xc0) != 0x80)
        !           128:      len++;
        !           129: 
        !           130:  for (;(utf8str[i] & 0xc0) == 0x80; i++);
        !           131: 
        !           132:  *utf8offset = i;
        !           133: 
        !           134:  if (len == utf16offset )
        !           135:    return TRUE;
        !           136:  else
        !           137:    return FALSE;
        !           138: }
        !           139: 
        !           140: /*                                   END
        !           141:  * Some helper functions to work with UTF-8 string as they were UTF-16 string
        !           142:  */
        !           143: 
        !           144: /**
        !           145:  * gdome_xml_cd_query_interface:
        !           146:  * @self:  Node Object ref
        !           147:  * @interface:  interface needed
        !           148:  * @exc:  Exception Object ref
        !           149:  *
        !           150:  * Returns: a reference to this object that implements the @interface needed,
        !           151:  *          or %NULL if the @interface is not supported by this Object.
        !           152:  */
        !           153: gpointer
        !           154: gdome_xml_cd_query_interface (GdomeNode *self, const char *interface, GdomeException *exc)
        !           155: {
        !           156:   Gdome_xml_CharacterData *priv = (Gdome_xml_CharacterData *)self;
        !           157: 
        !           158:   g_return_val_if_fail (priv != NULL, NULL);
        !           159:   g_return_val_if_fail (GDOME_XML_IS_CD (priv), NULL);
        !           160:   g_return_val_if_fail (interface != NULL, NULL);
        !           161:   g_return_val_if_fail (exc != NULL, NULL);
        !           162: 
        !           163:   if (!strcmp (interface, "Node") ||
        !           164:       !strcmp (interface, "CharacterData") ||
        !           165:       !strcmp (interface, "EventTarget")) {
        !           166:     priv->refcnt++;
        !           167:     return self;
        !           168:   }
        !           169:   else
        !           170:     return NULL;
        !           171: }
        !           172: 
        !           173: /**
        !           174:  * gdome_xml_cd_data:
        !           175:  * @self:  The CharacterData Object ref
        !           176:  * @exc:  The Exception Object ref
        !           177:  *
        !           178:  * Returns: the character data of the node that implements this interface.
        !           179:  */
        !           180: GdomeDOMString *
        !           181: gdome_xml_cd_data (GdomeCharacterData *self, GdomeException *exc) {
        !           182:  Gdome_xml_CharacterData *priv = (Gdome_xml_CharacterData *)self;
        !           183: 
        !           184:  g_return_val_if_fail (priv != NULL, NULL);
        !           185:  g_return_val_if_fail (GDOME_XML_IS_CD (priv), NULL);
        !           186:  g_return_val_if_fail (exc != NULL, NULL);
        !           187: 
        !           188:  return gdome_xml_str_mkref_xml (xmlNodeGetContent (priv->n));
        !           189: }
        !           190: 
        !           191: /**
        !           192:  * gdome_xml_cd_set_data:
        !           193:  * @self:  The CharacterData Object ref
        !           194:  * @data:  The data value for this node
        !           195:  * @exc:  The Exception Object ref
        !           196:  *
        !           197:  * Sets the data value of this node.
        !           198:  *
        !           199:  * %GDOME_NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
        !           200:  */
        !           201: void
        !           202: gdome_xml_cd_set_data (GdomeCharacterData *self, GdomeDOMString *data, GdomeException *exc)
        !           203: {
        !           204:  Gdome_xml_CharacterData *priv = (Gdome_xml_CharacterData *)self;
        !           205:   GdomeMutationEvent *mev;
        !           206:  GdomeDOMString *prevValue;
        !           207:   GdomeNode *parent;
        !           208: 
        !           209:  g_return_if_fail (priv != NULL);
        !           210:  g_return_if_fail (GDOME_XML_IS_CD (priv));
        !           211:  g_return_if_fail (data != NULL);
        !           212:  g_return_if_fail (exc != NULL);
        !           213: 
        !           214:   if (GDOME_ISREADONLY (priv)) {
        !           215:     *exc = GDOME_NO_MODIFICATION_ALLOWED_ERR;
        !           216:     return;
        !           217:   }
        !           218: 
        !           219:   prevValue = gdome_xml_cd_data (self, exc);
        !           220:  xmlNodeSetContent (priv->n, data->str);
        !           221: 
        !           222:  if (gdome_xml_n_eventEnabledByCode((GdomeNode *) self, DOM_CHARACTER_DATA_MODIFIED_EVENT_TYPE)) {
        !           223:    /* Fire DOMCharacterDataModified */
        !           224:    mev = gdome_evt_mevnt_mkref ();
        !           225:    gdome_str_ref (data);
        !           226:    gdome_evt_mevnt_initMutationEventByCode (mev, DOM_CHARACTER_DATA_MODIFIED_EVENT_TYPE,
        !           227:                                             TRUE, FALSE, NULL,
        !           228:                                             prevValue, data, NULL, 0, exc);
        !           229:    gdome_xml_n_dispatchEvent ((GdomeNode *)self, (GdomeEvent *)mev, exc);
        !           230:    gdome_xml_str_unref (data);
        !           231:    gdome_xml_str_unref (prevValue);
        !           232:    gdome_evt_mevnt_unref ((GdomeEvent *)mev, exc);
        !           233:  }
        !           234: 
        !           235:   if (gdome_xml_n_eventEnabledByCode((GdomeNode *) self, DOM_SUBTREE_MODIFIED_EVENT_TYPE)) {
        !           236:    /* Fire DOMSubtreeModified */
        !           237:    parent = gdome_xml_n_mkref (gdome_xmlGetParent (priv->n));
        !           238:    if (parent != NULL) {
        !           239:      mev = gdome_evt_mevnt_mkref ();
        !           240:      gdome_evt_mevnt_initMutationEventByCode (mev, DOM_SUBTREE_MODIFIED_EVENT_TYPE,
        !           241:                                               TRUE, FALSE, NULL,
        !           242:                                               NULL, NULL, NULL, 0, exc);
        !           243:      gdome_xml_n_dispatchEvent (parent, (GdomeEvent *)mev, exc);
        !           244:      gdome_xml_n_unref (parent, exc);
        !           245:      gdome_evt_mevnt_unref ((GdomeEvent *)mev, exc);
        !           246:    }
        !           247:  }
        !           248: }
        !           249: 
        !           250: /**
        !           251:  * gdome_xml_cd_length:
        !           252:  * @self:  The CharacterData Object ref
        !           253:  * @exc:  The GdomeException Object ref
        !           254:  *
        !           255:  * Returns: The number of 16-bit units that are available. This may have the
        !           256:  * value zero, i.e., CharacterData nodes may be empty.
        !           257:  */
        !           258: gulong
        !           259: gdome_xml_cd_length (GdomeCharacterData *self, GdomeException *exc)
        !           260: {
        !           261:  Gdome_xml_CharacterData *priv = (Gdome_xml_CharacterData *)self;
        !           262:  xmlChar *content;
        !           263:  gulong length;
        !           264: 
        !           265:  g_return_val_if_fail (priv != NULL, 0L);
        !           266:  g_return_val_if_fail (GDOME_XML_IS_CD (priv), 0L);
        !           267:  g_return_val_if_fail (exc != NULL, 0L);
        !           268: 
        !           269:  content = xmlNodeGetContent (priv->n);
        !           270:  length = gdome_utf16Length (content);
        !           271:  g_free (content);
        !           272:  return length;
        !           273: }
        !           274: 
        !           275: /**
        !           276:  * gdome_xml_cd_substringData:
        !           277:  * @self:  The CharacterData Object ref
        !           278:  * @offset:  Start offset of substring to extract
        !           279:  * @count:  The number of 16-bit units to extract
        !           280:  * @exc:  The Exception Object ref
        !           281:  *
        !           282:  * Extracts a range of data from the node.
        !           283:  *
        !           284:  * %GDOME_INDEX_SIZE_ERR: Raised if the specified @offset is greater than the
        !           285:  * number of 16-bit units in data.
        !           286:  * Returns: The specified substring. If the sum of @offset and @count exceeds
        !           287:  * the length, then all 16-bit units to the end of the data are returned.
        !           288:  */
        !           289: GdomeDOMString *
        !           290: gdome_xml_cd_substringData (GdomeCharacterData *self, gulong offset, gulong count, GdomeException *exc)
        !           291: {
        !           292:  Gdome_xml_CharacterData *priv = (Gdome_xml_CharacterData *)self;
        !           293:  xmlChar *ret = NULL;
        !           294:  xmlChar *str = NULL;
        !           295:  gulong start, stop;
        !           296: 
        !           297:  g_return_val_if_fail (priv != NULL, NULL);
        !           298:  g_return_val_if_fail (GDOME_XML_IS_CD (priv), NULL);
        !           299:  g_return_val_if_fail (exc != NULL, NULL);
        !           300: 
        !           301:  str = xmlNodeGetContent(priv->n);
        !           302: 
        !           303:  if (!gdome_utf16Offset (str, offset, &start)) {
        !           304:    xmlFree (str);
        !           305:    *exc = GDOME_INDEX_SIZE_ERR;
        !           306:    return NULL;
        !           307:  }
        !           308: 
        !           309:  gdome_utf16Offset (str, offset+count, &stop);
        !           310: 
        !           311:  ret = (xmlChar *)xmlMalloc (stop - start + 1 * sizeof (xmlChar));
        !           312:  memcpy (ret, str + start, stop - start);
        !           313:  ret[stop - start] = '\0';
        !           314: 
        !           315:  xmlFree (str);
        !           316:  return gdome_xml_str_mkref_xml (ret);
        !           317: }
        !           318: 
        !           319: /**
        !           320:  * gdome_xml_cd_appendData:
        !           321:  * @self:  The CharacterData Object ref
        !           322:  * @arg:  The string to append
        !           323:  * @exc:  The Exception Object ref
        !           324:  *
        !           325:  * Append the string to the end of the character data of the node. Upon
        !           326:  * success, data provides access to the concatenation of data and the
        !           327:  * string specified.
        !           328:  *
        !           329:  * %GDOME_NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
        !           330:  */
        !           331: void
        !           332: gdome_xml_cd_appendData (GdomeCharacterData *self, GdomeDOMString *arg, GdomeException *exc)
        !           333: {
        !           334:  Gdome_xml_CharacterData *priv = (Gdome_xml_CharacterData *)self;
        !           335:   GdomeMutationEvent *mev;
        !           336:   GdomeDOMString *prevValue, *newValue;
        !           337:   GdomeNode *parent;
        !           338:  xmlChar *old_str, *new_str = NULL;
        !           339:  int len1 = 0, len2 = 0;
        !           340: 
        !           341:  g_return_if_fail (priv != NULL);
        !           342:  g_return_if_fail (GDOME_XML_IS_CD (priv));
        !           343:  g_return_if_fail (arg != NULL);
        !           344:  g_return_if_fail (exc != NULL);
        !           345: 
        !           346:   if (GDOME_ISREADONLY (priv)) {
        !           347:     *exc = GDOME_NO_MODIFICATION_ALLOWED_ERR;
        !           348:     return;
        !           349:   }
        !           350: 
        !           351:  old_str = xmlNodeGetContent (priv->n);
        !           352:  len1 = strlen (old_str);
        !           353:  len2 = strlen (arg->str);
        !           354:  new_str = xmlMalloc (len1 + len2 + 1 * sizeof (xmlChar));
        !           355:  memcpy (new_str, old_str, len1);
        !           356:  memcpy (new_str + len1, arg->str, len2 + 1);
        !           357: 
        !           358:   xmlNodeSetContent (priv->n, new_str);
        !           359: 
        !           360:  if (gdome_xml_n_eventEnabledByCode((GdomeNode *) self, DOM_CHARACTER_DATA_MODIFIED_EVENT_TYPE)) {
        !           361:    /* Fire DOMCharacterDataModified */
        !           362:    mev = gdome_evt_mevnt_mkref ();
        !           363:    prevValue = gdome_xml_str_mkref (old_str);
        !           364:    newValue = gdome_xml_str_mkref (new_str);
        !           365:    gdome_evt_mevnt_initMutationEventByCode (mev, DOM_CHARACTER_DATA_MODIFIED_EVENT_TYPE,
        !           366:                                             TRUE, FALSE, NULL,
        !           367:                                             prevValue, newValue, NULL, 0, exc);
        !           368:    gdome_xml_n_dispatchEvent ((GdomeNode *)self, (GdomeEvent *)mev, exc);
        !           369:    gdome_xml_str_unref (newValue);
        !           370:    gdome_xml_str_unref (prevValue);
        !           371:    gdome_evt_mevnt_unref ((GdomeEvent *)mev, exc);
        !           372:  }
        !           373:  g_free (new_str);
        !           374: 
        !           375:   if (old_str != NULL)
        !           376:     xmlFree (old_str);
        !           377:  
        !           378:  if (gdome_xml_n_eventEnabledByCode((GdomeNode *) self, DOM_SUBTREE_MODIFIED_EVENT_TYPE)) {
        !           379:    /* Fire DOMSubtreeModified */
        !           380:    parent = gdome_xml_n_mkref (gdome_xmlGetParent (priv->n));
        !           381:    if (parent != NULL) {
        !           382:      mev = gdome_evt_mevnt_mkref ();
        !           383:      gdome_evt_mevnt_initMutationEventByCode (mev, DOM_SUBTREE_MODIFIED_EVENT_TYPE,
        !           384:                                               TRUE, FALSE, NULL,
        !           385:                                               NULL, NULL, NULL, 0, exc);
        !           386:      gdome_xml_n_dispatchEvent (parent, (GdomeEvent *)mev, exc);
        !           387:      gdome_xml_n_unref (parent, exc);
        !           388:      gdome_evt_mevnt_unref ((GdomeEvent *)mev, exc);
        !           389:    }
        !           390:  }
        !           391: }
        !           392: 
        !           393: /**
        !           394:  * gdome_xml_cd_insertData:
        !           395:  * @self:  The CharacterData Object ref
        !           396:  * @offset:  The character offset at which to insert
        !           397:  * @arg:  The string to insert
        !           398:  * @exc:  The Exception Object ref
        !           399:  *
        !           400:  * Insert a string at the specified 16-bit unit offset.
        !           401:  *
        !           402:  * %GDOME_INDEX_SIZE_ERR: Raised if the specified offset is greater than the
        !           403:  * number of 16-bit units in data.
        !           404:  * %GDOME_NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
        !           405:  */
        !           406: void
        !           407: gdome_xml_cd_insertData (GdomeCharacterData *self, gulong offset, GdomeDOMString *arg, GdomeException *exc)
        !           408: {
        !           409:  Gdome_xml_CharacterData *priv = (Gdome_xml_CharacterData *)self;
        !           410:   GdomeMutationEvent *mev;
        !           411:   GdomeDOMString *prevValue, *newValue;
        !           412:   GdomeNode *parent;
        !           413:  xmlChar *old_str, *new_str = NULL;
        !           414:  int len1 = 0, len2 = 0;
        !           415:  gulong start;
        !           416: 
        !           417:   if (GDOME_ISREADONLY (priv)) {
        !           418:     *exc = GDOME_NO_MODIFICATION_ALLOWED_ERR;
        !           419:     return;
        !           420:   }
        !           421: 
        !           422:  g_return_if_fail (priv != NULL);
        !           423:  g_return_if_fail (GDOME_XML_IS_CD (priv));
        !           424:  g_return_if_fail (arg != NULL);
        !           425:  g_return_if_fail (exc != NULL);
        !           426: 
        !           427:  old_str = xmlNodeGetContent (priv->n);
        !           428:  len1 = strlen (old_str);
        !           429:  len2 = strlen (arg->str);
        !           430: 
        !           431:  if (!gdome_utf16Offset (old_str, offset, &start)) {
        !           432:    xmlFree (old_str);
        !           433:    *exc = GDOME_INDEX_SIZE_ERR;
        !           434:    return;
        !           435:  }
        !           436: 
        !           437:  new_str = xmlMalloc (len1 + len2 + 1 * sizeof (xmlChar));
        !           438:  memcpy (new_str, old_str, start);
        !           439:  memcpy (new_str + start, arg->str, len2);
        !           440:   memcpy (new_str + start + len2, old_str + start, len1 - start + 1);
        !           441: 
        !           442:  xmlNodeSetContent (priv->n, new_str);
        !           443:  
        !           444:  if (gdome_xml_n_eventEnabledByCode((GdomeNode *) self, DOM_CHARACTER_DATA_MODIFIED_EVENT_TYPE)) {
        !           445:    /* Fire DOMCharacterDataModified */
        !           446:    mev = gdome_evt_mevnt_mkref ();
        !           447:    prevValue = gdome_xml_str_mkref (old_str);
        !           448:    newValue = gdome_xml_str_mkref (new_str);
        !           449:    gdome_evt_mevnt_initMutationEventByCode (mev, DOM_CHARACTER_DATA_MODIFIED_EVENT_TYPE,
        !           450:                                             TRUE, FALSE, NULL,
        !           451:                                             prevValue, newValue, NULL, 0, exc);
        !           452:    gdome_xml_n_dispatchEvent ((GdomeNode *)self, (GdomeEvent *)mev, exc);
        !           453:    gdome_xml_str_unref (newValue);
        !           454:    gdome_xml_str_unref (prevValue);
        !           455:    gdome_evt_mevnt_unref ((GdomeEvent *)mev, exc);
        !           456:  }
        !           457:  g_free (new_str);
        !           458: 
        !           459:   if (old_str != NULL)
        !           460:     xmlFree (old_str);
        !           461: 
        !           462:  if (gdome_xml_n_eventEnabledByCode((GdomeNode *) self, DOM_SUBTREE_MODIFIED_EVENT_TYPE)) {
        !           463:    /* Fire DOMSubtreeModified */
        !           464:    parent = gdome_xml_n_mkref (gdome_xmlGetParent (priv->n));
        !           465:    if (parent != NULL) {
        !           466:      mev = gdome_evt_mevnt_mkref ();
        !           467:      gdome_evt_mevnt_initMutationEventByCode (mev, DOM_SUBTREE_MODIFIED_EVENT_TYPE,
        !           468:                                               TRUE, FALSE, NULL,
        !           469:                                               NULL, NULL, NULL, 0, exc);
        !           470:      gdome_xml_n_dispatchEvent (parent, (GdomeEvent *)mev, exc);
        !           471:      gdome_xml_n_unref (parent, exc);
        !           472:      gdome_evt_mevnt_unref ((GdomeEvent *)mev, exc);
        !           473:    }
        !           474:  }
        !           475: }
        !           476: 
        !           477: /**
        !           478:  * gdome_xml_cd_deleteData:
        !           479:  * @self:  The CharacterData Object ref
        !           480:  * @offset:  The offset from which to start removing
        !           481:  * @count:  The number of 16-bit units to delete.
        !           482:  * @exc:  The Exception Object ref
        !           483:  *
        !           484:  * Remove a range of 16-bit units from the node. If the sum of @offset and
        !           485:  * @count exceeds length then all 16-bit units from @offset to the end of the
        !           486:  * data are deleted. Upon success, data and length reflect the change.
        !           487:  *
        !           488:  * %GDOME_INDEX_SIZE_ERR: Raised if the specified offset is greater than the
        !           489:  * number of 16-bit units in data.
        !           490:  * %GDOME_NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
        !           491:  */
        !           492: void
        !           493: gdome_xml_cd_deleteData (GdomeCharacterData *self, gulong offset, gulong count, GdomeException *exc)
        !           494: {
        !           495:  Gdome_xml_CharacterData *priv = (Gdome_xml_CharacterData *)self;
        !           496:   GdomeMutationEvent *mev;
        !           497:   GdomeDOMString *prevValue, *newValue;
        !           498:   GdomeNode *parent;
        !           499:  xmlChar *old_str, *new_str = NULL;
        !           500:  gulong start, stop, len1, len2;
        !           501: 
        !           502:   if (GDOME_ISREADONLY (priv)) {
        !           503:     *exc = GDOME_NO_MODIFICATION_ALLOWED_ERR;
        !           504:     return;
        !           505:   }
        !           506: 
        !           507:  g_return_if_fail (priv != NULL);
        !           508:  g_return_if_fail (GDOME_XML_IS_CD (priv));
        !           509:  g_return_if_fail (exc != NULL);
        !           510: 
        !           511:  old_str = xmlNodeGetContent (priv->n);
        !           512:  if (!gdome_utf16Offset (old_str, offset, &start)) {
        !           513:    xmlFree (old_str);
        !           514:    *exc = GDOME_INDEX_SIZE_ERR;
        !           515:    return;
        !           516:  }
        !           517: 
        !           518:  gdome_utf16Offset (old_str, offset+count, &stop);
        !           519:   len1 = strlen (old_str);
        !           520:  len2 = len1 - (stop - start);
        !           521:  new_str = (xmlChar *)xmlMalloc (len2 + 1 * sizeof (xmlChar));
        !           522:  memcpy (new_str, old_str, start);
        !           523:  memcpy (new_str + start, old_str + stop, len1 - stop);
        !           524:   new_str[len2] = '\0';
        !           525: 
        !           526:  xmlNodeSetContent (priv->n, new_str);
        !           527: 
        !           528:  if (gdome_xml_n_eventEnabledByCode((GdomeNode *) self, DOM_CHARACTER_DATA_MODIFIED_EVENT_TYPE)) {
        !           529:    /* Fire DOMCharacterDataModified */
        !           530:    mev = gdome_evt_mevnt_mkref ();
        !           531:    prevValue = gdome_xml_str_mkref (old_str);
        !           532:    newValue = gdome_xml_str_mkref (new_str);
        !           533:    gdome_evt_mevnt_initMutationEventByCode (mev, DOM_CHARACTER_DATA_MODIFIED_EVENT_TYPE,
        !           534:                                             TRUE, FALSE, NULL,
        !           535:                                             prevValue, newValue, NULL, 0, exc);
        !           536:    gdome_xml_n_dispatchEvent ((GdomeNode *)self, (GdomeEvent *)mev, exc);
        !           537:    gdome_xml_str_unref (newValue);
        !           538:    gdome_xml_str_unref (prevValue);
        !           539:    gdome_evt_mevnt_unref ((GdomeEvent *)mev, exc);
        !           540:  }
        !           541:  g_free (new_str);
        !           542: 
        !           543:   if (old_str != NULL)
        !           544:     xmlFree (old_str);
        !           545: 
        !           546:  if (gdome_xml_n_eventEnabledByCode((GdomeNode *) self, DOM_SUBTREE_MODIFIED_EVENT_TYPE)) {
        !           547:    /* Fire DOMSubtreeModified */
        !           548:    parent = gdome_xml_n_mkref (gdome_xmlGetParent (priv->n));
        !           549:    if (parent != NULL) {
        !           550:      mev = gdome_evt_mevnt_mkref ();
        !           551:      gdome_evt_mevnt_initMutationEventByCode (mev, DOM_SUBTREE_MODIFIED_EVENT_TYPE,
        !           552:                                               TRUE, FALSE, NULL,
        !           553:                                               NULL, NULL, NULL, 0, exc);
        !           554:      gdome_xml_n_dispatchEvent (parent, (GdomeEvent *)mev, exc);
        !           555:      gdome_xml_n_unref (parent, exc);
        !           556:      gdome_evt_mevnt_unref ((GdomeEvent *)mev, exc);
        !           557:    }
        !           558:  }
        !           559: }
        !           560: 
        !           561: /**
        !           562:  * gdome_xml_cd_replaceData:
        !           563:  * @self:  The CharacterData Object ref
        !           564:  * @offset:  The offset from which to start replacing
        !           565:  * @count:  The number of 16-bit units to replace.
        !           566:  * @arg:  The String with which the range must be replaced
        !           567:  * @exc:  The GdomeException Object ref
        !           568:  *
        !           569:  * Replace the characters starting at the specified 16-bit unit @offset with
        !           570:  * the specified string. If the sum of @offset and @count exceeds length, then
        !           571:  * all 16-bit units to the end of the data are replaced;
        !           572:  *
        !           573:  * %GDOME_INDEX_SIZE_ERR: Raised if the specified @offset is greater than the
        !           574:  * number of 16-bit units in data.
        !           575:  * %GDOME_NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
        !           576:  */
        !           577: void
        !           578: gdome_xml_cd_replaceData (GdomeCharacterData *self, gulong offset, gulong count, GdomeDOMString *arg, GdomeException *exc)
        !           579: {
        !           580:  g_return_if_fail (self != NULL);
        !           581:  g_return_if_fail (GDOME_XML_IS_CD (self));
        !           582:  g_return_if_fail (arg != NULL);
        !           583:  g_return_if_fail (exc != NULL);
        !           584: 
        !           585:  gdome_xml_cd_deleteData (self, offset, count, exc);
        !           586:  if (*exc == 0) {
        !           587:    gdome_xml_cd_insertData (self, offset, arg, exc);
        !           588:     if (*exc == GDOME_INDEX_SIZE_ERR) {
        !           589:       *exc = 0;
        !           590:       gdome_xml_cd_appendData (self, arg, exc);
        !           591:     }
        !           592:  }
        !           593: }

E-mail: