17 from __future__ 
import print_function
    23 from os.path 
import join 
as pjoin
    29 from genmsg 
import SrvSpec, MsgSpec, MsgContext
    30 from genmsg.msg_loader 
import load_srv_from_file, load_msg_by_type
    31 import genmsg.gentools
    32 from copy 
import deepcopy
    35     from cStringIO 
import StringIO 
    37     from io 
import StringIO 
    44     return t 
in [
'int8', 
'uint8', 
'int16', 
'uint16']
    47     return is_fixnum(t) 
or t 
in [
'byte', 
'char', 
'int32', 
'uint32', 
'int64', 
'uint64'] 
    50     return t 
in [
'int8', 
'int16', 
'int32', 
'int64']
    53     return t 
in [
'uint8', 
'uint16', 
'uint32', 
'uint64']
    62     return t 
in [
'float32', 
'float64']
    65     return t 
in [
'time', 
'duration']
    68     if f.base_type == 
'Header':
    69         return (
'std_msgs', 
'Header')
    71         return f.base_type.split(
'/')
    74     if t 
in [
'int8', 
'byte', 
'bool']:
    76     elif t 
in [
'uint8', 
'char']:
    95     return is_fixnum(t) 
or is_float(t) 
or t 
in [
'byte', 
'char', 
'bool', 
'uint8', 
'uint16',
'int8', 
'int16', 
'uint32', 
'int32']
    98     """Returns the size in bytes of a builtin type if available. Else None"""    99     if t 
in [
'int8', 
'uint8', 
'byte', 
'bool', 
'char']:
   101     elif t 
in [
'int16', 
'uint16']:
   103     elif t 
in [
'int32', 
'uint32', 
'float32']:
   105     elif t 
in [
'int64', 
'uint64', 
'float64', 
'time', 
'duration']:
   110     """Return the default value for a message data field"""   112         if not field.array_len:
   115             field_copy = deepcopy(field)
   116             field_copy.is_array = 
False;
   118             return 'new Array({}).fill({})'.format(field.array_len, field_default)
   119     elif field.is_builtin:
   123             return '{secs: 0, nsecs: 0}'   131     (package, msg_type) = field.base_type.split(
'/')
   132     if package == current_message_package:
   133         return 'new {}()'.format(msg_type)
   135         return 'new {}.msg.{}()'.format(package, msg_type)
   138     """Check if a particular message specification has a constant size in bytes"""   139     parsed_fields = spec.parsed_fields()
   140     types = [f.base_type 
for f 
in parsed_fields]
   141     variableLengthArrays = [f.is_array 
and not f.array_len 
for f 
in parsed_fields]
   142     isBuiltin = [f.is_builtin 
for f 
in parsed_fields]
   143     if 'string' in types:
   145     elif True in variableLengthArrays:
   147     elif False not in isBuiltin:
   150         nonBuiltins = [f 
for f 
in parsed_fields 
if not f.is_builtin]
   152         for idx, f 
in enumerate(nonBuiltins):
   153             field_msg_context = MsgContext.create_default()
   154             field_spec = genmsg.msg_loader.load_msg_by_type(field_msg_context, f.base_type, search_path)
   161     Return the size of a message.   162     If the message does not have a fixed size, returns None   168     for f 
in spec.parsed_fields():
   171             if type_size 
is None:
   172                 raise Exception(
'Field {} has a non-constant size'.format(f.base_type))
   175             elif not f.array_len:
   176                 raise Exception(
'Array field {} has a variable length'.format(f.base_type))
   178                 length += (f.array_len * type_size)
   180             field_msg_context = MsgContext.create_default()
   181             field_spec = genmsg.msg_loader.load_msg_by_type(field_msg_context, f.base_type, search_path)
   183             if field_size 
is None:
   184                 raise Exception(
'Field {} has a non-constant size'.format(f.base_type))
   199     def write(self, s, indent=True, newline=True):
   235         self.writer.inc_indent(self.
inc)
   237             self.writer.block_next_indent()
   240         self.writer.dec_indent(self.
inc)
   243     cmake_path = os.environ[
'CMAKE_PREFIX_PATH']
   244     paths = cmake_path.split(
':')
   245     for search_path 
in paths:
   246         test_path = pjoin(search_path, path)
   247         if os.path.exists(test_path):
   257     for field 
in spec.parsed_fields():
   258         if not field.is_builtin:
   259             (field_type_package, msg_type) = field.base_type.split(
'/')
   260             if field_type_package 
in found_packages:
   263             if field_type_package == spec.package:
   264                 if msg_type 
not in local_deps:
   265                     local_deps.append(msg_type)
   267                 found_packages.append(field_type_package)
   269     return found_packages, local_deps
   272     "Writes the beginning of the file: a comment saying it's auto-generated and the in-package form"   274     s.write(
'// Auto-generated. Do not edit!\n\n', newline=
False)
   275     suffix = 
'srv' if is_service 
else 'msg'   276     s.write(
'// (in-package %s.%s)\n\n'%(spec.package, suffix), newline=
False)
   278 def write_requires(s, spec, previous_packages=None, prev_deps=None, isSrv=False):
   279     "Writes out the require fields"   280     if previous_packages 
is None:
   281         s.write(
'"use strict";')
   283         s.write(
'const _serializer = _ros_msg_utils.Serialize;')
   284         s.write(
'const _arraySerializer = _serializer.Array;');
   285         s.write(
'const _deserializer = _ros_msg_utils.Deserialize;')
   286         s.write(
'const _arrayDeserializer = _deserializer.Array;');
   287         s.write(
'const _finder = _ros_msg_utils.Find;')
   288         s.write(
'const _getByteLength = _ros_msg_utils.getByteLength;');
   289         previous_packages = {}
   290     if prev_deps 
is None:
   296     local_deps = [dep 
for dep 
in local_deps 
if dep 
not in prev_deps]
   301     for dep 
in local_deps:
   303             s.write(
'let {} = require(\'../msg/{}.js\');'.format(dep, dep))
   305             s.write(
'let {} = require(\'./{}.js\');'.format(dep, dep))
   308     found_packages = {package 
for package 
in found_packages 
if package 
not in previous_packages}
   309     for package 
in found_packages:
   313         s.write(
'let {0} = _finder(\'{0}\');'.format(package))
   315     s.write(
'//-----------------------------------------------------------')
   317     return found_packages, local_deps
   320     s.write(
'if (initObj.hasOwnProperty(\'{}\')) {{'.format(field.name))
   322         s.write(
'this.{} = initObj.{}'.format(field.name, field.name))
   326         s.write(
'this.{} = {};'.format(field.name, 
get_default_value(field, spec.package)))
   330     s.write(
'class {} {{'.format(spec.actual_name))
   333         s.write(
'constructor(initObj={}) {')
   335             s.write(
'if (initObj === null) {')
   337                 s.write(
'// initObj === null is a special case for deserialization where we don\'t initialize fields')
   338                 for field 
in spec.parsed_fields():
   339                     s.write(
'this.{} = null;'.format(field.name))
   343                 for field 
in spec.parsed_fields():
   350     (field_pkg, msg_type) = field.base_type.split(
'/')
   354     return '{}.msg.{}'.format(field_pkg, msg_type)
   358         s.write(
'static Resolve(msg) {')
   360             s.write(
'// deep-construct a valid message object instance of whatever was passed in');
   361             s.write(
'if (typeof msg !== \'object\' || msg === null) {')
   365             s.write(
'const resolved = new {}(null);'.format(spec.short_name))
   366             for field 
in spec.parsed_fields():
   367                 if not field.is_builtin:
   368                     s.write(
'if (msg.{} !== undefined) {{'.format(field.name))
   371                             if field.array_len 
is None:
   372                                 s.write(
'resolved.{} = new Array(msg.{}.length);'.format(field.name, field.name))
   373                                 s.write(
'for (let i = 0; i < resolved.{}.length; ++i) {{'.format(field.name))
   375                                     s.write(
'resolved.{}[i] = {}.Resolve(msg.{}[i]);'.format(field.name, 
get_message_path_from_field(field, spec.package), field.name))
   378                                 s.write(
'resolved.{} = new Array({})'.format(field.name, field.array_len))
   379                                 s.write(
'for (let i = 0; i < resolved.{}.length; ++i) {{'.format(field.name))
   381                                     s.write(
'if (msg.{}.length > i) {{'.format(field.name))
   383                                         s.write(
'resolved.{}[i] = {}.Resolve(msg.{}[i]);'.format(field.name, 
get_message_path_from_field(field, spec.package), field.name))
   395                         s.write(
'resolved.{} = {}'.format(field.name, 
get_default_value(field, spec.package)))
   398                     s.write(
'if (msg.{} !== undefined) {{'.format(field.name))
   400                         s.write(
'resolved.{} = msg.{};'.format(field.name, field.name))
   404                         s.write(
'resolved.{} = {}'.format(field.name, 
get_default_value(field, spec.package)))
   407             s.write(
'return resolved;')
   414     s.write(
'module.exports = {};'.format(spec.actual_name))
   417     s.write(
'bufferOffset = {};'.format(rest))
   421     s.write(
'// Serialize the length for message field [{}]'.format(name))
   425     s.write(
'// Check that the constant length array field [{}] has the right length'.format(field.name))
   426     s.write(
'if (obj.{}.length !== {}) {{'.format(field.name, field.array_len))
   428         s.write(
'throw new Error(\'Unable to serialize array field {} - length must be {}\')'.format(field.name, field.array_len))
   434         write_serialize_base(s, 
'_arraySerializer.{}(obj.{}, buffer, bufferOffset, {})'.format(f.base_type, f.name, 
'null' if f.array_len 
is None else f.array_len))
   436         write_serialize_base(s, 
'_serializer.{}(obj.{}, buffer, bufferOffset)'.format(f.base_type, f.name))
   440     (package, msg_type) = f.base_type.split(
'/')
   441     samePackage =  package == thisPackage
   443         if f.array_len 
is None:
   445         s.write(
'obj.{}.forEach((val) => {{'.format(f.name))
   450                 write_serialize_base(s, 
'{}.msg.{}.serialize(val, buffer, bufferOffset)'.format(package, msg_type))
   456             write_serialize_base(s, 
'{}.msg.{}.serialize(obj.{}, buffer, bufferOffset)'.format(package, msg_type, f.name))
   461         if f.array_len 
is not None:
   464     s.write(
'// Serialize message field [{}]'.format(f.name))
   472     Write the serialize method   475         s.write(
'static serialize(obj, buffer, bufferOffset) {')
   477             s.write(
'// Serializes a message object of type {}'.format(spec.short_name))
   478             for f 
in spec.parsed_fields():
   480             s.write(
'return bufferOffset;')
   486     s.write(
'// Deserialize array length for message field [{}]'.format(name))
   487     s.write(
'len = _deserializer.uint32(buffer, bufferOffset);')
   490     (package, msg_type) = f.base_type.split(
'/')
   491     samePackage = package == thisPackage
   493         if f.array_len 
is None:
   496             s.write(
'len = {};'.format(f.array_len))
   498         s.write(
'data.{} = new Array(len);'.format(f.name))
   499         s.write(
'for (let i = 0; i < len; ++i) {')
   502                 s.write(
'data.{}[i] = {}.deserialize(buffer, bufferOffset)'.format(f.name, msg_type));
   504                 s.write(
'data.{}[i] = {}.msg.{}.deserialize(buffer, bufferOffset)'.format(f.name, package, msg_type));
   508             s.write(
'data.{} = {}.deserialize(buffer, bufferOffset);'.format(f.name, msg_type))
   510             s.write(
'data.{} = {}.msg.{}.deserialize(buffer, bufferOffset);'.format(f.name, package, msg_type))
   514         s.write(
'data.{} = _arrayDeserializer.{}(buffer, bufferOffset, {})'.format(f.name, f.base_type, 
'null' if f.array_len 
is None else f.array_len));
   516         s.write(
'data.{} = _deserializer.{}(buffer, bufferOffset);'.format(f.name, f.base_type))
   520     s.write(
'// Deserialize message field [{}]'.format(f.name))
   529     Write the deserialize method   532         s.write(
'static deserialize(buffer, bufferOffset=[0]) {')
   534             s.write(
'//deserializes a message object of type {}'.format(spec.short_name))
   536             s.write(
'let data = new {}(null);'.format(spec.short_name))
   537             for f 
in spec.parsed_fields():
   540             s.write(
'return data;')
   546     Write a static method to determine the buffer size of a complete message   550         s.write(
'static getMessageSize(object) {')
   552         if msg_size 
is not None:
   554                 s.write(
'return {};'.format(msg_size))
   556             def get_dynamic_field_length_line(field, query):
   559                         raise Exception(
'Unexpected field {} with type {} has unknown length'.format(field.name, field.base_type))
   561                     return 'length += 4 + {}.length;'.format(query)
   563                 (package, msg_type) = field.base_type.split(
'/')
   564                 samePackage = spec.package == package
   566                     return 'length += {}.getMessageSize({});'.format(msg_type, query)
   568                     return 'length += {}.msg.{}.getMessageSize({});'.format(package, msg_type, query)
   571                 s.write(
'let length = 0;')
   574                 len_constant_length_fields = 0;
   575                 for f 
in spec.parsed_fields():
   580                         field_msg_context = MsgContext.create_default()
   581                         field_spec = genmsg.msg_loader.load_msg_by_type(field_msg_context, f.base_type, search_path)
   585                         if f.array_len 
and field_size 
is not None:
   586                             len_constant_length_fields += (field_size * f.array_len)
   588                         elif not f.array_len:
   589                             len_constant_length_fields += 4
   592                             s.write(
'length += object.{}.length;'.format(f.name))
   593                         elif field_size 
is not None:
   594                             s.write(
'length += {} * object.{}.length;'.format(field_size, f.name))
   598                                     raise Exception(
'Unexpected field {} with type {} has unknown length'.format(f.name, f.base_type))
   600                                 line_to_write = 
'length += 4 + val.length;'   602                                 (package, msg_type) = f.base_type.split(
'/')
   603                                 samePackage = spec.package == package
   605                                     line_to_write = 
'length += {}.getMessageSize(val);'.format(msg_type,)
   607                                     line_to_write = 
'length += {}.msg.{}.getMessageSize(val);'.format(package, msg_type)
   608                             s.write(
'object.{}.forEach((val) => {{'.format(f.name))
   610                                 s.write(line_to_write)
   612                     elif field_size 
is not None:
   613                         len_constant_length_fields += field_size
   618                                 raise Exception(
'Unexpected field {} with type {} has unknown length'.format(f.name, f.base_type))
   620                             len_constant_length_fields += 4
   621                             line_to_write = 
'length += object.{}.length;'.format(f.name)
   623                             (package, msg_type) = f.base_type.split(
'/')
   624                             samePackage = spec.package == package
   626                                 line_to_write = 
'length += {}.getMessageSize(object.{});'.format(msg_type, f.name)
   628                                 line_to_write = 
'length += {}.msg.{}.getMessageSize(object.{});'.format(package, msg_type, f.name)
   629                         s.write(line_to_write)
   631                 if len_constant_length_fields > 0:
   632                     s.write(
'return length + {};'.format(len_constant_length_fields))
   634                     s.write(
'return length;')
   639     s.write(
'"use strict";')
   641     s.write(
'module.exports = {')
   642     msgExists = os.path.exists(pjoin(package_dir, 
'msg/_index.js'))
   643     srvExists = os.path.exists(pjoin(package_dir, 
'srv/_index.js'))
   646             s.write(
'msg: require(\'./msg/_index.js\'),')
   648             s.write(
'srv: require(\'./srv/_index.js\')')
   653     "Writes an index for the messages"   654     s.write(
'"use strict";')
   658         s.write(
'let {} = require(\'./{}.js\');'.format(msg, msg))
   660     s.write(
'module.exports = {')
   663             s.write(
'{}: {},'.format(msg, msg))
   668     "Writes an index for the messages"   669     s.write(
'"use strict";')
   672         s.write(
'let {} = require(\'./{}.js\')'.format(srv, srv))
   674     s.write(
'module.exports = {')
   677             s.write(
'{}: {},'.format(srv, srv))
   683         s.write(
'static datatype() {')
   685             s.write(
'// Returns string type for a %s object'%spec.component_type)
   686             s.write(
'return \'{}\';'.format(spec.full_name))
   691     md5sum = genmsg.compute_md5(msg_context, parent 
or spec)
   693         s.write(
'static md5sum() {')
   696             s.write(
'//Returns md5sum for a message object')
   697             s.write(
'return \'{}\';'.format(md5sum))
   703         s.write(
'static messageDefinition() {')
   705             s.write(
'// Returns full string definition for message')
   706             definition = genmsg.compute_full_text(msg_context, spec)
   707             lines = definition.split(
'\n')
   710                 s.write(
'{}'.format(line))
   717         s.write(
'// Constants for message')
   718         s.write(
'{}.Constants = {{'.format(spec.short_name))
   720             for c 
in spec.constants:
   722                     s.write(
'{}: \'{}\','.format(c.name.upper(), c.val))
   724                     s.write(
'{}: {},'.format(c.name.upper(), 
'true' if c.val 
else 'false'))
   726                     s.write(
'{}: {},'.format(c.name.upper(), c.val))
   731     spec.component_type=
'service'   745     s.write(
'module.exports = {')
   746     name = spec.short_name
   748         s.write(
'Request: {}Request,'.format(name))
   749         s.write(
'Response: {}Response,'.format(name))
   750         md5sum = genmsg.compute_md5(context, spec)
   751         s.write(
'md5sum() {{ return \'{}\'; }},'.format(md5sum))
   752         s.write(
'datatype() {{ return \'{}\'; }}'.format(spec.full_name))
   758     Generate javascript code for all messages in a package   760     msg_context = MsgContext.create_default()
   762         f = os.path.abspath(f)
   763         infile = os.path.basename(f)
   764         full_type = genmsg.gentools.compute_full_type_name(pkg, infile)
   765         spec = genmsg.msg_loader.load_msg_from_file(msg_context, f, full_type)
   770     Generate javascript code for all services in a package   772     msg_context = MsgContext.create_default()
   774         f = os.path.abspath(f)
   775         infile = os.path.basename(f)
   776         full_type = genmsg.gentools.compute_full_type_name(pkg, infile)
   777         spec = genmsg.msg_loader.load_srv_from_file(msg_context, f, full_type)
   781     dir_list = search_path[pkg]
   784         files.extend([f 
for f 
in os.listdir(d) 
if f.endswith(ext)])
   785     return [f[:-len(ext)] 
for f 
in files]
   791     @param msg_path: The path to the .msg file   794     genmsg.msg_loader.load_depends(msg_context, spec, search_path)
   795     spec.actual_name=spec.short_name
   796     spec.component_type=
'message'   797     msgs = 
msg_list(package, search_path, 
'.msg')
   799         genmsg.load_msg_by_type(msg_context, 
'%s/%s'%(package, m), search_path)
   819     if (
not os.path.exists(output_dir)):
   823             os.makedirs(output_dir)
   827     with open(
'%s/%s.js'%(output_dir, spec.short_name), 
'w') 
as f:
   828         f.write(io.getvalue() + 
"\n")
   839     with open(
'{}/_index.js'.format(output_dir), 
'w') 
as f:
   840         f.write(io.getvalue())
   850     package_dir = os.path.dirname(output_dir)
   852     with open(
'{}/_index.js'.format(package_dir), 
'w') 
as f:
   853         f.write(io.getvalue())
   858     "Generate code from .srv file"   859     genmsg.msg_loader.load_depends(msg_context, spec, search_path)
   861     srv_path = os.path.dirname(path)
   862     srvs = 
msg_list(package, {package: [srv_path]}, ext)
   864         load_srv_from_file(msg_context, 
'%s/%s%s'%(srv_path, srv, ext), 
'%s/%s'%(package, srv))
   873     found_packages,local_deps = 
write_requires(s, spec.request, 
None, 
None, 
True)
   874     write_requires(s, spec.response, found_packages, local_deps, 
True)
   875     spec.request.actual_name=
'%sRequest'%spec.short_name
   876     spec.response.actual_name=
'%sResponse'%spec.short_name
   881     with open(
'%s/%s.js'%(output_dir, spec.short_name), 
'w') 
as f:
   882         f.write(io.getvalue())
   893     with open(
'{}/_index.js'.format(output_dir), 
'w') 
as f:
   894         f.write(io.getvalue())
   904     package_dir = os.path.dirname(output_dir)
   906     with open(
'{}/_index.js'.format(package_dir), 
'w') 
as f:
   907         f.write(io.getvalue())
 def write_serialize(s, spec)
def write_serialize_complex(s, f, thisPackage)
def write_deserialize_builtin(s, f)
def write_deserialize_complex(s, f, thisPackage)
def write(self, s, indent=True, newline=True)
def get_message_path_from_field(field, pkg)
def is_message_fixed_size(spec, search_path)
def write_serialize_base(s, rest)
def get_default_value(field, current_message_package)
def find_path_for_package(package)
def write_resolve(s, spec)
def generate_msg_from_spec(msg_context, spec, search_path, output_dir, package, msgs=None)
def write_package_index(s, package_dir)
def is_fixnum(t)
Built in types. 
def write_srv_end(s, context, spec)
def write_srv_component(s, spec, context, parent, search_path)
def msg_list(pkg, search_path, ext)
def find_path_from_cmake_path(path)
def write_get_message_size(s, spec, search_path)
def write_serialize_builtin(s, f)
def get_message_fixed_size(spec, search_path)
def write_md5sum(s, msg_context, spec, parent=None)
def write_constants(s, spec)
def write_deserialize(s, spec)
def write_serialize_length(s, name)
def inc_indent(self, inc=2)
def dec_indent(self, dec=2)
def write_requires(s, spec, previous_packages=None, prev_deps=None, isSrv=False)
def write_serialize_field(s, f, package)
def generate_srv_from_spec(msg_context, spec, search_path, output_dir, package, path)
def write_ros_datatype(s, spec)
def write_msg_constructor_field(s, spec, field)
def generate_srv(pkg, files, out_dir, search_path)
def write_message_definition(s, msg_context, spec)
def __init__(self, w, inc=2, indent_first=True)
def block_next_indent(self)
def write_deserialize_field(s, f, package)
def write_deserialize_length(s, name)
def generate_msg(pkg, files, out_dir, search_path)
def write_msg_index(s, msgs, pkg, context)
def write_serialize_length_check(s, field)
def __exit__(self, type, val, traceback)
def write_begin(s, spec, is_service=False)
def write_srv_index(s, srvs, pkg)