blob: 74edeb9af87c1db1f6dc94307220e9e1aa051564 [file] [log] [blame]
/**
* 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;
}