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  import re 
 43   
 44  try: 
 45      from cStringIO import StringIO # Python 2.x 
 46  except ImportError: 
 47      from io import StringIO # Python 3.x 
 48   
 49  import roslib.msgs 
 50  import roslib.names 
 51  import roslib.packages 
 52  import roslib.resources 
 53   
 54  # don't directly use code from this, though we do depend on the 
 55  # manifest.Depend data type 
 56  import roslib.manifest 
 57   
 58  ## file extension 
 59  EXT = '.srv' #alias 
 60  SEP = '/' #e.g. std_msgs/String 
 61  ## input/output deliminator 
 62  IODELIM   = '---' 
 63  COMMENTCHAR = roslib.msgs.COMMENTCHAR 
 64   
 65  VERBOSE = False 
 66  ## @return: True if msg-related scripts should print verbose output 
67 -def is_verbose():
68 return VERBOSE
69 70 ## set whether msg-related scripts should print verbose output
71 -def set_verbose(v):
72 global VERBOSE 73 VERBOSE = v
74
75 -class SrvSpecException(Exception): pass
76 77 # msg spec representation ########################################## 78
79 -class SrvSpec(object):
80
81 - def __init__(self, request, response, text, full_name = '', short_name = '', package = ''):
82 self.request = request 83 self.response = response 84 self.text = text 85 self.full_name = full_name 86 self.short_name = short_name 87 self.package = package
88
89 - def __eq__(self, other):
90 if not other or not isinstance(other, SrvSpec): 91 return False 92 return self.request == other.request and \ 93 self.response == other.response and \ 94 self.text == other.text and \ 95 self.full_name == other.full_name and \ 96 self.short_name == other.short_name and \ 97 self.package == other.package
98
99 - def __ne__(self, other):
100 if not other or not isinstance(other, SrvSpec): 101 return True 102 return not self.__eq__(other)
103
104 - def __repr__(self):
105 return "SrvSpec[%s, %s]"%(repr(self.request), repr(self.response))
106 107 # srv spec loading utilities ########################################## 108 109 ## @internal 110 ## predicate for filtering directory list. matches message files
111 -def _srv_filter(f):
112 return os.path.isfile(f) and f.endswith(EXT)
113 114 # also used by doxymaker
115 -def list_srv_types(package, include_depends):
116 """ 117 list all services in the specified package 118 @param package: name of package to search 119 @type package: str 120 @param include_depends: if True, will also list services in package dependencies 121 @type include_depends: bool 122 @return: service type names 123 @rtype: [str] 124 """ 125 types = roslib.resources.list_package_resources(package, include_depends, 'srv', _srv_filter) 126 return [x[:-len(EXT)] for x in types]
127
128 -def srv_file(package, type_):
129 """ 130 @param package: name of package .srv file is in 131 @type package: str 132 @param type_: type name of service 133 @type type_: str 134 @return: file path of .srv file in specified package 135 @rtype: str 136 """ 137 return roslib.packages.resource_file(package, 'srv', type_+EXT)
138
139 -def get_pkg_srv_specs(package):
140 """ 141 List all messages that a package contains 142 @param depend: roslib.manifest.Depend object representing package 143 to load messages from 144 @type depend: Depend 145 @return: list of message type names and specs for package, as well as a list 146 of message names that could not be processed. 147 @rtype: [(str,roslib.MsgSpec), [str]] 148 """ 149 #almost identical to roslib.msgs.get_pkg_msg_specs 150 types = list_srv_types(package, False) 151 specs = [] #no fancy list comprehension as we want to show errors 152 failures = [] 153 for t in types: 154 try: 155 spec = load_from_file(srv_file(package, t), package) 156 specs.append(spec) 157 except Exception as e: 158 failures.append(t) 159 sys.stderr.write("ERROR: unable to load %s\n"%(t)) 160 return specs, failures
161
162 -def load_from_string(text, package_context='', full_name='', short_name=''):
163 """ 164 @param text: .msg text 165 @type text: str 166 @param package_context: context to use for msgTypeName, i.e. the package name, 167 or '' to use local naming convention. 168 @type package_context: str 169 @return: Message type name and message specification 170 @rtype: roslib.MsgSpec 171 @raise roslib.MsgSpecException: if syntax errors or other problems are detected in file 172 """ 173 text_in = StringIO() 174 text_out = StringIO() 175 accum = text_in 176 for l in text.split('\n'): 177 l = l.split(COMMENTCHAR)[0].strip() #strip comments 178 if l.startswith(IODELIM): #lenient, by request 179 accum = text_out 180 else: 181 accum.write(l+'\n') 182 # create separate roslib.msgs objects for each half of file 183 184 msg_in = roslib.msgs.load_from_string(text_in.getvalue(), package_context, '%sRequest'%(full_name), '%sRequest'%(short_name)) 185 msg_out = roslib.msgs.load_from_string(text_out.getvalue(), package_context, '%sResponse'%(full_name), '%sResponse'%(short_name)) 186 return SrvSpec(msg_in, msg_out, text, full_name, short_name, package_context)
187
188 -def load_from_file(file_name, package_context=''):
189 """ 190 Convert the .srv representation in the file to a SrvSpec instance. 191 @param file_name: name of file to load from 192 @type file_name: str 193 @param package_context: context to use for type name, i.e. the package name, 194 or '' to use local naming convention. 195 @type package_context: str 196 @return: Message type name and message specification 197 @rtype: (str, L{SrvSpec}) 198 @raise SrvSpecException: if syntax errors or other problems are detected in file 199 """ 200 if VERBOSE: 201 if package_context: 202 sys.stdout.write("Load spec from %s into namespace [%s]\n"%(file_name, package_context)) 203 else: 204 sys.stdout.write("Load spec from %s\n"%(file_name)) 205 base_file_name = os.path.basename(file_name) 206 type_ = base_file_name[:-len(EXT)] 207 base_type_ = type_ 208 # determine the type name 209 if package_context: 210 while package_context.endswith(SEP): 211 package_context = package_context[:-1] #strip message separators 212 type_ = "%s%s%s"%(package_context, SEP, type_) 213 if not roslib.names.is_legal_resource_name(type_): 214 raise SrvSpecException("%s: %s is not a legal service type name"%(file_name, type_)) 215 216 f = open(file_name, 'r') 217 try: 218 text = f.read() 219 return (type_, load_from_string(text, package_context, type_, base_type_)) 220 finally: 221 f.close()
222