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 ROS Service Description Language Spec
37 Implements U{http://ros.org/wiki/srv}
38 """
39
40 import os
41 import sys
42
43 try:
44 from cStringIO import StringIO
45 except ImportError:
46 from io import StringIO
47
48
49
50 import roslib.manifest
51 import roslib.msgs
52 import roslib.names
53 import roslib.packages
54 import roslib.resources
55
56
57 EXT = '.srv'
58 SEP = '/'
59
60 IODELIM = '---'
61 COMMENTCHAR = roslib.msgs.COMMENTCHAR
62
63 VERBOSE = False
64
65
66
69
70
71
75
76
79
80
81
82
84
85 - def __init__(self, request, response, text, full_name='', short_name='', package=''):
86 self.request = request
87 self.response = response
88 self.text = text
89 self.full_name = full_name
90 self.short_name = short_name
91 self.package = package
92
94 if not other or not isinstance(other, SrvSpec):
95 return False
96 return self.request == other.request and \
97 self.response == other.response and \
98 self.text == other.text and \
99 self.full_name == other.full_name and \
100 self.short_name == other.short_name and \
101 self.package == other.package
102
104 if not other or not isinstance(other, SrvSpec):
105 return True
106 return not self.__eq__(other)
107
109 return 'SrvSpec[%s, %s]' % (repr(self.request), repr(self.response))
110
111
112
113
114
115
117 return os.path.isfile(f) and f.endswith(EXT)
118
119
120
122 """
123 list all services in the specified package
124 @param package: name of package to search
125 @type package: str
126 @param include_depends: if True, will also list services in package dependencies
127 @type include_depends: bool
128 @return: service type names
129 @rtype: [str]
130 """
131 types = roslib.resources.list_package_resources(package, include_depends, 'srv', _srv_filter)
132 return [x[:-len(EXT)] for x in types]
133
134
136 """
137 @param package: name of package .srv file is in
138 @type package: str
139 @param type_: type name of service
140 @type type_: str
141 @return: file path of .srv file in specified package
142 @rtype: str
143 """
144 return roslib.packages.resource_file(package, 'srv', type_+EXT)
145
146
148 """
149 List all messages that a package contains
150 @param depend: roslib.manifest.Depend object representing package
151 to load messages from
152 @type depend: Depend
153 @return: list of message type names and specs for package, as well as a list
154 of message names that could not be processed.
155 @rtype: [(str,roslib.MsgSpec), [str]]
156 """
157
158 types = list_srv_types(package, False)
159 specs = []
160 failures = []
161 for t in types:
162 try:
163 spec = load_from_file(srv_file(package, t), package)
164 specs.append(spec)
165 except Exception:
166 failures.append(t)
167 sys.stderr.write('ERROR: unable to load %s\n' % (t))
168 return specs, failures
169
170
172 """
173 @param text: .msg text
174 @type text: str
175 @param package_context: context to use for msgTypeName, i.e. the package name,
176 or '' to use local naming convention.
177 @type package_context: str
178 @return: Message type name and message specification
179 @rtype: roslib.MsgSpec
180 @raise roslib.MsgSpecException: if syntax errors or other problems are detected in file
181 """
182 text_in = StringIO()
183 text_out = StringIO()
184 accum = text_in
185 for l in text.split('\n'):
186 l = l.split(COMMENTCHAR)[0].strip()
187 if l.startswith(IODELIM):
188 accum = text_out
189 else:
190 accum.write(l+'\n')
191
192
193 msg_in = roslib.msgs.load_from_string(text_in.getvalue(), package_context, '%sRequest' % (full_name), '%sRequest' % (short_name))
194 msg_out = roslib.msgs.load_from_string(text_out.getvalue(), package_context, '%sResponse' % (full_name), '%sResponse' % (short_name))
195 return SrvSpec(msg_in, msg_out, text, full_name, short_name, package_context)
196
197
199 """
200 Convert the .srv representation in the file to a SrvSpec instance.
201 @param file_name: name of file to load from
202 @type file_name: str
203 @param package_context: context to use for type name, i.e. the package name,
204 or '' to use local naming convention.
205 @type package_context: str
206 @return: Message type name and message specification
207 @rtype: (str, L{SrvSpec})
208 @raise SrvSpecException: if syntax errors or other problems are detected in file
209 """
210 if VERBOSE:
211 if package_context:
212 sys.stdout.write('Load spec from %s into namespace [%s]\n' % (file_name, package_context))
213 else:
214 sys.stdout.write('Load spec from %s\n' % (file_name))
215 base_file_name = os.path.basename(file_name)
216 type_ = base_file_name[:-len(EXT)]
217 base_type_ = type_
218
219 if package_context:
220 while package_context.endswith(SEP):
221 package_context = package_context[:-1]
222 type_ = '%s%s%s' % (package_context, SEP, type_)
223 if not roslib.names.is_legal_resource_name(type_):
224 raise SrvSpecException('%s: %s is not a legal service type name' % (file_name, type_))
225
226 f = open(file_name, 'r')
227 try:
228 text = f.read()
229 return (type_, load_from_string(text, package_context, type_, base_type_))
230 finally:
231 f.close()
232