| @@ 297-370 (lines=74) @@ | ||
| 294 | ReferenceType = 1371236 |
|
| 295 | View = 1335532 |
|
| 296 | ||
| 297 | ||
| 298 | class AttributeWriteMask(IntEnum): |
|
| 299 | ''' |
|
| 300 | Define bits used to indicate which attributes are writable. |
|
| 301 | ||
| 302 | :ivar None_: |
|
| 303 | :vartype None_: 0 |
|
| 304 | :ivar AccessLevel: |
|
| 305 | :vartype AccessLevel: 1 |
|
| 306 | :ivar ArrayDimensions: |
|
| 307 | :vartype ArrayDimensions: 2 |
|
| 308 | :ivar BrowseName: |
|
| 309 | :vartype BrowseName: 4 |
|
| 310 | :ivar ContainsNoLoops: |
|
| 311 | :vartype ContainsNoLoops: 8 |
|
| 312 | :ivar DataType: |
|
| 313 | :vartype DataType: 16 |
|
| 314 | :ivar Description: |
|
| 315 | :vartype Description: 32 |
|
| 316 | :ivar DisplayName: |
|
| 317 | :vartype DisplayName: 64 |
|
| 318 | :ivar EventNotifier: |
|
| 319 | :vartype EventNotifier: 128 |
|
| 320 | :ivar Executable: |
|
| 321 | :vartype Executable: 256 |
|
| 322 | :ivar Historizing: |
|
| 323 | :vartype Historizing: 512 |
|
| 324 | :ivar InverseName: |
|
| 325 | :vartype InverseName: 1024 |
|
| 326 | :ivar IsAbstract: |
|
| 327 | :vartype IsAbstract: 2048 |
|
| 328 | :ivar MinimumSamplingInterval: |
|
| 329 | :vartype MinimumSamplingInterval: 4096 |
|
| 330 | :ivar NodeClass: |
|
| 331 | :vartype NodeClass: 8192 |
|
| 332 | :ivar NodeId: |
|
| 333 | :vartype NodeId: 16384 |
|
| 334 | :ivar Symmetric: |
|
| 335 | :vartype Symmetric: 32768 |
|
| 336 | :ivar UserAccessLevel: |
|
| 337 | :vartype UserAccessLevel: 65536 |
|
| 338 | :ivar UserExecutable: |
|
| 339 | :vartype UserExecutable: 131072 |
|
| 340 | :ivar UserWriteMask: |
|
| 341 | :vartype UserWriteMask: 262144 |
|
| 342 | :ivar ValueRank: |
|
| 343 | :vartype ValueRank: 524288 |
|
| 344 | :ivar WriteMask: |
|
| 345 | :vartype WriteMask: 1048576 |
|
| 346 | :ivar ValueForVariableType: |
|
| 347 | :vartype ValueForVariableType: 2097152 |
|
| 348 | ''' |
|
| 349 | None_ = 0 |
|
| 350 | AccessLevel = 1 |
|
| 351 | ArrayDimensions = 2 |
|
| 352 | BrowseName = 4 |
|
| 353 | ContainsNoLoops = 8 |
|
| 354 | DataType = 16 |
|
| 355 | Description = 32 |
|
| 356 | DisplayName = 64 |
|
| 357 | EventNotifier = 128 |
|
| 358 | Executable = 256 |
|
| 359 | Historizing = 512 |
|
| 360 | InverseName = 1024 |
|
| 361 | IsAbstract = 2048 |
|
| 362 | MinimumSamplingInterval = 4096 |
|
| 363 | NodeClass = 8192 |
|
| 364 | NodeId = 16384 |
|
| 365 | Symmetric = 32768 |
|
| 366 | UserAccessLevel = 65536 |
|
| 367 | UserExecutable = 131072 |
|
| 368 | UserWriteMask = 262144 |
|
| 369 | ValueRank = 524288 |
|
| 370 | WriteMask = 1048576 |
|
| 371 | ValueForVariableType = 2097152 |
|
| 372 | ||
| 373 | ||
| @@ 805-865 (lines=61) @@ | ||
| 802 | encoding = uabin.set_bit(encoding, 6) |
|
| 803 | encoding = uabin.set_bit(encoding, 7) |
|
| 804 | b.append(uabin.Primitives.UInt8.pack(encoding)) |
|
| 805 | b.append(uabin.pack_uatype_array(self.VariantType, flatten(self.Value))) |
|
| 806 | if self.Dimensions is not None: |
|
| 807 | b.append(uabin.pack_uatype_array(VariantType.Int32, self.Dimensions)) |
|
| 808 | else: |
|
| 809 | b.append(uabin.Primitives.UInt8.pack(encoding)) |
|
| 810 | b.append(uabin.pack_uatype(self.VariantType, self.Value)) |
|
| 811 | ||
| 812 | return b"".join(b) |
|
| 813 | ||
| 814 | @staticmethod |
|
| 815 | def from_binary(data): |
|
| 816 | dimensions = None |
|
| 817 | encoding = ord(data.read(1)) |
|
| 818 | int_type = encoding & 0b00111111 |
|
| 819 | vtype = datatype_to_varianttype(int_type) |
|
| 820 | if vtype == VariantType.Null: |
|
| 821 | return Variant(None, vtype, encoding) |
|
| 822 | if uabin.test_bit(encoding, 7): |
|
| 823 | value = uabin.unpack_uatype_array(vtype, data) |
|
| 824 | else: |
|
| 825 | value = uabin.unpack_uatype(vtype, data) |
|
| 826 | if uabin.test_bit(encoding, 6): |
|
| 827 | dimensions = uabin.unpack_uatype_array(VariantType.Int32, data) |
|
| 828 | value = reshape(value, dimensions) |
|
| 829 | ||
| 830 | return Variant(value, vtype, dimensions) |
|
| 831 | ||
| 832 | ||
| 833 | def reshape(flat, dims): |
|
| 834 | subdims = dims[1:] |
|
| 835 | subsize = 1 |
|
| 836 | for i in subdims: |
|
| 837 | if i == 0: |
|
| 838 | i = 1 |
|
| 839 | subsize *= i |
|
| 840 | while dims[0] * subsize > len(flat): |
|
| 841 | flat.append([]) |
|
| 842 | if not subdims or subdims == [0]: |
|
| 843 | return flat |
|
| 844 | return [reshape(flat[i: i + subsize], subdims) for i in range(0, len(flat), subsize)] |
|
| 845 | ||
| 846 | ||
| 847 | def _split_list(l, n): |
|
| 848 | n = max(1, n) |
|
| 849 | return [l[i:i + n] for i in range(0, len(l), n)] |
|
| 850 | ||
| 851 | ||
| 852 | def flatten_and_get_shape(mylist): |
|
| 853 | dims = [] |
|
| 854 | dims.append(len(mylist)) |
|
| 855 | while isinstance(mylist[0], (list, tuple)): |
|
| 856 | dims.append(len(mylist[0])) |
|
| 857 | mylist = [item for sublist in mylist for item in sublist] |
|
| 858 | if len(mylist) == 0: |
|
| 859 | break |
|
| 860 | return mylist, dims |
|
| 861 | ||
| 862 | ||
| 863 | def flatten(mylist): |
|
| 864 | if len(mylist) == 0: |
|
| 865 | return mylist |
|
| 866 | while isinstance(mylist[0], (list, tuple)): |
|
| 867 | mylist = [item for sublist in mylist for item in sublist] |
|
| 868 | if len(mylist) == 0: |
|