Package roslib :: Module srvs
[frames] | no frames]

Source Code for Module roslib.srvs

  1  # Software License Agreement (BSD License) 
  2  # 
  3  # Copyright (c) 2008, Willow Garage, Inc. 
  4  # All rights reserved. 
  5  # 
  6  # Redistribution and use in source and binary forms, with or without 
  7  # modification, are permitted provided that the following conditions 
  8  # are met: 
  9  # 
 10  #  * Redistributions of source code must retain the above copyright 
 11  #    notice, this list of conditions and the following disclaimer. 
 12  #  * Redistributions in binary form must reproduce the above 
 13  #    copyright notice, this list of conditions and the following 
 14  #    disclaimer in the documentation and/or other materials provided 
 15  #    with the distribution. 
 16  #  * Neither the name of Willow Garage, Inc. nor the names of its 
 17  #    contributors may be used to endorse or promote products derived 
 18  #    from this software without specific prior written permission. 
 19  # 
 20  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 21  # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 22  # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
 23  # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
 24  # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
 25  # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
 26  # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
 27  # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
 28  # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
 29  # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
 30  # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 31  # POSSIBILITY OF SUCH DAMAGE. 
 32  # 
 33  # Revision $Id$ 
 34  # $Author$ 
 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  # Python 2.x 
 45  except ImportError: 
 46      from io import StringIO  # Python 3.x 
 47   
 48  # don't directly use code from this, though we do depend on the 
 49  # manifest.Depend data type 
 50  import roslib.manifest 
 51  import roslib.msgs 
 52  import roslib.names 
 53  import roslib.packages 
 54  import roslib.resources 
 55   
 56  # file extension 
 57  EXT = '.srv'  # alias 
 58  SEP = '/'  # e.g. std_msgs/String 
 59  # input/output deliminator 
 60  IODELIM = '---' 
 61  COMMENTCHAR = roslib.msgs.COMMENTCHAR 
 62   
 63  VERBOSE = False 
 64   
 65   
 66  # @return: True if msg-related scripts should print verbose output 
67 -def is_verbose():
68 return VERBOSE
69 70 71 # set whether msg-related scripts should print verbose output
72 -def set_verbose(v):
73 global VERBOSE 74 VERBOSE = v
75 76
77 -class SrvSpecException(Exception):
78 pass
79 80 81 # msg spec representation ########################################## 82
83 -class SrvSpec(object):
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
93 - def __eq__(self, other):
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
103 - def __ne__(self, other):
104 if not other or not isinstance(other, SrvSpec): 105 return True 106 return not self.__eq__(other)
107
108 - def __repr__(self):
109 return 'SrvSpec[%s, %s]' % (repr(self.request), repr(self.response))
110 111 112 # srv spec loading utilities ########################################## 113 114 # @internal 115 # predicate for filtering directory list. matches message files
116 -def _srv_filter(f):
117 return os.path.isfile(f) and f.endswith(EXT)
118 119 120 # also used by doxymaker
121 -def list_srv_types(package, include_depends):
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
135 -def srv_file(package, type_):
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
147 -def get_pkg_srv_specs(package):
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 # almost identical to roslib.msgs.get_pkg_msg_specs 158 types = list_srv_types(package, False) 159 specs = [] # no fancy list comprehension as we want to show errors 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
171 -def load_from_string(text, package_context='', full_name='', short_name=''):
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() # strip comments 187 if l.startswith(IODELIM): # lenient, by request 188 accum = text_out 189 else: 190 accum.write(l+'\n') 191 # create separate roslib.msgs objects for each half of file 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
198 -def load_from_file(file_name, package_context=''):
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 # determine the type name 219 if package_context: 220 while package_context.endswith(SEP): 221 package_context = package_context[:-1] # strip message separators 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