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