/*----------------------------------------------------------------------------*/ /* Copyright (c) FIRST 2015. All Rights Reserved. */ /* Open Source Software - may be modified and shared by FRC teams. The code */ /* must be accompanied by the FIRST BSD license file in the root directory of */ /* the project. */ /*----------------------------------------------------------------------------*/ #include "nt_Value.h" #include "Value_internal.h" using namespace nt; Value::Value() { m_val.type = NT_UNASSIGNED; } Value::Value(NT_Type type, const private_init&) { m_val.type = type; if (m_val.type == NT_BOOLEAN_ARRAY) m_val.data.arr_boolean.arr = nullptr; else if (m_val.type == NT_DOUBLE_ARRAY) m_val.data.arr_double.arr = nullptr; else if (m_val.type == NT_STRING_ARRAY) m_val.data.arr_string.arr = nullptr; } Value::~Value() { if (m_val.type == NT_BOOLEAN_ARRAY) delete[] m_val.data.arr_boolean.arr; else if (m_val.type == NT_DOUBLE_ARRAY) delete[] m_val.data.arr_double.arr; else if (m_val.type == NT_STRING_ARRAY) delete[] m_val.data.arr_string.arr; } std::shared_ptr Value::MakeBooleanArray(llvm::ArrayRef value) { auto val = std::make_shared(NT_BOOLEAN_ARRAY, private_init()); val->m_val.data.arr_boolean.arr = new int[value.size()]; val->m_val.data.arr_boolean.size = value.size(); std::copy(value.begin(), value.end(), val->m_val.data.arr_boolean.arr); return val; } std::shared_ptr Value::MakeDoubleArray(llvm::ArrayRef value) { auto val = std::make_shared(NT_DOUBLE_ARRAY, private_init()); val->m_val.data.arr_double.arr = new double[value.size()]; val->m_val.data.arr_double.size = value.size(); std::copy(value.begin(), value.end(), val->m_val.data.arr_double.arr); return val; } std::shared_ptr Value::MakeStringArray( llvm::ArrayRef value) { auto val = std::make_shared(NT_STRING_ARRAY, private_init()); val->m_string_array = value; // point NT_Value to the contents in the vector. val->m_val.data.arr_string.arr = new NT_String[value.size()]; for (std::size_t i=0; im_val.data.arr_string.arr[i].str = const_cast(value[i].c_str()); val->m_val.data.arr_string.arr[i].len = value[i].size(); } return val; } std::shared_ptr Value::MakeStringArray( std::vector&& value) { auto val = std::make_shared(NT_STRING_ARRAY, private_init()); val->m_string_array = std::move(value); value.clear(); // point NT_Value to the contents in the vector. val->m_val.data.arr_string.arr = new NT_String[val->m_string_array.size()]; for (std::size_t i=0; im_string_array.size(); ++i) { val->m_val.data.arr_string.arr[i].str = const_cast(val->m_string_array[i].c_str()); val->m_val.data.arr_string.arr[i].len = val->m_string_array[i].size(); } return val; } void nt::ConvertToC(const Value& in, NT_Value* out) { NT_DisposeValue(out); switch (in.type()) { case NT_UNASSIGNED: return; case NT_BOOLEAN: out->data.v_boolean = in.GetBoolean() ? 1 : 0; break; case NT_DOUBLE: out->data.v_double = in.GetDouble(); break; case NT_STRING: NT_InitString(&out->data.v_string); ConvertToC(in.GetString(), &out->data.v_string); break; case NT_RAW: NT_InitString(&out->data.v_raw); ConvertToC(in.GetRaw(), &out->data.v_raw); break; case NT_RPC: NT_InitString(&out->data.v_raw); ConvertToC(in.GetRpc(), &out->data.v_raw); break; case NT_BOOLEAN_ARRAY: { auto v = in.GetBooleanArray(); out->data.arr_boolean.arr = static_cast(std::malloc(v.size() * sizeof(int))); out->data.arr_boolean.size = v.size(); std::copy(v.begin(), v.end(), out->data.arr_boolean.arr); break; } case NT_DOUBLE_ARRAY: { auto v = in.GetDoubleArray(); out->data.arr_double.arr = static_cast(std::malloc(v.size() * sizeof(double))); out->data.arr_double.size = v.size(); std::copy(v.begin(), v.end(), out->data.arr_double.arr); break; } case NT_STRING_ARRAY: { auto v = in.GetStringArray(); out->data.arr_string.arr = static_cast(std::malloc(v.size()*sizeof(NT_String))); for (size_t i=0; idata.arr_string.arr[i]); ConvertToC(v[i], &out->data.arr_string.arr[i]); } out->data.arr_string.size = v.size(); break; } default: // assert(false && "unknown value type"); return; } out->type = in.type(); } void nt::ConvertToC(llvm::StringRef in, NT_String* out) { NT_DisposeString(out); out->len = in.size(); out->str = static_cast(std::malloc(in.size()+1)); std::memcpy(out->str, in.data(), in.size()); out->str[in.size()] = '\0'; } std::shared_ptr nt::ConvertFromC(const NT_Value& value) { switch (value.type) { case NT_UNASSIGNED: return nullptr; case NT_BOOLEAN: return Value::MakeBoolean(value.data.v_boolean != 0); case NT_DOUBLE: return Value::MakeDouble(value.data.v_double); case NT_STRING: return Value::MakeString(ConvertFromC(value.data.v_string)); case NT_RAW: return Value::MakeRaw(ConvertFromC(value.data.v_raw)); case NT_RPC: return Value::MakeRpc(ConvertFromC(value.data.v_raw)); case NT_BOOLEAN_ARRAY: return Value::MakeBooleanArray(llvm::ArrayRef( value.data.arr_boolean.arr, value.data.arr_boolean.size)); case NT_DOUBLE_ARRAY: return Value::MakeDoubleArray(llvm::ArrayRef( value.data.arr_double.arr, value.data.arr_double.size)); case NT_STRING_ARRAY: { std::vector v; v.reserve(value.data.arr_string.size); for (size_t i=0; i