--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xml/cxmllibrary/src/encoder/src/domencoder.c Tue Aug 31 17:02:56 2010 +0300
@@ -0,0 +1,513 @@
+/*
+* Copyright (c) 2000 - 2001 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include "cxml_internal.h"
+#include <xml/cxml/nw_encoder_domencoder.h>
+#include <xml/cxml/nw_encoder_stringtable.h>
+#include <xml/cxml/nw_dom_element.h>
+#include <xml/cxml/nw_dom_text.h>
+#include <xml/cxml/nw_dom_attribute.h>
+
+/* ------------------------------------------------------------------------- *
+ private methods
+ * ------------------------------------------------------------------------- */
+
+/*
+* Encodes an Attribute Val
+* Returns NW_STAT_BAD_INPUT_PARAM
+* NW_STAT_OUT_OF_MEMORY
+* NW_STAT_SUCCESS
+*/
+/* ------------------------------------------------------------------------- */
+static
+NW_Status_t
+NW_Encoder_encodeAttrVal(NW_Encoder_t * encoder, NW_DOM_AttrVal_t *val)
+{
+ NW_Status_t status;
+
+ if ((encoder == NULL) || (val == NULL)){
+ return NW_STAT_BAD_INPUT_PARAM;
+ }
+ status = NW_STAT_SUCCESS;
+ switch(NW_DOM_AttrVal_getType(val))
+ {
+ case NW_DOM_ATTR_VAL_STRING:
+ {
+ status = NW_WBXML_Writer_Text(&encoder->writer, encoder->encoding,
+ val->component.string.length,
+ val->component.string.storage);
+ break;
+ }
+ case NW_DOM_ATTR_VAL_EXTENSION:
+ {
+ NW_Uint8 t; /* 8-bit token */
+ NW_String_t str;
+
+ t = (NW_Uint8)(val->component.ext.token);
+ if ((t == NW_WBXML_EXT_0)
+ || (t == NW_WBXML_EXT_1)
+ || (t == NW_WBXML_EXT_2)) {
+ status
+ = NW_WBXML_Writer_Extension(&encoder->writer,
+ (NW_Uint16)(val->component.ext.token),
+ 0, 0, NULL);
+ } else if ((t == NW_WBXML_EXT_T_0)
+ || (t == NW_WBXML_EXT_T_1)
+ || (t == NW_WBXML_EXT_T_2)) {
+ NW_ASSERT((val->component.ext.type
+ == NW_TINYDOM_EXTENSION_TYPE_NORMAL)
+ || (val->component.ext.type
+ == NW_TINYDOM_EXTENSION_TYPE_EXT_T_INTEGER));
+ if (val->component.ext.type == NW_TINYDOM_EXTENSION_TYPE_NORMAL) {
+ NW_Uint16 token = NW_DOM_TextItem_getExtension(val, &str);
+ status
+ = NW_WBXML_Writer_ExtensionUseStringTable(&encoder->writer,
+ token,
+ str.length,
+ str.storage);
+ } else {
+ status = NW_WBXML_Writer_Extension(&encoder->writer,
+ (NW_Uint16)(val->component.ext.token),
+ val->component.ext.value.x,
+ 0, NULL);
+ }
+ } else if ((t == NW_WBXML_EXT_I_0)
+ || (t == NW_WBXML_EXT_I_1)
+ || (t == NW_WBXML_EXT_I_2)) {
+ NW_Uint16 token = NW_DOM_TextItem_getExtension(val, &str);
+ status = NW_WBXML_Writer_Extension(&encoder->writer, token,
+ 0, str.length, str.storage);
+ } else {
+ status = NW_STAT_FAILURE;
+ }
+ break;
+ }
+ case NW_DOM_ATTR_VAL_ENTITY:
+ {
+ NW_Uint32 entity;
+ entity = NW_DOM_TextItem_getEntity(val);
+ status = NW_WBXML_Writer_Entity(&encoder->writer, entity);
+ break;
+ }
+ case NW_DOM_ATTR_VAL_OPAQUE:
+ {
+ NW_Uint32 length;
+ NW_Byte *data;
+ data = NW_DOM_AttrVal_getOpaque(val, &length);
+ status = NW_WBXML_Writer_Opaque(&encoder->writer, length, data);
+ break;
+ }
+ case NW_DOM_ATTR_VAL_TOKEN:
+ {
+ NW_Uint16 fqToken = NW_DOM_AttrVal_getToken(val);
+ status = NW_WBXML_Writer_AttributeToken(&encoder->writer, fqToken);
+ break;
+ }
+ default:
+ return NW_STAT_FAILURE;
+ }
+ return status;
+}
+
+/*
+* Encodes an attribute
+* Returns NW_STAT_BAD_INPUT_PARAM
+* NW_STAT_OUT_OF_MEMORY
+* NW_STAT_SUCCESS
+*/
+/* ------------------------------------------------------------------------- */
+static
+NW_Status_t
+NW_Encoder_encodeAttribute(NW_Encoder_t * encoder,
+ NW_DOM_AttributeHandle_t * attrHandle)
+{
+ NW_Status_t status;
+ NW_DOM_AttrVal_t attrVal;
+ NW_Uint16 fqToken = 0;
+ NW_Uint8 token = 0;
+ NW_Ucs2 c;
+ NW_Uint32 numbytes;
+
+ fqToken = NW_DOM_AttributeHandle_getToken(attrHandle);
+
+ if ((encoder == NULL) || (attrHandle == NULL)){
+ return NW_STAT_BAD_INPUT_PARAM;
+ }
+ token = (NW_Uint8)(fqToken & NW_WBXML_MASK_TOKEN);
+
+ if (token == NW_WBXML_LITERAL)
+ {
+ NW_String_t attributeName;
+ if (NW_DOM_AttributeHandle_getName(attrHandle, &attributeName)
+ != NW_STAT_SUCCESS){
+ return NW_STAT_FAILURE;
+ }
+
+ numbytes = NW_String_readChar(attributeName.storage, &c, encoder->encoding);
+
+ status = NW_WBXML_Writer_AttributeNameString(&encoder->writer,
+ encoder->encoding,
+ (attributeName.length - numbytes)/numbytes,
+ attributeName.length,
+ attributeName.storage);
+ }
+ else{
+ status = NW_WBXML_Writer_AttributeToken(&encoder->writer, fqToken);
+ }
+
+ while (NW_DOM_AttributeHandle_getNextVal(attrHandle, &attrVal)
+ == NW_STAT_WBXML_ITERATE_MORE)
+ {
+ status = NW_Encoder_encodeAttrVal(encoder, &attrVal);
+ if (status != NW_STAT_SUCCESS)
+ return status;
+ }
+ return NW_STAT_SUCCESS;
+}
+
+/*
+* Encodes an element node
+* Returns NW_STAT_BAD_INPUT_PARAM
+* NW_STAT_OUT_OF_MEMORY
+* NW_STAT_SUCCESS
+*/
+/* ------------------------------------------------------------------------- */
+static
+NW_Status_t
+NW_Encoder_encodeElementNode(NW_Encoder_t * encoder, NW_DOM_ElementNode_t * e)
+{
+ NW_Status_t status;
+ NW_DOM_AttributeListIterator_t listIterator;
+ NW_DOM_AttributeHandle_t attrHandle;
+ NW_Uint16 fqToken;
+ NW_Uint8 token;
+ NW_Uint32 tagIndex;
+ NW_Int32 charCount;
+
+ if ((encoder == NULL) || (e == NULL)){
+ return NW_STAT_BAD_INPUT_PARAM;
+ }
+ fqToken = NW_DOM_ElementNode_getTagToken(e);
+ token = (NW_Uint8)(fqToken & NW_WBXML_MASK_TOKEN);
+ if (token == NW_WBXML_LITERAL)
+ {
+ NW_String_t elementName;
+
+ if (NW_DOM_ElementNode_getTagName(e, &elementName) != NW_STAT_SUCCESS){
+ return NW_STAT_FAILURE;
+ }
+
+ /*Get the char count */
+
+ charCount = NW_String_charBuffGetLength(elementName.storage,
+ encoder->encoding,
+ &(elementName.length) );
+
+ status = NW_WBXML_Writer_TagString(&encoder->writer, encoder->encoding, charCount,
+ elementName.length, elementName.storage, &tagIndex);
+ /* Do not free literal element here as this will be freed when literal table
+ * will be freed.
+ */
+
+ // NW_String_delete(&elementName);
+ }
+ else{
+ status = NW_WBXML_Writer_TagToken(&encoder->writer, fqToken, &tagIndex);
+ NW_ASSERT(status == NW_STAT_SUCCESS);
+ }
+
+ if (NW_DOM_Node_getFirstChild(e)){
+ status = NW_WBXML_Writer_TagSetContentFlag(&encoder->writer, tagIndex);
+ NW_ASSERT(status == NW_STAT_SUCCESS);
+ }
+ if (NW_DOM_ElementNode_hasAttributes(e)){
+ status = NW_WBXML_Writer_TagSetAttributesFlag(&encoder->writer, tagIndex);
+ NW_ASSERT(status == NW_STAT_SUCCESS);
+ }
+
+ if (status != NW_STAT_SUCCESS){
+ return status;
+ }
+
+ if (NW_DOM_ElementNode_hasAttributes(e))
+ {
+ status = NW_DOM_ElementNode_getAttributeListIterator(e, &listIterator);
+ if (status != NW_STAT_SUCCESS){
+ return status;
+ }
+ while (NW_DOM_AttributeListIterator_getNextAttribute(&listIterator, &attrHandle)
+ == NW_STAT_WBXML_ITERATE_MORE)
+ {
+ NW_Encoder_encodeAttribute(encoder, &attrHandle);
+ }
+ return NW_WBXML_Writer_End(&encoder->writer);
+ }
+ return NW_STAT_SUCCESS;
+}
+
+/*
+* Encodes a TextNode
+* Returns NW_STAT_BAD_INPUT_PARAM
+* NW_STAT_OUT_OF_MEMORY
+* NW_STAT_SUCCESS
+*/
+/* ------------------------------------------------------------------------- */
+static
+NW_Status_t
+NW_Encoder_encodeTextNode (NW_Encoder_t * encoder, NW_DOM_TextNode_t * textNode)
+{
+ NW_DOM_TextItemIterator_t textIter;
+ NW_DOM_TextItem_t item;
+ NW_Status_t status;
+
+ if ((encoder == NULL) || (textNode == NULL))
+ return NW_STAT_BAD_INPUT_PARAM;
+
+ status = NW_DOM_TextNode_getTextItemIterator(textNode, &textIter);
+ while (NW_DOM_TextItemIterator_getNextTextItem(&textIter, &item)
+ == NW_STAT_WBXML_ITERATE_MORE)
+ {
+ status = NW_Encoder_encodeAttrVal(encoder, &item);
+ if (status != NW_STAT_SUCCESS){
+ return status;
+ }
+ }
+ return NW_STAT_SUCCESS;
+}
+
+/*
+* Encodes a Node (recursive)
+* Returns NW_STAT_BAD_INPUT_PARAM
+* NW_STAT_OUT_OF_MEMORY
+* NW_STAT_SUCCESS
+*/
+/* ------------------------------------------------------------------------- */
+static
+NW_Status_t
+NW_Encoder_encodeNode(NW_Encoder_t * encoder, NW_DOM_Node_t *node)
+{
+ NW_Uint32 type = NW_DOM_Node_getNodeType(node);
+
+ if ((encoder == NULL) || (node == NULL))
+ return NW_STAT_BAD_INPUT_PARAM;
+
+ switch (type)
+ {
+ case NW_DOM_ELEMENT_NODE:
+ {
+ NW_Encoder_encodeElementNode(encoder, node);
+ if (NW_DOM_Node_getFirstChild(node))
+ {
+ NW_Encoder_encodeNode(encoder, NW_DOM_Node_getFirstChild(node));
+ /* Encode the tag terminator */
+ NW_WBXML_Writer_End(&encoder->writer);
+ }
+ if (NW_DOM_Node_getNextSibling(node))
+ NW_Encoder_encodeNode(encoder, NW_DOM_Node_getNextSibling(node));
+ }
+ break;
+
+ case NW_DOM_TEXT_NODE:
+ NW_Encoder_encodeTextNode(encoder, node);
+
+ if (NW_DOM_Node_getNextSibling(node)){
+ NW_Encoder_encodeNode (encoder, NW_DOM_Node_getNextSibling(node));
+ }
+ break;
+
+ case NW_DOM_PROCESSING_INSTRUCTION_NODE:
+ /* TODO: Pi Node support code */
+ if (NW_DOM_Node_getNextSibling(node))
+ NW_Encoder_encodeNode (encoder, NW_DOM_Node_getNextSibling(node));
+
+ break;
+
+ default:
+ if (NW_DOM_Node_getNextSibling(node))
+ NW_Encoder_encodeNode (encoder, NW_DOM_Node_getNextSibling(node));
+ }
+ return NW_STAT_SUCCESS;
+}
+
+/*
+* Encodes the header of document (version, publicid, docType, charset,
+* and string table
+* Returns NW_STAT_BAD_INPUT_PARAM
+* NW_STAT_OUT_OF_MEMORY
+* NW_STAT_SUCCESS
+*/
+/* ------------------------------------------------------------------------- */
+NW_Status_t
+NW_Encoder_encodeDocHeader(NW_Encoder_t * encoder, NW_DOM_DocumentNode_t * doc)
+{
+ NW_Uint8 version;
+ NW_Uint32 publicid;
+ NW_Uint32 byteLength;
+
+ version = NW_DOM_DocumentNode_getVersion(doc);
+ publicid = NW_DOM_DocumentNode_getPublicIdAsNumber(doc);
+ if (encoder->enableStringTable == NW_TRUE) {
+ byteLength = NW_Encoder_StringTable_getTotalBytes(encoder->stringTable);
+ } else {
+ byteLength = 0;
+ }
+
+ /* This call also encodes the string table, if any is used. */
+ return NW_WBXML_Writer_Header(&encoder->writer, version, publicid,
+ encoder->encoding, byteLength);
+}
+
+/* ------------------------------------------------------------------------- *
+ public methods
+ * ------------------------------------------------------------------------- */
+
+/*
+* Initializes an encoder
+* Returns NW_STAT_BAD_INPUT_PARAM
+* NW_STAT_OUT_OF_MEMORY
+* NW_STAT_SUCCESS
+*/
+/* ------------------------------------------------------------------------- */
+NW_Status_t
+NW_Encoder_initialize(NW_Encoder_t *encoder, NW_Bool enableStringTable)
+{
+ if (encoder == NULL){
+ return NW_STAT_BAD_INPUT_PARAM;
+ }
+ encoder->encoding = 0;
+ encoder->enableStringTable = enableStringTable;
+ encoder->stringTable = NULL;
+ if (enableStringTable == NW_TRUE) {
+ encoder->stringTable = NW_Encoder_StringTable_new();
+ if (encoder->stringTable == NULL) {
+ return NW_STAT_OUT_OF_MEMORY;
+ }
+ }
+ return NW_STAT_SUCCESS;
+}
+
+/*
+* Encodes the DOM document represented by document node
+* Returns NW_STAT_BAD_INPUT_PARAM
+* NW_STAT_OUT_OF_MEMORY
+* NW_STAT_SUCCESS
+*/
+/* ------------------------------------------------------------------------- */
+EXPORT_C NW_Status_t
+NW_Encoder_encodeWBXML(NW_Encoder_t* encoder,
+ NW_DOM_DocumentNode_t * docNode,
+ NW_Bool enableStringTable,
+ NW_Uint32 *length,
+ NW_Byte **buffer)
+{
+ NW_Status_t status;
+ NW_DOM_ElementNode_t *elem;
+ NW_Uint32 publicid;
+ NW_WBXML_Dictionary_t* dictionary;
+
+ if ((encoder == NULL) || (docNode == NULL)){
+ return NW_STAT_BAD_INPUT_PARAM;
+ }
+
+ status = NW_Encoder_initialize(encoder, enableStringTable);
+ if (status != NW_STAT_SUCCESS){
+ return status;
+ }
+
+ encoder->encoding = NW_DOM_DocumentNode_getCharacterEncoding(docNode);
+ elem = NW_DOM_DocumentNode_getDocumentElement(docNode);
+ publicid = NW_DOM_DocumentNode_getPublicIdAsNumber(docNode);
+
+ /* initialize WBXMLWriter */
+ if (publicid != 0){
+ dictionary = NW_WBXML_Dictionary_getByPublicId(publicid);
+ }
+ else
+ {
+ NW_String_t docType;
+
+ status = NW_DOM_DocumentNode_getPublicId(docNode, &docType);
+ if (status != NW_STAT_SUCCESS){
+ return status;
+ }
+ dictionary = NW_WBXML_Dictionary_getByDocType(&docType, encoder->encoding);
+ }
+ if (enableStringTable == NW_TRUE) {
+ /* assuming that same dictionary is used for both attributes and tags */
+ status = NW_Encoder_StringTable_createFromDOM(encoder->stringTable,
+ docNode,
+ dictionary);
+ if (status != NW_STAT_SUCCESS){
+ return status;
+ }
+ }
+
+ /* Set up the writer for a sizing pass */
+ NW_WBXML_Writer_SetToSizing(&encoder->writer);
+
+ NW_WBXML_Writer_Initialize(&encoder->writer,
+ 0,
+ NULL,
+ NULL,
+ dictionary,
+ dictionary,
+ ((enableStringTable == NW_TRUE) ?
+ NW_Encoder_StringTable_getStringTableOffset :
+ NULL),
+ ((enableStringTable == NW_TRUE) ?
+ NW_Encoder_StringTable_addToStringTable :
+ NULL),
+ ((enableStringTable == NW_TRUE) ?
+ encoder->stringTable :
+ NULL),
+ ((enableStringTable == NW_TRUE) ?
+ NW_Encoder_StringTable_StringTableIterateInit :
+ NULL),
+ ((enableStringTable == NW_TRUE) ?
+ NW_Encoder_StringTable_StringTableIterateNext :
+ NULL),
+ NW_TRUE /* sizing only */);
+
+ status = NW_Encoder_encodeDocHeader(encoder, docNode);
+ if (status != NW_STAT_SUCCESS){
+ return status;
+ }
+ status = NW_Encoder_encodeNode(encoder, elem);
+
+ /* Allocate a buffer of the correct size */
+ *length = (CXML_Vector_Metric_t)NW_WBXML_Writer_GetSize(&encoder->writer);
+ *buffer = (NW_Byte*)NW_Mem_Malloc(*length);
+
+ if (*buffer == NULL){
+ return NW_STAT_OUT_OF_MEMORY;
+ }
+
+ /* Set up the writer for a writing pass */
+ NW_WBXML_Writer_SetToWrite(&encoder->writer, *length, *buffer);
+
+ status = NW_Encoder_encodeDocHeader(encoder, docNode);
+ if (status != NW_STAT_SUCCESS){
+ return status;
+ }
+ status = NW_Encoder_encodeNode(encoder, elem);
+ NW_ASSERT(status == NW_STAT_SUCCESS);
+
+ NW_Encoder_StringTable_delete(encoder->stringTable);
+ return NW_STAT_SUCCESS;
+}
+