📄 wap_push_si_compiler.c
字号:
/* ==================================================================== * The Kannel Software License, Version 1.0 * * Copyright (c) 2001-2004 Kannel Group * Copyright (c) 1998-2001 WapIT Ltd. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Kannel Group (http://www.kannel.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Kannel" and "Kannel Group" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please * contact org@kannel.org. * * 5. Products derived from this software may not be called "Kannel", * nor may "Kannel" appear in their name, without prior written * permission of the Kannel Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Kannel Group. For more information on * the Kannel Group, please see <http://www.kannel.org/>. * * Portions of this software are based upon software originally written at * WapIT Ltd., Helsinki, Finland for the Kannel project. */ /* * wap_push_si_compiler.c: Tokenizes a SI document. SI DTD is defined in * Wapforum specification WAP-167-ServiceInd-20010731-a (hereafter called si), * chapter 8.2. * * By Aarno Syv鋘en for Wiral Ltd */#include <ctype.h>#include <libxml/xmlmemory.h>#include <libxml/tree.h>#include <libxml/debugXML.h>#include <libxml/encoding.h>#include "shared.h"#include "xml_shared.h"#include "wap_push_si_compiler.h"/**************************************************************************** * * Global variables * * Two token table types, one and two token fields */struct si_2table_t { char *name; unsigned char token;};typedef struct si_2table_t si_2table_t;/* * Value part can mean part or whole of the value. It can be NULL, too, which * means that no part of the value will be tokenised. See si, chapter 9.3.2. */struct si_3table_t { char *name; char *value_part; unsigned char token;};typedef struct si_3table_t si_3table_t;/* * Elements from tag code page zero. These are defined in si, chapter 9.3.1. */static si_2table_t si_elements[] = { { "si", 0x05 }, { "indication", 0x06 }, { "info", 0x07 }, { "item", 0x08 }};#define NUMBER_OF_ELEMENTS sizeof(si_elements)/sizeof(si_elements[0])/* * Attributes (and start or whole value of ) from attribute code page zero. * These are defined in si, chapter 9.3.2. */static si_3table_t si_attributes[] = { { "action", "signal-none", 0x05 }, { "action", "signal-low", 0x06 }, { "action", "signal-medium", 0x07 }, { "action", "signal-high", 0x08 }, { "action", "delete", 0x09 }, { "created", NULL, 0x0a }, { "href", "https://www.", 0x0f }, { "href", "http://www.", 0x0d }, { "href", "https://", 0x0e }, { "href", "http://", 0x0c }, { "href", NULL, 0x0b }, { "si-expires", NULL, 0x10 }, { "si-id", NULL, 0x11 }, { "class", NULL, 0x12 }};#define NUMBER_OF_ATTRIBUTES sizeof(si_attributes)/sizeof(si_attributes[0])/* * Attribute value tokes (URL value codes), from si, chapter 9.3.3. */static si_2table_t si_URL_values[] = { { ".com/", 0x85 }, { ".edu/", 0x86 }, { ".net/", 0x87 }, { ".org/", 0x88 }};#define NUMBER_OF_URL_VALUES sizeof(si_URL_values)/sizeof(si_URL_values[0])#include "xml_definitions.h"/**************************************************************************** * * Prototypes of internal functions. Note that 'Ptr' means here '*'. */static int parse_document(xmlDocPtr document, Octstr *charset, simple_binary_t **si_binary);static int parse_node(xmlNodePtr node, simple_binary_t **sibxml); static int parse_element(xmlNodePtr node, simple_binary_t **sibxml);static int parse_text(xmlNodePtr node, simple_binary_t **sibxml); static int parse_cdata(xmlNodePtr node, simple_binary_t **sibxml); static int parse_attribute(xmlAttrPtr attr, simple_binary_t **sibxml); static int url(int hex); static int action(int hex);static int date(int hex);static Octstr *tokenize_date(Octstr *date);static void octstr_drop_trailing_zeros(Octstr **date_token);static void flag_date_length(Octstr **token);static void parse_url_value(Octstr *value, simple_binary_t **sibxml); /**************************************************************************** * * Implementation of the external function */int si_compile(Octstr *si_doc, Octstr *charset, Octstr **si_binary){ simple_binary_t *sibxml; int ret; xmlDocPtr pDoc; size_t size; char *si_c_text; *si_binary = octstr_create(""); sibxml = simple_binary_create(); octstr_strip_blanks(si_doc); set_charset(si_doc, charset); size = octstr_len(si_doc); si_c_text = octstr_get_cstr(si_doc); pDoc = xmlParseMemory(si_c_text, size); ret = 0; if (pDoc) { ret = parse_document(pDoc, charset, &sibxml); simple_binary_output(*si_binary, sibxml); xmlFreeDoc(pDoc); } else { xmlFreeDoc(pDoc); octstr_destroy(*si_binary); simple_binary_destroy(sibxml); error(0, "SI: No document to parse. Probably an error in SI source"); return -1; } simple_binary_destroy(sibxml); return ret;}/**************************************************************************** * * Implementation of internal functions * * Parse document node. Store si version number, public identifier and char- * acter set into the start of the document. FIXME: Add parse_prologue! */static int parse_document(xmlDocPtr document, Octstr *charset, simple_binary_t **sibxml){ xmlNodePtr node; (*sibxml)->wbxml_version = 0x02; /* WBXML Version number 1.2 */ (*sibxml)->public_id = 0x05; /* SI 1.0 Public ID */ charset = octstr_create("UTF-8"); (*sibxml)->charset = parse_charset(charset); octstr_destroy(charset); node = xmlDocGetRootElement(document); return parse_node(node, sibxml);}/* * Parse an element node. Check if there is a token for an element tag; if not * output the element as a string, else ouput the token. After that, call * attribute parsing functions * Returns: 1, add an end tag (element node has no children) * 0, do not add an end tag (it has children) * -1, an error occurred */static int parse_element(xmlNodePtr node, simple_binary_t **sibxml){ Octstr *name, *outos; size_t i; unsigned char status_bits, si_hex; int add_end_tag; xmlAttrPtr attribute; name = octstr_create(node->name); outos = NULL; if (octstr_len(name) == 0) { octstr_destroy(name); return -1; } i = 0; while (i < NUMBER_OF_ELEMENTS) { if (octstr_compare(name, octstr_imm(si_elements[i].name)) == 0) break; ++i; } status_bits = 0x00; si_hex = 0x00; add_end_tag = 0; if (i != NUMBER_OF_ELEMENTS) { si_hex = si_elements[i].token; if ((status_bits = element_check_content(node)) > 0) { si_hex = si_hex | status_bits; if ((status_bits & WBXML_CONTENT_BIT) == WBXML_CONTENT_BIT) add_end_tag = 1; } output_char(si_hex, sibxml); } else { warning(0, "unknown tag %s in SI source", octstr_get_cstr(name)); si_hex = WBXML_LITERAL; if ((status_bits = element_check_content(node)) > 0) { si_hex = si_hex | status_bits; /* If this node has children, the end tag must be added after them. */ if ((status_bits & WBXML_CONTENT_BIT) == WBXML_CONTENT_BIT) add_end_tag = 1; } output_char(si_hex, sibxml); output_octet_string(outos = octstr_duplicate(name), sibxml); } if (node->properties != NULL) { attribute = node->properties; while (attribute != NULL) { parse_attribute(attribute, sibxml); attribute = attribute->next; } parse_end(sibxml); } octstr_destroy(outos); octstr_destroy(name); return add_end_tag;}/* * Parse a text node of a si document. Ignore empty text nodes (space addi- * tions to certain points will produce these). Si codes text nodes as an * inline string. */static int parse_text(xmlNodePtr node, simple_binary_t **sibxml){ Octstr *temp; temp = create_octstr_from_node(node); octstr_shrink_blanks(temp); octstr_strip_blanks(temp); if (octstr_len(temp) == 0) { octstr_destroy(temp); return 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -