From 167e818b396e4d4d77a56a993a0eaafd53b5522a Mon Sep 17 00:00:00 2001 From: rajsite Date: Mon, 18 Jun 2018 17:52:19 -0500 Subject: [PATCH 01/67] Add the findValueRef API function --- make-it/EmMakefile | 1 + source/core/CEntryPoints.cpp | 12 ++++ source/include/CEntryPoints.h | 1 + source/io/module_eggShell.js | 68 ++++++++++++++------ test-it/karma/publicapi/FindValueRef.Test.js | 27 ++++++++ 5 files changed, 88 insertions(+), 21 deletions(-) create mode 100644 test-it/karma/publicapi/FindValueRef.Test.js diff --git a/make-it/EmMakefile b/make-it/EmMakefile index 9c50e49c1..1ce7a4194 100644 --- a/make-it/EmMakefile +++ b/make-it/EmMakefile @@ -106,6 +106,7 @@ EM_EXPORTS = -s EXPORTED_FUNCTIONS="[\ '_EggShell_REPL',\ '_EggShell_ExecuteSlices',\ '_EggShell_Delete',\ + '_EggShell_FindValue',\ '_EggShell_ReadDouble',\ '_EggShell_WriteDouble',\ '_EggShell_ReadValueString',\ diff --git a/source/core/CEntryPoints.cpp b/source/core/CEntryPoints.cpp index ade53258d..f2a44e985 100644 --- a/source/core/CEntryPoints.cpp +++ b/source/core/CEntryPoints.cpp @@ -118,6 +118,18 @@ VIREO_EXPORT Int32 EggShell_PokeMemory(TypeManagerRef tm, } } //------------------------------------------------------------ +//! Get a reference to the type pointer and data for a symbol. +VIREO_EXPORT EggShellResult EggShell_FindValue(TypeManagerRef tm, const char* viName, const char* eltName, TypeRef* typeRefLocation, void** dataRefLocation) +{ + SubString objectName(viName); + SubString path(eltName); + *typeRefLocation = tm->GetObjectElementAddressFromPath(&objectName, &path, dataRefLocation, true); + if (*typeRefLocation == nullptr) + return kEggShellResult_ObjectNotFoundAtPath; + + return kEggShellResult_Success; +} +//------------------------------------------------------------ //! Write a numeric value to a symbol. Value will be coerced as needed. VIREO_EXPORT void EggShell_WriteDouble(TypeManagerRef tm, const char* viName, const char* eltName, Double d) { diff --git a/source/include/CEntryPoints.h b/source/include/CEntryPoints.h index 5f3b567fd..be03d1e7f 100644 --- a/source/include/CEntryPoints.h +++ b/source/include/CEntryPoints.h @@ -35,6 +35,7 @@ VIREO_EXPORT Int32 EggShell_PeekMemory(TypeManagerRef tm, const char* viName, co Int32 bufferSize, char* buffer); VIREO_EXPORT Int32 EggShell_PokeMemory(TypeManagerRef tm, const char* viName, const char* eltName, Int32 bufferSize, char* buffer); +VIREO_EXPORT EggShellResult EggShell_FindValue(TypeManagerRef tm, const char* viName, const char* eltName, TypeRef* typeRefLocation, void** dataRefLocation); VIREO_EXPORT void EggShell_WriteDouble(TypeManagerRef tm, const char* viName, const char* eltName, Double d); VIREO_EXPORT Double EggShell_ReadDouble(TypeManagerRef tm, const char* viName, const char* eltName); VIREO_EXPORT void EggShell_WriteValueString(TypeManagerRef tm, const char* viName, const char* eltName, diff --git a/source/io/module_eggShell.js b/source/io/module_eggShell.js index 6b47a8173..e6b7c7dad 100644 --- a/source/io/module_eggShell.js +++ b/source/io/module_eggShell.js @@ -75,6 +75,29 @@ // Private Instance Variables (per vireo instance) var NULL = 0; + var POINTER_SIZE = 4; + + // Keep in sync with EggShellResult in CEntryPoints.h + var eggShellResultEnum = { + 0: 'Success', + 1: 'ObjectNotFoundAtPath', + 2: 'UnexpectedObjectType', + 3: 'InvalidResultPointer', + 4: 'UnableToCreateReturnBuffer' + }; + + // Keep in sync with NIError in DataTypes.h + var niErrorEnum = { + 0: 'Success', + 1: 'InsufficientResources', + 2: 'ResourceNotFound', + 3: 'ArrayRankMismatch', + 4: 'CantDecode', + 5: 'CantEncode', + 6: 'LogicFailure', + 7: 'ValueTruncated' + }; + var Vireo_Version = Module.cwrap('Vireo_Version', 'number', []); var Vireo_MaxExecWakeUpTime = Module.cwrap('Vireo_MaxExecWakeUpTime', 'number', []); var EggShell_Create = Module.cwrap('EggShell_Create', 'number', ['number']); @@ -168,6 +191,30 @@ v_userShell = EggShell_Create(v_root); }; + Module.eggShell.findValueRef = publicAPI.eggShell.findValueRef = function (vi, path) { + var stack = Module.stackSave(); + + var viStackPointer = Module.coreHelpers.writeJSStringToStack(vi); + var pathStackPointer = Module.coreHelpers.writeJSStringToStack(path); + var typeStackPointer = Module.stackAlloc(POINTER_SIZE); + var dataStackPointer = Module.stackAlloc(POINTER_SIZE); + + var eggShellResult = Module._EggShell_FindValue(v_userShell, viStackPointer, pathStackPointer, typeStackPointer, dataStackPointer); + if (eggShellResult !== 0) { + throw new Error('A ValueRef could not be made for the following reason: ' + eggShellResultEnum[eggShellResult] + + ' (error code: ' + eggShellResult + ')' + + ' (vi name: ' + vi + ')' + + ' (path: ' + path + ')'); + } + var valueRef = { + typeRef: Module.getValue(typeStackPointer, 'i32'), + dataRef: Module.getValue(dataStackPointer, 'i32') + }; + + Module.stackRestore(stack); + return valueRef; + }; + Module.eggShell.readDouble = publicAPI.eggShell.readDouble = function (vi, path) { return EggShell_ReadDouble(v_userShell, vi, path); }; @@ -231,27 +278,6 @@ } }; - // Keep in sync with EggShellResult in CEntryPoints.h - var eggShellResultEnum = { - 0: 'Success', - 1: 'ObjectNotFoundAtPath', - 2: 'UnexpectedObjectType', - 3: 'InvalidResultPointer', - 4: 'UnableToCreateReturnBuffer' - }; - - // Keep in sync with NIError in DataTypes.h - var niErrorEnum = { - 0: 'Success', - 1: 'InsufficientResources', - 2: 'ResourceNotFound', - 3: 'ArrayRankMismatch', - 4: 'CantDecode', - 5: 'CantEncode', - 6: 'LogicFailure', - 7: 'ValueTruncated' - }; - var groupByDimensionLength = function (arr, startIndex, arrLength, dimensionLength) { var i, retArr, currArr, currArrIndex; diff --git a/test-it/karma/publicapi/FindValueRef.Test.js b/test-it/karma/publicapi/FindValueRef.Test.js new file mode 100644 index 000000000..482f53b07 --- /dev/null +++ b/test-it/karma/publicapi/FindValueRef.Test.js @@ -0,0 +1,27 @@ +describe('The Vireo EggShell findValueRef api can', function () { + 'use strict'; + // Reference aliases + var Vireo = window.NationalInstruments.Vireo.Vireo; + var vireoRunner = window.testHelpers.vireoRunner; + var fixtures = window.testHelpers.fixtures; + + var vireo = new Vireo(); + + var publicApiMultipleTypesViaUrl = fixtures.convertToAbsoluteFromFixturesDir('publicapi/MultipleTypes.via'); + var viName = 'MyVI'; + + beforeAll(function (done) { + fixtures.preloadAbsoluteUrls([ + publicApiMultipleTypesViaUrl + ], done); + }); + + beforeAll(function () { + vireoRunner.rebootAndLoadVia(vireo, publicApiMultipleTypesViaUrl); + }); + + it('find a double', function () { + var valueRef = vireo.eggShell.findValueRef(viName, 'dataItem_NumericDouble'); + console.log(valueRef); + }); +}); From c4fbfd7cfe5c3c2d5ee47b03c65108b10aace08e Mon Sep 17 00:00:00 2001 From: rajsite Date: Mon, 18 Jun 2018 19:44:08 -0500 Subject: [PATCH 02/67] Update readDouble for ValueRef api --- source/core/CEntryPoints.cpp | 13 ++-- source/core/TypeAndDataManager.cpp | 36 ++++++----- source/include/CEntryPoints.h | 2 +- source/include/TypeAndDataManager.h | 2 +- source/io/module_eggShell.js | 21 +++++-- .../fixtures/publicapi/MultipleTypes.via | 22 +++++++ test-it/karma/publicapi/Double.Test.js | 60 +++++++++++++++++++ test-it/karma/publicapi/FPSync.Test.js | 3 +- 8 files changed, 127 insertions(+), 32 deletions(-) create mode 100644 test-it/karma/publicapi/Double.Test.js diff --git a/source/core/CEntryPoints.cpp b/source/core/CEntryPoints.cpp index f2a44e985..2af4913ea 100644 --- a/source/core/CEntryPoints.cpp +++ b/source/core/CEntryPoints.cpp @@ -145,16 +145,11 @@ VIREO_EXPORT void EggShell_WriteDouble(TypeManagerRef tm, const char* viName, co } //------------------------------------------------------------ //! Read a numeric value from a symbol. Value will be coerced as needed. -VIREO_EXPORT Double EggShell_ReadDouble(TypeManagerRef tm, const char* viName, const char* eltName) +VIREO_EXPORT NIError EggShell_ReadDouble(TypeManagerRef tm, const TypeRef actualType, const void* pData, Double* result) { - void *pData = nullptr; - SubString objectName(viName); - SubString path(eltName); - TypeRef actualType = tm->GetObjectElementAddressFromPath(&objectName, &path, &pData, true); - if (actualType == nullptr) - return -1; - - return ReadDoubleFromMemory(actualType, pData); + NIError err = kNIError_Success; + *result = ReadDoubleFromMemory(actualType, pData, &err); + return err; } //------------------------------------------------------------ // Write a string value to a symbol. Value will be parsed according to format designated. diff --git a/source/core/TypeAndDataManager.cpp b/source/core/TypeAndDataManager.cpp index c341aafe7..a6e3b33ea 100644 --- a/source/core/TypeAndDataManager.cpp +++ b/source/core/TypeAndDataManager.cpp @@ -2640,9 +2640,9 @@ NIError WriteIntToMemory(TypeRef type, void* pData, IntMax value) } //------------------------------------------------------------ //! Read a IEEE754 double value from memory converting as necessary. -Double ReadDoubleFromMemory(TypeRef type, void* pData) +Double ReadDoubleFromMemory(TypeRef type, const void* pData, NIError* errResult) { - Boolean isErr = false; + NIError err = kNIError_Success; Double value = 0.0; EncodingEnum encoding = type->BitEncoding(); Int32 aqSize = type->TopAQSize(); @@ -2651,33 +2651,33 @@ Double ReadDoubleFromMemory(TypeRef type, void* pData) switch (aqSize) { case 4: value = *(Single*)pData; break; case 8: value = *(Double*)pData; break; - default: isErr = true; break; + default: err = kNIError_kCantDecode; break; } break; case kEncoding_S2CInt: case kEncoding_DimInt: switch (aqSize) { - case 1: value = *(Int8*)pData; break; - case 2: value = *(Int16*)pData; break; - case 4: value = *(Int32*)pData; break; - case 8: value = static_cast(*(Int64*)pData); break; - default: isErr = true; break; + case 1: value = *(Int8*)pData; break; + case 2: value = *(Int16*)pData; break; + case 4: value = *(Int32*)pData; break; + case 8: value = static_cast(*(Int64*)pData); break; + default: err = kNIError_kCantDecode; break; } break; case kEncoding_UInt: case kEncoding_Enum: switch (aqSize) { - case 1: value = *(UInt8*)pData; break; - case 2: value = *(UInt16*)pData; break; - case 4: value = *(UInt32*)pData; break; - case 8: value = static_cast(*(UInt64*)pData); break; - default: isErr = true; break; + case 1: value = *(UInt8*)pData; break; + case 2: value = *(UInt16*)pData; break; + case 4: value = *(UInt32*)pData; break; + case 8: value = static_cast(*(UInt64*)pData); break; + default: err = kNIError_kCantDecode; break; } break; case kEncoding_Boolean: switch (aqSize) { case 1: value = (*(UInt8*)pData) ? 1.0 : 0.0; break; - default: isErr = true; break; + default: err = kNIError_kCantDecode; break; } break; case kEncoding_Cluster: @@ -2687,14 +2687,18 @@ Double ReadDoubleFromMemory(TypeRef type, void* pData) } break; default: - isErr = true; + err = kNIError_kCantDecode; break; } - if (isErr) { + if (err != kNIError_Success) { gPlatform.IO.Printf("(Error \"ReadDoubleFromMemory encoding:%d aqSize:%d\")\n", (int)encoding, (int)aqSize); } + if (errResult != nullptr) { + *errResult = err; + } + return value; } //------------------------------------------------------------ diff --git a/source/include/CEntryPoints.h b/source/include/CEntryPoints.h index be03d1e7f..47624de8a 100644 --- a/source/include/CEntryPoints.h +++ b/source/include/CEntryPoints.h @@ -37,7 +37,7 @@ VIREO_EXPORT Int32 EggShell_PokeMemory(TypeManagerRef tm, const char* viName, co Int32 bufferSize, char* buffer); VIREO_EXPORT EggShellResult EggShell_FindValue(TypeManagerRef tm, const char* viName, const char* eltName, TypeRef* typeRefLocation, void** dataRefLocation); VIREO_EXPORT void EggShell_WriteDouble(TypeManagerRef tm, const char* viName, const char* eltName, Double d); -VIREO_EXPORT Double EggShell_ReadDouble(TypeManagerRef tm, const char* viName, const char* eltName); +VIREO_EXPORT NIError EggShell_ReadDouble(TypeManagerRef tm, const TypeRef actualType, const void* pData, Double* result); VIREO_EXPORT void EggShell_WriteValueString(TypeManagerRef tm, const char* viName, const char* eltName, const char* format, const char* value); VIREO_EXPORT const char* EggShell_ReadValueString(TypeManagerRef tm, const char* viName, const char* eltName, diff --git a/source/include/TypeAndDataManager.h b/source/include/TypeAndDataManager.h index 06ce4e4a8..2b92e8af9 100644 --- a/source/include/TypeAndDataManager.h +++ b/source/include/TypeAndDataManager.h @@ -347,7 +347,7 @@ class TypeManager // Utility functions to read and write numbers to non aligned memory based on size and encoding IntMax ReadIntFromMemory(TypeRef type, void* pData); NIError WriteIntToMemory(TypeRef type, void* pData, IntMax value); -Double ReadDoubleFromMemory(TypeRef type, void* pData); +Double ReadDoubleFromMemory(TypeRef type, const void* pData, NIError* errResult = nullptr); NIError WriteDoubleToMemory(TypeRef type, void* pData, Double value); IntMax ConvertNumericRange(EncodingEnum encoding, Int32 size, IntMax input); //------------------------------------------------------------ diff --git a/source/io/module_eggShell.js b/source/io/module_eggShell.js index e6b7c7dad..99eb6671c 100644 --- a/source/io/module_eggShell.js +++ b/source/io/module_eggShell.js @@ -32,7 +32,6 @@ 'Vireo_MaxExecWakeUpTime', 'EggShell_Create', 'EggShell_Delete', - 'EggShell_ReadDouble', 'EggShell_WriteDouble', 'EggShell_WriteValueString', 'EggShell_GetPointer', @@ -76,6 +75,7 @@ // Private Instance Variables (per vireo instance) var NULL = 0; var POINTER_SIZE = 4; + var DOUBLE_SIZE = 8; // Keep in sync with EggShellResult in CEntryPoints.h var eggShellResultEnum = { @@ -102,7 +102,6 @@ var Vireo_MaxExecWakeUpTime = Module.cwrap('Vireo_MaxExecWakeUpTime', 'number', []); var EggShell_Create = Module.cwrap('EggShell_Create', 'number', ['number']); var EggShell_Delete = Module.cwrap('EggShell_Delete', 'number', ['number']); - var EggShell_ReadDouble = Module.cwrap('EggShell_ReadDouble', 'number', ['number', 'string', 'string']); var EggShell_WriteDouble = Module.cwrap('EggShell_WriteDouble', 'void', ['number', 'string', 'string', 'number']); var EggShell_WriteValueString = Module.cwrap('EggShell_WriteValueString', 'void', ['number', 'string', 'string', 'string', 'string']); var EggShell_GetPointer = Module.cwrap('EggShell_GetPointer', 'number', ['number', 'string', 'string', 'number', 'number']); @@ -215,8 +214,22 @@ return valueRef; }; - Module.eggShell.readDouble = publicAPI.eggShell.readDouble = function (vi, path) { - return EggShell_ReadDouble(v_userShell, vi, path); + Module.eggShell.readDouble = publicAPI.eggShell.readDouble = function (valueRef) { + var stack = Module.stackSave(); + var resultPointer = Module.stackAlloc(DOUBLE_SIZE); + + // TODO mraj should we try to resolve the typeref name on error for more context? + var niError = Module._EggShell_ReadDouble(v_userShell, valueRef.typeRef, valueRef.dataRef, resultPointer); + if (niError !== 0) { + throw new Error('Loading VIA failed for the following reason: ' + niErrorEnum[niError] + + ' (error code: ' + niError + ')' + + ' (typeRef: ' + valueRef.typeRef + ')' + + ' (dataRef: ' + valueRef.dataRef + ')'); + } + var result = Module.getValue(resultPointer, 'double'); + + Module.stackRestore(stack); + return result; }; Module.eggShell.writeDouble = publicAPI.eggShell.writeDouble = function (vi, path, value) { diff --git a/test-it/karma/fixtures/publicapi/MultipleTypes.via b/test-it/karma/fixtures/publicapi/MultipleTypes.via index 6b63818d5..f41ef68f2 100644 --- a/test-it/karma/fixtures/publicapi/MultipleTypes.via +++ b/test-it/karma/fixtures/publicapi/MultipleTypes.via @@ -134,6 +134,28 @@ define (MyVI dv(.VirtualInstrument ( e(dv(.Int64 -1152921504606846976)dataItem_Numeric64) e(dv(.UInt64 18446744073709551615) dataItem_NumericU64) e(dv(.ComplexDouble (1337.73 -9283.12))dataItem_Complex) + e(dv(.Boolean true) booleanTrueValue) + e(dv(.Boolean false) booleanFalseValue) + e(dv(.Int8 -128) int8MinValue) + e(dv(.Int8 127) int8MaxValue) + e(dv(.Int16 -32768) int16MinValue) + e(dv(.Int16 32767) int16MaxValue) + e(dv(.Int32 -2147483648) int32MinValue) + e(dv(.Int32 2147483647) int32MaxValue) + e(dv(.Int64 -9007199254740991) int64MinSafeInteger) + e(dv(.Int64 9007199254740991) int64MaxSafeInteger) + e(dv(.Int64 -9223372036854775808) int64MinValue) + e(dv(.Int64 9223372036854775807) int64MaxValue) + e(dv(.UInt8 0) uInt8MinValue) + e(dv(.UInt8 255) uInt8MaxValue) + e(dv(.UInt16 0) uInt16MinValue) + e(dv(.UInt16 65535) uInt16MaxValue) + e(dv(.UInt32 0) uInt32MinValue) + e(dv(.UInt32 4294967295) uInt32MaxValue) + e(dv(.UInt64 0) uInt64MinSafeInteger) + e(dv(.UInt64 9007199254740991) uInt64MaxSafeInteger) + e(dv(.UInt64 0) uInt64MinValue) + e(dv(.UInt64 18446744073709551615) uInt64MaxValue) e(dv(.Boolean true)dataItem_Boolean) e(dv(.Timestamp (3564057536 7811758927381448193))dataItem_Timestamp) e(dv(.AnalogWaveform<.Double> ((300 123) 8.8 (5.5 6.6 7.7 8.8) ) ) wave_Double) diff --git a/test-it/karma/publicapi/Double.Test.js b/test-it/karma/publicapi/Double.Test.js new file mode 100644 index 000000000..189d4458a --- /dev/null +++ b/test-it/karma/publicapi/Double.Test.js @@ -0,0 +1,60 @@ +describe('The Vireo EggShell Double api can', function () { + 'use strict'; + // Reference aliases + var Vireo = window.NationalInstruments.Vireo.Vireo; + var vireoRunner = window.testHelpers.vireoRunner; + var fixtures = window.testHelpers.fixtures; + + var vireo = new Vireo(); + + var publicApiMultipleTypesViaUrl = fixtures.convertToAbsoluteFromFixturesDir('publicapi/MultipleTypes.via'); + var viName = 'MyVI'; + + var find = function (path) { + return vireo.eggShell.findValueRef(viName, path); + }; + + beforeAll(function (done) { + fixtures.preloadAbsoluteUrls([ + publicApiMultipleTypesViaUrl + ], done); + }); + + beforeAll(function () { + vireoRunner.rebootAndLoadVia(vireo, publicApiMultipleTypesViaUrl); + }); + + describe('use readDouble', function () { + it('to read different double values from memory', function () { + expect(vireo.eggShell.readDouble(find('dataItem_NumericDouble'))).toMatchIEEE754Number(123.456); + expect(vireo.eggShell.readDouble(find('dataItem_NumericDoubleNaN'))).toMatchIEEE754Number(NaN); + expect(vireo.eggShell.readDouble(find('dataItem_NumericDoublePositiveInfinity'))).toMatchIEEE754Number(Infinity); + expect(vireo.eggShell.readDouble(find('dataItem_NumericDoubleNegativeInfinity'))).toMatchIEEE754Number(-Infinity); + expect(vireo.eggShell.readDouble(find('dataItem_NumericDoublePositiveZero'))).toMatchIEEE754Number(0); + expect(vireo.eggShell.readDouble(find('dataItem_NumericDoubleNegativeZero'))).toMatchIEEE754Number(-0); + }); + + it('to read different integer types from memory', function () { + expect(vireo.eggShell.readDouble(find('int8MinValue'))).toMatchIEEE754Number(-128); + expect(vireo.eggShell.readDouble(find('int8MaxValue'))).toMatchIEEE754Number(127); + expect(vireo.eggShell.readDouble(find('int16MinValue'))).toMatchIEEE754Number(-32768); + expect(vireo.eggShell.readDouble(find('int16MaxValue'))).toMatchIEEE754Number(32767); + expect(vireo.eggShell.readDouble(find('int32MinValue'))).toMatchIEEE754Number(-2147483648); + expect(vireo.eggShell.readDouble(find('int32MaxValue'))).toMatchIEEE754Number(2147483647); + expect(vireo.eggShell.readDouble(find('int64MinSafeInteger'))).toMatchIEEE754Number(-9007199254740991); + expect(vireo.eggShell.readDouble(find('int64MaxSafeInteger'))).toMatchIEEE754Number(9007199254740991); + expect(vireo.eggShell.readDouble(find('int64MinValue'))).toMatchIEEE754Number(-9223372036854776000); // Expected precision loss, full value -9223372036854775808 + expect(vireo.eggShell.readDouble(find('int64MaxValue'))).toMatchIEEE754Number(9223372036854776000); // Expected precision loss, full value 9223372036854775807 + expect(vireo.eggShell.readDouble(find('uInt8MinValue'))).toMatchIEEE754Number(0); + expect(vireo.eggShell.readDouble(find('uInt8MaxValue'))).toMatchIEEE754Number(255); + expect(vireo.eggShell.readDouble(find('uInt16MinValue'))).toMatchIEEE754Number(0); + expect(vireo.eggShell.readDouble(find('uInt16MaxValue'))).toMatchIEEE754Number(65535); + expect(vireo.eggShell.readDouble(find('uInt32MinValue'))).toMatchIEEE754Number(0); + expect(vireo.eggShell.readDouble(find('uInt32MaxValue'))).toMatchIEEE754Number(4294967295); + expect(vireo.eggShell.readDouble(find('uInt64MinSafeInteger'))).toMatchIEEE754Number(0); + expect(vireo.eggShell.readDouble(find('uInt64MaxSafeInteger'))).toMatchIEEE754Number(9007199254740991); + expect(vireo.eggShell.readDouble(find('uInt64MinValue'))).toMatchIEEE754Number(0); + expect(vireo.eggShell.readDouble(find('uInt64MaxValue'))).toMatchIEEE754Number(18446744073709552000); // Expected precision loss, full value 18446744073709551615 + }); + }); +}); diff --git a/test-it/karma/publicapi/FPSync.Test.js b/test-it/karma/publicapi/FPSync.Test.js index 22360d3cc..6b11dd3df 100644 --- a/test-it/karma/publicapi/FPSync.Test.js +++ b/test-it/karma/publicapi/FPSync.Test.js @@ -41,7 +41,8 @@ describe('The Vireo CoreHelpers setFPSyncFunction api', function () { var trackerCalls = []; var tracker = function (fpSyncString) { - var myDouble = vireo.eggShell.readDouble(viName, 'myDouble'); + var valueRef = vireo.eggShell.findValueRef(viName, 'myDouble'); + var myDouble = vireo.eggShell.readDouble(valueRef); trackerCalls.push({ myDouble: myDouble, fpSyncString: fpSyncString From 493d545114f4b9602b07bbcecbf4f00ed4e75615 Mon Sep 17 00:00:00 2001 From: rajsite Date: Tue, 19 Jun 2018 11:21:24 -0500 Subject: [PATCH 03/67] Add the shared createValueRef function --- source/io/module_eggShell.js | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/source/io/module_eggShell.js b/source/io/module_eggShell.js index 99eb6671c..583a0fdc3 100644 --- a/source/io/module_eggShell.js +++ b/source/io/module_eggShell.js @@ -190,6 +190,13 @@ v_userShell = EggShell_Create(v_root); }; + Module.eggShell.createValueRef = function (typeRef, dataRef) { + return Object.freeze({ + typeRef: typeRef, + dataRef: dataRef + }); + }; + Module.eggShell.findValueRef = publicAPI.eggShell.findValueRef = function (vi, path) { var stack = Module.stackSave(); @@ -205,10 +212,10 @@ ' (vi name: ' + vi + ')' + ' (path: ' + path + ')'); } - var valueRef = { - typeRef: Module.getValue(typeStackPointer, 'i32'), - dataRef: Module.getValue(dataStackPointer, 'i32') - }; + + var typeRef = Module.getValue(typeStackPointer, 'i32'); + var dataRef = Module.getValue(dataStackPointer, 'i32'); + var valueRef = Module.createValueRef(typeRef, dataRef); Module.stackRestore(stack); return valueRef; From 7fa3d60973618645988c29659156d2abf222956a Mon Sep 17 00:00:00 2001 From: rajsite Date: Tue, 19 Jun 2018 13:13:59 -0500 Subject: [PATCH 04/67] Fix usage of createValueRef --- source/io/module_eggShell.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/io/module_eggShell.js b/source/io/module_eggShell.js index 583a0fdc3..1e18f5d52 100644 --- a/source/io/module_eggShell.js +++ b/source/io/module_eggShell.js @@ -215,7 +215,7 @@ var typeRef = Module.getValue(typeStackPointer, 'i32'); var dataRef = Module.getValue(dataStackPointer, 'i32'); - var valueRef = Module.createValueRef(typeRef, dataRef); + var valueRef = Module.eggShell.createValueRef(typeRef, dataRef); Module.stackRestore(stack); return valueRef; From ce1727c63afc61f2033611f1e954b4e25e2f5a64 Mon Sep 17 00:00:00 2001 From: rajsite Date: Tue, 19 Jun 2018 17:18:01 -0500 Subject: [PATCH 05/67] Test unsupported types for readDouble --- source/core/TypeAndDataManager.cpp | 6 +- .../fixtures/publicapi/MultipleTypes.via | 5 ++ test-it/karma/publicapi/Double.Test.js | 83 ++++++++++++------- test-it/karma/publicapi/FindValueRef.Test.js | 41 ++++++++- 4 files changed, 103 insertions(+), 32 deletions(-) diff --git a/source/core/TypeAndDataManager.cpp b/source/core/TypeAndDataManager.cpp index a6e3b33ea..04320a986 100644 --- a/source/core/TypeAndDataManager.cpp +++ b/source/core/TypeAndDataManager.cpp @@ -2684,6 +2684,8 @@ Double ReadDoubleFromMemory(TypeRef type, const void* pData, NIError* errResult) if (type->IsTimestamp()) { Timestamp* t = (Timestamp*) pData; value = t->ToDouble(); + } else { + err = kNIError_kCantDecode; } break; default: @@ -2740,13 +2742,15 @@ NIError WriteDoubleToMemory(TypeRef type, void* pData, Double value) switch (aqSize) { // Beware that anything that's not exactly 0.0 will be true case 1: *(UInt8*)pData = value != 0.0 ? 1 : 0; break; - default: err = kNIError_kCantEncode; break; + default: err = kNIError_kCantEncode; break; } break; case kEncoding_Cluster: if (type->IsTimestamp()) { Timestamp* t = (Timestamp*) pData; *t = Timestamp(value); + } else { + err = kNIError_kCantEncode; } break; default: err = kNIError_kCantDecode; break; diff --git a/test-it/karma/fixtures/publicapi/MultipleTypes.via b/test-it/karma/fixtures/publicapi/MultipleTypes.via index f41ef68f2..112beddb2 100644 --- a/test-it/karma/fixtures/publicapi/MultipleTypes.via +++ b/test-it/karma/fixtures/publicapi/MultipleTypes.via @@ -159,6 +159,11 @@ define (MyVI dv(.VirtualInstrument ( e(dv(.Boolean true)dataItem_Boolean) e(dv(.Timestamp (3564057536 7811758927381448193))dataItem_Timestamp) e(dv(.AnalogWaveform<.Double> ((300 123) 8.8 (5.5 6.6 7.7 8.8) ) ) wave_Double) + + e(dv(Enum8 (a b c d e f g h) 6) enum8alphabet) + e(dv(Enum16 (zero one two three four) 3) enum16numbers) + e(dv(Enum32 (red orange yellow green blue purple) 2) enum32colors) + e(dv(Enum64 (altair bajor cardassiaA cardassiaB armadillo cobra lynx marmot panda whiskyjack) 5) enum64releases) ) clump( ) diff --git a/test-it/karma/publicapi/Double.Test.js b/test-it/karma/publicapi/Double.Test.js index 189d4458a..67d52b1f2 100644 --- a/test-it/karma/publicapi/Double.Test.js +++ b/test-it/karma/publicapi/Double.Test.js @@ -10,8 +10,8 @@ describe('The Vireo EggShell Double api can', function () { var publicApiMultipleTypesViaUrl = fixtures.convertToAbsoluteFromFixturesDir('publicapi/MultipleTypes.via'); var viName = 'MyVI'; - var find = function (path) { - return vireo.eggShell.findValueRef(viName, path); + var readDouble = function (path) { + return vireo.eggShell.readDouble(vireo.eggShell.findValueRef(viName, path)); }; beforeAll(function (done) { @@ -26,35 +26,62 @@ describe('The Vireo EggShell Double api can', function () { describe('use readDouble', function () { it('to read different double values from memory', function () { - expect(vireo.eggShell.readDouble(find('dataItem_NumericDouble'))).toMatchIEEE754Number(123.456); - expect(vireo.eggShell.readDouble(find('dataItem_NumericDoubleNaN'))).toMatchIEEE754Number(NaN); - expect(vireo.eggShell.readDouble(find('dataItem_NumericDoublePositiveInfinity'))).toMatchIEEE754Number(Infinity); - expect(vireo.eggShell.readDouble(find('dataItem_NumericDoubleNegativeInfinity'))).toMatchIEEE754Number(-Infinity); - expect(vireo.eggShell.readDouble(find('dataItem_NumericDoublePositiveZero'))).toMatchIEEE754Number(0); - expect(vireo.eggShell.readDouble(find('dataItem_NumericDoubleNegativeZero'))).toMatchIEEE754Number(-0); + expect(readDouble('dataItem_NumericDouble')).toMatchIEEE754Number(123.456); + expect(readDouble('dataItem_NumericDoubleNaN')).toMatchIEEE754Number(NaN); + expect(readDouble('dataItem_NumericDoublePositiveInfinity')).toMatchIEEE754Number(Infinity); + expect(readDouble('dataItem_NumericDoubleNegativeInfinity')).toMatchIEEE754Number(-Infinity); + expect(readDouble('dataItem_NumericDoublePositiveZero')).toMatchIEEE754Number(0); + expect(readDouble('dataItem_NumericDoubleNegativeZero')).toMatchIEEE754Number(-0); }); it('to read different integer types from memory', function () { - expect(vireo.eggShell.readDouble(find('int8MinValue'))).toMatchIEEE754Number(-128); - expect(vireo.eggShell.readDouble(find('int8MaxValue'))).toMatchIEEE754Number(127); - expect(vireo.eggShell.readDouble(find('int16MinValue'))).toMatchIEEE754Number(-32768); - expect(vireo.eggShell.readDouble(find('int16MaxValue'))).toMatchIEEE754Number(32767); - expect(vireo.eggShell.readDouble(find('int32MinValue'))).toMatchIEEE754Number(-2147483648); - expect(vireo.eggShell.readDouble(find('int32MaxValue'))).toMatchIEEE754Number(2147483647); - expect(vireo.eggShell.readDouble(find('int64MinSafeInteger'))).toMatchIEEE754Number(-9007199254740991); - expect(vireo.eggShell.readDouble(find('int64MaxSafeInteger'))).toMatchIEEE754Number(9007199254740991); - expect(vireo.eggShell.readDouble(find('int64MinValue'))).toMatchIEEE754Number(-9223372036854776000); // Expected precision loss, full value -9223372036854775808 - expect(vireo.eggShell.readDouble(find('int64MaxValue'))).toMatchIEEE754Number(9223372036854776000); // Expected precision loss, full value 9223372036854775807 - expect(vireo.eggShell.readDouble(find('uInt8MinValue'))).toMatchIEEE754Number(0); - expect(vireo.eggShell.readDouble(find('uInt8MaxValue'))).toMatchIEEE754Number(255); - expect(vireo.eggShell.readDouble(find('uInt16MinValue'))).toMatchIEEE754Number(0); - expect(vireo.eggShell.readDouble(find('uInt16MaxValue'))).toMatchIEEE754Number(65535); - expect(vireo.eggShell.readDouble(find('uInt32MinValue'))).toMatchIEEE754Number(0); - expect(vireo.eggShell.readDouble(find('uInt32MaxValue'))).toMatchIEEE754Number(4294967295); - expect(vireo.eggShell.readDouble(find('uInt64MinSafeInteger'))).toMatchIEEE754Number(0); - expect(vireo.eggShell.readDouble(find('uInt64MaxSafeInteger'))).toMatchIEEE754Number(9007199254740991); - expect(vireo.eggShell.readDouble(find('uInt64MinValue'))).toMatchIEEE754Number(0); - expect(vireo.eggShell.readDouble(find('uInt64MaxValue'))).toMatchIEEE754Number(18446744073709552000); // Expected precision loss, full value 18446744073709551615 + expect(readDouble('int8MinValue')).toBe(-128); + expect(readDouble('int8MaxValue')).toBe(127); + expect(readDouble('int16MinValue')).toBe(-32768); + expect(readDouble('int16MaxValue')).toBe(32767); + expect(readDouble('int32MinValue')).toBe(-2147483648); + expect(readDouble('int32MaxValue')).toBe(2147483647); + expect(readDouble('int64MinSafeInteger')).toBe(-9007199254740991); + expect(readDouble('int64MaxSafeInteger')).toBe(9007199254740991); + expect(readDouble('int64MinValue')).toBe(-9223372036854776000); // Expected precision loss, full value -9223372036854775808 + expect(readDouble('int64MaxValue')).toBe(9223372036854776000); // Expected precision loss, full value 9223372036854775807 + expect(readDouble('uInt8MinValue')).toBe(0); + expect(readDouble('uInt8MaxValue')).toBe(255); + expect(readDouble('uInt16MinValue')).toBe(0); + expect(readDouble('uInt16MaxValue')).toBe(65535); + expect(readDouble('uInt32MinValue')).toBe(0); + expect(readDouble('uInt32MaxValue')).toBe(4294967295); + expect(readDouble('uInt64MinSafeInteger')).toBe(0); + expect(readDouble('uInt64MaxSafeInteger')).toBe(9007199254740991); + expect(readDouble('uInt64MinValue')).toBe(0); + expect(readDouble('uInt64MaxValue')).toBe(18446744073709552000); // Expected precision loss, full value 18446744073709551615 + }); + + it('to read different enum types from memory', function () { + expect(readDouble('enum8alphabet')).toBe(6); + expect(readDouble('enum16numbers')).toBe(3); + expect(readDouble('enum32colors')).toBe(2); + expect(readDouble('enum64releases')).toBe(5); + }); + + it('to read different boolean types from memory', function () { + expect(readDouble('booleanTrueValue')).toBe(1); + expect(readDouble('booleanFalseValue')).toBe(0); + }); + + it('to read different timestamp values from memory', function () { + expect(readDouble('dataItem_Timestamp')).toBe(3564057536.423476); + }); + + it('to error for unsupported types', function () { + var unsupportedTypeCheck = function (path) { + return function () { + readDouble(path); + }; + }; + + expect(unsupportedTypeCheck('dataItem_Complex')).toThrow(); + expect(unsupportedTypeCheck('dataItem_String')).toThrow(); }); }); }); diff --git a/test-it/karma/publicapi/FindValueRef.Test.js b/test-it/karma/publicapi/FindValueRef.Test.js index 482f53b07..54e6ab32f 100644 --- a/test-it/karma/publicapi/FindValueRef.Test.js +++ b/test-it/karma/publicapi/FindValueRef.Test.js @@ -9,6 +9,7 @@ describe('The Vireo EggShell findValueRef api can', function () { var publicApiMultipleTypesViaUrl = fixtures.convertToAbsoluteFromFixturesDir('publicapi/MultipleTypes.via'); var viName = 'MyVI'; + var pathName = 'dataItem_NumericDouble'; beforeAll(function (done) { fixtures.preloadAbsoluteUrls([ @@ -20,8 +21,42 @@ describe('The Vireo EggShell findValueRef api can', function () { vireoRunner.rebootAndLoadVia(vireo, publicApiMultipleTypesViaUrl); }); - it('find a double', function () { - var valueRef = vireo.eggShell.findValueRef(viName, 'dataItem_NumericDouble'); - console.log(valueRef); + it('find a value in memory', function () { + var valueRef = vireo.eggShell.findValueRef(viName, pathName); + expect(valueRef).toBeNonEmptyObject(); + expect(valueRef.typeRef).toBeNumber(); + expect(valueRef.typeRef).not.toBe(0); + expect(valueRef.dataRef).toBeNumber(); + expect(valueRef.dataRef).not.toBe(0); + }); + + it('to throw for a nonexistant vi name', function () { + var invalidViName = function () { + vireo.eggShell.findValueRef('nonexistantvi', pathName); + }; + expect(invalidViName).toThrow(); + }); + + it('to throw for an empty vi name', function () { + var invalidViName = function () { + vireo.eggShell.findValueRef('', pathName); + }; + expect(invalidViName).toThrow(); + }); + + it('to throw for a nonexistant path', function () { + var invalidPath = function () { + vireo.eggShell.findValueRef(viName, 'nonexistantvalue'); + }; + expect(invalidPath).toThrow(); + }); + + it('to return a typeRef for the the local scope of a VI for an empty path', function () { + var valueRef = vireo.eggShell.findValueRef(viName, ''); + expect(valueRef).toBeNonEmptyObject(); + expect(valueRef.typeRef).toBeNumber(); + expect(valueRef.typeRef).not.toBe(0); + expect(valueRef.dataRef).toBeNumber(); + expect(valueRef.dataRef).not.toBe(0); }); }); From e69710ceee30439ec274be5b186933dc6a8b58ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Le=C3=B3n?= Date: Tue, 19 Jun 2018 18:33:08 -0500 Subject: [PATCH 06/67] Merged changes for readDouble --- make-it/EmMakefile | 4 ++++ source/core/CEntryPoints.cpp | 22 ++++++++++++++++++++-- source/include/CEntryPoints.h | 2 +- source/io/module_eggShell.js | 26 +++++++++++++++++++++++++- 4 files changed, 50 insertions(+), 4 deletions(-) diff --git a/make-it/EmMakefile b/make-it/EmMakefile index 1ce7a4194..7c94cc486 100644 --- a/make-it/EmMakefile +++ b/make-it/EmMakefile @@ -143,6 +143,10 @@ EM_EXPORTS = -s EXPORTED_FUNCTIONS="[\ '_Data_GetArrayMetadata',\ '_Data_GetArrayDimLength',\ '_Data_ResizeArray',\ + '_TypeRef_TopAQSize',\ + '_TypeRef_Name',\ + '_TypeRef_SubElementCount',\ + '_TypeRef_SubElementByIndex',\ '_JavaScriptInvoke_GetParameterType',\ '_JavaScriptInvoke_GetParameterPointer',\ '_JavaScriptInvoke_GetArrayElementType'\ diff --git a/source/core/CEntryPoints.cpp b/source/core/CEntryPoints.cpp index 2af4913ea..bfe0b5796 100644 --- a/source/core/CEntryPoints.cpp +++ b/source/core/CEntryPoints.cpp @@ -512,10 +512,28 @@ VIREO_EXPORT Int32 TypeRef_Alignment(TypeRef typeRef) return typeRef->AQAlignment(); } //------------------------------------------------------------ -VIREO_EXPORT void TypeRef_Name(TypeRef typeRef, Int32* bufferSize, char* buffer) +VIREO_EXPORT const char* TypeRef_Name(TypeRef typeRef) { SubString name = typeRef->Name(); - *bufferSize = name.CopyToBoundedBuffer(*bufferSize, reinterpret_cast(buffer)); + + static StringRef returnBuffer = nullptr; + if (returnBuffer == nullptr) { + // Allocate a string the first time it is used. + // After that it will be resized as needed. + STACK_VAR(String, tempReturn); + returnBuffer = tempReturn.DetachValue(); + } else { + returnBuffer->Resize1D(0); + } + + if (returnBuffer) { + returnBuffer->AppendSubString(&name); + // Add an explicit nullptr terminator so it looks like a C string. + returnBuffer->Append((Utf8Char)'\0'); + return (const char*) returnBuffer->Begin(); + } + + return ""; } //------------------------------------------------------------ VIREO_EXPORT Int32 TypeRef_ElementOffset(TypeRef typeRef) diff --git a/source/include/CEntryPoints.h b/source/include/CEntryPoints.h index 47624de8a..68031d16d 100644 --- a/source/include/CEntryPoints.h +++ b/source/include/CEntryPoints.h @@ -70,7 +70,7 @@ VIREO_EXPORT Boolean TypeRef_IsValid(TypeRef typeRef); VIREO_EXPORT Boolean TypeRef_HasCustomDefault(TypeRef typeRef); VIREO_EXPORT EncodingEnum TypeRef_BitEncoding(TypeRef typeRef); VIREO_EXPORT Int32 TypeRef_Alignment(TypeRef typeRef); -VIREO_EXPORT void TypeRef_Name(TypeRef typeRef, Int32* bufferSize, char* buffer); +VIREO_EXPORT const char* TypeRef_Name(TypeRef typeRef); VIREO_EXPORT Int32 TypeRef_ElementOffset(TypeRef typeRef); VIREO_EXPORT Int32 TypeRef_Rank(TypeRef typeRef); VIREO_EXPORT PointerTypeEnum TypeRef_PointerType(TypeRef typeRef); diff --git a/source/io/module_eggShell.js b/source/io/module_eggShell.js index 1e18f5d52..748f30a14 100644 --- a/source/io/module_eggShell.js +++ b/source/io/module_eggShell.js @@ -66,7 +66,11 @@ 'EggShell_REPL', 'EggShell_ExecuteSlices', 'Occurrence_Set', - 'Pointer_stringify' + 'Pointer_stringify', + 'TypeRef_TopAQSize', + 'TypeRef_Name', + 'TypeRef_SubElementCount', + 'TypeRef_GetSubElementByIndex', ]}], */ Module.eggShell = {}; @@ -134,6 +138,10 @@ var Data_WriteDouble = Module.cwrap('Data_WriteDouble', 'void', ['number', 'number']); var EggShell_ExecuteSlices = Module.cwrap('EggShell_ExecuteSlices', 'number', ['number', 'number', 'number']); var Occurrence_Set = Module.cwrap('Occurrence_Set', 'void', ['number']); + var TypeRef_TopAQSize = Module.cwrap('TypeRef_TopAQSize', 'number', ['number']); + var TypeRef_Name = Module.cwrap('TypeRef_Name', 'string', ['number']); + var TypeRef_SubElementCount = Module.cwrap('TypeRef_SubElementCount', 'number', ['number']); + var TypeRef_GetSubElementByIndex = Module.cwrap('TypeRef_GetSubElementByIndex', 'number', ['number']); // Create shell for vireo instance var v_root = EggShell_Create(0); @@ -239,6 +247,22 @@ return result; }; + Module.eggShell.typeTopAQSize = function (typePointer) { + return TypeRef_TopAQSize(typePointer); + }; + + Module.eggShell.typeName = function (typePointer) { + return TypeRef_Name(typePointer); + }; + + Module.eggShell.typeSubElementCount = function (typePointer) { + return TypeRef_SubElementCount(typePointer); + }; + + Module.eggShell.typeSubElementByIndex = function (typePointer) { + return TypeRef_GetSubElementByIndex(typePointer); + }; + Module.eggShell.writeDouble = publicAPI.eggShell.writeDouble = function (vi, path, value) { EggShell_WriteDouble(v_userShell, vi, path, value); }; From 20c171c30e01f7887010ee46d7f9ae46def5fa4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Le=C3=B3n?= Date: Tue, 19 Jun 2018 14:13:12 -0500 Subject: [PATCH 07/67] Exported more Is* functions from TypeCommon --- source/core/CEntryPoints.cpp | 60 +++++++++++++++++++++++++++++ source/core/TypeAndDataManager.cpp | 56 +++++++++++++++++++++++++++ source/include/CEntryPoints.h | 12 ++++++ source/include/TypeAndDataManager.h | 6 +++ 4 files changed, 134 insertions(+) diff --git a/source/core/CEntryPoints.cpp b/source/core/CEntryPoints.cpp index bfe0b5796..839709cee 100644 --- a/source/core/CEntryPoints.cpp +++ b/source/core/CEntryPoints.cpp @@ -571,6 +571,66 @@ VIREO_EXPORT TypeRef TypeRef_GetSubElementByIndex(TypeRef typeRef, Int32 index) return typeRef->GetSubElement(index); } //------------------------------------------------------------ +VIREO_EXPORT Boolean TypeRef_IsCluster(TypeRef typeRef) +{ + return typeRef->IsCluster(); +} +//------------------------------------------------------------ +VIREO_EXPORT Boolean TypeRef_IsArray(TypeRef typeRef) +{ + return typeRef->IsArray(); +} +//------------------------------------------------------------ +VIREO_EXPORT Boolean TypeRef_IsBoolean(TypeRef typeRef) +{ + return typeRef->IsBoolean(); +} +//------------------------------------------------------------ +VIREO_EXPORT Boolean TypeRef_IsInteger(TypeRef typeRef) +{ + return typeRef->IsInteger(); +} +//------------------------------------------------------------ +VIREO_EXPORT Boolean TypeRef_IsSigned(TypeRef typeRef) +{ + return typeRef->IsSignedInteger(); +} +//------------------------------------------------------------ +VIREO_EXPORT Boolean TypeRef_IsEnum(TypeRef typeRef) +{ + return typeRef->IsEnum(); +} +//------------------------------------------------------------ +VIREO_EXPORT Boolean TypeRef_IsFloat(TypeRef typeRef) +{ + return typeRef->IsFloat(); +} +//------------------------------------------------------------ +VIREO_EXPORT Boolean TypeRef_IsString(TypeRef typeRef) +{ + return typeRef->IsString(); +} +//------------------------------------------------------------ +VIREO_EXPORT Boolean TypeRef_IsPath(TypeRef typeRef) +{ + return typeRef->IsPath(); +} +//------------------------------------------------------------ +VIREO_EXPORT Boolean TypeRef_IsTimestamp(TypeRef typeRef) +{ + return typeRef->IsTimestamp(); +} +//------------------------------------------------------------ +VIREO_EXPORT Boolean TypeRef_IsComplex(TypeRef typeRef) +{ + return typeRef->IsComplex(); +} +//------------------------------------------------------------ +VIREO_EXPORT Boolean TypeRef_IsAnalogWaveform(TypeRef typeRef) +{ + return typeRef->IsAnalogWaveform(); +} +//------------------------------------------------------------ //------------------------------------------------------------ VIREO_EXPORT Int32 Data_RawBlockSize(TypedBlock* object) { diff --git a/source/core/TypeAndDataManager.cpp b/source/core/TypeAndDataManager.cpp index 04320a986..4f30238c0 100644 --- a/source/core/TypeAndDataManager.cpp +++ b/source/core/TypeAndDataManager.cpp @@ -602,6 +602,8 @@ const SubString TypeCommon::TypeTimestamp = SubString("Timestamp"); const SubString TypeCommon::TypeComplexSingle = SubString("ComplexSingle"); const SubString TypeCommon::TypeComplexDouble = SubString("ComplexDouble"); const SubString TypeCommon::TypeJavaScriptRefNum = SubString(tsJavaScriptRefNumToken); +const SubString TypeCommon::TypePath = SubString("NIPath"); +const SubString TypeCommon::TypeAnalogWaveform = SubString("AnalogWaveform"); const SubString TypeCommon::TypeStaticTypeAndData = SubString("StaticTypeAndData"); TypeCommon::TypeCommon(TypeManagerRef typeManager) @@ -872,6 +874,34 @@ Boolean TypeCommon::IsNumeric() return false; } //------------------------------------------------------------ +Boolean TypeCommon::IsInteger() +{ + TypeRef t = this; + while (t) { + if (t->Name().Compare(&TypeInt8) || t->Name().Compare(&TypeInt16) || t->Name().Compare(&TypeInt32) + || t->Name().Compare(&TypeInt64) || t->Name().Compare(&TypeUInt8) + || t->Name().Compare(&TypeUInt16) || t->Name().Compare(&TypeUInt32) + || t->Name().Compare(&TypeUInt64)) { + return true; + } + t = t->BaseType(); + } + return false; +} +//------------------------------------------------------------ +Boolean TypeCommon::IsSignedInteger() +{ + TypeRef t = this; + while (t) { + if (t->Name().Compare(&TypeInt8) || t->Name().Compare(&TypeInt16) || t->Name().Compare(&TypeInt32) + || t->Name().Compare(&TypeInt64)) { + return true; + } + t = t->BaseType(); + } + return false; +} +//------------------------------------------------------------ Boolean TypeCommon::IsInteger64() { TypeRef t = this; @@ -922,6 +952,18 @@ Boolean TypeCommon::IsString() return false; } +//------------------------------------------------------------ +Boolean TypeCommon::IsPath() +{ + TypeRef t = this; + while (t) { + if (t->Name().Compare(&TypePath)) { + return true; + } + t = t->BaseType(); + } + return false; +} //------------------------------------------------------------ Boolean TypeCommon::IsTimestamp() { @@ -959,6 +1001,20 @@ Boolean TypeCommon::IsJavaScriptRefNum() return false; } //------------------------------------------------------------ +Boolean TypeCommon::IsAnalogWaveform() +{ + TypeRef t = this; + while (t) { + SubString typeName = t->Name(); + SubString analogTypess(TypeAnalogWaveform); + if (typeName.FindFirstMatch(&analogTypess, 0, false) == 0) { + return true; + } + t = t->BaseType(); + } + return false; +} +//------------------------------------------------------------ Boolean TypeCommon::IsIntrinsicClusterDataType(SubString *foundTypeName) { TypeRef t = this; while (t) { diff --git a/source/include/CEntryPoints.h b/source/include/CEntryPoints.h index 68031d16d..aa022a5ea 100644 --- a/source/include/CEntryPoints.h +++ b/source/include/CEntryPoints.h @@ -78,6 +78,18 @@ VIREO_EXPORT TypeRef TypeRef_Next(TypeRef typeRef); VIREO_EXPORT UsageTypeEnum TypeRef_ElementUsageType(TypeRef typeRef); VIREO_EXPORT Int32 TypeRef_SubElementCount(TypeRef typeRef); VIREO_EXPORT TypeRef TypeRef_GetSubElementByIndex(TypeRef typeRef, Int32 index); +VIREO_EXPORT Boolean TypeRef_IsCluster(TypeRef typeRef); +VIREO_EXPORT Boolean TypeRef_IsArray(TypeRef typeRef); +VIREO_EXPORT Boolean TypeRef_IsBoolean(TypeRef typeRef); +VIREO_EXPORT Boolean TypeRef_IsInteger(TypeRef typeRef); +VIREO_EXPORT Boolean TypeRef_IsSigned(TypeRef typeRef); +VIREO_EXPORT Boolean TypeRef_IsEnum(TypeRef typeRef); +VIREO_EXPORT Boolean TypeRef_IsFloat(TypeRef typeRef); +VIREO_EXPORT Boolean TypeRef_IsString(TypeRef typeRef); +VIREO_EXPORT Boolean TypeRef_IsPath(TypeRef typeRef); +VIREO_EXPORT Boolean TypeRef_IsTimestamp(TypeRef typeRef); +VIREO_EXPORT Boolean TypeRef_IsComplex(TypeRef typeRef); +VIREO_EXPORT Boolean TypeRef_IsAnalogWaveform(TypeRef typeRef); //------------------------------------------------------------ //! TypedBlock functions VIREO_EXPORT Int32 Data_RawBlockSize(TypedBlock* object); diff --git a/source/include/TypeAndDataManager.h b/source/include/TypeAndDataManager.h index 2b92e8af9..f5b751579 100644 --- a/source/include/TypeAndDataManager.h +++ b/source/include/TypeAndDataManager.h @@ -463,6 +463,8 @@ class TypeCommon static const SubString TypeComplexSingle; static const SubString TypeComplexDouble; static const SubString TypeJavaScriptRefNum; + static const SubString TypePath; + static const SubString TypeAnalogWaveform; static const SubString TypeStaticTypeAndData; explicit TypeCommon(TypeManagerRef typeManager); @@ -610,13 +612,17 @@ class TypeCommon Boolean IsA(TypeRef otherType); Boolean IsA(TypeRef otherType, Boolean compatibleArrays); Boolean IsNumeric(); + Boolean IsInteger(); + Boolean IsSignedInteger(); Boolean IsInteger64(); Boolean IsFloat(); Boolean IsBoolean(); Boolean IsString(); + Boolean IsPath(); Boolean IsTimestamp(); Boolean IsComplex(); Boolean IsJavaScriptRefNum(); + Boolean IsAnalogWaveform(); Boolean IsIntrinsicClusterDataType(SubString *foundTypeName); // Returns true for builtin data types such as Timestamp, Complex, etc //! Size of the type in bits including padding. If the type is bit level it's the raw bit size with no padding. From 56d5567572315c793ed5af96f64414ebd392d008 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Le=C3=B3n?= Date: Tue, 19 Jun 2018 18:34:18 -0500 Subject: [PATCH 08/67] Merged isType functions --- make-it/EmMakefile | 12 ++ source/io/module_eggShell.js | 207 +++++++++++++++++++++++++++++++++++ 2 files changed, 219 insertions(+) diff --git a/make-it/EmMakefile b/make-it/EmMakefile index 7c94cc486..cad9d3abd 100644 --- a/make-it/EmMakefile +++ b/make-it/EmMakefile @@ -147,6 +147,18 @@ EM_EXPORTS = -s EXPORTED_FUNCTIONS="[\ '_TypeRef_Name',\ '_TypeRef_SubElementCount',\ '_TypeRef_SubElementByIndex',\ + '_TypeRef_IsCluster',\ + '_TypeRef_IsArray',\ + '_TypeRef_IsBoolean',\ + '_TypeRef_IsInteger',\ + '_TypeRef_IsSigned',\ + '_TypeRef_IsEnum',\ + '_TypeRef_IsFloat',\ + '_TypeRef_IsString',\ + '_TypeRef_IsPath',\ + '_TypeRef_IsTimestamp',\ + '_TypeRef_IsComplex',\ + '_TypeRef_IsAnalogWaveform',\ '_JavaScriptInvoke_GetParameterType',\ '_JavaScriptInvoke_GetParameterPointer',\ '_JavaScriptInvoke_GetArrayElementType'\ diff --git a/source/io/module_eggShell.js b/source/io/module_eggShell.js index 748f30a14..ffb042e31 100644 --- a/source/io/module_eggShell.js +++ b/source/io/module_eggShell.js @@ -263,6 +263,213 @@ return TypeRef_GetSubElementByIndex(typePointer); }; + Module.eggShell.typeIsCluster = function (typePointer) { + return Module._TypeRef_IsCluster(typePointer); + }; + + Module.eggShell.typeIsArray = function (typePointer) { + return Module._TypeRef_IsArray(typePointer); + }; + + Module.eggShell.typeIsBoolean = function (typePointer) { + return Module._TypeRef_IsBoolean(typePointer); + }; + + Module.eggShell.typeIsInteger = function (typePointer) { + return Module._TypeRef_IsInteger(typePointer); + }; + + Module.eggShell.typeIsSigned = function (typePointer) { + return Module._TypeRef_IsSigned(typePointer); + }; + + Module.eggShell.typeIsEnum = function (typePointer) { + return Module._TypeRef_IsEnum(typePointer); + }; + + Module.eggShell.typeIsFloat = function (typePointer) { + return Module._TypeRef_IsFloat(typePointer); + }; + + Module.eggShell.typeIsString = function (typePointer) { + return Module._TypeRef_IsString(typePointer); + }; + + Module.eggShell.typeIsPath = function (typePointer) { + return Module._TypeRef_IsPath(typePointer); + }; + + Module.eggShell.typeIsTimestamp = function (typePointer) { + return Module._TypeRef_IsTimestamp(typePointer); + }; + + Module.eggShell.typeIsComplex = function (typePointer) { + return Module._TypeRef_IsComplex(typePointer); + }; + + Module.eggShell.typeIsAnalogWaveform = function (typePointer) { + return Module._TypeRef_IsAnalogWaveform(typePointer); + }; + + var dispatchVisitBoolean = function (typeVisitor, args) { + return typeVisitor.visitBoolean.apply(typeVisitor, args); + }; + + var dispatchVisitEnum = function (typeVisitor, args) { + return typeVisitor.visitEnum.apply(typeVisitor, args); + }; + + var dispatchVisitInteger = function (typeVisitor, args) { + var typeRef = args[0].typeRef; + var isSignedInteger = Module.eggShell.typeIsSigned(typeRef); + var sizeOfInteger = Module.eggShell.typeTopAQSize(typeRef); + var visitFn = undefined; + if (isSignedInteger === true) { + switch (sizeOfInteger) { + case 1: + visitFn = typeVisitor.visitInt8; + break; + case 2: + visitFn = typeVisitor.visitInt16; + break; + case 4: + visitFn = typeVisitor.visitInt32; + break; + case 8: + visitFn = typeVisitor.visitInt64; + break; + default: + throw new Error('Unexpected size for Integer'); + } + } else { + switch (sizeOfInteger) { + case 1: + visitFn = typeVisitor.visitUInt8; + break; + case 2: + visitFn = typeVisitor.visitUInt16; + break; + case 4: + visitFn = typeVisitor.visitUInt32; + break; + case 8: + visitFn = typeVisitor.visitUInt64; + break; + default: + throw new Error('Unexpected size for Unsigned Integer'); + } + } + + return visitFn.apply(typeVisitor, args); + }; + + var dispatchVisitFloat = function (typeVisitor, args) { + var typeRef = args[0].typeRef; + var sizeOfFloat = Module.eggShell.typeTopAQSize(typeRef); + switch (sizeOfFloat) { + case 4: + return typeVisitor.visitSingle.apply(typeVisitor, args); + case 8: + return typeVisitor.visitDouble.apply(typeVisitor, args); + default: + throw new Error('Unexpected size for a Float value'); + } + }; + + var dispatchVisitString = function (typeVisitor, args) { + return typeVisitor.visitString.apply(typeVisitor, args); + }; + + var dispatchVisitComplex = function (typeVisitor, args) { + var typeRef = args[0].typeRef; + var sizeOfComplex = Module.eggShell.typeTopAQSize(typeRef); + switch (sizeOfComplex) { + case 8: + return typeVisitor.visitComplexSingle.apply(typeVisitor, args); + case 16: + return typeVisitor.visitComplexDouble.apply(typeVisitor, args); + default: + throw new Error('Unexpected size for a Complex value'); + } + }; + + var dispatchVisitAnalogWaveform = function (typeVisitor, args) { + return typeVisitor.visitAnalogWaveform.apply(typeVisitor, args); + }; + + var dispatchVisitTimestamp = function (typeVisitor, args) { + return typeVisitor.visitTimestamp.apply(typeVisitor, args); + }; + + var dispatchVisitPath = function (typeVisitor, args) { + return typeVisitor.visitPath.apply(typeVisitor, args); + }; + + var dispatchVisitArray = function (typeVisitor, args) { + return typeVisitor.visitArray.apply(typeVisitor, args); + }; + + var dispatchVisitCluster = function (typeVisitor, args) { + return typeVisitor.visitCluster.apply(typeVisitor, args); + }; + + var typeDispatchFunctions = [ + dispatchVisitBoolean, + dispatchVisitEnum, + dispatchVisitInteger, + dispatchVisitFloat, + dispatchVisitString, + dispatchVisitComplex, + dispatchVisitAnalogWaveform, + dispatchVisitTimestamp, + dispatchVisitPath, + dispatchVisitArray, + dispatchVisitCluster + ]; + + var registeredTypes = [ + Module.eggShell.typeIsBoolean, + Module.eggShell.typeIsEnum, + Module.eggShell.typeIsInteger, + Module.eggShell.typeIsFloat, + Module.eggShell.typeIsString, + Module.eggShell.typeIsComplex, + Module.eggShell.typeIsAnalogWaveform, + Module.eggShell.typeIsTimestamp, + Module.eggShell.typeIsPath, + Module.eggShell.typeIsArray, + Module.eggShell.typeIsCluster + ]; + + Module.eggShell.reflectOnValueRef = publicAPI.eggShell.reflectOnValueRef = function (typeVisitor, valueRef) { + if (typeof valueRef !== 'object') { + throw new Error('valueRef must be an object. Found: ' + valueRef); + } + + if (typeof typeVisitor !== 'object') { + throw new Error('typeVisitor must be an object. Found: ' + typeVisitor); + } + + var typeRef = valueRef.typeRef, + args = Array.prototype.slice.call(arguments, 1), + foundTypeIndex = -1, + i = 0; + + for (i = 0; i < registeredTypes.length; i += 1) { + if (registeredTypes[i](typeRef)) { + foundTypeIndex = i; + break; + } + } + + if (foundTypeIndex < 0) { + throw new Error('unexpected type'); + } + + var dispatchFunction = typeDispatchFunctions[foundTypeIndex]; + return dispatchFunction(typeVisitor, valueRef, args); + }; + Module.eggShell.writeDouble = publicAPI.eggShell.writeDouble = function (vi, path, value) { EggShell_WriteDouble(v_userShell, vi, path, value); }; From f303d5532ecde097608124f2d38169fc7dec5105 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Le=C3=B3n?= Date: Wed, 20 Jun 2018 16:17:29 -0500 Subject: [PATCH 09/67] Added tests for `reflectOnValueRef` and fixed some issues. --- make-it/EmMakefile | 2 +- source/io/module_eggShell.js | 76 +++++++--- .../fixtures/publicapi/MultipleTypes.via | 2 + .../karma/publicapi/TypeReflection.Test.js | 140 ++++++++++++++++++ 4 files changed, 195 insertions(+), 25 deletions(-) create mode 100644 test-it/karma/publicapi/TypeReflection.Test.js diff --git a/make-it/EmMakefile b/make-it/EmMakefile index cad9d3abd..e344c0826 100644 --- a/make-it/EmMakefile +++ b/make-it/EmMakefile @@ -146,7 +146,7 @@ EM_EXPORTS = -s EXPORTED_FUNCTIONS="[\ '_TypeRef_TopAQSize',\ '_TypeRef_Name',\ '_TypeRef_SubElementCount',\ - '_TypeRef_SubElementByIndex',\ + '_TypeRef_GetSubElementByIndex',\ '_TypeRef_IsCluster',\ '_TypeRef_IsArray',\ '_TypeRef_IsBoolean',\ diff --git a/source/io/module_eggShell.js b/source/io/module_eggShell.js index ffb042e31..517950f1d 100644 --- a/source/io/module_eggShell.js +++ b/source/io/module_eggShell.js @@ -264,58 +264,66 @@ }; Module.eggShell.typeIsCluster = function (typePointer) { - return Module._TypeRef_IsCluster(typePointer); + return Module._TypeRef_IsCluster(typePointer) !== 0; }; Module.eggShell.typeIsArray = function (typePointer) { - return Module._TypeRef_IsArray(typePointer); + return Module._TypeRef_IsArray(typePointer) !== 0; }; Module.eggShell.typeIsBoolean = function (typePointer) { - return Module._TypeRef_IsBoolean(typePointer); + return Module._TypeRef_IsBoolean(typePointer) !== 0; }; Module.eggShell.typeIsInteger = function (typePointer) { - return Module._TypeRef_IsInteger(typePointer); + return Module._TypeRef_IsInteger(typePointer) !== 0; }; Module.eggShell.typeIsSigned = function (typePointer) { - return Module._TypeRef_IsSigned(typePointer); + return Module._TypeRef_IsSigned(typePointer) !== 0; }; Module.eggShell.typeIsEnum = function (typePointer) { - return Module._TypeRef_IsEnum(typePointer); + return Module._TypeRef_IsEnum(typePointer) !== 0; }; Module.eggShell.typeIsFloat = function (typePointer) { - return Module._TypeRef_IsFloat(typePointer); + return Module._TypeRef_IsFloat(typePointer) !== 0; }; Module.eggShell.typeIsString = function (typePointer) { - return Module._TypeRef_IsString(typePointer); + return Module._TypeRef_IsString(typePointer) !== 0; }; Module.eggShell.typeIsPath = function (typePointer) { - return Module._TypeRef_IsPath(typePointer); + return Module._TypeRef_IsPath(typePointer) !== 0; }; Module.eggShell.typeIsTimestamp = function (typePointer) { - return Module._TypeRef_IsTimestamp(typePointer); + return Module._TypeRef_IsTimestamp(typePointer) !== 0; }; Module.eggShell.typeIsComplex = function (typePointer) { - return Module._TypeRef_IsComplex(typePointer); + return Module._TypeRef_IsComplex(typePointer) !== 0; }; Module.eggShell.typeIsAnalogWaveform = function (typePointer) { - return Module._TypeRef_IsAnalogWaveform(typePointer); + return Module._TypeRef_IsAnalogWaveform(typePointer) !== 0; + }; + + var validateVisitMethod = function (fn, fnName) { + if (typeof fn !== 'function') { + throw new Error('Visitor must have a method named `' + fnName + '`. Found: ' + fn); + } }; var dispatchVisitBoolean = function (typeVisitor, args) { + validateVisitMethod(typeVisitor.visitBoolean, 'visitBoolean'); return typeVisitor.visitBoolean.apply(typeVisitor, args); }; var dispatchVisitEnum = function (typeVisitor, args) { + validateVisitMethod(typeVisitor.visitEnum, 'visitEnum'); return typeVisitor.visitEnum.apply(typeVisitor, args); }; @@ -356,60 +364,80 @@ visitFn = typeVisitor.visitUInt64; break; default: - throw new Error('Unexpected size for Unsigned Integer'); + throw new Error('Unexpected size for Unsigned Integer. Found: '); } } + var intName = (isSignedInteger ? '' : 'U') + 'Int' + (sizeOfInteger * 8); + validateVisitMethod(visitFn, 'visit' + intName); return visitFn.apply(typeVisitor, args); }; var dispatchVisitFloat = function (typeVisitor, args) { var typeRef = args[0].typeRef; var sizeOfFloat = Module.eggShell.typeTopAQSize(typeRef); + var visitFn; switch (sizeOfFloat) { case 4: - return typeVisitor.visitSingle.apply(typeVisitor, args); + visitFn = typeVisitor.visitSingle; + break; case 8: - return typeVisitor.visitDouble.apply(typeVisitor, args); + visitFn = typeVisitor.visitDouble; + break; default: throw new Error('Unexpected size for a Float value'); } + + validateVisitMethod(visitFn, 'visit' + (sizeOfFloat === 4 ? 'Single' : 'Double')); + return visitFn.apply(typeVisitor, args); }; var dispatchVisitString = function (typeVisitor, args) { + validateVisitMethod(typeVisitor.visitString, 'visitString'); return typeVisitor.visitString.apply(typeVisitor, args); }; var dispatchVisitComplex = function (typeVisitor, args) { - var typeRef = args[0].typeRef; - var sizeOfComplex = Module.eggShell.typeTopAQSize(typeRef); + var typeRef = args[0].typeRef, + sizeOfComplex = Module.eggShell.typeTopAQSize(typeRef), + visitFn; switch (sizeOfComplex) { case 8: - return typeVisitor.visitComplexSingle.apply(typeVisitor, args); + visitFn = typeVisitor.visitComplexSingle; + break; case 16: - return typeVisitor.visitComplexDouble.apply(typeVisitor, args); + visitFn = typeVisitor.visitComplexDouble; + break; default: throw new Error('Unexpected size for a Complex value'); } + + validateVisitMethod(visitFn, 'visitComplex' + (sizeOfComplex === 8 ? 'Single' : 'Double')); + return visitFn.apply(typeVisitor, args); }; var dispatchVisitAnalogWaveform = function (typeVisitor, args) { + validateVisitMethod(typeVisitor.visitAnalogWaveform, 'visitAnalogWaveform'); return typeVisitor.visitAnalogWaveform.apply(typeVisitor, args); }; var dispatchVisitTimestamp = function (typeVisitor, args) { + validateVisitMethod(typeVisitor.visitTimestamp, 'visitTimestamp'); return typeVisitor.visitTimestamp.apply(typeVisitor, args); }; var dispatchVisitPath = function (typeVisitor, args) { + validateVisitMethod(typeVisitor.visitPath, 'visitPath'); return typeVisitor.visitPath.apply(typeVisitor, args); }; var dispatchVisitArray = function (typeVisitor, args) { + validateVisitMethod(typeVisitor.visitArray, 'visitArray'); return typeVisitor.visitArray.apply(typeVisitor, args); }; var dispatchVisitCluster = function (typeVisitor, args) { + validateVisitMethod(typeVisitor.visitCluster, 'visitCluster'); return typeVisitor.visitCluster.apply(typeVisitor, args); }; @@ -442,11 +470,11 @@ ]; Module.eggShell.reflectOnValueRef = publicAPI.eggShell.reflectOnValueRef = function (typeVisitor, valueRef) { - if (typeof valueRef !== 'object') { + if (typeof valueRef !== 'object' || Array.isArray(valueRef)) { throw new Error('valueRef must be an object. Found: ' + valueRef); } - if (typeof typeVisitor !== 'object') { + if (typeof typeVisitor !== 'object' || Array.isArray(typeVisitor)) { throw new Error('typeVisitor must be an object. Found: ' + typeVisitor); } @@ -456,18 +484,18 @@ i = 0; for (i = 0; i < registeredTypes.length; i += 1) { - if (registeredTypes[i](typeRef)) { + if (registeredTypes[i](typeRef) === true) { foundTypeIndex = i; break; } } if (foundTypeIndex < 0) { - throw new Error('unexpected type'); + throw new Error('Unexpected type. Is typeRef pointing to a valid type?. TypeRef found: ' + typeRef); } var dispatchFunction = typeDispatchFunctions[foundTypeIndex]; - return dispatchFunction(typeVisitor, valueRef, args); + return dispatchFunction(typeVisitor, args); }; Module.eggShell.writeDouble = publicAPI.eggShell.writeDouble = function (vi, path, value) { diff --git a/test-it/karma/fixtures/publicapi/MultipleTypes.via b/test-it/karma/fixtures/publicapi/MultipleTypes.via index 112beddb2..845c581bd 100644 --- a/test-it/karma/fixtures/publicapi/MultipleTypes.via +++ b/test-it/karma/fixtures/publicapi/MultipleTypes.via @@ -124,6 +124,7 @@ define (MyVI dv(.VirtualInstrument ( e(dv('\xF0\x8F\xBF\xBF') dataItem_utf8sequence_overlonglargest4byte) // U+FFFF e(dv(.String '\\"') dataItem_StringOtherJSONEscapedCharacters) + e(dv(.Single 123.5) dataItem_NumericSingle) e(dv(.Double 123.456)dataItem_NumericDouble) e(dv(.Double nan)dataItem_NumericDoubleNaN) e(dv(.Double inf)dataItem_NumericDoublePositiveInfinity) @@ -133,6 +134,7 @@ define (MyVI dv(.VirtualInstrument ( e(dv(.Int32 -1073741824)dataItem_Numeric32) e(dv(.Int64 -1152921504606846976)dataItem_Numeric64) e(dv(.UInt64 18446744073709551615) dataItem_NumericU64) + e(dv(.ComplexSingle (123.5 -20.75)) dataItem_ComplexSingle) e(dv(.ComplexDouble (1337.73 -9283.12))dataItem_Complex) e(dv(.Boolean true) booleanTrueValue) e(dv(.Boolean false) booleanFalseValue) diff --git a/test-it/karma/publicapi/TypeReflection.Test.js b/test-it/karma/publicapi/TypeReflection.Test.js new file mode 100644 index 000000000..5c19681e2 --- /dev/null +++ b/test-it/karma/publicapi/TypeReflection.Test.js @@ -0,0 +1,140 @@ +fdescribe('The Vireo EggShell Reflection API', function () { + 'use strict'; + + var Vireo = window.NationalInstruments.Vireo.Vireo; + var vireoRunner = window.testHelpers.vireoRunner; + var fixtures = window.testHelpers.fixtures; + + var vireo = new Vireo(); + + var publicApiMultipleTypesViaUrl = fixtures.convertToAbsoluteFromFixturesDir('publicapi/MultipleTypes.via'); + var viName = 'MyVI'; + + var typeDescriptor = (function () { + var returnTypeName = function (name) { + var typeName = name; + return function () { + return typeName; + }; + }; + + return { + visitBoolean: returnTypeName('Boolean'), + visitEnum: returnTypeName('Enum'), + visitInt8: returnTypeName('Int8'), + visitInt16: returnTypeName('Int16'), + visitInt32: returnTypeName('Int32'), + visitInt64: returnTypeName('Int64'), + visitUInt8: returnTypeName('UInt8'), + visitUInt16: returnTypeName('UInt16'), + visitUInt32: returnTypeName('UInt32'), + visitUInt64: returnTypeName('UInt64'), + visitSingle: returnTypeName('Single'), + visitDouble: returnTypeName('Double'), + visitString: returnTypeName('String'), + visitComplexSingle: returnTypeName('ComplexSingle'), + visitComplexDouble: returnTypeName('ComplexDouble'), + visitAnalogWaveform: returnTypeName('AnalogWaveform'), + visitTimestamp: returnTypeName('Timestamp'), + visitPath: returnTypeName('Path'), + visitArray: returnTypeName('Array'), + visitCluster: returnTypeName('Cluster') + }; + }()); + + beforeAll(function (done) { + fixtures.preloadAbsoluteUrls([ + publicApiMultipleTypesViaUrl + ], done); + }); + + beforeAll(function () { + vireoRunner.rebootAndLoadVia(vireo, publicApiMultipleTypesViaUrl); + }); + + var getTypeName = function (path) { + return vireo.eggShell.reflectOnValueRef(typeDescriptor, vireo.eggShell.findValueRef(viName, path)); + }; + + var reflectOnEmptyVisitor = function (path) { + var thePath = path; + return function () { + vireo.eggShell.reflectOnValueRef({}, vireo.eggShell.findValueRef(viName, thePath)); + }; + }; + + describe('reflectOnValueRef', function () { + describe('error handling', function () { + it('throws when typeDescriptor is not an object', function () { + var throwingFunction = function () { + vireo.eggShell.reflectOnValueRef([]); + }; + + expect(throwingFunction).toThrow(); + }); + + it('throws when valueRef is not an object', function () { + var throwingFunction = function () { + vireo.eggShell.reflectOnValueRef({}, []); + }; + + expect(throwingFunction).toThrow(); + }); + + it('throws when visitor does not have visit methods for all types', function () { + expect(reflectOnEmptyVisitor('int8MinValue')).toThrowError(/visitInt8/); + expect(reflectOnEmptyVisitor('int16MinValue')).toThrowError(/visitInt16/); + expect(reflectOnEmptyVisitor('int32MinValue')).toThrowError(/visitInt32/); + expect(reflectOnEmptyVisitor('int64MinSafeInteger')).toThrowError(/visitInt64/); + expect(reflectOnEmptyVisitor('uInt8MinValue')).toThrowError(/visitUInt8/); + expect(reflectOnEmptyVisitor('uInt16MinValue')).toThrowError(/visitUInt16/); + expect(reflectOnEmptyVisitor('uInt32MinValue')).toThrowError(/visitUInt32/); + expect(reflectOnEmptyVisitor('uInt64MinSafeInteger')).toThrowError(/visitUInt64/); + expect(reflectOnEmptyVisitor('dataItem_NumericSingle')).toThrowError(/visitSingle/); + expect(reflectOnEmptyVisitor('dataItem_NumericDouble')).toThrowError(/visitDouble/); + expect(reflectOnEmptyVisitor('dataItem_ComplexSingle')).toThrowError(/visitComplexSingle/); + expect(reflectOnEmptyVisitor('dataItem_Complex')).toThrowError(/visitComplexDouble/); + expect(reflectOnEmptyVisitor('dataItem_String')).toThrowError(/visitString/); + expect(reflectOnEmptyVisitor('dataItem_Boolean')).toThrowError(/visitBoolean/); + expect(reflectOnEmptyVisitor('dataItem_Timestamp')).toThrowError(/visitTimestamp/); + expect(reflectOnEmptyVisitor('enum8alphabet')).toThrowError(/visitEnum/); + expect(reflectOnEmptyVisitor('wave_Double')).toThrowError(/visitAnalogWaveform/); + expect(reflectOnEmptyVisitor('dataItem_ClusterOfScalars')).toThrowError(/visitCluster/); + expect(reflectOnEmptyVisitor('dataItem_ArrayOfBoolean')).toThrowError(/visitArray/); + }); + }); + + describe('dispatches a call on visitor', function () { + it('for all numerics', function () { + expect(getTypeName('int8MinValue')).toEqual('Int8'); + expect(getTypeName('int16MinValue')).toEqual('Int16'); + expect(getTypeName('int32MinValue')).toEqual('Int32'); + expect(getTypeName('int64MinSafeInteger')).toEqual('Int64'); + expect(getTypeName('uInt8MinValue')).toEqual('UInt8'); + expect(getTypeName('uInt16MinValue')).toEqual('UInt16'); + expect(getTypeName('uInt32MinValue')).toEqual('UInt32'); + expect(getTypeName('uInt64MinSafeInteger')).toEqual('UInt64'); + expect(getTypeName('dataItem_NumericSingle')).toEqual('Single'); + expect(getTypeName('dataItem_NumericDouble')).toEqual('Double'); + expect(getTypeName('dataItem_ComplexSingle')).toEqual('ComplexSingle'); + expect(getTypeName('dataItem_Complex')).toEqual('ComplexDouble'); + }); + + it('for strings', function () { + expect(getTypeName('dataItem_String')).toEqual('String'); + }); + + it('for booleans', function () { + expect(getTypeName('dataItem_Boolean')).toEqual('Boolean'); + }); + + it('for aggregate types', function () { + expect(getTypeName('dataItem_Timestamp')).toEqual('Timestamp'); + expect(getTypeName('enum8alphabet')).toEqual('Enum'); + expect(getTypeName('wave_Double')).toEqual('AnalogWaveform'); + expect(getTypeName('dataItem_ClusterOfScalars')).toEqual('Cluster'); + expect(getTypeName('dataItem_ArrayOfBoolean')).toEqual('Array'); + }); + }); + }); +}); From d58340df86d5ffd698acd0d64c348c1b3fdd15f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Le=C3=B3n?= Date: Wed, 20 Jun 2018 16:46:45 -0500 Subject: [PATCH 10/67] Fixed whitespace in EmMakeFile and removed cwrap for TopAQSize. --- make-it/EmMakefile | 32 ++++++++++++++++---------------- source/io/module_eggShell.js | 3 +-- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/make-it/EmMakefile b/make-it/EmMakefile index e344c0826..ddd7cabf3 100644 --- a/make-it/EmMakefile +++ b/make-it/EmMakefile @@ -143,22 +143,22 @@ EM_EXPORTS = -s EXPORTED_FUNCTIONS="[\ '_Data_GetArrayMetadata',\ '_Data_GetArrayDimLength',\ '_Data_ResizeArray',\ - '_TypeRef_TopAQSize',\ - '_TypeRef_Name',\ - '_TypeRef_SubElementCount',\ - '_TypeRef_GetSubElementByIndex',\ - '_TypeRef_IsCluster',\ - '_TypeRef_IsArray',\ - '_TypeRef_IsBoolean',\ - '_TypeRef_IsInteger',\ - '_TypeRef_IsSigned',\ - '_TypeRef_IsEnum',\ - '_TypeRef_IsFloat',\ - '_TypeRef_IsString',\ - '_TypeRef_IsPath',\ - '_TypeRef_IsTimestamp',\ - '_TypeRef_IsComplex',\ - '_TypeRef_IsAnalogWaveform',\ + '_TypeRef_TopAQSize',\ + '_TypeRef_Name',\ + '_TypeRef_SubElementCount',\ + '_TypeRef_GetSubElementByIndex',\ + '_TypeRef_IsCluster',\ + '_TypeRef_IsArray',\ + '_TypeRef_IsBoolean',\ + '_TypeRef_IsInteger',\ + '_TypeRef_IsSigned',\ + '_TypeRef_IsEnum',\ + '_TypeRef_IsFloat',\ + '_TypeRef_IsString',\ + '_TypeRef_IsPath',\ + '_TypeRef_IsTimestamp',\ + '_TypeRef_IsComplex',\ + '_TypeRef_IsAnalogWaveform',\ '_JavaScriptInvoke_GetParameterType',\ '_JavaScriptInvoke_GetParameterPointer',\ '_JavaScriptInvoke_GetArrayElementType'\ diff --git a/source/io/module_eggShell.js b/source/io/module_eggShell.js index 517950f1d..2f54fa7df 100644 --- a/source/io/module_eggShell.js +++ b/source/io/module_eggShell.js @@ -138,7 +138,6 @@ var Data_WriteDouble = Module.cwrap('Data_WriteDouble', 'void', ['number', 'number']); var EggShell_ExecuteSlices = Module.cwrap('EggShell_ExecuteSlices', 'number', ['number', 'number', 'number']); var Occurrence_Set = Module.cwrap('Occurrence_Set', 'void', ['number']); - var TypeRef_TopAQSize = Module.cwrap('TypeRef_TopAQSize', 'number', ['number']); var TypeRef_Name = Module.cwrap('TypeRef_Name', 'string', ['number']); var TypeRef_SubElementCount = Module.cwrap('TypeRef_SubElementCount', 'number', ['number']); var TypeRef_GetSubElementByIndex = Module.cwrap('TypeRef_GetSubElementByIndex', 'number', ['number']); @@ -248,7 +247,7 @@ }; Module.eggShell.typeTopAQSize = function (typePointer) { - return TypeRef_TopAQSize(typePointer); + return Module._TypeRef_TopAQSize(typePointer); }; Module.eggShell.typeName = function (typePointer) { From b7c830f47ea6d0791ff09e023722d27fd124184d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Le=C3=B3n?= Date: Thu, 21 Jun 2018 14:38:27 -0500 Subject: [PATCH 11/67] Moved all type related functions to its own module. Also addressed feedback from the PR. --- source/core/CEntryPoints.cpp | 5 +- source/core/module_typeHelpers.js | 306 ++++++++++++++++++ source/core/vireo.loader.js | 3 + source/io/module_eggShell.js | 249 +------------- .../karma/publicapi/TypeReflection.Test.js | 5 +- 5 files changed, 321 insertions(+), 247 deletions(-) create mode 100644 source/core/module_typeHelpers.js diff --git a/source/core/CEntryPoints.cpp b/source/core/CEntryPoints.cpp index 839709cee..5ea9109da 100644 --- a/source/core/CEntryPoints.cpp +++ b/source/core/CEntryPoints.cpp @@ -514,6 +514,7 @@ VIREO_EXPORT Int32 TypeRef_Alignment(TypeRef typeRef) //------------------------------------------------------------ VIREO_EXPORT const char* TypeRef_Name(TypeRef typeRef) { + TypeManagerScope scope(typeRef->TheTypeManager()); SubString name = typeRef->Name(); static StringRef returnBuffer = nullptr; @@ -532,7 +533,7 @@ VIREO_EXPORT const char* TypeRef_Name(TypeRef typeRef) returnBuffer->Append((Utf8Char)'\0'); return (const char*) returnBuffer->Begin(); } - + return ""; } //------------------------------------------------------------ @@ -601,7 +602,7 @@ VIREO_EXPORT Boolean TypeRef_IsEnum(TypeRef typeRef) return typeRef->IsEnum(); } //------------------------------------------------------------ -VIREO_EXPORT Boolean TypeRef_IsFloat(TypeRef typeRef) +VIREO_EXPORT Boolean TypeRef_IsFloat(TypeRef typeRef) { return typeRef->IsFloat(); } diff --git a/source/core/module_typeHelpers.js b/source/core/module_typeHelpers.js new file mode 100644 index 000000000..ac232defa --- /dev/null +++ b/source/core/module_typeHelpers.js @@ -0,0 +1,306 @@ +// Using a modified UMD module format. Specifically a modified returnExports (no dependencies) version +(function (root, globalName, factory) { + 'use strict'; + var buildGlobalNamespace = function () { + var buildArgs = Array.prototype.slice.call(arguments); + return globalName.split('.').reduce(function (currObj, subNamespace, currentIndex, globalNameParts) { + var nextValue = currentIndex === globalNameParts.length - 1 ? factory.apply(undefined, buildArgs) : {}; + return currObj[subNamespace] === undefined ? (currObj[subNamespace] = nextValue) : currObj[subNamespace]; + }, root); + }; + + if (typeof define === 'function' && define.amd) { + // AMD. Register as a named module. + define(globalName, [], factory); + } else if (typeof module === 'object' && module.exports) { + // Node. "CommonJS-like" for environments like Node but not strict CommonJS + module.exports = factory(); + } else { + // Browser globals (root is window) + buildGlobalNamespace(); + } +}(this, 'NationalInstruments.Vireo.Core.assignTypeHelpers', function () { + 'use strict'; + + var assignTypeHelpers = function (Module) { + // Disable new-cap for the cwrap functions so the names can be the same in C and JS + /* eslint 'new-cap': ['error', {'capIsNewExceptions': [ + 'TypeRef_Name' + ]}], */ + Module.typeHelpers = {}; + + var TypeRef_Name = Module.cwrap('TypeRef_Name', 'string', ['number']); + + // Private instance functions + var validateVisitMethod = function (fn, fnName) { + if (typeof fn !== 'function') { + throw new Error('Visitor must have a method named `' + fnName + '`. Found: ' + fn); + } + }; + + var dispatchVisitBoolean = function (typeVisitor, valueRef, data) { + validateVisitMethod(typeVisitor.visitBoolean, 'visitBoolean'); + return typeVisitor.visitBoolean(valueRef, data); + }; + + var dispatchVisitEnum = function (typeVisitor, valueRef, data) { + validateVisitMethod(typeVisitor.visitEnum, 'visitEnum'); + return typeVisitor.visitEnum(typeVisitor, valueRef, data); + }; + + var dispatchVisitInteger = function (typeVisitor, valueRef, data) { + var typeRef = valueRef.typeRef; + var isSignedInteger = Module.typeHelpers.isSigned(typeRef); + var sizeOfInteger = Module.typeHelpers.topAQSize(typeRef); + var visitFn = undefined; + var typeName = ''; + if (isSignedInteger === true) { + switch (sizeOfInteger) { + case 1: + visitFn = typeVisitor.visitInt8; + typeName = 'Int8'; + break; + case 2: + visitFn = typeVisitor.visitInt16; + typeName = 'Int16'; + break; + case 4: + visitFn = typeVisitor.visitInt32; + typeName = 'Int32'; + break; + case 8: + visitFn = typeVisitor.visitInt64; + typeName = 'Int64'; + break; + default: + throw new Error('Unexpected size for Integer'); + } + } else { + switch (sizeOfInteger) { + case 1: + visitFn = typeVisitor.visitUInt8; + typeName = 'UInt8'; + break; + case 2: + visitFn = typeVisitor.visitUInt16; + typeName = 'UInt16'; + break; + case 4: + visitFn = typeVisitor.visitUInt32; + typeName = 'UInt32'; + break; + case 8: + visitFn = typeVisitor.visitUInt64; + typeName = 'UInt64'; + break; + default: + throw new Error('Unexpected size for Unsigned Integer. Found: '); + } + } + + validateVisitMethod(visitFn, 'visit' + typeName); + return visitFn.call(typeVisitor, valueRef, data); + }; + + var dispatchVisitFloat = function (typeVisitor, valueRef, data) { + var typeRef = valueRef.typeRef; + var sizeOfFloat = Module.typeHelpers.topAQSize(typeRef); + var visitFn; + var typeName = ''; + switch (sizeOfFloat) { + case 4: + visitFn = typeVisitor.visitSingle; + typeName = 'Single'; + break; + case 8: + visitFn = typeVisitor.visitDouble; + typeName = 'Double'; + break; + default: + throw new Error('Unexpected size for a Float value'); + } + + validateVisitMethod(visitFn, 'visit' + typeName); + return visitFn.call(typeVisitor, valueRef, data); + }; + + var dispatchVisitString = function (typeVisitor, valueRef, data) { + validateVisitMethod(typeVisitor.visitString, 'visitString'); + return typeVisitor.visitString(valueRef, data); + }; + + var dispatchVisitComplex = function (typeVisitor, valueRef, data) { + var typeRef = valueRef.typeRef, + sizeOfComplex = Module.typeHelpers.topAQSize(typeRef), + visitFn, + typeName; + switch (sizeOfComplex) { + case 8: + visitFn = typeVisitor.visitComplexSingle; + typeName = 'Single'; + break; + case 16: + visitFn = typeVisitor.visitComplexDouble; + typeName = 'Double'; + break; + default: + throw new Error('Unexpected size for a Complex value'); + } + + validateVisitMethod(visitFn, 'visitComplex' + typeName); + return visitFn.call(typeVisitor, valueRef, data); + }; + + var dispatchVisitAnalogWaveform = function (typeVisitor, valueRef, data) { + validateVisitMethod(typeVisitor.visitAnalogWaveform, 'visitAnalogWaveform'); + return typeVisitor.visitAnalogWaveform(valueRef, data); + }; + + var dispatchVisitTimestamp = function (typeVisitor, valueRef, data) { + validateVisitMethod(typeVisitor.visitTimestamp, 'visitTimestamp'); + return typeVisitor.visitTimestamp(valueRef, data); + }; + + var dispatchVisitPath = function (typeVisitor, valueRef, data) { + validateVisitMethod(typeVisitor.visitPath, 'visitPath'); + return typeVisitor.visitPath(valueRef, data); + }; + + var dispatchVisitArray = function (typeVisitor, valueRef, data) { + validateVisitMethod(typeVisitor.visitArray, 'visitArray'); + return typeVisitor.visitArray(valueRef, data); + }; + + var dispatchVisitCluster = function (typeVisitor, valueRef, data) { + validateVisitMethod(typeVisitor.visitCluster, 'visitCluster'); + return typeVisitor.visitCluster(typeVisitor, valueRef, data); + }; + + // Exported functions + Module.typeHelpers.topAQSize = function (typeRef) { + return Module._TypeRef_TopAQSize(typeRef); + }; + + Module.typeHelpers.typeName = function (typeRef) { + return TypeRef_Name(typeRef); + }; + + Module.typeHelpers.subElementCount = function (typeRef) { + return Module._TypeRef_SubElementCount(typeRef); + }; + + Module.typeHelpers.subElementByIndex = function (typeRef, index) { + return Module._TypeRef_GetSubElementByIndex(typeRef, index); + }; + + Module.typeHelpers.isCluster = function (typeRef) { + return Module._TypeRef_IsCluster(typeRef) !== 0; + }; + + Module.typeHelpers.isArray = function (typeRef) { + return Module._TypeRef_IsArray(typeRef) !== 0; + }; + + Module.typeHelpers.isBoolean = function (typeRef) { + return Module._TypeRef_IsBoolean(typeRef) !== 0; + }; + + Module.typeHelpers.isInteger = function (typeRef) { + return Module._TypeRef_IsInteger(typeRef) !== 0; + }; + + Module.typeHelpers.isSigned = function (typeRef) { + return Module._TypeRef_IsSigned(typeRef) !== 0; + }; + + Module.typeHelpers.isEnum = function (typeRef) { + return Module._TypeRef_IsEnum(typeRef) !== 0; + }; + + Module.typeHelpers.isFloat = function (typeRef) { + return Module._TypeRef_IsFloat(typeRef) !== 0; + }; + + Module.typeHelpers.isString = function (typeRef) { + return Module._TypeRef_IsString(typeRef) !== 0; + }; + + Module.typeHelpers.isPath = function (typeRef) { + return Module._TypeRef_IsPath(typeRef) !== 0; + }; + + Module.typeHelpers.isTimestamp = function (typeRef) { + return Module._TypeRef_IsTimestamp(typeRef) !== 0; + }; + + Module.typeHelpers.isComplex = function (typeRef) { + return Module._TypeRef_IsComplex(typeRef) !== 0; + }; + + Module.typeHelpers.isAnalogWaveform = function (typeRef) { + return Module._TypeRef_IsAnalogWaveform(typeRef) !== 0; + }; + + var typeHandlers = [ + { + typeChecker: Module.typeHelpers.isBoolean, + dispatcher: dispatchVisitBoolean + }, + { + typeChecker: Module.typeHelpers.isEnum, + dispatcher: dispatchVisitEnum + }, + { + typeChecker: Module.typeHelpers.isInteger, + dispatcher: dispatchVisitInteger + }, + { + typeChecker: Module.typeHelpers.isFloat, + dispatcher: dispatchVisitFloat + }, + { + typeChecker: Module.typeHelpers.isString, + dispatcher: dispatchVisitString + }, + { + typeChecker: Module.typeHelpers.isComplex, + dispatcher: dispatchVisitComplex + }, + { + typeChecker: Module.typeHelpers.isAnalogWaveform, + dispatcher: dispatchVisitAnalogWaveform + }, + { + typeChecker: Module.typeHelpers.isTimestamp, + dispatcher: dispatchVisitTimestamp + }, + { + typeChecker: Module.typeHelpers.isPath, + dispatcher: dispatchVisitPath + }, + { + typeChecker: Module.typeHelpers.isArray, + dispatcher: dispatchVisitArray + }, + { + typeChecker: Module.typeHelpers.isCluster, + dispatcher: dispatchVisitCluster + } + ]; + + Module.typeHelpers.findTypeDispatcher = function (typeRef) { + var i = 0, + typeHandler; + + for (i = 0; typeHandlers.length; i += 1) { + typeHandler = typeHandlers[i]; + if (typeHandler.typeChecker(typeRef) === true) { + return typeHandler.dispatcher; + } + } + return undefined; + }; + }; + + return assignTypeHelpers; +})); diff --git a/source/core/vireo.loader.js b/source/core/vireo.loader.js index 6ea8bd06c..69c759ebb 100644 --- a/source/core/vireo.loader.js +++ b/source/core/vireo.loader.js @@ -16,6 +16,7 @@ define(globalName, [ 'NationalInstruments.Vireo.Core.createVireoCore', 'NationalInstruments.Vireo.Core.assignCoreHelpers', + 'NationalInstruments.Vireo.Core.assignTypeHelpers', 'NationalInstruments.Vireo.ModuleBuilders.assignEggShell', 'NationalInstruments.Vireo.ModuleBuilders.assignHttpClient', 'NationalInstruments.Vireo.ModuleBuilders.assignJavaScriptInvoke', @@ -33,6 +34,7 @@ module.exports = factory( vireoCore, require('../../source/core/module_coreHelpers.js'), + require('../../source/core/module_typeHelpers.js'), require('../../source/io/module_eggShell.js'), require('../../source/io/module_httpClient.js'), require('../../source/io/module_javaScriptInvoke.js'), @@ -44,6 +46,7 @@ buildGlobalNamespace( root.NationalInstruments.Vireo.Core.createVireoCore, root.NationalInstruments.Vireo.Core.assignCoreHelpers, + root.NationalInstruments.Vireo.Core.assignTypeHelpers, root.NationalInstruments.Vireo.ModuleBuilders.assignEggShell, root.NationalInstruments.Vireo.ModuleBuilders.assignHttpClient, root.NationalInstruments.Vireo.ModuleBuilders.assignJavaScriptInvoke, diff --git a/source/io/module_eggShell.js b/source/io/module_eggShell.js index 2f54fa7df..925ac0199 100644 --- a/source/io/module_eggShell.js +++ b/source/io/module_eggShell.js @@ -138,9 +138,6 @@ var Data_WriteDouble = Module.cwrap('Data_WriteDouble', 'void', ['number', 'number']); var EggShell_ExecuteSlices = Module.cwrap('EggShell_ExecuteSlices', 'number', ['number', 'number', 'number']); var Occurrence_Set = Module.cwrap('Occurrence_Set', 'void', ['number']); - var TypeRef_Name = Module.cwrap('TypeRef_Name', 'string', ['number']); - var TypeRef_SubElementCount = Module.cwrap('TypeRef_SubElementCount', 'number', ['number']); - var TypeRef_GetSubElementByIndex = Module.cwrap('TypeRef_GetSubElementByIndex', 'number', ['number']); // Create shell for vireo instance var v_root = EggShell_Create(0); @@ -246,255 +243,23 @@ return result; }; - Module.eggShell.typeTopAQSize = function (typePointer) { - return Module._TypeRef_TopAQSize(typePointer); - }; - - Module.eggShell.typeName = function (typePointer) { - return TypeRef_Name(typePointer); - }; - - Module.eggShell.typeSubElementCount = function (typePointer) { - return TypeRef_SubElementCount(typePointer); - }; - - Module.eggShell.typeSubElementByIndex = function (typePointer) { - return TypeRef_GetSubElementByIndex(typePointer); - }; - - Module.eggShell.typeIsCluster = function (typePointer) { - return Module._TypeRef_IsCluster(typePointer) !== 0; - }; - - Module.eggShell.typeIsArray = function (typePointer) { - return Module._TypeRef_IsArray(typePointer) !== 0; - }; - - Module.eggShell.typeIsBoolean = function (typePointer) { - return Module._TypeRef_IsBoolean(typePointer) !== 0; - }; - - Module.eggShell.typeIsInteger = function (typePointer) { - return Module._TypeRef_IsInteger(typePointer) !== 0; - }; - - Module.eggShell.typeIsSigned = function (typePointer) { - return Module._TypeRef_IsSigned(typePointer) !== 0; - }; - - Module.eggShell.typeIsEnum = function (typePointer) { - return Module._TypeRef_IsEnum(typePointer) !== 0; - }; - - Module.eggShell.typeIsFloat = function (typePointer) { - return Module._TypeRef_IsFloat(typePointer) !== 0; - }; - - Module.eggShell.typeIsString = function (typePointer) { - return Module._TypeRef_IsString(typePointer) !== 0; - }; - - Module.eggShell.typeIsPath = function (typePointer) { - return Module._TypeRef_IsPath(typePointer) !== 0; - }; - - Module.eggShell.typeIsTimestamp = function (typePointer) { - return Module._TypeRef_IsTimestamp(typePointer) !== 0; - }; - - Module.eggShell.typeIsComplex = function (typePointer) { - return Module._TypeRef_IsComplex(typePointer) !== 0; - }; - - Module.eggShell.typeIsAnalogWaveform = function (typePointer) { - return Module._TypeRef_IsAnalogWaveform(typePointer) !== 0; - }; - - var validateVisitMethod = function (fn, fnName) { - if (typeof fn !== 'function') { - throw new Error('Visitor must have a method named `' + fnName + '`. Found: ' + fn); - } - }; - - var dispatchVisitBoolean = function (typeVisitor, args) { - validateVisitMethod(typeVisitor.visitBoolean, 'visitBoolean'); - return typeVisitor.visitBoolean.apply(typeVisitor, args); - }; - - var dispatchVisitEnum = function (typeVisitor, args) { - validateVisitMethod(typeVisitor.visitEnum, 'visitEnum'); - return typeVisitor.visitEnum.apply(typeVisitor, args); - }; - - var dispatchVisitInteger = function (typeVisitor, args) { - var typeRef = args[0].typeRef; - var isSignedInteger = Module.eggShell.typeIsSigned(typeRef); - var sizeOfInteger = Module.eggShell.typeTopAQSize(typeRef); - var visitFn = undefined; - if (isSignedInteger === true) { - switch (sizeOfInteger) { - case 1: - visitFn = typeVisitor.visitInt8; - break; - case 2: - visitFn = typeVisitor.visitInt16; - break; - case 4: - visitFn = typeVisitor.visitInt32; - break; - case 8: - visitFn = typeVisitor.visitInt64; - break; - default: - throw new Error('Unexpected size for Integer'); - } - } else { - switch (sizeOfInteger) { - case 1: - visitFn = typeVisitor.visitUInt8; - break; - case 2: - visitFn = typeVisitor.visitUInt16; - break; - case 4: - visitFn = typeVisitor.visitUInt32; - break; - case 8: - visitFn = typeVisitor.visitUInt64; - break; - default: - throw new Error('Unexpected size for Unsigned Integer. Found: '); - } - } - - var intName = (isSignedInteger ? '' : 'U') + 'Int' + (sizeOfInteger * 8); - validateVisitMethod(visitFn, 'visit' + intName); - return visitFn.apply(typeVisitor, args); - }; - - var dispatchVisitFloat = function (typeVisitor, args) { - var typeRef = args[0].typeRef; - var sizeOfFloat = Module.eggShell.typeTopAQSize(typeRef); - var visitFn; - switch (sizeOfFloat) { - case 4: - visitFn = typeVisitor.visitSingle; - break; - case 8: - visitFn = typeVisitor.visitDouble; - break; - default: - throw new Error('Unexpected size for a Float value'); - } - - validateVisitMethod(visitFn, 'visit' + (sizeOfFloat === 4 ? 'Single' : 'Double')); - return visitFn.apply(typeVisitor, args); - }; - - var dispatchVisitString = function (typeVisitor, args) { - validateVisitMethod(typeVisitor.visitString, 'visitString'); - return typeVisitor.visitString.apply(typeVisitor, args); - }; - - var dispatchVisitComplex = function (typeVisitor, args) { - var typeRef = args[0].typeRef, - sizeOfComplex = Module.eggShell.typeTopAQSize(typeRef), - visitFn; - switch (sizeOfComplex) { - case 8: - visitFn = typeVisitor.visitComplexSingle; - break; - case 16: - visitFn = typeVisitor.visitComplexDouble; - break; - default: - throw new Error('Unexpected size for a Complex value'); - } - - validateVisitMethod(visitFn, 'visitComplex' + (sizeOfComplex === 8 ? 'Single' : 'Double')); - return visitFn.apply(typeVisitor, args); - }; - - var dispatchVisitAnalogWaveform = function (typeVisitor, args) { - validateVisitMethod(typeVisitor.visitAnalogWaveform, 'visitAnalogWaveform'); - return typeVisitor.visitAnalogWaveform.apply(typeVisitor, args); - }; - - var dispatchVisitTimestamp = function (typeVisitor, args) { - validateVisitMethod(typeVisitor.visitTimestamp, 'visitTimestamp'); - return typeVisitor.visitTimestamp.apply(typeVisitor, args); - }; - - var dispatchVisitPath = function (typeVisitor, args) { - validateVisitMethod(typeVisitor.visitPath, 'visitPath'); - return typeVisitor.visitPath.apply(typeVisitor, args); - }; - - var dispatchVisitArray = function (typeVisitor, args) { - validateVisitMethod(typeVisitor.visitArray, 'visitArray'); - return typeVisitor.visitArray.apply(typeVisitor, args); - }; - - var dispatchVisitCluster = function (typeVisitor, args) { - validateVisitMethod(typeVisitor.visitCluster, 'visitCluster'); - return typeVisitor.visitCluster.apply(typeVisitor, args); - }; - - var typeDispatchFunctions = [ - dispatchVisitBoolean, - dispatchVisitEnum, - dispatchVisitInteger, - dispatchVisitFloat, - dispatchVisitString, - dispatchVisitComplex, - dispatchVisitAnalogWaveform, - dispatchVisitTimestamp, - dispatchVisitPath, - dispatchVisitArray, - dispatchVisitCluster - ]; - - var registeredTypes = [ - Module.eggShell.typeIsBoolean, - Module.eggShell.typeIsEnum, - Module.eggShell.typeIsInteger, - Module.eggShell.typeIsFloat, - Module.eggShell.typeIsString, - Module.eggShell.typeIsComplex, - Module.eggShell.typeIsAnalogWaveform, - Module.eggShell.typeIsTimestamp, - Module.eggShell.typeIsPath, - Module.eggShell.typeIsArray, - Module.eggShell.typeIsCluster - ]; - - Module.eggShell.reflectOnValueRef = publicAPI.eggShell.reflectOnValueRef = function (typeVisitor, valueRef) { - if (typeof valueRef !== 'object' || Array.isArray(valueRef)) { + Module.eggShell.reflectOnValueRef = publicAPI.eggShell.reflectOnValueRef = function (typeVisitor, valueRef, data) { + if (typeof valueRef !== 'object' || valueRef === null) { throw new Error('valueRef must be an object. Found: ' + valueRef); } - if (typeof typeVisitor !== 'object' || Array.isArray(typeVisitor)) { + if (typeof typeVisitor !== 'object' || typeVisitor === null) { throw new Error('typeVisitor must be an object. Found: ' + typeVisitor); } var typeRef = valueRef.typeRef, - args = Array.prototype.slice.call(arguments, 1), - foundTypeIndex = -1, - i = 0; - - for (i = 0; i < registeredTypes.length; i += 1) { - if (registeredTypes[i](typeRef) === true) { - foundTypeIndex = i; - break; - } - } + dispatchFunction = Module.typeHelpers.findTypeDispatcher(typeRef); - if (foundTypeIndex < 0) { - throw new Error('Unexpected type. Is typeRef pointing to a valid type?. TypeRef found: ' + typeRef); + if (dispatchFunction === undefined) { + throw new Error('Unexpected type. Is typeRef pointing to a valid type?. Type found: ' + typeRef === 0 ? 'invalid type' : Module.typeHelpers.typeName(typeRef)); } - var dispatchFunction = typeDispatchFunctions[foundTypeIndex]; - return dispatchFunction(typeVisitor, args); + return dispatchFunction(typeVisitor, valueRef, data); }; Module.eggShell.writeDouble = publicAPI.eggShell.writeDouble = function (vi, path, value) { diff --git a/test-it/karma/publicapi/TypeReflection.Test.js b/test-it/karma/publicapi/TypeReflection.Test.js index 5c19681e2..d4b52b7b3 100644 --- a/test-it/karma/publicapi/TypeReflection.Test.js +++ b/test-it/karma/publicapi/TypeReflection.Test.js @@ -1,4 +1,4 @@ -fdescribe('The Vireo EggShell Reflection API', function () { +describe('The Vireo EggShell Reflection API', function () { 'use strict'; var Vireo = window.NationalInstruments.Vireo.Vireo; @@ -12,9 +12,8 @@ fdescribe('The Vireo EggShell Reflection API', function () { var typeDescriptor = (function () { var returnTypeName = function (name) { - var typeName = name; return function () { - return typeName; + return name; }; }; From 6db68343a29088b54e9038b6aec0fa587dcf44e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Le=C3=B3n?= Date: Thu, 21 Jun 2018 14:55:02 -0500 Subject: [PATCH 12/67] Fixed linting issues --- source/core/TypeAndDataManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/core/TypeAndDataManager.cpp b/source/core/TypeAndDataManager.cpp index 4f30238c0..f0fe6781c 100644 --- a/source/core/TypeAndDataManager.cpp +++ b/source/core/TypeAndDataManager.cpp @@ -874,7 +874,7 @@ Boolean TypeCommon::IsNumeric() return false; } //------------------------------------------------------------ -Boolean TypeCommon::IsInteger() +Boolean TypeCommon::IsInteger() { TypeRef t = this; while (t) { From 5f812dc73ba5180d7283d6407fe436f6b1bd3606 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Le=C3=B3n?= Date: Thu, 21 Jun 2018 15:07:06 -0500 Subject: [PATCH 13/67] Modified TypeRef_Name to take a TypeManagerRef as other similar functions --- source/core/CEntryPoints.cpp | 4 ++-- source/include/CEntryPoints.h | 2 +- source/io/module_eggShell.js | 3 +++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/source/core/CEntryPoints.cpp b/source/core/CEntryPoints.cpp index 5ea9109da..0ff662231 100644 --- a/source/core/CEntryPoints.cpp +++ b/source/core/CEntryPoints.cpp @@ -512,9 +512,9 @@ VIREO_EXPORT Int32 TypeRef_Alignment(TypeRef typeRef) return typeRef->AQAlignment(); } //------------------------------------------------------------ -VIREO_EXPORT const char* TypeRef_Name(TypeRef typeRef) +VIREO_EXPORT const char* TypeRef_Name(TypeManagerRef tm, TypeRef typeRef) { - TypeManagerScope scope(typeRef->TheTypeManager()); + TypeManagerScope scope(tm); SubString name = typeRef->Name(); static StringRef returnBuffer = nullptr; diff --git a/source/include/CEntryPoints.h b/source/include/CEntryPoints.h index aa022a5ea..3c20263c1 100644 --- a/source/include/CEntryPoints.h +++ b/source/include/CEntryPoints.h @@ -70,7 +70,7 @@ VIREO_EXPORT Boolean TypeRef_IsValid(TypeRef typeRef); VIREO_EXPORT Boolean TypeRef_HasCustomDefault(TypeRef typeRef); VIREO_EXPORT EncodingEnum TypeRef_BitEncoding(TypeRef typeRef); VIREO_EXPORT Int32 TypeRef_Alignment(TypeRef typeRef); -VIREO_EXPORT const char* TypeRef_Name(TypeRef typeRef); +VIREO_EXPORT const char* TypeRef_Name(TypeManagerRef typeManager, TypeRef typeRef); VIREO_EXPORT Int32 TypeRef_ElementOffset(TypeRef typeRef); VIREO_EXPORT Int32 TypeRef_Rank(TypeRef typeRef); VIREO_EXPORT PointerTypeEnum TypeRef_PointerType(TypeRef typeRef); diff --git a/source/io/module_eggShell.js b/source/io/module_eggShell.js index 925ac0199..0d6826988 100644 --- a/source/io/module_eggShell.js +++ b/source/io/module_eggShell.js @@ -143,6 +143,9 @@ var v_root = EggShell_Create(0); var v_userShell = EggShell_Create(v_root); + Module.eggShell.v_root = v_root; + Module.eggShell.v_userShell = v_userShell; + // Exported functions Module.print = function (text) { console.log(text); From cfd90b0f077015a44f8215393a1f20aeef4cd3a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Le=C3=B3n?= Date: Thu, 21 Jun 2018 15:08:01 -0500 Subject: [PATCH 14/67] Removed string allocations for errors --- source/core/module_typeHelpers.js | 46 +++++++++++++++---------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/source/core/module_typeHelpers.js b/source/core/module_typeHelpers.js index ac232defa..d102e5fb3 100644 --- a/source/core/module_typeHelpers.js +++ b/source/core/module_typeHelpers.js @@ -53,52 +53,52 @@ var isSignedInteger = Module.typeHelpers.isSigned(typeRef); var sizeOfInteger = Module.typeHelpers.topAQSize(typeRef); var visitFn = undefined; - var typeName = ''; + var fnName = ''; if (isSignedInteger === true) { switch (sizeOfInteger) { case 1: visitFn = typeVisitor.visitInt8; - typeName = 'Int8'; + fnName = 'visitInt8'; break; case 2: visitFn = typeVisitor.visitInt16; - typeName = 'Int16'; + fnName = 'visitInt16'; break; case 4: visitFn = typeVisitor.visitInt32; - typeName = 'Int32'; + fnName = 'visitInt32'; break; case 8: visitFn = typeVisitor.visitInt64; - typeName = 'Int64'; + fnName = 'visitInt64'; break; default: - throw new Error('Unexpected size for Integer'); + throw new Error('Unexpected size for Integer. Found: ' + sizeOfInteger); } } else { switch (sizeOfInteger) { case 1: visitFn = typeVisitor.visitUInt8; - typeName = 'UInt8'; + fnName = 'visitUInt8'; break; case 2: visitFn = typeVisitor.visitUInt16; - typeName = 'UInt16'; + fnName = 'visitUInt16'; break; case 4: visitFn = typeVisitor.visitUInt32; - typeName = 'UInt32'; + fnName = 'visitUInt32'; break; case 8: visitFn = typeVisitor.visitUInt64; - typeName = 'UInt64'; + fnName = 'visitUInt64'; break; default: - throw new Error('Unexpected size for Unsigned Integer. Found: '); + throw new Error('Unexpected size for Unsigned Integer. Found: ' + sizeOfInteger); } } - validateVisitMethod(visitFn, 'visit' + typeName); + validateVisitMethod(visitFn, fnName); return visitFn.call(typeVisitor, valueRef, data); }; @@ -106,21 +106,21 @@ var typeRef = valueRef.typeRef; var sizeOfFloat = Module.typeHelpers.topAQSize(typeRef); var visitFn; - var typeName = ''; + var fnName = ''; switch (sizeOfFloat) { case 4: visitFn = typeVisitor.visitSingle; - typeName = 'Single'; + fnName = 'visitSingle'; break; case 8: visitFn = typeVisitor.visitDouble; - typeName = 'Double'; + fnName = 'visitDouble'; break; default: - throw new Error('Unexpected size for a Float value'); + throw new Error('Unexpected size for a Float value. Found: ' + sizeOfFloat); } - validateVisitMethod(visitFn, 'visit' + typeName); + validateVisitMethod(visitFn, fnName); return visitFn.call(typeVisitor, valueRef, data); }; @@ -133,21 +133,21 @@ var typeRef = valueRef.typeRef, sizeOfComplex = Module.typeHelpers.topAQSize(typeRef), visitFn, - typeName; + fnName; switch (sizeOfComplex) { case 8: visitFn = typeVisitor.visitComplexSingle; - typeName = 'Single'; + fnName = 'visitComplexSingle'; break; case 16: visitFn = typeVisitor.visitComplexDouble; - typeName = 'Double'; + fnName = 'visitComplexDouble'; break; default: - throw new Error('Unexpected size for a Complex value'); + throw new Error('Unexpected size for a Complex value. Found: ' + sizeOfComplex); } - validateVisitMethod(visitFn, 'visitComplex' + typeName); + validateVisitMethod(visitFn, fnName); return visitFn.call(typeVisitor, valueRef, data); }; @@ -182,7 +182,7 @@ }; Module.typeHelpers.typeName = function (typeRef) { - return TypeRef_Name(typeRef); + return TypeRef_Name(Module.eggShell.v_userShell, typeRef); }; Module.typeHelpers.subElementCount = function (typeRef) { From 9d732e77f88e2ce8d980ca3414cb097429becc0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Le=C3=B3n?= Date: Thu, 21 Jun 2018 15:17:04 -0500 Subject: [PATCH 15/67] Moved v_root and v_userShell --- source/io/module_eggShell.js | 49 +++++++++++++++++------------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/source/io/module_eggShell.js b/source/io/module_eggShell.js index 0d6826988..20bdb0b73 100644 --- a/source/io/module_eggShell.js +++ b/source/io/module_eggShell.js @@ -140,11 +140,8 @@ var Occurrence_Set = Module.cwrap('Occurrence_Set', 'void', ['number']); // Create shell for vireo instance - var v_root = EggShell_Create(0); - var v_userShell = EggShell_Create(v_root); - - Module.eggShell.v_root = v_root; - Module.eggShell.v_userShell = v_userShell; + Module.eggShell.v_root = EggShell_Create(0); + Module.eggShell.v_userShell = EggShell_Create(Module.eggShell.v_root); // Exported functions Module.print = function (text) { @@ -191,10 +188,10 @@ Module.eggShell.maxExecWakeUpTime = publicAPI.eggShell.maxExecWakeUpTime = Vireo_MaxExecWakeUpTime; Module.eggShell.reboot = publicAPI.eggShell.reboot = function () { - EggShell_Delete(v_userShell); - EggShell_Delete(v_root); - v_root = EggShell_Create(0); - v_userShell = EggShell_Create(v_root); + EggShell_Delete(Module.eggShell.v_userShell); + EggShell_Delete(Module.eggShell.v_root); + Module.eggShell.v_root = EggShell_Create(0); + Module.eggShell.v_userShell = EggShell_Create(Module.eggShell.v_root); }; Module.eggShell.createValueRef = function (typeRef, dataRef) { @@ -212,7 +209,7 @@ var typeStackPointer = Module.stackAlloc(POINTER_SIZE); var dataStackPointer = Module.stackAlloc(POINTER_SIZE); - var eggShellResult = Module._EggShell_FindValue(v_userShell, viStackPointer, pathStackPointer, typeStackPointer, dataStackPointer); + var eggShellResult = Module._EggShell_FindValue(Module.eggShell.v_userShell, viStackPointer, pathStackPointer, typeStackPointer, dataStackPointer); if (eggShellResult !== 0) { throw new Error('A ValueRef could not be made for the following reason: ' + eggShellResultEnum[eggShellResult] + ' (error code: ' + eggShellResult + ')' + @@ -233,7 +230,7 @@ var resultPointer = Module.stackAlloc(DOUBLE_SIZE); // TODO mraj should we try to resolve the typeref name on error for more context? - var niError = Module._EggShell_ReadDouble(v_userShell, valueRef.typeRef, valueRef.dataRef, resultPointer); + var niError = Module._EggShell_ReadDouble(Module.eggShell.v_userShell, valueRef.typeRef, valueRef.dataRef, resultPointer); if (niError !== 0) { throw new Error('Loading VIA failed for the following reason: ' + niErrorEnum[niError] + ' (error code: ' + niError + ')' + @@ -266,7 +263,7 @@ }; Module.eggShell.writeDouble = publicAPI.eggShell.writeDouble = function (vi, path, value) { - EggShell_WriteDouble(v_userShell, vi, path, value); + EggShell_WriteDouble(Module.eggShell.v_userShell, vi, path, value); }; Module.eggShell.readJSON = publicAPI.eggShell.readJSON = function (vi, path) { @@ -277,7 +274,7 @@ var pathStackPointer = Module.coreHelpers.writeJSStringToStack(path); var typeStackPointer = Module.coreHelpers.writeJSStringToStack(type); - var responsePointer = Module._EggShell_ReadValueString(v_userShell, viStackPointer, pathStackPointer, typeStackPointer); + var responsePointer = Module._EggShell_ReadValueString(Module.eggShell.v_userShell, viStackPointer, pathStackPointer, typeStackPointer); var responseLength = Module.coreHelpers.findCStringLength(Module.HEAPU8, responsePointer); var response = Module.coreHelpers.sizedUtf8ArrayToJSString(Module.HEAPU8, responsePointer, responseLength); @@ -286,7 +283,7 @@ }; Module.eggShell.writeJSON = publicAPI.eggShell.writeJSON = function (vi, path, value) { - EggShell_WriteValueString(v_userShell, vi, path, 'JSON', value); + EggShell_WriteValueString(Module.eggShell.v_userShell, vi, path, 'JSON', value); }; var supportedArrayTypeConfig = { @@ -394,7 +391,7 @@ var vireoTypePointer = Module._malloc(4); Module.eggShell.getNumericArray = publicAPI.eggShell.getNumericArray = function (vi, path) { - var eggShellResult = EggShell_GetPointer(v_userShell, vi, path, vireoObjectPointer, vireoTypePointer); + var eggShellResult = EggShell_GetPointer(Module.eggShell.v_userShell, vi, path, vireoObjectPointer, vireoTypePointer); if (eggShellResult !== 0) { throw new Error('Getting the array pointer failed for the following reason: ' + eggShellResultEnum[eggShellResult] + @@ -405,7 +402,7 @@ var arrayVireoPointer = Module.getValue(vireoObjectPointer, 'i32'); var typePointer = Module.getValue(vireoTypePointer, 'i32'); - eggShellResult = Data_ValidateArrayType(v_userShell, typePointer); + eggShellResult = Data_ValidateArrayType(Module.eggShell.v_userShell, typePointer); if (eggShellResult !== 0) { throw new Error('Getting the array pointer failed for the following reason: ' + eggShellResultEnum[eggShellResult] + @@ -432,7 +429,7 @@ }; Module.eggShell.getArrayDimLength = publicAPI.eggShell.getArrayDimLength = function (vi, path, dim) { - return EggShell_GetArrayDimLength(v_userShell, vi, path, dim); + return EggShell_GetArrayDimLength(Module.eggShell.v_userShell, vi, path, dim); }; Module.eggShell.resizeArray = publicAPI.eggShell.resizeArray = function (vi, path, newDimensionSizes) { @@ -444,7 +441,7 @@ Module.setValue(newLengths + (i * int32Byte), newDimensionSizes[i], 'i32'); } - var success = EggShell_ResizeArray(v_userShell, vi, path, rank, newLengths); + var success = EggShell_ResizeArray(Module.eggShell.v_userShell, vi, path, rank, newLengths); Module._free(newLengths); @@ -468,14 +465,14 @@ // Source should be a JS String Module.eggShell.dataWriteString = function (destination, source) { var sourceLength = Module.lengthBytesUTF8(source); - Data_WriteString(v_userShell, destination, source, sourceLength); + Data_WriteString(Module.eggShell.v_userShell, destination, source, sourceLength); }; // Source should be a JS array of numbers or a TypedArray of Uint8Array or Int8Array Module.eggShell.dataWriteStringFromArray = function (destination, source) { var sourceHeapPointer = Module._malloc(source.length); Module.writeArrayToMemory(source, sourceHeapPointer); - Module._Data_WriteString(v_userShell, destination, sourceHeapPointer, source.length); + Module._Data_WriteString(Module.eggShell.v_userShell, destination, sourceHeapPointer, source.length); Module._free(sourceHeapPointer); }; @@ -529,7 +526,7 @@ }; Module.eggShell.dataReadNumericArrayAsTypedArray = function (arrayPointer) { - var eggShellResult = Data_GetArrayMetadata(v_userShell, arrayPointer, arrayTypeNameDoublePointer, arrayRankPointer, arrayBeginPointer); + var eggShellResult = Data_GetArrayMetadata(Module.eggShell.v_userShell, arrayPointer, arrayTypeNameDoublePointer, arrayRankPointer, arrayBeginPointer); if (eggShellResult !== 0) { throw new Error('Querying Array Metadata failed for the following reason: ' + eggShellResultEnum[eggShellResult] + @@ -567,7 +564,7 @@ var arrayLength = 1; dimensionLengths = []; for (var j = 0; j < arrayRank; j += 1) { - dimensionLengths[j] = Data_GetArrayDimLength(v_userShell, arrayPointer, j); + dimensionLengths[j] = Data_GetArrayDimLength(Module.eggShell.v_userShell, arrayPointer, j); arrayLength *= dimensionLengths[j]; } @@ -622,10 +619,10 @@ var newLengths = Module._malloc(rank * int32Byte); Module.setValue(newLengths, value.length, 'i32'); - Data_ResizeArray(v_userShell, destination, rank, newLengths); + Data_ResizeArray(Module.eggShell.v_userShell, destination, rank, newLengths); Module._free(newLengths); - var eggShellResult = Data_GetArrayMetadata(v_userShell, destination, arrayTypeNameDoublePointer, arrayRankPointer, arrayBeginPointer); + var eggShellResult = Data_GetArrayMetadata(Module.eggShell.v_userShell, destination, arrayTypeNameDoublePointer, arrayRankPointer, arrayBeginPointer); if (eggShellResult !== 0) { throw new Error('Querying Array Metadata failed for the following reason: ' + eggShellResultEnum[eggShellResult] + @@ -668,7 +665,7 @@ origPrintErr(textErr); }; - var result = Module._EggShell_REPL(v_userShell, viaTextPointer, viaTextLength); + var result = Module._EggShell_REPL(Module.eggShell.v_userShell, viaTextPointer, viaTextLength); Module._free(viaTextPointer); Module.print = origPrint; Module.printErr = origPrintErr; @@ -690,7 +687,7 @@ // returns < 0 if should be called again ASAP, 0 if nothing to run, or positive value N if okay // to delay up to N milliseconds before calling again Module.eggShell.executeSlicesUntilWait = publicAPI.eggShell.executeSlicesUntilWait = function (numSlices, millisecondsToRun) { - return EggShell_ExecuteSlices(v_userShell, numSlices, millisecondsToRun); + return EggShell_ExecuteSlices(Module.eggShell.v_userShell, numSlices, millisecondsToRun); }; // Pumps vireo asynchronously until the currently loaded via has finished all clumps From 440a1758b84c78b24b5573407ab356614bfc2ee3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Le=C3=B3n?= Date: Thu, 21 Jun 2018 17:47:56 -0500 Subject: [PATCH 16/67] Added findSubValueRef --- make-it/EmMakefile | 1 + source/core/CEntryPoints.cpp | 12 ++++++++++++ source/include/CEntryPoints.h | 1 + source/io/module_eggShell.js | 23 +++++++++++++++++++++++ 4 files changed, 37 insertions(+) diff --git a/make-it/EmMakefile b/make-it/EmMakefile index ddd7cabf3..56d74505d 100644 --- a/make-it/EmMakefile +++ b/make-it/EmMakefile @@ -107,6 +107,7 @@ EM_EXPORTS = -s EXPORTED_FUNCTIONS="[\ '_EggShell_ExecuteSlices',\ '_EggShell_Delete',\ '_EggShell_FindValue',\ + '_EggShell_FindSubValue',\ '_EggShell_ReadDouble',\ '_EggShell_WriteDouble',\ '_EggShell_ReadValueString',\ diff --git a/source/core/CEntryPoints.cpp b/source/core/CEntryPoints.cpp index 0ff662231..994ad0450 100644 --- a/source/core/CEntryPoints.cpp +++ b/source/core/CEntryPoints.cpp @@ -130,6 +130,18 @@ VIREO_EXPORT EggShellResult EggShell_FindValue(TypeManagerRef tm, const char* vi return kEggShellResult_Success; } //------------------------------------------------------------ +//! Get a reference to the type pointer and data for a sub element +VIREO_EXPORT EggShellResult EggShell_FindSubValue(TypeManagerRef tm, TypeRef typeRef, const char* eltName, TypeRef* typeRefLocation, void** dataRefLocation) +{ + SubString path(eltName); + void* pData = typeRef->Begin(kPARead); + *typeRefLocation = typeRef->GetSubElementAddressFromPath(&path, pData, dataRefLocation, true); + if (*typeRefLocation == nullptr) + return kEggShellResult_ObjectNotFoundAtPath; + + return kEggShellResult_Success; +} +//------------------------------------------------------------ //! Write a numeric value to a symbol. Value will be coerced as needed. VIREO_EXPORT void EggShell_WriteDouble(TypeManagerRef tm, const char* viName, const char* eltName, Double d) { diff --git a/source/include/CEntryPoints.h b/source/include/CEntryPoints.h index 3c20263c1..4831a448a 100644 --- a/source/include/CEntryPoints.h +++ b/source/include/CEntryPoints.h @@ -36,6 +36,7 @@ VIREO_EXPORT Int32 EggShell_PeekMemory(TypeManagerRef tm, const char* viName, co VIREO_EXPORT Int32 EggShell_PokeMemory(TypeManagerRef tm, const char* viName, const char* eltName, Int32 bufferSize, char* buffer); VIREO_EXPORT EggShellResult EggShell_FindValue(TypeManagerRef tm, const char* viName, const char* eltName, TypeRef* typeRefLocation, void** dataRefLocation); +VIREO_EXPORT EggShellResult EggShell_FindSubValue(TypeManagerRef tm, TypeRef type, const char* eltName, TypeRef* typeRefLocation, void** dataRefLocation); VIREO_EXPORT void EggShell_WriteDouble(TypeManagerRef tm, const char* viName, const char* eltName, Double d); VIREO_EXPORT NIError EggShell_ReadDouble(TypeManagerRef tm, const TypeRef actualType, const void* pData, Double* result); VIREO_EXPORT void EggShell_WriteValueString(TypeManagerRef tm, const char* viName, const char* eltName, diff --git a/source/io/module_eggShell.js b/source/io/module_eggShell.js index 20bdb0b73..8e105ae6a 100644 --- a/source/io/module_eggShell.js +++ b/source/io/module_eggShell.js @@ -225,6 +225,29 @@ return valueRef; }; + Module.eggShell.findSubValueRef = publicAPI.eggShell.findSubValueRef = function (valueRef, path) { + var stack = Module.stackSave(); + + var pathStackPointer = Module.coreHelpers.writeJSStringToStack(path); + var typeStackPointer = Module.stackAlloc(POINTER_SIZE); + var dataStackPointer = Module.stackAlloc(POINTER_SIZE); + + var eggShellResult = Module._EggShell_FindSubValue(Module.eggShell.v_userShell, valueRef.typeRef, pathStackPointer, typeStackPointer, dataStackPointer); + if (eggShellResult !== 0) { + throw new Error('A ValueRef could not be made for the following reason: ' + eggShellResultEnum[eggShellResult] + + ' (error code: ' + eggShellResult + ')' + + ' (type name: ' + Module.typeHelpers.typeName(valueRef.typeRef) + ')' + + ' (path: ' + path + ')'); + } + + var typeRef = Module.getValue(typeStackPointer, 'i32'); + var dataRef = Module.getValue(dataStackPointer, 'i32'); + var subValueRef = Module.eggShell.createValueRef(typeRef, dataRef); + + Module.stackRestore(stack); + return subValueRef; + }; + Module.eggShell.readDouble = publicAPI.eggShell.readDouble = function (valueRef) { var stack = Module.stackSave(); var resultPointer = Module.stackAlloc(DOUBLE_SIZE); From caa3ca82a38d7af6957228c2478aed9d87cf594b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Le=C3=B3n?= Date: Fri, 22 Jun 2018 13:00:17 -0500 Subject: [PATCH 17/67] Added tests for FindSubValueRef --- .../karma/publicapi/DoubleInAggregate.Test.js | 75 +++++++ .../karma/publicapi/FindSubValueRef.Test.js | 192 ++++++++++++++++++ 2 files changed, 267 insertions(+) create mode 100644 test-it/karma/publicapi/DoubleInAggregate.Test.js create mode 100644 test-it/karma/publicapi/FindSubValueRef.Test.js diff --git a/test-it/karma/publicapi/DoubleInAggregate.Test.js b/test-it/karma/publicapi/DoubleInAggregate.Test.js new file mode 100644 index 000000000..fab3ec040 --- /dev/null +++ b/test-it/karma/publicapi/DoubleInAggregate.Test.js @@ -0,0 +1,75 @@ +describe('The Vireo EggShell Double api can', function () { + 'use strict'; + // Reference aliases + var Vireo = window.NationalInstruments.Vireo.Vireo; + var vireoRunner = window.testHelpers.vireoRunner; + var fixtures = window.testHelpers.fixtures; + + var vireo = new Vireo(); + + var publicApiMultipleTypesViaUrl = fixtures.convertToAbsoluteFromFixturesDir('publicapi/MultipleTypes.via'); + var viName = 'MyVI'; + + var readDouble = function (path, subPath) { + var valueRef = vireo.eggShell.findValueRef(viName, path); + var subValueRef = vireo.eggShell.findSubValueRef(valueRef, subPath); + return vireo.eggShell.readDouble(subValueRef); + }; + + beforeAll(function (done) { + fixtures.preloadAbsoluteUrls([ + publicApiMultipleTypesViaUrl + ], done); + }); + + beforeAll(function () { + vireoRunner.rebootAndLoadVia(vireo, publicApiMultipleTypesViaUrl); + }); + + describe('use readDouble', function () { + it('to read different double values from 1-D arrays', function () { + expect(readDouble('dataItem_ArrayOfBoolean', '3')).toBe(1); + expect(readDouble('dataItem_ArrayOfDouble', '4')).toMatchIEEE754Number(1234.5678); + expect(readDouble('dataItem_ArrayOfInt32', '3')).toBe(9876543); + expect(readDouble('dataItem_ArrayOfInt64', '1')).toBe(9090); + expect(readDouble('dataItem_ArrayOfTimestamp', '0')).toMatchIEEE754Number(3564057536.423476); + }); + + it('to read different double values from N-dimensional arrays', function () { + expect(readDouble('dataItem_2DArrayOfBoolean', '2,1')).toBe(1); + expect(readDouble('dataItem_2DArrayOfDouble', '1,2')).toMatchIEEE754Number(-6.789); + expect(readDouble('dataItem_3DArrayOfInt32', '1,1,2')).toBe(223); + expect(readDouble('dataItem_2DArrayOfInt64', '0,0')).toBe(9090); + expect(readDouble('dataItem_2DArrayOfTimestamp', '0,1')).toMatchIEEE754Number(3564057542.904824); + }); + + it('to read different double values from clusters', function () { + var path = 'dataItem_ClusterOfScalars'; + expect(readDouble(path, 'bool')).toBe(1); + expect(readDouble(path, 'double')).toMatchIEEE754Number(3.14159); + expect(readDouble(path, 'int32')).toBe(42); + expect(readDouble(path, 'int64')).toBe(-72057594037927936); + expect(readDouble(path, 'uint64')).toBe(9223372041149743104); + expect(readDouble(path, 'time')).toMatchIEEE754Number(3564057536.423476); + }); + + it('to read different double values from array of clusters', function () { + var path = 'dataItem_ArrayOfClusters'; + expect(readDouble(path, '0.bool')).toBe(1); + expect(readDouble(path, '1.double')).toMatchIEEE754Number(6.2831); + expect(readDouble(path, '2.int32')).toBe(144); + expect(readDouble(path, '0.int64')).toBe(72057594037927936); + expect(readDouble(path, '1.time')).toMatchIEEE754Number(3564059871.423476); + }); + + it('to read different double values from cluster of arrays', function () { + var path = 'dataItem_ClusterOfArrays'; + expect(readDouble(path, 'booleans.2')).toBe(1); + expect(readDouble(path, 'doubles.3')).toMatchIEEE754Number(7.89); + expect(readDouble(path, 'int32s.0')).toBe(-1000); + expect(readDouble(path, 'int64s.1')).toBe(9090); + expect(readDouble(path, 'uint64s.2')).toBe(9223376434901286912); + expect(readDouble(path, 'times.1')).toMatchIEEE754Number(3564057542.904824); + }); + }); +}); diff --git a/test-it/karma/publicapi/FindSubValueRef.Test.js b/test-it/karma/publicapi/FindSubValueRef.Test.js new file mode 100644 index 000000000..e6cfa60f0 --- /dev/null +++ b/test-it/karma/publicapi/FindSubValueRef.Test.js @@ -0,0 +1,192 @@ +describe('The Vireo EggShell findSubValueRef', function () { + 'use strict'; + + // Reference aliases + var Vireo = window.NationalInstruments.Vireo.Vireo; + var vireoRunner = window.testHelpers.vireoRunner; + var fixtures = window.testHelpers.fixtures; + + var vireo = new Vireo(); + + var publicApiMultipleTypesViaUrl = fixtures.convertToAbsoluteFromFixturesDir('publicapi/MultipleTypes.via'); + var viName = 'MyVI'; + + var expectValidValueRef = function (valueRef) { + expect(valueRef).toBeNonEmptyObject(); + expect(valueRef.typeRef).toBeNumber(); + expect(valueRef.typeRef).not.toBe(0); + expect(valueRef.dataRef).toBeNumber(); + expect(valueRef.dataRef).not.toBe(0); + }; + + beforeAll(function (done) { + fixtures.preloadAbsoluteUrls([ + publicApiMultipleTypesViaUrl + ], done); + }); + + beforeAll(function () { + vireoRunner.rebootAndLoadVia(vireo, publicApiMultipleTypesViaUrl); + }); + + describe('for a cluster of scalars', function () { + var valueRef, + clusterOfScalarsPath = 'dataItem_ClusterOfScalars'; + + beforeAll(function () { + valueRef = vireo.eggShell.findValueRef(viName, clusterOfScalarsPath); + }); + + it('throws for an object with no typeRef', function () { + var invalidValueRef = function () { + vireo.eggShell.findSubValueRef({}, 'dataItem_ClusterOfScalars'); + }; + + expect(invalidValueRef).toThrow(); + }); + + it('throws for a nonexistant path', function () { + var invalidPath = function () { + vireo.eggShell.findSubValueRef(valueRef, 'nonexistantpath'); + }; + + expect(invalidPath).toThrow(); + }); + + it('finds values of cluster elements', function () { + expectValidValueRef(vireo.eggShell.findSubValueRef(valueRef, 'bool')); + expectValidValueRef(vireo.eggShell.findSubValueRef(valueRef, 'string')); + expectValidValueRef(vireo.eggShell.findSubValueRef(valueRef, 'double')); + expectValidValueRef(vireo.eggShell.findSubValueRef(valueRef, 'int32')); + expectValidValueRef(vireo.eggShell.findSubValueRef(valueRef, 'int64')); + expectValidValueRef(vireo.eggShell.findSubValueRef(valueRef, 'uint64')); + expectValidValueRef(vireo.eggShell.findSubValueRef(valueRef, 'complex')); + expectValidValueRef(vireo.eggShell.findSubValueRef(valueRef, 'time')); + }); + }); + + describe('for a 1D array', function () { + var valueRef, + arrayOfBooleansPath = 'dataItem_ArrayOfBoolean'; + + beforeAll(function () { + valueRef = vireo.eggShell.findValueRef(viName, arrayOfBooleansPath); + }); + + it('throws for invalid index', function () { + var invalidIndex = function () { + vireo.eggShell.findSubValueRef(valueRef, '-1'); + }; + + expect(invalidIndex).toThrow(); + }); + + it('throws for index out of bounds', function () { + var invalidIndex = function () { + vireo.eggShell.findSubValueRef(valueRef, '10'); + }; + + expect(invalidIndex).toThrow(); + }); + + it('finds a value', function () { + expectValidValueRef(vireo.eggShell.findSubValueRef(valueRef, '0')); + }); + }); + + describe('for a multidimensional array', function () { + var valueRef, + ndimArrayPath = 'dataItem_3DArrayOfInt32'; // Dimensions: [1, 2, 3] + + beforeAll(function () { + valueRef = vireo.eggShell.findValueRef(viName, ndimArrayPath); + }); + + it('throws for an invalid path format', function () { + var invalidPathFormat = function () { + vireo.eggShell.findSubValueRef(valueRef, '0,0.0'); + }; + + expect(invalidPathFormat).toThrow(); + }); + + it('throws for index out of bounds', function () { + var indexOutOfBounds = function () { + vireo.eggShell.findSubValueRef(valueRef, '2,0,0'); + }; + + expect(indexOutOfBounds).toThrow(); + }); + + it('finds values for comma-separated indexes', function () { + expectValidValueRef(vireo.eggShell.findSubValueRef(valueRef, '0,0,0')); + expectValidValueRef(vireo.eggShell.findSubValueRef(valueRef, '0,0,2')); + expectValidValueRef(vireo.eggShell.findSubValueRef(valueRef, '0,1,2')); + expectValidValueRef(vireo.eggShell.findSubValueRef(valueRef, '1,0,0')); + expectValidValueRef(vireo.eggShell.findSubValueRef(valueRef, '1,0,2')); + expectValidValueRef(vireo.eggShell.findSubValueRef(valueRef, '1,1,2')); + }); + }); + + describe('for an array of clusters', function () { + var valueRef, + arrayOfClustersPath = 'dataItem_ArrayOfClusters'; + + beforeAll(function () { + valueRef = vireo.eggShell.findValueRef(viName, arrayOfClustersPath); + }); + + it('throws for invalid path format', function () { + var invalidPathFormat = function () { + vireo.eggShell.findSubValueRef(valueRef, '0,bool'); + }; + + expect(invalidPathFormat).toThrow(); + }); + + it('finds values for indexes followed by "." field name', function () { + expectValidValueRef(vireo.eggShell.findSubValueRef(valueRef, '0.bool')); + expectValidValueRef(vireo.eggShell.findSubValueRef(valueRef, '0.string')); + expectValidValueRef(vireo.eggShell.findSubValueRef(valueRef, '1.double')); + expectValidValueRef(vireo.eggShell.findSubValueRef(valueRef, '1.int32')); + expectValidValueRef(vireo.eggShell.findSubValueRef(valueRef, '2.int64')); + expectValidValueRef(vireo.eggShell.findSubValueRef(valueRef, '2.complex')); + expectValidValueRef(vireo.eggShell.findSubValueRef(valueRef, '2.time')); + }); + }); + + describe('for a cluster of arrays', function () { + var valueRef, + clusterOfArraysPath = 'dataItem_ClusterOfArrays'; + + beforeAll(function () { + valueRef = vireo.eggShell.findValueRef(viName, clusterOfArraysPath); + }); + + it('throws for invalid path format', function () { + var invalidPathFormat = function () { + vireo.eggShell.findSubValueRef(valueRef, 'booleans,0'); + }; + + expect(invalidPathFormat).toThrow(); + }); + + it('throws for index out of bounds', function () { + var indexOutOfBounds = function () { + vireo.eggShell.findSubValueRef(valueRef, 'booleans.3'); + }; + + expect(indexOutOfBounds).toThrow(); + }); + + it('finds values for fields followed by "." index', function () { + expectValidValueRef(vireo.eggShell.findSubValueRef(valueRef, 'booleans.0')); + expectValidValueRef(vireo.eggShell.findSubValueRef(valueRef, 'strings.1')); + expectValidValueRef(vireo.eggShell.findSubValueRef(valueRef, 'doubles.2')); + expectValidValueRef(vireo.eggShell.findSubValueRef(valueRef, 'int32s.3')); + expectValidValueRef(vireo.eggShell.findSubValueRef(valueRef, 'int64s.3')); + expectValidValueRef(vireo.eggShell.findSubValueRef(valueRef, 'complexes.2')); + expectValidValueRef(vireo.eggShell.findSubValueRef(valueRef, 'times.0')); + }); + }); +}); From 3c6658ea401e028d3699a40cc190c9c5b1df8826 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Le=C3=B3n?= Date: Fri, 22 Jun 2018 13:01:22 -0500 Subject: [PATCH 18/67] Moved readDouble function in eggShell Now is next to writeDouble --- source/io/module_eggShell.js | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/source/io/module_eggShell.js b/source/io/module_eggShell.js index 8e105ae6a..607e21ce2 100644 --- a/source/io/module_eggShell.js +++ b/source/io/module_eggShell.js @@ -248,24 +248,6 @@ return subValueRef; }; - Module.eggShell.readDouble = publicAPI.eggShell.readDouble = function (valueRef) { - var stack = Module.stackSave(); - var resultPointer = Module.stackAlloc(DOUBLE_SIZE); - - // TODO mraj should we try to resolve the typeref name on error for more context? - var niError = Module._EggShell_ReadDouble(Module.eggShell.v_userShell, valueRef.typeRef, valueRef.dataRef, resultPointer); - if (niError !== 0) { - throw new Error('Loading VIA failed for the following reason: ' + niErrorEnum[niError] + - ' (error code: ' + niError + ')' + - ' (typeRef: ' + valueRef.typeRef + ')' + - ' (dataRef: ' + valueRef.dataRef + ')'); - } - var result = Module.getValue(resultPointer, 'double'); - - Module.stackRestore(stack); - return result; - }; - Module.eggShell.reflectOnValueRef = publicAPI.eggShell.reflectOnValueRef = function (typeVisitor, valueRef, data) { if (typeof valueRef !== 'object' || valueRef === null) { throw new Error('valueRef must be an object. Found: ' + valueRef); @@ -285,6 +267,24 @@ return dispatchFunction(typeVisitor, valueRef, data); }; + Module.eggShell.readDouble = publicAPI.eggShell.readDouble = function (valueRef) { + var stack = Module.stackSave(); + var resultPointer = Module.stackAlloc(DOUBLE_SIZE); + + // TODO mraj should we try to resolve the typeref name on error for more context? + var niError = Module._EggShell_ReadDouble(Module.eggShell.v_userShell, valueRef.typeRef, valueRef.dataRef, resultPointer); + if (niError !== 0) { + throw new Error('Loading VIA failed for the following reason: ' + niErrorEnum[niError] + + ' (error code: ' + niError + ')' + + ' (typeRef: ' + valueRef.typeRef + ')' + + ' (dataRef: ' + valueRef.dataRef + ')'); + } + var result = Module.getValue(resultPointer, 'double'); + + Module.stackRestore(stack); + return result; + }; + Module.eggShell.writeDouble = publicAPI.eggShell.writeDouble = function (vi, path, value) { EggShell_WriteDouble(Module.eggShell.v_userShell, vi, path, value); }; From 7ec66136452d8dbfd17c178a206c932fe06f3d03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Le=C3=B3n?= Date: Fri, 22 Jun 2018 13:35:58 -0500 Subject: [PATCH 19/67] Added a little more validation to FindSubValue --- source/core/CEntryPoints.cpp | 3 +++ test-it/karma/publicapi/FindSubValueRef.Test.js | 11 +++++++++++ 2 files changed, 14 insertions(+) diff --git a/source/core/CEntryPoints.cpp b/source/core/CEntryPoints.cpp index 994ad0450..a9158dade 100644 --- a/source/core/CEntryPoints.cpp +++ b/source/core/CEntryPoints.cpp @@ -133,6 +133,9 @@ VIREO_EXPORT EggShellResult EggShell_FindValue(TypeManagerRef tm, const char* vi //! Get a reference to the type pointer and data for a sub element VIREO_EXPORT EggShellResult EggShell_FindSubValue(TypeManagerRef tm, TypeRef typeRef, const char* eltName, TypeRef* typeRefLocation, void** dataRefLocation) { + if (typeRef == nullptr || !typeRef->IsValid() || tm != typeRef->TheTypeManager()) + return kEggShellResult_UnexpectedObjectType; + SubString path(eltName); void* pData = typeRef->Begin(kPARead); *typeRefLocation = typeRef->GetSubElementAddressFromPath(&path, pData, dataRefLocation, true); diff --git a/test-it/karma/publicapi/FindSubValueRef.Test.js b/test-it/karma/publicapi/FindSubValueRef.Test.js index e6cfa60f0..531139839 100644 --- a/test-it/karma/publicapi/FindSubValueRef.Test.js +++ b/test-it/karma/publicapi/FindSubValueRef.Test.js @@ -45,6 +45,17 @@ describe('The Vireo EggShell findSubValueRef', function () { expect(invalidValueRef).toThrow(); }); + it('throws for an object with invalid typeRef', function () { + var invalidValueRef = function () { + var invalidTypeRef = { + typeRef: 0 + }; + vireo.eggShell.findSubValueRef(invalidTypeRef, 'dataItem_ClusterOfScalars'); + }; + + expect(invalidValueRef).toThrow(); + }); + it('throws for a nonexistant path', function () { var invalidPath = function () { vireo.eggShell.findSubValueRef(valueRef, 'nonexistantpath'); From 6e61e379d55c723adae31ff942a7a9e2aa73cfb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Le=C3=B3n?= Date: Mon, 25 Jun 2018 11:16:33 -0500 Subject: [PATCH 20/67] Added InvalidTypeRef as an EggShellResult Addressed feedback. --- source/core/CEntryPoints.cpp | 5 +++-- source/include/CEntryPoints.h | 1 + source/io/module_eggShell.js | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/source/core/CEntryPoints.cpp b/source/core/CEntryPoints.cpp index a9158dade..a2553604d 100644 --- a/source/core/CEntryPoints.cpp +++ b/source/core/CEntryPoints.cpp @@ -133,9 +133,10 @@ VIREO_EXPORT EggShellResult EggShell_FindValue(TypeManagerRef tm, const char* vi //! Get a reference to the type pointer and data for a sub element VIREO_EXPORT EggShellResult EggShell_FindSubValue(TypeManagerRef tm, TypeRef typeRef, const char* eltName, TypeRef* typeRefLocation, void** dataRefLocation) { - if (typeRef == nullptr || !typeRef->IsValid() || tm != typeRef->TheTypeManager()) - return kEggShellResult_UnexpectedObjectType; + if (typeRef == nullptr || !typeRef->IsValid()) + return kEggShellResult_InvalidTypeRef; + TypeManagerScope scope(tm); SubString path(eltName); void* pData = typeRef->Begin(kPARead); *typeRefLocation = typeRef->GetSubElementAddressFromPath(&path, pData, dataRefLocation, true); diff --git a/source/include/CEntryPoints.h b/source/include/CEntryPoints.h index 4831a448a..5df88e3f6 100644 --- a/source/include/CEntryPoints.h +++ b/source/include/CEntryPoints.h @@ -21,6 +21,7 @@ typedef enum { kEggShellResult_UnexpectedObjectType = 2, kEggShellResult_InvalidResultPointer = 3, kEggShellResult_UnableToCreateReturnBuffer = 4, + kEggShellResult_InvalidTypeRef = 5, } EggShellResult; //------------------------------------------------------------ //! TypeManager functions diff --git a/source/io/module_eggShell.js b/source/io/module_eggShell.js index 607e21ce2..5339344e1 100644 --- a/source/io/module_eggShell.js +++ b/source/io/module_eggShell.js @@ -87,7 +87,8 @@ 1: 'ObjectNotFoundAtPath', 2: 'UnexpectedObjectType', 3: 'InvalidResultPointer', - 4: 'UnableToCreateReturnBuffer' + 4: 'UnableToCreateReturnBuffer', + 5: 'InvalidTypeRef' }; // Keep in sync with NIError in DataTypes.h From 89b024b37cf60a82816c28fd15d85ecede67e782 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Le=C3=B3n?= Date: Mon, 25 Jun 2018 17:54:23 -0500 Subject: [PATCH 21/67] Changed top-level test description --- test-it/karma/publicapi/DoubleInAggregate.Test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-it/karma/publicapi/DoubleInAggregate.Test.js b/test-it/karma/publicapi/DoubleInAggregate.Test.js index fab3ec040..13112677e 100644 --- a/test-it/karma/publicapi/DoubleInAggregate.Test.js +++ b/test-it/karma/publicapi/DoubleInAggregate.Test.js @@ -1,4 +1,4 @@ -describe('The Vireo EggShell Double api can', function () { +describe('The Vireo EggShell Double and FindSubValueRef api over aggregate types can', function () { 'use strict'; // Reference aliases var Vireo = window.NationalInstruments.Vireo.Vireo; From 285aafaa8fc7b390bc8bc48dab2b5e5afc5c8d1c Mon Sep 17 00:00:00 2001 From: rajsite Date: Wed, 20 Jun 2018 20:17:08 -0500 Subject: [PATCH 22/67] First pass at string read --- make-it/EmMakefile | 6 +++- source/core/CEntryPoints.cpp | 28 ++++++++++++++++ source/include/CEntryPoints.h | 3 ++ source/io/module_eggShell.js | 46 ++++++++++++++++++++++++++ test-it/karma/publicapi/String.Test.js | 34 +++++++++++++++++++ 5 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 test-it/karma/publicapi/String.Test.js diff --git a/make-it/EmMakefile b/make-it/EmMakefile index 56d74505d..59f369410 100644 --- a/make-it/EmMakefile +++ b/make-it/EmMakefile @@ -142,6 +142,9 @@ EM_EXPORTS = -s EXPORTED_FUNCTIONS="[\ '_Data_WriteDouble',\ '_Data_WriteJavaScriptRefNum',\ '_Data_GetArrayMetadata',\ + '_Data_GetArrayBegin',\ + '_Data_GetArrayDimensions',\ + '_Data_GetArrayLength',\ '_Data_GetArrayDimLength',\ '_Data_ResizeArray',\ '_TypeRef_TopAQSize',\ @@ -162,7 +165,8 @@ EM_EXPORTS = -s EXPORTED_FUNCTIONS="[\ '_TypeRef_IsAnalogWaveform',\ '_JavaScriptInvoke_GetParameterType',\ '_JavaScriptInvoke_GetParameterPointer',\ - '_JavaScriptInvoke_GetArrayElementType'\ + '_JavaScriptInvoke_GetArrayElementType',\ + '_TypeRef_Rank'\ ]" EM_RUNTIME_EXPORTS = -s EXTRA_EXPORTED_RUNTIME_METHODS="[\ diff --git a/source/core/CEntryPoints.cpp b/source/core/CEntryPoints.cpp index a2553604d..f34e92377 100644 --- a/source/core/CEntryPoints.cpp +++ b/source/core/CEntryPoints.cpp @@ -352,6 +352,34 @@ VIREO_EXPORT EggShellResult Data_GetArrayMetadata(TypeManagerRef tm, return kEggShellResult_Success; } //------------------------------------------------------------ +//! Get the starting location of the first element of an Array / String type in memory +// This function returns the start address of where elements would appear in memory (returns address even if length zero) +VIREO_EXPORT UInt32 Data_GetArrayBegin(const void* pData) +{ + TypedArrayCoreRef arrayObject = *(TypedArrayCoreRef*)pData; + VIREO_ASSERT(TypedArrayCore::ValidateHandle(arrayObject)); + return (UInt32) arrayObject->BeginAt(0); +} +//------------------------------------------------------------ +//! Get the values for dimensions of the array. Assumes dimensions target is of length equal to rank +VIREO_EXPORT void Data_GetArrayDimensions(const void* pData, IntIndex dimensions[]) +{ + TypedArrayCoreRef arrayObject = *(TypedArrayCoreRef*)pData; + VIREO_ASSERT(TypedArrayCore::ValidateHandle(arrayObject)); + for (int i = 0; i < arrayObject->Rank(); i++) + { + dimensions[i] = arrayObject->GetLength(i); + } +} +//------------------------------------------------------------ +//! Get the total length for an array +VIREO_EXPORT Int32 Data_GetArrayLength(const void* pData) +{ + TypedArrayCoreRef arrayObject = *(TypedArrayCoreRef*)pData; + VIREO_ASSERT(TypedArrayCore::ValidateHandle(arrayObject)); + return arrayObject->Length(); +} +//------------------------------------------------------------ //! Get the Length of a dimension in an Array Symbol. Returns -1 if the Symbol is not found or not //! an Array or dimension requested is out of the bounds of the rank. VIREO_EXPORT Int32 Data_GetArrayDimLength(TypeManagerRef tm, TypedArrayCoreRef arrayObject, Int32 dim) diff --git a/source/include/CEntryPoints.h b/source/include/CEntryPoints.h index 5df88e3f6..a0c477497 100644 --- a/source/include/CEntryPoints.h +++ b/source/include/CEntryPoints.h @@ -54,6 +54,9 @@ VIREO_EXPORT void* Data_GetStringBegin(StringRef stringObject); VIREO_EXPORT Int32 Data_GetStringLength(StringRef stringObject); VIREO_EXPORT EggShellResult Data_GetArrayMetadata(TypeManagerRef tm, TypedArrayCoreRef arrayObject, char** arrayTypeName, Int32* arrayRank, unsigned char** arrayBegin); +VIREO_EXPORT UInt32 Data_GetArrayBegin(const void* pData); +VIREO_EXPORT void Data_GetArrayDimensions(const void* pData, IntIndex dimensions[]); +VIREO_EXPORT Int32 Data_GetArrayLength(const void* pData); VIREO_EXPORT Int32 Data_GetArrayDimLength(TypeManagerRef tm, TypedArrayCoreRef arrayObject, Int32 dim); VIREO_EXPORT Int32 Data_ResizeArray(TypeManagerRef tm, TypedArrayCoreRef arrayObject, Int32 rank, Int32* newLengths); VIREO_EXPORT void Data_WriteString(TypeManagerRef tm, StringRef stringObject, const unsigned char* buffer, diff --git a/source/io/module_eggShell.js b/source/io/module_eggShell.js index 5339344e1..26bb30f1b 100644 --- a/source/io/module_eggShell.js +++ b/source/io/module_eggShell.js @@ -80,6 +80,7 @@ var NULL = 0; var POINTER_SIZE = 4; var DOUBLE_SIZE = 8; + var LENGTH_SIZE = 4; // Keep in sync with EggShellResult in CEntryPoints.h var eggShellResultEnum = { @@ -345,6 +346,51 @@ } }; + Module.eggShell.getArrayDimensions = publicAPI.eggShell.getArrayDimensions = function (valueRef) { + var rank = Module.eggShell.typeRank(valueRef.typeRef); + + var stack = Module.stackSave(); + var dimensionsPointer = Module.stackAlloc(rank * LENGTH_SIZE); + Module._Data_GetArrayDimensions(valueRef.dataRef, dimensionsPointer); + var dimensions = []; + var i; + for (i = 0; i < rank; i += 1) { + dimensions.push(Module.getValue(dimensionsPointer + (i * LENGTH_SIZE), 'i32')); + } + Module.stackRestore(stack); + + return dimensions; + }; + + Module.eggShell.dataGetArrayBegin = function (dataRef) { + return Module._Data_GetArrayBegin(dataRef); + }; + + Module.eggShell.typeRank = function (typeRef) { + return Module._TypeRef_Rank(typeRef); + }; + + Module.eggShell.dataGetArrayLength = function (dataRef) { + return Module._Data_GetArrayLength(dataRef); + }; + + Module.eggShell.readString = publicAPI.eggShell.readString = function (valueRef) { + var arrayBegin = Module.eggShell.dataGetArrayBegin(valueRef.dataRef); + var totalLength = Module.eggShell.dataGetArrayLength(valueRef.dataRef); + var result = Module.coreHelpers.sizedUtf8ArrayToJSString(Module.HEAPU8, arrayBegin, totalLength); + return result; + }; + + Module.eggShell.readTypedArray = publicAPI.eggShell.readTypedArray = function (valueRef) { + // TODO use the type functions to determine the supportedArrayTypeConfig to use + var TypedArrayConstructor = Uint8Array; + + var arrayBegin = Module.eggShell.dataGetArrayBegin(valueRef.dataRef); + var totalLength = Module.eggShell.dataGetArrayLength(valueRef.dataRef); + var typedArray = new TypedArrayConstructor(Module.buffer, arrayBegin, totalLength * TypedArrayConstructor.BYTES_PER_ELEMENT); + return typedArray; + }; + var groupByDimensionLength = function (arr, startIndex, arrLength, dimensionLength) { var i, retArr, currArr, currArrIndex; diff --git a/test-it/karma/publicapi/String.Test.js b/test-it/karma/publicapi/String.Test.js new file mode 100644 index 000000000..db2a41cb7 --- /dev/null +++ b/test-it/karma/publicapi/String.Test.js @@ -0,0 +1,34 @@ +describe('The Vireo EggShell String api can', function () { + 'use strict'; + // Reference aliases + var Vireo = window.NationalInstruments.Vireo.Vireo; + var vireoRunner = window.testHelpers.vireoRunner; + var fixtures = window.testHelpers.fixtures; + + var vireo = new Vireo(); + + var publicApiMultipleTypesViaUrl = fixtures.convertToAbsoluteFromFixturesDir('publicapi/MultipleTypes.via'); + var viName = 'MyVI'; + + var readString = function (path) { + return vireo.eggShell.readString(vireo.eggShell.findValueRef(viName, path)); + }; + + beforeAll(function (done) { + fixtures.preloadAbsoluteUrls([ + publicApiMultipleTypesViaUrl + ], done); + }); + + beforeAll(function () { + vireoRunner.rebootAndLoadVia(vireo, publicApiMultipleTypesViaUrl); + }); + + describe('use readString', function () { + fit('to read different string values from memory', function () { + var valueRef = vireo.eggShell.findValueRef(viName, 'dataItem_String'); + vireo.eggShell.readString(valueRef); + expect(readString('dataItem_String')).toBe('Hello'); + }); + }); +}); From c95bfdd0d8a5d2bfe550f371077073fb0c7c154b Mon Sep 17 00:00:00 2001 From: rajsite Date: Wed, 20 Jun 2018 20:18:03 -0500 Subject: [PATCH 23/67] Enable all tests --- test-it/karma/publicapi/String.Test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-it/karma/publicapi/String.Test.js b/test-it/karma/publicapi/String.Test.js index db2a41cb7..94dbf74c2 100644 --- a/test-it/karma/publicapi/String.Test.js +++ b/test-it/karma/publicapi/String.Test.js @@ -25,7 +25,7 @@ describe('The Vireo EggShell String api can', function () { }); describe('use readString', function () { - fit('to read different string values from memory', function () { + it('to read different string values from memory', function () { var valueRef = vireo.eggShell.findValueRef(viName, 'dataItem_String'); vireo.eggShell.readString(valueRef); expect(readString('dataItem_String')).toBe('Hello'); From 357a75847ec78222fed672332111f706b0996ab9 Mon Sep 17 00:00:00 2001 From: rajsite Date: Thu, 21 Jun 2018 16:54:33 -0500 Subject: [PATCH 24/67] Move type functions to new module --- source/core/module_typeHelpers.js | 4 ++++ source/io/module_eggShell.js | 12 ++---------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/source/core/module_typeHelpers.js b/source/core/module_typeHelpers.js index d102e5fb3..885e1fc20 100644 --- a/source/core/module_typeHelpers.js +++ b/source/core/module_typeHelpers.js @@ -185,6 +185,10 @@ return TypeRef_Name(Module.eggShell.v_userShell, typeRef); }; + Module.typeHelpers.typeRank = function (typeRef) { + return Module._TypeRef_Rank(typeRef); + }; + Module.typeHelpers.subElementCount = function (typeRef) { return Module._TypeRef_SubElementCount(typeRef); }; diff --git a/source/io/module_eggShell.js b/source/io/module_eggShell.js index 26bb30f1b..11f87e814 100644 --- a/source/io/module_eggShell.js +++ b/source/io/module_eggShell.js @@ -66,11 +66,7 @@ 'EggShell_REPL', 'EggShell_ExecuteSlices', 'Occurrence_Set', - 'Pointer_stringify', - 'TypeRef_TopAQSize', - 'TypeRef_Name', - 'TypeRef_SubElementCount', - 'TypeRef_GetSubElementByIndex', + 'Pointer_stringify' ]}], */ Module.eggShell = {}; @@ -347,7 +343,7 @@ }; Module.eggShell.getArrayDimensions = publicAPI.eggShell.getArrayDimensions = function (valueRef) { - var rank = Module.eggShell.typeRank(valueRef.typeRef); + var rank = Module.typeHelpers.typeRank(valueRef.typeRef); var stack = Module.stackSave(); var dimensionsPointer = Module.stackAlloc(rank * LENGTH_SIZE); @@ -366,10 +362,6 @@ return Module._Data_GetArrayBegin(dataRef); }; - Module.eggShell.typeRank = function (typeRef) { - return Module._TypeRef_Rank(typeRef); - }; - Module.eggShell.dataGetArrayLength = function (dataRef) { return Module._Data_GetArrayLength(dataRef); }; From 997876924c255f72a18f2fca5953670d15c97b2c Mon Sep 17 00:00:00 2001 From: rajsite Date: Thu, 21 Jun 2018 20:42:30 -0500 Subject: [PATCH 25/67] Expand types for readTypedArray --- source/io/module_eggShell.js | 58 ++++++++++++- test-it/karma/publicapi/TypedArray.Test.js | 96 ++++++++++++++++++++++ 2 files changed, 150 insertions(+), 4 deletions(-) create mode 100644 test-it/karma/publicapi/TypedArray.Test.js diff --git a/source/io/module_eggShell.js b/source/io/module_eggShell.js index 11f87e814..cf226f6ae 100644 --- a/source/io/module_eggShell.js +++ b/source/io/module_eggShell.js @@ -373,13 +373,63 @@ return result; }; - Module.eggShell.readTypedArray = publicAPI.eggShell.readTypedArray = function (valueRef) { - // TODO use the type functions to determine the supportedArrayTypeConfig to use - var TypedArrayConstructor = Uint8Array; + var findCompatibleTypedArrayConstructor = function (typeRef) { + var subTypeRef, isSigned, size; + // String will go down the Array code path a bit as is so check before array checks + if (Module.typeHelpers.isString(typeRef)) { + return Uint8Array; // exposes UTF-8 encoded array to client + } else if (Module.typeHelpers.isArray(typeRef)) { + subTypeRef = Module.typeHelpers.subElementByIndex(typeRef, 0); + if (Module.typeHelpers.isInteger(subTypeRef)) { + isSigned = Module.typeHelpers.isSigned(subTypeRef); + size = Module.typeHelpers.topAQSize(subTypeRef); + if (isSigned === true) { + switch (size) { + case 1: + return Int8Array; + case 2: + return Int16Array; + case 4: + return Int32Array; + default: + return undefined; + } + } else { + switch (size) { + case 1: + return Uint8Array; + case 2: + return Uint16Array; + case 4: + return Uint32Array; + default: + return undefined; + } + } + } else if (Module.typeHelpers.isFloat(subTypeRef)) { + size = Module.typeHelpers.topAQSize(subTypeRef); + switch (size) { + case 4: + return Float32Array; + case 8: + return Float64Array; + default: + return undefined; + } + } + } + return undefined; + }; + Module.eggShell.isTypedArrayCompatible = publicAPI.eggShell.isTypedArrayCompatible = function (valueRef) { + return findCompatibleTypedArrayConstructor(valueRef.typeRef) !== undefined; + }; + + Module.eggShell.readTypedArray = publicAPI.eggShell.readTypedArray = function (valueRef) { + var TypedArrayConstructor = findCompatibleTypedArrayConstructor(valueRef.typeRef); var arrayBegin = Module.eggShell.dataGetArrayBegin(valueRef.dataRef); var totalLength = Module.eggShell.dataGetArrayLength(valueRef.dataRef); - var typedArray = new TypedArrayConstructor(Module.buffer, arrayBegin, totalLength * TypedArrayConstructor.BYTES_PER_ELEMENT); + var typedArray = new TypedArrayConstructor(Module.buffer, arrayBegin, totalLength); return typedArray; }; diff --git a/test-it/karma/publicapi/TypedArray.Test.js b/test-it/karma/publicapi/TypedArray.Test.js new file mode 100644 index 000000000..6fdc07244 --- /dev/null +++ b/test-it/karma/publicapi/TypedArray.Test.js @@ -0,0 +1,96 @@ +describe('The Vireo EggShell Typed Array api', function () { + 'use strict'; + // Reference aliases + var Vireo = window.NationalInstruments.Vireo.Vireo; + var vireoRunner = window.testHelpers.vireoRunner; + var fixtures = window.testHelpers.fixtures; + + var vireo; + + var publicApiArrayTypesOptimizedViaUrl = fixtures.convertToAbsoluteFromFixturesDir('publicapi/ArrayTypesOptimized.via'); + + beforeAll(function (done) { + fixtures.preloadAbsoluteUrls([ + publicApiArrayTypesOptimizedViaUrl + ], done); + }); + + beforeEach(function () { + vireo = new Vireo(); + }); + + it('can read arrays for specific optimized types', function (done) { + var viName = 'ArrayTypesOptimized'; + + var readTypedArray = function (path) { + var valueRef = vireo.eggShell.findValueRef(viName, path); + var typedArray = vireo.eggShell.readTypedArray(valueRef); + return typedArray; + }; + + var runSlicesAsync = vireoRunner.rebootAndLoadVia(vireo, publicApiArrayTypesOptimizedViaUrl); + + runSlicesAsync(function (rawPrint, rawPrintError) { + expect(rawPrint).toBeEmptyString(); + expect(rawPrintError).toBeEmptyString(); + + expect(readTypedArray('arrayInt8') instanceof Int8Array).toBeTrue(); + expect(readTypedArray('arrayInt8')).toEqual(new Int8Array([8, 6, 7, 5, 3, 0, 9, 0, -128, 127])); + expect(readTypedArray('arrayInt16') instanceof Int16Array).toBeTrue(); + expect(readTypedArray('arrayInt16')).toEqual(new Int16Array([8, 6, 7, 5, 3, 0, 9, 0, -32768, 32767])); + expect(readTypedArray('arrayInt32') instanceof Int32Array).toBeTrue(); + expect(readTypedArray('arrayInt32')).toEqual(new Int32Array([8, 6, 7, 5, 3, 0, 9, 0, -2147483648, 2147483647])); + expect(readTypedArray('arrayUInt8') instanceof Uint8Array).toBeTrue(); + expect(readTypedArray('arrayUInt8')).toEqual(new Uint8Array([8, 6, 7, 5, 3, 0, 9, 0, 255])); + expect(readTypedArray('arrayUInt16') instanceof Uint16Array).toBeTrue(); + expect(readTypedArray('arrayUInt16')).toEqual(new Uint16Array([8, 6, 7, 5, 3, 0, 9, 0, 65535])); + expect(readTypedArray('arrayUInt32') instanceof Uint32Array).toBeTrue(); + expect(readTypedArray('arrayUInt32')).toEqual(new Uint32Array([8, 6, 7, 5, 3, 0, 9, 0, 4294967295])); + expect(readTypedArray('arraySingle') instanceof Float32Array).toBeTrue(); + expect(readTypedArray('arraySingle')).toEqual(new Float32Array([Math.fround(1.1), Math.fround(2.2), +0, -0, Infinity, NaN, -Infinity, -16777216, 16777216])); + expect(readTypedArray('arrayDouble') instanceof Float64Array).toBeTrue(); + expect(readTypedArray('arrayDouble')).toEqual(new Float64Array([1.1, 2.2, +0, -0, Infinity, NaN, -Infinity, -9007199254740992, 9007199254740992])); + expect(readTypedArray('array2DInt32') instanceof Int32Array).toBeTrue(); + expect(readTypedArray('array2DInt32')).toEqual(new Int32Array([1, 2, 3, 4, 5, 6, 7, 8, 9])); + expect(readTypedArray('array3DInt32') instanceof Int32Array).toBeTrue(); + expect(readTypedArray('array3DInt32')).toEqual(new Int32Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18])); + expect(readTypedArray('arrayInt8Empty') instanceof Int8Array).toBeTrue(); + expect(readTypedArray('arrayInt8Empty')).toEqual(new Int8Array([])); + expect(readTypedArray('array2DInt8Empty') instanceof Int8Array).toBeTrue(); + expect(readTypedArray('array2DInt8Empty')).toEqual(new Int8Array([])); + expect(readTypedArray('array3DInt8Empty') instanceof Int8Array).toBeTrue(); + expect(readTypedArray('array3DInt8Empty')).toEqual(new Int8Array([])); + + done(); + }); + }); + + // it('errors with unsupported types', function (done) { + // var viName = 'ArrayTypesOptimized'; + + // var runSlicesAsync = vireoRunner.rebootAndLoadVia(vireo, publicApiArrayTypesOptimizedViaUrl); + + // runSlicesAsync(function (rawPrint, rawPrintError) { + // expect(rawPrint).toBeEmptyString(); + // expect(rawPrintError).toBeEmptyString(); + + // expect(function () { + // vireo.eggShell.getNumericArray(viName, 'arrayString'); + // }).toThrowError(/Unsupported type/); + + // expect(function () { + // vireo.eggShell.getNumericArray(viName, 'arrayBoolean'); + // }).toThrowError(/Unsupported type/); + + // expect(function () { + // vireo.eggShell.getNumericArray(viName, 'nonExistantPath'); + // }).toThrowError(/ObjectNotFoundAtPath/); + + // expect(function () { + // vireo.eggShell.getNumericArray(viName, 'scalarNumber'); + // }).toThrowError(/UnexpectedObjectType/); + + // done(); + // }); + // }); +}); From a5003836bfb79aac65c96474763750b2ba56da70 Mon Sep 17 00:00:00 2001 From: rajsite Date: Thu, 21 Jun 2018 20:44:56 -0500 Subject: [PATCH 26/67] Fix cpplint error --- source/core/CEntryPoints.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/core/CEntryPoints.cpp b/source/core/CEntryPoints.cpp index f34e92377..09643bc45 100644 --- a/source/core/CEntryPoints.cpp +++ b/source/core/CEntryPoints.cpp @@ -366,8 +366,7 @@ VIREO_EXPORT void Data_GetArrayDimensions(const void* pData, IntIndex dimensions { TypedArrayCoreRef arrayObject = *(TypedArrayCoreRef*)pData; VIREO_ASSERT(TypedArrayCore::ValidateHandle(arrayObject)); - for (int i = 0; i < arrayObject->Rank(); i++) - { + for (int i = 0; i < arrayObject->Rank(); i++) { dimensions[i] = arrayObject->GetLength(i); } } From deefc471704a8f559436d2921b4ff2307b47f42a Mon Sep 17 00:00:00 2001 From: rajsite Date: Fri, 22 Jun 2018 10:56:01 -0500 Subject: [PATCH 27/67] Change Data_GetArrayBegin to return pointer Was casting pointer to Int32 to emphasize 32-bit JS API behavior, but as 64-bit builds of Vireo and C API usage are possible changed to void* as return type. --- source/core/CEntryPoints.cpp | 4 ++-- source/include/CEntryPoints.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/core/CEntryPoints.cpp b/source/core/CEntryPoints.cpp index 09643bc45..e19b5ef08 100644 --- a/source/core/CEntryPoints.cpp +++ b/source/core/CEntryPoints.cpp @@ -354,11 +354,11 @@ VIREO_EXPORT EggShellResult Data_GetArrayMetadata(TypeManagerRef tm, //------------------------------------------------------------ //! Get the starting location of the first element of an Array / String type in memory // This function returns the start address of where elements would appear in memory (returns address even if length zero) -VIREO_EXPORT UInt32 Data_GetArrayBegin(const void* pData) +VIREO_EXPORT void* Data_GetArrayBegin(const void* pData) { TypedArrayCoreRef arrayObject = *(TypedArrayCoreRef*)pData; VIREO_ASSERT(TypedArrayCore::ValidateHandle(arrayObject)); - return (UInt32) arrayObject->BeginAt(0); + return arrayObject->BeginAt(0); } //------------------------------------------------------------ //! Get the values for dimensions of the array. Assumes dimensions target is of length equal to rank diff --git a/source/include/CEntryPoints.h b/source/include/CEntryPoints.h index a0c477497..3fc36b48b 100644 --- a/source/include/CEntryPoints.h +++ b/source/include/CEntryPoints.h @@ -54,7 +54,7 @@ VIREO_EXPORT void* Data_GetStringBegin(StringRef stringObject); VIREO_EXPORT Int32 Data_GetStringLength(StringRef stringObject); VIREO_EXPORT EggShellResult Data_GetArrayMetadata(TypeManagerRef tm, TypedArrayCoreRef arrayObject, char** arrayTypeName, Int32* arrayRank, unsigned char** arrayBegin); -VIREO_EXPORT UInt32 Data_GetArrayBegin(const void* pData); +VIREO_EXPORT void* Data_GetArrayBegin(const void* pData); VIREO_EXPORT void Data_GetArrayDimensions(const void* pData, IntIndex dimensions[]); VIREO_EXPORT Int32 Data_GetArrayLength(const void* pData); VIREO_EXPORT Int32 Data_GetArrayDimLength(TypeManagerRef tm, TypedArrayCoreRef arrayObject, Int32 dim); From 3b526c1e1e85acc24aab0252f7eeadaedd72706b Mon Sep 17 00:00:00 2001 From: rajsite Date: Fri, 22 Jun 2018 19:18:41 -0500 Subject: [PATCH 28/67] Add boolean array support for readTypedArray --- source/io/module_eggShell.js | 35 +++++++--- .../publicapi/ArrayTypesOptimized.via | 20 ++++-- test-it/karma/publicapi/TypedArray.Test.js | 68 ++++++++++--------- 3 files changed, 77 insertions(+), 46 deletions(-) diff --git a/source/io/module_eggShell.js b/source/io/module_eggShell.js index cf226f6ae..a7b482ab4 100644 --- a/source/io/module_eggShell.js +++ b/source/io/module_eggShell.js @@ -79,14 +79,21 @@ var LENGTH_SIZE = 4; // Keep in sync with EggShellResult in CEntryPoints.h - var eggShellResultEnum = { - 0: 'Success', - 1: 'ObjectNotFoundAtPath', - 2: 'UnexpectedObjectType', - 3: 'InvalidResultPointer', - 4: 'UnableToCreateReturnBuffer', - 5: 'InvalidTypeRef' - }; + var EGGSHELL_RESULT = { + SUCCESS: 0, + OBJECT_NOT_FOUND_AT_PATH: 1, + UNEXPECTED_OBJECT_TYPE: 2, + INVALID_RESULT_POINTER: 3, + UNABLE_TO_CREATE_RETURN_BUFFER: 4, + INVALID_TYPE_REF: 5 + }; + var eggShellResultEnum = {}; + eggShellResultEnum[EGGSHELL_RESULT.SUCCESS] = 'Success'; + eggShellResultEnum[EGGSHELL_RESULT.OBJECT_NOT_FOUND_AT_PATH] = 'ObjectNotFoundAtPath'; + eggShellResultEnum[EGGSHELL_RESULT.UNEXPECTED_OBJECT_TYPE] = 'UnexpectedObjectType'; + eggShellResultEnum[EGGSHELL_RESULT.INVALID_RESULT_POINTER] = 'InvalidResultPointer'; + eggShellResultEnum[EGGSHELL_RESULT.UNABLE_TO_CREATE_RETURN_BUFFER] = 'UnableToCreateReturnBuffer'; + eggShellResultEnum[EGGSHELL_RESULT.INVALID_TYPE_REF] = 'InvalidTypeRef'; // Keep in sync with NIError in DataTypes.h var niErrorEnum = { @@ -272,7 +279,7 @@ // TODO mraj should we try to resolve the typeref name on error for more context? var niError = Module._EggShell_ReadDouble(Module.eggShell.v_userShell, valueRef.typeRef, valueRef.dataRef, resultPointer); if (niError !== 0) { - throw new Error('Loading VIA failed for the following reason: ' + niErrorEnum[niError] + + throw new Error('Performing readDouble failed for the following reason: ' + niErrorEnum[niError] + ' (error code: ' + niError + ')' + ' (typeRef: ' + valueRef.typeRef + ')' + ' (dataRef: ' + valueRef.dataRef + ')'); @@ -380,7 +387,9 @@ return Uint8Array; // exposes UTF-8 encoded array to client } else if (Module.typeHelpers.isArray(typeRef)) { subTypeRef = Module.typeHelpers.subElementByIndex(typeRef, 0); - if (Module.typeHelpers.isInteger(subTypeRef)) { + if (Module.typeHelpers.isBoolean(subTypeRef)) { + return Uint8Array; + } else if (Module.typeHelpers.isInteger(subTypeRef)) { // Used for Enums and Integers isSigned = Module.typeHelpers.isSigned(subTypeRef); size = Module.typeHelpers.topAQSize(subTypeRef); if (isSigned === true) { @@ -427,6 +436,12 @@ Module.eggShell.readTypedArray = publicAPI.eggShell.readTypedArray = function (valueRef) { var TypedArrayConstructor = findCompatibleTypedArrayConstructor(valueRef.typeRef); + if (TypedArrayConstructor === undefined) { + throw new Error('Performing readTypedArray failed for the following reason: ' + eggShellResultEnum[EGGSHELL_RESULT.UNEXPECTED_OBJECT_TYPE] + + ' (error code: ' + EGGSHELL_RESULT.UNEXPECTED_OBJECT_TYPE + ')' + + ' (typeRef: ' + valueRef.typeRef + ')' + + ' (dataRef: ' + valueRef.dataRef + ')'); + } var arrayBegin = Module.eggShell.dataGetArrayBegin(valueRef.dataRef); var totalLength = Module.eggShell.dataGetArrayLength(valueRef.dataRef); var typedArray = new TypedArrayConstructor(Module.buffer, arrayBegin, totalLength); diff --git a/test-it/karma/fixtures/publicapi/ArrayTypesOptimized.via b/test-it/karma/fixtures/publicapi/ArrayTypesOptimized.via index 397d1458e..f73b6dfa9 100644 --- a/test-it/karma/fixtures/publicapi/ArrayTypesOptimized.via +++ b/test-it/karma/fixtures/publicapi/ArrayTypesOptimized.via @@ -1,5 +1,13 @@ define(ArrayTypesOptimized dv(.VirtualInstrument ( - c( + c( + // Supported non-array types + e(dv(.String 'Hello')stringHello) + e(dv(.String '\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u0009\u000A\u000B\u000C\u000D\u000E\u000F\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001A\u001B\u001C\u001D\u001E\u001F') stringControlCharacters) + + // Unsupported non-array types + e(dv(.UInt32 10) scalarUInt32) + + // Supported array types e(dv(a(.Int8 *) (8 6 7 5 3 0 9 0 -128 127)) arrayInt8) e(dv(a(.Int16 *) (8 6 7 5 3 0 9 0 -32768 32767)) arrayInt16) e(dv(a(.Int32 *) (8 6 7 5 3 0 9 0 -2147483648 2147483647)) arrayInt32) @@ -10,12 +18,16 @@ define(ArrayTypesOptimized dv(.VirtualInstrument ( e(dv(a(.Double *) (1.1 2.2 0 -0 inf nan -inf -9007199254740992 9007199254740992)) arrayDouble) e(dv(a(.Int32 * *) ((1 2 3 )(4 5 6 )(7 8 9 ))) array2DInt32) e(dv(a(.Int32 * * *) (((1 2 3 )(4 5 6 )(7 8 9 ))((10 11 12 )(13 14 15 )(16 17 18 )))) array3DInt32) - e(dv(a(.String *) ('aaa' 'bbb' 'ccc')) arrayString) - e(dv(a(.Boolean *) (true false true false)) arrayBoolean) - e(dv(.UInt32 10) scalarNumber) e(dv(a(.Int8 *) ()) arrayInt8Empty) e(dv(a(.Int8 * *) ()) array2DInt8Empty) e(dv(a(.Int8 * * *) ()) array3DInt8Empty) + e(dv(a(Enum8(a b c d e f g h) *) (3 2 1))arrayEnum8) + e(dv(a(Enum16(zero one two three four) *) (3 2 1)) arrayEnum16) + e(dv(a(Enum32(red orange yellow green blue purple) *) (3 2 1)) arrayEnum32) + e(dv(a(.Boolean *) (true false true false)) arrayBoolean) + + // Unsupported array types + e(dv(a(.String *) ('aaa' 'bbb' 'ccc')) arrayString) ) clump( ) diff --git a/test-it/karma/publicapi/TypedArray.Test.js b/test-it/karma/publicapi/TypedArray.Test.js index 6fdc07244..5d5ff0fbf 100644 --- a/test-it/karma/publicapi/TypedArray.Test.js +++ b/test-it/karma/publicapi/TypedArray.Test.js @@ -19,15 +19,14 @@ describe('The Vireo EggShell Typed Array api', function () { vireo = new Vireo(); }); - it('can read arrays for specific optimized types', function (done) { - var viName = 'ArrayTypesOptimized'; - - var readTypedArray = function (path) { - var valueRef = vireo.eggShell.findValueRef(viName, path); - var typedArray = vireo.eggShell.readTypedArray(valueRef); - return typedArray; - }; + var viName = 'ArrayTypesOptimized'; + var readTypedArray = function (path) { + var valueRef = vireo.eggShell.findValueRef(viName, path); + var typedArray = vireo.eggShell.readTypedArray(valueRef); + return typedArray; + }; + it('can read arrays for specific optimized types', function (done) { var runSlicesAsync = vireoRunner.rebootAndLoadVia(vireo, publicApiArrayTypesOptimizedViaUrl); runSlicesAsync(function (rawPrint, rawPrintError) { @@ -60,37 +59,42 @@ describe('The Vireo EggShell Typed Array api', function () { expect(readTypedArray('array2DInt8Empty')).toEqual(new Int8Array([])); expect(readTypedArray('array3DInt8Empty') instanceof Int8Array).toBeTrue(); expect(readTypedArray('array3DInt8Empty')).toEqual(new Int8Array([])); - + expect(readTypedArray('arrayEnum8') instanceof Uint8Array).toBeTrue(); + expect(readTypedArray('arrayEnum8')).toEqual(new Uint8Array([3, 2, 1])); + expect(readTypedArray('arrayEnum16') instanceof Uint16Array).toBeTrue(); + expect(readTypedArray('arrayEnum16')).toEqual(new Uint16Array([3, 2, 1])); + expect(readTypedArray('arrayEnum32') instanceof Uint32Array).toBeTrue(); + expect(readTypedArray('arrayEnum32')).toEqual(new Uint32Array([3, 2, 1])); + expect(readTypedArray('arrayBoolean') instanceof Uint8Array).toBeTrue(); + expect(readTypedArray('arrayBoolean')).toEqual(new Uint8Array([1, 0, 1, 0])); + expect(readTypedArray('stringHello') instanceof Uint8Array).toBeTrue(); + expect(readTypedArray('stringHello')).toEqual(new Uint8Array([0x48, 0x65, 0x6C, 0x6C, 0x6F])); + expect(readTypedArray('stringControlCharacters') instanceof Uint8Array).toBeTrue(); + expect(readTypedArray('stringControlCharacters')).toEqual(new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31])); done(); }); }); - // it('errors with unsupported types', function (done) { - // var viName = 'ArrayTypesOptimized'; - - // var runSlicesAsync = vireoRunner.rebootAndLoadVia(vireo, publicApiArrayTypesOptimizedViaUrl); - - // runSlicesAsync(function (rawPrint, rawPrintError) { - // expect(rawPrint).toBeEmptyString(); - // expect(rawPrintError).toBeEmptyString(); + it('errors with unsupported types', function (done) { + var runSlicesAsync = vireoRunner.rebootAndLoadVia(vireo, publicApiArrayTypesOptimizedViaUrl); - // expect(function () { - // vireo.eggShell.getNumericArray(viName, 'arrayString'); - // }).toThrowError(/Unsupported type/); + runSlicesAsync(function (rawPrint, rawPrintError) { + expect(rawPrint).toBeEmptyString(); + expect(rawPrintError).toBeEmptyString(); - // expect(function () { - // vireo.eggShell.getNumericArray(viName, 'arrayBoolean'); - // }).toThrowError(/Unsupported type/); + expect(function () { + readTypedArray('arrayString'); + }).toThrowError(/UnexpectedObjectType/); - // expect(function () { - // vireo.eggShell.getNumericArray(viName, 'nonExistantPath'); - // }).toThrowError(/ObjectNotFoundAtPath/); + expect(function () { + readTypedArray('nonExistantPath'); + }).toThrowError(/ObjectNotFoundAtPath/); - // expect(function () { - // vireo.eggShell.getNumericArray(viName, 'scalarNumber'); - // }).toThrowError(/UnexpectedObjectType/); + expect(function () { + readTypedArray('scalarUInt32'); + }).toThrowError(/UnexpectedObjectType/); - // done(); - // }); - // }); + done(); + }); + }); }); From 8c3eee6b551bf6b2b3bcfa6a084b995209e66ded Mon Sep 17 00:00:00 2001 From: rajsite Date: Fri, 22 Jun 2018 19:50:17 -0500 Subject: [PATCH 29/67] Fix GetNumericArray test for new variable name --- test-it/karma/publicapi/GetNumericArray.Test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-it/karma/publicapi/GetNumericArray.Test.js b/test-it/karma/publicapi/GetNumericArray.Test.js index 5f7584e3a..2e96858e8 100644 --- a/test-it/karma/publicapi/GetNumericArray.Test.js +++ b/test-it/karma/publicapi/GetNumericArray.Test.js @@ -68,7 +68,7 @@ describe('The Vireo EggShell getNumericArray api', function () { }).toThrowError(/ObjectNotFoundAtPath/); expect(function () { - vireo.eggShell.getNumericArray(viName, 'scalarNumber'); + vireo.eggShell.getNumericArray(viName, 'scalarUInt32'); }).toThrowError(/UnexpectedObjectType/); done(); From e200e3e550df7bd7cd0c324ebb79191473002973 Mon Sep 17 00:00:00 2001 From: rajsite Date: Fri, 22 Jun 2018 20:15:10 -0500 Subject: [PATCH 30/67] Use readTypedArray for HttpPost buffer --- source/io/HttpClient.cpp | 11 ++++++++--- source/io/module_httpClient.js | 9 +++++---- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/source/io/HttpClient.cpp b/source/io/HttpClient.cpp index 94d73a685..0a344afbe 100644 --- a/source/io/HttpClient.cpp +++ b/source/io/HttpClient.cpp @@ -37,7 +37,7 @@ extern "C" { extern void jsHttpClientGetHeader(UInt32, StringRef, StringRef, Boolean *, Int32 *, StringRef); extern void jsHttpClientHeaderExists(UInt32, StringRef, UInt32 *, StringRef, Boolean *, Int32 *, StringRef); extern void jsHttpClientListHeaders(UInt32, StringRef, Boolean *, Int32 *, StringRef); - extern void jsHttpClientMethod(HttpClientMethodId, UInt32, StringRef, StringRef, StringRef, + extern void jsHttpClientMethod(HttpClientMethodId, UInt32, StringRef, StringRef, TypeRef, StringRef*, Int32 *, StringRef, StringRef, UInt32 *, Boolean *, Int32 *, StringRef, OccurrenceRef); extern void jsHttpClientConfigCORS(UInt32, UInt32, Boolean *, Int32 *, StringRef); } @@ -293,6 +293,7 @@ VIREO_FUNCTION_SIGNATURE9(HttpClientGet, UInt32, StringRef, StringRef, Int32, St _Param(1), _Param(2), nullptr, + nullptr, _ParamPointer(3), _Param(4), _Param(5), @@ -344,6 +345,7 @@ VIREO_FUNCTION_SIGNATURE7(HttpClientHead, UInt32, StringRef, Int32, StringRef, U _Param(1), nullptr, nullptr, + nullptr, _ParamPointer(2), _Param(3), nullptr, @@ -395,7 +397,8 @@ VIREO_FUNCTION_SIGNATURE10(HttpClientPut, UInt32, StringRef, StringRef, StringRe _Param(0), _Param(1), _Param(2), - _Param(3), + _Param(3)->Type(), + _ParamPointer(3), _ParamPointer(4), _Param(5), _Param(6), @@ -448,6 +451,7 @@ VIREO_FUNCTION_SIGNATURE9(HttpClientDelete, UInt32, StringRef, StringRef, Int32, _Param(1), _Param(2), nullptr, + nullptr, _ParamPointer(3), _Param(4), _Param(5), @@ -499,7 +503,8 @@ VIREO_FUNCTION_SIGNATURE10(HttpClientPost, UInt32, StringRef, StringRef, StringR _Param(0), _Param(1), _Param(2), - _Param(3), + _Param(3)->Type(), + _ParamPointer(3), _ParamPointer(4), _Param(5), _Param(6), diff --git a/source/io/module_httpClient.js b/source/io/module_httpClient.js index 02b9e4520..8b4fe2ee4 100644 --- a/source/io/module_httpClient.js +++ b/source/io/module_httpClient.js @@ -677,7 +677,7 @@ Module.eggShell.dataWriteString(listPointer, list); }; - Module.httpClient.jsHttpClientMethod = function (methodId, handle, urlPointer, outputFilePointer, bufferPointer, timeoutPointer, headersPointer, bodyPointer, statusCodePointer, errorStatusPointer, errorCodePointer, errorSourcePointer, occurrencePointer) { + Module.httpClient.jsHttpClientMethod = function (methodId, handle, urlPointer, outputFilePointer, bufferTypeRef, bufferDataRef, timeoutPointer, headersPointer, bodyPointer, statusCodePointer, errorStatusPointer, errorCodePointer, errorSourcePointer, occurrencePointer) { var setDefaultOutputs = function () { Module.eggShell.dataWriteString(headersPointer, ''); Module.eggShell.dataWriteUInt32(statusCodePointer, 0); @@ -707,9 +707,10 @@ } } - var buffer, typedArrayBuffer; - if (bufferPointer !== NULL) { - typedArrayBuffer = Module.eggShell.dataReadStringAsArray_NoCopy(bufferPointer); + var valueRef, buffer, typedArrayBuffer; + if (bufferDataRef !== NULL) { + valueRef = Module.eggShell.createValueRef(bufferTypeRef, bufferDataRef); + typedArrayBuffer = Module.eggShell.readTypedArray(valueRef); // Blob API does not exist in node.js if (typeof Blob === 'undefined') { From 289aad2bd763992829cf837ee4f42469b27b679d Mon Sep 17 00:00:00 2001 From: rajsite Date: Mon, 25 Jun 2018 11:02:31 -0500 Subject: [PATCH 31/67] Fix Makefile whitespace --- make-it/EmMakefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/make-it/EmMakefile b/make-it/EmMakefile index 59f369410..53c7ef4ee 100644 --- a/make-it/EmMakefile +++ b/make-it/EmMakefile @@ -143,8 +143,8 @@ EM_EXPORTS = -s EXPORTED_FUNCTIONS="[\ '_Data_WriteJavaScriptRefNum',\ '_Data_GetArrayMetadata',\ '_Data_GetArrayBegin',\ - '_Data_GetArrayDimensions',\ - '_Data_GetArrayLength',\ + '_Data_GetArrayDimensions',\ + '_Data_GetArrayLength',\ '_Data_GetArrayDimLength',\ '_Data_ResizeArray',\ '_TypeRef_TopAQSize',\ @@ -166,7 +166,7 @@ EM_EXPORTS = -s EXPORTED_FUNCTIONS="[\ '_JavaScriptInvoke_GetParameterType',\ '_JavaScriptInvoke_GetParameterPointer',\ '_JavaScriptInvoke_GetArrayElementType',\ - '_TypeRef_Rank'\ + '_TypeRef_Rank'\ ]" EM_RUNTIME_EXPORTS = -s EXTRA_EXPORTED_RUNTIME_METHODS="[\ From 38f6b95f3aed4d85cf10dc2c1528b0ee6674835e Mon Sep 17 00:00:00 2001 From: rajsite Date: Mon, 25 Jun 2018 15:58:15 -0500 Subject: [PATCH 32/67] Cover unsupported cases for readString and getArrayDimensions --- source/io/module_eggShell.js | 45 +++++++++----- test-it/karma/publicapi/Double.Test.js | 4 +- test-it/karma/publicapi/FindValueRef.Test.js | 6 +- .../publicapi/GetArrayDimensions.Test.js | 61 +++++++++++++++++++ test-it/karma/publicapi/String.Test.js | 9 ++- 5 files changed, 102 insertions(+), 23 deletions(-) create mode 100644 test-it/karma/publicapi/GetArrayDimensions.Test.js diff --git a/source/io/module_eggShell.js b/source/io/module_eggShell.js index a7b482ab4..f46193b04 100644 --- a/source/io/module_eggShell.js +++ b/source/io/module_eggShell.js @@ -349,22 +349,6 @@ } }; - Module.eggShell.getArrayDimensions = publicAPI.eggShell.getArrayDimensions = function (valueRef) { - var rank = Module.typeHelpers.typeRank(valueRef.typeRef); - - var stack = Module.stackSave(); - var dimensionsPointer = Module.stackAlloc(rank * LENGTH_SIZE); - Module._Data_GetArrayDimensions(valueRef.dataRef, dimensionsPointer); - var dimensions = []; - var i; - for (i = 0; i < rank; i += 1) { - dimensions.push(Module.getValue(dimensionsPointer + (i * LENGTH_SIZE), 'i32')); - } - Module.stackRestore(stack); - - return dimensions; - }; - Module.eggShell.dataGetArrayBegin = function (dataRef) { return Module._Data_GetArrayBegin(dataRef); }; @@ -374,6 +358,12 @@ }; Module.eggShell.readString = publicAPI.eggShell.readString = function (valueRef) { + if (Module.typeHelpers.isString(valueRef.typeRef) === false) { + throw new Error('Performing readString failed for the following reason: ' + eggShellResultEnum[EGGSHELL_RESULT.UNEXPECTED_OBJECT_TYPE] + + ' (error code: ' + EGGSHELL_RESULT.UNEXPECTED_OBJECT_TYPE + ')' + + ' (typeRef: ' + valueRef.typeRef + ')' + + ' (dataRef: ' + valueRef.dataRef + ')'); + } var arrayBegin = Module.eggShell.dataGetArrayBegin(valueRef.dataRef); var totalLength = Module.eggShell.dataGetArrayLength(valueRef.dataRef); var result = Module.coreHelpers.sizedUtf8ArrayToJSString(Module.HEAPU8, arrayBegin, totalLength); @@ -434,6 +424,29 @@ return findCompatibleTypedArrayConstructor(valueRef.typeRef) !== undefined; }; + Module.eggShell.getArrayDimensions = publicAPI.eggShell.getArrayDimensions = function (valueRef) { + var TypedArrayConstructor = findCompatibleTypedArrayConstructor(valueRef.typeRef); + if (TypedArrayConstructor === undefined) { + throw new Error('Performing getArrayDimensions failed for the following reason: ' + eggShellResultEnum[EGGSHELL_RESULT.UNEXPECTED_OBJECT_TYPE] + + ' (error code: ' + EGGSHELL_RESULT.UNEXPECTED_OBJECT_TYPE + ')' + + ' (typeRef: ' + valueRef.typeRef + ')' + + ' (dataRef: ' + valueRef.dataRef + ')'); + } + + var rank = Module.typeHelpers.typeRank(valueRef.typeRef); + var stack = Module.stackSave(); + var dimensionsPointer = Module.stackAlloc(rank * LENGTH_SIZE); + Module._Data_GetArrayDimensions(valueRef.dataRef, dimensionsPointer); + var dimensions = []; + var i; + for (i = 0; i < rank; i += 1) { + dimensions.push(Module.getValue(dimensionsPointer + (i * LENGTH_SIZE), 'i32')); + } + Module.stackRestore(stack); + + return dimensions; + }; + Module.eggShell.readTypedArray = publicAPI.eggShell.readTypedArray = function (valueRef) { var TypedArrayConstructor = findCompatibleTypedArrayConstructor(valueRef.typeRef); if (TypedArrayConstructor === undefined) { diff --git a/test-it/karma/publicapi/Double.Test.js b/test-it/karma/publicapi/Double.Test.js index 67d52b1f2..9d4001d3c 100644 --- a/test-it/karma/publicapi/Double.Test.js +++ b/test-it/karma/publicapi/Double.Test.js @@ -80,8 +80,8 @@ describe('The Vireo EggShell Double api can', function () { }; }; - expect(unsupportedTypeCheck('dataItem_Complex')).toThrow(); - expect(unsupportedTypeCheck('dataItem_String')).toThrow(); + expect(unsupportedTypeCheck('dataItem_Complex')).toThrowError(/CantDecode/); + expect(unsupportedTypeCheck('dataItem_String')).toThrowError(/CantDecode/); }); }); }); diff --git a/test-it/karma/publicapi/FindValueRef.Test.js b/test-it/karma/publicapi/FindValueRef.Test.js index 54e6ab32f..c373dd882 100644 --- a/test-it/karma/publicapi/FindValueRef.Test.js +++ b/test-it/karma/publicapi/FindValueRef.Test.js @@ -34,21 +34,21 @@ describe('The Vireo EggShell findValueRef api can', function () { var invalidViName = function () { vireo.eggShell.findValueRef('nonexistantvi', pathName); }; - expect(invalidViName).toThrow(); + expect(invalidViName).toThrowError(/ObjectNotFoundAtPath/); }); it('to throw for an empty vi name', function () { var invalidViName = function () { vireo.eggShell.findValueRef('', pathName); }; - expect(invalidViName).toThrow(); + expect(invalidViName).toThrowError(/ObjectNotFoundAtPath/); }); it('to throw for a nonexistant path', function () { var invalidPath = function () { vireo.eggShell.findValueRef(viName, 'nonexistantvalue'); }; - expect(invalidPath).toThrow(); + expect(invalidPath).toThrowError(/ObjectNotFoundAtPath/); }); it('to return a typeRef for the the local scope of a VI for an empty path', function () { diff --git a/test-it/karma/publicapi/GetArrayDimensions.Test.js b/test-it/karma/publicapi/GetArrayDimensions.Test.js new file mode 100644 index 000000000..f23a7a576 --- /dev/null +++ b/test-it/karma/publicapi/GetArrayDimensions.Test.js @@ -0,0 +1,61 @@ +describe('The Vireo EggShell getArrayDimensions api', function () { + 'use strict'; + // Reference aliases + var Vireo = window.NationalInstruments.Vireo.Vireo; + var vireoRunner = window.testHelpers.vireoRunner; + var fixtures = window.testHelpers.fixtures; + + var vireo; + + var testsArrayDemoViaUrl = fixtures.convertToAbsoluteFromViaTestsDir('ArrayDemo.via'); + var publicApiMultipleTypesViaUrl = fixtures.convertToAbsoluteFromFixturesDir('publicapi/MultipleTypes.via'); + var viNameArrayDemo = 'ArrayDemo'; + var viNameMultipleTypes = 'MyVI'; + var getArrayDimensionsHelper = function (viName, path) { + var valueRef = vireo.eggShell.findValueRef(viName, path); + var dimensions = vireo.eggShell.getArrayDimensions(valueRef); + return dimensions; + }; + + beforeAll(function (done) { + fixtures.preloadAbsoluteUrls([ + testsArrayDemoViaUrl, + publicApiMultipleTypesViaUrl + ], done); + }); + + beforeEach(function () { + vireo = new Vireo(); + }); + + it('can expose array lengths', function (done) { + var getArrayDimensions = getArrayDimensionsHelper.bind(undefined, viNameArrayDemo); + var runSlicesAsync = vireoRunner.rebootAndLoadVia(vireo, testsArrayDemoViaUrl); + + runSlicesAsync(function (rawPrint, rawPrintError) { + expect(rawPrint).toBeNonEmptyString(); + expect(rawPrintError).toBeEmptyString(); + expect(getArrayDimensions('variableArray1d')).toEqual([0]); + expect(getArrayDimensions('fixedArray1d')).toEqual([5]); + expect(getArrayDimensions('boundedArray1d')).toEqual([0]); + expect(getArrayDimensions('variableArray1dwithDefaults')).toEqual([4]); + expect(getArrayDimensions('fixedArray1dwithDefaults')).toEqual([5]); + expect(getArrayDimensions('boundedArray1dwithDefaults')).toEqual([4]); + expect(getArrayDimensions('fixedArray2d')).toEqual([2, 3]); + expect(getArrayDimensions('fixedArray3d')).toEqual([1, 2, 3]); + done(); + }); + }); + + it('errors for unsupported types', function (done) { + var getArrayDimensions = getArrayDimensionsHelper.bind(undefined, viNameMultipleTypes); + var runSlicesAsync = vireoRunner.rebootAndLoadVia(vireo, publicApiMultipleTypesViaUrl); + + runSlicesAsync(function (rawPrint, rawPrintError) { + expect(rawPrint).toBeEmptyString(); + expect(rawPrintError).toBeEmptyString(); + expect(getArrayDimensions.bind(undefined, 'dataItem_Boolean')).toThrowError(/UnexpectedObjectType/); + done(); + }); + }); +}); diff --git a/test-it/karma/publicapi/String.Test.js b/test-it/karma/publicapi/String.Test.js index 94dbf74c2..b66c20e1e 100644 --- a/test-it/karma/publicapi/String.Test.js +++ b/test-it/karma/publicapi/String.Test.js @@ -26,9 +26,14 @@ describe('The Vireo EggShell String api can', function () { describe('use readString', function () { it('to read different string values from memory', function () { - var valueRef = vireo.eggShell.findValueRef(viName, 'dataItem_String'); - vireo.eggShell.readString(valueRef); expect(readString('dataItem_String')).toBe('Hello'); }); + + it('to throw on unsupported types', function () { + var readStringThrows = function () { + readString('dataItem_NumericDouble'); + }; + expect(readStringThrows).toThrowError(/UnexpectedObjectType/); + }); }); }); From 4327ab084889df9a837565ba0f8d55dc904e247a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Le=C3=B3n?= Date: Tue, 26 Jun 2018 13:54:05 -0500 Subject: [PATCH 33/67] Merged typeRank and elementName --- make-it/EmMakefile | 1 + source/core/CEntryPoints.cpp | 25 +++++++++++++++++++++++++ source/core/module_typeHelpers.js | 8 +++++++- source/include/CEntryPoints.h | 1 + 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/make-it/EmMakefile b/make-it/EmMakefile index 53c7ef4ee..3c3ade6a3 100644 --- a/make-it/EmMakefile +++ b/make-it/EmMakefile @@ -149,6 +149,7 @@ EM_EXPORTS = -s EXPORTED_FUNCTIONS="[\ '_Data_ResizeArray',\ '_TypeRef_TopAQSize',\ '_TypeRef_Name',\ + '_TypeRef_ElementName',\ '_TypeRef_SubElementCount',\ '_TypeRef_GetSubElementByIndex',\ '_TypeRef_IsCluster',\ diff --git a/source/core/CEntryPoints.cpp b/source/core/CEntryPoints.cpp index e19b5ef08..ef9e97264 100644 --- a/source/core/CEntryPoints.cpp +++ b/source/core/CEntryPoints.cpp @@ -580,6 +580,31 @@ VIREO_EXPORT const char* TypeRef_Name(TypeManagerRef tm, TypeRef typeRef) return ""; } //------------------------------------------------------------ +VIREO_EXPORT const char* TypeRef_ElementName(TypeManagerRef tm, TypeRef typeRef) +{ + TypeManagerScope scope(tm); + SubString name = typeRef->ElementName(); + + static StringRef returnBuffer = nullptr; + if (returnBuffer == nullptr) { + // Allocate a string the first time it is used. + // After that it will be resized as needed. + STACK_VAR(String, tempReturn); + returnBuffer = tempReturn.DetachValue(); + } else { + returnBuffer->Resize1D(0); + } + + if (returnBuffer) { + returnBuffer->AppendSubString(&name); + // Add an explicit nullptr terminator so it looks like a C string. + returnBuffer->Append((Utf8Char)'\0'); + return (const char*) returnBuffer->Begin(); + } + + return ""; +} +//------------------------------------------------------------ VIREO_EXPORT Int32 TypeRef_ElementOffset(TypeRef typeRef) { return typeRef->ElementOffset(); diff --git a/source/core/module_typeHelpers.js b/source/core/module_typeHelpers.js index 885e1fc20..ab46ace99 100644 --- a/source/core/module_typeHelpers.js +++ b/source/core/module_typeHelpers.js @@ -25,11 +25,13 @@ var assignTypeHelpers = function (Module) { // Disable new-cap for the cwrap functions so the names can be the same in C and JS /* eslint 'new-cap': ['error', {'capIsNewExceptions': [ - 'TypeRef_Name' + 'TypeRef_Name', + 'TypeRef_ElementName' ]}], */ Module.typeHelpers = {}; var TypeRef_Name = Module.cwrap('TypeRef_Name', 'string', ['number']); + var TypeRef_ElementName = Module.cwrap('TypeRef_ElementName', 'string', ['number']); // Private instance functions var validateVisitMethod = function (fn, fnName) { @@ -189,6 +191,10 @@ return Module._TypeRef_Rank(typeRef); }; + Module.typeHelpers.elementName = function (typeRef) { + return TypeRef_ElementName(Module.eggShell.v_userShell, typeRef); + }; + Module.typeHelpers.subElementCount = function (typeRef) { return Module._TypeRef_SubElementCount(typeRef); }; diff --git a/source/include/CEntryPoints.h b/source/include/CEntryPoints.h index 3fc36b48b..f4cae952f 100644 --- a/source/include/CEntryPoints.h +++ b/source/include/CEntryPoints.h @@ -76,6 +76,7 @@ VIREO_EXPORT Boolean TypeRef_HasCustomDefault(TypeRef typeRef); VIREO_EXPORT EncodingEnum TypeRef_BitEncoding(TypeRef typeRef); VIREO_EXPORT Int32 TypeRef_Alignment(TypeRef typeRef); VIREO_EXPORT const char* TypeRef_Name(TypeManagerRef typeManager, TypeRef typeRef); +VIREO_EXPORT const char* TypeRef_ElementName(TypeManagerRef typeManager, TypeRef typeRef); VIREO_EXPORT Int32 TypeRef_ElementOffset(TypeRef typeRef); VIREO_EXPORT Int32 TypeRef_Rank(TypeRef typeRef); VIREO_EXPORT PointerTypeEnum TypeRef_PointerType(TypeRef typeRef); From 756359018360ed3e3d1ebc0bcea1d70b1b2f40fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Le=C3=B3n?= Date: Mon, 25 Jun 2018 10:54:02 -0500 Subject: [PATCH 34/67] Initial implementation of readValueRefObject with tests --- source/io/module_eggShell.js | 15 +++ .../publicapi/ReadValueRefObject.Test.js | 117 ++++++++++++++++++ 2 files changed, 132 insertions(+) create mode 100644 test-it/karma/publicapi/ReadValueRefObject.Test.js diff --git a/source/io/module_eggShell.js b/source/io/module_eggShell.js index f46193b04..4e643baf2 100644 --- a/source/io/module_eggShell.js +++ b/source/io/module_eggShell.js @@ -253,6 +253,21 @@ return subValueRef; }; + Module.eggShell.readValueRefObject = publicAPI.eggShell.readValueRefObject = function (valueRef) { + var typeRef = valueRef.typeRef; + var valueRefs = {}; + + var fieldCount = Module.typeHelpers.subElementCount(typeRef); + + for (var i = 0; i < fieldCount; i += 1) { + var fieldTypeRef = Module.typeHelpers.subElementByIndex(typeRef, i); + var fieldName = Module.typeHelpers.elementName(fieldTypeRef); + valueRefs[fieldName] = Module.eggShell.findSubValueRef(valueRef, fieldName); + } + + return valueRefs; + }; + Module.eggShell.reflectOnValueRef = publicAPI.eggShell.reflectOnValueRef = function (typeVisitor, valueRef, data) { if (typeof valueRef !== 'object' || valueRef === null) { throw new Error('valueRef must be an object. Found: ' + valueRef); diff --git a/test-it/karma/publicapi/ReadValueRefObject.Test.js b/test-it/karma/publicapi/ReadValueRefObject.Test.js new file mode 100644 index 000000000..01619ae9d --- /dev/null +++ b/test-it/karma/publicapi/ReadValueRefObject.Test.js @@ -0,0 +1,117 @@ +describe('The Vireo EggShell readValueRefObject', function () { + 'use strict'; + + // Reference aliases + var Vireo = window.NationalInstruments.Vireo.Vireo; + var vireoRunner = window.testHelpers.vireoRunner; + var fixtures = window.testHelpers.fixtures; + + var vireo = new Vireo(); + + var publicApiMultipleTypesViaUrl = fixtures.convertToAbsoluteFromFixturesDir('publicapi/MultipleTypes.via'); + var viName = 'MyVI'; + + var expectValidValueRef = function (valueRef) { + expect(valueRef).toBeNonEmptyObject(); + expect(valueRef.typeRef).toBeNumber(); + expect(valueRef.typeRef).not.toBe(0); + expect(valueRef.dataRef).toBeNumber(); + expect(valueRef.dataRef).not.toBe(0); + }; + + beforeAll(function (done) { + fixtures.preloadAbsoluteUrls([ + publicApiMultipleTypesViaUrl + ], done); + }); + + beforeAll(function () { + vireoRunner.rebootAndLoadVia(vireo, publicApiMultipleTypesViaUrl); + }); + + describe('for a cluster of scalars', function () { + var valueRef, + clusterOfScalarsPath = 'dataItem_ClusterOfScalars'; + + beforeAll(function () { + valueRef = vireo.eggShell.findValueRef(viName, clusterOfScalarsPath); + }); + + it('returns an object with field names as keys and valueRefs as values', function () { + var objectRef = vireo.eggShell.readValueRefObject(valueRef); + expectValidValueRef(objectRef.bool); + expectValidValueRef(objectRef.string); + expectValidValueRef(objectRef.double); + expectValidValueRef(objectRef.int32); + expectValidValueRef(objectRef.int64); + expectValidValueRef(objectRef.uint64); + expectValidValueRef(objectRef.complex); + expectValidValueRef(objectRef.time); + }); + + it('valueRefObject can be used to read from it', function () { + var objectValueRef = vireo.eggShell.readValueRefObject(valueRef); + expect(vireo.eggShell.readDouble(objectValueRef.bool)).toBe(1); + expect(vireo.eggShell.readDouble(objectValueRef.double)).toMatchIEEE754Number(3.14159); + expect(vireo.eggShell.readDouble(objectValueRef.int32)).toBe(42); + expect(vireo.eggShell.readDouble(objectValueRef.int64)).toBe(-72057594037927936); + expect(vireo.eggShell.readDouble(objectValueRef.uint64)).toBe(9223372041149743104); + expect(vireo.eggShell.readDouble(objectValueRef.time)).toBe(3564057536.423476); + }); + }); + + describe('for a timestamp', function () { + var valueRef, + timestampPath = 'dataItem_Timestamp'; + + beforeAll(function () { + valueRef = vireo.eggShell.findValueRef(viName, timestampPath); + }); + + it('returns something', function () { + var objectValueRef = vireo.eggShell.readValueRefObject(valueRef); + expectValidValueRef(objectValueRef.seconds); + expectValidValueRef(objectValueRef.fraction); + }); + }); + + describe('for an analogwaveform', function () { + var valueRef, + analogWaveformPath = 'wave_Double'; + + beforeAll(function () { + valueRef = vireo.eggShell.findValueRef(viName, analogWaveformPath); + }); + + it('returns something else', function () { + var objectValueRef = vireo.eggShell.readValueRefObject(valueRef); + expectValidValueRef(objectValueRef.t0); + expectValidValueRef(objectValueRef.dt); + expectValidValueRef(objectValueRef.Y); + }); + }); + + describe('for complex', function () { + var valueRef, + complexSinglePath = 'dataItem_ComplexSingle'; + + beforeAll(function () { + valueRef = vireo.eggShell.findValueRef(viName, complexSinglePath); + }); + + it('returns something else', function () { + var objectValueRef = vireo.eggShell.readValueRefObject(valueRef); + expectValidValueRef(objectValueRef.real); + expectValidValueRef(objectValueRef.imaginary); + }); + }); + + describe('for a 1-D array of', function () { + it('booleans', function () { + var valueRef = vireo.eggShell.findValueRef(viName, 'dataItem_ArrayOfBoolean'); + var objectValueRef = vireo.eggShell.readValueRefObject(valueRef); + console.log(objectValueRef); + expectValidValueRef(objectValueRef['']); + }); + }); +}); From 93713dbd42b5ed1086dc08eae6fb220543a9d895 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Le=C3=B3n?= Date: Tue, 26 Jun 2018 13:50:04 -0500 Subject: [PATCH 35/67] Added some more validation for accepted types of readValueRefObject. --- source/io/module_eggShell.js | 10 ++++++ .../publicapi/ReadValueRefObject.Test.js | 36 +++++++++++++------ 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/source/io/module_eggShell.js b/source/io/module_eggShell.js index 4e643baf2..ef247655d 100644 --- a/source/io/module_eggShell.js +++ b/source/io/module_eggShell.js @@ -257,6 +257,16 @@ var typeRef = valueRef.typeRef; var valueRefs = {}; + if (Module.typeHelpers.isCluster(typeRef) === false && + Module.typeHelpers.isTimestamp(typeRef) === false && + Module.typeHelpers.isComplex(typeRef) === false && + Module.typeHelpers.isAnalogWaveform(typeRef) === false) { + var unexpectedObjectTypeErrorCode = 2; + throw new Error('A ValueRefObject could not be made for the following reason: ' + eggShellResultEnum[unexpectedObjectTypeErrorCode] + + ' (error code: ' + unexpectedObjectTypeErrorCode + ')' + + ' (type name: ' + Module.typeHelpers.typeName(typeRef) + ')'); + } + var fieldCount = Module.typeHelpers.subElementCount(typeRef); for (var i = 0; i < fieldCount; i += 1) { diff --git a/test-it/karma/publicapi/ReadValueRefObject.Test.js b/test-it/karma/publicapi/ReadValueRefObject.Test.js index 01619ae9d..f743d0b22 100644 --- a/test-it/karma/publicapi/ReadValueRefObject.Test.js +++ b/test-it/karma/publicapi/ReadValueRefObject.Test.js @@ -68,7 +68,7 @@ describe('The Vireo EggShell readValueRefObject', function () { valueRef = vireo.eggShell.findValueRef(viName, timestampPath); }); - it('returns something', function () { + it('returns an object with keys "seconds" and "fraction" and valueRefs as values', function () { var objectValueRef = vireo.eggShell.readValueRefObject(valueRef); expectValidValueRef(objectValueRef.seconds); expectValidValueRef(objectValueRef.fraction); @@ -83,7 +83,7 @@ describe('The Vireo EggShell readValueRefObject', function () { valueRef = vireo.eggShell.findValueRef(viName, analogWaveformPath); }); - it('returns something else', function () { + it('returns an object with keys "dt", "t0" and "Y" and valueRefs as values', function () { var objectValueRef = vireo.eggShell.readValueRefObject(valueRef); expectValidValueRef(objectValueRef.t0); expectValidValueRef(objectValueRef.dt); @@ -99,19 +99,35 @@ describe('The Vireo EggShell readValueRefObject', function () { valueRef = vireo.eggShell.findValueRef(viName, complexSinglePath); }); - it('returns something else', function () { + it('returns an object with keys "real" and "imaginary" and valueRefs as values', function () { var objectValueRef = vireo.eggShell.readValueRefObject(valueRef); expectValidValueRef(objectValueRef.real); expectValidValueRef(objectValueRef.imaginary); }); }); - describe('for a 1-D array of', function () { - it('booleans', function () { - var valueRef = vireo.eggShell.findValueRef(viName, 'dataItem_ArrayOfBoolean'); - var objectValueRef = vireo.eggShell.readValueRefObject(valueRef); - console.log(objectValueRef); - expectValidValueRef(objectValueRef['']); - }); + it('throws for any other type', function () { + var tryReadValueRefObject = function (path) { + return function () { + vireo.eggShell.readValueRefObject(vireo.eggShell.findValueRef(viName, path)); + }; + }; + + expect(tryReadValueRefObject('dataItem_ArrayOfBoolean')).toThrowError(/ValueRefObject/); + expect(tryReadValueRefObject('dataItem_ArrayOfClusters')).toThrowError(/ValueRefObject/); + expect(tryReadValueRefObject('dataItem_NumericSingle')).toThrowError(/ValueRefObject/); + expect(tryReadValueRefObject('dataItem_NumericDouble')).toThrowError(/ValueRefObject/); + expect(tryReadValueRefObject('booleanTrueValue')).toThrowError(/ValueRefObject/); + expect(tryReadValueRefObject('int8MinValue')).toThrowError(/ValueRefObject/); + expect(tryReadValueRefObject('int16MinValue')).toThrowError(/ValueRefObject/); + expect(tryReadValueRefObject('int32MinValue')).toThrowError(/ValueRefObject/); + expect(tryReadValueRefObject('int64MinSafeInteger')).toThrowError(/ValueRefObject/); + expect(tryReadValueRefObject('int64MinValue')).toThrowError(/ValueRefObject/); + expect(tryReadValueRefObject('uInt8MinValue')).toThrowError(/ValueRefObject/); + expect(tryReadValueRefObject('uInt16MinValue')).toThrowError(/ValueRefObject/); + expect(tryReadValueRefObject('uInt32MinValue')).toThrowError(/ValueRefObject/); + expect(tryReadValueRefObject('uInt64MinSafeInteger')).toThrowError(/ValueRefObject/); + expect(tryReadValueRefObject('dataItem_String')).toThrowError(/ValueRefObject/); + expect(tryReadValueRefObject('enum8alphabet')).toThrowError(/ValueRefObject/); }); }); From e365f83438e7b973855678903c7eff83d24a7148 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Le=C3=B3n?= Date: Tue, 26 Jun 2018 15:04:29 -0500 Subject: [PATCH 36/67] Updated error for readValueRefObject --- source/io/module_eggShell.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source/io/module_eggShell.js b/source/io/module_eggShell.js index ef247655d..f3e947213 100644 --- a/source/io/module_eggShell.js +++ b/source/io/module_eggShell.js @@ -261,9 +261,8 @@ Module.typeHelpers.isTimestamp(typeRef) === false && Module.typeHelpers.isComplex(typeRef) === false && Module.typeHelpers.isAnalogWaveform(typeRef) === false) { - var unexpectedObjectTypeErrorCode = 2; - throw new Error('A ValueRefObject could not be made for the following reason: ' + eggShellResultEnum[unexpectedObjectTypeErrorCode] + - ' (error code: ' + unexpectedObjectTypeErrorCode + ')' + + throw new Error('A ValueRefObject could not be made for the following reason: ' + eggShellResultEnum[EGGSHELL_RESULT.UNEXPECTED_OBJECT_TYPE] + + ' (error code: ' + EGGSHELL_RESULT.UNEXPECTED_OBJECT_TYPE + ')' + ' (type name: ' + Module.typeHelpers.typeName(typeRef) + ')'); } From 800ca42d717266ad8949a8e6c6c5c642dec7de34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Le=C3=B3n?= Date: Tue, 26 Jun 2018 15:47:08 -0500 Subject: [PATCH 37/67] Added note on typeHandlers order. --- source/core/module_typeHelpers.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/core/module_typeHelpers.js b/source/core/module_typeHelpers.js index ab46ace99..317d36fb8 100644 --- a/source/core/module_typeHelpers.js +++ b/source/core/module_typeHelpers.js @@ -293,6 +293,8 @@ dispatcher: dispatchVisitArray }, { + // Cluster is evaluated last, since internally Complex, AnalogWaveform and Timestamps + // are also clusters. typeChecker: Module.typeHelpers.isCluster, dispatcher: dispatchVisitCluster } From 129c5125c29eed7b6346b62bffb4908c13cb5e72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Le=C3=B3n?= Date: Tue, 26 Jun 2018 16:43:08 -0500 Subject: [PATCH 38/67] Added a few more comments to explain order of typeHandlers --- source/core/module_typeHelpers.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/core/module_typeHelpers.js b/source/core/module_typeHelpers.js index 317d36fb8..d7cd6fdcc 100644 --- a/source/core/module_typeHelpers.js +++ b/source/core/module_typeHelpers.js @@ -257,6 +257,7 @@ dispatcher: dispatchVisitBoolean }, { + // Enum is wrapping an integer, so it needs to be evaluated first. typeChecker: Module.typeHelpers.isEnum, dispatcher: dispatchVisitEnum }, @@ -269,6 +270,7 @@ dispatcher: dispatchVisitFloat }, { + // String is an array of UTF-8 chars so it is evaluated before array. typeChecker: Module.typeHelpers.isString, dispatcher: dispatchVisitString }, @@ -293,8 +295,8 @@ dispatcher: dispatchVisitArray }, { - // Cluster is evaluated last, since internally Complex, AnalogWaveform and Timestamps - // are also clusters. + // Cluster is evaluated last because Complex, AnalogWaveform, Path and Timestamps + // are internally also clusters. typeChecker: Module.typeHelpers.isCluster, dispatcher: dispatchVisitCluster } From 17bffaef2834beab65d6c8e06b89bfc27192c561 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Le=C3=B3n?= Date: Tue, 26 Jun 2018 16:43:25 -0500 Subject: [PATCH 39/67] Added tests for NIPath --- source/io/module_eggShell.js | 5 +---- .../karma/fixtures/publicapi/MultipleTypes.via | 4 ++++ .../karma/publicapi/ReadValueRefObject.Test.js | 15 +++++++++++++++ 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/source/io/module_eggShell.js b/source/io/module_eggShell.js index f3e947213..52b955959 100644 --- a/source/io/module_eggShell.js +++ b/source/io/module_eggShell.js @@ -257,10 +257,7 @@ var typeRef = valueRef.typeRef; var valueRefs = {}; - if (Module.typeHelpers.isCluster(typeRef) === false && - Module.typeHelpers.isTimestamp(typeRef) === false && - Module.typeHelpers.isComplex(typeRef) === false && - Module.typeHelpers.isAnalogWaveform(typeRef) === false) { + if (Module.typeHelpers.isCluster(typeRef) === false) { throw new Error('A ValueRefObject could not be made for the following reason: ' + eggShellResultEnum[EGGSHELL_RESULT.UNEXPECTED_OBJECT_TYPE] + ' (error code: ' + EGGSHELL_RESULT.UNEXPECTED_OBJECT_TYPE + ')' + ' (type name: ' + Module.typeHelpers.typeName(typeRef) + ')'); diff --git a/test-it/karma/fixtures/publicapi/MultipleTypes.via b/test-it/karma/fixtures/publicapi/MultipleTypes.via index 845c581bd..c78316831 100644 --- a/test-it/karma/fixtures/publicapi/MultipleTypes.via +++ b/test-it/karma/fixtures/publicapi/MultipleTypes.via @@ -166,6 +166,10 @@ define (MyVI dv(.VirtualInstrument ( e(dv(Enum16 (zero one two three four) 3) enum16numbers) e(dv(Enum32 (red orange yellow green blue purple) 2) enum32colors) e(dv(Enum64 (altair bajor cardassiaA cardassiaB armadillo cobra lynx marmot panda whiskyjack) 5) enum64releases) + + e(dv(.NIPath (() '')) notAPath) + e(dv(.NIPath (() 'ABSOLUTE')) emptyPath) + e(dv(.NIPath (('C' 'Windows' 'System32') 'ABSOLUTE')) win32Path) ) clump( ) diff --git a/test-it/karma/publicapi/ReadValueRefObject.Test.js b/test-it/karma/publicapi/ReadValueRefObject.Test.js index f743d0b22..fe4379d05 100644 --- a/test-it/karma/publicapi/ReadValueRefObject.Test.js +++ b/test-it/karma/publicapi/ReadValueRefObject.Test.js @@ -106,6 +106,21 @@ describe('The Vireo EggShell readValueRefObject', function () { }); }); + describe('for path', function () { + var valueRef, + nipathPath = 'win32Path'; + + beforeAll(function () { + valueRef = vireo.eggShell.findValueRef(viName, nipathPath); + }); + + it('returns an object with keys "components" and "type" and valueReds as values', function () { + var objectValueRef = vireo.eggShell.readValueRefObject(valueRef); + expectValidValueRef(objectValueRef.components); + expectValidValueRef(objectValueRef.type); + }); + }); + it('throws for any other type', function () { var tryReadValueRefObject = function (path) { return function () { From 9524c9dfb1aa1dd811215c4b0b30ecfb87875c73 Mon Sep 17 00:00:00 2001 From: rajsite Date: Mon, 25 Jun 2018 18:29:57 -0500 Subject: [PATCH 40/67] Resize array initial implementation --- source/core/CEntryPoints.cpp | 24 ++++---- source/include/CEntryPoints.h | 3 +- source/io/module_eggShell.js | 40 ++++++++----- test-it/ViaTests/ArrayDemo.via | 1 + .../publicapi/GetArrayDimensions.Test.js | 1 + test-it/karma/publicapi/ResizeArray.Test.js | 56 ++++++++----------- 6 files changed, 64 insertions(+), 61 deletions(-) diff --git a/source/core/CEntryPoints.cpp b/source/core/CEntryPoints.cpp index ef9e97264..209d27f18 100644 --- a/source/core/CEntryPoints.cpp +++ b/source/core/CEntryPoints.cpp @@ -280,20 +280,21 @@ VIREO_EXPORT Int32 EggShell_GetArrayDimLength(TypeManagerRef tm, const char* viN } //------------------------------------------------------------ //! Resizes a variable size Array symbol to have new dimension lengths specified by newLengths, it also initializes cells for non-flat data. -//! Returns -1 if the symbols is not found, -2 if was not possible to resize the array and 0 if resizing was successful. -VIREO_EXPORT Int32 EggShell_ResizeArray(TypeManagerRef tm, const char* viName, const char* eltName, Int32 rank, Int32* newLengths) +//! Caller is expected to allocate an array newLengths of size rank for the duration of function invocation. +VIREO_EXPORT EggShellResult EggShell_ResizeArray(TypeManagerRef tm, const TypeRef actualType, const void* pData, Int32 rank, Int32 newLengths[]) { - SubString objectName(viName); - SubString path(eltName); - void *pData = nullptr; - - TypeRef actualType = tm->GetObjectElementAddressFromPath(&objectName, &path, &pData, true); - if (actualType == nullptr || !actualType->IsArray()) { - return kLVError_ArgError; + TypeManagerScope scope(tm); + if (actualType == nullptr || !actualType->IsValid() || !actualType->IsArray()) { + return kEggShellResult_UnexpectedObjectType; // TODO(mraj): use memos new invalid type eggShellResult } - TypedArrayCoreRef actualArray = *(TypedArrayCoreRef*)pData; - return Data_ResizeArray(tm, actualArray, rank, newLengths); + TypedArrayCoreRef arrayObject = *(TypedArrayCoreRef*)pData; + VIREO_ASSERT(TypedArrayCore::ValidateHandle(arrayObject)); + + if (!arrayObject->ResizeDimensions(rank, newLengths, true, false)) { + return kEggShellResult_UnableToCreateReturnBuffer; + } + return kEggShellResult_Success; } //------------------------------------------------------------ VIREO_EXPORT void* Data_GetStringBegin(StringRef stringObject) @@ -362,6 +363,7 @@ VIREO_EXPORT void* Data_GetArrayBegin(const void* pData) } //------------------------------------------------------------ //! Get the values for dimensions of the array. Assumes dimensions target is of length equal to rank +//! Caller is expected to allocate an array dimensions of size array rank for the duration of function invocation. VIREO_EXPORT void Data_GetArrayDimensions(const void* pData, IntIndex dimensions[]) { TypedArrayCoreRef arrayObject = *(TypedArrayCoreRef*)pData; diff --git a/source/include/CEntryPoints.h b/source/include/CEntryPoints.h index f4cae952f..1e9d9cc65 100644 --- a/source/include/CEntryPoints.h +++ b/source/include/CEntryPoints.h @@ -47,8 +47,7 @@ VIREO_EXPORT const char* EggShell_ReadValueString(TypeManagerRef tm, const char* VIREO_EXPORT EggShellResult EggShell_GetPointer(TypeManagerRef tm, const char* viName, const char* elementName, void** dataPointer, void** typePointer); VIREO_EXPORT Int32 EggShell_GetArrayDimLength(TypeManagerRef tm, const char* viName, const char* eltName, Int32 dim); -VIREO_EXPORT Int32 EggShell_ResizeArray(TypeManagerRef tm, const char* viName, const char* eltName, - Int32 rank, Int32* newLengths); +VIREO_EXPORT EggShellResult EggShell_ResizeArray(TypeManagerRef tm, const TypeRef actualType, const void* pData, Int32 rank, Int32 newLengths[]); VIREO_EXPORT EggShellResult Data_ValidateArrayType(TypeManagerRef tm, TypeRef typeRef); VIREO_EXPORT void* Data_GetStringBegin(StringRef stringObject); VIREO_EXPORT Int32 Data_GetStringLength(StringRef stringObject); diff --git a/source/io/module_eggShell.js b/source/io/module_eggShell.js index 52b955959..c2ae25fd6 100644 --- a/source/io/module_eggShell.js +++ b/source/io/module_eggShell.js @@ -36,7 +36,6 @@ 'EggShell_WriteValueString', 'EggShell_GetPointer', 'EggShell_GetArrayDimLength', - 'EggShell_ResizeArray', 'Data_ValidateArrayType', 'Data_GetStringBegin', 'Data_GetStringLength', @@ -115,7 +114,6 @@ var EggShell_WriteValueString = Module.cwrap('EggShell_WriteValueString', 'void', ['number', 'string', 'string', 'string', 'string']); var EggShell_GetPointer = Module.cwrap('EggShell_GetPointer', 'number', ['number', 'string', 'string', 'number', 'number']); var EggShell_GetArrayDimLength = Module.cwrap('EggShell_GetArrayDimLength', 'number', ['number', 'string', 'string', 'number']); - var EggShell_ResizeArray = Module.cwrap('EggShell_ResizeArray', 'number', ['number', 'string', 'string', 'number', 'number']); var Data_ValidateArrayType = Module.cwrap('Data_ValidateArrayType', 'number', ['number', 'number']); var Data_GetStringBegin = Module.cwrap('Data_GetStringBegin', 'number', []); var Data_GetStringLength = Module.cwrap('Data_GetStringLength', 'number', []); @@ -446,8 +444,7 @@ }; Module.eggShell.getArrayDimensions = publicAPI.eggShell.getArrayDimensions = function (valueRef) { - var TypedArrayConstructor = findCompatibleTypedArrayConstructor(valueRef.typeRef); - if (TypedArrayConstructor === undefined) { + if (!Module.typeHelpers.isArray(valueRef.typeRef)) { throw new Error('Performing getArrayDimensions failed for the following reason: ' + eggShellResultEnum[EGGSHELL_RESULT.UNEXPECTED_OBJECT_TYPE] + ' (error code: ' + EGGSHELL_RESULT.UNEXPECTED_OBJECT_TYPE + ')' + ' (typeRef: ' + valueRef.typeRef + ')' + @@ -593,20 +590,33 @@ return EggShell_GetArrayDimLength(Module.eggShell.v_userShell, vi, path, dim); }; - Module.eggShell.resizeArray = publicAPI.eggShell.resizeArray = function (vi, path, newDimensionSizes) { - var int32Byte = 4; - var rank = newDimensionSizes.length; - var newLengths = Module._malloc(rank * int32Byte); - - for (var i = 0; i < rank; i += 1) { - Module.setValue(newLengths + (i * int32Byte), newDimensionSizes[i], 'i32'); + Module.eggShell.resizeArray = publicAPI.eggShell.resizeArray = function (valueRef, newDimensions) { + if (!Module.typeHelpers.isArray(valueRef.typeRef)) { + throw new Error('Performing resizeArray failed for the following reason: ' + eggShellResultEnum[EGGSHELL_RESULT.UNEXPECTED_OBJECT_TYPE] + + ' (error code: ' + EGGSHELL_RESULT.UNEXPECTED_OBJECT_TYPE + ')' + + ' (typeRef: ' + valueRef.typeRef + ')' + + ' (dataRef: ' + valueRef.dataRef + ')'); } - var success = EggShell_ResizeArray(Module.eggShell.v_userShell, vi, path, rank, newLengths); - - Module._free(newLengths); + var rank = Module.typeHelpers.typeRank(valueRef.typeRef); + if (rank !== newDimensions.length) { + throw new Error('Current array is of rank ' + rank + ' and resize was called with only ' + newDimensions.length + ' dimensions specified.'); + } - return success; + var stack = Module.stackSave(); + var dimensionsPointer = Module.stackAlloc(rank * LENGTH_SIZE); + var i; + for (i = 0; i < newDimensions.length; i += 1) { + Module.setValue(dimensionsPointer + (i * LENGTH_SIZE), newDimensions[i], 'i32'); + } + var eggShellResult = Module._EggShell_ResizeArray(Module.eggShell.v_userShell, valueRef.typeRef, valueRef.dataRef, rank, dimensionsPointer); + if (eggShellResult !== 0) { + throw new Error('Resizing the array failed for the following reason: ' + eggShellResultEnum[eggShellResult] + + ' (error code: ' + eggShellResult + ')' + + ' (typeRef: ' + valueRef.typeRef + ')' + + ' (dataRef: ' + valueRef.dataRef + ')'); + } + Module.stackRestore(stack); }; Module.eggShell.dataReadString = function (stringPointer) { diff --git a/test-it/ViaTests/ArrayDemo.via b/test-it/ViaTests/ArrayDemo.via index e2584cd97..590fd7472 100644 --- a/test-it/ViaTests/ArrayDemo.via +++ b/test-it/ViaTests/ArrayDemo.via @@ -10,6 +10,7 @@ define(ArrayDemo dv(.VirtualInstrument ( e(a(.Int32 * *) variableArray2d) e(a(.Int32 2 3) fixedArray2d) + e(a(.Int32 0 0) fixedArray2dEmpty) e(a(.Int32 1 2 3) fixedArray3d) ) clump(1 diff --git a/test-it/karma/publicapi/GetArrayDimensions.Test.js b/test-it/karma/publicapi/GetArrayDimensions.Test.js index f23a7a576..8d4325926 100644 --- a/test-it/karma/publicapi/GetArrayDimensions.Test.js +++ b/test-it/karma/publicapi/GetArrayDimensions.Test.js @@ -42,6 +42,7 @@ describe('The Vireo EggShell getArrayDimensions api', function () { expect(getArrayDimensions('fixedArray1dwithDefaults')).toEqual([5]); expect(getArrayDimensions('boundedArray1dwithDefaults')).toEqual([4]); expect(getArrayDimensions('fixedArray2d')).toEqual([2, 3]); + expect(getArrayDimensions('fixedArray2dEmpty')).toEqual([0, 0]); expect(getArrayDimensions('fixedArray3d')).toEqual([1, 2, 3]); done(); }); diff --git a/test-it/karma/publicapi/ResizeArray.Test.js b/test-it/karma/publicapi/ResizeArray.Test.js index ad72cbadb..156b9d0e1 100644 --- a/test-it/karma/publicapi/ResizeArray.Test.js +++ b/test-it/karma/publicapi/ResizeArray.Test.js @@ -11,6 +11,22 @@ describe('Arrays in Vireo', function () { var viName = 'ArrayDemo'; var runSlicesAsync; + var resizeArray = function (path, dimensions) { + var valueRef = vireo.eggShell.findValueRef(viName, path); + vireo.eggShell.resizeArray(valueRef, dimensions); + }; + + var getArrayDimensions = function (path) { + var valueRef = vireo.eggShell.findValueRef(viName, path); + return vireo.eggShell.getArrayDimensions(valueRef); + }; + + beforeAll(function (done) { + fixtures.preloadAbsoluteUrls([ + viaPath + ], done); + }); + beforeEach(function () { runSlicesAsync = vireoRunner.rebootAndLoadVia(vireo, viaPath); }); @@ -20,67 +36,41 @@ describe('Arrays in Vireo', function () { expect(rawPrint).toBeNonEmptyString(); expect(rawPrintError).toBeEmptyString(); - var resized = vireo.eggShell.resizeArray(viName, 'variableArray1d', [5]); - expect(resized).toBe(0); - expect(vireo.eggShell.getArrayDimLength(viName, 'variableArray1d', 0)).toBe(5); + resizeArray('variableArray1d', [5]); + expect(getArrayDimensions('variableArray1d')).toEqual([5]); done(); }); }); it('can be resized when they are 1d array with defaults', function (done) { - var variableName = 'variableArray1dwithDefaults'; - runSlicesAsync(function (rawPrint, rawPrintError) { - expect(rawPrint).toBeNonEmptyString(); - expect(rawPrintError).toBeEmptyString(); - - var resized = vireo.eggShell.resizeArray(viName, variableName, [6]); - - expect(resized).toBe(0); - expect(vireo.eggShell.getArrayDimLength(viName, variableName, 0)).toBe(6); - - done(); - }); - }); - - it('returns error code 1 if the array does not exist', function (done) { - var variableName = 'imaginaryArrayThatDoesNotExist'; runSlicesAsync(function (rawPrint, rawPrintError) { expect(rawPrint).toBeNonEmptyString(); expect(rawPrintError).toBeEmptyString(); + resizeArray('variableArray1dwithDefaults', [6]); + expect(getArrayDimensions('variableArray1dwithDefaults')).toEqual([6]); - var resized = vireo.eggShell.resizeArray(viName, variableName, [6]); - expect(resized).toBe(1); done(); }); }); it('cannot be resized if they are fixed 2d arrays', function (done) { - var variableName = 'fixedArray2d'; runSlicesAsync(function (rawPrint, rawPrintError) { expect(rawPrint).toBeNonEmptyString(); expect(rawPrintError).toBeEmptyString(); - var resized = vireo.eggShell.resizeArray(viName, variableName, [3, 4]); - - expect(resized).toBe(2); - expect(vireo.eggShell.getArrayDimLength(viName, variableName, 0)).toBe(2); - expect(vireo.eggShell.getArrayDimLength(viName, variableName, 1)).toBe(3); + expect(resizeArray.bind(undefined, 'fixedArray2d', [3, 4])).toThrowError(/UnableToCreateReturnBuffer/); done(); }); }); it('can be resized when they are variable 2d array', function (done) { - var variableName = 'variableArray2d'; runSlicesAsync(function (rawPrint, rawPrintError) { expect(rawPrint).toBeNonEmptyString(); expect(rawPrintError).toBeEmptyString(); - var resized = vireo.eggShell.resizeArray(viName, variableName, [3, 4]); - - expect(resized).toBe(0); - expect(vireo.eggShell.getArrayDimLength(viName, variableName, 0)).toBe(3); - expect(vireo.eggShell.getArrayDimLength(viName, variableName, 1)).toBe(4); + resizeArray('variableArray2d', [3, 4]); + expect(getArrayDimensions('variableArray2d')).toEqual([3, 4]); done(); }); From c761212e6f159b2f1d46d13c8e139b13c10a599e Mon Sep 17 00:00:00 2001 From: rajsite Date: Tue, 26 Jun 2018 17:40:03 -0500 Subject: [PATCH 41/67] Move Rank validation to Cpp layer --- source/core/CEntryPoints.cpp | 12 +- source/include/CEntryPoints.h | 4 +- source/io/module_eggShell.js | 26 ++-- test-it/karma/publicapi/ResizeArray.Test.js | 136 ++++++++++++++------ 4 files changed, 125 insertions(+), 53 deletions(-) diff --git a/source/core/CEntryPoints.cpp b/source/core/CEntryPoints.cpp index 209d27f18..a31305513 100644 --- a/source/core/CEntryPoints.cpp +++ b/source/core/CEntryPoints.cpp @@ -280,18 +280,22 @@ VIREO_EXPORT Int32 EggShell_GetArrayDimLength(TypeManagerRef tm, const char* viN } //------------------------------------------------------------ //! Resizes a variable size Array symbol to have new dimension lengths specified by newLengths, it also initializes cells for non-flat data. -//! Caller is expected to allocate an array newLengths of size rank for the duration of function invocation. -VIREO_EXPORT EggShellResult EggShell_ResizeArray(TypeManagerRef tm, const TypeRef actualType, const void* pData, Int32 rank, Int32 newLengths[]) +VIREO_EXPORT EggShellResult EggShell_ResizeArray(TypeManagerRef tm, const TypeRef actualType, const void* pData, + Int32 newDimensionsLength, Int32 newDimensions[]) { TypeManagerScope scope(tm); if (actualType == nullptr || !actualType->IsValid() || !actualType->IsArray()) { - return kEggShellResult_UnexpectedObjectType; // TODO(mraj): use memos new invalid type eggShellResult + return kEggShellResult_InvalidTypeRef; + } + + if (actualType->Rank() != newDimensionsLength) { + return kEggShellResult_MismatchedArrayRank; } TypedArrayCoreRef arrayObject = *(TypedArrayCoreRef*)pData; VIREO_ASSERT(TypedArrayCore::ValidateHandle(arrayObject)); - if (!arrayObject->ResizeDimensions(rank, newLengths, true, false)) { + if (!arrayObject->ResizeDimensions(newDimensionsLength, newDimensions, true, false)) { return kEggShellResult_UnableToCreateReturnBuffer; } return kEggShellResult_Success; diff --git a/source/include/CEntryPoints.h b/source/include/CEntryPoints.h index 1e9d9cc65..794824e80 100644 --- a/source/include/CEntryPoints.h +++ b/source/include/CEntryPoints.h @@ -22,6 +22,7 @@ typedef enum { kEggShellResult_InvalidResultPointer = 3, kEggShellResult_UnableToCreateReturnBuffer = 4, kEggShellResult_InvalidTypeRef = 5, + kEggShellResult_MismatchedArrayRank = 6, } EggShellResult; //------------------------------------------------------------ //! TypeManager functions @@ -47,7 +48,8 @@ VIREO_EXPORT const char* EggShell_ReadValueString(TypeManagerRef tm, const char* VIREO_EXPORT EggShellResult EggShell_GetPointer(TypeManagerRef tm, const char* viName, const char* elementName, void** dataPointer, void** typePointer); VIREO_EXPORT Int32 EggShell_GetArrayDimLength(TypeManagerRef tm, const char* viName, const char* eltName, Int32 dim); -VIREO_EXPORT EggShellResult EggShell_ResizeArray(TypeManagerRef tm, const TypeRef actualType, const void* pData, Int32 rank, Int32 newLengths[]); +VIREO_EXPORT EggShellResult EggShell_ResizeArray(TypeManagerRef tm, const TypeRef actualType, const void* pData, + Int32 newDimensionsLength, Int32 newDimensions[]); VIREO_EXPORT EggShellResult Data_ValidateArrayType(TypeManagerRef tm, TypeRef typeRef); VIREO_EXPORT void* Data_GetStringBegin(StringRef stringObject); VIREO_EXPORT Int32 Data_GetStringLength(StringRef stringObject); diff --git a/source/io/module_eggShell.js b/source/io/module_eggShell.js index c2ae25fd6..0bef9557c 100644 --- a/source/io/module_eggShell.js +++ b/source/io/module_eggShell.js @@ -84,7 +84,8 @@ UNEXPECTED_OBJECT_TYPE: 2, INVALID_RESULT_POINTER: 3, UNABLE_TO_CREATE_RETURN_BUFFER: 4, - INVALID_TYPE_REF: 5 + INVALID_TYPE_REF: 5, + MISMATCHED_ARRAY_RANK: 6 }; var eggShellResultEnum = {}; eggShellResultEnum[EGGSHELL_RESULT.SUCCESS] = 'Success'; @@ -93,6 +94,7 @@ eggShellResultEnum[EGGSHELL_RESULT.INVALID_RESULT_POINTER] = 'InvalidResultPointer'; eggShellResultEnum[EGGSHELL_RESULT.UNABLE_TO_CREATE_RETURN_BUFFER] = 'UnableToCreateReturnBuffer'; eggShellResultEnum[EGGSHELL_RESULT.INVALID_TYPE_REF] = 'InvalidTypeRef'; + eggShellResultEnum[EGGSHELL_RESULT.MISMATCHED_ARRAY_RANK] = 'MismatchedArrayRank'; // Keep in sync with NIError in DataTypes.h var niErrorEnum = { @@ -598,18 +600,22 @@ ' (dataRef: ' + valueRef.dataRef + ')'); } - var rank = Module.typeHelpers.typeRank(valueRef.typeRef); - if (rank !== newDimensions.length) { - throw new Error('Current array is of rank ' + rank + ' and resize was called with only ' + newDimensions.length + ' dimensions specified.'); + if (!Array.isArray(newDimensions)) { + throw new Error('Expected newDimensions to be an array of dimension lengths, instead got: ' + newDimensions); } - var stack = Module.stackSave(); - var dimensionsPointer = Module.stackAlloc(rank * LENGTH_SIZE); - var i; - for (i = 0; i < newDimensions.length; i += 1) { - Module.setValue(dimensionsPointer + (i * LENGTH_SIZE), newDimensions[i], 'i32'); + var newDimensionsLength = newDimensions.length; + var dimensionsPointer = Module.stackAlloc(newDimensionsLength * LENGTH_SIZE); + var i, currentDimension; + for (i = 0; i < newDimensionsLength; i += 1) { + currentDimension = newDimensions[i]; + + if (typeof currentDimension !== 'number') { + throw new Error('Expected all dimensions of newDimensions to be numeric values for dimension length, instead got' + currentDimension); + } + Module.setValue(dimensionsPointer + (i * LENGTH_SIZE), currentDimension, 'i32'); } - var eggShellResult = Module._EggShell_ResizeArray(Module.eggShell.v_userShell, valueRef.typeRef, valueRef.dataRef, rank, dimensionsPointer); + var eggShellResult = Module._EggShell_ResizeArray(Module.eggShell.v_userShell, valueRef.typeRef, valueRef.dataRef, newDimensionsLength, dimensionsPointer); if (eggShellResult !== 0) { throw new Error('Resizing the array failed for the following reason: ' + eggShellResultEnum[eggShellResult] + ' (error code: ' + eggShellResult + ')' + diff --git a/test-it/karma/publicapi/ResizeArray.Test.js b/test-it/karma/publicapi/ResizeArray.Test.js index 156b9d0e1..52a5fc424 100644 --- a/test-it/karma/publicapi/ResizeArray.Test.js +++ b/test-it/karma/publicapi/ResizeArray.Test.js @@ -5,74 +5,134 @@ describe('Arrays in Vireo', function () { var vireoRunner = window.testHelpers.vireoRunner; var fixtures = window.testHelpers.fixtures; - // Sharing Vireo instances across tests make them run soooo much faster var vireo = new Vireo(); - var viaPath = fixtures.convertToAbsoluteFromViaTestsDir('ArrayDemo.via'); - var viName = 'ArrayDemo'; + var testsArrayDemoViaUrl = fixtures.convertToAbsoluteFromViaTestsDir('ArrayDemo.via'); + var publicApiMultipleTypesViaUrl = fixtures.convertToAbsoluteFromFixturesDir('publicapi/MultipleTypes.via'); var runSlicesAsync; - var resizeArray = function (path, dimensions) { + var resizeArrayHelper = function (viName, path, dimensions) { var valueRef = vireo.eggShell.findValueRef(viName, path); vireo.eggShell.resizeArray(valueRef, dimensions); }; - var getArrayDimensions = function (path) { + var getArrayDimensionsHelper = function (viName, path) { var valueRef = vireo.eggShell.findValueRef(viName, path); return vireo.eggShell.getArrayDimensions(valueRef); }; beforeAll(function (done) { fixtures.preloadAbsoluteUrls([ - viaPath + testsArrayDemoViaUrl, + publicApiMultipleTypesViaUrl ], done); }); - beforeEach(function () { - runSlicesAsync = vireoRunner.rebootAndLoadVia(vireo, viaPath); - }); + describe('when using array types', function () { + var viName = 'ArrayDemo'; + var resizeArray = resizeArrayHelper.bind(undefined, viName); + var getArrayDimensions = getArrayDimensionsHelper.bind(undefined, viName); + + beforeAll(function () { + runSlicesAsync = vireoRunner.rebootAndLoadVia(vireo, testsArrayDemoViaUrl); + }); - it('can be resized when they are variable size 1D array', function (done) { - runSlicesAsync(function (rawPrint, rawPrintError) { - expect(rawPrint).toBeNonEmptyString(); - expect(rawPrintError).toBeEmptyString(); + it('can be resized when they are variable size 1D array', function (done) { + runSlicesAsync(function (rawPrint, rawPrintError) { + expect(rawPrint).toBeNonEmptyString(); + expect(rawPrintError).toBeEmptyString(); - resizeArray('variableArray1d', [5]); - expect(getArrayDimensions('variableArray1d')).toEqual([5]); - done(); + resizeArray('variableArray1d', [5]); + expect(getArrayDimensions('variableArray1d')).toEqual([5]); + done(); + }); }); - }); - it('can be resized when they are 1d array with defaults', function (done) { - runSlicesAsync(function (rawPrint, rawPrintError) { - expect(rawPrint).toBeNonEmptyString(); - expect(rawPrintError).toBeEmptyString(); - resizeArray('variableArray1dwithDefaults', [6]); - expect(getArrayDimensions('variableArray1dwithDefaults')).toEqual([6]); + it('can be resized when they are 1d array with defaults', function (done) { + runSlicesAsync(function (rawPrint, rawPrintError) { + expect(rawPrint).toBeNonEmptyString(); + expect(rawPrintError).toBeEmptyString(); - done(); + resizeArray('variableArray1dwithDefaults', [6]); + expect(getArrayDimensions('variableArray1dwithDefaults')).toEqual([6]); + + done(); + }); }); - }); - it('cannot be resized if they are fixed 2d arrays', function (done) { - runSlicesAsync(function (rawPrint, rawPrintError) { - expect(rawPrint).toBeNonEmptyString(); - expect(rawPrintError).toBeEmptyString(); + it('cannot be resized if they are fixed 2d arrays', function (done) { + runSlicesAsync(function (rawPrint, rawPrintError) { + expect(rawPrint).toBeNonEmptyString(); + expect(rawPrintError).toBeEmptyString(); - expect(resizeArray.bind(undefined, 'fixedArray2d', [3, 4])).toThrowError(/UnableToCreateReturnBuffer/); + expect(resizeArray.bind(undefined, 'fixedArray2d', [3, 4])).toThrowError(/UnableToCreateReturnBuffer/); - done(); + done(); + }); + }); + + it('can be resized when they are variable 2d array', function (done) { + runSlicesAsync(function (rawPrint, rawPrintError) { + expect(rawPrint).toBeNonEmptyString(); + expect(rawPrintError).toBeEmptyString(); + + resizeArray('variableArray2d', [3, 4]); + expect(getArrayDimensions('variableArray2d')).toEqual([3, 4]); + + done(); + }); + }); + + it('throws for dimension arrays that are invalid arrays', function (done) { + runSlicesAsync(function (rawPrint, rawPrintError) { + expect(rawPrint).toBeNonEmptyString(); + expect(rawPrintError).toBeEmptyString(); + + expect(resizeArray.bind(undefined, 'variableArray2d', 'notAnArray')).toThrowError(/to be an array/); + + done(); + }); + }); + + it('throws for dimension arrays with non-numeric dimensions', function (done) { + runSlicesAsync(function (rawPrint, rawPrintError) { + expect(rawPrint).toBeNonEmptyString(); + expect(rawPrintError).toBeEmptyString(); + + expect(resizeArray.bind(undefined, 'variableArray2d', ['pen', 'pineapple'])).toThrowError(/numeric values/); + + done(); + }); + }); + + it('throws for new dimensions with wrong rank', function (done) { + runSlicesAsync(function (rawPrint, rawPrintError) { + expect(rawPrint).toBeNonEmptyString(); + expect(rawPrintError).toBeEmptyString(); + + expect(resizeArray.bind(undefined, 'variableArray2d', [1])).toThrowError(/MismatchedArrayRank/); + + done(); + }); }); }); - it('can be resized when they are variable 2d array', function (done) { - runSlicesAsync(function (rawPrint, rawPrintError) { - expect(rawPrint).toBeNonEmptyString(); - expect(rawPrintError).toBeEmptyString(); + describe('when using non-array types', function () { + var viName = 'MyVI'; + var resizeArray = resizeArrayHelper.bind(undefined, viName); + + beforeAll(function () { + runSlicesAsync = vireoRunner.rebootAndLoadVia(vireo, publicApiMultipleTypesViaUrl); + }); + + it('will throw for a boolean type', function (done) { + runSlicesAsync(function (rawPrint, rawPrintError) { + expect(rawPrint).toBeEmptyString(); + expect(rawPrintError).toBeEmptyString(); - resizeArray('variableArray2d', [3, 4]); - expect(getArrayDimensions('variableArray2d')).toEqual([3, 4]); + expect(resizeArray.bind(undefined, 'dataItem_Boolean', [3, 4])).toThrowError(/UnexpectedObjectType/); - done(); + done(); + }); }); }); }); From d9755ccbd67232a898f15e37e039bb60b8d9bc23 Mon Sep 17 00:00:00 2001 From: rajsite Date: Tue, 26 Jun 2018 17:45:43 -0500 Subject: [PATCH 42/67] Move valid array type check to cpp --- source/core/CEntryPoints.cpp | 6 +++++- source/io/module_eggShell.js | 7 ------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/source/core/CEntryPoints.cpp b/source/core/CEntryPoints.cpp index a31305513..92a580c30 100644 --- a/source/core/CEntryPoints.cpp +++ b/source/core/CEntryPoints.cpp @@ -284,10 +284,14 @@ VIREO_EXPORT EggShellResult EggShell_ResizeArray(TypeManagerRef tm, const TypeRe Int32 newDimensionsLength, Int32 newDimensions[]) { TypeManagerScope scope(tm); - if (actualType == nullptr || !actualType->IsValid() || !actualType->IsArray()) { + if (actualType == nullptr || !actualType->IsValid()) { return kEggShellResult_InvalidTypeRef; } + if(!actualType->IsArray()) { + return kEggShellResult_UnexpectedObjectType; + } + if (actualType->Rank() != newDimensionsLength) { return kEggShellResult_MismatchedArrayRank; } diff --git a/source/io/module_eggShell.js b/source/io/module_eggShell.js index 0bef9557c..76a6fba1e 100644 --- a/source/io/module_eggShell.js +++ b/source/io/module_eggShell.js @@ -593,13 +593,6 @@ }; Module.eggShell.resizeArray = publicAPI.eggShell.resizeArray = function (valueRef, newDimensions) { - if (!Module.typeHelpers.isArray(valueRef.typeRef)) { - throw new Error('Performing resizeArray failed for the following reason: ' + eggShellResultEnum[EGGSHELL_RESULT.UNEXPECTED_OBJECT_TYPE] + - ' (error code: ' + EGGSHELL_RESULT.UNEXPECTED_OBJECT_TYPE + ')' + - ' (typeRef: ' + valueRef.typeRef + ')' + - ' (dataRef: ' + valueRef.dataRef + ')'); - } - if (!Array.isArray(newDimensions)) { throw new Error('Expected newDimensions to be an array of dimension lengths, instead got: ' + newDimensions); } From 070a00cd1f2f4258dcb391c185c1ac134ff3b200 Mon Sep 17 00:00:00 2001 From: rajsite Date: Tue, 26 Jun 2018 17:57:30 -0500 Subject: [PATCH 43/67] Fix cpp lint error --- source/core/CEntryPoints.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/core/CEntryPoints.cpp b/source/core/CEntryPoints.cpp index 92a580c30..9d67f4ec0 100644 --- a/source/core/CEntryPoints.cpp +++ b/source/core/CEntryPoints.cpp @@ -288,7 +288,7 @@ VIREO_EXPORT EggShellResult EggShell_ResizeArray(TypeManagerRef tm, const TypeRe return kEggShellResult_InvalidTypeRef; } - if(!actualType->IsArray()) { + if (!actualType->IsArray()) { return kEggShellResult_UnexpectedObjectType; } From 6ccce6e4f11cea31eed71a5c9dc3b60415f0a016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Le=C3=B3n?= Date: Tue, 26 Jun 2018 18:11:19 -0500 Subject: [PATCH 44/67] Updated EggShell_ReadValueString to use type and data pointers. This function returns an EggShellResult for error handling. Updated all tests where readJSON was used. --- source/core/CEntryPoints.cpp | 19 +++++------- source/include/CEntryPoints.h | 3 +- source/io/module_eggShell.js | 20 +++++++++---- test-it/httptest1/testhttp.js | 3 +- test-it/karma/publicapi/ReadJson.Test.js | 30 +++++++++++-------- test-it/karma/publicapi/WriteJson.Test.js | 9 ++++-- .../utilities/TestHelpers.VireoRunner.js | 3 +- 7 files changed, 51 insertions(+), 36 deletions(-) diff --git a/source/core/CEntryPoints.cpp b/source/core/CEntryPoints.cpp index 9d67f4ec0..c70bffb0d 100644 --- a/source/core/CEntryPoints.cpp +++ b/source/core/CEntryPoints.cpp @@ -191,17 +191,12 @@ VIREO_EXPORT void EggShell_WriteValueString(TypeManagerRef tm, } //------------------------------------------------------------ //! Read a symbol's value as a string. Value will be formatted according to the format designated. -VIREO_EXPORT const char* EggShell_ReadValueString(TypeManagerRef tm, - const char* viName, const char* eltName, const char* format) +VIREO_EXPORT EggShellResult EggShell_ReadValueString(TypeManagerRef tm, TypeRef typeRef, void* data, const char* format, UInt8** valueString) { TypeManagerScope scope(tm); - void *pData = nullptr; - SubString objectName(viName); - SubString path(eltName); - TypeRef actualType = tm->GetObjectElementAddressFromPath(&objectName, &path, &pData, true); - if (actualType == nullptr) - return nullptr; + if (typeRef == null || !typeRef->IsValid()) + return kEggShellResult_InvalidTypeRef; static StringRef returnBuffer = nullptr; if (returnBuffer == nullptr) { @@ -216,12 +211,14 @@ VIREO_EXPORT const char* EggShell_ReadValueString(TypeManagerRef tm, if (returnBuffer) { SubString formatss(format); TDViaFormatter formatter(returnBuffer, true, 0, &formatss, kJSONEncodingEggShell); - formatter.FormatData(actualType, pData); + formatter.FormatData(typeRef, data); // Add an explicit nullptr terminator so it looks like a C string. returnBuffer->Append((Utf8Char)'\0'); - return (const char*) returnBuffer->Begin(); + *valueString = returnBuffer->Begin(); + return kEggShellResult_Success; } - return ""; + + return kEggShellResult_UnableToCreateReturnBuffer; } void CopyArrayTypeNameStringToBuffer(StringRef arrayTypeNameBuffer, SubString arrayTypeName) { diff --git a/source/include/CEntryPoints.h b/source/include/CEntryPoints.h index 794824e80..845d5b0a3 100644 --- a/source/include/CEntryPoints.h +++ b/source/include/CEntryPoints.h @@ -43,8 +43,7 @@ VIREO_EXPORT void EggShell_WriteDouble(TypeManagerRef tm, const char* viName, co VIREO_EXPORT NIError EggShell_ReadDouble(TypeManagerRef tm, const TypeRef actualType, const void* pData, Double* result); VIREO_EXPORT void EggShell_WriteValueString(TypeManagerRef tm, const char* viName, const char* eltName, const char* format, const char* value); -VIREO_EXPORT const char* EggShell_ReadValueString(TypeManagerRef tm, const char* viName, const char* eltName, - const char* format); +VIREO_EXPORT EggShellResult EggShell_ReadValueString(TypeManagerRef tm, TypeRef typeRef, void* pData, const char* format, UInt8** valueString); VIREO_EXPORT EggShellResult EggShell_GetPointer(TypeManagerRef tm, const char* viName, const char* elementName, void** dataPointer, void** typePointer); VIREO_EXPORT Int32 EggShell_GetArrayDimLength(TypeManagerRef tm, const char* viName, const char* eltName, Int32 dim); diff --git a/source/io/module_eggShell.js b/source/io/module_eggShell.js index 76a6fba1e..4824e5cb5 100644 --- a/source/io/module_eggShell.js +++ b/source/io/module_eggShell.js @@ -315,17 +315,25 @@ EggShell_WriteDouble(Module.eggShell.v_userShell, vi, path, value); }; - Module.eggShell.readJSON = publicAPI.eggShell.readJSON = function (vi, path) { + Module.eggShell.readJSON = publicAPI.eggShell.readJSON = function (valueRef) { var stack = Module.stackSave(); // Stack save only needed for input parameter string or array var type = 'JSON'; - var viStackPointer = Module.coreHelpers.writeJSStringToStack(vi); - var pathStackPointer = Module.coreHelpers.writeJSStringToStack(path); + var jsonStackDoublePointer = Module.stackAlloc(POINTER_SIZE); var typeStackPointer = Module.coreHelpers.writeJSStringToStack(type); - var responsePointer = Module._EggShell_ReadValueString(Module.eggShell.v_userShell, viStackPointer, pathStackPointer, typeStackPointer); - var responseLength = Module.coreHelpers.findCStringLength(Module.HEAPU8, responsePointer); - var response = Module.coreHelpers.sizedUtf8ArrayToJSString(Module.HEAPU8, responsePointer, responseLength); + var eggShellError = Module._EggShell_ReadValueString(Module.eggShell.v_userShell, valueRef.typeRef, valueRef.dataRef, typeStackPointer, jsonStackDoublePointer); + + if (eggShellError !== 0) { + throw new Error('Performing readJSON failed for the following reason: ' + eggShellResultEnum[eggShellError] + + ' (error code: ' + eggShellError + ')' + + ' (typeRef: ' + valueRef.typeRef + ')' + + ' (dataRef: ' + valueRef.dataRef + ')'); + } + + var jsonStackPointer = Module.getValue(jsonStackDoublePointer, 'i32'); + var responseLength = Module.coreHelpers.findCStringLength(Module.HEAPU8, jsonStackPointer); + var response = Module.coreHelpers.sizedUtf8ArrayToJSString(Module.HEAPU8, jsonStackPointer, responseLength); Module.stackRestore(stack); return response; diff --git a/test-it/httptest1/testhttp.js b/test-it/httptest1/testhttp.js index 1830a9f3c..4ab3f468e 100644 --- a/test-it/httptest1/testhttp.js +++ b/test-it/httptest1/testhttp.js @@ -13,7 +13,8 @@ var vireo = new Vireo(); vireo.eggShell.loadVia(viaCode); vireo.eggShell.executeSlicesUntilClumpsFinished(function () { - console.log(JSON.parse(vireo.eggShell.readJSON('%3AWeb%20Server%3AInteractive%3AApplication%3AMain%2Egviweb', 'dataItem_Body'))); + var valueRef = vireo.eggShell.findValueRef('%3AWeb%20Server%3AInteractive%3AApplication%3AMain%2Egviweb', 'dataItem_Body'); + console.log(JSON.parse(vireo.eggShell.readJSON(valueRef))); console.log('finished :D'); }); }; diff --git a/test-it/karma/publicapi/ReadJson.Test.js b/test-it/karma/publicapi/ReadJson.Test.js index d44861394..a3fc6f164 100644 --- a/test-it/karma/publicapi/ReadJson.Test.js +++ b/test-it/karma/publicapi/ReadJson.Test.js @@ -10,14 +10,20 @@ describe('The Vireo EggShell readJSON api can read', function () { var publicApiMultipleTypesViaUrl = fixtures.convertToAbsoluteFromFixturesDir('publicapi/MultipleTypes.via'); var viName = 'MyVI'; + var readActualJSON = function (viName, path) { + var valueRef = vireo.eggShell.findValueRef(viName, path); + var valJSON = vireo.eggShell.readJSON(valueRef); + return valJSON; + }; + var readTest = function (path, expectedVal) { - var valJSON = vireo.eggShell.readJSON(viName, path); + var valJSON = readActualJSON(viName, path); var val = JSON.parse(valJSON); expect(val).toMatchIEEE754Number(expectedVal); }; var readTestWithJSON = function (path, expectedValJSON, expectedVal) { - var valJSON = vireo.eggShell.readJSON(viName, path); + var valJSON = readActualJSON(viName, path); expect(valJSON).toMatchIEEE754Number(expectedValJSON); var val = JSON.parse(valJSON); @@ -266,14 +272,14 @@ describe('The Vireo EggShell readJSON api can read', function () { }); it('Int64', function () { - var actualJSON = vireo.eggShell.readJSON(viName, 'dataItem_Numeric64'); + var actualJSON = readActualJSON(viName, 'dataItem_Numeric64'); var actual = JSON.parse(actualJSON); expect(actual).toBe('-1152921504606846976'); }); it('UInt64', function () { - var actualJSON = vireo.eggShell.readJSON(viName, 'dataItem_NumericU64'); + var actualJSON = readActualJSON(viName, 'dataItem_NumericU64'); var actual = JSON.parse(actualJSON); expect(actual).toBe('18446744073709551615'); @@ -287,7 +293,7 @@ describe('The Vireo EggShell readJSON api can read', function () { }); it('Timestamp', function () { - var actualJSON = vireo.eggShell.readJSON(viName, 'dataItem_Timestamp'); + var actualJSON = readActualJSON(viName, 'dataItem_Timestamp'); var actual = JSON.parse(actualJSON); expect(actual).toEqual({ @@ -315,7 +321,7 @@ describe('The Vireo EggShell readJSON api can read', function () { }); it('Int64', function () { - var actualJSON = vireo.eggShell.readJSON(viName, 'dataItem_ArrayOfInt64'); + var actualJSON = readActualJSON(viName, 'dataItem_ArrayOfInt64'); var actual = JSON.parse(actualJSON); expect(actual).toEqual([ @@ -342,7 +348,7 @@ describe('The Vireo EggShell readJSON api can read', function () { }); it('Timestamp', function () { - var actualJSON = vireo.eggShell.readJSON(viName, 'dataItem_ArrayOfTimestamp'); + var actualJSON = readActualJSON(viName, 'dataItem_ArrayOfTimestamp'); var actual = JSON.parse(actualJSON); expect(actual).toEqual([ @@ -357,7 +363,7 @@ describe('The Vireo EggShell readJSON api can read', function () { }); it('Cluster', function () { - var actualJSON = vireo.eggShell.readJSON(viName, 'dataItem_ArrayOfClusters'); + var actualJSON = readActualJSON(viName, 'dataItem_ArrayOfClusters'); var actual = JSON.parse(actualJSON); expect(actual).toEqual([ @@ -435,7 +441,7 @@ describe('The Vireo EggShell readJSON api can read', function () { }); it('Int64', function () { - var actualJSON = vireo.eggShell.readJSON(viName, 'dataItem_2DArrayOfInt64'); + var actualJSON = readActualJSON(viName, 'dataItem_2DArrayOfInt64'); var actual = JSON.parse(actualJSON); expect(actual).toEqual([ @@ -469,7 +475,7 @@ describe('The Vireo EggShell readJSON api can read', function () { }); it('Timestamp', function () { - var actualJSON = vireo.eggShell.readJSON(viName, 'dataItem_2DArrayOfTimestamp'); + var actualJSON = readActualJSON(viName, 'dataItem_2DArrayOfTimestamp'); var actual = JSON.parse(actualJSON); expect(actual).toEqual([ @@ -521,7 +527,7 @@ describe('The Vireo EggShell readJSON api can read', function () { describe('composite types of', function () { it('clusters with scalars', function () { - var actualJSON = vireo.eggShell.readJSON(viName, 'dataItem_ClusterOfScalars'); + var actualJSON = readActualJSON(viName, 'dataItem_ClusterOfScalars'); var actual = JSON.parse(actualJSON); expect(actual).toEqual({ @@ -543,7 +549,7 @@ describe('The Vireo EggShell readJSON api can read', function () { }); it('clusters with 1D arrays', function () { - var actualJSON = vireo.eggShell.readJSON(viName, 'dataItem_ClusterOfArrays'); + var actualJSON = readActualJSON(viName, 'dataItem_ClusterOfArrays'); var actual = JSON.parse(actualJSON); expect(actual).toEqual({ diff --git a/test-it/karma/publicapi/WriteJson.Test.js b/test-it/karma/publicapi/WriteJson.Test.js index 90d6ef105..cff7a843b 100644 --- a/test-it/karma/publicapi/WriteJson.Test.js +++ b/test-it/karma/publicapi/WriteJson.Test.js @@ -11,7 +11,8 @@ describe('The Vireo EggShell writeJSON api can write', function () { var publicApiMultipleTypesViaUrl = fixtures.convertToAbsoluteFromFixturesDir('publicapi/MultipleTypes.via'); var writeTest = function (path, oldVal, newVal) { - var oldValJSON = vireo.eggShell.readJSON(viName, path); + var valueRef = vireo.eggShell.findValueRef(viName, path); + var oldValJSON = vireo.eggShell.readJSON(valueRef); var oldValActual = JSON.parse(oldValJSON); expect(oldValActual).toMatchIEEE754Number(oldVal); @@ -26,7 +27,8 @@ describe('The Vireo EggShell writeJSON api can write', function () { vireo.eggShell.writeJSON(viName, path, newValToWriteJSON); - var newValJSON = vireo.eggShell.readJSON(viName, path); + var newValueRef = vireo.eggShell.findValueRef(viName, path); + var newValJSON = vireo.eggShell.readJSON(newValueRef); var newValActual = JSON.parse(newValJSON); if (typeof newValActual === 'string' && typeof newVal === 'number') { // we're writing as a JS number, but reading always returns a string. @@ -36,7 +38,8 @@ describe('The Vireo EggShell writeJSON api can write', function () { } vireo.eggShell.writeJSON(viName, path, oldValJSON); - var oldValRewriteJSON = vireo.eggShell.readJSON(viName, path); + var newNewValueRef = vireo.eggShell.findValueRef(viName, path); + var oldValRewriteJSON = vireo.eggShell.readJSON(newNewValueRef); var oldValRewrite = JSON.parse(oldValRewriteJSON); expect(oldValRewrite).toMatchIEEE754Number(oldVal); }; diff --git a/test-it/karma/utilities/TestHelpers.VireoRunner.js b/test-it/karma/utilities/TestHelpers.VireoRunner.js index 88d3eb567..7ea377256 100644 --- a/test-it/karma/utilities/TestHelpers.VireoRunner.js +++ b/test-it/karma/utilities/TestHelpers.VireoRunner.js @@ -51,7 +51,8 @@ var createVIPathParser = function (vireo, viName) { return function (path) { - return JSON.parse(vireo.eggShell.readJSON(viName, path)); + var valueRef = vireo.eggShell.findValueRef(viName, path); + return JSON.parse(vireo.eggShell.readJSON(valueRef)); }; }; From f816bcbc5dfccdaad21257abf76a1e64e0ac6122 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Le=C3=B3n?= Date: Tue, 26 Jun 2018 18:12:08 -0500 Subject: [PATCH 45/67] Deleted HelloNode.js We now have tests for FPSync and extensive coverage for readJSON and writeJSON. --- test-it/HelloNode.js | 79 -------------------------------------------- 1 file changed, 79 deletions(-) delete mode 100644 test-it/HelloNode.js diff --git a/test-it/HelloNode.js b/test-it/HelloNode.js deleted file mode 100644 index 593b485f1..000000000 --- a/test-it/HelloNode.js +++ /dev/null @@ -1,79 +0,0 @@ -(function () { - 'use strict'; - var Vireo = require('../'); - - var vireo = new Vireo(); - var text = - 'define(c0 dv(.String "wubbalubbadubdub"))\n' + - 'define(HelloWorld dv(.VirtualInstrument (\n' + - 'Locals: c(' + - 'e(dv(.String "Hello, world. I can fly.") variable1)' + - ')\n' + - 'clump (' + - 'Println(variable1)' + - 'FPSync(c0)' + - ')' + - ') ) )\n' + - 'enqueue(HelloWorld)\n'; - - var currFPID = ''; - - vireo.coreHelpers.setFPSyncFunction(function (fpId) { - currFPID = 'fpsync called with (' + fpId + ')'; - }); - - vireo.eggShell.loadVia(text); - vireo.eggShell.executeSlicesUntilWait(); - - var testResult = false; - var testString = ''; - var preTestString = ''; - - console.log('test1'); - testString = 'fpsync called with (wubbalubbadubdub)'; - testResult = currFPID === testString; - console.assert(testResult, 'FPSync function called from vireo and passes value 90'); - - console.log('test2'); - testString = 'Hello, world. I can fly.'; - testResult = JSON.parse(vireo.eggShell.readJSON('HelloWorld', 'variable1')) === testString; - console.assert(testResult, 'Read a value after execution is done'); - - console.log('test3'); - testString = 'Hello, world. I can fly.你好世界。我能飛。'; - vireo.eggShell.writeJSON('HelloWorld', 'variable1', JSON.stringify(testString)); - testResult = JSON.parse(vireo.eggShell.readJSON('HelloWorld', 'variable1')) === testString; - console.assert(testResult, 'Read a value with unicode characters'); - - console.log('test4'); - testString = 'May it be a good Day!'; - vireo.eggShell.writeJSON('HelloWorld', 'variable1', JSON.stringify(testString)); - testResult = JSON.parse(vireo.eggShell.readJSON('HelloWorld', 'variable1')) === testString; - console.assert(testResult, 'Write a value and get it back'); - - console.log('test5'); - testString = 'multi\nline with \'single\' and "double" quotes'; - vireo.eggShell.writeJSON('HelloWorld', 'variable1', JSON.stringify(testString)); - testResult = JSON.parse(vireo.eggShell.readJSON('HelloWorld', 'variable1')) === testString; - console.assert(testResult, 'Write some special characters'); - - console.log('test6'); - preTestString = 'multi\nline with \'single\' and "double" quotes'; - vireo.eggShell.writeJSON('HelloWorld', 'variable1', JSON.stringify(preTestString)); - console.assert(JSON.parse(vireo.eggShell.readJSON('HelloWorld', 'variable1')) === preTestString, 'The initial valid JSON is written'); - testString = 'Buenas Dias'; - vireo.eggShell.writeJSON('HelloWorld', 'variable1', testString); // JSON.stringify intentionally left off - testResult = JSON.parse(vireo.eggShell.readJSON('HelloWorld', 'variable1')) === preTestString; - console.assert(testResult, 'Write string that is not in JSON format is ignored'); - - console.log('test7'); - preTestString = 'multi\nline with \'single\' and "double" quotes'; - vireo.eggShell.writeJSON('HelloWorld', 'variable1', JSON.stringify(preTestString)); - console.assert(JSON.parse(vireo.eggShell.readJSON('HelloWorld', 'variable1')) === preTestString, 'The initial valid JSON is written'); - testString = 'Buenas Dias'; - vireo.eggShell.writeJSON('HelloWorld', 'variable1', JSON.stringify(testString)); // JSON.stringify intentionally added - testResult = JSON.parse(vireo.eggShell.readJSON('HelloWorld', 'variable1')) === testString; - console.assert(testResult, 'Write string that has been fixed'); - - console.log('test end'); -}()); From 4282813875d0a8b3be6604809af1ae3bbc9cc99e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Le=C3=B3n?= Date: Wed, 27 Jun 2018 17:18:20 -0500 Subject: [PATCH 46/67] Added UnableToParseData to eggShellResultEnum --- source/core/CEntryPoints.cpp | 21 ++++++++++----------- source/include/CEntryPoints.h | 4 ++-- source/io/module_eggShell.js | 24 +++++++++++++++++++----- 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/source/core/CEntryPoints.cpp b/source/core/CEntryPoints.cpp index c70bffb0d..eb79c6196 100644 --- a/source/core/CEntryPoints.cpp +++ b/source/core/CEntryPoints.cpp @@ -169,25 +169,24 @@ VIREO_EXPORT NIError EggShell_ReadDouble(TypeManagerRef tm, const TypeRef actual } //------------------------------------------------------------ // Write a string value to a symbol. Value will be parsed according to format designated. -VIREO_EXPORT void EggShell_WriteValueString(TypeManagerRef tm, - const char* viName, const char* eltName, const char* format, const char* value) +VIREO_EXPORT EggShellResult EggShell_WriteValueString(TypeManagerRef tm, TypeRef typeRef, void* data, const char* format, const char* value) { TypeManagerScope scope(tm); - void *pData = nullptr; - - SubString objectName(viName); - SubString path(eltName); SubString valueString(value); - TypeRef actualType = tm->GetObjectElementAddressFromPath(&objectName, &path, &pData, true); - if (actualType == nullptr) - return; + if (typeRef == nullptr || !typeRef->IsValid()) + return kEggShellResult_InvalidTypeRef; EventLog log(EventLog::DevNull); SubString formatss(format); TDViaParser parser(tm, &valueString, &log, 1, &formatss, true, true, true); - parser.ParseData(actualType, pData); + Int32 error = parser.ParseData(typeRef, data); + if (error) { + return kEggSehllResult_UnableToParseData; + } + + return kEggShellResult_Success; } //------------------------------------------------------------ //! Read a symbol's value as a string. Value will be formatted according to the format designated. @@ -195,7 +194,7 @@ VIREO_EXPORT EggShellResult EggShell_ReadValueString(TypeManagerRef tm, TypeRef { TypeManagerScope scope(tm); - if (typeRef == null || !typeRef->IsValid()) + if (typeRef == nullptr || !typeRef->IsValid()) return kEggShellResult_InvalidTypeRef; static StringRef returnBuffer = nullptr; diff --git a/source/include/CEntryPoints.h b/source/include/CEntryPoints.h index 845d5b0a3..4b98d29ea 100644 --- a/source/include/CEntryPoints.h +++ b/source/include/CEntryPoints.h @@ -23,6 +23,7 @@ typedef enum { kEggShellResult_UnableToCreateReturnBuffer = 4, kEggShellResult_InvalidTypeRef = 5, kEggShellResult_MismatchedArrayRank = 6, + kEggSehllResult_UnableToParseData = 7, } EggShellResult; //------------------------------------------------------------ //! TypeManager functions @@ -41,8 +42,7 @@ VIREO_EXPORT EggShellResult EggShell_FindValue(TypeManagerRef tm, const char* vi VIREO_EXPORT EggShellResult EggShell_FindSubValue(TypeManagerRef tm, TypeRef type, const char* eltName, TypeRef* typeRefLocation, void** dataRefLocation); VIREO_EXPORT void EggShell_WriteDouble(TypeManagerRef tm, const char* viName, const char* eltName, Double d); VIREO_EXPORT NIError EggShell_ReadDouble(TypeManagerRef tm, const TypeRef actualType, const void* pData, Double* result); -VIREO_EXPORT void EggShell_WriteValueString(TypeManagerRef tm, const char* viName, const char* eltName, - const char* format, const char* value); +VIREO_EXPORT EggShellResult EggShell_WriteValueString(TypeManagerRef tm, TypeRef typeRef, void* data, const char* format, const char* value); VIREO_EXPORT EggShellResult EggShell_ReadValueString(TypeManagerRef tm, TypeRef typeRef, void* pData, const char* format, UInt8** valueString); VIREO_EXPORT EggShellResult EggShell_GetPointer(TypeManagerRef tm, const char* viName, const char* elementName, void** dataPointer, void** typePointer); diff --git a/source/io/module_eggShell.js b/source/io/module_eggShell.js index 4824e5cb5..ee64437a5 100644 --- a/source/io/module_eggShell.js +++ b/source/io/module_eggShell.js @@ -33,7 +33,6 @@ 'EggShell_Create', 'EggShell_Delete', 'EggShell_WriteDouble', - 'EggShell_WriteValueString', 'EggShell_GetPointer', 'EggShell_GetArrayDimLength', 'Data_ValidateArrayType', @@ -85,7 +84,8 @@ INVALID_RESULT_POINTER: 3, UNABLE_TO_CREATE_RETURN_BUFFER: 4, INVALID_TYPE_REF: 5, - MISMATCHED_ARRAY_RANK: 6 + MISMATCHED_ARRAY_RANK: 6, + UNABLE_TO_PARSE_DATA: 7 }; var eggShellResultEnum = {}; eggShellResultEnum[EGGSHELL_RESULT.SUCCESS] = 'Success'; @@ -95,6 +95,7 @@ eggShellResultEnum[EGGSHELL_RESULT.UNABLE_TO_CREATE_RETURN_BUFFER] = 'UnableToCreateReturnBuffer'; eggShellResultEnum[EGGSHELL_RESULT.INVALID_TYPE_REF] = 'InvalidTypeRef'; eggShellResultEnum[EGGSHELL_RESULT.MISMATCHED_ARRAY_RANK] = 'MismatchedArrayRank'; + eggShellResultEnum[EGGSHELL_RESULT.UNABLE_TO_PARSE_DATA] = 'UnableToParseData'; // Keep in sync with NIError in DataTypes.h var niErrorEnum = { @@ -113,7 +114,6 @@ var EggShell_Create = Module.cwrap('EggShell_Create', 'number', ['number']); var EggShell_Delete = Module.cwrap('EggShell_Delete', 'number', ['number']); var EggShell_WriteDouble = Module.cwrap('EggShell_WriteDouble', 'void', ['number', 'string', 'string', 'number']); - var EggShell_WriteValueString = Module.cwrap('EggShell_WriteValueString', 'void', ['number', 'string', 'string', 'string', 'string']); var EggShell_GetPointer = Module.cwrap('EggShell_GetPointer', 'number', ['number', 'string', 'string', 'number', 'number']); var EggShell_GetArrayDimLength = Module.cwrap('EggShell_GetArrayDimLength', 'number', ['number', 'string', 'string', 'number']); var Data_ValidateArrayType = Module.cwrap('Data_ValidateArrayType', 'number', ['number', 'number']); @@ -339,8 +339,22 @@ return response; }; - Module.eggShell.writeJSON = publicAPI.eggShell.writeJSON = function (vi, path, value) { - EggShell_WriteValueString(Module.eggShell.v_userShell, vi, path, 'JSON', value); + Module.eggShell.writeJSON = publicAPI.eggShell.writeJSON = function (valueRef, value) { + var stack = Module.stackSave(); + + var type = 'JSON'; + var valueStackPointer = Module.coreHelpers.writeJSStringToHeap(value); + var typeStackPointer = Module.coreHelpers.writeJSStringToStack(type); + + var eggShellError = Module._EggShell_WriteValueString(Module.eggShell.v_userShell, valueRef.typeRef, valueRef.dataRef, typeStackPointer, valueStackPointer); + if (eggShellError !== 0) { + throw new Error('Performing writeJSON failed for the following reason: ' + eggShellResultEnum[eggShellError] + + ' (error code: ' + eggShellError + ')' + + ' (typeRef: ' + valueRef.typeRef + ')' + + ' (dataRef: ' + valueRef.dataRef + ')'); + } + + Module.stackRestore(stack); }; var supportedArrayTypeConfig = { From b324a8d198dc9785b6294bf5c5240181facb28ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Le=C3=B3n?= Date: Tue, 26 Jun 2018 19:04:28 -0500 Subject: [PATCH 47/67] Fixed tests for new writeJSON API. There are still a few tests failing we need to address. --- .../karma/publicapi/ExecuteSlicesUntilClumpsFinshed.Test.js | 6 ++++-- test-it/karma/publicapi/WriteJson.Test.js | 4 ++-- test-it/karma/utilities/TestHelpers.VireoRunner.js | 6 ++++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/test-it/karma/publicapi/ExecuteSlicesUntilClumpsFinshed.Test.js b/test-it/karma/publicapi/ExecuteSlicesUntilClumpsFinshed.Test.js index c00d13c5a..376cba95a 100644 --- a/test-it/karma/publicapi/ExecuteSlicesUntilClumpsFinshed.Test.js +++ b/test-it/karma/publicapi/ExecuteSlicesUntilClumpsFinshed.Test.js @@ -56,7 +56,8 @@ describe('The Vireo EggShell executeSlicesUntilClumpsFinished api', function () vireo.eggShell.loadVia(viaCode); var maxExecWakeUpTime = vireo.eggShell.maxExecWakeUpTime(); var numIterations = 100; - vireo.eggShell.writeJSON('MyVI', 'numIterations', JSON.stringify(numIterations)); + var valueRef = vireo.eggShell.findValueRef('MyVI', 'numIterations'); + vireo.eggShell.writeJSON(valueRef, JSON.stringify(numIterations)); var maxTimewithBuffer = maxExecWakeUpTime * numIterations * 0.5; @@ -87,7 +88,8 @@ describe('The Vireo EggShell executeSlicesUntilClumpsFinished api', function () var maxExecWakeUpTime = vireo.eggShell.maxExecWakeUpTime(); var maxExecuteSlicesCalls = 20; var waitTime = maxExecuteSlicesCalls * maxExecWakeUpTime; - vireo.eggShell.writeJSON('MyVI', 'waitTime', JSON.stringify(waitTime)); + var valueRef = vireo.eggShell.findValueRef('MyVI', 'waitTime'); + vireo.eggShell.writeJSON(valueRef, JSON.stringify(waitTime)); var internalModule = vireo.eggShell.internal_module_do_not_use_or_you_will_be_fired; spyOn(internalModule.eggShell, 'executeSlicesUntilWait').and.callThrough(); diff --git a/test-it/karma/publicapi/WriteJson.Test.js b/test-it/karma/publicapi/WriteJson.Test.js index cff7a843b..c2b2e1b53 100644 --- a/test-it/karma/publicapi/WriteJson.Test.js +++ b/test-it/karma/publicapi/WriteJson.Test.js @@ -25,7 +25,7 @@ describe('The Vireo EggShell writeJSON api can write', function () { return value; }); - vireo.eggShell.writeJSON(viName, path, newValToWriteJSON); + vireo.eggShell.writeJSON(valueRef, newValToWriteJSON); var newValueRef = vireo.eggShell.findValueRef(viName, path); var newValJSON = vireo.eggShell.readJSON(newValueRef); @@ -37,7 +37,7 @@ describe('The Vireo EggShell writeJSON api can write', function () { expect(newValActual).toMatchIEEE754Number(newVal); } - vireo.eggShell.writeJSON(viName, path, oldValJSON); + vireo.eggShell.writeJSON(valueRef, oldValJSON); var newNewValueRef = vireo.eggShell.findValueRef(viName, path); var oldValRewriteJSON = vireo.eggShell.readJSON(newNewValueRef); var oldValRewrite = JSON.parse(oldValRewriteJSON); diff --git a/test-it/karma/utilities/TestHelpers.VireoRunner.js b/test-it/karma/utilities/TestHelpers.VireoRunner.js index 7ea377256..c076bc16f 100644 --- a/test-it/karma/utilities/TestHelpers.VireoRunner.js +++ b/test-it/karma/utilities/TestHelpers.VireoRunner.js @@ -52,13 +52,15 @@ var createVIPathParser = function (vireo, viName) { return function (path) { var valueRef = vireo.eggShell.findValueRef(viName, path); - return JSON.parse(vireo.eggShell.readJSON(valueRef)); + var json = vireo.eggShell.readJSON(valueRef); + return JSON.parse(json); }; }; var createVIPathWriter = function (vireo, viName) { return function (path, value) { - vireo.eggShell.writeJSON(viName, path, JSON.stringify(value)); + var valueRef = vireo.eggShell.findValueRef(viName, path); + vireo.eggShell.writeJSON(valueRef, JSON.stringify(value)); }; }; From 44724a8652de361ac6f9769b8b648e91c2bef8f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Le=C3=B3n?= Date: Wed, 27 Jun 2018 16:55:53 -0500 Subject: [PATCH 48/67] Fixed remaining broken tests Added const to TypeRef in EggShell_[Write|Read]ValueString too. --- source/core/CEntryPoints.cpp | 4 ++-- test-it/karma/propertynode/PropertyNode.Test.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/core/CEntryPoints.cpp b/source/core/CEntryPoints.cpp index eb79c6196..fde7267bd 100644 --- a/source/core/CEntryPoints.cpp +++ b/source/core/CEntryPoints.cpp @@ -169,7 +169,7 @@ VIREO_EXPORT NIError EggShell_ReadDouble(TypeManagerRef tm, const TypeRef actual } //------------------------------------------------------------ // Write a string value to a symbol. Value will be parsed according to format designated. -VIREO_EXPORT EggShellResult EggShell_WriteValueString(TypeManagerRef tm, TypeRef typeRef, void* data, const char* format, const char* value) +VIREO_EXPORT EggShellResult EggShell_WriteValueString(TypeManagerRef tm, const TypeRef typeRef, void* data, const char* format, const char* value) { TypeManagerScope scope(tm); @@ -190,7 +190,7 @@ VIREO_EXPORT EggShellResult EggShell_WriteValueString(TypeManagerRef tm, TypeRef } //------------------------------------------------------------ //! Read a symbol's value as a string. Value will be formatted according to the format designated. -VIREO_EXPORT EggShellResult EggShell_ReadValueString(TypeManagerRef tm, TypeRef typeRef, void* data, const char* format, UInt8** valueString) +VIREO_EXPORT EggShellResult EggShell_ReadValueString(TypeManagerRef tm, const TypeRef typeRef, void* data, const char* format, UInt8** valueString) { TypeManagerScope scope(tm); diff --git a/test-it/karma/propertynode/PropertyNode.Test.js b/test-it/karma/propertynode/PropertyNode.Test.js index a9d9a2c68..b3e1fb2a8 100644 --- a/test-it/karma/propertynode/PropertyNode.Test.js +++ b/test-it/karma/propertynode/PropertyNode.Test.js @@ -136,7 +136,7 @@ describe('The Vireo PropertyNode', function () { fraction: '0' }; var valuesToRead = [true, -123, -4321, -987654321, '-9876543210', 123, 4321, 987654321, '9876543210', - 3.5, 6.28, complexToRead, complexToRead, 'Lorem ipsum', '0:0', 1.618, 3.236, true]; + 3.5, 6.28, complexToRead, complexToRead, 'Lorem ipsum', expectedTimestamp, 1.618, 3.236, true]; var readFunction = generateReadFunction(valuesToRead); vireo.propertyNode.setPropertyReadFunction(readFunction); From a905e1122fd967250e0acd7bd6431dcc854f8d4d Mon Sep 17 00:00:00 2001 From: rajsite Date: Tue, 26 Jun 2018 20:48:33 -0500 Subject: [PATCH 49/67] First pass of writeString --- source/core/module_coreHelpers.js | 75 ++++++++++++++++++++++++++ source/io/module_eggShell.js | 21 ++++++++ test-it/karma/publicapi/String.Test.js | 12 +++++ 3 files changed, 108 insertions(+) diff --git a/source/core/module_coreHelpers.js b/source/core/module_coreHelpers.js index cdcefedb5..36984e590 100644 --- a/source/core/module_coreHelpers.js +++ b/source/core/module_coreHelpers.js @@ -211,6 +211,81 @@ } }; + // Source adapted from https://github.com/kripken/emscripten/blob/bd050e64bb0d9952df1344b8ea9356252328ad83/src/preamble.js#L488 + // Copies the given Javascript String object 'str' to the given byte array at address 'outIdx', + // encoded in UTF8 form. Use the function lengthBytesUTF8 to compute the exact number of bytes (excluding null terminator) that this function will write. + // Parameters: + // str: the Javascript string to copy. + // outU8Array: the array to copy to. Each index in this array is assumed to be one 8-byte element. + // outIdx: The starting offset in the array to begin the copying. + // maxBytesToWrite: The maximum number of bytes this function can write to the array. maxBytesToWrite=0 does not write any bytes to the output. + // Returns the number of bytes written. + Module.coreHelpers.jsStringToSizedUTF8Array = function (str, outU8Array, startIndex, maxBytesToWrite) { + /* eslint-disable no-plusplus, id-length */ + // Parameter maxBytesToWrite is not optional. Negative values, 0, null, undefined and false each don't write out any bytes. + if (!(maxBytesToWrite > 0)) { + return 0; + } + var outIdx = startIndex; + var endIdx = outIdx + maxBytesToWrite; + for (var i = 0; i < str.length; ++i) { + // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! So decode UTF16->UTF32->UTF8. + // See http://unicode.org/faq/utf_bom.html#utf16-3 + // For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description and https://www.ietf.org/rfc/rfc2279.txt and https://tools.ietf.org/html/rfc3629 + var u = str.charCodeAt(i); // possibly a lead surrogate + if (u >= 0xD800 && u <= 0xDFFF) { + u = 0x10000 + ((u & 0x3FF) << 10) | (str.charCodeAt(++i) & 0x3FF); + } + if (u <= 0x7F) { + if (outIdx >= endIdx) { + break; + } + outU8Array[outIdx++] = u; + } else if (u <= 0x7FF) { + if (outIdx + 1 >= endIdx) { + break; + } + outU8Array[outIdx++] = 0xC0 | (u >> 6); + outU8Array[outIdx++] = 0x80 | (u & 63); + } else if (u <= 0xFFFF) { + if (outIdx + 2 >= endIdx) { + break; + } + outU8Array[outIdx++] = 0xE0 | (u >> 12); + outU8Array[outIdx++] = 0x80 | ((u >> 6) & 63); + outU8Array[outIdx++] = 0x80 | (u & 63); + } else if (u <= 0x1FFFFF) { + if (outIdx + 3 >= endIdx) { + break; + } + outU8Array[outIdx++] = 0xF0 | (u >> 18); + outU8Array[outIdx++] = 0x80 | ((u >> 12) & 63); + outU8Array[outIdx++] = 0x80 | ((u >> 6) & 63); + outU8Array[outIdx++] = 0x80 | (u & 63); + } else if (u <= 0x3FFFFFF) { + if (outIdx + 4 >= endIdx) { + break; + } + outU8Array[outIdx++] = 0xF8 | (u >> 24); + outU8Array[outIdx++] = 0x80 | ((u >> 18) & 63); + outU8Array[outIdx++] = 0x80 | ((u >> 12) & 63); + outU8Array[outIdx++] = 0x80 | ((u >> 6) & 63); + outU8Array[outIdx++] = 0x80 | (u & 63); + } else { + if (outIdx + 5 >= endIdx) { + break; + } + outU8Array[outIdx++] = 0xFC | (u >> 30); + outU8Array[outIdx++] = 0x80 | ((u >> 24) & 63); + outU8Array[outIdx++] = 0x80 | ((u >> 18) & 63); + outU8Array[outIdx++] = 0x80 | ((u >> 12) & 63); + outU8Array[outIdx++] = 0x80 | ((u >> 6) & 63); + outU8Array[outIdx++] = 0x80 | (u & 63); + } + } + return outIdx - startIndex; + }; + Module.coreHelpers.jsCurrentBrowserFPS = function () { if (trackingFPS === false) { trackingFPS = true; diff --git a/source/io/module_eggShell.js b/source/io/module_eggShell.js index ee64437a5..998f2bb10 100644 --- a/source/io/module_eggShell.js +++ b/source/io/module_eggShell.js @@ -413,6 +413,27 @@ return result; }; + Module.eggShell.writeString = publicAPI.eggShell.writeString = function (valueRef, inputString) { + if (Module.typeHelpers.isString(valueRef.typeRef) === false) { + throw new Error('Performing writeString failed for the following reason: ' + eggShellResultEnum[EGGSHELL_RESULT.UNEXPECTED_OBJECT_TYPE] + + ' (error code: ' + EGGSHELL_RESULT.UNEXPECTED_OBJECT_TYPE + ')' + + ' (typeRef: ' + valueRef.typeRef + ')' + + ' (dataRef: ' + valueRef.dataRef + ')'); + } + + if (typeof inputString !== 'string') { + throw new Error('Expected string input to be of type string, instead got: ' + inputString); + } + + var strLength = Module.lengthBytesUTF8(inputString); + Module.eggShell.resizeArray(valueRef, [strLength]); + var typedArray = Module.eggShell.readTypedArray(valueRef); + var bytesWritten = Module.coreHelpers.jsStringToSizedUTF8Array(inputString, typedArray, 0, strLength); + if (bytesWritten !== strLength) { + throw new Error('Could not write JS string to memory'); + } + }; + var findCompatibleTypedArrayConstructor = function (typeRef) { var subTypeRef, isSigned, size; // String will go down the Array code path a bit as is so check before array checks diff --git a/test-it/karma/publicapi/String.Test.js b/test-it/karma/publicapi/String.Test.js index b66c20e1e..b72bab7d3 100644 --- a/test-it/karma/publicapi/String.Test.js +++ b/test-it/karma/publicapi/String.Test.js @@ -14,6 +14,10 @@ describe('The Vireo EggShell String api can', function () { return vireo.eggShell.readString(vireo.eggShell.findValueRef(viName, path)); }; + var writeString = function (path, str) { + vireo.eggShell.writeString(vireo.eggShell.findValueRef(viName, path), str); + }; + beforeAll(function (done) { fixtures.preloadAbsoluteUrls([ publicApiMultipleTypesViaUrl @@ -36,4 +40,12 @@ describe('The Vireo EggShell String api can', function () { expect(readStringThrows).toThrowError(/UnexpectedObjectType/); }); }); + + describe('use writeString', function () { + it('to write different string values from memory', function () { + expect(readString('dataItem_String')).toBe('Hello'); + writeString('dataItem_String', 'Iñtërnâtiônàlizætiøn☃💩'); + expect(readString('dataItem_String')).toBe('Iñtërnâtiônàlizætiøn☃💩'); + }); + }); }); From cc225b84bbc74f1aa9f510e8e430fd9768d81631 Mon Sep 17 00:00:00 2001 From: rajsite Date: Wed, 27 Jun 2018 09:45:27 -0500 Subject: [PATCH 50/67] Update comment for jsStringToSizedUTF8Array --- source/core/module_coreHelpers.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/source/core/module_coreHelpers.js b/source/core/module_coreHelpers.js index 36984e590..be07f7905 100644 --- a/source/core/module_coreHelpers.js +++ b/source/core/module_coreHelpers.js @@ -56,6 +56,7 @@ fpSync = fn; }; + // Returns the length of a C string (excluding null terminator) Module.coreHelpers.findCStringLength = function (u8Array, startIndex) { var i, end = u8Array.length; @@ -212,12 +213,12 @@ }; // Source adapted from https://github.com/kripken/emscripten/blob/bd050e64bb0d9952df1344b8ea9356252328ad83/src/preamble.js#L488 - // Copies the given Javascript String object 'str' to the given byte array at address 'outIdx', - // encoded in UTF8 form. Use the function lengthBytesUTF8 to compute the exact number of bytes (excluding null terminator) that this function will write. + // Copies the given Javascript String object 'str' to the given byte array at address 'startIndex' encoded in UTF8 form. + // Use the function lengthBytesUTF8 to compute the exact number of bytes that this function will write. // Parameters: // str: the Javascript string to copy. // outU8Array: the array to copy to. Each index in this array is assumed to be one 8-byte element. - // outIdx: The starting offset in the array to begin the copying. + // startIndex: The starting offset in the array to begin the copying. // maxBytesToWrite: The maximum number of bytes this function can write to the array. maxBytesToWrite=0 does not write any bytes to the output. // Returns the number of bytes written. Module.coreHelpers.jsStringToSizedUTF8Array = function (str, outU8Array, startIndex, maxBytesToWrite) { From d59084d1330e0454435e535f728a13869d901c6e Mon Sep 17 00:00:00 2001 From: rajsite Date: Wed, 27 Jun 2018 19:38:04 -0500 Subject: [PATCH 51/67] Expand readString and writeString tests --- test-it/karma/publicapi/String.Test.js | 210 +++++++++++++++++++++++-- 1 file changed, 200 insertions(+), 10 deletions(-) diff --git a/test-it/karma/publicapi/String.Test.js b/test-it/karma/publicapi/String.Test.js index b72bab7d3..e0c7659df 100644 --- a/test-it/karma/publicapi/String.Test.js +++ b/test-it/karma/publicapi/String.Test.js @@ -14,10 +14,34 @@ describe('The Vireo EggShell String api can', function () { return vireo.eggShell.readString(vireo.eggShell.findValueRef(viName, path)); }; + var tryReadString = function (path) { + return function () { + readString(path); + }; + }; + + var readTest = function (path, result) { + expect(readString(path)).toBe(result); + }; + var writeString = function (path, str) { vireo.eggShell.writeString(vireo.eggShell.findValueRef(viName, path), str); }; + var tryWriteString = function (path, value) { + return function () { + writeString(path, value); + }; + }; + + var writeTest = function (path, initialValue, newValue) { + expect(readString(path)).toBe(initialValue); + writeString(path, newValue); + expect(readString(path)).toBe(newValue); + writeString(path, initialValue); + expect(readString(path)).toBe(initialValue); + }; + beforeAll(function (done) { fixtures.preloadAbsoluteUrls([ publicApiMultipleTypesViaUrl @@ -29,23 +53,189 @@ describe('The Vireo EggShell String api can', function () { }); describe('use readString', function () { - it('to read different string values from memory', function () { - expect(readString('dataItem_String')).toBe('Hello'); + it('to throw on unsupported types', function () { + expect(tryReadString('dataItem_NumericDouble')).toThrowError(/UnexpectedObjectType/); }); - it('to throw on unsupported types', function () { - var readStringThrows = function () { - readString('dataItem_NumericDouble'); - }; - expect(readStringThrows).toThrowError(/UnexpectedObjectType/); + it('String', function () { + readTest('dataItem_String', 'Hello'); + }); + + it('String Control Characters', function () { + readTest('dataItem_StringControlCharacters', + '\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u0009\u000A\u000B\u000C\u000D\u000E\u000F\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001A\u001B\u001C\u001D\u001E\u001F' + ); + }); + + it('String Other JSON Escaped Characters', function () { + readTest('dataItem_StringOtherJSONEscapedCharacters', + '\\"' + ); + }); + + it('String UTF-8 sequence ranges', function () { + readTest('dataItem_utf8sequence_firstinsequence1byte', + '\x00' + ); + readTest('dataItem_utf8sequence_firstinsequence2byte', + '\u0080' + ); + readTest('dataItem_utf8sequence_firstinsequence3byte', + '\u0800' + ); + readTest('dataItem_utf8sequence_firstinsequence4byte', + '\uD800\uDC00' + ); + readTest('dataItem_utf8sequence_firstinsequence5byte', + '\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD' + ); + readTest('dataItem_utf8sequence_lastinsequence1byte', + '\u007F' + ); + readTest('dataItem_utf8sequence_lastinsequence2byte', + '\u07FF' + ); + readTest('dataItem_utf8sequence_lastinsequence3byte', + '\uFFFF' + ); + readTest('dataItem_utf8sequence_lastinsequence4byte_lastvalidunicode', + '\uDBFF\uDFFF' + ); + readTest('dataItem_utf8sequence_lastinsequence4byte_firsthighinvalidutf8', + '\uFFFD\uFFFD\uFFFD\uFFFD' + ); + readTest('dataItem_utf8sequence_lastinsequence4byte_lasthighinvalidutf8', + '\uFFFD\uFFFD\uFFFD\uFFFD' + ); + }); + + it('String UTF-8 around surrogate border', function () { + readTest('dataItem_utf8sequence_lastbeforesurrogate', + '\uD7FF' + ); + readTest('dataItem_utf8sequence_firstinsurrogate', + '\uD800' + ); + readTest('dataItem_utf8sequence_lastinsurrogate', + '\uDFFF' + ); + readTest('dataItem_utf8sequence_firstaftersurrogate', + '\uE000' + ); + }); + + it('Invalid continuation bytes', function () { + readTest('dataItem_utf8sequence_firstcontinuationbyte', + '\uFFFD' + ); + readTest('dataItem_utf8sequence_lastcontinuationbyte', + '\uFFFD' + ); + readTest('dataItem_utf8sequence_2continuationbytes', + '\uFFFD\uFFFD' + ); + readTest('dataItem_utf8sequence_3continuationbytes', + '\uFFFD\uFFFD\uFFFD' + ); + readTest('dataItem_utf8sequence_4continuationbytes', + '\uFFFD\uFFFD\uFFFD\uFFFD' + ); + readTest('dataItem_utf8sequence_5continuationbytes', + '\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD' + ); + readTest('dataItem_utf8sequence_6continuationbytes', + '\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD' + ); + readTest('dataItem_utf8sequence_7continuationbytes', + '\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD' + ); + readTest('dataItem_utf8sequence_allcontinuationbytes', + Array(65).join('\uFFFD') + ); + }); + + it('Invalid start bytes', function () { + readTest('dataItem_utf8sequence_allstartbytesfor2bytes', + Array(33).join('\uFFFD ').trim() + ); + readTest('dataItem_utf8sequence_allstartbytesfor3bytes', + Array(17).join('\uFFFD ').trim() + ); + readTest('dataItem_utf8sequence_allstartbytesfor4bytes', + Array(9).join('\uFFFD ').trim() + ); + readTest('dataItem_utf8sequence_allstartbytesfor5bytes', + Array(5).join('\uFFFD ').trim() + ); + readTest('dataItem_utf8sequence_allstartbytesfor6bytes', + Array(3).join('\uFFFD ').trim() + ); + }); + + it('Missing last byte in sequence', function () { + readTest('dataItem_utf8sequence_2bytesequencewithlastbytemissing', + '\uFFFD' + ); + readTest('dataItem_utf8sequence_3bytesequencewithlastbytemissing', + '\uFFFD\uFFFD' + ); + readTest('dataItem_utf8sequence_4bytesequencewithlastbytemissing', + '\uFFFD\uFFFD\uFFFD' + ); + readTest('dataItem_utf8sequence_concatenatedtruncatedsequences', + '\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD' + ); + }); + + it('Impossible UTF-8 sequences', function () { + readTest('dataItem_utf8sequence_impossible1', + '\uFFFD' + ); + readTest('dataItem_utf8sequence_impossible2', + '\uFFFD' + ); + readTest('dataItem_utf8sequence_impossible3', + '\uFFFD\uFFFD\uFFFD\uFFFD' + ); + }); + + it('Overlong UTF-8 sequences', function () { + readTest('dataItem_utf8sequence_overlongnull2byte', + '\uFFFD\uFFFD' + ); + readTest('dataItem_utf8sequence_overlongnull3byte', + '\uFFFD\uFFFD\uFFFD' + ); + readTest('dataItem_utf8sequence_overlongnull4byte', + '\uFFFD\uFFFD\uFFFD\uFFFD' + ); + readTest('dataItem_utf8sequence_overlonglargest2byte', + '\uFFFD\uFFFD' + ); + readTest('dataItem_utf8sequence_overlonglargest3byte', + '\uFFFD\uFFFD\uFFFD' + ); + readTest('dataItem_utf8sequence_overlonglargest4byte', + '\uFFFD\uFFFD\uFFFD\uFFFD' + ); }); }); describe('use writeString', function () { + it('to throw on unsupported types', function () { + expect(tryWriteString('dataItem_NumericDouble', 'Test')).toThrowError(/UnexpectedObjectType/); + expect(tryWriteString('dataItem_String', 42)).toThrowError(/type string/); + }); + it('to write different string values from memory', function () { - expect(readString('dataItem_String')).toBe('Hello'); - writeString('dataItem_String', 'Iñtërnâtiônàlizætiøn☃💩'); - expect(readString('dataItem_String')).toBe('Iñtërnâtiônàlizætiøn☃💩'); + writeTest('dataItem_String', 'Hello', 'Hello World! :D'); + writeTest('dataItem_String', 'Hello', 'Iñtërnâtiônàlizætiøn☃💩'); + }); + + it('String Control Characters', function () { + writeTest('dataItem_String', 'Hello', + '\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u0009\u000A\u000B\u000C\u000D\u000E\u000F\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001A\u001B\u001C\u001D\u001E\u001F' + ); }); }); }); From b14bda84990b453c8def50005f3d4490fde1b271 Mon Sep 17 00:00:00 2001 From: rajsite Date: Wed, 27 Jun 2018 20:52:25 -0500 Subject: [PATCH 52/67] First pass writeDouble api --- source/core/CEntryPoints.cpp | 20 ++++++------ source/core/TypeAndDataManager.cpp | 2 +- source/include/CEntryPoints.h | 2 +- source/include/TypeAndDataManager.h | 2 +- source/io/module_eggShell.js | 16 ++++++--- test-it/karma/publicapi/Double.Test.js | 45 +++++++++++++++++++++----- 6 files changed, 62 insertions(+), 25 deletions(-) diff --git a/source/core/CEntryPoints.cpp b/source/core/CEntryPoints.cpp index fde7267bd..0b32de7c1 100644 --- a/source/core/CEntryPoints.cpp +++ b/source/core/CEntryPoints.cpp @@ -147,17 +147,17 @@ VIREO_EXPORT EggShellResult EggShell_FindSubValue(TypeManagerRef tm, TypeRef typ } //------------------------------------------------------------ //! Write a numeric value to a symbol. Value will be coerced as needed. -VIREO_EXPORT void EggShell_WriteDouble(TypeManagerRef tm, const char* viName, const char* eltName, Double d) +VIREO_EXPORT EggShellResult EggShell_WriteDouble(TypeManagerRef tm, const TypeRef actualType, void* pData, Double value) { - void *pData = nullptr; - - SubString objectName(viName); - SubString path(eltName); - TypeRef actualType = tm->GetObjectElementAddressFromPath(&objectName, &path, &pData, true); - if (actualType == nullptr) - return; - - WriteDoubleToMemory(actualType, pData, d); + TypeManagerScope scope(tm); + if (actualType == nullptr || !actualType->IsValid()) { + return kEggShellResult_InvalidTypeRef; + } + NIError error = WriteDoubleToMemory(actualType, pData, value); + if (error) { + return kEggShellResult_UnexpectedObjectType; // TODO(mraj) use memos new error + } + return kEggShellResult_Success; } //------------------------------------------------------------ //! Read a numeric value from a symbol. Value will be coerced as needed. diff --git a/source/core/TypeAndDataManager.cpp b/source/core/TypeAndDataManager.cpp index f0fe6781c..387c442a5 100644 --- a/source/core/TypeAndDataManager.cpp +++ b/source/core/TypeAndDataManager.cpp @@ -2761,7 +2761,7 @@ Double ReadDoubleFromMemory(TypeRef type, const void* pData, NIError* errResult) } //------------------------------------------------------------ //! Write a IEEE754 double value to memory converting as necessary. -NIError WriteDoubleToMemory(TypeRef type, void* pData, Double value) +NIError WriteDoubleToMemory(TypeRef type, void* pData, const Double value) { NIError err = kNIError_Success; EncodingEnum encoding = type->BitEncoding(); diff --git a/source/include/CEntryPoints.h b/source/include/CEntryPoints.h index 4b98d29ea..2698756d7 100644 --- a/source/include/CEntryPoints.h +++ b/source/include/CEntryPoints.h @@ -40,7 +40,7 @@ VIREO_EXPORT Int32 EggShell_PokeMemory(TypeManagerRef tm, const char* viName, co Int32 bufferSize, char* buffer); VIREO_EXPORT EggShellResult EggShell_FindValue(TypeManagerRef tm, const char* viName, const char* eltName, TypeRef* typeRefLocation, void** dataRefLocation); VIREO_EXPORT EggShellResult EggShell_FindSubValue(TypeManagerRef tm, TypeRef type, const char* eltName, TypeRef* typeRefLocation, void** dataRefLocation); -VIREO_EXPORT void EggShell_WriteDouble(TypeManagerRef tm, const char* viName, const char* eltName, Double d); +VIREO_EXPORT EggShellResult EggShell_WriteDouble(TypeManagerRef tm, const TypeRef actualType, void* pData, Double value); VIREO_EXPORT NIError EggShell_ReadDouble(TypeManagerRef tm, const TypeRef actualType, const void* pData, Double* result); VIREO_EXPORT EggShellResult EggShell_WriteValueString(TypeManagerRef tm, TypeRef typeRef, void* data, const char* format, const char* value); VIREO_EXPORT EggShellResult EggShell_ReadValueString(TypeManagerRef tm, TypeRef typeRef, void* pData, const char* format, UInt8** valueString); diff --git a/source/include/TypeAndDataManager.h b/source/include/TypeAndDataManager.h index f5b751579..138b52465 100644 --- a/source/include/TypeAndDataManager.h +++ b/source/include/TypeAndDataManager.h @@ -348,7 +348,7 @@ class TypeManager IntMax ReadIntFromMemory(TypeRef type, void* pData); NIError WriteIntToMemory(TypeRef type, void* pData, IntMax value); Double ReadDoubleFromMemory(TypeRef type, const void* pData, NIError* errResult = nullptr); -NIError WriteDoubleToMemory(TypeRef type, void* pData, Double value); +NIError WriteDoubleToMemory(TypeRef type, void* pData, const Double value); IntMax ConvertNumericRange(EncodingEnum encoding, Int32 size, IntMax input); //------------------------------------------------------------ //! Banker's rounding for Doubles. diff --git a/source/io/module_eggShell.js b/source/io/module_eggShell.js index 998f2bb10..075e3db50 100644 --- a/source/io/module_eggShell.js +++ b/source/io/module_eggShell.js @@ -32,7 +32,6 @@ 'Vireo_MaxExecWakeUpTime', 'EggShell_Create', 'EggShell_Delete', - 'EggShell_WriteDouble', 'EggShell_GetPointer', 'EggShell_GetArrayDimLength', 'Data_ValidateArrayType', @@ -113,7 +112,6 @@ var Vireo_MaxExecWakeUpTime = Module.cwrap('Vireo_MaxExecWakeUpTime', 'number', []); var EggShell_Create = Module.cwrap('EggShell_Create', 'number', ['number']); var EggShell_Delete = Module.cwrap('EggShell_Delete', 'number', ['number']); - var EggShell_WriteDouble = Module.cwrap('EggShell_WriteDouble', 'void', ['number', 'string', 'string', 'number']); var EggShell_GetPointer = Module.cwrap('EggShell_GetPointer', 'number', ['number', 'string', 'string', 'number', 'number']); var EggShell_GetArrayDimLength = Module.cwrap('EggShell_GetArrayDimLength', 'number', ['number', 'string', 'string', 'number']); var Data_ValidateArrayType = Module.cwrap('Data_ValidateArrayType', 'number', ['number', 'number']); @@ -311,8 +309,18 @@ return result; }; - Module.eggShell.writeDouble = publicAPI.eggShell.writeDouble = function (vi, path, value) { - EggShell_WriteDouble(Module.eggShell.v_userShell, vi, path, value); + Module.eggShell.writeDouble = publicAPI.eggShell.writeDouble = function (valueRef, value) { + if (typeof value !== 'number') { + throw new Error('Expected value to write to be of type number, instead got: ' + value); + } + + var eggShellResult = Module._EggShell_WriteDouble(Module.eggShell.v_userShell, valueRef.typeRef, valueRef.dataRef, value); + if (eggShellResult !== 0) { + throw new Error('Could not run writeDouble for the following reason: ' + eggShellResultEnum[eggShellResult] + + ' (error code: ' + eggShellResult + ')' + + ' (typeRef: ' + valueRef.typeRef + ')' + + ' (dataRef: ' + valueRef.dataRef + ')'); + } }; Module.eggShell.readJSON = publicAPI.eggShell.readJSON = function (valueRef) { diff --git a/test-it/karma/publicapi/Double.Test.js b/test-it/karma/publicapi/Double.Test.js index 9d4001d3c..17f0295ec 100644 --- a/test-it/karma/publicapi/Double.Test.js +++ b/test-it/karma/publicapi/Double.Test.js @@ -14,6 +14,30 @@ describe('The Vireo EggShell Double api can', function () { return vireo.eggShell.readDouble(vireo.eggShell.findValueRef(viName, path)); }; + var tryReadDouble = function (path) { + return function () { + readDouble(path); + }; + }; + + var writeDouble = function (path, value) { + vireo.eggShell.writeDouble(vireo.eggShell.findValueRef(viName, path), value); + }; + + var tryWriteDouble = function (path, value) { + return function () { + writeDouble(path, value); + }; + }; + + var testWriteDouble = function (path, initialValue, newValue) { + expect(readDouble(path)).toBe(initialValue); + writeDouble(path, newValue); + expect(readDouble(path)).toBe(newValue); + writeDouble(path, initialValue); + expect(readDouble(path)).toBe(initialValue); + }; + beforeAll(function (done) { fixtures.preloadAbsoluteUrls([ publicApiMultipleTypesViaUrl @@ -74,14 +98,19 @@ describe('The Vireo EggShell Double api can', function () { }); it('to error for unsupported types', function () { - var unsupportedTypeCheck = function (path) { - return function () { - readDouble(path); - }; - }; - - expect(unsupportedTypeCheck('dataItem_Complex')).toThrowError(/CantDecode/); - expect(unsupportedTypeCheck('dataItem_String')).toThrowError(/CantDecode/); + expect(tryReadDouble('dataItem_Complex')).toThrowError(/CantDecode/); + expect(tryReadDouble('dataItem_String')).toThrowError(/CantDecode/); + }); + }); + + describe('use writeDouble', function () { + it('to write double values to memory', function () { + testWriteDouble('dataItem_NumericDouble', 123.456, 42); + }); + + it('to error for unsupported types', function () { + expect(tryWriteDouble('dataItem_Complex', 42)).toThrowError(/UnexpectedObjectType/); + expect(tryWriteDouble('dataItem_String', 42)).toThrowError(/UnexpectedObjectType/); }); }); }); From 5eb6d594f6522ea1d78fc61573e946b43bfaf20a Mon Sep 17 00:00:00 2001 From: rajsite Date: Thu, 28 Jun 2018 16:29:17 -0500 Subject: [PATCH 53/67] Expand writeDouble tests and use EggShellResult --- source/core/CEntryPoints.cpp | 41 ++++++------ source/include/CEntryPoints.h | 2 +- source/io/module_eggShell.js | 16 ++--- test-it/karma/publicapi/Double.Test.js | 88 ++++++++++++++++++++++++-- 4 files changed, 115 insertions(+), 32 deletions(-) diff --git a/source/core/CEntryPoints.cpp b/source/core/CEntryPoints.cpp index 0b32de7c1..42bc35ec7 100644 --- a/source/core/CEntryPoints.cpp +++ b/source/core/CEntryPoints.cpp @@ -147,25 +147,33 @@ VIREO_EXPORT EggShellResult EggShell_FindSubValue(TypeManagerRef tm, TypeRef typ } //------------------------------------------------------------ //! Write a numeric value to a symbol. Value will be coerced as needed. -VIREO_EXPORT EggShellResult EggShell_WriteDouble(TypeManagerRef tm, const TypeRef actualType, void* pData, Double value) +VIREO_EXPORT EggShellResult EggShell_WriteDouble(TypeManagerRef tm, const TypeRef typeRef, void* pData, Double value) { TypeManagerScope scope(tm); - if (actualType == nullptr || !actualType->IsValid()) { + if (typeRef == nullptr || !typeRef->IsValid()) return kEggShellResult_InvalidTypeRef; - } - NIError error = WriteDoubleToMemory(actualType, pData, value); - if (error) { - return kEggShellResult_UnexpectedObjectType; // TODO(mraj) use memos new error - } + + NIError error = WriteDoubleToMemory(typeRef, pData, value); + if (error) + return kEggShellResult_UnexpectedObjectType; return kEggShellResult_Success; } //------------------------------------------------------------ //! Read a numeric value from a symbol. Value will be coerced as needed. -VIREO_EXPORT NIError EggShell_ReadDouble(TypeManagerRef tm, const TypeRef actualType, const void* pData, Double* result) +VIREO_EXPORT EggShellResult EggShell_ReadDouble(TypeManagerRef tm, const TypeRef typeRef, const void* pData, Double* result) { - NIError err = kNIError_Success; - *result = ReadDoubleFromMemory(actualType, pData, &err); - return err; + TypeManagerScope scope(tm); + if (typeRef == nullptr || !typeRef->IsValid()) + return kEggShellResult_InvalidTypeRef; + + if (result == nullptr) + return kEggShellResult_InvalidResultPointer; + + NIError error = kNIError_Success; + *result = ReadDoubleFromMemory(typeRef, pData, &error); + if (error) + return kEggShellResult_UnexpectedObjectType; + return kEggShellResult_Success; } //------------------------------------------------------------ // Write a string value to a symbol. Value will be parsed according to format designated. @@ -276,21 +284,18 @@ VIREO_EXPORT Int32 EggShell_GetArrayDimLength(TypeManagerRef tm, const char* viN } //------------------------------------------------------------ //! Resizes a variable size Array symbol to have new dimension lengths specified by newLengths, it also initializes cells for non-flat data. -VIREO_EXPORT EggShellResult EggShell_ResizeArray(TypeManagerRef tm, const TypeRef actualType, const void* pData, +VIREO_EXPORT EggShellResult EggShell_ResizeArray(TypeManagerRef tm, const TypeRef typeRef, const void* pData, Int32 newDimensionsLength, Int32 newDimensions[]) { TypeManagerScope scope(tm); - if (actualType == nullptr || !actualType->IsValid()) { + if (typeRef == nullptr || !typeRef->IsValid()) return kEggShellResult_InvalidTypeRef; - } - if (!actualType->IsArray()) { + if (!typeRef->IsArray()) return kEggShellResult_UnexpectedObjectType; - } - if (actualType->Rank() != newDimensionsLength) { + if (typeRef->Rank() != newDimensionsLength) return kEggShellResult_MismatchedArrayRank; - } TypedArrayCoreRef arrayObject = *(TypedArrayCoreRef*)pData; VIREO_ASSERT(TypedArrayCore::ValidateHandle(arrayObject)); diff --git a/source/include/CEntryPoints.h b/source/include/CEntryPoints.h index 2698756d7..33fd3f36a 100644 --- a/source/include/CEntryPoints.h +++ b/source/include/CEntryPoints.h @@ -41,7 +41,7 @@ VIREO_EXPORT Int32 EggShell_PokeMemory(TypeManagerRef tm, const char* viName, co VIREO_EXPORT EggShellResult EggShell_FindValue(TypeManagerRef tm, const char* viName, const char* eltName, TypeRef* typeRefLocation, void** dataRefLocation); VIREO_EXPORT EggShellResult EggShell_FindSubValue(TypeManagerRef tm, TypeRef type, const char* eltName, TypeRef* typeRefLocation, void** dataRefLocation); VIREO_EXPORT EggShellResult EggShell_WriteDouble(TypeManagerRef tm, const TypeRef actualType, void* pData, Double value); -VIREO_EXPORT NIError EggShell_ReadDouble(TypeManagerRef tm, const TypeRef actualType, const void* pData, Double* result); +VIREO_EXPORT EggShellResult EggShell_ReadDouble(TypeManagerRef tm, const TypeRef actualType, const void* pData, Double* result); VIREO_EXPORT EggShellResult EggShell_WriteValueString(TypeManagerRef tm, TypeRef typeRef, void* data, const char* format, const char* value); VIREO_EXPORT EggShellResult EggShell_ReadValueString(TypeManagerRef tm, TypeRef typeRef, void* pData, const char* format, UInt8** valueString); VIREO_EXPORT EggShellResult EggShell_GetPointer(TypeManagerRef tm, diff --git a/source/io/module_eggShell.js b/source/io/module_eggShell.js index 075e3db50..11c0eaaa0 100644 --- a/source/io/module_eggShell.js +++ b/source/io/module_eggShell.js @@ -213,7 +213,7 @@ var dataStackPointer = Module.stackAlloc(POINTER_SIZE); var eggShellResult = Module._EggShell_FindValue(Module.eggShell.v_userShell, viStackPointer, pathStackPointer, typeStackPointer, dataStackPointer); - if (eggShellResult !== 0) { + if (eggShellResult !== EGGSHELL_RESULT.SUCCESS) { throw new Error('A ValueRef could not be made for the following reason: ' + eggShellResultEnum[eggShellResult] + ' (error code: ' + eggShellResult + ')' + ' (vi name: ' + vi + ')' + @@ -236,7 +236,7 @@ var dataStackPointer = Module.stackAlloc(POINTER_SIZE); var eggShellResult = Module._EggShell_FindSubValue(Module.eggShell.v_userShell, valueRef.typeRef, pathStackPointer, typeStackPointer, dataStackPointer); - if (eggShellResult !== 0) { + if (eggShellResult !== EGGSHELL_RESULT.SUCCESS) { throw new Error('A ValueRef could not be made for the following reason: ' + eggShellResultEnum[eggShellResult] + ' (error code: ' + eggShellResult + ')' + ' (type name: ' + Module.typeHelpers.typeName(valueRef.typeRef) + ')' + @@ -296,10 +296,10 @@ var resultPointer = Module.stackAlloc(DOUBLE_SIZE); // TODO mraj should we try to resolve the typeref name on error for more context? - var niError = Module._EggShell_ReadDouble(Module.eggShell.v_userShell, valueRef.typeRef, valueRef.dataRef, resultPointer); - if (niError !== 0) { - throw new Error('Performing readDouble failed for the following reason: ' + niErrorEnum[niError] + - ' (error code: ' + niError + ')' + + var eggShellResult = Module._EggShell_ReadDouble(Module.eggShell.v_userShell, valueRef.typeRef, valueRef.dataRef, resultPointer); + if (eggShellResult !== EGGSHELL_RESULT.SUCCESS) { + throw new Error('Could not run readDouble for the following reason: ' + eggShellResultEnum[eggShellResult] + + ' (error code: ' + eggShellResult + ')' + ' (typeRef: ' + valueRef.typeRef + ')' + ' (dataRef: ' + valueRef.dataRef + ')'); } @@ -315,7 +315,7 @@ } var eggShellResult = Module._EggShell_WriteDouble(Module.eggShell.v_userShell, valueRef.typeRef, valueRef.dataRef, value); - if (eggShellResult !== 0) { + if (eggShellResult !== EGGSHELL_RESULT.SUCCESS) { throw new Error('Could not run writeDouble for the following reason: ' + eggShellResultEnum[eggShellResult] + ' (error code: ' + eggShellResult + ')' + ' (typeRef: ' + valueRef.typeRef + ')' + @@ -660,7 +660,7 @@ Module.setValue(dimensionsPointer + (i * LENGTH_SIZE), currentDimension, 'i32'); } var eggShellResult = Module._EggShell_ResizeArray(Module.eggShell.v_userShell, valueRef.typeRef, valueRef.dataRef, newDimensionsLength, dimensionsPointer); - if (eggShellResult !== 0) { + if (eggShellResult !== EGGSHELL_RESULT.SUCCESS) { throw new Error('Resizing the array failed for the following reason: ' + eggShellResultEnum[eggShellResult] + ' (error code: ' + eggShellResult + ')' + ' (typeRef: ' + valueRef.typeRef + ')' + diff --git a/test-it/karma/publicapi/Double.Test.js b/test-it/karma/publicapi/Double.Test.js index 17f0295ec..26ec6eec3 100644 --- a/test-it/karma/publicapi/Double.Test.js +++ b/test-it/karma/publicapi/Double.Test.js @@ -31,11 +31,25 @@ describe('The Vireo EggShell Double api can', function () { }; var testWriteDouble = function (path, initialValue, newValue) { - expect(readDouble(path)).toBe(initialValue); + expect(readDouble(path)).toMatchIEEE754Number(initialValue); writeDouble(path, newValue); - expect(readDouble(path)).toBe(newValue); + expect(readDouble(path)).toMatchIEEE754Number(newValue); writeDouble(path, initialValue); - expect(readDouble(path)).toBe(initialValue); + expect(readDouble(path)).toMatchIEEE754Number(initialValue); + }; + + var testWriteDoubleCoerced = function (path, initialValue, attemptedNewValue, coercedNewValue) { + expect(readDouble(path)).toMatchIEEE754Number(initialValue); + writeDouble(path, attemptedNewValue); + expect(readDouble(path)).toMatchIEEE754Number(coercedNewValue); + writeDouble(path, initialValue); + expect(readDouble(path)).toMatchIEEE754Number(initialValue); + }; + + // Expected coerced values of Doubles in Vireo should have the same behavior as assignment to typed arrays + // This is so a user assigning a double to a typedarray using getTypedArray will see the same effect as writing to a double using writeDouble + var expectedCoercedValue = function (TypedArrayConstructor, value) { + return (new TypedArrayConstructor([value])[0]); }; beforeAll(function (done) { @@ -98,14 +112,78 @@ describe('The Vireo EggShell Double api can', function () { }); it('to error for unsupported types', function () { - expect(tryReadDouble('dataItem_Complex')).toThrowError(/CantDecode/); - expect(tryReadDouble('dataItem_String')).toThrowError(/CantDecode/); + expect(tryReadDouble('dataItem_Complex')).toThrowError(/UnexpectedObjectType/); + expect(tryReadDouble('dataItem_String')).toThrowError(/UnexpectedObjectType/); }); }); describe('use writeDouble', function () { it('to write double values to memory', function () { testWriteDouble('dataItem_NumericDouble', 123.456, 42); + testWriteDouble('dataItem_NumericDouble', 123.456, NaN); + testWriteDouble('dataItem_NumericDouble', 123.456, Infinity); + testWriteDouble('dataItem_NumericDouble', 123.456, -Infinity); + testWriteDouble('dataItem_NumericDouble', 123.456, 0); + testWriteDouble('dataItem_NumericDouble', 123.456, -0); + }); + + it('to write integer values to memory', function () { + testWriteDoubleCoerced('int8MinValue', -128, 812, expectedCoercedValue(Int8Array, 812)); + testWriteDoubleCoerced('int8MinValue', -128, -812, expectedCoercedValue(Int8Array, -812)); + testWriteDoubleCoerced('int16MinValue', -32768, 81234, expectedCoercedValue(Int16Array, 81234)); + testWriteDoubleCoerced('int16MinValue', -32768, -81234, expectedCoercedValue(Int16Array, -81234)); + testWriteDoubleCoerced('int32MinValue', -2147483648, 8123456789, expectedCoercedValue(Int32Array, 8123456789)); + testWriteDoubleCoerced('int32MinValue', -2147483648, -8123456789, expectedCoercedValue(Int32Array, -8123456789)); + testWriteDoubleCoerced('uInt8MinValue', 0, 812, expectedCoercedValue(Uint8Array, 812)); + testWriteDoubleCoerced('uInt8MinValue', 0, -812, expectedCoercedValue(Uint8Array, -812)); + testWriteDoubleCoerced('uInt16MinValue', 0, 81234, expectedCoercedValue(Uint16Array, 81234)); + testWriteDoubleCoerced('uInt16MinValue', 0, -81234, expectedCoercedValue(Uint16Array, -81234)); + testWriteDoubleCoerced('uInt32MinValue', 0, 8123456789, expectedCoercedValue(Uint32Array, 8123456789)); + testWriteDoubleCoerced('uInt32MinValue', 0, -8123456789, expectedCoercedValue(Uint32Array, -8123456789)); + + expect(expectedCoercedValue(Int8Array, 812)).toBe(44); + expect(expectedCoercedValue(Int8Array, -812)).toBe(-44); + expect(expectedCoercedValue(Int16Array, 81234)).toBe(15698); + expect(expectedCoercedValue(Int16Array, -81234)).toBe(-15698); + expect(expectedCoercedValue(Int32Array, 8123456789)).toBe(-466477803); + expect(expectedCoercedValue(Int32Array, -8123456789)).toBe(466477803); + expect(expectedCoercedValue(Uint8Array, 812)).toBe(44); + expect(expectedCoercedValue(Uint8Array, -812)).toBe(212); + expect(expectedCoercedValue(Uint16Array, 81234)).toBe(15698); + expect(expectedCoercedValue(Uint16Array, -81234)).toBe(49838); + expect(expectedCoercedValue(Uint32Array, 8123456789)).toBe(3828489493); + expect(expectedCoercedValue(Uint32Array, -8123456789)).toBe(466477803); + }); + + it('to coerce iee754 special values to memory', function () { + testWriteDoubleCoerced('int8MinValue', -128, NaN, expectedCoercedValue(Int8Array, NaN)); + testWriteDoubleCoerced('int8MinValue', -128, Infinity, expectedCoercedValue(Int8Array, Infinity)); + testWriteDoubleCoerced('int8MinValue', -128, -Infinity, expectedCoercedValue(Int8Array, -Infinity)); + testWriteDoubleCoerced('int8MinValue', -128, -0, expectedCoercedValue(Int8Array, -0)); + testWriteDoubleCoerced('int8MinValue', -128, 0, expectedCoercedValue(Int8Array, 0)); + + expect(expectedCoercedValue(Int8Array, NaN)).toBe(0); + expect(expectedCoercedValue(Int8Array, Infinity)).toBe(0); + expect(expectedCoercedValue(Int8Array, -Infinity)).toBe(0); + expect(expectedCoercedValue(Int8Array, -0)).toBe(0); + expect(expectedCoercedValue(Int8Array, 0)).toBe(0); + }); + + it('to write different enum types to memory', function () { + testWriteDouble('enum8alphabet', 6, 4); + testWriteDouble('enum16numbers', 3, 4); + testWriteDouble('enum32colors', 2, 4); + testWriteDouble('enum64releases', 5, 4); + }); + + it('to write different boolean types to memory', function () { + testWriteDouble('booleanTrueValue', 1, 0); + testWriteDoubleCoerced('booleanTrueValue', 1, 70, 1); + testWriteDoubleCoerced('booleanTrueValue', 1, -70, 1); + }); + + it('to write different timestamp values to memory', function () { + testWriteDouble('dataItem_Timestamp', 3564057536.423476, 7); }); it('to error for unsupported types', function () { From 4f8a8e25681801ba66d6d660045eee211e9050c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Le=C3=B3n?= Date: Thu, 28 Jun 2018 15:31:54 -0500 Subject: [PATCH 54/67] Aded visitEnum[8|16|32] to visitor reflection API --- source/core/module_typeHelpers.js | 24 +++++++++++++++++-- .../karma/publicapi/TypeReflection.Test.js | 12 +++++++--- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/source/core/module_typeHelpers.js b/source/core/module_typeHelpers.js index d7cd6fdcc..6a7306ba8 100644 --- a/source/core/module_typeHelpers.js +++ b/source/core/module_typeHelpers.js @@ -46,8 +46,28 @@ }; var dispatchVisitEnum = function (typeVisitor, valueRef, data) { - validateVisitMethod(typeVisitor.visitEnum, 'visitEnum'); - return typeVisitor.visitEnum(typeVisitor, valueRef, data); + var sizeOfEnum = Module.typeHelpers.topAQSize(valueRef.typeRef); + var visitFn = undefined; + var fnName = ''; + switch (sizeOfEnum) { + case 1: + visitFn = typeVisitor.visitEnumUInt8; + fnName = 'visitEnumUInt8'; + break; + case 2: + visitFn = typeVisitor.visitEnumUInt16; + fnName = 'visitEnumUInt16'; + break; + case 4: + visitFn = typeVisitor.visitEnumUInt32; + fnName = 'visitEnumUInt32'; + break; + default: + throw new Error('Unexpected size for Enum. Found: ' + sizeOfEnum); + } + + validateVisitMethod(visitFn, fnName); + return visitFn.call(typeVisitor, valueRef, data); }; var dispatchVisitInteger = function (typeVisitor, valueRef, data) { diff --git a/test-it/karma/publicapi/TypeReflection.Test.js b/test-it/karma/publicapi/TypeReflection.Test.js index d4b52b7b3..bf9ea38bc 100644 --- a/test-it/karma/publicapi/TypeReflection.Test.js +++ b/test-it/karma/publicapi/TypeReflection.Test.js @@ -19,7 +19,9 @@ describe('The Vireo EggShell Reflection API', function () { return { visitBoolean: returnTypeName('Boolean'), - visitEnum: returnTypeName('Enum'), + visitEnumUInt8: returnTypeName('Enum8'), + visitEnumUInt16: returnTypeName('Enum16'), + visitEnumUInt32: returnTypeName('Enum32'), visitInt8: returnTypeName('Int8'), visitInt16: returnTypeName('Int16'), visitInt32: returnTypeName('Int32'), @@ -96,7 +98,9 @@ describe('The Vireo EggShell Reflection API', function () { expect(reflectOnEmptyVisitor('dataItem_String')).toThrowError(/visitString/); expect(reflectOnEmptyVisitor('dataItem_Boolean')).toThrowError(/visitBoolean/); expect(reflectOnEmptyVisitor('dataItem_Timestamp')).toThrowError(/visitTimestamp/); - expect(reflectOnEmptyVisitor('enum8alphabet')).toThrowError(/visitEnum/); + expect(reflectOnEmptyVisitor('enum8alphabet')).toThrowError(/visitEnumUInt8/); + expect(reflectOnEmptyVisitor('enum16numbers')).toThrowError(/visitEnumUInt16/); + expect(reflectOnEmptyVisitor('enum32colors')).toThrowError(/visitEnumUInt32/); expect(reflectOnEmptyVisitor('wave_Double')).toThrowError(/visitAnalogWaveform/); expect(reflectOnEmptyVisitor('dataItem_ClusterOfScalars')).toThrowError(/visitCluster/); expect(reflectOnEmptyVisitor('dataItem_ArrayOfBoolean')).toThrowError(/visitArray/); @@ -129,7 +133,9 @@ describe('The Vireo EggShell Reflection API', function () { it('for aggregate types', function () { expect(getTypeName('dataItem_Timestamp')).toEqual('Timestamp'); - expect(getTypeName('enum8alphabet')).toEqual('Enum'); + expect(getTypeName('enum8alphabet')).toEqual('Enum8'); + expect(getTypeName('enum16numbers')).toEqual('Enum16'); + expect(getTypeName('enum32colors')).toEqual('Enum32'); expect(getTypeName('wave_Double')).toEqual('AnalogWaveform'); expect(getTypeName('dataItem_ClusterOfScalars')).toEqual('Cluster'); expect(getTypeName('dataItem_ArrayOfBoolean')).toEqual('Array'); From 0e9519d3f59f01382895ae9f07f20a9fcd8d4aa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Le=C3=B3n?= Date: Thu, 28 Jun 2018 16:58:06 -0500 Subject: [PATCH 55/67] Changed name of visitor functions for enums Also added a test for unssported Enums of 64 bits. --- source/core/module_typeHelpers.js | 12 ++++++------ test-it/karma/publicapi/TypeReflection.Test.js | 16 ++++++++++------ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/source/core/module_typeHelpers.js b/source/core/module_typeHelpers.js index 6a7306ba8..479fa73ec 100644 --- a/source/core/module_typeHelpers.js +++ b/source/core/module_typeHelpers.js @@ -51,16 +51,16 @@ var fnName = ''; switch (sizeOfEnum) { case 1: - visitFn = typeVisitor.visitEnumUInt8; - fnName = 'visitEnumUInt8'; + visitFn = typeVisitor.visitEnum8; + fnName = 'visitEnum8'; break; case 2: - visitFn = typeVisitor.visitEnumUInt16; - fnName = 'visitEnumUInt16'; + visitFn = typeVisitor.visitEnum16; + fnName = 'visitEnum16'; break; case 4: - visitFn = typeVisitor.visitEnumUInt32; - fnName = 'visitEnumUInt32'; + visitFn = typeVisitor.visitEnum32; + fnName = 'visitEnum32'; break; default: throw new Error('Unexpected size for Enum. Found: ' + sizeOfEnum); diff --git a/test-it/karma/publicapi/TypeReflection.Test.js b/test-it/karma/publicapi/TypeReflection.Test.js index bf9ea38bc..bebe9fcca 100644 --- a/test-it/karma/publicapi/TypeReflection.Test.js +++ b/test-it/karma/publicapi/TypeReflection.Test.js @@ -19,9 +19,9 @@ describe('The Vireo EggShell Reflection API', function () { return { visitBoolean: returnTypeName('Boolean'), - visitEnumUInt8: returnTypeName('Enum8'), - visitEnumUInt16: returnTypeName('Enum16'), - visitEnumUInt32: returnTypeName('Enum32'), + visitEnum8: returnTypeName('Enum8'), + visitEnum16: returnTypeName('Enum16'), + visitEnum32: returnTypeName('Enum32'), visitInt8: returnTypeName('Int8'), visitInt16: returnTypeName('Int16'), visitInt32: returnTypeName('Int32'), @@ -98,13 +98,17 @@ describe('The Vireo EggShell Reflection API', function () { expect(reflectOnEmptyVisitor('dataItem_String')).toThrowError(/visitString/); expect(reflectOnEmptyVisitor('dataItem_Boolean')).toThrowError(/visitBoolean/); expect(reflectOnEmptyVisitor('dataItem_Timestamp')).toThrowError(/visitTimestamp/); - expect(reflectOnEmptyVisitor('enum8alphabet')).toThrowError(/visitEnumUInt8/); - expect(reflectOnEmptyVisitor('enum16numbers')).toThrowError(/visitEnumUInt16/); - expect(reflectOnEmptyVisitor('enum32colors')).toThrowError(/visitEnumUInt32/); + expect(reflectOnEmptyVisitor('enum8alphabet')).toThrowError(/visitEnum8/); + expect(reflectOnEmptyVisitor('enum16numbers')).toThrowError(/visitEnum16/); + expect(reflectOnEmptyVisitor('enum32colors')).toThrowError(/visitEnum32/); expect(reflectOnEmptyVisitor('wave_Double')).toThrowError(/visitAnalogWaveform/); expect(reflectOnEmptyVisitor('dataItem_ClusterOfScalars')).toThrowError(/visitCluster/); expect(reflectOnEmptyVisitor('dataItem_ArrayOfBoolean')).toThrowError(/visitArray/); }); + + it('throws for unsupported enum types', function () { + expect(reflectOnEmptyVisitor('enum64releases')).toThrowError(/Unexpected size/); + }); }); describe('dispatches a call on visitor', function () { From e9e9b21518f891b37a86d0caa57e98ad2c2f5cae Mon Sep 17 00:00:00 2001 From: rajsite Date: Fri, 29 Jun 2018 10:18:57 -0500 Subject: [PATCH 56/67] Mark deprecated functions in eggShell api --- source/io/module_eggShell.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/source/io/module_eggShell.js b/source/io/module_eggShell.js index 11c0eaaa0..2a021a813 100644 --- a/source/io/module_eggShell.js +++ b/source/io/module_eggShell.js @@ -601,6 +601,7 @@ var vireoObjectPointer = Module._malloc(4); var vireoTypePointer = Module._malloc(4); + // **DEPRECATED** Module.eggShell.getNumericArray = publicAPI.eggShell.getNumericArray = function (vi, path) { var eggShellResult = EggShell_GetPointer(Module.eggShell.v_userShell, vi, path, vireoObjectPointer, vireoTypePointer); @@ -639,6 +640,7 @@ return convertFlatArraytoNArray(actualArray, arrayInfo.dimensionLengths); }; + // **DEPRECATED** Module.eggShell.getArrayDimLength = publicAPI.eggShell.getArrayDimLength = function (vi, path, dim) { return EggShell_GetArrayDimLength(Module.eggShell.v_userShell, vi, path, dim); }; @@ -669,6 +671,7 @@ Module.stackRestore(stack); }; + // **DEPRECATED** Module.eggShell.dataReadString = function (stringPointer) { var begin = Data_GetStringBegin(stringPointer); var length = Data_GetStringLength(stringPointer); @@ -677,6 +680,7 @@ }; // Note this function is tied to the underlying buffer, a copy is not made + // **DEPRECATED** Module.eggShell.dataReadStringAsArray_NoCopy = function (stringPointer) { var begin = Data_GetStringBegin(stringPointer); var length = Data_GetStringLength(stringPointer); @@ -684,12 +688,14 @@ }; // Source should be a JS String + // **DEPRECATED** Module.eggShell.dataWriteString = function (destination, source) { var sourceLength = Module.lengthBytesUTF8(source); Data_WriteString(Module.eggShell.v_userShell, destination, source, sourceLength); }; // Source should be a JS array of numbers or a TypedArray of Uint8Array or Int8Array + // **DEPRECATED** Module.eggShell.dataWriteStringFromArray = function (destination, source) { var sourceHeapPointer = Module._malloc(source.length); Module.writeArrayToMemory(source, sourceHeapPointer); @@ -697,55 +703,66 @@ Module._free(sourceHeapPointer); }; + // **DEPRECATED** Module.eggShell.dataReadBoolean = function (booleanPointer) { var numericValue = Data_ReadBoolean(booleanPointer); return numericValue !== 0; }; + // **DEPRECATED** Module.eggShell.dataReadInt8 = function (intPointer) { var numericValue = Data_ReadInt8(intPointer); return numericValue; }; + // **DEPRECATED** Module.eggShell.dataReadInt16 = function (intPointer) { var numericValue = Data_ReadInt16(intPointer); return numericValue; }; + // **DEPRECATED** Module.eggShell.dataReadInt32 = function (intPointer) { var numericValue = Data_ReadInt32(intPointer); return numericValue; }; + // **DEPRECATED** Module.eggShell.dataReadUInt8 = function (intPointer) { var numericValue = Data_ReadUInt8(intPointer); return numericValue; }; + // **DEPRECATED** Module.eggShell.dataReadUInt16 = function (intPointer) { var numericValue = Data_ReadUInt16(intPointer); return numericValue; }; + // **DEPRECATED** Module.eggShell.dataReadUInt32 = function (intPointer) { var numericValue = Data_ReadUInt32(intPointer); return numericValue; }; + // **DEPRECATED** Module.eggShell.dataReadSingle = function (singlePointer) { var numericValue = Data_ReadSingle(singlePointer); return numericValue; }; + // **DEPRECATED** Module.eggShell.dataReadDouble = function (doublePointer) { var numericValue = Data_ReadDouble(doublePointer); return numericValue; }; + // **DEPRECATED** Module.eggShell.dataReadTypedArray = function (arrayPointer) { return Module.eggShell.dataReadNumericArrayAsTypedArray(arrayPointer).array; }; + // **DEPRECATED** Module.eggShell.dataReadNumericArrayAsTypedArray = function (arrayPointer) { var eggShellResult = Data_GetArrayMetadata(Module.eggShell.v_userShell, arrayPointer, arrayTypeNameDoublePointer, arrayRankPointer, arrayBeginPointer); @@ -797,43 +814,53 @@ }; }; + // **DEPRECATED** Module.eggShell.dataWriteBoolean = function (booleanPointer, booleanValue) { var numericValue = booleanValue ? 1 : 0; Data_WriteBoolean(booleanPointer, numericValue); }; + // **DEPRECATED** Module.eggShell.dataWriteInt8 = function (destination, value) { Data_WriteInt8(destination, value); }; + // **DEPRECATED** Module.eggShell.dataWriteInt16 = function (destination, value) { Data_WriteInt16(destination, value); }; + // **DEPRECATED** Module.eggShell.dataWriteInt32 = function (destination, value) { Data_WriteInt32(destination, value); }; + // **DEPRECATED** Module.eggShell.dataWriteUInt8 = function (destination, value) { Data_WriteUInt8(destination, value); }; + // **DEPRECATED** Module.eggShell.dataWriteUInt16 = function (destination, value) { Data_WriteUInt16(destination, value); }; + // **DEPRECATED** Module.eggShell.dataWriteUInt32 = function (destination, value) { Data_WriteUInt32(destination, value); }; + // **DEPRECATED** Module.eggShell.dataWriteSingle = function (destination, value) { Data_WriteSingle(destination, value); }; + // **DEPRECATED** Module.eggShell.dataWriteDouble = function (destination, value) { Data_WriteDouble(destination, value); }; + // **DEPRECATED** Module.eggShell.dataWriteTypedArray = function (destination, value) { var int32Byte = 4; var rank = 1; From 7004589de0d3dc06684312e2df37fc2f6fa8137e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Le=C3=B3n?= Date: Mon, 2 Jul 2018 16:53:17 -0500 Subject: [PATCH 57/67] Standardized on call for dispatchers and fixed loop condition. --- source/core/module_typeHelpers.js | 37 ++++++++++++++++++------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/source/core/module_typeHelpers.js b/source/core/module_typeHelpers.js index 479fa73ec..31f348566 100644 --- a/source/core/module_typeHelpers.js +++ b/source/core/module_typeHelpers.js @@ -41,8 +41,9 @@ }; var dispatchVisitBoolean = function (typeVisitor, valueRef, data) { - validateVisitMethod(typeVisitor.visitBoolean, 'visitBoolean'); - return typeVisitor.visitBoolean(valueRef, data); + var visitFn = typeVisitor.visitBoolean; + validateVisitMethod(visitFn, 'visitBoolean'); + return visitFn.call(typeVisitor, valueRef, data); }; var dispatchVisitEnum = function (typeVisitor, valueRef, data) { @@ -147,8 +148,9 @@ }; var dispatchVisitString = function (typeVisitor, valueRef, data) { - validateVisitMethod(typeVisitor.visitString, 'visitString'); - return typeVisitor.visitString(valueRef, data); + var visitFn = typeVisitor.visitString; + validateVisitMethod(visitFn, 'visitString'); + return visitFn.call(typeVisitor, valueRef, data); }; var dispatchVisitComplex = function (typeVisitor, valueRef, data) { @@ -174,28 +176,33 @@ }; var dispatchVisitAnalogWaveform = function (typeVisitor, valueRef, data) { - validateVisitMethod(typeVisitor.visitAnalogWaveform, 'visitAnalogWaveform'); - return typeVisitor.visitAnalogWaveform(valueRef, data); + var visitFn = typeVisitor.visitAnalogWaveform; + validateVisitMethod(visitFn, 'visitAnalogWaveform'); + return visitFn.call(typeVisitor, valueRef, data); }; var dispatchVisitTimestamp = function (typeVisitor, valueRef, data) { - validateVisitMethod(typeVisitor.visitTimestamp, 'visitTimestamp'); - return typeVisitor.visitTimestamp(valueRef, data); + var visitFn = typeVisitor.visitTimestamp; + validateVisitMethod(visitFn, 'visitTimestamp'); + return visitFn.call(typeVisitor, valueRef, data); }; var dispatchVisitPath = function (typeVisitor, valueRef, data) { - validateVisitMethod(typeVisitor.visitPath, 'visitPath'); - return typeVisitor.visitPath(valueRef, data); + var visitFn = typeVisitor.visitPath; + validateVisitMethod(visitFn, 'visitPath'); + return visitFn.call(typeVisitor, valueRef, data); }; var dispatchVisitArray = function (typeVisitor, valueRef, data) { - validateVisitMethod(typeVisitor.visitArray, 'visitArray'); - return typeVisitor.visitArray(valueRef, data); + var visitFn = typeVisitor.visitArray; + validateVisitMethod(visitFn, 'visitArray'); + return visitFn.call(typeVisitor, valueRef, data); }; var dispatchVisitCluster = function (typeVisitor, valueRef, data) { - validateVisitMethod(typeVisitor.visitCluster, 'visitCluster'); - return typeVisitor.visitCluster(typeVisitor, valueRef, data); + var visitFn = typeVisitor.visitCluster; + validateVisitMethod(visitFn, 'visitCluster'); + return visitFn.call(typeVisitor, valueRef, data); }; // Exported functions @@ -326,7 +333,7 @@ var i = 0, typeHandler; - for (i = 0; typeHandlers.length; i += 1) { + for (i = 0; i < typeHandlers.length; i += 1) { typeHandler = typeHandlers[i]; if (typeHandler.typeChecker(typeRef) === true) { return typeHandler.dispatcher; From 72050a11479295907ac89e11567ab68ea1cb08a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Le=C3=B3n?= Date: Mon, 9 Jul 2018 11:28:24 -0500 Subject: [PATCH 58/67] Added tests for context and arguments of visitor functions. --- .../karma/publicapi/TypeReflection.Test.js | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/test-it/karma/publicapi/TypeReflection.Test.js b/test-it/karma/publicapi/TypeReflection.Test.js index bebe9fcca..76bb5f768 100644 --- a/test-it/karma/publicapi/TypeReflection.Test.js +++ b/test-it/karma/publicapi/TypeReflection.Test.js @@ -43,6 +43,14 @@ describe('The Vireo EggShell Reflection API', function () { }; }()); + var validateValueRef = function (valueRef) { + expect(valueRef).toBeNonEmptyObject(); + expect(valueRef.typeRef).toBeNumber(); + expect(valueRef.typeRef).not.toBe(0); + expect(valueRef.dataRef).toBeNumber(); + expect(valueRef.dataRef).not.toBe(0); + }; + beforeAll(function (done) { fixtures.preloadAbsoluteUrls([ publicApiMultipleTypesViaUrl @@ -144,6 +152,49 @@ describe('The Vireo EggShell Reflection API', function () { expect(getTypeName('dataItem_ClusterOfScalars')).toEqual('Cluster'); expect(getTypeName('dataItem_ArrayOfBoolean')).toEqual('Array'); }); + + it('with "this" bound to the visitor a valid valueRef and data as arguments', function () { + var dummyData = {}; + var visitor = {}; + var validateVisitArgs = function (valueRef, data) { + /* eslint-disable no-invalid-this */ + expect(this).toBe(visitor); + validateValueRef(valueRef); + expect(data).toBe(dummyData); + }; + + for (var visitkey in typeDescriptor) { + if (typeDescriptor.hasOwnProperty(visitkey)) { + visitor[visitkey] = validateVisitArgs; + } + } + + var visitorArgsTest = function (path) { + vireo.eggShell.reflectOnValueRef(visitor, vireo.eggShell.findValueRef(viName, path), dummyData); + }; + + visitorArgsTest('int8MinValue'); + visitorArgsTest('int16MinValue'); + visitorArgsTest('int32MinValue'); + visitorArgsTest('int64MinSafeInteger'); + visitorArgsTest('uInt8MinValue'); + visitorArgsTest('uInt16MinValue'); + visitorArgsTest('uInt32MinValue'); + visitorArgsTest('uInt64MinSafeInteger'); + visitorArgsTest('dataItem_NumericSingle'); + visitorArgsTest('dataItem_NumericDouble'); + visitorArgsTest('dataItem_ComplexSingle'); + visitorArgsTest('dataItem_Complex'); + visitorArgsTest('dataItem_String'); + visitorArgsTest('dataItem_Boolean'); + visitorArgsTest('dataItem_Timestamp'); + visitorArgsTest('enum8alphabet'); + visitorArgsTest('enum16numbers'); + visitorArgsTest('enum32colors'); + visitorArgsTest('wave_Double'); + visitorArgsTest('dataItem_ClusterOfScalars'); + visitorArgsTest('dataItem_ArrayOfBoolean'); + }); }); }); }); From ae135caa36081190fa3eb7ebf96730531adf4753 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Le=C3=B3n?= Date: Tue, 3 Jul 2018 15:36:03 -0500 Subject: [PATCH 59/67] Renamed TypeWaveform tests to be included in the test suite. --- .../publicapi/{TypeWaveform.test.js => TypeWaveform.Test.js} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test-it/karma/publicapi/{TypeWaveform.test.js => TypeWaveform.Test.js} (100%) diff --git a/test-it/karma/publicapi/TypeWaveform.test.js b/test-it/karma/publicapi/TypeWaveform.Test.js similarity index 100% rename from test-it/karma/publicapi/TypeWaveform.test.js rename to test-it/karma/publicapi/TypeWaveform.Test.js From 9db209f75b6ea427ad15e2ef853b95cd4c2ec04c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Le=C3=B3n?= Date: Tue, 3 Jul 2018 15:40:36 -0500 Subject: [PATCH 60/67] Fixed tests in TypeWaveform. Timestamps are 2 UInt64 therefore their JSON representation are strings. Updating expected values to match this. --- test-it/karma/publicapi/TypeWaveform.Test.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/test-it/karma/publicapi/TypeWaveform.Test.js b/test-it/karma/publicapi/TypeWaveform.Test.js index 07ea5af7c..7b500c404 100644 --- a/test-it/karma/publicapi/TypeWaveform.Test.js +++ b/test-it/karma/publicapi/TypeWaveform.Test.js @@ -24,8 +24,8 @@ describe('Peek/Poke different datatypes', function () { expect(viPathParser('wave_dbl_1')).toEqual({ t0: { - seconds: 3566073600, - fraction: 123 + seconds: '3566073600', + fraction: '123' }, dt: 5.8, Y: [1.2, 1.3, 1, -0.5] // eslint-disable-line id-length @@ -33,8 +33,8 @@ describe('Peek/Poke different datatypes', function () { expect(viPathParser('wave_i32_1')).toEqual({ t0: { - seconds: 0, - fraction: 0 + seconds: '0', + fraction: '0' }, dt: 0, Y: [] // eslint-disable-line id-length @@ -42,8 +42,8 @@ describe('Peek/Poke different datatypes', function () { var newValue = { t0: { - seconds: 50000, - fraction: 456 + seconds: '50000', + fraction: '456' }, dt: 10.5, Y: [5, 25] // eslint-disable-line id-length @@ -53,8 +53,8 @@ describe('Peek/Poke different datatypes', function () { var newValue2 = { t0: { - seconds: 60000, - fraction: 656 + seconds: '60000', + fraction: '656' }, dt: 20.5, Y: [45, 55] // eslint-disable-line id-length @@ -67,8 +67,8 @@ describe('Peek/Poke different datatypes', function () { runSlicesAsync(function () { expect(viPathParser('wave_i32_1')).toEqual({ t0: { - seconds: 456, - fraction: 123 + seconds: '456', + fraction: '123' }, dt: 6.8, Y: [10, 20, 30] // eslint-disable-line id-length From e79f1e3be012186ba0baab9cefbd5c8f08d3be2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Le=C3=B3n?= Date: Tue, 3 Jul 2018 18:03:06 -0500 Subject: [PATCH 61/67] Fixing FindSubValueRef Also added tests that verify this behavior. --- source/core/CEntryPoints.cpp | 3 +- source/include/CEntryPoints.h | 2 +- source/io/module_eggShell.js | 4 +- .../publicapi/ReadWriteIntegration.via | 22 +++ .../ReadWriteJson.Integration.Test.js | 136 ++++++++++++++++++ 5 files changed, 162 insertions(+), 5 deletions(-) create mode 100644 test-it/karma/fixtures/publicapi/ReadWriteIntegration.via create mode 100644 test-it/karma/publicapi/ReadWriteJson.Integration.Test.js diff --git a/source/core/CEntryPoints.cpp b/source/core/CEntryPoints.cpp index 42bc35ec7..7c99a8936 100644 --- a/source/core/CEntryPoints.cpp +++ b/source/core/CEntryPoints.cpp @@ -131,14 +131,13 @@ VIREO_EXPORT EggShellResult EggShell_FindValue(TypeManagerRef tm, const char* vi } //------------------------------------------------------------ //! Get a reference to the type pointer and data for a sub element -VIREO_EXPORT EggShellResult EggShell_FindSubValue(TypeManagerRef tm, TypeRef typeRef, const char* eltName, TypeRef* typeRefLocation, void** dataRefLocation) +VIREO_EXPORT EggShellResult EggShell_FindSubValue(TypeManagerRef tm, const TypeRef typeRef, void * pData, const char* eltName, TypeRef* typeRefLocation, void** dataRefLocation) { if (typeRef == nullptr || !typeRef->IsValid()) return kEggShellResult_InvalidTypeRef; TypeManagerScope scope(tm); SubString path(eltName); - void* pData = typeRef->Begin(kPARead); *typeRefLocation = typeRef->GetSubElementAddressFromPath(&path, pData, dataRefLocation, true); if (*typeRefLocation == nullptr) return kEggShellResult_ObjectNotFoundAtPath; diff --git a/source/include/CEntryPoints.h b/source/include/CEntryPoints.h index 33fd3f36a..fe3f83d18 100644 --- a/source/include/CEntryPoints.h +++ b/source/include/CEntryPoints.h @@ -39,7 +39,7 @@ VIREO_EXPORT Int32 EggShell_PeekMemory(TypeManagerRef tm, const char* viName, co VIREO_EXPORT Int32 EggShell_PokeMemory(TypeManagerRef tm, const char* viName, const char* eltName, Int32 bufferSize, char* buffer); VIREO_EXPORT EggShellResult EggShell_FindValue(TypeManagerRef tm, const char* viName, const char* eltName, TypeRef* typeRefLocation, void** dataRefLocation); -VIREO_EXPORT EggShellResult EggShell_FindSubValue(TypeManagerRef tm, TypeRef type, const char* eltName, TypeRef* typeRefLocation, void** dataRefLocation); +VIREO_EXPORT EggShellResult EggShell_FindSubValue(TypeManagerRef tm, const TypeRef type, void *start, const char* eltName, TypeRef* typeRefLocation, void** dataRefLocation); VIREO_EXPORT EggShellResult EggShell_WriteDouble(TypeManagerRef tm, const TypeRef actualType, void* pData, Double value); VIREO_EXPORT EggShellResult EggShell_ReadDouble(TypeManagerRef tm, const TypeRef actualType, const void* pData, Double* result); VIREO_EXPORT EggShellResult EggShell_WriteValueString(TypeManagerRef tm, TypeRef typeRef, void* data, const char* format, const char* value); diff --git a/source/io/module_eggShell.js b/source/io/module_eggShell.js index 2a021a813..62cf07cb6 100644 --- a/source/io/module_eggShell.js +++ b/source/io/module_eggShell.js @@ -235,7 +235,7 @@ var typeStackPointer = Module.stackAlloc(POINTER_SIZE); var dataStackPointer = Module.stackAlloc(POINTER_SIZE); - var eggShellResult = Module._EggShell_FindSubValue(Module.eggShell.v_userShell, valueRef.typeRef, pathStackPointer, typeStackPointer, dataStackPointer); + var eggShellResult = Module._EggShell_FindSubValue(Module.eggShell.v_userShell, valueRef.typeRef, valueRef.dataRef, pathStackPointer, typeStackPointer, dataStackPointer); if (eggShellResult !== EGGSHELL_RESULT.SUCCESS) { throw new Error('A ValueRef could not be made for the following reason: ' + eggShellResultEnum[eggShellResult] + ' (error code: ' + eggShellResult + ')' + @@ -351,7 +351,7 @@ var stack = Module.stackSave(); var type = 'JSON'; - var valueStackPointer = Module.coreHelpers.writeJSStringToHeap(value); + var valueStackPointer = Module.coreHelpers.writeJSStringToStack(value); var typeStackPointer = Module.coreHelpers.writeJSStringToStack(type); var eggShellError = Module._EggShell_WriteValueString(Module.eggShell.v_userShell, valueRef.typeRef, valueRef.dataRef, typeStackPointer, valueStackPointer); diff --git a/test-it/karma/fixtures/publicapi/ReadWriteIntegration.via b/test-it/karma/fixtures/publicapi/ReadWriteIntegration.via new file mode 100644 index 000000000..fc607e38b --- /dev/null +++ b/test-it/karma/fixtures/publicapi/ReadWriteIntegration.via @@ -0,0 +1,22 @@ +define (MyVI dv(.VirtualInstrument ( + Locals: c( + e(.ErrorCluster uninitializedError) + e(dv(.ErrorCluster (false 0 '')) initializedError) + e(c( + e(.Boolean status) + e(.Int32 code) + e(.String source) + ) expandedError) + e(dv(c( + e(.Boolean status) + e(.Int32 code) + e(.String source) + ) (true 12345 'Is this the real life?')) initializedExpandedError) + ) + clump ( + + ) +))) + +enqueue (MyVI) +// Finished! \ No newline at end of file diff --git a/test-it/karma/publicapi/ReadWriteJson.Integration.Test.js b/test-it/karma/publicapi/ReadWriteJson.Integration.Test.js new file mode 100644 index 000000000..6aabf0a9d --- /dev/null +++ b/test-it/karma/publicapi/ReadWriteJson.Integration.Test.js @@ -0,0 +1,136 @@ +describe('The Vireo EggShell public api can', function () { + 'use strict'; + // Reference aliases + var Vireo = window.NationalInstruments.Vireo.Vireo; + var vireoRunner = window.testHelpers.vireoRunner; + var fixtures = window.testHelpers.fixtures; + + var vireo = new Vireo(); + + var publicApiReadWriteJSONViaUrl = fixtures.convertToAbsoluteFromFixturesDir('publicapi/ReadWriteIntegration.via'); + var viName = 'MyVI'; + + var readValue = function (valueRef) { + var json = vireo.eggShell.readJSON(valueRef); + return JSON.parse(json); + }; + + var readSubValue = function (valueRef, path) { + var subValueRef = vireo.eggShell.findSubValueRef(valueRef, path); + return readValue(subValueRef); + }; + + var writeValue = function (valueRef, value) { + var json = JSON.stringify(value); + vireo.eggShell.writeJSON(valueRef, json); + }; + + var writeSubValue = function (valueRef, subPath, value) { + var subValueRef = vireo.eggShell.findSubValueRef(valueRef, subPath); + writeValue(subValueRef, value); + }; + + var errorValue = { + status: true, + code: 12345, + source: 'Is this just fantasy?' + }; + + beforeAll(function (done) { + fixtures.preloadAbsoluteUrls([ + publicApiReadWriteJSONViaUrl + ], done); + }); + + beforeEach(function () { + vireo = new Vireo(); + vireoRunner.rebootAndLoadVia(vireo, publicApiReadWriteJSONViaUrl); + }); + + var testCases = [ + { + testName: 'error cluster with no default values', + path: 'uninitializedError' + }, + { + testName: 'error cluster with default values', + path: 'initializedError' + }, + { + testName: 'expanded error cluster with default values', + path: 'initializedExpandedError' + }, + { + testName: 'expanded error cluster with no default values', + path: 'expandedError' + } + ]; + + describe('write JSON and read each field with findSubValueRef of', function () { + testCases.forEach(function (testConfig) { + it(testConfig.testName, function () { + var valueRef = vireo.eggShell.findValueRef(viName, testConfig.path); + writeValue(valueRef, errorValue); + + expect(readSubValue(valueRef, 'status')).toEqual(errorValue.status); + expect(readSubValue(valueRef, 'code')).toEqual(errorValue.code); + expect(readSubValue(valueRef, 'source')).toEqual(errorValue.source); + + expect(readValue(valueRef)).toEqual(errorValue); + }); + }); + }); + + describe('write JSON and read each field with valueRefObject of', function () { + testCases.forEach(function (testConfig) { + it(testConfig.testName, function () { + var valueRef = vireo.eggShell.findValueRef(viName, testConfig.path); + writeValue(valueRef, errorValue); + var valueRefObject = vireo.eggShell.readValueRefObject(valueRef); + + expect(readValue(valueRefObject.status)).toEqual(errorValue.status); + expect(readValue(valueRefObject.code)).toEqual(errorValue.code); + expect(readValue(valueRefObject.source)).toEqual(errorValue.source); + + expect(readValue(valueRef)).toEqual(errorValue); + }); + }); + }); + + describe('write and read each field with valueRefObject of', function () { + testCases.forEach(function (testConfig) { + it(testConfig.testName, function () { + var valueRef = vireo.eggShell.findValueRef(viName, testConfig.path); + var valueRefObject = vireo.eggShell.readValueRefObject(valueRef); + + writeValue(valueRefObject.status, errorValue.status); + writeValue(valueRefObject.code, errorValue.code); + writeValue(valueRefObject.source, errorValue.source); + + expect(readValue(valueRefObject.status)).toEqual(errorValue.status); + expect(readValue(valueRefObject.code)).toEqual(errorValue.code); + expect(readValue(valueRefObject.source)).toEqual(errorValue.source); + + expect(readValue(valueRef)).toEqual(errorValue); + }); + }); + }); + + describe('write and read each field with findSubValueRef of', function () { + testCases.forEach(function (testConfig) { + it(testConfig.testName, function () { + var valueRef = vireo.eggShell.findValueRef(viName, testConfig.path); + + writeSubValue(valueRef, 'status', errorValue.status); + writeSubValue(valueRef, 'code', errorValue.code); + writeSubValue(valueRef, 'source', errorValue.source); + + expect(readSubValue(valueRef, 'status')).toEqual(errorValue.status); + expect(readSubValue(valueRef, 'code')).toEqual(errorValue.code); + expect(readSubValue(valueRef, 'source')).toEqual(errorValue.source); + + expect(readValue(valueRef)).toEqual(errorValue); + }); + }); + }); +}); From c01c7e2919d5a5ef46ff6ad82165d77e9e45d4a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Le=C3=B3n?= Date: Mon, 9 Jul 2018 10:08:15 -0500 Subject: [PATCH 62/67] Fixed linting errors --- source/core/CEntryPoints.cpp | 3 ++- source/include/CEntryPoints.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/source/core/CEntryPoints.cpp b/source/core/CEntryPoints.cpp index 7c99a8936..b7e5c8591 100644 --- a/source/core/CEntryPoints.cpp +++ b/source/core/CEntryPoints.cpp @@ -131,7 +131,8 @@ VIREO_EXPORT EggShellResult EggShell_FindValue(TypeManagerRef tm, const char* vi } //------------------------------------------------------------ //! Get a reference to the type pointer and data for a sub element -VIREO_EXPORT EggShellResult EggShell_FindSubValue(TypeManagerRef tm, const TypeRef typeRef, void * pData, const char* eltName, TypeRef* typeRefLocation, void** dataRefLocation) +VIREO_EXPORT EggShellResult EggShell_FindSubValue(TypeManagerRef tm, + const TypeRef typeRef, void * pData, const char* eltName, TypeRef* typeRefLocation, void** dataRefLocation) { if (typeRef == nullptr || !typeRef->IsValid()) return kEggShellResult_InvalidTypeRef; diff --git a/source/include/CEntryPoints.h b/source/include/CEntryPoints.h index fe3f83d18..ae6307c1c 100644 --- a/source/include/CEntryPoints.h +++ b/source/include/CEntryPoints.h @@ -39,7 +39,8 @@ VIREO_EXPORT Int32 EggShell_PeekMemory(TypeManagerRef tm, const char* viName, co VIREO_EXPORT Int32 EggShell_PokeMemory(TypeManagerRef tm, const char* viName, const char* eltName, Int32 bufferSize, char* buffer); VIREO_EXPORT EggShellResult EggShell_FindValue(TypeManagerRef tm, const char* viName, const char* eltName, TypeRef* typeRefLocation, void** dataRefLocation); -VIREO_EXPORT EggShellResult EggShell_FindSubValue(TypeManagerRef tm, const TypeRef type, void *start, const char* eltName, TypeRef* typeRefLocation, void** dataRefLocation); +VIREO_EXPORT EggShellResult EggShell_FindSubValue(TypeManagerRef tm, const TypeRef type, void *start, const char* eltName, + TypeRef* typeRefLocation, void** dataRefLocation); VIREO_EXPORT EggShellResult EggShell_WriteDouble(TypeManagerRef tm, const TypeRef actualType, void* pData, Double value); VIREO_EXPORT EggShellResult EggShell_ReadDouble(TypeManagerRef tm, const TypeRef actualType, const void* pData, Double* result); VIREO_EXPORT EggShellResult EggShell_WriteValueString(TypeManagerRef tm, TypeRef typeRef, void* data, const char* format, const char* value); From 558ff6fca6e276013d82d4f5614f92e43f76e0a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Le=C3=B3n?= Date: Mon, 9 Jul 2018 12:50:06 -0500 Subject: [PATCH 63/67] Renamed tests --- .../{ReadWriteIntegration.via => ReadWriteErrorCluster.via} | 0 ...teJson.Integration.Test.js => ReadWriteErrorCluster.Test.js} | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename test-it/karma/fixtures/publicapi/{ReadWriteIntegration.via => ReadWriteErrorCluster.via} (100%) rename test-it/karma/publicapi/{ReadWriteJson.Integration.Test.js => ReadWriteErrorCluster.Test.js} (98%) diff --git a/test-it/karma/fixtures/publicapi/ReadWriteIntegration.via b/test-it/karma/fixtures/publicapi/ReadWriteErrorCluster.via similarity index 100% rename from test-it/karma/fixtures/publicapi/ReadWriteIntegration.via rename to test-it/karma/fixtures/publicapi/ReadWriteErrorCluster.via diff --git a/test-it/karma/publicapi/ReadWriteJson.Integration.Test.js b/test-it/karma/publicapi/ReadWriteErrorCluster.Test.js similarity index 98% rename from test-it/karma/publicapi/ReadWriteJson.Integration.Test.js rename to test-it/karma/publicapi/ReadWriteErrorCluster.Test.js index 6aabf0a9d..361ee224b 100644 --- a/test-it/karma/publicapi/ReadWriteJson.Integration.Test.js +++ b/test-it/karma/publicapi/ReadWriteErrorCluster.Test.js @@ -7,7 +7,7 @@ describe('The Vireo EggShell public api can', function () { var vireo = new Vireo(); - var publicApiReadWriteJSONViaUrl = fixtures.convertToAbsoluteFromFixturesDir('publicapi/ReadWriteIntegration.via'); + var publicApiReadWriteJSONViaUrl = fixtures.convertToAbsoluteFromFixturesDir('publicapi/ReadWriteErrorCluster.via'); var viName = 'MyVI'; var readValue = function (valueRef) { From 32b5f737443fc4055693a1ce40cecf7660dd5a74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Le=C3=B3n?= Date: Mon, 9 Jul 2018 13:36:23 -0500 Subject: [PATCH 64/67] Reverted writeJSStringToStack and added a free memory on writeJSON. --- source/io/module_eggShell.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/io/module_eggShell.js b/source/io/module_eggShell.js index 62cf07cb6..88d4ff6ec 100644 --- a/source/io/module_eggShell.js +++ b/source/io/module_eggShell.js @@ -351,7 +351,7 @@ var stack = Module.stackSave(); var type = 'JSON'; - var valueStackPointer = Module.coreHelpers.writeJSStringToStack(value); + var valueStackPointer = Module.coreHelpers.writeJSStringToHeap(value); var typeStackPointer = Module.coreHelpers.writeJSStringToStack(type); var eggShellError = Module._EggShell_WriteValueString(Module.eggShell.v_userShell, valueRef.typeRef, valueRef.dataRef, typeStackPointer, valueStackPointer); @@ -362,6 +362,7 @@ ' (dataRef: ' + valueRef.dataRef + ')'); } + Module._free(valueStackPointer); Module.stackRestore(stack); }; From 1eef26cf1e1fe529a993d1c164c2c818f21e994a Mon Sep 17 00:00:00 2001 From: Guillermo Leon Date: Mon, 9 Jul 2018 18:47:38 -0500 Subject: [PATCH 65/67] Type support feedback (#4) * Adressed feedback from PR * Renamed subpathstackPointer * Fixing typo, variable names and TypeManagerScope for FindValue. * Renamed pData in header --- source/core/CEntryPoints.cpp | 37 +++++++++++++++--------------- source/core/StringUtilities.cpp | 2 +- source/core/TypeAndDataManager.cpp | 3 +-- source/include/CEntryPoints.h | 8 +++---- source/include/StringUtilities.h | 2 +- source/io/module_eggShell.js | 8 +++---- 6 files changed, 30 insertions(+), 30 deletions(-) diff --git a/source/core/CEntryPoints.cpp b/source/core/CEntryPoints.cpp index b7e5c8591..b425921f2 100644 --- a/source/core/CEntryPoints.cpp +++ b/source/core/CEntryPoints.cpp @@ -121,6 +121,7 @@ VIREO_EXPORT Int32 EggShell_PokeMemory(TypeManagerRef tm, //! Get a reference to the type pointer and data for a symbol. VIREO_EXPORT EggShellResult EggShell_FindValue(TypeManagerRef tm, const char* viName, const char* eltName, TypeRef* typeRefLocation, void** dataRefLocation) { + TypeManagerScope scope(tm); SubString objectName(viName); SubString path(eltName); *typeRefLocation = tm->GetObjectElementAddressFromPath(&objectName, &path, dataRefLocation, true); @@ -177,7 +178,7 @@ VIREO_EXPORT EggShellResult EggShell_ReadDouble(TypeManagerRef tm, const TypeRef } //------------------------------------------------------------ // Write a string value to a symbol. Value will be parsed according to format designated. -VIREO_EXPORT EggShellResult EggShell_WriteValueString(TypeManagerRef tm, const TypeRef typeRef, void* data, const char* format, const char* value) +VIREO_EXPORT EggShellResult EggShell_WriteValueString(TypeManagerRef tm, const TypeRef typeRef, void* pData, const char* format, const char* value) { TypeManagerScope scope(tm); @@ -189,16 +190,16 @@ VIREO_EXPORT EggShellResult EggShell_WriteValueString(TypeManagerRef tm, const T EventLog log(EventLog::DevNull); SubString formatss(format); TDViaParser parser(tm, &valueString, &log, 1, &formatss, true, true, true); - Int32 error = parser.ParseData(typeRef, data); + Int32 error = parser.ParseData(typeRef, pData); if (error) { - return kEggSehllResult_UnableToParseData; + return kEggShellResult_UnableToParseData; } return kEggShellResult_Success; } //------------------------------------------------------------ -//! Read a symbol's value as a string. Value will be formatted according to the format designated. -VIREO_EXPORT EggShellResult EggShell_ReadValueString(TypeManagerRef tm, const TypeRef typeRef, void* data, const char* format, UInt8** valueString) +//! Read a symbol's value as a string. Value will be formatted according to designated format. +VIREO_EXPORT EggShellResult EggShell_ReadValueString(TypeManagerRef tm, const TypeRef typeRef, void* pData, const char* format, UInt8** valueString) { TypeManagerScope scope(tm); @@ -218,8 +219,8 @@ VIREO_EXPORT EggShellResult EggShell_ReadValueString(TypeManagerRef tm, const Ty if (returnBuffer) { SubString formatss(format); TDViaFormatter formatter(returnBuffer, true, 0, &formatss, kJSONEncodingEggShell); - formatter.FormatData(typeRef, data); - // Add an explicit nullptr terminator so it looks like a C string. + formatter.FormatData(typeRef, pData); + // Add an explicit null terminator so it looks like a C string. returnBuffer->Append((Utf8Char)'\0'); *valueString = returnBuffer->Begin(); return kEggShellResult_Success; @@ -285,7 +286,7 @@ VIREO_EXPORT Int32 EggShell_GetArrayDimLength(TypeManagerRef tm, const char* viN //------------------------------------------------------------ //! Resizes a variable size Array symbol to have new dimension lengths specified by newLengths, it also initializes cells for non-flat data. VIREO_EXPORT EggShellResult EggShell_ResizeArray(TypeManagerRef tm, const TypeRef typeRef, const void* pData, - Int32 newDimensionsLength, Int32 newDimensions[]) + Int32 rank, Int32 dimensionLengths[]) { TypeManagerScope scope(tm); if (typeRef == nullptr || !typeRef->IsValid()) @@ -294,13 +295,13 @@ VIREO_EXPORT EggShellResult EggShell_ResizeArray(TypeManagerRef tm, const TypeRe if (!typeRef->IsArray()) return kEggShellResult_UnexpectedObjectType; - if (typeRef->Rank() != newDimensionsLength) + if (typeRef->Rank() != rank) return kEggShellResult_MismatchedArrayRank; TypedArrayCoreRef arrayObject = *(TypedArrayCoreRef*)pData; VIREO_ASSERT(TypedArrayCore::ValidateHandle(arrayObject)); - if (!arrayObject->ResizeDimensions(newDimensionsLength, newDimensions, true, false)) { + if (!arrayObject->ResizeDimensions(rank, dimensionLengths, true, false)) { return kEggShellResult_UnableToCreateReturnBuffer; } return kEggShellResult_Success; @@ -373,12 +374,12 @@ VIREO_EXPORT void* Data_GetArrayBegin(const void* pData) //------------------------------------------------------------ //! Get the values for dimensions of the array. Assumes dimensions target is of length equal to rank //! Caller is expected to allocate an array dimensions of size array rank for the duration of function invocation. -VIREO_EXPORT void Data_GetArrayDimensions(const void* pData, IntIndex dimensions[]) +VIREO_EXPORT void Data_GetArrayDimensions(const void* pData, IntIndex dimensionsLengths[]) { TypedArrayCoreRef arrayObject = *(TypedArrayCoreRef*)pData; VIREO_ASSERT(TypedArrayCore::ValidateHandle(arrayObject)); for (int i = 0; i < arrayObject->Rank(); i++) { - dimensions[i] = arrayObject->GetLength(i); + dimensionsLengths[i] = arrayObject->GetLength(i); } } //------------------------------------------------------------ @@ -578,12 +579,12 @@ VIREO_EXPORT const char* TypeRef_Name(TypeManagerRef tm, TypeRef typeRef) STACK_VAR(String, tempReturn); returnBuffer = tempReturn.DetachValue(); } else { - returnBuffer->Resize1D(0); + returnBuffer->Resize1D(name.Length() + 1); } if (returnBuffer) { - returnBuffer->AppendSubString(&name); - // Add an explicit nullptr terminator so it looks like a C string. + returnBuffer->CopyFromSubString(&name); + // Add an explicit null terminator so it looks like a C string. returnBuffer->Append((Utf8Char)'\0'); return (const char*) returnBuffer->Begin(); } @@ -603,12 +604,12 @@ VIREO_EXPORT const char* TypeRef_ElementName(TypeManagerRef tm, TypeRef typeRef) STACK_VAR(String, tempReturn); returnBuffer = tempReturn.DetachValue(); } else { - returnBuffer->Resize1D(0); + returnBuffer->Resize1D(name.Length() + 1); } if (returnBuffer) { - returnBuffer->AppendSubString(&name); - // Add an explicit nullptr terminator so it looks like a C string. + returnBuffer->CopyFromSubString(&name); + // Add an explicit null terminator so it looks like a C string. returnBuffer->Append((Utf8Char)'\0'); return (const char*) returnBuffer->Begin(); } diff --git a/source/core/StringUtilities.cpp b/source/core/StringUtilities.cpp index 0be75e1f4..6cbb4d673 100644 --- a/source/core/StringUtilities.cpp +++ b/source/core/StringUtilities.cpp @@ -1073,7 +1073,7 @@ void SubString::TrimQuotedString(TokenTraits tt) } } //------------------------------------------------------------ -IntIndex SubString::FindFirstMatch(SubString* searchString, IntIndex offset, Boolean ignoreCase) +IntIndex SubString::FindFirstMatch(const SubString* searchString, IntIndex offset, Boolean ignoreCase) { IntIndex searchStringLength = searchString->Length(); if (Length() == 0 || searchStringLength > Length()) diff --git a/source/core/TypeAndDataManager.cpp b/source/core/TypeAndDataManager.cpp index 387c442a5..f9710e41c 100644 --- a/source/core/TypeAndDataManager.cpp +++ b/source/core/TypeAndDataManager.cpp @@ -1006,8 +1006,7 @@ Boolean TypeCommon::IsAnalogWaveform() TypeRef t = this; while (t) { SubString typeName = t->Name(); - SubString analogTypess(TypeAnalogWaveform); - if (typeName.FindFirstMatch(&analogTypess, 0, false) == 0) { + if (typeName.FindFirstMatch(&TypeAnalogWaveform, 0, false) == 0) { return true; } t = t->BaseType(); diff --git a/source/include/CEntryPoints.h b/source/include/CEntryPoints.h index ae6307c1c..78874138b 100644 --- a/source/include/CEntryPoints.h +++ b/source/include/CEntryPoints.h @@ -23,7 +23,7 @@ typedef enum { kEggShellResult_UnableToCreateReturnBuffer = 4, kEggShellResult_InvalidTypeRef = 5, kEggShellResult_MismatchedArrayRank = 6, - kEggSehllResult_UnableToParseData = 7, + kEggShellResult_UnableToParseData = 7, } EggShellResult; //------------------------------------------------------------ //! TypeManager functions @@ -43,20 +43,20 @@ VIREO_EXPORT EggShellResult EggShell_FindSubValue(TypeManagerRef tm, const TypeR TypeRef* typeRefLocation, void** dataRefLocation); VIREO_EXPORT EggShellResult EggShell_WriteDouble(TypeManagerRef tm, const TypeRef actualType, void* pData, Double value); VIREO_EXPORT EggShellResult EggShell_ReadDouble(TypeManagerRef tm, const TypeRef actualType, const void* pData, Double* result); -VIREO_EXPORT EggShellResult EggShell_WriteValueString(TypeManagerRef tm, TypeRef typeRef, void* data, const char* format, const char* value); +VIREO_EXPORT EggShellResult EggShell_WriteValueString(TypeManagerRef tm, TypeRef typeRef, void* pData, const char* format, const char* value); VIREO_EXPORT EggShellResult EggShell_ReadValueString(TypeManagerRef tm, TypeRef typeRef, void* pData, const char* format, UInt8** valueString); VIREO_EXPORT EggShellResult EggShell_GetPointer(TypeManagerRef tm, const char* viName, const char* elementName, void** dataPointer, void** typePointer); VIREO_EXPORT Int32 EggShell_GetArrayDimLength(TypeManagerRef tm, const char* viName, const char* eltName, Int32 dim); VIREO_EXPORT EggShellResult EggShell_ResizeArray(TypeManagerRef tm, const TypeRef actualType, const void* pData, - Int32 newDimensionsLength, Int32 newDimensions[]); + Int32 rank, Int32 dimensionLengths[]); VIREO_EXPORT EggShellResult Data_ValidateArrayType(TypeManagerRef tm, TypeRef typeRef); VIREO_EXPORT void* Data_GetStringBegin(StringRef stringObject); VIREO_EXPORT Int32 Data_GetStringLength(StringRef stringObject); VIREO_EXPORT EggShellResult Data_GetArrayMetadata(TypeManagerRef tm, TypedArrayCoreRef arrayObject, char** arrayTypeName, Int32* arrayRank, unsigned char** arrayBegin); VIREO_EXPORT void* Data_GetArrayBegin(const void* pData); -VIREO_EXPORT void Data_GetArrayDimensions(const void* pData, IntIndex dimensions[]); +VIREO_EXPORT void Data_GetArrayDimensions(const void* pData, IntIndex dimensionsLengths[]); VIREO_EXPORT Int32 Data_GetArrayLength(const void* pData); VIREO_EXPORT Int32 Data_GetArrayDimLength(TypeManagerRef tm, TypedArrayCoreRef arrayObject, Int32 dim); VIREO_EXPORT Int32 Data_ResizeArray(TypeManagerRef tm, TypedArrayCoreRef arrayObject, Int32 rank, Int32* newLengths); diff --git a/source/include/StringUtilities.h b/source/include/StringUtilities.h index ed665ebc1..447243954 100644 --- a/source/include/StringUtilities.h +++ b/source/include/StringUtilities.h @@ -328,7 +328,7 @@ class SubString : public SubVector //! based on previously determined token trait. void TrimQuotedString(TokenTraits tt); - IntIndex FindFirstMatch(SubString* searchString, IntIndex offset, Boolean ignoreCase); + IntIndex FindFirstMatch(const SubString* searchString, IntIndex offset, Boolean ignoreCase); }; //------------------------------------------------------------ diff --git a/source/io/module_eggShell.js b/source/io/module_eggShell.js index 88d4ff6ec..7a58e382f 100644 --- a/source/io/module_eggShell.js +++ b/source/io/module_eggShell.js @@ -228,19 +228,19 @@ return valueRef; }; - Module.eggShell.findSubValueRef = publicAPI.eggShell.findSubValueRef = function (valueRef, path) { + Module.eggShell.findSubValueRef = publicAPI.eggShell.findSubValueRef = function (valueRef, subPath) { var stack = Module.stackSave(); - var pathStackPointer = Module.coreHelpers.writeJSStringToStack(path); + var subPathStackPointer = Module.coreHelpers.writeJSStringToStack(subPath); var typeStackPointer = Module.stackAlloc(POINTER_SIZE); var dataStackPointer = Module.stackAlloc(POINTER_SIZE); - var eggShellResult = Module._EggShell_FindSubValue(Module.eggShell.v_userShell, valueRef.typeRef, valueRef.dataRef, pathStackPointer, typeStackPointer, dataStackPointer); + var eggShellResult = Module._EggShell_FindSubValue(Module.eggShell.v_userShell, valueRef.typeRef, valueRef.dataRef, subPathStackPointer, typeStackPointer, dataStackPointer); if (eggShellResult !== EGGSHELL_RESULT.SUCCESS) { throw new Error('A ValueRef could not be made for the following reason: ' + eggShellResultEnum[eggShellResult] + ' (error code: ' + eggShellResult + ')' + ' (type name: ' + Module.typeHelpers.typeName(valueRef.typeRef) + ')' + - ' (path: ' + path + ')'); + ' (subpath: ' + subPath + ')'); } var typeRef = Module.getValue(typeStackPointer, 'i32'); From 7754218659624dc3034104027e5b04441f1822de Mon Sep 17 00:00:00 2001 From: Guillermo Leon Date: Tue, 10 Jul 2018 15:24:36 -0500 Subject: [PATCH 66/67] Type support feedback5 (#5) * Changed test names to from types to values to keep them consistent * Added an extra line at the end to remove red marker * Improving readibility by having signed type checks in same line --- source/core/TypeAndDataManager.cpp | 14 +++++--------- .../fixtures/publicapi/ReadWriteErrorCluster.via | 2 +- test-it/karma/publicapi/Double.Test.js | 10 +++++----- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/source/core/TypeAndDataManager.cpp b/source/core/TypeAndDataManager.cpp index f9710e41c..fdf4bc326 100644 --- a/source/core/TypeAndDataManager.cpp +++ b/source/core/TypeAndDataManager.cpp @@ -862,11 +862,9 @@ Boolean TypeCommon::IsNumeric() { TypeRef t = this; while (t) { - if (t->Name().Compare(&TypeInt8) || t->Name().Compare(&TypeInt16) || t->Name().Compare(&TypeInt32) - || t->Name().Compare(&TypeInt64) || t->Name().Compare(&TypeUInt8) - || t->Name().Compare(&TypeUInt16) || t->Name().Compare(&TypeUInt32) - || t->Name().Compare(&TypeUInt64) || t->Name().Compare(&TypeSingle) - || t->Name().Compare(&TypeDouble)) { + if (t->Name().Compare(&TypeInt8) || t->Name().Compare(&TypeInt16) || t->Name().Compare(&TypeInt32) || t->Name().Compare(&TypeInt64) + || t->Name().Compare(&TypeUInt8) || t->Name().Compare(&TypeUInt16) || t->Name().Compare(&TypeUInt32) || t->Name().Compare(&TypeUInt64) + || t->Name().Compare(&TypeSingle) || t->Name().Compare(&TypeDouble)) { return true; } t = t->BaseType(); @@ -878,10 +876,8 @@ Boolean TypeCommon::IsInteger() { TypeRef t = this; while (t) { - if (t->Name().Compare(&TypeInt8) || t->Name().Compare(&TypeInt16) || t->Name().Compare(&TypeInt32) - || t->Name().Compare(&TypeInt64) || t->Name().Compare(&TypeUInt8) - || t->Name().Compare(&TypeUInt16) || t->Name().Compare(&TypeUInt32) - || t->Name().Compare(&TypeUInt64)) { + if (t->Name().Compare(&TypeInt8) || t->Name().Compare(&TypeInt16) || t->Name().Compare(&TypeInt32) || t->Name().Compare(&TypeInt64) + || t->Name().Compare(&TypeUInt8) || t->Name().Compare(&TypeUInt16) || t->Name().Compare(&TypeUInt32) || t->Name().Compare(&TypeUInt64)) { return true; } t = t->BaseType(); diff --git a/test-it/karma/fixtures/publicapi/ReadWriteErrorCluster.via b/test-it/karma/fixtures/publicapi/ReadWriteErrorCluster.via index fc607e38b..d1093b303 100644 --- a/test-it/karma/fixtures/publicapi/ReadWriteErrorCluster.via +++ b/test-it/karma/fixtures/publicapi/ReadWriteErrorCluster.via @@ -19,4 +19,4 @@ define (MyVI dv(.VirtualInstrument ( ))) enqueue (MyVI) -// Finished! \ No newline at end of file +// Finished! diff --git a/test-it/karma/publicapi/Double.Test.js b/test-it/karma/publicapi/Double.Test.js index 26ec6eec3..139b04357 100644 --- a/test-it/karma/publicapi/Double.Test.js +++ b/test-it/karma/publicapi/Double.Test.js @@ -72,7 +72,7 @@ describe('The Vireo EggShell Double api can', function () { expect(readDouble('dataItem_NumericDoubleNegativeZero')).toMatchIEEE754Number(-0); }); - it('to read different integer types from memory', function () { + it('to read different integer values from memory', function () { expect(readDouble('int8MinValue')).toBe(-128); expect(readDouble('int8MaxValue')).toBe(127); expect(readDouble('int16MinValue')).toBe(-32768); @@ -95,14 +95,14 @@ describe('The Vireo EggShell Double api can', function () { expect(readDouble('uInt64MaxValue')).toBe(18446744073709552000); // Expected precision loss, full value 18446744073709551615 }); - it('to read different enum types from memory', function () { + it('to read different enum values from memory', function () { expect(readDouble('enum8alphabet')).toBe(6); expect(readDouble('enum16numbers')).toBe(3); expect(readDouble('enum32colors')).toBe(2); expect(readDouble('enum64releases')).toBe(5); }); - it('to read different boolean types from memory', function () { + it('to read different boolean values from memory', function () { expect(readDouble('booleanTrueValue')).toBe(1); expect(readDouble('booleanFalseValue')).toBe(0); }); @@ -169,14 +169,14 @@ describe('The Vireo EggShell Double api can', function () { expect(expectedCoercedValue(Int8Array, 0)).toBe(0); }); - it('to write different enum types to memory', function () { + it('to write different enum values to memory', function () { testWriteDouble('enum8alphabet', 6, 4); testWriteDouble('enum16numbers', 3, 4); testWriteDouble('enum32colors', 2, 4); testWriteDouble('enum64releases', 5, 4); }); - it('to write different boolean types to memory', function () { + it('to write different boolean values to memory', function () { testWriteDouble('booleanTrueValue', 1, 0); testWriteDoubleCoerced('booleanTrueValue', 1, 70, 1); testWriteDoubleCoerced('booleanTrueValue', 1, -70, 1); From 84987421777cbbbb96815cae1573514da249c315 Mon Sep 17 00:00:00 2001 From: rajsite Date: Tue, 10 Jul 2018 19:38:44 -0500 Subject: [PATCH 67/67] Use decoded field names in readValueRefObject --- source/core/vireo.loader.js | 5 +++++ source/io/module_eggShell.js | 8 ++++--- .../fixtures/publicapi/MultipleTypes.via | 12 +++++++++++ .../publicapi/ReadValueRefObject.Test.js | 21 +++++++++++++++++++ 4 files changed, 43 insertions(+), 3 deletions(-) diff --git a/source/core/vireo.loader.js b/source/core/vireo.loader.js index 69c759ebb..2047dba2a 100644 --- a/source/core/vireo.loader.js +++ b/source/core/vireo.loader.js @@ -89,6 +89,11 @@ if (typeof createVireoCore !== 'function') { throw new Error('createVireoCore could not be found, make sure to build and include vireo.js before using'); } + + // Save a Vireo class reference on the module instance so the instance can access static functions on the class + // TODO(mraj) Instead use the static functions directly when we switch to ES6 modules and can resolve the Vireo class correctly + Module.Vireo = Vireo; + createVireoCore(Module); moduleBuilders.forEach(function (currBuilder) { currBuilder(Module, that); diff --git a/source/io/module_eggShell.js b/source/io/module_eggShell.js index 7a58e382f..12afbc6e1 100644 --- a/source/io/module_eggShell.js +++ b/source/io/module_eggShell.js @@ -263,10 +263,12 @@ var fieldCount = Module.typeHelpers.subElementCount(typeRef); + var fieldTypeRef, fieldNameEncoded, fieldName; for (var i = 0; i < fieldCount; i += 1) { - var fieldTypeRef = Module.typeHelpers.subElementByIndex(typeRef, i); - var fieldName = Module.typeHelpers.elementName(fieldTypeRef); - valueRefs[fieldName] = Module.eggShell.findSubValueRef(valueRef, fieldName); + fieldTypeRef = Module.typeHelpers.subElementByIndex(typeRef, i); + fieldNameEncoded = Module.typeHelpers.elementName(fieldTypeRef); + fieldName = Module.Vireo.decodeIdentifier(fieldNameEncoded); + valueRefs[fieldName] = Module.eggShell.findSubValueRef(valueRef, fieldNameEncoded); } return valueRefs; diff --git a/test-it/karma/fixtures/publicapi/MultipleTypes.via b/test-it/karma/fixtures/publicapi/MultipleTypes.via index c78316831..61d3fec52 100644 --- a/test-it/karma/fixtures/publicapi/MultipleTypes.via +++ b/test-it/karma/fixtures/publicapi/MultipleTypes.via @@ -36,6 +36,18 @@ define (MyVI dv(.VirtualInstrument ( ) (true 'first' 3.14159 42 -72057594037927936 9223372041149743104 (3.4 -5.9) (3564057536 7811758927381448193) ) ) dataItem_ClusterOfScalars) + e(dv(c( + e(.Boolean bool%20fun) + e(.String string%20fun) + e(.Double double%20fun) + e(.Int32 int32%20fun) + e(.Int64 int64%20fun) + e(.UInt64 uint64%20fun) + e(.ComplexDouble complex%20fun) + e(.Timestamp time%20fun) + ) (true 'first' 3.14159 42 -72057594037927936 9223372041149743104 (3.4 -5.9) (3564057536 7811758927381448193) ) + ) dataItem_ClusterOfEncodedScalars) + e(dv(c( e(a(.Boolean *) booleans) e(a(.String *) strings) diff --git a/test-it/karma/publicapi/ReadValueRefObject.Test.js b/test-it/karma/publicapi/ReadValueRefObject.Test.js index fe4379d05..d117b8a64 100644 --- a/test-it/karma/publicapi/ReadValueRefObject.Test.js +++ b/test-it/karma/publicapi/ReadValueRefObject.Test.js @@ -60,6 +60,27 @@ describe('The Vireo EggShell readValueRefObject', function () { }); }); + describe('for a cluster of scalars with encoded field names', function () { + var valueRef, + clusterOfScalarsPath = 'dataItem_ClusterOfEncodedScalars'; + + beforeAll(function () { + valueRef = vireo.eggShell.findValueRef(viName, clusterOfScalarsPath); + }); + + it('returns an object with decoded field names as keys', function () { + var objectRef = vireo.eggShell.readValueRefObject(valueRef); + expect(objectRef['bool fun']).toBeDefined(); + expect(objectRef['string fun']).toBeDefined(); + expect(objectRef['double fun']).toBeDefined(); + expect(objectRef['int32 fun']).toBeDefined(); + expect(objectRef['int64 fun']).toBeDefined(); + expect(objectRef['uint64 fun']).toBeDefined(); + expect(objectRef['complex fun']).toBeDefined(); + expect(objectRef['time fun']).toBeDefined(); + }); + }); + describe('for a timestamp', function () { var valueRef, timestampPath = 'dataItem_Timestamp';