UNPKG

ni-data-types

Version:

Non-standard data types used by the webcharts team.

286 lines (201 loc) 11.2 kB
# NIType Contains all the information needed to correctly describe a data type. Helper methods to explore type properties. ## Supported data types * Boolean * Int8 * Int16 * Int32 * Int64 * UInt8 * UInt16 * UInt32 * UInt64 * Single * Double * ComplexSingle * ComplexDouble * String * Path * Timestamp * Enum * Cluster * Array * AnalogWaveform * DigitalWaveform ## Usage It can be constructed from a JSON string that at least contains `name` property that maps to one of the names in `window.NITypeNames`. Examples: ```javascript var int16Type = new NIType('{"name":"Int16"}'); var stringType = new NIType('{"name":"String"}'); ``` Is also possible to use a full notation JS Object like ```javascript var arrayType = new NIType({name: 'Array', rank: 1, subtype: {name: 'String'}}); var clusterType = new NIType({name: 'Cluster', fields: ['One', 'Two'], subtype: [{name: 'Boolean'}, {name: 'UInt8'}]}); ``` Or simply use short-notation JS objects ```javascript var arrayType = new NIType({name: 'Array', rank: 1, subtype: 'Path'}); var clusterType = new NIType({name: 'Cluster', fields: ['One', 'Two'], subtype: ['Boolean', 'UInt16']}); ``` To reduce overhead a little, you can also just pass the name of the type as a JSON string. ```javascript var int16Type = new NIType('"Int16"'); var stringType = new NIType('"String"'); ``` This is true for all simple types (Only require the type `name`): * Void * Boolean * Int8 * Int16 * Int32 * Int64 * UInt8 * UInt16 * UInt32 * UInt64 * Single * Double * ComplexSingle * ComplexDouble * String * Path * Timestamp * DigitalWaveform There are other types that require extra information to be described correctly. ### Enum In addition of having the `name` property with value `NITypeNames.ENUM`. It must have a `subtype` property with a valid descriptor for `UInt8`, `UInt16`, `UInt32`. Example: ```javascript var enumType = new NIType('{"name":"Enum","subtype":{"name":"UInt32"}}'); var shortEnumType = new NIType('{"name":"Enum","subtype":"UInt16"}'); var invalidEnumType = new NIType('{"name":"Enum","subtype":"Int64"}'); // This would throw. Invalid subtype. ``` ### Array Must have as `name` property the string in `NITypeNames.ARRAY`. It must contain a `subtype` property with a valid descriptor for any type except `Array`. It should have a `rank` property, a positive integer for the number of dimensions in the array. Optionally, for a fixed-size array, the property `size` is available, which must map to an array of integers describing the size of each dimension of the `Array`. Example: ```javascript var arrayType = new NIType('{"name":"Array","subtype":{"name":"String"},"rank":1}'); // Variable size 1-D array var shortArrayType = new NIType('{"name":"Array","subtype":"Timestamp","rank":3}'); var fixedSizeArrayType = new NIType('{"name":"Array","subtype":"Boolean","rank":2,"size":[2,3]}'); // 2-D array (2 by 3) of booleans. var invalidType = new NIType('{"name":"Array","subtype":{"name":"Array","rank":1,"subtype":"Path"},"rank":1}'); // This throws. For an array of arrays better use multidimensional array. ``` ### Cluster For the cluster descriptor, the `name` property must be `NITypeNames.CLUSTER`. It must contain a `fields` property also, which points to an array of strings. Each string in said array must be the name of the variable in the cluster. The `subtype` property is optional, but if provided must be an array of valid descriptors. Each variable name from `fields` maps to the descriptor in `subtype`, therefore both arrays must be of the same length. Examples: ```javascript var clusterType = new NIType('{"name":"Cluster","fields":[]}'); // Empty cluster. var clusterBooleanType = new NIType('{"name":"Cluster","fields":["Power Button"],"subtype":[{"name":"Boolean"}]}'); var clusterShortIntType = new NIType('{"name":"Cluster","fields":["Power Button"],"subtype":["Int16"]}'); var invalidSubtypeClusterType = new NIType('{"name":"Cluster","fields":["First"],"subtype":[]}'); // This throws. subtype.length === fields.length, must be true. ``` ### AnalogWaveform An analog waveform descriptor must have its `name` property assigned to `NITypeNames.ANALOGWAVEFORM`. The other required property is `subtype` and it must be a numeric, this includes: integers, unsigned integers, floating point and complex types. ## Type helper methods Once an instance is succesfully created, you can use its helper functions to find out about the properties of the type. ### General types methods All types have their own `is{TypeName}()`, which returns true if the type described is actually the {TypeName} of the method. (See the list above to see the names) Examples: ```javascript var booleanType = new NIType('"Boolean"'); console.log(booleanType.isBoolean()); // This prints "true" console.log(booleanType.isString()); // This prints "false" var arrayType = new NIType('{"name":"Array","subtype":"UInt16","rank":1}'); console.log(arrayType.isArray()); // This prints "true" ``` `getName()` returns the name of the type. Its value matches one in the enum `NITypeNames`. ```javascript // Therefore is possible to implement something like: switch(descriptor.getName()) { case NITypeNames.PATH: case NITypeNames.STRING: // Do something } ``` `makeArray(rank, size)` creates a new instance of NIType that describes an array of the instances that calls this. It can be called on any type except *Array*. `size` is either `undefined` for variable size arrays or an array of integers for fixed-size arrays. ```javascript var arrayOfDoublesType = NITypes.DOUBLE.makeArray(); // 1 dimensional variable sized array. console.log(arrayOfDoublesType.isArray()); // true console.log(arrayOfDoublesType.getRank()); // 1 var arrayOfStrings3d = NITypes.STRING.makeArray(3); console.log(arrayOfStrings3d.getRank()); // 3 var fixed2darray = NITypes.UINT16.makeArray(2, [100, 100]); // 2 dimensional fixed size array of 100 x 100 UInt16 console.log(fixed2darray.getSize()); // [100, 100] ``` `equals(NIType)` returns true if all the properties from the type descriptor provided as parameter match the instance recursively. Examples: ```javascript var arrayType1 = new NIType('{"name":"Array","rank":1,"subtype":"Boolean"}'); var arrayType2 = new NIType('{"name":"Array","rank":1,"subtype":"Boolean"}'); var areArraysEqual = arraType1.equals(arrayType2); // This is true var arrayOfClusters = new NIType('{"name":"Array","rank":1,"subtype":{"name":"Cluster","fields":["A"]}}'); var array2DOfClusters = new NIType('{"name":"Array","rank":2,"subtype":{"name":"Cluster","fields":["A"]}}'); var areArraysOfClusterEquals = arrayOfClusters.equals(array2DOfClusters); // This is false since rank is different. // Clusters fields and subtypes order must match. var clusterType = new NIType('{"name":"Cluster","fields":["A","B","C"],"subtype":["Boolean","UInt8","String"]}'); var clusterType2 = new NIType('{"name":"Cluster","fields":["A","B","C"],"subtype":["Boolean","ComplexSingle","String"]}'); var areClustersEqual = clusterType.equals(clusterType2); // This is false, subtype[1] are different. // However order declaration doesn't affect equality clusterType = new NIType('{"name":"Cluster","fields":["A","B","C"],"subtype":["Boolean","UInt8","String"]}'); clusterType2 = new NIType('{"subtype":["Boolean","UInt8","String"],"name":"Cluster","fields":["A","B","C"]}'); areClustersEqual = clusterType.equals(clusterType2); // Now this is true, since they have identical properties. ``` ### Numerics Additionally, numerics count with broader type checks. * `isFloat()` returns true if the type represents a floating point type like `Single` or `Double`, false otherwise. * `isSignedInteger()` returns true if the type is a signed integer type like `Int8`, `Int16`, `Int32` or `Int64`, false otherwise. * `isUnsignedInteger()` returns true if the type is an unsigned integer type like `UInt8`, `UInt16`, `UInt32` or `UInt64`, false otherwise. * `is64BitInteger()` returns true if the type is an integer that needs 64 bits to be represented precisely, like `Int64` or `UInt64`, false otherwise. * `isInteger()` returns true if the type returns true to either `isSignedInteger()` or `isUnsignedInteger()`, false otherwise. * `isComplex()` returns true if the type is either a complex number like `ComplexSingle` or `ComplexDouble`. * `isNumeric()` returns true if the type returns true to any of the previous functions. ### Aggregate types `Array`, `Enum`, `AnalogWaveform` and `Cluster` are aggregate types, they share the following function: * `getSubtype()`. Returns an instance of `NIType` or an array of those in case of the `Cluster` Examples: ```javascript var arrayType = new NIType('{"name":"Array","rank":1,"subtype":"Double"}'); var enumType = new NIType('{"name":"Enum","subtype":"UInt32"}'); var analogType = new NIType('{"name":"AnalogWaveform","subtype":"Single"}'); var arraySubtype = arrayType.getSubtype(); var enumSubtype = enumType.getSubtype(); var analogSubtype = enumType.getSubtype(); // All these are true console.log(arraySubtype.isDouble()); console.log(enumType.isUInt32()); console.log(analogSubtype.isSingle()); ``` `isAggregateType()` returns true for aggregate types ### Array methods Array types also have some extra methods. * `getRank()` returns an integer greater than zero with the rank of the array. * `getSize()` defined for fixed-size arrays. Returns an array of positive integers, including zero, that describe the size of each dimension in the array. Examples: ```javascript var arrayType = new NIType('{"name":"Array","rank":2,"size":[2,3],"subtype":"Boolean"}'); console.log(arrayType.getSize()); // prints [2, 3] console.log(arrayType.getRank()); // prints 2 ``` ### Cluster methods Clusters instances expose these methods. * `getSubtype()` returns an array of NIType instances of the subelements in the cluster. `undefined` if information is not there (Cluster is partially built). * `getFields()` returns an array of `string` with the names of the fields in the subelements of the cluster. Examples: ```javascript var clusterType = new NIType('{"name":"Cluster","subtype":["Boolean"],"fields":["Power Button"]}'); var partialClusterType = new NIType('{"name":"Cluster","fields":["Text Button"]}'); var clusterSubtype = clusterType.getSubtype(); // returns an array containing a NIType of boolean. console.log(clusterSubType[0].isBoolean()); // Would print true var partialClusterSubtype = partialClusterType.getSubtype(); console.log(partialClusterSubtype); // Prints undefined var clusterFields = clusterType.getFields(); console.log(clusterFields); // ["Power Button"] ``` ### JSON descriptor Sometimes is required to send the JSON type descriptor to other applications, for that case 2 functions are provided: * `toJSON()` returns a JSON string that describes the whole type using the full-format. This means that even simple subtypes are described as objects. e.g. `{"name":"Array", "subtype":{"name":"Path"}}`. * `toShortJSON()` returns a JSON string that describes the whole type but uses strings for simple subtypes. e.g. `{"name":"Array","subtype":"Path"}`.