| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| // |
| // Created by furture on 2018/5/15. |
| // |
| |
| #include "wson_parser.h" |
| #include "wson.h" |
| #include "wson_util.h" |
| |
| wson_parser::wson_parser(const char *data) { |
| |
| this->wsonBuffer = wson_buffer_from((void *) data, 1024*1024); |
| } |
| |
| wson_parser::wson_parser(const char *data, int length) { |
| this->wsonBuffer = wson_buffer_from((void *) data, length); |
| } |
| |
| wson_parser::~wson_parser() { |
| if(wsonBuffer){ |
| wsonBuffer->data = nullptr; |
| free(wsonBuffer); |
| wsonBuffer = NULL; |
| } |
| if(decodingBuffer != nullptr && decodingBufferSize > 0){ |
| delete [] decodingBuffer; |
| decodingBuffer = nullptr; |
| } |
| } |
| |
| std::string wson_parser::nextMapKeyUTF8(){ |
| int keyLength = wson_next_uint(wsonBuffer); |
| uint16_t * utf16 = ( uint16_t *)wson_next_bts(wsonBuffer, keyLength); |
| std::string str; |
| wson::utf16_convert_to_utf8_string(utf16, keyLength/sizeof(uint16_t), requireDecodingBuffer(keyLength*2), str); |
| return str; |
| } |
| |
| |
| |
| char* wson_parser::requireDecodingBuffer(int length){ |
| if(decodingBufferSize <= 0 || decodingBufferSize < length){ |
| if(decodingBuffer != nullptr && decodingBufferSize > 0){ |
| delete [] decodingBuffer; |
| decodingBuffer = nullptr; |
| } |
| decodingBuffer = new char[length]; |
| decodingBufferSize = length; |
| }else{ |
| return decodingBuffer; |
| } |
| return decodingBuffer; |
| } |
| |
| |
| void wson_parser::toJSONtring(std::string &builder){ |
| uint8_t type = wson_next_type(wsonBuffer); |
| switch (type) { |
| case WSON_UINT8_STRING_TYPE: { |
| int size = wson_next_uint(wsonBuffer); |
| uint8_t *utf8 = wson_next_bts(wsonBuffer, size); |
| builder.append(reinterpret_cast<char*>(utf8), size); |
| } |
| return; |
| case WSON_STRING_TYPE: |
| case WSON_NUMBER_BIG_INT_TYPE: |
| case WSON_NUMBER_BIG_DECIMAL_TYPE: { |
| int size = wson_next_uint(wsonBuffer); |
| uint16_t *utf16 = (uint16_t *) wson_next_bts(wsonBuffer, size); |
| wson::utf16_convert_to_utf8_quote_string(utf16, size / sizeof(uint16_t), requireDecodingBuffer(size*2), builder); |
| } |
| return; |
| case WSON_NULL_TYPE: |
| builder.append("\"\""); |
| break; |
| case WSON_NUMBER_INT_TYPE: { |
| int32_t num = wson_next_int(wsonBuffer); |
| wson::str_append_number(builder, num); |
| } |
| return; |
| case WSON_NUMBER_FLOAT_TYPE: { |
| float num = wson_next_float(wsonBuffer); |
| wson::str_append_number(builder, num); |
| } |
| return; |
| case WSON_NUMBER_DOUBLE_TYPE: { |
| double num = wson_next_double(wsonBuffer); |
| wson::str_append_number(builder, num); |
| } |
| return; |
| case WSON_NUMBER_LONG_TYPE: { |
| int64_t num = wson_next_long(wsonBuffer); |
| wson::str_append_number(builder, num); |
| } |
| return; |
| case WSON_BOOLEAN_TYPE_TRUE: |
| builder.append("true"); |
| return; |
| case WSON_BOOLEAN_TYPE_FALSE: |
| builder.append("false"); |
| return; |
| case WSON_MAP_TYPE:{ |
| int length = wson_next_uint(wsonBuffer); |
| builder.append("{"); |
| for(int i=0; i<length; i++){ |
| int keyLength = wson_next_uint(wsonBuffer); |
| uint16_t * utf16 = ( uint16_t *)wson_next_bts(wsonBuffer, keyLength); |
| wson::utf16_convert_to_utf8_quote_string(utf16, keyLength/sizeof(uint16_t), requireDecodingBuffer(keyLength*2), builder); |
| builder.append(":"); |
| toJSONtring(builder); |
| if(i != (length - 1)){ |
| builder.append(","); |
| } |
| } |
| builder.append("}"); |
| } |
| return; |
| case WSON_ARRAY_TYPE:{ |
| builder.append("["); |
| int length = wson_next_uint(wsonBuffer); |
| for(int i=0; i<length; i++){ |
| toJSONtring(builder); |
| if(i != (length - 1)){ |
| builder.append(","); |
| } |
| } |
| builder.append("]"); |
| } |
| return; |
| default: |
| break; |
| } |
| } |
| |
| std::string wson_parser::nextStringUTF8(uint8_t type) { |
| std::string str; |
| switch (type) { |
| case WSON_UINT8_STRING_TYPE: { |
| int size = wson_next_uint(wsonBuffer); |
| uint8_t *utf8 = wson_next_bts(wsonBuffer, size); |
| str.append(reinterpret_cast<char *>(utf8), size); |
| return str; |
| } |
| case WSON_STRING_TYPE: |
| case WSON_NUMBER_BIG_INT_TYPE: |
| case WSON_NUMBER_BIG_DECIMAL_TYPE: { |
| int size = wson_next_uint(wsonBuffer); |
| uint16_t *utf16 = (uint16_t *) wson_next_bts(wsonBuffer, size); |
| wson::utf16_convert_to_utf8_string(utf16, size / sizeof(uint16_t), requireDecodingBuffer(size*2), str); |
| return str; |
| } |
| case WSON_NULL_TYPE: |
| str.append(""); |
| break; |
| case WSON_NUMBER_INT_TYPE: { |
| int32_t num = wson_next_int(wsonBuffer);; |
| wson::str_append_number(str, num); |
| } |
| return str; |
| case WSON_NUMBER_FLOAT_TYPE: { |
| float num = wson_next_float(wsonBuffer); |
| wson::str_append_number(str, num); |
| } |
| return str; |
| case WSON_NUMBER_DOUBLE_TYPE: { |
| double num = wson_next_double(wsonBuffer); |
| wson::str_append_number(str, num); |
| } |
| return str; |
| case WSON_NUMBER_LONG_TYPE: { |
| int64_t num = wson_next_long(wsonBuffer); |
| wson::str_append_number(str, num); |
| } |
| return str; |
| case WSON_BOOLEAN_TYPE_TRUE: |
| str.append("true"); |
| return str; |
| case WSON_BOOLEAN_TYPE_FALSE: |
| str.append("false"); |
| return str; |
| case WSON_MAP_TYPE: |
| case WSON_ARRAY_TYPE: |
| wsonBuffer->position--; |
| toJSONtring(str); |
| default: |
| break; |
| } |
| return str; |
| } |
| |
| double wson_parser::nextNumber(uint8_t type) { |
| switch (type) { |
| case WSON_UINT8_STRING_TYPE: { |
| int size = wson_next_uint(wsonBuffer); |
| std::string str; |
| wson_next_bts(wsonBuffer, size); |
| uint8_t *utf8 = wson_next_bts(wsonBuffer, size); |
| str.append(reinterpret_cast<char *>(utf8), size); |
| return atof(str.c_str()); |
| } |
| case WSON_STRING_TYPE: |
| case WSON_NUMBER_BIG_INT_TYPE: |
| case WSON_NUMBER_BIG_DECIMAL_TYPE: { |
| int size = wson_next_uint(wsonBuffer); |
| std::string str; |
| wson_next_bts(wsonBuffer, size); |
| uint16_t *utf16 = (uint16_t *) wson_next_bts(wsonBuffer, size); |
| wson::utf16_convert_to_utf8_string(utf16, size/sizeof(uint16_t), requireDecodingBuffer(size*2),str); |
| return atof(str.c_str()); |
| } |
| case WSON_NULL_TYPE: |
| return 0; |
| case WSON_NUMBER_INT_TYPE:{ |
| int32_t num = wson_next_int(wsonBuffer); |
| return num; |
| } |
| break; |
| case WSON_NUMBER_FLOAT_TYPE:{ |
| float num = wson_next_float(wsonBuffer); |
| return num; |
| } |
| break; |
| case WSON_NUMBER_DOUBLE_TYPE:{ |
| double num = wson_next_double(wsonBuffer); |
| return num; |
| } |
| break; |
| case WSON_NUMBER_LONG_TYPE:{ |
| int64_t num = wson_next_long(wsonBuffer); |
| return num; |
| } |
| break; |
| case WSON_BOOLEAN_TYPE_TRUE: |
| return 1; |
| case WSON_BOOLEAN_TYPE_FALSE: |
| return 0; |
| case WSON_MAP_TYPE: |
| case WSON_ARRAY_TYPE: |
| default: |
| break; |
| } |
| skipValue(type); |
| return 0; |
| } |
| |
| bool wson_parser::nextBool(uint8_t type) { |
| if(type == WSON_BOOLEAN_TYPE_FALSE || type == WSON_NULL_TYPE){ |
| return false; |
| } |
| skipValue(type); |
| return true; |
| } |
| |
| void wson_parser::skipValue(uint8_t type) { |
| switch (type) { |
| case WSON_STRING_TYPE: |
| case WSON_UINT8_STRING_TYPE: |
| case WSON_NUMBER_BIG_INT_TYPE: |
| case WSON_NUMBER_BIG_DECIMAL_TYPE: { |
| int size = wson_next_uint(wsonBuffer); |
| wson_next_bts(wsonBuffer, size); |
| return; |
| } |
| case WSON_NULL_TYPE: |
| break; |
| case WSON_NUMBER_INT_TYPE: |
| wson_next_int(wsonBuffer); |
| return; |
| case WSON_NUMBER_FLOAT_TYPE: |
| wson_next_float(wsonBuffer); |
| return; |
| case WSON_NUMBER_DOUBLE_TYPE: |
| wson_next_double(wsonBuffer); |
| return; |
| case WSON_NUMBER_LONG_TYPE: |
| wson_next_long(wsonBuffer); |
| return; |
| case WSON_BOOLEAN_TYPE_TRUE: |
| return; |
| case WSON_BOOLEAN_TYPE_FALSE: |
| return; |
| case WSON_MAP_TYPE:{ |
| int length = wson_next_uint(wsonBuffer); |
| for(int i=0; i<length; i++){ |
| int keyLength = wson_next_uint(wsonBuffer); |
| wson_next_bts(wsonBuffer, keyLength); |
| skipValue(wson_next_type(wsonBuffer)); |
| } |
| } |
| return; |
| case WSON_ARRAY_TYPE:{ |
| int length = wson_next_uint(wsonBuffer); |
| for(int i=0; i<length; i++){ |
| skipValue(wson_next_type(wsonBuffer)); |
| } |
| } |
| return; |
| default: |
| break; |
| } |
| } |
| |
| |
| std::string wson_parser::toStringUTF8() { |
| int position = this->wsonBuffer->position; |
| this->wsonBuffer->position = 0; |
| std::string json = nextStringUTF8(nextType()); |
| this->wsonBuffer->position = position; |
| return json; |
| } |