/**
|
/*
|
* @file
|
* Copyright 2018 Sergey Khabarov, sergeykhbr@gmail.com
|
* @copyright Copyright 2016 GNSS Sensor Ltd. All right reserved.
|
*
|
* @author Sergey Khabarov - sergeykhbr@gmail.com
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
* @brief Core attribute methods implementation.
|
* 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.
|
*/
|
*/
|
|
|
#include "api_core.h"
|
#include <attribute.h>
|
#include "autobuffer.h"
|
#include <api_core.h>
|
#include "iservice.h"
|
#include <autobuffer.h>
|
#include "api_utils.h"
|
#include <iservice.h>
|
|
#include <api_utils.h>
|
#include <cstdlib>
|
#include <cstdlib>
|
|
#include <string>
|
|
#include <algorithm>
|
|
|
namespace debugger {
|
namespace debugger {
|
|
|
static const int64_t MIN_ALLOC_BYTES = 1 << 12;
|
static const int64_t MIN_ALLOC_BYTES = 1 << 12;
|
static AttributeType NilAttribute;
|
static AttributeType NilAttribute;
|
static AutoBuffer strBuffer;
|
|
|
|
char *attribute_to_string(const AttributeType *attr);
|
void attribute_to_string(const AttributeType *attr, AutoBuffer *buf);
|
int string_to_attribute(const char *cfg, int &off, AttributeType *out);
|
int string_to_attribute(const char *cfg, int &off, AttributeType *out);
|
|
|
|
void AttributeType::allocAttrName(const char *name) {
|
|
size_t len = strlen(name) + 1;
|
|
attr_name_ = static_cast<char *>(RISCV_malloc(len));
|
|
memcpy(attr_name_, name, len);
|
|
}
|
|
|
|
void AttributeType::freeAttrName() {
|
|
if (attr_name_) {
|
|
RISCV_free(attr_name_);
|
|
}
|
|
}
|
|
|
|
void AttributeType::allocAttrDescription(const char *descr) {
|
|
size_t len = strlen(descr) + 1;
|
|
attr_descr_ = static_cast<char *>(RISCV_malloc(len));
|
|
memcpy(attr_descr_, descr, len);
|
|
}
|
|
|
|
void AttributeType::freeAttrDescription() {
|
|
if (attr_descr_) {
|
|
RISCV_free(attr_descr_);
|
|
}
|
|
}
|
|
|
void AttributeType::attr_free() {
|
void AttributeType::attr_free() {
|
if (size()) {
|
if (size()) {
|
if (is_string()) {
|
if (is_string()) {
|
RISCV_free(u_.string);
|
RISCV_free(u_.string);
|
} else if (is_data() && size() > 8) {
|
} else if (is_data() && size() > 8) {
|
RISCV_free(u_.data);
|
RISCV_free(u_.data);
|
} else if (is_list()) {
|
} else if (is_list()) {
|
for (unsigned i = 0; i < size(); i++) {
|
for (unsigned i = 0; i < size(); i++) {
|
u_.list[i].attr_free();
|
u_.list[i].attr_free();
|
}
|
}
|
RISCV_free(u_.list);
|
RISCV_free(u_.list);
|
} else if (is_dict()) {
|
} else if (is_dict()) {
|
for (unsigned i = 0; i < size(); i++) {
|
for (unsigned i = 0; i < size(); i++) {
|
u_.dict[i].key_.attr_free();
|
u_.dict[i].key_.attr_free();
|
u_.dict[i].value_.attr_free();
|
u_.dict[i].value_.attr_free();
|
}
|
}
|
RISCV_free(u_.dict);
|
RISCV_free(u_.dict);
|
}
|
}
|
}
|
}
|
kind_ = Attr_Invalid;
|
kind_ = Attr_Invalid;
|
size_ = 0;
|
size_ = 0;
|
u_.integer = 0;
|
u_.integer = 0;
|
}
|
}
|
|
|
void AttributeType::clone(const AttributeType *v) {
|
void AttributeType::clone(const AttributeType *v) {
|
attr_free();
|
attr_free();
|
|
|
if (v->is_string()) {
|
if (v->is_string()) {
|
this->make_string(v->to_string());
|
this->make_string(v->to_string());
|
} else if (v->is_data()) {
|
} else if (v->is_data()) {
|
this->make_data(v->size(), v->data());
|
this->make_data(v->size(), v->data());
|
} else if (v->is_list()) {
|
} else if (v->is_list()) {
|
make_list(v->size());
|
make_list(v->size());
|
for (unsigned i = 0; i < v->size(); i++ ) {
|
for (unsigned i = 0; i < v->size(); i++) {
|
u_.list[i].clone(v->list(i));
|
u_.list[i].clone(v->list(i));
|
}
|
}
|
} else if (v->is_dict()) {
|
} else if (v->is_dict()) {
|
make_dict();
|
make_dict();
|
realloc_dict(v->size());
|
realloc_dict(v->size());
|
for (unsigned i = 0; i < v->size(); i++ ) {
|
for (unsigned i = 0; i < v->size(); i++) {
|
u_.dict[i].key_.make_string(v->dict_key(i)->to_string());
|
u_.dict[i].key_.make_string(v->dict_key(i)->to_string());
|
u_.dict[i].value_.clone(v->dict_value(i));
|
u_.dict[i].value_.clone(v->dict_value(i));
|
}
|
}
|
} else {
|
} else {
|
this->kind_ = v->kind_;
|
this->kind_ = v->kind_;
|
this->u_ = v->u_;
|
this->u_ = v->u_;
|
this->size_ = v->size_;
|
this->size_ = v->size_;
|
}
|
}
|
}
|
}
|
|
|
bool AttributeType::is_equal(const char *v) {
|
bool AttributeType::is_equal(const char *v) {
|
if (!is_string()) {
|
if (!is_string()) {
|
return false;
|
return false;
|
}
|
}
|
return !strcmp(to_string(), v);
|
return !strcmp(to_string(), v);
|
}
|
}
|
|
|
|
|
AttributeType &AttributeType::operator=(const AttributeType& other) {
|
AttributeType &AttributeType::operator=(const AttributeType& other) {
|
if (&other != this) {
|
if (&other != this) {
|
clone(&other);
|
clone(&other);
|
}
|
}
|
return *this;
|
return *this;
|
}
|
}
|
|
|
|
|
const AttributeType &AttributeType::operator[](unsigned idx) const {
|
const AttributeType &AttributeType::operator[](unsigned idx) const {
|
if (is_list()) {
|
if (is_list()) {
|
return u_.list[idx];
|
return u_.list[idx];
|
} else if (is_dict()) {
|
} else if (is_dict()) {
|
return u_.dict[idx].value_;
|
return u_.dict[idx].value_;
|
} else {
|
} else {
|
RISCV_printf(NULL, LOG_ERROR, "%s", "Non-indexed attribute type");
|
RISCV_printf(NULL, LOG_ERROR, "%s", "Non-indexed attribute type");
|
}
|
}
|
return NilAttribute;
|
return NilAttribute;
|
}
|
}
|
|
|
AttributeType &AttributeType::operator[](unsigned idx) {
|
AttributeType &AttributeType::operator[](unsigned idx) {
|
if (is_list()) {
|
if (is_list()) {
|
return u_.list[idx];
|
return u_.list[idx];
|
} else if (is_dict()) {
|
} else if (is_dict()) {
|
return u_.dict[idx].value_;
|
return u_.dict[idx].value_;
|
} else {
|
} else {
|
RISCV_printf(NULL, LOG_ERROR, "%s", "Non-indexed attribute type");
|
RISCV_printf(NULL, LOG_ERROR, "%s", "Non-indexed attribute type");
|
}
|
}
|
return NilAttribute;
|
return NilAttribute;
|
}
|
}
|
|
|
const AttributeType &AttributeType::operator[](const char *key) const {
|
const AttributeType &AttributeType::operator[](const char *key) const {
|
for (unsigned i = 0; i < size(); i++) {
|
for (unsigned i = 0; i < size(); i++) {
|
if (strcmp(key, u_.dict[i].key_.to_string()) == 0) {
|
if (strcmp(key, u_.dict[i].key_.to_string()) == 0) {
|
return u_.dict[i].value_;
|
return u_.dict[i].value_;
|
}
|
}
|
}
|
}
|
AttributeType *pthis = const_cast<AttributeType*>(this);
|
AttributeType *pthis = const_cast<AttributeType*>(this);
|
pthis->realloc_dict(size()+1);
|
pthis->realloc_dict(size()+1);
|
pthis->u_.dict[size()-1].key_.make_string(key);
|
pthis->u_.dict[size()-1].key_.make_string(key);
|
pthis->u_.dict[size()-1].value_.make_nil();
|
pthis->u_.dict[size()-1].value_.make_nil();
|
return u_.dict[size()-1].value_;
|
return u_.dict[size()-1].value_;
|
}
|
}
|
|
|
AttributeType &AttributeType::operator[](const char *key) {
|
AttributeType &AttributeType::operator[](const char *key) {
|
for (unsigned i = 0; i < size(); i++) {
|
for (unsigned i = 0; i < size(); i++) {
|
if (strcmp(key, u_.dict[i].key_.to_string()) == 0) {
|
if (strcmp(key, u_.dict[i].key_.to_string()) == 0) {
|
return u_.dict[i].value_;
|
return u_.dict[i].value_;
|
}
|
}
|
}
|
}
|
realloc_dict(size()+1);
|
realloc_dict(size()+1);
|
u_.dict[size()-1].key_.make_string(key);
|
u_.dict[size()-1].key_.make_string(key);
|
u_.dict[size()-1].value_.make_nil();
|
u_.dict[size()-1].value_.make_nil();
|
return u_.dict[size()-1].value_;
|
return u_.dict[size()-1].value_;
|
}
|
}
|
|
|
const uint8_t &AttributeType::operator()(unsigned idx) const {
|
const uint8_t &AttributeType::operator()(unsigned idx) const {
|
if (idx > size()) {
|
if (idx > size()) {
|
RISCV_printf(NULL, LOG_ERROR, "Data index '%d' out of range.", idx);
|
RISCV_printf(NULL, LOG_ERROR, "Data index '%d' out of range.", idx);
|
return u_.data[0];
|
return u_.data[0];
|
}
|
}
|
if (size_ > 8) {
|
if (size_ > 8) {
|
return u_.data[idx];
|
return u_.data[idx];
|
}
|
}
|
return u_.data_bytes[idx];
|
return u_.data_bytes[idx];
|
}
|
}
|
|
|
void AttributeType::make_string(const char *value) {
|
void AttributeType::make_string(const char *value) {
|
attr_free();
|
attr_free();
|
if (value) {
|
if (value) {
|
kind_ = Attr_String;
|
kind_ = Attr_String;
|
size_ = (unsigned)strlen(value);
|
size_ = (unsigned)strlen(value);
|
u_.string = static_cast<char *>(RISCV_malloc(size_ + 1));
|
u_.string = static_cast<char *>(RISCV_malloc(size_ + 1));
|
memcpy(u_.string, value, size_ + 1);
|
memcpy(u_.string, value, size_ + 1);
|
} else {
|
} else {
|
kind_ = Attr_Nil;
|
kind_ = Attr_Nil;
|
}
|
}
|
}
|
}
|
|
|
void AttributeType::make_data(unsigned size) {
|
void AttributeType::make_data(unsigned size) {
|
attr_free();
|
attr_free();
|
kind_ = Attr_Data;
|
kind_ = Attr_Data;
|
size_ = size;
|
size_ = size;
|
if (size > 8) {
|
if (size > 8) {
|
u_.data = static_cast<uint8_t *>(RISCV_malloc(size_));
|
u_.data = static_cast<uint8_t *>(RISCV_malloc(size_));
|
}
|
}
|
}
|
}
|
|
|
void AttributeType::make_data(unsigned size, const void *data) {
|
void AttributeType::make_data(unsigned size, const void *data) {
|
attr_free();
|
attr_free();
|
kind_ = Attr_Data;
|
kind_ = Attr_Data;
|
size_ = size;
|
size_ = size;
|
if (size > 8) {
|
if (size > 8) {
|
u_.data = static_cast<uint8_t *>(RISCV_malloc(size_));
|
u_.data = static_cast<uint8_t *>(RISCV_malloc(size_));
|
memcpy(u_.data, data, size);
|
memcpy(u_.data, data, size);
|
} else {
|
} else {
|
memcpy(u_.data_bytes, data, size);
|
memcpy(u_.data_bytes, data, size);
|
}
|
}
|
}
|
}
|
|
|
|
void AttributeType::realloc_data(unsigned size) {
|
|
if (!is_data()) {
|
|
return;
|
|
}
|
|
if (size <= 8) {
|
|
if (size_ > 8) {
|
|
memcpy(u_.data_bytes, u_.data, size);
|
|
RISCV_free(u_.data);
|
|
}
|
|
size_ = size;
|
|
return;
|
|
}
|
|
uint8_t *pnew = static_cast<uint8_t *>(RISCV_malloc(size));
|
|
unsigned sz = size;
|
|
if (size_ < sz) {
|
|
sz = size_;
|
|
}
|
|
if (sz > 8) {
|
|
memcpy(pnew, u_.data, sz);
|
|
RISCV_free(u_.data);
|
|
} else {
|
|
memcpy(pnew, u_.data_bytes, sz);
|
|
}
|
|
u_.data = pnew;
|
|
size_ = size;
|
|
}
|
|
|
void AttributeType::make_list(unsigned size) {
|
void AttributeType::make_list(unsigned size) {
|
attr_free();
|
attr_free();
|
kind_ = Attr_List;
|
kind_ = Attr_List;
|
if (size) {
|
if (size) {
|
realloc_list(size);
|
realloc_list(size);
|
}
|
}
|
}
|
}
|
|
|
void AttributeType::realloc_list(unsigned size) {
|
void AttributeType::realloc_list(unsigned size) {
|
size_t req_sz = (size * sizeof(AttributeType) + MIN_ALLOC_BYTES - 1)
|
size_t req_sz = (size * sizeof(AttributeType) + MIN_ALLOC_BYTES - 1)
|
/ MIN_ALLOC_BYTES;
|
/ MIN_ALLOC_BYTES;
|
size_t cur_sz = (size_ * sizeof(AttributeType) + MIN_ALLOC_BYTES - 1)
|
size_t cur_sz = (size_ * sizeof(AttributeType) + MIN_ALLOC_BYTES - 1)
|
/ MIN_ALLOC_BYTES;
|
/ MIN_ALLOC_BYTES;
|
if (req_sz > cur_sz ) {
|
if (req_sz > cur_sz) {
|
AttributeType * t1 = static_cast<AttributeType *>(
|
AttributeType * t1 = static_cast<AttributeType *>(
|
RISCV_malloc(MIN_ALLOC_BYTES * req_sz));
|
RISCV_malloc(MIN_ALLOC_BYTES * req_sz));
|
memcpy(t1, u_.list, size_ * sizeof(AttributeType));
|
memcpy(t1, u_.list, size_ * sizeof(AttributeType));
|
memset(&t1[size_], 0,
|
memset(&t1[size_], 0,
|
(MIN_ALLOC_BYTES * req_sz) - size_ * sizeof(AttributeType));
|
(MIN_ALLOC_BYTES * req_sz) - size_ * sizeof(AttributeType));
|
if (size_) {
|
if (size_) {
|
RISCV_free(u_.list);
|
RISCV_free(u_.list);
|
}
|
}
|
u_.list = t1;
|
u_.list = t1;
|
}
|
}
|
size_ = size;
|
size_ = size;
|
}
|
}
|
|
|
void AttributeType::insert_to_list(unsigned idx, const AttributeType *item) {
|
void AttributeType::insert_to_list(unsigned idx, const AttributeType *item) {
|
if (idx > size_) {
|
if (idx > size_) {
|
RISCV_printf(NULL, LOG_ERROR, "%s", "Insert index out of bound");
|
RISCV_printf(NULL, LOG_ERROR, "%s", "Insert index out of bound");
|
return;
|
return;
|
}
|
}
|
size_t new_sz = ((size_ + 1) * sizeof(AttributeType) + MIN_ALLOC_BYTES - 1)
|
size_t new_sz = ((size_ + 1) * sizeof(AttributeType) + MIN_ALLOC_BYTES - 1)
|
/ MIN_ALLOC_BYTES;
|
/ MIN_ALLOC_BYTES;
|
AttributeType * t1 = static_cast<AttributeType *>(
|
AttributeType * t1 = static_cast<AttributeType *>(
|
RISCV_malloc(MIN_ALLOC_BYTES * new_sz));
|
RISCV_malloc(MIN_ALLOC_BYTES * new_sz));
|
memset(t1 + idx, 0, sizeof(AttributeType)); // Fix bug request #4
|
memset(t1 + idx, 0, sizeof(AttributeType)); // Fix bug request #4
|
|
|
memcpy(t1, u_.list, idx * sizeof(AttributeType));
|
memcpy(t1, u_.list, idx * sizeof(AttributeType));
|
t1[idx].clone(item);
|
t1[idx].clone(item);
|
memcpy(&t1[idx + 1], &u_.list[idx], (size_ - idx) * sizeof(AttributeType));
|
memcpy(&t1[idx + 1], &u_.list[idx], (size_ - idx) * sizeof(AttributeType));
|
memset(&t1[size_ + 1], 0,
|
memset(&t1[size_ + 1], 0,
|
(MIN_ALLOC_BYTES * new_sz) - (size_ + 1) * sizeof(AttributeType));
|
(MIN_ALLOC_BYTES * new_sz) - (size_ + 1) * sizeof(AttributeType));
|
if (size_) {
|
if (size_) {
|
RISCV_free(u_.list);
|
RISCV_free(u_.list);
|
}
|
}
|
u_.list = t1;
|
u_.list = t1;
|
size_++;
|
size_++;
|
}
|
}
|
|
|
void AttributeType::remove_from_list(unsigned idx) {
|
void AttributeType::remove_from_list(unsigned idx) {
|
if (idx >= size_) {
|
if (idx >= size_) {
|
RISCV_printf(NULL, LOG_ERROR, "%s", "Remove index out of range");
|
RISCV_printf(NULL, LOG_ERROR, "%s", "Remove index out of range");
|
return;
|
return;
|
}
|
}
|
(*this)[idx].attr_free();
|
(*this)[idx].attr_free();
|
if (idx == (size() - 1)) {
|
if (idx == (size() - 1)) {
|
size_ -= 1;
|
size_ -= 1;
|
} else if (idx < size ()) {
|
} else if (idx < size()) {
|
swap_list_item(idx, size() - 1);
|
swap_list_item(idx, size() - 1);
|
size_ -= 1;
|
size_ -= 1;
|
}
|
}
|
}
|
}
|
|
|
void AttributeType::trim_list(unsigned start, unsigned end) {
|
void AttributeType::trim_list(unsigned start, unsigned end) {
|
for (unsigned i = start; i < (size_ - end); i++) {
|
for (unsigned i = start; i < (size_ - end); i++) {
|
u_.list[start + i].attr_free();
|
u_.list[start + i].attr_free();
|
u_.list[start + i] = u_.list[end + i];
|
u_.list[start + i] = u_.list[end + i];
|
}
|
}
|
size_ -= (end - start);
|
size_ -= (end - start);
|
}
|
}
|
|
|
void AttributeType::swap_list_item(unsigned n, unsigned m) {
|
void AttributeType::swap_list_item(unsigned n, unsigned m) {
|
if (n == m) {
|
if (n == m) {
|
return;
|
return;
|
}
|
}
|
unsigned tsize = u_.list[n].size_;
|
unsigned tsize = u_.list[n].size_;
|
KindType tkind = u_.list[n].kind_;
|
KindType tkind = u_.list[n].kind_;
|
int64_t tinteger = u_.list[n].u_.integer;
|
int64_t tinteger = u_.list[n].u_.integer;
|
u_.list[n].size_ = u_.list[m].size_;
|
u_.list[n].size_ = u_.list[m].size_;
|
u_.list[n].kind_ = u_.list[m].kind_;
|
u_.list[n].kind_ = u_.list[m].kind_;
|
u_.list[n].u_.integer = u_.list[m].u_.integer;
|
u_.list[n].u_.integer = u_.list[m].u_.integer;
|
u_.list[m].size_ = tsize;
|
u_.list[m].size_ = tsize;
|
u_.list[m].kind_ = tkind;
|
u_.list[m].kind_ = tkind;
|
u_.list[m].u_.integer = tinteger;
|
u_.list[m].u_.integer = tinteger;
|
}
|
}
|
|
|
|
|
int partition(AttributeType *A, int lo, int hi, int lst_idx) {
|
int partition(AttributeType *A, int lo, int hi, int lst_idx) {
|
AttributeType *pivot = &(*A)[hi];
|
AttributeType *pivot = &(*A)[hi];
|
bool do_swap;
|
bool do_swap;
|
int i = lo - 1;
|
int i = lo - 1;
|
for (int j = lo; j < hi; j++) {
|
for (int j = lo; j < hi; j++) {
|
AttributeType &item = (*A)[j];
|
AttributeType &item = (*A)[j];
|
do_swap = false;
|
do_swap = false;
|
if (item.is_string()) {
|
if (item.is_string()) {
|
if (strcmp(item.to_string(), pivot->to_string()) <= 0) {
|
if (strcmp(item.to_string(), pivot->to_string()) <= 0) {
|
do_swap = true;
|
do_swap = true;
|
}
|
}
|
} else if (item.is_int64()) {
|
} else if (item.is_int64()) {
|
if (item.to_int64() <= pivot->to_int64()) {
|
if (item.to_int64() <= pivot->to_int64()) {
|
do_swap = true;
|
do_swap = true;
|
}
|
}
|
} else if (item.is_uint64()) {
|
} else if (item.is_uint64()) {
|
if (item.to_uint64() <= pivot->to_uint64()) {
|
if (item.to_uint64() <= pivot->to_uint64()) {
|
do_swap = true;
|
do_swap = true;
|
}
|
}
|
} else if (item.is_list()) {
|
} else if (item.is_list()) {
|
AttributeType &t1 = item[lst_idx];
|
AttributeType &t1 = item[lst_idx];
|
if (t1.is_string() &&
|
if (t1.is_string() &&
|
strcmp(t1.to_string(), (*pivot)[lst_idx].to_string()) <= 0) {
|
strcmp(t1.to_string(), (*pivot)[lst_idx].to_string()) <= 0) {
|
do_swap = true;
|
do_swap = true;
|
} else if (t1.is_int64() &&
|
} else if (t1.is_int64() &&
|
t1.to_int64() <= (*pivot)[lst_idx].to_int64()) {
|
t1.to_int64() <= (*pivot)[lst_idx].to_int64()) {
|
do_swap = true;
|
do_swap = true;
|
} else if (t1.is_uint64() &&
|
} else if (t1.is_uint64() &&
|
t1.to_uint64() <= (*pivot)[lst_idx].to_uint64()) {
|
t1.to_uint64() <= (*pivot)[lst_idx].to_uint64()) {
|
do_swap = true;
|
do_swap = true;
|
}
|
}
|
} else {
|
} else {
|
RISCV_printf(NULL, LOG_ERROR, "%s",
|
RISCV_printf(NULL, LOG_ERROR, "%s",
|
"Not supported attribute type for sorting");
|
"Not supported attribute type for sorting");
|
return i + 1;
|
return i + 1;
|
}
|
}
|
|
|
if (do_swap) {
|
if (do_swap) {
|
i = i + 1;
|
i = i + 1;
|
A->swap_list_item(i, j);
|
A->swap_list_item(i, j);
|
}
|
}
|
}
|
}
|
A->swap_list_item(i + 1, hi);
|
A->swap_list_item(i + 1, hi);
|
return i + 1;
|
return i + 1;
|
}
|
}
|
|
|
void quicksort(AttributeType *A, int lo, int hi, int lst_idx) {
|
void quicksort(AttributeType *A, int lo, int hi, int lst_idx) {
|
if (lo >= hi) {
|
if (lo >= hi) {
|
return;
|
return;
|
}
|
}
|
int p = partition(A, lo, hi, lst_idx);
|
int p = partition(A, lo, hi, lst_idx);
|
quicksort(A, lo, p - 1, lst_idx);
|
quicksort(A, lo, p - 1, lst_idx);
|
quicksort(A, p + 1, hi, lst_idx);
|
quicksort(A, p + 1, hi, lst_idx);
|
}
|
}
|
|
|
void AttributeType::sort(int idx) {
|
void AttributeType::sort(int idx) {
|
if (!is_list()) {
|
if (!is_list()) {
|
RISCV_printf(NULL, LOG_ERROR, "%s",
|
RISCV_printf(NULL, LOG_ERROR, "%s",
|
"Sort algorithm can applied only to list attribute");
|
"Sort algorithm can applied only to list attribute");
|
}
|
}
|
quicksort(this, 0, static_cast<int>(size()) - 1, idx);
|
quicksort(this, 0, static_cast<int>(size()) - 1, idx);
|
}
|
}
|
|
|
bool AttributeType::has_key(const char *key) const {
|
bool AttributeType::has_key(const char *key) const {
|
for (unsigned i = 0; i < size(); i++) {
|
for (unsigned i = 0; i < size(); i++) {
|
if (strcmp(u_.dict[i].key_.to_string(), key) == 0
|
AttributePairType &pair = u_.dict[i];
|
&& !u_.dict[i].value_.is_nil()) {
|
if (pair.key_.is_equal(key) && !pair.value_.is_nil()) {
|
return true;
|
return true;
|
}
|
}
|
}
|
}
|
return false;
|
return false;
|
}
|
}
|
|
|
const AttributeType *AttributeType::dict_key(unsigned idx) const {
|
const AttributeType *AttributeType::dict_key(unsigned idx) const {
|
return &u_.dict[idx].key_;
|
return &u_.dict[idx].key_;
|
}
|
}
|
AttributeType *AttributeType::dict_key(unsigned idx) {
|
AttributeType *AttributeType::dict_key(unsigned idx) {
|
return &u_.dict[idx].key_;
|
return &u_.dict[idx].key_;
|
}
|
}
|
|
|
const AttributeType *AttributeType::dict_value(unsigned idx) const {
|
const AttributeType *AttributeType::dict_value(unsigned idx) const {
|
return &u_.dict[idx].value_;
|
return &u_.dict[idx].value_;
|
}
|
}
|
AttributeType *AttributeType::dict_value(unsigned idx) {
|
AttributeType *AttributeType::dict_value(unsigned idx) {
|
return &u_.dict[idx].value_;
|
return &u_.dict[idx].value_;
|
}
|
}
|
|
|
void AttributeType::make_dict() {
|
void AttributeType::make_dict() {
|
attr_free();
|
attr_free();
|
kind_ = Attr_Dict;
|
kind_ = Attr_Dict;
|
size_ = 0;
|
size_ = 0;
|
u_.dict = NULL;
|
u_.dict = NULL;
|
}
|
}
|
|
|
void AttributeType::realloc_dict(unsigned size) {
|
void AttributeType::realloc_dict(unsigned size) {
|
size_t req_sz = (size * sizeof(AttributePairType) + MIN_ALLOC_BYTES - 1)
|
size_t req_sz = (size * sizeof(AttributePairType) + MIN_ALLOC_BYTES - 1)
|
/ MIN_ALLOC_BYTES;
|
/ MIN_ALLOC_BYTES;
|
size_t cur_sz = (size_ * sizeof(AttributePairType) + MIN_ALLOC_BYTES - 1)
|
size_t cur_sz = (size_ * sizeof(AttributePairType) + MIN_ALLOC_BYTES - 1)
|
/ MIN_ALLOC_BYTES;
|
/ MIN_ALLOC_BYTES;
|
if (req_sz > cur_sz ) {
|
if (req_sz > cur_sz) {
|
AttributePairType * t1 = static_cast<AttributePairType *>(
|
AttributePairType * t1 = static_cast<AttributePairType *>(
|
RISCV_malloc(MIN_ALLOC_BYTES * req_sz));
|
RISCV_malloc(MIN_ALLOC_BYTES * req_sz));
|
memcpy(t1, u_.dict, size_ * sizeof(AttributePairType));
|
memcpy(t1, u_.dict, size_ * sizeof(AttributePairType));
|
memset(&t1[size_], 0,
|
memset(&t1[size_], 0,
|
(MIN_ALLOC_BYTES * req_sz) - size_ * sizeof(AttributePairType));
|
(MIN_ALLOC_BYTES * req_sz) - size_ * sizeof(AttributePairType));
|
if (size_) {
|
if (size_) {
|
RISCV_free(u_.dict);
|
RISCV_free(u_.dict);
|
}
|
}
|
u_.dict = t1;
|
u_.dict = t1;
|
}
|
}
|
size_ = size;
|
size_ = size;
|
}
|
}
|
|
|
char *AttributeType::to_config() {
|
const AttributeType& AttributeType::to_config() {
|
strBuffer.clear();
|
AutoBuffer strBuffer;
|
attribute_to_string(this);
|
attribute_to_string(this, &strBuffer);
|
return strBuffer.getBuffer();
|
make_string(strBuffer.getBuffer());
|
|
return (*this);
|
}
|
}
|
|
|
void AttributeType::from_config(const char *str) {
|
void AttributeType::from_config(const char *str) {
|
int off = 0;
|
int off = 0;
|
string_to_attribute(str, off, this);
|
string_to_attribute(str, off, this);
|
}
|
}
|
|
|
char *attribute_to_string(const AttributeType *attr) {
|
void attribute_to_string(const AttributeType *attr, AutoBuffer *buf) {
|
IService *iserv;
|
IService *iserv;
|
AutoBuffer *buf = &strBuffer;
|
|
if (attr->is_nil()) {
|
if (attr->is_nil()) {
|
buf->write_string("None");
|
buf->write_string("None");
|
} else if (attr->is_int64() || attr->is_uint64()) {
|
} else if (attr->is_int64() || attr->is_uint64()) {
|
buf->write_uint64(attr->to_uint64());
|
buf->write_uint64(attr->to_uint64());
|
} else if (attr->is_string()) {
|
} else if (attr->is_string()) {
|
buf->write_string('\'');
|
buf->write_string('\'');
|
buf->write_string(attr->to_string());
|
buf->write_string(attr->to_string());
|
buf->write_string('\'');
|
buf->write_string('\'');
|
} else if (attr->is_bool()) {
|
} else if (attr->is_bool()) {
|
if (attr->to_bool()) {
|
if (attr->to_bool()) {
|
buf->write_string("true");
|
buf->write_string("True");
|
} else {
|
} else {
|
buf->write_string("false");
|
buf->write_string("False");
|
}
|
}
|
} else if (attr->is_list()) {
|
} else if (attr->is_list()) {
|
AttributeType list_item;
|
AttributeType list_item;
|
unsigned list_sz = attr->size();
|
unsigned list_sz = attr->size();
|
buf->write_string('[');
|
buf->write_string('[');
|
for (unsigned i = 0; i < list_sz; i++) {
|
for (unsigned i = 0; i < list_sz; i++) {
|
list_item = (*attr)[i];
|
list_item = (*attr)[i];
|
attribute_to_string(&list_item);
|
attribute_to_string(&list_item, buf);
|
if (i < (list_sz - 1)) {
|
if (i < (list_sz - 1)) {
|
buf->write_string(',');
|
buf->write_string(',');
|
}
|
}
|
}
|
}
|
buf->write_string(']');
|
buf->write_string(']');
|
} else if (attr->is_dict()) {
|
} else if (attr->is_dict()) {
|
AttributeType dict_item;
|
AttributeType dict_item;
|
unsigned dict_sz = attr->size();;
|
unsigned dict_sz = attr->size();;
|
buf->write_string('{');
|
buf->write_string('{');
|
|
|
for (unsigned i = 0; i < dict_sz; i++) {
|
for (unsigned i = 0; i < dict_sz; i++) {
|
buf->write_string('\'');
|
buf->write_string('\'');
|
buf->write_string(attr->u_.dict[i].key_.to_string());
|
buf->write_string(attr->u_.dict[i].key_.to_string());
|
buf->write_string('\'');
|
buf->write_string('\'');
|
buf->write_string(':');
|
buf->write_string(':');
|
const AttributeType &dict_value = (*attr)[i];
|
const AttributeType &dict_value = (*attr)[i];
|
attribute_to_string(&dict_value);
|
attribute_to_string(&dict_value, buf);
|
if (i < (dict_sz - 1)) {
|
if (i < (dict_sz - 1)) {
|
buf->write_string(',');
|
buf->write_string(',');
|
}
|
}
|
}
|
}
|
buf->write_string('}');
|
buf->write_string('}');
|
} else if (attr->is_data()) {
|
} else if (attr->is_data()) {
|
buf->write_string('(');
|
buf->write_string('(');
|
if (attr->size() > 0) {
|
if (attr->size() > 0) {
|
for (unsigned n = 0; n < attr->size()-1; n++) {
|
for (unsigned n = 0; n < attr->size()-1; n++) {
|
buf->write_byte((*attr)(n));
|
buf->write_byte((*attr)(n));
|
buf->write_string(',');
|
buf->write_string(',');
|
}
|
}
|
buf->write_byte((*attr)(attr->size()-1));
|
buf->write_byte((*attr)(attr->size()-1));
|
}
|
}
|
buf->write_string(')');
|
buf->write_string(')');
|
} else if (attr->is_iface()) {
|
} else if (attr->is_iface()) {
|
IFace *iface = attr->to_iface();
|
IFace *iface = attr->to_iface();
|
if (strcmp(iface->getFaceName(), IFACE_SERVICE) == 0) {
|
if (strcmp(iface->getFaceName(), IFACE_SERVICE) == 0) {
|
iserv = static_cast<IService *>(iface);
|
iserv = static_cast<IService *>(iface);
|
buf->write_string('{');
|
buf->write_string('{');
|
buf->write_string("'Type':'");
|
buf->write_string("'Type':'");
|
buf->write_string(iface->getFaceName());
|
buf->write_string(iface->getFaceName());
|
buf->write_string("','ModuleName':'");
|
buf->write_string("','ModuleName':'");
|
buf->write_string(iserv->getObjName());
|
buf->write_string(iserv->getObjName());
|
buf->write_string("'}");
|
buf->write_string("'}");
|
} else {
|
} else {
|
RISCV_printf(NULL, LOG_ERROR,
|
RISCV_printf(NULL, LOG_ERROR,
|
"Not implemented interface to dict. method");
|
"Not implemented interface to dict. method");
|
}
|
}
|
} else if (attr->is_floating()) {
|
} else if (attr->is_floating()) {
|
char fstr[64];
|
char fstr[64];
|
RISCV_sprintf(fstr, sizeof(fstr), "%.4f", attr->to_float());
|
RISCV_sprintf(fstr, sizeof(fstr), "%.4f", attr->to_float());
|
buf->write_string(fstr);
|
buf->write_string(fstr);
|
}
|
}
|
return buf->getBuffer();
|
|
}
|
}
|
|
|
int skip_special_symbols(const char *cfg, int off) {
|
int skip_special_symbols(const char *cfg, int off) {
|
const char *pcur = &cfg[off];
|
const char *pcur = &cfg[off];
|
while (*pcur == ' ' || *pcur == '\r' || *pcur == '\n' || *pcur == '\t') {
|
while (*pcur == ' ' || *pcur == '\r' || *pcur == '\n' || *pcur == '\t') {
|
pcur++;
|
pcur++;
|
off++;
|
off++;
|
}
|
}
|
return off;
|
return off;
|
}
|
}
|
|
|
int string_to_attribute(const char *cfg, int &off,
|
int string_to_attribute(const char *cfg, int &off,
|
AttributeType *out) {
|
AttributeType *out) {
|
off = skip_special_symbols(cfg, off);
|
off = skip_special_symbols(cfg, off);
|
int checkstart = off;
|
int checkstart = off;
|
if (cfg[off] == '\'' || cfg[off] == '"') {
|
if (cfg[off] == '\'' || cfg[off] == '"') {
|
AutoBuffer buf;
|
AutoBuffer buf;
|
uint8_t t1 = cfg[off];
|
uint8_t t1 = cfg[off];
|
int str_sz = 0;
|
int str_sz = 0;
|
const char *pcur = &cfg[++off];
|
const char *pcur = &cfg[++off];
|
while (*pcur != t1 && *pcur != '\0') {
|
while (*pcur != t1 && *pcur != '\0') {
|
pcur++;
|
pcur++;
|
str_sz++;
|
str_sz++;
|
}
|
}
|
buf.write_bin(&cfg[off], str_sz);
|
buf.write_bin(&cfg[off], str_sz);
|
out->make_string(buf.getBuffer());
|
out->make_string(buf.getBuffer());
|
off += str_sz;
|
off += str_sz;
|
if (cfg[off] != t1) {
|
if (cfg[off] != t1) {
|
RISCV_printf(NULL, LOG_ERROR,
|
RISCV_printf(NULL, LOG_ERROR,
|
"JSON parser error: Wrong string format");
|
"JSON parser error: Wrong string format");
|
out->attr_free();
|
out->attr_free();
|
return -1;
|
return -1;
|
}
|
}
|
off = skip_special_symbols(cfg, off + 1);
|
off = skip_special_symbols(cfg, off + 1);
|
} else if (cfg[off] == '[') {
|
} else if (cfg[off] == '[') {
|
off = skip_special_symbols(cfg, off + 1);
|
off = skip_special_symbols(cfg, off + 1);
|
AttributeType new_item;
|
AttributeType new_item;
|
out->make_list(0);
|
out->make_list(0);
|
while (cfg[off] != ']' && cfg[off] != '\0') {
|
while (cfg[off] != ']' && cfg[off] != '\0') {
|
if (string_to_attribute(cfg, off, &new_item)) {
|
if (string_to_attribute(cfg, off, &new_item)) {
|
/* error handling */
|
/* error handling */
|
out->attr_free();
|
out->attr_free();
|
return -1;
|
return -1;
|
}
|
}
|
out->realloc_list(out->size() + 1);
|
out->realloc_list(out->size() + 1);
|
(*out)[out->size() - 1] = new_item;
|
(*out)[out->size() - 1] = new_item;
|
|
|
off = skip_special_symbols(cfg, off);
|
off = skip_special_symbols(cfg, off);
|
if (cfg[off] == ',') {
|
if (cfg[off] == ',') {
|
off = skip_special_symbols(cfg, off + 1);
|
off = skip_special_symbols(cfg, off + 1);
|
}
|
}
|
}
|
}
|
if (cfg[off] != ']') {
|
if (cfg[off] != ']') {
|
RISCV_printf(NULL, LOG_ERROR,
|
RISCV_printf(NULL, LOG_ERROR,
|
"JSON parser error: Wrong list format");
|
"JSON parser error: Wrong list format");
|
out->attr_free();
|
out->attr_free();
|
return -1;
|
return -1;
|
}
|
}
|
off = skip_special_symbols(cfg, off + 1);
|
off = skip_special_symbols(cfg, off + 1);
|
} else if (cfg[off] == '{') {
|
} else if (cfg[off] == '{') {
|
AttributeType new_key;
|
AttributeType new_key;
|
AttributeType new_value;
|
AttributeType new_value;
|
out->make_dict();
|
out->make_dict();
|
off = skip_special_symbols(cfg, off + 1);
|
off = skip_special_symbols(cfg, off + 1);
|
while (cfg[off] != '}' && cfg[off] != '\0') {
|
while (cfg[off] != '}' && cfg[off] != '\0') {
|
if (string_to_attribute(cfg, off, &new_key)) {
|
if (string_to_attribute(cfg, off, &new_key)) {
|
RISCV_printf(NULL, LOG_ERROR,
|
RISCV_printf(NULL, LOG_ERROR,
|
"JSON parser error: Wrong dictionary key");
|
"JSON parser error: Wrong dictionary key");
|
out->attr_free();
|
out->attr_free();
|
return -1;
|
return -1;
|
}
|
}
|
off = skip_special_symbols(cfg, off);
|
off = skip_special_symbols(cfg, off);
|
if (cfg[off] != ':') {
|
if (cfg[off] != ':') {
|
out->attr_free();
|
out->attr_free();
|
RISCV_printf(NULL, LOG_ERROR,
|
RISCV_printf(NULL, LOG_ERROR,
|
"JSON parser error: Wrong dictionary delimiter");
|
"JSON parser error: Wrong dictionary delimiter");
|
return -1;
|
return -1;
|
}
|
}
|
off = skip_special_symbols(cfg, off + 1);
|
off = skip_special_symbols(cfg, off + 1);
|
if (string_to_attribute(cfg, off, &new_value)) {
|
if (string_to_attribute(cfg, off, &new_value)) {
|
RISCV_printf(NULL, LOG_ERROR,
|
RISCV_printf(NULL, LOG_ERROR,
|
"JSON parser error: Wrong dictionary value");
|
"JSON parser error: Wrong dictionary value");
|
out->attr_free();
|
out->attr_free();
|
return -1;
|
return -1;
|
}
|
}
|
|
|
(*out)[new_key.to_string()] = new_value;
|
(*out)[new_key.to_string()] = new_value;
|
|
|
off = skip_special_symbols(cfg, off);
|
off = skip_special_symbols(cfg, off);
|
if (cfg[off] == ',') {
|
if (cfg[off] == ',') {
|
off = skip_special_symbols(cfg, off + 1);
|
off = skip_special_symbols(cfg, off + 1);
|
}
|
}
|
}
|
}
|
if (cfg[off] != '}') {
|
if (cfg[off] != '}') {
|
RISCV_printf(NULL, LOG_ERROR,
|
RISCV_printf(NULL, LOG_ERROR,
|
"JSON parser error: Wrong dictionary format");
|
"JSON parser error: Wrong dictionary format");
|
out->attr_free();
|
out->attr_free();
|
return -1;
|
return -1;
|
}
|
}
|
off = skip_special_symbols(cfg, off + 1);
|
off = skip_special_symbols(cfg, off + 1);
|
|
|
if (out->has_key("Type")) {
|
if (out->has_key("Type")) {
|
if (strcmp((*out)["Type"].to_string(), IFACE_SERVICE) == 0) {
|
if (strcmp((*out)["Type"].to_string(), IFACE_SERVICE) == 0) {
|
IService *iserv;
|
IService *iserv;
|
iserv = static_cast<IService *>(
|
iserv = static_cast<IService *>(
|
RISCV_get_service((*out)["ModuleName"].to_string()));
|
RISCV_get_service((*out)["ModuleName"].to_string()));
|
out->attr_free();
|
out->attr_free();
|
*out = AttributeType(iserv);
|
*out = AttributeType(iserv);
|
} else {
|
} else {
|
RISCV_printf(NULL, LOG_ERROR,
|
RISCV_printf(NULL, LOG_ERROR,
|
"Not implemented string to dict. attribute");
|
"Not implemented string to dict. attribute");
|
}
|
}
|
}
|
}
|
} else if (cfg[off] == '(') {
|
} else if (cfg[off] == '(') {
|
AutoBuffer buf;
|
AutoBuffer buf;
|
char byte_value;
|
char byte_value;
|
off = skip_special_symbols(cfg, off);
|
off = skip_special_symbols(cfg, off + 1);
|
while (cfg[off] != ')' && cfg[off] != '\0') {
|
while (cfg[off] != ')' && cfg[off] != '\0') {
|
byte_value = 0;
|
byte_value = 0;
|
for (int n = 0; n < 2; n++) {
|
for (int n = 0; n < 2; n++) {
|
if (cfg[off] >= 'A' && cfg[off] <= 'F') {
|
if (cfg[off] >= 'A' && cfg[off] <= 'F') {
|
byte_value = (byte_value << 4) | ((cfg[off] - 'A') + 10);
|
byte_value = (byte_value << 4) | ((cfg[off] - 'A') + 10);
|
|
} else if (cfg[off] >= 'a' && cfg[off] <= 'f') {
|
|
byte_value = (byte_value << 4) | ((cfg[off] - 'a') + 10);
|
} else {
|
} else {
|
byte_value = (byte_value << 4) | (cfg[off] - '0');
|
byte_value = (byte_value << 4) | (cfg[off] - '0');
|
}
|
}
|
off++;
|
off++;
|
}
|
}
|
buf.write_bin(&byte_value, 1);
|
buf.write_bin(&byte_value, 1);
|
|
|
off = skip_special_symbols(cfg, off);
|
off = skip_special_symbols(cfg, off);
|
|
if (cfg[off] == ')') {
|
|
break;
|
|
}
|
if (cfg[off] != ',') {
|
if (cfg[off] != ',') {
|
RISCV_printf(NULL, LOG_ERROR,
|
RISCV_printf(NULL, LOG_ERROR,
|
"JSON parser error: Wrong data dytes delimiter");
|
"JSON parser error: Wrong data dytes delimiter");
|
out->attr_free();
|
out->attr_free();
|
return -1;
|
return -1;
|
}
|
}
|
off = skip_special_symbols(cfg, off + 1);
|
off = skip_special_symbols(cfg, off + 1);
|
}
|
}
|
if (cfg[off] != ')') {
|
if (cfg[off] != ')') {
|
RISCV_printf(NULL, LOG_ERROR,
|
RISCV_printf(NULL, LOG_ERROR,
|
"JSON parser error: Wrong data format");
|
"JSON parser error: Wrong data format");
|
out->attr_free();
|
out->attr_free();
|
return -1;
|
return -1;
|
}
|
}
|
out->make_data(buf.size(), buf.getBuffer());
|
out->make_data(buf.size(), buf.getBuffer());
|
off = skip_special_symbols(cfg, off + 1);
|
off = skip_special_symbols(cfg, off + 1);
|
} else if (cfg[off] == 'N' && cfg[off + 1] == 'o' && cfg[off + 2] == 'n'
|
} else if (cfg[off] == 'N' && cfg[off + 1] == 'o' && cfg[off + 2] == 'n'
|
&& cfg[off + 3] == 'e') {
|
&& cfg[off + 3] == 'e') {
|
out->make_nil();
|
out->make_nil();
|
off = skip_special_symbols(cfg, off + 4);
|
off = skip_special_symbols(cfg, off + 4);
|
} else if (cfg[off] == 'f' && cfg[off + 1] == 'a' && cfg[off + 2] == 'l'
|
} else if ((cfg[off] == 'f' || cfg[off] == 'F') && cfg[off + 1] == 'a'
|
&& cfg[off + 3] == 's' && cfg[off + 4] == 'e') {
|
&& cfg[off + 2] == 'l' && cfg[off + 3] == 's'
|
|
&& cfg[off + 4] == 'e') {
|
out->make_boolean(false);
|
out->make_boolean(false);
|
off = skip_special_symbols(cfg, off + 5);
|
off = skip_special_symbols(cfg, off + 5);
|
} else if (cfg[off] == 't' && cfg[off + 1] == 'r' && cfg[off + 2] == 'u'
|
} else if ((cfg[off] == 't' || cfg[off] == 'T') && cfg[off + 1] == 'r'
|
&& cfg[off + 3] == 'e') {
|
&& cfg[off + 2] == 'u' && cfg[off + 3] == 'e') {
|
out->make_boolean(true);
|
out->make_boolean(true);
|
off = skip_special_symbols(cfg, off + 4);
|
off = skip_special_symbols(cfg, off + 4);
|
} else {
|
} else {
|
char digits[64] = {0};
|
char digits[64] = {0};
|
int digits_cnt = 0;
|
int digits_cnt = 0;
|
bool negative = false;
|
bool negative = false;
|
if (cfg[off] == '0' && cfg[off + 1] == 'x') {
|
if (cfg[off] == '0' && cfg[off + 1] == 'x') {
|
off += 2;
|
off += 2;
|
digits[digits_cnt++] = '0';
|
digits[digits_cnt++] = '0';
|
digits[digits_cnt++] = 'x';
|
digits[digits_cnt++] = 'x';
|
} else if (cfg[off] == '-') {
|
} else if (cfg[off] == '-') {
|
negative = true;
|
negative = true;
|
off++;
|
off++;
|
}
|
}
|
while (digits_cnt < 63 && ((cfg[off] >= '0' && cfg[off] <= '9')
|
while (digits_cnt < 63 && ((cfg[off] >= '0' && cfg[off] <= '9')
|
|| (cfg[off] >= 'a' && cfg[off] <= 'f')
|
|| (cfg[off] >= 'a' && cfg[off] <= 'f')
|
|| (cfg[off] >= 'A' && cfg[off] <= 'F'))) {
|
|| (cfg[off] >= 'A' && cfg[off] <= 'F'))) {
|
digits[digits_cnt++] = cfg[off++];
|
digits[digits_cnt++] = cfg[off++];
|
digits[digits_cnt] = 0;
|
digits[digits_cnt] = 0;
|
}
|
}
|
int64_t t1 = strtoull(digits, NULL, 0);
|
int64_t t1 = strtoull(digits, NULL, 0);
|
if (cfg[off] == '.') {
|
if (cfg[off] == '.') {
|
digits_cnt = 0;
|
digits_cnt = 0;
|
digits[0] = 0;
|
digits[0] = 0;
|
double divrate = 1.0;
|
double divrate = 1.0;
|
double d1 = static_cast<double>(t1);
|
double d1 = static_cast<double>(t1);
|
off++;
|
off++;
|
|
bool trim_zeros = true;
|
while (digits_cnt < 63 && cfg[off] >= '0' && cfg[off] <= '9') {
|
while (digits_cnt < 63 && cfg[off] >= '0' && cfg[off] <= '9') {
|
|
if (trim_zeros && cfg[off] == '0') {
|
|
off++;
|
|
divrate *= 10; // Fix: strtoull(0008) gives 0
|
|
continue;
|
|
}
|
|
trim_zeros = false;
|
digits[digits_cnt++] = cfg[off++];
|
digits[digits_cnt++] = cfg[off++];
|
digits[digits_cnt] = 0;
|
digits[digits_cnt] = 0;
|
divrate *= 10.0;
|
divrate *= 10.0;
|
}
|
}
|
t1 = strtoull(digits, NULL, 0);
|
t1 = strtoull(digits, NULL, 0);
|
d1 += static_cast<double>(t1)/divrate;
|
d1 += static_cast<double>(t1)/divrate;
|
if (negative) {
|
if (negative) {
|
d1 = -d1;
|
d1 = -d1;
|
}
|
}
|
out->make_floating(d1);
|
out->make_floating(d1);
|
} else {
|
} else {
|
if (negative) {
|
if (negative) {
|
t1 = -t1;
|
t1 = -t1;
|
}
|
}
|
out->make_int64(t1);
|
out->make_int64(t1);
|
}
|
}
|
off = skip_special_symbols(cfg, off);
|
off = skip_special_symbols(cfg, off);
|
}
|
}
|
/** Guard to skip wrong formatted string and avoid hanging: */
|
/** Guard to skip wrong formatted string and avoid hanging: */
|
if (off == checkstart) {
|
if (off == checkstart) {
|
RISCV_printf(NULL, LOG_ERROR,
|
RISCV_printf(NULL, LOG_ERROR,
|
"JSON parser error: Can't detect format");
|
"JSON parser error: Can't detect format");
|
out->attr_free();
|
out->attr_free();
|
return -1;
|
return -1;
|
}
|
}
|
return 0;
|
return 0;
|
}
|
}
|
|
|
} // namespace debugger
|
} // namespace debugger
|
|
|