Add support for variant types - #32
Open
logmanoriginal wants to merge 1 commit into
Open
Conversation
This is a major addition for (de-)composition of variant types that enables the use of variant elements inside composable types. Variant types behave different from other types. When used as terminals on the connector pane, whatever type is connected to it will keep its original type, which means that the type can be handled as if working with the original. When a type is "boxed" inside a variant - for example, when using variant Maps - the embedded type is serialized into the data string of the variant. Variant data consists of several key fields: 4 Bytes - Version ----------------- This is the LabVIEW version used to serialize the variant. For exapmle, [0x17,0x00,0x80,0x00] for LabVIEW 2017 SP1 or [0x19,0x00,0x80,0x00] for LabVIEW 2019 SP1. The major version number is clearly visible in the first byte when viewed in hexadecimal. The service pack version appears to be part of the third byte. 4 Bytes - Number of type definitions ------------------------------------ A variant can box many type definitions, each of which represents one type. The order in which these types are defined is important because when using a container (e.g., cluster), it references back to one of the previously defined types. This means that duplicate types only appear once in the definition. For example, if a cluster contains two strings, the type definition of the string only appears once and is referenced twice. Regardless of how many times a type appears, it is always referenced by the container. Only when the container is not further divided, will it be the sole type definition. Once all type definitions are identified, the backrefs must be resolved. TDs --- What follows are the type definitions. Simply extracted by reading the first two bytes (length) and then the rest to fill up that length. 2 Bytes - Number of "top-level" types (I think) ------------------------------------- The next two bytes are not 100% clear but I believe they specify how many top-level types there are. I have only observed 0x0001 always and don't know if there is any way to change that. Alternatively it might specify how many words of backrefs follow (next 2 bytes) but this is also just speculation because I don't think there are so many types (unless typedefs count)... currently ignored. 2 Bytes - Number of backrefs ---------------------------- This count depends on how many backref type definitions exist. Data ---- What follows is the data section, which is the data for the top-level type and all its nested types. This can be anything. 4 Bytes - Number of attributes ------------------------------ Next up are four bytes that specify the number of attributes on a variant. Since attributes are optional, the count can be zero. Attributes ---------- Finally, if there are any attributes, they all follow the same convention: 4 Bytes for the length of the key, followed by the key, followed by the value as boxed variant. Since attributes can contain variants with attributes, all of this is recursive. Further information can be found in the official documentation [1][2] [1]: https://knowledge.ni.com/KnowledgeArticleDetails?id=kA03q000000YGQrCAO&l=en-US [2]: https://www.ni.com/docs/en-US/bundle/labview/page/type-descriptors.html
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is a major addition for (de-)composition of variant types that enables the use of variant elements inside composable types.
Variant types behave different from other types. When used as terminals on the connector pane, whatever type is connected to it will keep its original type, which means that the type can be handled as if working with the original.
When a type is "boxed" inside a variant - for example, when using variant Maps - the embedded type is serialized into the data string of the variant.
Variant data consists of several key fields:
4 Bytes - Version
This is the LabVIEW version used to serialize the variant. For exapmle, [0x17,0x00,0x80,0x00] for LabVIEW 2017 SP1 or [0x19,0x00,0x80,0x00] for LabVIEW 2019 SP1. The major version number is clearly visible in the first byte when viewed in hexadecimal. The service pack version appears to be part of the third byte.
4 Bytes - Number of type definitions
A variant can box many type definitions, each of which represents one type. The order in which these types are defined is important because when using a container (e.g., cluster), it references back to one of the previously defined types. This means that duplicate types only appear once in the definition.
For example, if a cluster contains two strings, the type definition of the string only appears once and is referenced twice. Regardless of how many times a type appears, it is always referenced by the container. Only when the container is not further divided, will it be the sole type definition.
Once all type definitions are identified, the backrefs must be resolved.
TDs
What follows are the type definitions. Simply extracted by reading the first two bytes (length) and then the rest to fill up that length.
2 Bytes - Number of "top-level" types (I think)
The next two bytes are not 100% clear but I believe they specify how many top-level types there are. I have only observed 0x0001 always and don't know if there is any way to change that. Alternatively it might specify how many words of backrefs follow (next 2 bytes) but this is also just speculation because I don't think there are so many types (unless typedefs count)... currently ignored.
2 Bytes - Number of backrefs
This count depends on how many backref type definitions exist.
Data
What follows is the data section, which is the data for the top-level type and all its nested types. This can be anything.
4 Bytes - Number of attributes
Next up are four bytes that specify the number of attributes on a variant. Since attributes are optional, the count can be zero.
Attributes
Finally, if there are any attributes, they all follow the same convention: 4 Bytes for the length of the key, followed by the key, followed by the value as boxed variant.
Since attributes can contain variants with attributes, all of this is recursive.
Further information can be found in the official documentation 1 2
Closes #31