-
Notifications
You must be signed in to change notification settings - Fork 91
/
Copy pathcommon.py
99 lines (84 loc) · 2.99 KB
/
common.py
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
from itertools import zip_longest
toc_properties = {
'kTocMetaData': (1 << 1),
'kTocRawData': (1 << 3),
'kTocDAQmxRawData': (1 << 7),
'kTocInterleavedData': (1 << 5),
'kTocBigEndian': (1 << 6),
'kTocNewObjList': (1 << 2)
}
class ObjectPath(object):
""" Represents the path of an object in a TDMS file
:ivar group: Group name or None for the root object
:ivar channel: Channel name or None for the root object or a group objecct
"""
def __init__(self, *path_components):
self.group = None
self.channel = None
if len(path_components) > 0:
self.group = path_components[0]
if len(path_components) > 1:
self.channel = path_components[1]
if len(path_components) > 2:
raise ValueError("Object path may only have up to two components")
self._path = _components_to_path(self.group, self.channel)
@property
def is_root(self):
return self.group is None
@property
def is_group(self):
return self.group is not None and self.channel is None
@property
def is_channel(self):
return self.channel is not None
def group_path(self):
""" For channel paths, returns the path of the channel's group as a string
"""
return _components_to_path(self.group, None)
@staticmethod
def from_string(path_string):
components = list(_path_components(path_string))
return ObjectPath(*components)
def __str__(self):
""" String representation of the object path
"""
return self._path
def _path_components(path):
""" Generator that yields components within an object path
"""
# Iterate over each character and the next character
chars = zip_longest(path, path[1:])
try:
# Iterate over components
while True:
char, next_char = next(chars)
if char != '/':
raise ValueError("Invalid path, expected \"/\"")
elif next_char is not None and next_char != "'":
raise ValueError("Invalid path, expected \"'\"")
else:
# Consume "'" or raise StopIteration if at the end
next(chars)
component = []
# Iterate over characters in component name
while True:
char, next_char = next(chars)
if char == "'" and next_char == "'":
component += "'"
# Consume second "'"
next(chars)
elif char == "'":
yield "".join(component)
break
else:
component += char
except StopIteration:
return
def _components_to_path(group, channel):
components = []
if group is not None:
components.append(group)
if channel is not None:
components.append(channel)
return ('/' + '/'.join(
["'" + c.replace("'", "''") + "'" for c in components]))