VALUE xml_to_wbxml(VALUE self, VALUE xml_source) { WBXMLError ret = WBXML_OK; WBXMLConvXML2WBXMLParams params; WB_UTINY* xml = NULL; /* Must be null terminated */ WB_UTINY* wbxml = NULL; WB_ULONG wbxml_len = 0; VALUE value; Check_SafeStr(xml_source); if (TYPE(xml_source) != T_STRING) rb_raise(rb_eTypeError, "parameter to xml_to_wbxml must be a string"); xml = (WB_UTINY*)STR2CSTR(xml_source); params.wbxml_version = WBXML_VERSION_13; params.use_strtbl = TRUE; params.keep_ignorable_ws = FALSE; ret = wbxml_conv_xml2wbxml(xml, &wbxml, &wbxml_len, ¶ms); if (ret != WBXML_OK) rb_raise(rb_eRuntimeError, (const char*)wbxml_errors_string(ret)); value = rb_str_new((const char*)wbxml, wbxml_len); if (wbxml != NULL) wbxml_free(wbxml); return value; }
WBXML_DECLARE(void) wbxml_buffer_destroy(WBXMLBuffer *buffer) { if (buffer != NULL) { if (!buffer->is_static) { /* Free dynamic data */ wbxml_free(buffer->data); } /* Free structure */ wbxml_free(buffer); } }
WBXML_DECLARE(WBXMLBuffer *) wbxml_buffer_create_real(const WB_UTINY *data, WB_ULONG len, WB_ULONG malloc_block) { WBXMLBuffer *buffer = NULL; buffer = (WBXMLBuffer *) wbxml_malloc(sizeof(WBXMLBuffer)); if (buffer == NULL) return NULL; buffer->malloc_block = malloc_block; buffer->is_static = FALSE; if ((len <= 0) || (data == NULL)) { buffer->malloced = 0; buffer->len = 0; buffer->data = NULL; } else { if (len + 1 > malloc_block + 1) buffer->malloced = len + 1 + malloc_block; else buffer->malloced = malloc_block + 1; buffer->data = (WB_UTINY *) wbxml_malloc(buffer->malloced * sizeof(WB_UTINY)); if (buffer->data == NULL) { wbxml_free(buffer); return NULL; } buffer->len = len; memcpy(buffer->data, data, len); buffer->data[len] = '\0'; } return buffer; }
VALUE wbxml_to_xml(VALUE self, VALUE wbxml_source) { WBXMLError ret = WBXML_OK; WBXMLConvWBXML2XMLParams params; WB_UTINY* wbxml = NULL; WB_ULONG wbxml_len = 0; WB_UTINY* xml = NULL; /* Must be null terminated */ VALUE value; Check_SafeStr(wbxml_source); if (TYPE(wbxml_source) != T_STRING) rb_raise(rb_eTypeError, "parameter to wbxml_to_xml must be a string"); wbxml = (WB_UTINY*)STR2CSTR(wbxml_source); wbxml_len = RSTRING_LEN(wbxml_source); params.gen_type = WBXML_ENCODER_XML_GEN_INDENT; params.lang = WBXML_LANG_UNKNOWN; /* Don't force the language */ params.indent = 2; params.keep_ignorable_ws = FALSE; ret = wbxml_conv_wbxml2xml(wbxml, wbxml_len, &xml, ¶ms); if (ret != WBXML_OK) rb_raise(rb_eRuntimeError, (const char*)wbxml_errors_string(ret)); value = rb_str_new((const char*)xml, strlen(xml)); if (xml != NULL) wbxml_free(xml); return value; }
WBXML_DECLARE(WBXMLError) wbxml_buffer_encode_base64(WBXMLBuffer *buffer) { WB_UTINY *result = NULL; WBXMLError ret = WBXML_OK; if ( (buffer == NULL) || (buffer->is_static) ) { return WBXML_ERROR_INTERNAL; } if ((result = wbxml_base64_encode((const WB_UTINY *) wbxml_buffer_get_cstr(buffer), wbxml_buffer_len(buffer))) == NULL) { return WBXML_ERROR_B64_ENC; } /* Reset buffer */ wbxml_buffer_delete(buffer, 0, wbxml_buffer_len(buffer)); /* Set data */ if (!wbxml_buffer_append_cstr(buffer, result)) { ret = WBXML_ERROR_NOT_ENOUGH_MEMORY; } wbxml_free(result); return ret; }
WBXML_DECLARE(WBXMLError) wbxml_buffer_decode_base64(WBXMLBuffer *buffer) { WB_UTINY *result = NULL; WB_LONG len = 0; WBXMLError ret = WBXML_OK; if ( (buffer == NULL) || (buffer->is_static) ) { return WBXML_ERROR_INTERNAL; } wbxml_buffer_no_spaces(buffer); if ((len = wbxml_base64_decode((const WB_UTINY *) wbxml_buffer_get_cstr(buffer), wbxml_buffer_len(buffer), &result)) <= 0) { return WBXML_ERROR_B64_DEC; } /* Reset buffer */ wbxml_buffer_delete(buffer, 0, wbxml_buffer_len(buffer)); /* Set binary data */ if (!wbxml_buffer_append_data(buffer, result, len)) { ret = WBXML_ERROR_NOT_ENOUGH_MEMORY; } wbxml_free(result); return ret; }
/** * @brief Add space for at least 'size' octets * @param buffer The buffer * @param size The size to add * @return TRUE is space successfully reserved, FALSE is size was negative, buffer was NULL or if not enough memory */ static WB_BOOL grow_buff(WBXMLBuffer *buffer, WB_ULONG size) { // unsigned char *Srcbuff; if ((buffer == NULL) || buffer->is_static || ((int)size < 0)) return FALSE; /* Make room for the invisible terminating NUL */ size++; if ((buffer->len + size) > buffer->malloced) { if ((buffer->malloced + buffer->malloc_block) < (buffer->len + size)) buffer->malloced = buffer->len + size + buffer->malloc_block; else buffer->malloced = buffer->malloced + buffer->malloc_block; #if 1 //CSH1024. 2008 Tmp Fix 1 buffer->data = wbxml_realloc(buffer->data, buffer->malloced); #else Srcbuff = buffer->data; buffer->data = wbxml_malloc(buffer->malloced); memcpy(buffer->data, Srcbuff, buffer->len); wbxml_free(Srcbuff); #endif if (buffer->data == NULL) return FALSE; } return TRUE; }
/** * @brief Destroy a List Element * @param elt The element to destroy * @param destructor The Destructor Function to clean Element Item (can be NULL) */ static void wbxml_elt_destroy(WBXMLListElt *elt, WBXMLListEltCleaner *destructor) { if (elt == NULL) return; if (destructor != NULL) destructor(elt->item); wbxml_free(elt); }
WBXML_DECLARE(void) wbxml_tree_destroy(WBXMLTree *tree) { if (tree != NULL) { /* Destroy root node and all its children */ wbxml_tree_node_destroy_all(tree->root); /* Free tree */ wbxml_free(tree); } }
WBXML_DECLARE(void) wbxml_tree_node_destroy(WBXMLTreeNode *node) { if (node == NULL) return; wbxml_tag_destroy(node->name); wbxml_list_destroy(node->attrs, wbxml_attribute_destroy_item); wbxml_buffer_destroy(node->content); wbxml_tree_destroy(node->tree); wbxml_free(node); }
WBXML_DECLARE(void) wbxml_list_destroy(WBXMLList *list, WBXMLListEltCleaner *destructor) { WBXMLListElt *elt = NULL, *next = NULL; if (list == NULL) return; elt = list->head; while (elt != NULL) { next = elt->next; wbxml_elt_destroy(elt, destructor); elt = next; } wbxml_free(list); }
WBXML_DECLARE(WBXMLError) wbxml_charset_conv(const WB_TINY *in_buf, WB_ULONG *io_bytes, WBXMLCharsetMIBEnum in_charset, WBXMLBuffer **out_buf, WBXMLCharsetMIBEnum out_charset) { /************************************************** * First, check for simple US-ASCII / UTF-8 cases */ /* Are we dealing with US-ASCII or UTF-8 ? */ if (((in_charset == WBXML_CHARSET_US_ASCII) || (in_charset == WBXML_CHARSET_UTF_8)) && ((out_charset == WBXML_CHARSET_US_ASCII) || (out_charset == WBXML_CHARSET_UTF_8))) { /* Create a static buffer */ if ((*out_buf = wbxml_buffer_sta_create_from_cstr(in_buf)) == NULL) { return WBXML_ERROR_NOT_ENOUGH_MEMORY; } /* US-ASCII and UTF-8 are NULL terminated */ *io_bytes -= WBXML_STRLEN(in_buf) + 1; return WBXML_OK; } /************************************** * Ok guys, we really have to convert */ #if defined( HAVE_ICONV ) { /********************** * The iconv way */ const WB_TINY * inbuf_pos = NULL; WB_TINY **__restrict__ inbuf_ref = NULL; const WB_TINY * charset_to = NULL; const WB_TINY * charset_from = NULL; WB_TINY * tmp_buf = NULL; WB_TINY * tmp_ptr = NULL; WB_ULONG tmp_buf_len = 0; WB_ULONG tmp_len_left = 0; WBXMLError ret = WBXML_OK; iconv_t cd = 0; WB_UTINY last_char = 0; /* Get Charsets names */ if (!wbxml_charset_get_name(in_charset, &charset_from)) { return WBXML_ERROR_CHARSET_UNKNOWN; } if (!wbxml_charset_get_name(out_charset, &charset_to)) { return WBXML_ERROR_CHARSET_UNKNOWN; } /* Init iconv */ if ((cd = iconv_open(charset_to, charset_from)) == (iconv_t)(-1)) { /* Init failed */ return WBXML_ERROR_CHARSET_CONV_INIT; } /* Allocate maximum result buffer (4 bytes unicode) */ tmp_len_left = tmp_buf_len = 4 * (sizeof(WB_TINY) * (*io_bytes)); if ((tmp_buf = (WB_TINY *) wbxml_malloc(tmp_buf_len)) == NULL) { iconv_close(cd); return WBXML_ERROR_NOT_ENOUGH_MEMORY; } tmp_ptr = tmp_buf; /* The input buffer is const but not the pointer itself. The original const *inbuf should not be modified for a potential later usage. */ inbuf_pos = in_buf; inbuf_ref = (WB_TINY **__restrict__) &inbuf_pos; /* Convert ! */ (void) iconv(cd, inbuf_ref, (size_t*)io_bytes, &tmp_buf, (size_t*)&tmp_len_left); /** @todo Check errno (but it doesn't seems to work on windows) */ if (tmp_buf_len > tmp_len_left) { /* Create result buffer */ if ((*out_buf = wbxml_buffer_create(tmp_ptr, tmp_buf_len - tmp_len_left, tmp_buf_len - tmp_len_left)) == NULL) { /* Not enough memory */ ret = WBXML_ERROR_NOT_ENOUGH_MEMORY; } /* Remove trailing NULL char */ wbxml_buffer_remove_trailing_zeros(*out_buf); } else { /* Not converted */ ret = WBXML_ERROR_CHARSET_CONV; } /* Shutdown iconv */ iconv_close(cd); /* Clean-up */ wbxml_free(tmp_ptr); return ret; } #else { /*************************************************** * Add your own charset conversion function here ! */ return WBXML_ERROR_NO_CHARSET_CONV; } #endif /* HAVE_ICONV */ }
WB_LONG main(WB_LONG argc, WB_TINY **argv) { WB_UTINY *wbxml = NULL, *output = NULL, *xml = NULL; FILE *input_file = NULL, *output_file = NULL; WB_ULONG wbxml_len = 0; WB_LONG count = 0, xml_len = 0, total = 0; WB_TINY opt; WBXMLError ret = WBXML_OK; WB_UTINY input_buffer[INPUT_BUFFER_SIZE + 1]; WBXMLConvXML2WBXML *conv = NULL; ret = wbxml_conv_xml2wbxml_create(&conv); if (ret != WBXML_OK) { fprintf(stderr, "xml2wbxml failed: %s\n", wbxml_errors_string(ret)); goto clean_up; } while ((opt = (WB_TINY) wbxml_getopt(argc, argv, "nkah?o:v:")) != EOF) { switch (opt) { case 'v': wbxml_conv_xml2wbxml_set_version(conv, get_version((const WB_TINY*)optarg)); break; case 'n': wbxml_conv_xml2wbxml_disable_string_table(conv); break; case 'k': wbxml_conv_xml2wbxml_enable_preserve_whitespaces(conv); break; case 'a': wbxml_conv_xml2wbxml_disable_public_id(conv); break; case 'o': output = (WB_UTINY*) optarg; break; case 'h': case '?': default: help(); return 0; } } if (optind >= argc) { fprintf(stderr, "Missing arguments\n"); help(); return 0; } #ifdef WBXML_USE_LEAKTRACKER lt_init_mem(); lt_log_open_file("xml2wbxml.log"); lt_log(0, "\n***************************\n Converting file: %s", argv[optind]); #endif /********************************** * Read the XML Document */ if (WBXML_STRCMP(argv[optind], "-") == 0) { input_file = stdin; } else { /* Open XML document */ input_file = fopen(argv[optind], "r"); if (input_file == NULL) { printf("Failed to open %s\n", argv[optind]); goto clean_up; } } /* Read XML document */ while(!feof(input_file)) { count = fread(input_buffer, sizeof(WB_UTINY), INPUT_BUFFER_SIZE, input_file); if (ferror(input_file)) { fprintf(stderr, "Error while reading from file %s\n", argv[1]); if (input_file != stdin) fclose(input_file); if (xml != NULL) #ifdef WBXML_USE_LEAKTRACKER wbxml_free(xml); #else free(xml); #endif goto clean_up; } total += count; #ifdef WBXML_USE_LEAKTRACKER xml = wbxml_realloc(xml, total + 1); #else xml = realloc(xml, total + 1); #endif if (xml == NULL) { fprintf(stderr, "Not enought memory\n"); if (input_file != stdin) fclose(input_file); goto clean_up; } memcpy(xml + xml_len, input_buffer, count); xml_len += count; } if (input_file != stdin) fclose(input_file); xml[xml_len] = '\0'; /* Convert XML document */ ret = wbxml_conv_xml2wbxml_run(conv, xml, xml_len, &wbxml, &wbxml_len); if (ret != WBXML_OK) { fprintf(stderr, "xml2wbxml failed: %s\n", wbxml_errors_string(ret)); } else { fprintf(stderr, "xml2wbxml succeded\n"); if (output != NULL) { if (WBXML_STRCMP(output, "-") == 0) { output_file = stdout; } else { /* Open Output File */ output_file = fopen((const WB_TINY*) output, "wb"); } if (output_file == NULL) { fprintf(stderr, "Failed to open output file: %s\n", output); } else { /* Write to Output File */ if (fwrite(wbxml, sizeof(WB_UTINY), wbxml_len, output_file) < wbxml_len) fprintf(stderr, "Error while writing to file: %s\n", output); /* else fprintf(stderr, "Written %u bytes to file: %s\n", wbxml_len, output); */ if (output_file != stdout) fclose(output_file); } } /* Clean-up */ if (wbxml != NULL) #ifdef WBXML_USE_LEAKTRACKER wbxml_free(wbxml); #else free(wbxml); #endif } if (xml != NULL) #ifdef WBXML_USE_LEAKTRACKER wbxml_free(xml); #else free(xml); #endif clean_up: if (conv != NULL) wbxml_conv_xml2wbxml_destroy(conv); #ifdef WBXML_USE_LEAKTRACKER lt_check_leaks(); lt_shutdown_mem(); lt_log_close_file(); #endif return ret; }
WB_LONG main(WB_LONG argc, WB_TINY **argv) { WB_UTINY *wbxml = NULL, *output = NULL, *xml = NULL; FILE *input_file = NULL, *output_file = NULL; WB_LONG count = 0, wbxml_len = 0, total = 0; WB_ULONG xml_len = 0; WB_TINY opt; WBXMLError ret = WBXML_OK; WB_UTINY input_buffer[INPUT_BUFFER_SIZE + 1]; WBXMLGenXMLParams params; /* Init Default Parameters */ params.lang = WBXML_LANG_UNKNOWN; params.gen_type = WBXML_GEN_XML_INDENT; params.indent = 1; params.keep_ignorable_ws = FALSE; while ((opt = (WB_TINY) getopt(argc, argv, "kh?o:m:i:l:")) != EOF) { switch (opt) { case 'k': params.keep_ignorable_ws = TRUE; break; case 'i': params.indent = (WB_UTINY) atoi((const WB_TINY*)optarg); break; case 'l': params.lang = get_lang((const WB_TINY*)optarg); break; case 'm': switch (atoi((const WB_TINY*)optarg)) { case 0: params.gen_type = WBXML_GEN_XML_COMPACT; break; case 1: params.gen_type = WBXML_GEN_XML_INDENT; break; case 2: params.gen_type = WBXML_GEN_XML_CANONICAL; break; default: params.gen_type = WBXML_GEN_XML_INDENT; } break; case 'o': output = (WB_UTINY*) optarg; break; case 'h': case '?': default: help(); return 0; } } if (optind >= argc) { fprintf(stderr, "Missing arguments\n"); help(); return 0; } #ifdef WBXML_USE_LEAKTRACKER lt_init_mem(); lt_log_open_file("wbxml2xml.log"); lt_log(0, "\n***************************\n Converting file: %s", argv[optind]); #endif /********************************** * Read the WBXML Document */ if (WBXML_STRCMP(argv[optind], "-") == 0) { input_file = stdin; } else { /* Open WBXML document */ input_file = fopen(argv[optind], "rb"); if (input_file == NULL) { fprintf(stderr, "Failed to open %s\n", argv[optind]); goto clean_up; } } /* Read WBXML document */ while(!feof(input_file)) { count = fread(input_buffer, sizeof(WB_UTINY), INPUT_BUFFER_SIZE, input_file); if (ferror(input_file)) { fprintf(stderr, "Error while reading from file %s\n", argv[optind]); if (input_file != stdin) fclose(input_file); if (wbxml != NULL) wbxml_free(wbxml); goto clean_up; } total += count; wbxml = wbxml_realloc(wbxml, total); if (wbxml == NULL) { fprintf(stderr, "Not enought memory\n"); if (input_file != stdin) fclose(input_file); if (wbxml != NULL) wbxml_free(wbxml); goto clean_up; } memcpy(wbxml + wbxml_len, input_buffer, count); wbxml_len += count; } if (input_file != stdin) fclose(input_file); /* Convert WBXML document */ ret = wbxml_conv_wbxml2xml_withlen(wbxml, wbxml_len, &xml, &xml_len, ¶ms); if (ret != WBXML_OK) { fprintf(stderr, "wbxml2xml failed: %s\n", wbxml_errors_string(ret)); } else { /* fprintf(stderr, "wbxml2xml succeded: \n%s\n", xml); */ fprintf(stderr, "wbxml2xml succeded\n"); if (output != NULL) { if (WBXML_STRCMP(output, "-") == 0) { output_file = stdout; } else { /* Open Output File */ output_file = fopen((const WB_TINY*) output, "w"); } if (output_file == NULL) { fprintf(stderr, "Failed to open output file: %s\n", output); } /* Write to Output File */ if (fwrite(xml, sizeof(WB_UTINY), xml_len, output_file) < xml_len) fprintf(stderr, "Error while writing to file: %s\n", output); /* else fprintf(stderr, "Written %u bytes to file: %s\n", xml_len, output); */ if (output_file != stdout) fclose(output_file); } /* Clean-up */ wbxml_free(xml); } wbxml_free(wbxml); clean_up: #ifdef WBXML_USE_LEAKTRACKER lt_check_leaks(); lt_shutdown_mem(); lt_log_close_file(); #endif return 0; }