Skip to content

Commit

Permalink
Merge pull request #125 from mkrufky/arrays-of-arrays
Browse files Browse the repository at this point in the history
encoder: fix marshalling of nested arrays
  • Loading branch information
Shouqun committed Apr 14, 2016
2 parents d7b497f + 0d38655 commit 6bf6889
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 16 deletions.
45 changes: 30 additions & 15 deletions src/encoder.cc
Expand Up @@ -14,7 +14,7 @@ namespace Encoder {
using namespace v8;
using namespace std;

bool IsByte(Local<Value>& value)
bool IsByte(Local<Value>& value, const char* sig = NULL)
{
if(value->IsUint32()) {
int number = value->Int32Value();
Expand All @@ -25,53 +25,59 @@ namespace Encoder {
return false;
}

bool IsBoolean(Local<Value>& value)
bool IsBoolean(Local<Value>& value, const char* sig = NULL)
{
return value->IsTrue() || value->IsFalse() || value->IsBoolean();
}

bool IsUint32(Local<Value>& value)
bool IsUint32(Local<Value>& value, const char* sig = NULL)
{
return value->IsUint32();
}

bool IsInt32(Local<Value>& value)
bool IsInt32(Local<Value>& value, const char* sig = NULL)
{
return value->IsInt32();
}

bool IsNumber(Local<Value>& value)
bool IsNumber(Local<Value>& value, const char* sig = NULL)
{
return value->IsNumber();
}

bool IsString(Local<Value>& value)
bool IsString(Local<Value>& value, const char* sig = NULL)
{
return value->IsString();
}

bool IsArray(Local<Value>& value)
bool IsArray(Local<Value>& value, const char* sig = NULL)
{
return value->IsArray();
}

bool IsObject(Local<Value>& value)
bool IsObject(Local<Value>& value, const char* sig = NULL)
{
return value->IsObject();
}

typedef bool (*CheckTypeCallback) (Local<Value>& value);
bool CheckArrayItems(Local<Array>& array, CheckTypeCallback checkType)
bool HasSameSig(Local<Value>& value, const char* sig = NULL)
{
return (sig) && (strlen(sig)) &&
(0 == GetSignatureFromV8Type(value).compare(sig));
}

typedef bool (*CheckTypeCallback) (Local<Value>& value, const char* sig);
bool CheckArrayItems(Local<Array>& array, CheckTypeCallback checkType, const char* sig = NULL)
{
for (unsigned int i = 0; i < array->Length(); ++i) {
Local<Value> arrayItem = array->Get(i);
if (!checkType(arrayItem))
if (!checkType(arrayItem, sig))
return false;
}
return true;
}

const char *GetSignatureFromV8Type(Local<Value>& value)
string GetSignatureFromV8Type(Local<Value>& value)
{
if (IsBoolean(value)) {
return const_cast<char*>(DBUS_TYPE_BOOLEAN_AS_STRING);
Expand All @@ -94,8 +100,9 @@ typedef bool (*CheckTypeCallback) (Local<Value>& value);
if (IsArray(value)) {

Local<Array> arrayData = Local<Array>::Cast(value);
size_t arrayDataLength = arrayData->Length();

if (arrayData->Length() == 0) {
if (0 == arrayDataLength) {
return const_cast<char*>(DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_VARIANT_AS_STRING);
}
if (CheckArrayItems(arrayData, IsBoolean)) {
Expand All @@ -117,6 +124,13 @@ typedef bool (*CheckTypeCallback) (Local<Value>& value);
return const_cast<char*>(DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING);
}
if (CheckArrayItems(arrayData, IsArray)) {

Local<Value> lastArrayItem = arrayData->Get(arrayDataLength - 1);
string lastArrayItemSig = GetSignatureFromV8Type(lastArrayItem);

if (CheckArrayItems(arrayData, HasSameSig, lastArrayItemSig.c_str())) {
return string(const_cast<char*>(DBUS_TYPE_ARRAY_AS_STRING)).append(lastArrayItemSig);
}
return const_cast<char*>(DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_ARRAY_AS_STRING
DBUS_TYPE_VARIANT_AS_STRING);
}
Expand All @@ -134,7 +148,7 @@ typedef bool (*CheckTypeCallback) (Local<Value>& value);
DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
DBUS_DICT_ENTRY_END_CHAR_AS_STRING);
}
return NULL;
return "";
}

bool EncodeObject(Local<Value> value, DBusMessageIter *iter, const char *signature)
Expand Down Expand Up @@ -396,7 +410,8 @@ typedef bool (*CheckTypeCallback) (Local<Value>& value);
{
DBusMessageIter subIter;

const char *var_sig = GetSignatureFromV8Type(value);
string str_sig = GetSignatureFromV8Type(value);
const char *var_sig = str_sig.c_str();

if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, var_sig, &subIter)) {
printf("Can't open container for VARIANT type\n");
Expand Down
2 changes: 1 addition & 1 deletion src/encoder.h
Expand Up @@ -7,7 +7,7 @@ namespace Encoder {
using namespace v8;
using namespace std;

const char *GetSignatureFromV8Type(Local<Value>& value);
string GetSignatureFromV8Type(Local<Value>& value);
bool EncodeObject(Local<Value> value, DBusMessageIter *iter, const char *signature);
}

Expand Down

0 comments on commit 6bf6889

Please sign in to comment.