Skip to content

Commit

Permalink
Represent bitmask as array of flags
Browse files Browse the repository at this point in the history
  • Loading branch information
sonndinh committed Apr 1, 2024
1 parent 3e8cfef commit 84eaad4
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 81 deletions.
29 changes: 20 additions & 9 deletions src/NodeValueReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -386,16 +386,27 @@ bool NodeValueReader::read_long_enum(ACE_CDR::Long& value, const OpenDDS::DCPS::
bool NodeValueReader::read_bitmask(ACE_CDR::ULongLong& value, const OpenDDS::DCPS::BitmaskHelper& helper)
{
Nan::MaybeLocal<v8::Value> mlvai = use_name_ ? Nan::Get(current_object_, current_property_name_) : Nan::Get(current_object_, current_index_);
if (!mlvai.IsEmpty()) {
std::string temp;
if (read_string(temp)) {
value = string_to_bitmask(temp, helper);
return true;
}
}
if (!mlvai.IsEmpty() && mlvai.ToLocalChecked()->IsObject()) {
v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(mlvai.ToLocalChecked());
if (!array.IsEmpty()) {
OPENDDS_VECTOR(OpenDDS::DCPS::String) flag_names(array->Length());
for (uint32_t i = 0; i < array->Length(); ++i) {
Nan::MaybeLocal<v8::Value> mlv = Nan::Get(array, i);
if (mlv.IsEmpty()) {
return false;
}
Nan::MaybeLocal<v8::String> mlstr = Nan::To<v8::String>(mlv.ToLocalChecked());
if (mlstr.IsEmpty()) {
return false;
}
Nan::Utf8String flag(mlstr.ToLocalChecked());
flag_names[i] = *flag;
}

if (primitive_helper<v8::Integer>(value, &v8::Value::IsNumber, strtoull)) {
return true;
if (helper.get_value(value, flag_names)) {
return true;
}
}
}

return false;
Expand Down
109 changes: 55 additions & 54 deletions src/NodeValueWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ void NodeValueWriter::use_bigint(bool value)

bool NodeValueWriter::begin_struct(OpenDDS::DCPS::Extensibility /*extensibility*/)
{
object_helper<v8::Object>();
return true;
return object_helper<v8::Object>();
}

bool NodeValueWriter::end_struct()
Expand All @@ -49,8 +48,7 @@ bool NodeValueWriter::end_struct_member()

bool NodeValueWriter::begin_union(OpenDDS::DCPS::Extensibility /*extensibility*/)
{
object_helper<v8::Object>();
return true;
return object_helper<v8::Object>();
}

bool NodeValueWriter::end_union()
Expand Down Expand Up @@ -86,8 +84,7 @@ bool NodeValueWriter::end_union_member()

bool NodeValueWriter::begin_array(OpenDDS::XTypes::TypeKind /*elem_kind*/)
{
object_helper<v8::Array>();
return true;
return object_helper<v8::Array>();
}

bool NodeValueWriter::end_array()
Expand All @@ -101,8 +98,7 @@ bool NodeValueWriter::end_array()

bool NodeValueWriter::begin_sequence(OpenDDS::XTypes::TypeKind /*elem_kind*/, ACE_CDR::ULong /*length*/)
{
object_helper<v8::Array>();
return true;
return object_helper<v8::Array>();
}

bool NodeValueWriter::end_sequence()
Expand All @@ -127,121 +123,112 @@ bool NodeValueWriter::end_element()

bool NodeValueWriter::write_boolean(ACE_CDR::Boolean value)
{
primitive_helper<ACE_CDR::Boolean, v8::Boolean>(value);
return true;
return primitive_helper<ACE_CDR::Boolean, v8::Boolean>(value);
}

bool NodeValueWriter::write_byte(ACE_CDR::Octet value)
{
primitive_helper<ACE_CDR::Octet, v8::Integer>(value);
return true;
return primitive_helper<ACE_CDR::Octet, v8::Integer>(value);
}

#if OPENDDS_HAS_EXPLICIT_INTS

bool NodeValueWriter::write_int8(ACE_CDR::Int8 value)
{
primitive_helper<ACE_CDR::Int8, v8::Integer>(value);
return true;
return primitive_helper<ACE_CDR::Int8, v8::Integer>(value);
}

bool NodeValueWriter::write_uint8(ACE_CDR::UInt8 value)
{
primitive_helper<ACE_CDR::UInt8, v8::Integer>(value);
return true;
return primitive_helper<ACE_CDR::UInt8, v8::Integer>(value);
}
#endif

bool NodeValueWriter::write_int16(ACE_CDR::Short value)
{
primitive_helper<ACE_CDR::Short, v8::Integer>(value);
return true;
return primitive_helper<ACE_CDR::Short, v8::Integer>(value);
}

bool NodeValueWriter::write_uint16(ACE_CDR::UShort value)
{
primitive_helper<ACE_CDR::UShort, v8::Integer>(value);
return true;
return primitive_helper<ACE_CDR::UShort, v8::Integer>(value);
}

bool NodeValueWriter::write_int32(ACE_CDR::Long value)
{
primitive_helper<ACE_CDR::Long, v8::Integer>(value);
return true;
return primitive_helper<ACE_CDR::Long, v8::Integer>(value);
}

bool NodeValueWriter::write_uint32(ACE_CDR::ULong value)
{
primitive_helper<ACE_CDR::ULong, v8::Integer>(value);
return true;
return primitive_helper<ACE_CDR::ULong, v8::Integer>(value);
}

bool NodeValueWriter::write_int64(ACE_CDR::LongLong value)
{
if (value <= NODE_MAX_SAFE_INT) {
primitive_helper<ACE_CDR::LongLong, v8::Number>(value);
return true;
return primitive_helper<ACE_CDR::LongLong, v8::Number>(value);
}

bool ret = true;
#ifdef HAS_BIGINT
if (use_bigint_) {
v8::MaybeLocal<v8::BigInt> v8_value = v8::BigInt::New(v8::Isolate::GetCurrent(), static_cast<int64_t>(value));
value_helper<v8::BigInt>(v8_value);
ret = value_helper<v8::BigInt>(v8_value);
} else {
#endif
char buff[21]; // 2^63 is 19 characters long in decimal representation, plus optional sign, plus null
std::sprintf(buff, ACE_INT64_FORMAT_SPECIFIER_ASCII, value);
v8::MaybeLocal<v8::String> v8_value = Nan::New<v8::String>(buff, std::strlen(buff));
value_helper<v8::String>(v8_value);
ret = value_helper<v8::String>(v8_value);
#ifdef HAS_BIGINT
}
#endif
return true;

return ret;
}

bool NodeValueWriter::write_uint64(ACE_CDR::ULongLong value)
{
if (value <= static_cast<ACE_CDR::ULongLong>(NODE_MAX_SAFE_INT)) {
primitive_helper<ACE_CDR::ULongLong, v8::Number>(value);
return true;
return primitive_helper<ACE_CDR::ULongLong, v8::Number>(value);
}

bool ret = true;
#ifdef HAS_BIGINT
if (use_bigint_) {
v8::MaybeLocal<v8::BigInt> v8_value = v8::BigInt::NewFromUnsigned(v8::Isolate::GetCurrent(), static_cast<uint64_t>(value));
value_helper<v8::BigInt>(v8_value);
ret = value_helper<v8::BigInt>(v8_value);
} else {
#endif
char buff[21]; // 2^64 is 20 characters long in decimal representation, plus null
std::sprintf(buff, ACE_UINT64_FORMAT_SPECIFIER_ASCII, value);
v8::MaybeLocal<v8::String> v8_value = Nan::New<v8::String>(buff, std::strlen(buff));
value_helper<v8::String>(v8_value);
ret = value_helper<v8::String>(v8_value);
#ifdef HAS_BIGINT
}
#endif
return true;

return ret;
}

bool NodeValueWriter::write_float32(ACE_CDR::Float value)
{
primitive_helper<ACE_CDR::Float, v8::Number>(value);
return true;
return primitive_helper<ACE_CDR::Float, v8::Number>(value);
}

bool NodeValueWriter::write_float64(ACE_CDR::Double value)
{
primitive_helper<ACE_CDR::Double, v8::Number>(value);
return true;
return primitive_helper<ACE_CDR::Double, v8::Number>(value);
}

bool NodeValueWriter::write_float128(ACE_CDR::LongDouble value)
{
#if ACE_SIZEOF_LONG_DOUBLE == 16
primitive_helper<ACE_CDR::LongDouble, v8::Number>(value);
return primitive_helper<ACE_CDR::LongDouble, v8::Number>(value);
#else
primitive_helper<ACE_CDR::LongDouble::NativeImpl, v8::Number>(value);
return primitive_helper<ACE_CDR::LongDouble::NativeImpl, v8::Number>(value);
#endif
return true;
}

bool NodeValueWriter::write_fixed(const ACE_CDR::Fixed& /*value*/)
Expand All @@ -252,23 +239,20 @@ bool NodeValueWriter::write_fixed(const ACE_CDR::Fixed& /*value*/)
bool NodeValueWriter::write_char8(ACE_CDR::Char value)
{
v8::MaybeLocal<v8::String> v8_value = Nan::New<v8::String>(&value, 1);
value_helper<v8::String>(v8_value);
return true;
return value_helper<v8::String>(v8_value);
}

bool NodeValueWriter::write_char16(ACE_CDR::WChar value)
{
const uint16_t c = static_cast<uint16_t>(value);
v8::MaybeLocal<v8::String> v8_value = Nan::New<v8::String>(&c, 1);
value_helper<v8::String>(v8_value);
return true;
return value_helper<v8::String>(v8_value);
}

bool NodeValueWriter::write_string(const ACE_CDR::Char* value, size_t length)
{
v8::MaybeLocal<v8::String> v8_value = Nan::New<v8::String>(value, length);
value_helper<v8::String>(v8_value);
return true;
return value_helper<v8::String>(v8_value);
}

bool NodeValueWriter::write_wstring(const ACE_CDR::WChar* value, size_t length)
Expand All @@ -278,9 +262,8 @@ bool NodeValueWriter::write_wstring(const ACE_CDR::WChar* value, size_t length)
str[i] = static_cast<uint16_t>(value[i]);
}
v8::MaybeLocal<v8::String> v8_value = Nan::New<v8::String>(str, length);
value_helper<v8::String>(v8_value);
delete [] str;
return true;
return value_helper<v8::String>(v8_value);
}

bool NodeValueWriter::write_enum(ACE_CDR::Long value, const OpenDDS::DCPS::EnumHelper& helper)
Expand All @@ -290,15 +273,33 @@ bool NodeValueWriter::write_enum(ACE_CDR::Long value, const OpenDDS::DCPS::EnumH
return false;
}
v8::MaybeLocal<v8::String> v8_value = Nan::New<v8::String>(name);
value_helper<v8::String>(v8_value);
return true;
return value_helper<v8::String>(v8_value);
}

bool NodeValueWriter::write_bitmask(ACE_CDR::ULongLong value, const OpenDDS::DCPS::BitmaskHelper& helper)
{
const OpenDDS::DCPS::String flags = bitmask_to_string(value, helper);
v8::MaybeLocal<v8::String> v8_value = Nan::New<v8::String>(flags.c_str());
value_helper<v8::String>(v8_value);
OPENDDS_VECTOR(OpenDDS::DCPS::String) flags;
helper.get_names(flags, value);
v8::MaybeLocal<v8::Object> array = Nan::New<v8::Array>();
if (array.IsEmpty()) {
return false;
}

uint32_t i = 0;
for (OPENDDS_VECTOR(OpenDDS::DCPS::String)::const_iterator it = flags.begin();
it != flags.end(); ++it, ++i) {
v8::MaybeLocal<v8::String> flag = Nan::New<v8::String>(*it);
if (flag.IsEmpty()) {
return false;
}
Nan::Set(array.ToLocalChecked(), i, flag.ToLocalChecked());
}

if (object_stack_.empty()) {
return false;
}

insert_object(array);
return true;
}

Expand Down
53 changes: 35 additions & 18 deletions src/NodeValueWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,57 +61,74 @@ class NodeValueWriter : public OpenDDS::DCPS::ValueWriter {
bool write_absent_value();

template <typename V>
void value_helper(v8::MaybeLocal<V>& v8_value)
bool value_helper(v8::MaybeLocal<V>& v8_value)
{
if (v8_value.IsEmpty()) {
return;
return false;
}

if (object_stack_.empty()) {
return;
return false;
}

if (object_stack_.back()->IsArray()) {
uint32_t next_index = static_cast<uint32_t>(next_index_);
Nan::Set(object_stack_.back(), next_index, v8_value.ToLocalChecked());
} else {
v8::MaybeLocal<v8::String> key = Nan::New<v8::String>(next_key_.c_str());
if (!key.IsEmpty()) {
Nan::Set(object_stack_.back(), key.ToLocalChecked(), v8_value.ToLocalChecked());
if (key.IsEmpty()) {
return false;
}
Nan::Set(object_stack_.back(), key.ToLocalChecked(), v8_value.ToLocalChecked());
}
return true;
}

template <typename T, typename V>
void primitive_helper(T value)
bool primitive_helper(T value)
{
v8::MaybeLocal<V> v8_value = Nan::New<V>(value);
value_helper<V>(v8_value);
return value_helper<V>(v8_value);
}

bool insert_object(v8::MaybeLocal<v8::Object>& obj)
{
if (object_stack_.back()->IsArray()) {
uint32_t next_index = static_cast<uint32_t>(next_index_);
Nan::Set(object_stack_.back(), next_index, obj.ToLocalChecked());
} else {
v8::MaybeLocal<v8::String> key = Nan::New<v8::String>(next_key_.c_str());
if (key.IsEmpty()) {
return false;
}
Nan::Set(object_stack_.back(), key.ToLocalChecked(), obj.ToLocalChecked());
}
return true;
}

template <typename T>
void object_helper()
bool object_helper()
{
v8::MaybeLocal<v8::Object> temp = Nan::New<T>();
if (temp.IsEmpty()) {
return;
return false;
}

if (!object_stack_.empty()) {
if (object_stack_.back()->IsArray()) {
uint32_t next_index = static_cast<uint32_t>(next_index_);
Nan::Set(object_stack_.back(), next_index, temp.ToLocalChecked());
} else {
v8::MaybeLocal<v8::String> key = Nan::New<v8::String>(next_key_.c_str());
if (!key.IsEmpty()) {
Nan::Set(object_stack_.back(), key.ToLocalChecked(), temp.ToLocalChecked());
}
if (!insert_object(temp)) {
return false;
}
}
object_stack_.push_back(temp.ToLocalChecked());
return true;
}

v8::Local<v8::Object> get_result() { v8::Local<v8::Object> result = result_; result_.Clear(); return result; }
v8::Local<v8::Object> get_result()
{
v8::Local<v8::Object> result = result_;
result_.Clear();
return result;
}

private:

Expand Down

0 comments on commit 84eaad4

Please sign in to comment.