$search
00001 #!/usr/bin/env python 00002 # Software License Agreement (BSD License) 00003 # 00004 # Copyright (c) 2009, Willow Garage, Inc. 00005 # All rights reserved. 00006 # 00007 # Redistribution and use in source and binary forms, with or without 00008 # modification, are permitted provided that the following conditions 00009 # are met: 00010 # 00011 # * Redistributions of source code must retain the above copyright 00012 # notice, this list of conditions and the following disclaimer. 00013 # * Redistributions in binary form must reproduce the above 00014 # copyright notice, this list of conditions and the following 00015 # disclaimer in the documentation and/or other materials provided 00016 # with the distribution. 00017 # * Neither the name of Willow Garage, Inc. nor the names of its 00018 # contributors may be used to endorse or promote products derived 00019 # from this software without specific prior written permission. 00020 # 00021 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00022 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00023 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00024 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00025 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00026 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00027 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00028 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00029 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00030 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00031 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00032 # POSSIBILITY OF SUCH DAMAGE. 00033 # 00034 00035 import roslib; roslib.load_manifest('rosjava_jni') 00036 00037 import sys 00038 import os 00039 import traceback 00040 00041 import roslib.msgs 00042 import roslib.packages 00043 import roslib.gentools 00044 00045 from cStringIO import StringIO 00046 00047 MSG_TYPE_TO_JAVA = {'bool': 'boolean', 00048 'char': 'char', 00049 'byte': 'short', 00050 'uint8': 'short', 'int8': 'byte', 00051 'uint16': 'int', 'int16': 'short', 00052 'uint32': 'long', 'int32': 'int', 00053 'uint64': 'long', 'int64': 'long', 00054 'float32': 'float', 00055 'float64': 'double', 00056 'string': 'java.lang.String', 00057 'time': 'ros.communication.Time', 00058 'duration': 'ros.communication.Duration'} 00059 00060 MSG_TYPE_TO_SERIALIZATION_CODE = { 00061 'bool': '%(buffer)s.put((byte)(%(name)s ? 1 : 0))', 00062 'char': '%(buffer)s.put((byte)%(name)s)', 00063 'byte': '%(buffer)s.put((byte)%(name)s)', 00064 'uint8': '%(buffer)s.put((byte)%(name)s)', 00065 'int8': '%(buffer)s.put(%(name)s)', 00066 'uint16': '%(buffer)s.putShort((short)%(name)s)', 00067 'int16': '%(buffer)s.putShort(%(name)s)', 00068 'uint32': '%(buffer)s.putInt((int)%(name)s)', 00069 'int32': '%(buffer)s.putInt(%(name)s)', 00070 'uint64': '%(buffer)s.putLong(%(name)s)', 00071 'int64': '%(buffer)s.putLong(%(name)s)', 00072 'float32': '%(buffer)s.putFloat(%(name)s)', 00073 'float64': '%(buffer)s.putDouble(%(name)s)', 00074 'string': 'Serialization.writeString(%(buffer)s, %(name)s)', 00075 'time': 'Serialization.writeTime(%(buffer)s, %(name)s)', 00076 'duration': 'Serialization.writeDuration(%(buffer)s, %(name)s)'} 00077 00078 MSG_TYPE_TO_DESERIALIZATION_CODE = { 00079 'bool': '%s.get() != 0 ? true : false', 00080 'char': '(char)(%s.get() & 0xff)', 00081 'byte': '(short)(%s.get() & 0xff)', 00082 'uint8': '(short)(%s.get() & 0xff)', 00083 'int8': '%s.get()', 00084 'uint16': '(int)(%s.getShort() & 0xffff)', 00085 'int16': '%s.getShort()', 00086 'uint32': '(long)(%s.getInt() & 0xffffffff)', 00087 'int32': '%s.getInt()', 00088 'uint64': '%s.getLong()', 00089 'int64': '%s.getLong()', 00090 'float32': '%s.getFloat()', 00091 'float64': '%s.getDouble()', 00092 'string': 'Serialization.readString(%s)', 00093 'time': 'Serialization.readTime(%s)', 00094 'duration': 'Serialization.readDuration(%s)'} 00095 00096 BUILTIN_TYPE_SIZES = {'bool': 1, 'int8': 1, 'byte': 1, 'int16': 2, 'int32': 4, 'int64': 8, 00097 'char': 1, 'uint8': 1, 'uint16': 2, 'uint32': 4, 'uint64': 8, 00098 'float32': 4, 'float64': 8, 'time': 8, 'duration': 8} 00099 00100 JAVA_PRIMITIVE_TYPES = ['char', 'byte', 'short', 'int', 'long', 'boolean', 'float', 'double'] 00101 00102 JAVA_HASH_CODES = { 00103 'char': '%(value)s', 00104 'byte': '%(value)s', 00105 'short': '%(value)s', 00106 'int': '%(value)s', 00107 'long': '(int)(%(value)s ^ (%(value)s >>> 32))', 00108 'boolean': '(%(value)s ? 1231 : 1237)', # stolen from eclipse autogenerated code 00109 'float': 'Float.floatToIntBits(%(value)s)', 00110 'double': '(int)((tmp = Double.doubleToLongBits(%(value)s)) ^ (tmp >>> 32))'} 00111 00112 def builtin_type_size(type): 00113 return BUILTIN_TYPE_SIZES[type.split('[')[0]] 00114 00115 def base_type_to_java(base_type): 00116 base_type = base_type.split('[')[0] 00117 if (roslib.msgs.is_builtin(base_type)): 00118 java_type = MSG_TYPE_TO_JAVA[base_type] 00119 elif (len(base_type.split('/')) == 1): 00120 if (roslib.msgs.is_header_type(base_type)): 00121 ros_v = ros_version() 00122 if ros_v and ros_v[0] == 1 and ros_v[1] < 3: 00123 java_type = 'ros.pkg.roslib.msg.Header' 00124 else: 00125 java_type = 'ros.pkg.std_msgs.msg.Header' 00126 else: 00127 java_type = base_type 00128 else: 00129 pkg = base_type.split('/')[0] 00130 msg = base_type.split('/')[1] 00131 java_type = 'ros.pkg.%s.msg.%s' % (pkg, msg) 00132 return java_type 00133 00134 def base_type_serialization_code(type): 00135 return MSG_TYPE_TO_SERIALIZATION_CODE[type.split('[')[0]] 00136 00137 def base_type_deserialization_code(type): 00138 return MSG_TYPE_TO_DESERIALIZATION_CODE[type.split('[')[0]] 00139 00140 def type_initializer(type, default_val = None): 00141 if default_val is not None: 00142 if type == 'float32': 00143 return ' = %sf' % default_val 00144 else: 00145 return ' = %s' % default_val 00146 elif roslib.msgs.is_builtin(type): 00147 if type in ['time', 'duration', 'string']: 00148 return ' = new %s()' % base_type_to_java(type) 00149 else: 00150 return '' 00151 else: 00152 return ' = new %s()' % base_type_to_java(type) 00153 00154 def msg_decl_to_java(field, default_val=None): 00155 """ 00156 Converts a message type (e.g. uint32, std_msgs/String, etc.) to the Java declaration 00157 for that type. 00158 00159 @param type: The message type 00160 @type type: str 00161 @return: The Java declaration 00162 @rtype: str 00163 """ 00164 java_type = base_type_to_java(field.type) 00165 00166 if type(field).__name__ == 'Field' and field.is_array: 00167 if field.array_len is None: 00168 if field.is_builtin and java_type in JAVA_PRIMITIVE_TYPES: 00169 decl_string = '%(java_type)s[] %(name)s = new %(java_type)s[0]' 00170 else: 00171 decl_string = 'java.util.ArrayList<%(java_type)s> %(name)s = new java.util.ArrayList<%(java_type)s>()' 00172 return decl_string % { 'name': field.name, 'java_type': java_type} 00173 else: 00174 return '%(java_type)s[] %(name)s = new %(java_type)s[%(array_len)d]' % {'java_type': java_type, 00175 'name': field.name, 00176 'array_len': field.array_len} 00177 else: 00178 return '%(type)s %(name)s%(initializer)s' % {'type': java_type, 00179 'name': field.name, 00180 'initializer': type_initializer(field.type, default_val)} 00181 00182 def write_begin(s, spec, file): 00183 """ 00184 Writes the beginning of the header file: a comment saying it's auto-generated and the include guards 00185 00186 @param s: The stream to write to 00187 @type s: stream 00188 @param spec: The spec 00189 @type spec: roslib.msgs.MsgSpec 00190 @param file: The file this message is being generated for 00191 @type file: str 00192 """ 00193 s.write('/* Auto-generated by genmsg_java.py for file %s */\n'%(file)) 00194 s.write('\npackage ros.pkg.%s.msg;\n' % spec.package) 00195 s.write('\nimport java.nio.ByteBuffer;\n') 00196 00197 def write_end(s, spec): 00198 """ 00199 Writes the end of the header file: the ending of the include guards 00200 00201 @param s: The stream to write to 00202 @type s: stream 00203 @param spec: The spec 00204 @type spec: roslib.msgs.MsgSpec 00205 """ 00206 pass 00207 00208 def write_imports(s, spec): 00209 """ 00210 Writes the message-specific imports 00211 00212 @param s: The stream to write to 00213 @type s: stream 00214 @param spec: The message spec to iterate over 00215 @type spec: roslib.msgs.MsgSpec 00216 """ 00217 s.write('\n') 00218 00219 00220 def write_class(s, spec, extra_metadata_methods={}, static=False): 00221 """ 00222 Writes the entire message struct: declaration, constructors, members, constants and member functions 00223 @param s: The stream to write to 00224 @type s: stream 00225 @param spec: The message spec 00226 @type spec: roslib.msgs.MsgSpec 00227 """ 00228 00229 msg = spec.short_name 00230 if static: 00231 s.write('static public class %s extends ros.communication.Message {\n' % msg) 00232 else: 00233 s.write('public class %s extends ros.communication.Message {\n' % msg) 00234 00235 write_constant_declarations(s, spec) 00236 write_members(s, spec) 00237 00238 write_constructor(s, spec) 00239 00240 gendeps_dict = roslib.gentools.get_dependencies(spec, spec.package, compute_files=False) 00241 md5sum = roslib.gentools.compute_md5(gendeps_dict) 00242 full_text = compute_full_text_escaped(gendeps_dict) 00243 00244 write_member_functions(s, spec, 00245 dict({'MD5Sum': '"%s"' % md5sum, 00246 'DataType': '"%s/%s"' % (spec.package, spec.short_name), 00247 'MessageDefinition': full_text}, 00248 **extra_metadata_methods)) 00249 00250 s.write('} // class %s\n'%(msg)) 00251 00252 def write_constructor(s, spec): 00253 s.write(""" 00254 public %s() { 00255 """ % spec.short_name) 00256 for field in spec.parsed_fields(): 00257 if field.type.split('[')[0] in roslib.msgs.PRIMITIVE_TYPES and \ 00258 field.type.split('[')[0] != 'string': 00259 continue 00260 if field.is_array and field.array_len: 00261 s.write(""" 00262 for(int __i=0; __i<%(array_len)d; __i++) { 00263 %(name)s[__i]%(initializer)s; 00264 } 00265 """ % {'name': field.name, 'type': field.type.split('[')[0], 00266 'array_len': field.array_len, 00267 'initializer': type_initializer(field.type.split('[')[0])}) 00268 s.write(' }\n') 00269 00270 def write_member(s, field): 00271 """ 00272 Writes a single member's declaration and type typedef 00273 00274 @param s: The stream to write to 00275 @type s: stream 00276 @param type: The member type 00277 @type type: str 00278 @param name: The name of the member 00279 @type name: str 00280 """ 00281 java_decl = msg_decl_to_java(field) 00282 s.write(' public %s;\n' % java_decl) 00283 00284 def write_members(s, spec): 00285 """ 00286 Write all the member declarations 00287 00288 @param s: The stream to write to 00289 @type s: stream 00290 @param spec: The message spec 00291 @type spec: roslib.msgs.MsgSpec 00292 """ 00293 [write_member(s, field) for field in spec.parsed_fields()] 00294 00295 def escape_string(str): 00296 str = str.replace('\\', '\\\\') 00297 str = str.replace('"', '\\"') 00298 return str 00299 00300 def write_constant_declaration(s, constant): 00301 """ 00302 Write a constant value as a static member 00303 00304 @param s: The stream to write to 00305 @type s: stream 00306 @param constant: The constant 00307 @type constant: roslib.msgs.Constant 00308 """ 00309 if constant.type == 'string': 00310 s.write(' static public final %s;\n'% msg_decl_to_java(constant, '"' + escape_string(constant.val) + '"')) 00311 else: 00312 s.write(' static public final %s;\n'% msg_decl_to_java(constant, constant.val)) 00313 00314 def write_constant_declarations(s, spec): 00315 """ 00316 Write all the constants from a spec as static members 00317 00318 @param s: The stream to write to 00319 @type s: stream 00320 @param spec: The message spec 00321 @type spec: roslib.msgs.MsgSpec 00322 """ 00323 for constant in spec.constants: 00324 write_constant_declaration(s, constant) 00325 s.write('\n') 00326 00327 def write_clone_methods(s, spec): 00328 s.write(""" 00329 public %(type)s clone() { 00330 %(type)s c = new %(type)s(); 00331 c.deserialize(serialize(0)); 00332 return c; 00333 } 00334 """ % {'type': spec.short_name}) 00335 s.write(""" 00336 public void setTo(ros.communication.Message m) { 00337 deserialize(m.serialize(0)); 00338 } 00339 """) 00340 00341 def write_serialization_length(s, spec): 00342 s.write(""" 00343 public int serializationLength() { 00344 int __l = 0; 00345 """) 00346 for field in spec.parsed_fields(): 00347 java_type = base_type_to_java(field.base_type) 00348 if field.type.split('[')[0] == 'string': 00349 if field.is_array: 00350 if field.array_len is None: 00351 s.write(' __l += 4;') 00352 s.write(""" 00353 for(java.lang.String val : %(name)s) { 00354 __l += 4 + val.length(); 00355 } 00356 """ % {'name': field.name}) 00357 else: 00358 s.write(' __l += 4 + %s.length();\n' % field.name) 00359 00360 elif field.is_builtin: 00361 if field.is_array and field.array_len is None: 00362 if java_type in JAVA_PRIMITIVE_TYPES: 00363 size_expr = '4 + %s.length * %d' % (field.name, builtin_type_size(field.type)) 00364 else: 00365 size_expr = '4 + %s.size() * %d' % (field.name, builtin_type_size(field.type)) 00366 elif field.is_array: 00367 size_expr = '%d' % (int(field.array_len) * builtin_type_size(field.type)) 00368 else: 00369 size_expr = '%d' % builtin_type_size(field.type) 00370 s.write(' __l += %s; // %s\n' % (size_expr, field.name)) 00371 elif field.is_array: 00372 if field.array_len is None: 00373 s.write(' __l += 4;') 00374 s.write(""" 00375 for(%s val : %s) { 00376 __l += val.serializationLength(); 00377 } 00378 """ % (java_type, field.name)) 00379 else: 00380 s.write(' __l += %s.serializationLength();\n' % field.name) 00381 00382 s.write(' return __l;\n }\n') 00383 00384 def write_serialization_method(s, spec): 00385 s.write(""" 00386 public void serialize(ByteBuffer bb, int seq) { 00387 """) 00388 for field in spec.parsed_fields(): 00389 java_type = base_type_to_java(field.base_type) 00390 if field.is_builtin: 00391 if field.is_array: 00392 if field.array_len is None: 00393 if java_type in JAVA_PRIMITIVE_TYPES: 00394 s.write(' bb.putInt(%s.length);' % field.name) 00395 else: 00396 s.write(' bb.putInt(%s.size());' % field.name) 00397 s.write(""" 00398 for(%(type)s val : %(name)s) { 00399 %(serialization)s; 00400 } 00401 """ % {'type': java_type, 00402 'name': field.name, 00403 'serialization': base_type_serialization_code(field.type) % {'buffer': 'bb', 'name': 'val'}}) 00404 00405 # No array. Use primitive serialization 00406 else: 00407 s.write(' %s;\n' % (base_type_serialization_code(field.type) % {'buffer': 'bb', 00408 'name': field.name})) 00409 # Not a builtin type, but array 00410 else: 00411 if field.is_array: 00412 if field.array_len is None: 00413 s.write(' bb.putInt(%s.size());' % field.name) 00414 s.write(""" 00415 for(%s val : %s) { 00416 val.serialize(bb, seq); 00417 } 00418 """ % (java_type, field.name)) 00419 00420 # No primitive type, no array 00421 else: 00422 s.write(' %s.serialize(bb, seq);\n' % field.name) 00423 00424 s.write(' }\n') 00425 00426 def write_deserialization_method(s, spec): 00427 s.write(""" 00428 public void deserialize(ByteBuffer bb) { 00429 """) 00430 for field in spec.parsed_fields(): 00431 java_type = base_type_to_java(field.base_type) 00432 00433 if field.is_array: 00434 # Template fields: 00435 # size_initializer 00436 # type_initializer 00437 # deserialization code 00438 00439 size_initializer = None 00440 type_initializer = None 00441 deserialization_code = None 00442 00443 if field.array_len is None: 00444 size_initializer = 'bb.getInt()' 00445 if java_type not in JAVA_PRIMITIVE_TYPES: 00446 type_initializer = 'new java.util.ArrayList<%(type)s>(__%(name)s_len)' 00447 if field.is_builtin: 00448 deserialization_code = '%(name)s.add(%(deserialization_code)s)' \ 00449 % {'name': '%(name)s', 00450 'deserialization_code': base_type_deserialization_code(field.type) % 'bb'} 00451 else: 00452 deserialization_code = """%(type)s __tmp = new %(type)s(); 00453 %(indent)s__tmp.deserialize(bb); 00454 %(indent)s%(name)s.add(__tmp);""" 00455 00456 if not size_initializer: 00457 size_initializer = '%(name)s.length;' % {'name': field.name} 00458 if not type_initializer: 00459 type_initializer = 'new %(type)s[__%(name)s_len]' 00460 if not deserialization_code: 00461 if field.is_builtin: 00462 deserialization_code = '%(name)s[__i] = %(deserialization_code)s' \ 00463 % {'name': '%(name)s', 00464 'deserialization_code': base_type_deserialization_code(field.type) % 'bb'} 00465 else: 00466 deserialization_code = """%(type)s __tmp = new %(type)s(); 00467 %(indent)s__tmp.deserialize(bb); 00468 %(indent)s%(name)s[__i] = __tmp""" 00469 00470 # Assemble the code from size_initializer, type_initializer and deserialization_code 00471 default_vars_dict = {'name': field.name, 'type': java_type} 00472 s.write(""" 00473 int __%(name)s_len = %(size_initializer)s; 00474 %(name)s = %(type_initializer)s; 00475 for(int __i=0; __i<__%(name)s_len; __i++) { 00476 %(deserialization_code)s; 00477 } 00478 """ % dict(default_vars_dict, 00479 **{'size_initializer': size_initializer % default_vars_dict, 00480 'type_initializer': type_initializer % default_vars_dict, 00481 'deserialization_code': deserialization_code % dict(default_vars_dict, **{'indent': 6*' '})})) 00482 00483 # No array. Default deserialization. 00484 elif field.is_builtin: 00485 s.write(' %s = %s;\n' % (field.name, 00486 base_type_deserialization_code(field.type) % 'bb')) 00487 else: 00488 s.write(' %s.deserialize(bb);\n' % field.name) 00489 s.write(' }\n') 00490 00491 def write_serialization_methods(s, spec): 00492 write_serialization_length(s, spec) 00493 write_serialization_method(s, spec) 00494 write_deserialization_method(s, spec) 00495 write_compare_methods(s, spec) 00496 00497 def write_msg_metadata_method(s, name, return_value): 00498 s.write(' public static java.lang.String __s_get%s() { return %s; }\n' % (name, return_value)) 00499 s.write(' public java.lang.String get%(name)s() { return __s_get%(name)s(); }\n' 00500 % {'name': name}) 00501 00502 def write_equals_method(s, spec): 00503 s.write(""" 00504 @SuppressWarnings("all") 00505 public boolean equals(Object o) { 00506 if(!(o instanceof %(type)s)) 00507 return false; 00508 %(type)s other = (%(type)s) o; 00509 return 00510 """ % {'type': spec.short_name}) 00511 00512 for field in spec.parsed_fields(): 00513 java_type = base_type_to_java(field.base_type) 00514 template_dict = {'name': field.name} 00515 if field.is_array and (field.array_len or java_type in JAVA_PRIMITIVE_TYPES): 00516 s.write(' java.util.Arrays.equals(%(name)s, other.%(name)s) &&\n' % template_dict) 00517 elif not field.is_array and java_type in JAVA_PRIMITIVE_TYPES: 00518 s.write(' %(name)s == other.%(name)s &&\n' % template_dict) 00519 else: 00520 s.write(' %(name)s.equals(other.%(name)s) &&\n' % template_dict) 00521 s.write(""" true; 00522 } 00523 """) 00524 00525 def write_hash_code_method(s, spec): 00526 s.write(""" 00527 @SuppressWarnings("all") 00528 public int hashCode() { 00529 final int prime = 31; 00530 int result = 1; 00531 long tmp; 00532 """) 00533 for field in spec.parsed_fields(): 00534 java_type = base_type_to_java(field.base_type) 00535 template_dict = {'name': 'this.%s' % field.name} 00536 if field.is_array and (field.array_len or java_type in JAVA_PRIMITIVE_TYPES): 00537 s.write(' result = prime * result + java.util.Arrays.hashCode(%(name)s);\n' % template_dict) 00538 elif not field.is_array and java_type in JAVA_PRIMITIVE_TYPES: 00539 s.write(' result = prime * result + %(hash_code)s;\n' \ 00540 % dict(template_dict, **{'hash_code': JAVA_HASH_CODES[java_type] % {'value': template_dict['name']}})) 00541 else: 00542 s.write(' result = prime * result + (%(name)s == null ? 0 : %(name)s.hashCode());\n' % template_dict) 00543 s.write(' return result;\n }\n') 00544 00545 def write_compare_methods(s, spec): 00546 write_equals_method(s, spec) 00547 write_hash_code_method(s, spec) 00548 00549 def write_member_functions(s, spec, msg_metadata_methods): 00550 """ 00551 The the default member functions 00552 """ 00553 s.write('\n') 00554 for method_desc in msg_metadata_methods.items(): 00555 write_msg_metadata_method(s, *method_desc) 00556 00557 write_clone_methods(s, spec) 00558 write_serialization_methods(s, spec) 00559 00560 def compute_full_text_escaped(gen_deps_dict): 00561 """ 00562 Same as roslib.gentools.compute_full_text, except that the 00563 resulting text is escaped to be safe for C++ double quotes 00564 00565 @param get_deps_dict: dictionary returned by get_dependencies call 00566 @type get_deps_dict: dict 00567 @return: concatenated text for msg/srv file and embedded msg/srv types. Text will be escaped for double quotes 00568 @rtype: str 00569 """ 00570 definition = roslib.gentools.compute_full_text(gen_deps_dict) 00571 lines = definition.split('\n') 00572 s = StringIO() 00573 for line in lines: 00574 line = escape_string(line) 00575 s.write('\"%s\\n\" +\n'%(line)) 00576 00577 s.write('\"\"') 00578 val = s.getvalue() 00579 s.close() 00580 return val 00581 00582 def ros_version(): 00583 p = os.popen('rosversion ros') 00584 version_string = p.readline() 00585 if version_string: 00586 result = tuple([int(x) for x in version_string.split('.')]) 00587 else: 00588 result = None 00589 p.close() 00590 return result 00591 00592 def generate(msg_path, output_base_path=None): 00593 """ 00594 Generate a message 00595 00596 @param msg_path: The path to the .msg file 00597 @type msg_path: str 00598 """ 00599 (package_dir, package) = roslib.packages.get_dir_pkg(msg_path) 00600 (_, spec) = roslib.msgs.load_from_file(msg_path, package) 00601 00602 s = StringIO() 00603 write_begin(s, spec, msg_path) 00604 write_imports(s, spec) 00605 00606 write_class(s, spec) 00607 00608 write_end(s, spec) 00609 00610 if output_base_path: 00611 output_dir = '%s/ros/pkg/%s/msg'%(output_base_path, package) 00612 else: 00613 output_dir = '%s/msg_gen/java/ros/pkg/%s/msg'%(package_dir, package) 00614 00615 if (not os.path.exists(output_dir)): 00616 # if we're being run concurrently, the above test can report false but os.makedirs can still fail if 00617 # another copy just created the directory 00618 try: 00619 os.makedirs(output_dir) 00620 except OSError, e: 00621 pass 00622 00623 f = open('%s/%s.java'%(output_dir, spec.short_name), 'w') 00624 print >> f, s.getvalue() 00625 00626 s.close() 00627 00628 def generate_messages(argv): 00629 if not os.path.exists(argv[-1]) or os.path.isdir(argv[-1]): 00630 for arg in argv[1:-1]: 00631 generate(arg, argv[-1]) 00632 else: 00633 for arg in argv[1:]: 00634 generate(arg) 00635 00636 if __name__ == "__main__": 00637 generate_messages(sys.argv)