示例#1
0
文件: emit_cpp.c 项目: cd127/lcm-1
static void emit_encode_nohash(lcmgen_t *lcm, FILE *f, lcm_struct_t *ls)
{
    const char* sn = ls->structname->shortname;
    if(0 == g_ptr_array_size(ls->members)) {
        emit(0, "int %s::_encodeNoHash(void *, int, int) const", sn);
        emit(0, "{");
        emit(1,     "return 0;");
        emit(0, "}");
        emit(0, "");
        return;
    }
    emit(0, "int %s::_encodeNoHash(void *buf, int offset, int maxlen) const", sn);
    emit(0, "{");
    emit(1,     "int pos = 0, tlen;");
    emit(0, "");
    for (unsigned int m = 0; m < g_ptr_array_size(ls->members); m++) {
        lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, m);
        int num_dims = g_ptr_array_size(lm->dimensions);

        if (0 == num_dims) {
            if (lcm_is_primitive_type(lm->type->lctypename)) {
                if(!strcmp(lm->type->lctypename, "string")) {
                    emit(1, "char* %s_cstr = (char*) this->%s.c_str();", lm->membername, lm->membername);
                    emit(1, "tlen = __string_encode_array(buf, offset + pos, maxlen - pos, &%s_cstr, 1);",
                         lm->membername);
                } else {
                    emit(1, "tlen = __%s_encode_array(buf, offset + pos, maxlen - pos, &this->%s, 1);",
                         lm->type->lctypename, lm->membername);
                }
                emit(1, "if(tlen < 0) return tlen; else pos += tlen;");
            } else {
                _encode_recursive(lcm, f, lm, 0, 0);
            }
        } else {
            lcm_dimension_t *last_dim = (lcm_dimension_t*) g_ptr_array_index(lm->dimensions, num_dims - 1);

            // for non-string primitive types with variable size final
            // dimension, add an optimization to only call the primitive encode
            // functions only if the final dimension size is non-zero.
            if(lcm_is_primitive_type(lm->type->lctypename) &&
                    strcmp(lm->type->lctypename, "string") &&
                    !is_dim_size_fixed(last_dim->size)) {
                emit(1, "if(%s%s > 0) {", dim_size_prefix(last_dim->size), last_dim->size);
                _encode_recursive(lcm, f, lm, 0, 1);
                emit(1, "}");
            } else {
                _encode_recursive(lcm, f, lm, 0, 0);
            }
        }

        emit(0,"");
    }
    emit(1, "return pos;");
    emit(0,"}");
    emit(0,"");
}
示例#2
0
static void
emit_python_dependencies (const lcmgen_t *lcm, FILE *f, lcm_struct_t *ls)
{
    GHashTable *dependencies = g_hash_table_new (g_str_hash, g_str_equal);
    for (unsigned int m=0; m<ls->members->len; m++) {
        lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index (ls->members, m);
        if (! lcm_is_primitive_type (lm->type->lctypename)) {
            if (strlen (lm->type->package) && 
                ! is_same_package (ls->structname, lm->type)) {
                if (! g_hash_table_lookup (dependencies, lm->type->lctypename)) {
                    g_hash_table_insert (dependencies, lm->type->lctypename, 
                            lm->type->lctypename);
                }
            } else if (! g_hash_table_lookup (dependencies, 
                        lm->type->shortname)){
                g_hash_table_insert (dependencies, lm->type->shortname, 
                        lm->type->shortname);
            }
        }
    }
    GPtrArray *deps = _hash_table_get_vals (dependencies);
    for (int i=0; i<deps->len; i++) {
        const char *package = (char *) g_ptr_array_index (deps, i);
        emit (0, "import %s\n", package);
    }
    g_ptr_array_free (deps, TRUE);
    g_hash_table_destroy (dependencies);
}
示例#3
0
文件: emit_lua.c 项目: GArlington/lcm
static void
emit_lua_dependencies (const lcmgen_t *lcm, FILE *f, lcm_struct_t *ls)
{
    GHashTable *dependencies = g_hash_table_new (g_str_hash, g_str_equal);
    for (unsigned int m=0; m<ls->members->len; m++) {
        lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index (ls->members, m);
        if (! lcm_is_primitive_type (lm->type->lctypename)) {
        	if (!g_hash_table_lookup (dependencies, lm->type->lctypename)
        			&& strcmp(lm->type->lctypename, ls->structname->lctypename)) {
        		g_hash_table_insert (dependencies, lm->type->lctypename,
        				lm->type->lctypename);
        	}
        }
    }
    GPtrArray *deps = _hash_table_get_vals (dependencies);
    for (int i=0; i<deps->len; i++) {
        const char *package = (char *) g_ptr_array_index (deps, i);
        char *variablename = escape_typename_to_variablename(package);
        emit (0, "local %s = require('%s')", variablename, package);
        g_free(variablename);
    }

    if(deps->len) emit (0, "");

    g_ptr_array_free (deps, TRUE);
    g_hash_table_destroy (dependencies);
}
示例#4
0
static void
emit_python_fingerprint (const lcmgen_t *lcm, FILE *f, lcm_struct_t *ls)
{
    const char *sn = ls->structname->shortname;
    emit (1, "_hash = None");

    emit (1, "def _get_hash_recursive(parents):");
    emit (2,     "if %s in parents: return 0", sn);
    for (unsigned int m = 0; m < ls->members->len; m++) {
        lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, m);
        if (! lcm_is_primitive_type (lm->type->lctypename)) {
            emit (2,     "newparents = parents + [%s]", sn);
            break;
        }
    }
    emit_start (2, "tmphash = (0x%"PRIx64, ls->hash);
    for (unsigned int m = 0; m < ls->members->len; m++) {
        lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, m);
        const char *msn = lm->type->shortname;
        if (! lcm_is_primitive_type (lm->type->lctypename)) {
            const char *ghr = "_get_hash_recursive(newparents)";
            if (is_same_type (lm->type, ls->structname)) {
                emit_continue ("+ %s.%s", msn, ghr);
            } else if (is_same_package (lm->type, ls->structname)) {
                emit_continue ("+ %s.%s.%s", msn, msn, ghr);
            } else {
                emit_continue ("+ %s.%s", lm->type->lctypename, ghr);
            }
        }
    }
    emit_end (") & 0xffffffffffffffff");
    emit (2, "tmphash  = (((tmphash<<1)&0xffffffffffffffff)  + "
            "(tmphash>>63)) & 0xffffffffffffffff");
    emit (2,     "return tmphash");
    emit (1, "_get_hash_recursive = staticmethod(_get_hash_recursive)");

    emit (1, "_packed_fingerprint = None");
    emit (0, "");
    emit (1, "def _get_packed_fingerprint():");
    emit (2,     "if %s._packed_fingerprint is None:", sn);
    emit (3,         "%s._packed_fingerprint = struct.pack(\">Q\", "
            "%s._get_hash_recursive([]))", sn, sn);
    emit (2,     "return %s._packed_fingerprint", sn);
    emit (1, "_get_packed_fingerprint = staticmethod(_get_packed_fingerprint)");
    fprintf (f, "\n");

}
示例#5
0
文件: emit_cpp.c 项目: cd127/lcm-1
static void emit_compute_hash(lcmgen_t *lcm, FILE *f, lcm_struct_t *ls)
{
    const char *sn  = ls->structname->shortname;
    int last_complex_member = -1;
    for (unsigned int m = 0; m < g_ptr_array_size(ls->members); m++) {
        lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, m);
        if(!lcm_is_primitive_type(lm->type->lctypename))
            last_complex_member = m;
    }

    if(last_complex_member >= 0) {
        emit(0, "uint64_t %s::_computeHash(const __lcm_hash_ptr *p)", sn);
        emit(0, "{");
        emit(1,     "const __lcm_hash_ptr *fp;");
        emit(1,     "for(fp = p; fp != NULL; fp = fp->parent)");
        emit(2,         "if(fp->v == %s::getHash)", sn);
        emit(3,              "return 0;");
        if(g_ptr_array_size(ls->members)) {
            emit(1, "const __lcm_hash_ptr cp = { p, (void*)%s::getHash };", sn);
        }
        emit(0, "");
        emit(1,     "uint64_t hash = 0x%016"PRIx64"LL +", ls->hash);

        for (unsigned int m = 0; m <= last_complex_member; m++) {
            lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, m);
            char* lm_tnc = dots_to_double_colons(lm->type->lctypename);
            if(!lcm_is_primitive_type(lm->type->lctypename)) {
                emit(2, " %s::_computeHash(&cp)%s",
                     lm_tnc,
                     (m == last_complex_member) ? ";" : " +");
            }
            free(lm_tnc);
        }
        emit(0, "");
    } else {
        emit(0, "uint64_t %s::_computeHash(const __lcm_hash_ptr *)", sn);
        emit(0, "{");
        emit(1,     "uint64_t hash = 0x%016"PRIx64"LL;", ls->hash);
    }

    emit(1, "return (hash<<1) + ((hash>>63)&1);");
    emit(0, "}");
    emit(0, "");
}
示例#6
0
文件: emit_m.c 项目: cd127/lcm-1
static int emit_header(lcmgen_t *lcm, lcm_struct_t *ls)
{
	start_file("_new");

    // define the class
    emit(0, "function S = %s_new()", sn);
    emit(1,   "S = struct(...");

    // data members
	int const members = g_ptr_array_size(ls->members);

	for (unsigned int mx = 0; mx < members; mx++) {
		lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, mx);
		char* lm_tnc = dots_to_double_colons(lm->type->lctypename);

		emit_start(2, "'%s', ", lm->membername);
		int const dimensions = g_ptr_array_size(lm->dimensions);
		int const primitive = lcm_is_primitive_type(lm->type->lctypename);
		if (0 == dimensions) {
			emit_continue("%s%s", map_type_name(lm_tnc) , primitive ? "(0)" : "_new()");
		} else {
			emit_continue("repmat( %s%s, [", map_type_name(lm_tnc), primitive ? "(0)" : "_new()");
			for (int dx = 0; dx < dimensions - 1; ++dx) {
				lcm_dimension_t *dim = (lcm_dimension_t *) g_ptr_array_index(lm->dimensions, dx);
				emit_continue("%s, ", dim->size);
			}
			lcm_dimension_t *dim = (lcm_dimension_t*) g_ptr_array_index(lm->dimensions, dimensions - 1);
			emit_continue("%s%s] )", dim->size, dimensions == 1 ? ", 1" : "");
		}
		emit_end("%s", (members == mx + 1 ? " );" : ",..."));
	}
	emit(0, "%%endfunction");
	emit(0, "");

//    // constants TODO
//    if (g_ptr_array_size(ls->constants) > 0) {
//        emit(1, "public:");
//        for (unsigned int i = 0; i < g_ptr_array_size(ls->constants); i++) {
//            lcm_constant_t *lc = (lcm_constant_t *) g_ptr_array_index(ls->constants, i);
//            assert(lcm_is_legal_const_type(lc->lctypename));
//
//            const char *suffix = "";
//            if (!strcmp(lc->lctypename, "int64_t"))
//              suffix = "LL";
//            char const * mapped_typename = map_type_name(lc->lctypename);
//            emit(2, "static const %-8s %s = %s%s;", mapped_typename,
//                lc->membername, lc->val_str, suffix);
//            //free(mapped_typename);
//        }
//        emit(0, "");
//    }
//	emit(9, "};");
//
//    free(tn_);
	end_file();
}
示例#7
0
文件: emit_cpp.c 项目: cd127/lcm-1
static void emit_encoded_size_nohash(lcmgen_t *lcm, FILE *f, lcm_struct_t *ls)
{
    const char *sn = ls->structname->shortname;
    emit(0, "int %s::_getEncodedSizeNoHash() const", sn);
    emit(0, "{");
    if(0 == g_ptr_array_size(ls->members)) {
        emit(1,     "return 0;");
        emit(0,"}");
        emit(0,"");
        return;
    }
    emit(1,     "int enc_size = 0;");
    for (unsigned int m = 0; m < g_ptr_array_size(ls->members); m++) {
        lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, m);
        int ndim = g_ptr_array_size(lm->dimensions);

        if(lcm_is_primitive_type(lm->type->lctypename) &&
                strcmp(lm->type->lctypename, "string")) {
            emit_start(1, "enc_size += ");
            for(int n=0; n < ndim - 1; n++) {
                lcm_dimension_t *dim = (lcm_dimension_t*) g_ptr_array_index(lm->dimensions, n);
                emit_continue("%s%s * ", dim_size_prefix(dim->size), dim->size);
            }
            if(ndim > 0) {
                lcm_dimension_t *dim = (lcm_dimension_t*) g_ptr_array_index(lm->dimensions, ndim - 1);
                emit_end("__%s_encoded_array_size(NULL, %s%s);",
                         lm->type->lctypename, dim_size_prefix(dim->size), dim->size);
            } else {
                emit_end("__%s_encoded_array_size(NULL, 1);", lm->type->lctypename);
            }
        } else {
            for(int n=0; n < ndim; n++) {
                lcm_dimension_t *dim = (lcm_dimension_t*) g_ptr_array_index(lm->dimensions, n);
                emit(1+n, "for (int a%d = 0; a%d < %s%s; a%d++) {",
                     n, n, dim_size_prefix(dim->size), dim->size, n);
            }
            emit_start(ndim + 1, "enc_size += this->%s", lm->membername);
            for(int i=0; i<ndim; i++)
                emit_continue("[a%d]", i);
            if(!strcmp(lm->type->lctypename, "string")) {
                emit_end(".size() + 4 + 1;");
            } else {
                emit_end("._getEncodedSizeNoHash();");
            }
            for(int n=ndim-1; n >= 0; n--) {
                emit(1 + n, "}");
            }
        }
    }
    emit(1, "return enc_size;");
    emit(0,"}");
    emit(0,"");
}
示例#8
0
文件: emit_cpp.c 项目: cd127/lcm-1
static void _encode_recursive(lcmgen_t* lcm, FILE* f, lcm_member_t* lm, int depth, int extra_indent)
{
    int indent = extra_indent + 1 + depth;
    // primitive array
    if (depth+1 == g_ptr_array_size(lm->dimensions) &&
            lcm_is_primitive_type(lm->type->lctypename) &&
            strcmp(lm->type->lctypename, "string")) {
        lcm_dimension_t *dim = (lcm_dimension_t*) g_ptr_array_index(lm->dimensions, depth);
        emit_start(indent, "tlen = __%s_encode_array(buf, offset + pos, maxlen - pos, &this->%s",
                   lm->type->lctypename, lm->membername);
        for(int i=0; i<depth; i++)
            emit_continue("[a%d]", i);
        emit_end("[0], %s%s);", dim_size_prefix(dim->size), dim->size);

        emit(indent, "if(tlen < 0) return tlen; else pos += tlen;");
        return;
    }
    //
    if(depth == g_ptr_array_size(lm->dimensions)) {
        if(!strcmp(lm->type->lctypename, "string")) {
            emit_start(indent, "char* __cstr = (char*) this->%s", lm->membername);
            for(int i=0; i<depth; i++)
                emit_continue("[a%d]", i);
            emit_end(".c_str();");
            emit(indent, "tlen = __string_encode_array(buf, offset + pos, maxlen - pos, &__cstr, 1);");
        } else {
            emit_start(indent, "tlen = this->%s", lm->membername);
            for(int i=0; i<depth; i++)
                emit_continue("[a%d]", i);
            emit_end("._encodeNoHash(buf, offset + pos, maxlen - pos);");
        }
        emit(indent, "if(tlen < 0) return tlen; else pos += tlen;");
        return;
    }

    lcm_dimension_t *dim = (lcm_dimension_t*) g_ptr_array_index(lm->dimensions, depth);

    emit(indent, "for (int a%d = 0; a%d < %s%s; a%d++) {",
         depth, depth, dim_size_prefix(dim->size), dim->size, depth);

    _encode_recursive(lcm, f, lm, depth+1, extra_indent);

    emit(indent, "}");
}
示例#9
0
文件: emit_m.c 项目: cd127/lcm-1
static int emit_compute_hash(lcmgen_t *lcm, lcm_struct_t *ls)
{
	start_file("_computeHash");

    emit(0, "function hash = %s_computeHash(parents)", sn);
	emit(1,   "parents_len = length(parents);");
    emit(1,   "parents = [parents, %zu, '%s'];", strlen(sn), sn);
    emit(0, "");
	emit(1,   "hash = hex2int64('%016"PRIx64"');", ls->hash);

    for (unsigned int m = 0; m < g_ptr_array_size(ls->members); m++) {
        lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, m);
        if(!lcm_is_primitive_type(lm->type->lctypename)) {
            char* lm_tnc = dots_to_double_colons(lm->type->lctypename);

			emit(1, "visit = true;");
			emit(1, "ix = uint32(1);");
			emit(1, "while ix < parents_len");
			emit(2,   "p_len = uint32(parents(ix));");
			emit(2,   "if %zu == p_len && strcmp(parents(ix + 1: ix + p_len), '%s')", strlen(lm_tnc), lm_tnc);
			emit(3,     "visit = false;");
			emit(3,     "break");
			emit(2,   "end");
			emit(2,   "ix = ix + p_len + 1;");
			emit(1, "end");
			emit(1, "if visit");
			emit(2,   "hash = add_overflow(hash, %s_computeHash(parents));", lm_tnc);
			emit(1, "end");
			emit(0, "");
            free(lm_tnc);
		}
	}
	emit(1,   "%%wrap around shift");
	emit(1,   "overflowbit = bitshift(hash(2), -31);");
	emit(1,   "bigendbit = bitshift(hash(1), -31);");
	emit(1,   "hash = bitshift(hash, 1);");
	emit(1,   "hash(1) = bitor(hash(1), overflowbit);");
	emit(1,   "hash(2) = bitor(hash(2), bigendbit);");
    emit(0, "%%endfunction");
    emit(0, "");

	end_file();
}
示例#10
0
文件: emit_lua.c 项目: GArlington/lcm
static void
emit_lua_fingerprint (const lcmgen_t *lcm, FILE *f, lcm_struct_t *ls)
{
    const char *sn = ls->structname->shortname;

    emit(0, "function %s._get_hash_recursive(parents)", sn);
    emit(0, "");
    emit(0, "  local newparents = {}");
    emit(0, "");
    emit(0, "  for _, v in ipairs(parents) do");
    emit(0, "    if v == %s then return lcm._hash.new('0x0') end", sn);
    emit(0, "    table.insert(newparents, v)");
    emit(0, "  end");
    emit(0, "");
    emit(0, "  table.insert(newparents, %s)", sn);
    emit(0, "");
    emit(0, "  local hash = lcm._hash.new('0x%"PRIx64"')", ls->hash);

    // add all substruct hashes
    for (unsigned int m = 0; m < ls->members->len; m++) {
    	lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, m);
    	const char *msn = lm->type->shortname;
    	if (! lcm_is_primitive_type(lm->type->lctypename)) {
    		const char *ghr = "_get_hash_recursive(newparents)";
    		// XXX this might need a touch up, not sure about intra-module names
    		if (is_same_type(lm->type, ls->structname)) {
    			emit(0, "    + %s.%s", msn, ghr);
    		} else {
    			char *variablename = escape_typename_to_variablename(lm->type->lctypename);
    			emit(0, "    + %s.%s", variablename, ghr);
    			g_free(variablename);
    		}
    	}
    }

    emit(0, "  hash:rotate(1)");
    emit(0, "");
    emit(0, "  return hash");
    emit(0, "end");
    emit(0, "");
    emit(0, "%s._packed_fingerprint = lcm._pack.pack('>X', %s._get_hash_recursive({}))", sn, sn);
    emit(0, "");
}
示例#11
0
文件: emit_cpp.c 项目: cd127/lcm-1
static void emit_decode_nohash(lcmgen_t *lcm, FILE *f, lcm_struct_t *ls)
{
    const char* sn = ls->structname->shortname;
    if(0 == g_ptr_array_size(ls->members)) {
        emit(0, "int %s::_decodeNoHash(const void *, int, int)", sn);
        emit(0, "{");
        emit(1,     "return 0;");
        emit(0, "}");
        emit(0, "");
        return;
    }
    emit(0, "int %s::_decodeNoHash(const void *buf, int offset, int maxlen)", sn);
    emit(0, "{");
    emit(1,     "int pos = 0, tlen;");
    emit(0, "");
    for (unsigned int m = 0; m < g_ptr_array_size(ls->members); m++) {
        lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, m);

        if (0 == g_ptr_array_size(lm->dimensions) && lcm_is_primitive_type(lm->type->lctypename)) {
            if(!strcmp(lm->type->lctypename, "string")) {
                emit(1, "int32_t __%s_len__;", lm->membername);
                emit(1, "tlen = __int32_t_decode_array(buf, offset + pos, maxlen - pos, &__%s_len__, 1);", lm->membername);
                emit(1, "if(tlen < 0) return tlen; else pos += tlen;");
                emit(1, "if(__%s_len__ > maxlen - pos) return -1;", lm->membername);
                emit(1, "this->%s.assign(((const char*)buf) + offset + pos, __%s_len__ - 1);", lm->membername, lm->membername);
                emit(1, "pos += __%s_len__;", lm->membername);
            } else {
                emit(1, "tlen = __%s_decode_array(buf, offset + pos, maxlen - pos, &this->%s, 1);", lm->type->lctypename, lm->membername);
                emit(1, "if(tlen < 0) return tlen; else pos += tlen;");
            }
        } else {
            _decode_recursive(lcm, f, lm, 0);
        }

        emit(0,"");
    }
    emit(1, "return pos;");
    emit(0, "}");
    emit(0, "");
}
示例#12
0
文件: emit_lua.c 项目: GArlington/lcm
static void
emit_lua_encode_one (const lcmgen_t *lcm, FILE *f, lcm_struct_t *ls)
{
    emit(0, "function %s:_encode_one()", ls->structname->shortname);

    // check for no members
    if(!g_ptr_array_size(ls->members)){
    	emit(0, "");
    	emit(0, "  -- nothing to do");
    	emit(0, "end");
    	return;
    }

    emit(0, "");
    emit(0, "  local buf_table = {}");
    emit(0, "");

    GQueue *struct_fmt = g_queue_new ();
    GQueue *struct_members = g_queue_new ();

    for (unsigned int m = 0; m < g_ptr_array_size(ls->members); m++) {
        lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, m);
        char fmt = _struct_format (lm);

        if (! lm->dimensions->len) {
        	// XXX not an array
            if (fmt) {
            	// XXX is a primitive
                g_queue_push_tail (struct_fmt, GINT_TO_POINTER ((int)fmt));
                g_queue_push_tail (struct_members, lm);
            } else {
            	// XXX not a primitive
                _flush_write_struct_fmt (f, struct_fmt, struct_members);
                char *accessor = g_strdup_printf("self.%s", lm->membername);
                _emit_encode_one (lcm, f, ls, lm, accessor, 1);
                g_free(accessor);
            }
        } else {
        	// XXX this is an array
            _flush_write_struct_fmt (f, struct_fmt, struct_members);
            GString *accessor = g_string_new ("");
            g_string_append_printf (accessor, "self.%s", lm->membername);

            int n;
            for (n=0; n<lm->dimensions->len - 1; n++) {
                lcm_dimension_t *dim = 
                    (lcm_dimension_t*) g_ptr_array_index (lm->dimensions, n);

                g_string_append_printf (accessor, "[i%d]", n);
                if (dim->mode == LCM_CONST) {
                    emit (1+n, "for i%d = 1, %s do", n, dim->size);
                } else {
                    emit (1+n, "for i%d = 1, self.%s do", n, dim->size);
                }
            }

            // last dimension.
            lcm_dimension_t *last_dim = (lcm_dimension_t *) g_ptr_array_index(lm->dimensions,
                    lm->dimensions->len - 1);
            int last_dim_fixed_len = last_dim->mode == LCM_CONST;

            if(lcm_is_primitive_type(lm->type->lctypename) && 
               0 != strcmp(lm->type->lctypename, "string")) {

                _emit_encode_list(lcm, f, ls, lm,
                        accessor->str, 1+n, last_dim->size, last_dim_fixed_len);
            } else {
                if (last_dim_fixed_len) {
                    emit (1+n, "for i%d = 1, %s do", n, last_dim->size);
                } else {
                    emit (1+n, "for i%d = 1, self.%s do", n, last_dim->size);
                }
                g_string_append_printf (accessor, "[i%d]", n);
                _emit_encode_one (lcm, f, ls, lm, accessor->str, n+2);
                emit (1+n, "end");
            }

            g_string_free (accessor, TRUE);

            while ( --n >= 0 ) {
            	emit (1+n, "end");
            }
        }
    }
    _flush_write_struct_fmt (f, struct_fmt, struct_members);

    g_queue_free (struct_fmt);
    g_queue_free (struct_members);

    emit(0, "");
    emit(0, "  return table.concat(buf_table)");
    emit(0, "end");
    emit(0, "");
}
示例#13
0
文件: emit_lua.c 项目: GArlington/lcm
static void
emit_lua_decode_one (const lcmgen_t *lcm, FILE *f, lcm_struct_t *ls)
{
    emit(0, "function %s._decode_one(data)", ls->structname->shortname);
    emit(0, "");
    emit(0, "  if not data.read then");
    emit(0, "    data = _buffer_helper:new(data)");
    emit(0, "  end");
    emit(0, "");
    emit(0, "  local obj = %s:new()", ls->structname->shortname);
    emit(0, "");

    GQueue *struct_fmt = g_queue_new ();
    GQueue *struct_members = g_queue_new ();

    for (unsigned int m = 0; m < g_ptr_array_size(ls->members); m++) {
        lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, m);
        char fmt = _struct_format (lm);

        if (! lm->dimensions->len) {
            if (fmt) {
                g_queue_push_tail (struct_fmt, GINT_TO_POINTER ((int)fmt));
                g_queue_push_tail (struct_members, lm);
            } else {
                _flush_read_struct_fmt (lcm, f, struct_fmt, struct_members);
                char *accessor = g_strdup_printf("obj.%s", lm->membername);
                _emit_decode_one (lcm, f, ls, lm, accessor, 1);
                g_free(accessor);
            }
        } else {
            _flush_read_struct_fmt (lcm, f, struct_fmt, struct_members);
            GString *accessor = g_string_new ("");
            g_string_append_printf (accessor, "obj.%s", lm->membername);

            // iterate through the dimensions of the member, building up
            // an accessor string, and emitting for loops
            int n;
            for (n=0; n<lm->dimensions->len - 1; n++) {
                lcm_dimension_t *dim =
                	(lcm_dimension_t *) g_ptr_array_index (lm->dimensions, n);

                emit (1+n, "%s = {}", accessor->str);
                if (dim->mode == LCM_CONST) {
                    emit (1+n, "for i%d = 1, %s do", n, dim->size);
                } else {
                    emit (1+n, "for i%d = 1, obj.%s do", n, dim->size);
                }
                g_string_append_printf(accessor, "[i%d]", n);
            }

            // last dimension.
            lcm_dimension_t *last_dim = (lcm_dimension_t *) g_ptr_array_index(lm->dimensions,
                    lm->dimensions->len - 1);
            int last_dim_fixed_len = last_dim->mode == LCM_CONST;

            if(lcm_is_primitive_type(lm->type->lctypename) && 
               0 != strcmp(lm->type->lctypename, "string")) {
                // member is a primitive non-string type.  Emit code to 
                // decode a full array in one call to struct.unpack

            	_emit_decode_list(lcm, f, ls, lm,
                        accessor->str, 1+n, last_dim->size, last_dim_fixed_len);
            } else {
                // member is either a string type or an inner LCM type.  Each
                // array element must be decoded individually
            	emit (1+n, "%s = {}", accessor->str);
            	if (last_dim_fixed_len) {
            		emit (1+n, "for i%d = 1, %s do", n, last_dim->size);
            	} else {
            		emit (1+n, "for i%d = 1, obj.%s do", n, last_dim->size);
            	}
            	g_string_append_printf (accessor, "[i%d]", n);
            	_emit_decode_one (lcm, f, ls, lm, accessor->str, n+2);
            	emit (1+n, "end");
            }

            g_string_free (accessor, TRUE);

            while ( --n >= 0 ) {
            	emit (1+n, "end");
            }
        }
    }
    _flush_read_struct_fmt (lcm, f, struct_fmt, struct_members);

    g_queue_free (struct_fmt);
    g_queue_free (struct_members);

    emit(0, "");
    emit(0, "  return obj");
    emit(0, "end");
    emit(0, "");
}
示例#14
0
文件: emit_c.c 项目: tbeu/lcm
/** Emit header file output specific to a particular type of struct. **/
static void emit_header_struct(lcmgen_t *lcm, FILE *f, lcm_struct_t *ls)
{
    char *tn = ls->structname->lctypename;
    char *tn_ = dots_to_underscores(tn);
    char *tn_upper = g_utf8_strup(tn_, -1);

    // include header files required by members
    for (unsigned int i = 0; i < g_ptr_array_size(ls->members); i++) {
        lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, i);

        if (!lcm_is_primitive_type(lm->type->lctypename) &&
             strcmp(lm->type->lctypename, ls->structname->lctypename)) {
            char *other_tn = dots_to_underscores (lm->type->lctypename);
            fprintf(f, "#include \"%s%s%s.h\"\n",
                    getopt_get_string(lcm->gopt, "cinclude"),
                    strlen(getopt_get_string(lcm->gopt, "cinclude"))>0 ? "/" : "",
                    other_tn);
            free (other_tn);
        }
    }

    // output constants
    for (unsigned int i = 0; i < g_ptr_array_size(ls->constants); i++) {
        lcm_constant_t *lc = (lcm_constant_t *) g_ptr_array_index(ls->constants, i);
        assert(lcm_is_legal_const_type(lc->lctypename));
        const char *suffix = "";
        if (!strcmp(lc->lctypename, "int64_t")) {
            suffix = "LL";
        }
        emit_comment(f, 0, lc->comment);
        emit(0, "#define %s_%s %s%s", tn_upper, lc->membername, lc->val_str,
                suffix);
    }
    if (g_ptr_array_size(ls->constants) > 0) {
        emit(0, "");
    }

    // define the struct
    emit_comment(f, 0, ls->comment);
    emit(0, "typedef struct _%s %s;", tn_, tn_);
    emit(0, "struct _%s", tn_);
    emit(0, "{");

    for (unsigned int m = 0; m < g_ptr_array_size(ls->members); m++) {
        lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, m);

        emit_comment(f, 1, lm->comment);

        int ndim = g_ptr_array_size(lm->dimensions);
        if (ndim == 0) {
            emit(1, "%-10s %s;", map_type_name(lm->type->lctypename),
                    lm->membername);
        } else {
            if (lcm_is_constant_size_array(lm)) {
                emit_start(1, "%-10s %s", map_type_name(lm->type->lctypename), lm->membername);
                for (unsigned int d = 0; d < ndim; d++) {
                    lcm_dimension_t *ld = (lcm_dimension_t *) g_ptr_array_index(lm->dimensions, d);
                    emit_continue("[%s]", ld->size);
                }
                emit_end(";");
            } else {
                emit_start(1, "%-10s ", map_type_name(lm->type->lctypename));
                for (unsigned int d = 0; d < ndim; d++)
                    emit_continue("*");
                emit_end("%s;", lm->membername);
            }
        }
    }
    emit(0, "};");
    emit(0, "");

    free(tn_);
    g_free(tn_upper);
}
示例#15
0
文件: emit_cpp.c 项目: cd127/lcm-1
static void emit_compare_test(lcmgen_t *lcm, FILE *f, lcm_struct_t *ls)
{
    const char *sn = ls->structname->shortname;
    emit(0, "bool %s::compareTestObject(%s const & other) const", sn, sn);
    emit(0, "{");
    if(0 == g_ptr_array_size(ls->members)) {
        emit(1,     "return true;");
        emit(0,"}");
        emit(0,"");
        return;
    }
    // For each member
    uint8_t firstVar = 1;
    emit_start(1, "bool equal = true;");
    for (unsigned int mInd = 0; mInd < g_ptr_array_size(ls->members); ++mInd) {
        lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, mInd);
        int numDim = g_ptr_array_size(lm->dimensions);
        uint8_t isFloat = (0==strcmp(lm->type->lctypename,"float")) || (0==strcmp(lm->type->lctypename,"double"));

        emit_end("");
        if (firstVar) {
            emit_start(1, "equal = ");
            firstVar = 0;
        }
        else {
            emit_start(2, "&& ");
        }

        if (0==numDim) {
            if (isFloat) {
                emit_continue("( (std::fabs(%s - other.%s) < 1e-5) )", lm->membername, lm->membername);
            }
            else if ( ! lcm_is_primitive_type(lm->type->lctypename) ) {
                emit_continue("(%s.compareTestObject(other.%s))", lm->membername, lm->membername);
            }
            else {
                emit_continue("(%s == other.%s)", lm->membername, lm->membername);
            }
        }
        else {
            // Check if it's a dynamic array, in which case we ignore it at the moment.
            uint8_t isDynamic=0;
            for (int dim=0; dim < numDim; ++dim) {
                lcm_dimension_t *ld = (lcm_dimension_t *) g_ptr_array_index(lm->dimensions, dim);
                if (!is_dim_size_fixed(ld->size)) {
                    isDynamic=1;
                    break;
                }
            }
            if (!isDynamic) {
                // Compare first component in array
                char * dimStr = g_strdup_printf("");
                for (uint8_t dim = 0; dim < numDim; ++dim) {
                    char * tmpStr = g_strdup_printf("%s", dimStr);
                    g_free(dimStr);
                    dimStr = g_strdup_printf("%s[0]", tmpStr);
                    g_free(tmpStr);
                }

                if (isFloat) {
                    emit_continue("( (std::fabs(%s%s - other.%s%s) < 1e-5) )", lm->membername, dimStr, lm->membername, dimStr);
                }
                else if ( ! lcm_is_primitive_type(lm->type->lctypename) ) {
                    emit_continue("(%s%s.compareTestObject(other.%s%s))", lm->membername, dimStr, lm->membername, dimStr);
                }
                else {
                    emit_continue("(%s%s == other.%s%s)", lm->membername, dimStr, lm->membername, dimStr);
                }
                g_free(dimStr);

                dimStr = g_strdup_printf("");
                // Compare last component in array
                for (uint8_t dim = 0; dim < numDim; ++dim) {
                    lcm_dimension_t *ld = (lcm_dimension_t *) g_ptr_array_index(lm->dimensions, dim);
                    char * tmpStr = g_strdup_printf("%s", dimStr);
                    g_free(dimStr);
                    dimStr = g_strdup_printf("%s[%i]", tmpStr, atoi(ld->size)-1);
                    g_free(tmpStr);
                }

                if (isFloat) {
                    emit_continue(" && ( (std::fabs(%s%s - other.%s%s) < 1e-5) )", lm->membername, dimStr, lm->membername, dimStr);
                }
                else if ( ! lcm_is_primitive_type(lm->type->lctypename) ) {
                    emit_continue(" && (%s%s.compareTestObject(other.%s%s))", lm->membername, dimStr, lm->membername, dimStr);
                }
                else {
                    emit_continue(" && (%s%s == other.%s%s)", lm->membername, dimStr, lm->membername, dimStr);
                }
                g_free(dimStr);
            }
            else {
                emit_end("// %s is a dynamic array", lm->membername);
            }
        }

    }
    emit_end(";");
    emit(0,"");
    emit(1, "return equal;");
    emit(0,"}");
    emit(0,"");
}
示例#16
0
文件: emit_cpp.c 项目: cd127/lcm-1
static void emit_inc_test(lcmgen_t *lcm, FILE *f, lcm_struct_t *ls)
{
    const char *sn = ls->structname->shortname;
    emit(0, "bool %s::incTestObject()", sn);
    emit(0, "{");
    if(0 == g_ptr_array_size(ls->members)) {
        emit(1,     "return true;");
        emit(0,"}");
        emit(0,"");
        return;
    }
    // For each member
    for (unsigned int mInd = 0; mInd < g_ptr_array_size(ls->members); mInd++) {
        lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, mInd);
        char * valueAssignment;

        // For non-primitive types, simply call object's increment function
        if ( ! lcm_is_primitive_type(lm->type->lctypename) ) {
            valueAssignment = strdup(".incTestObject()");
        }
        else if (!strcmp(lm->type->lctypename,"string")) {
            valueAssignment = g_strdup_printf(" = std::to_string(std::stol(%s", lm->membername);
        }
        else {
            valueAssignment = strdup("++");
        }

        int ndim = g_ptr_array_size(lm->dimensions);

        if (0==ndim) {
            emit_start(1, "%s%s", lm->membername, valueAssignment);
            if (!strcmp(lm->type->lctypename,"string")) {
                emit_continue(")+1)");
            }
            emit_end(";");
        }
        else {
            // Check if it's a dynamic array, in which case we ignore it at the moment.
            uint8_t isDynamic=0;
            for (int dim=0; dim < ndim; ++dim) {
                lcm_dimension_t *ld = (lcm_dimension_t *) g_ptr_array_index(lm->dimensions, dim);
                if (!is_dim_size_fixed(ld->size)) {
                    isDynamic=1;
                    break;
                }
            }
            if (!isDynamic) {
                // Inc first component in array
                emit_start(1, "%s", lm->membername);
                for (int dim=0; dim < ndim; ++dim) {
                    emit_continue("[0]");
                }
                emit_continue("%s", valueAssignment);
                if (!strcmp(lm->type->lctypename,"string")) {
                    // This is not pretty but is the simplest way to avoid mem allocation
                    for (int dim=0; dim < ndim; ++dim) {
                        emit_continue("[0]");
                    }
                    emit_continue(")+1)");
                }
                emit_end(";");

                // Inc last component in array
                emit_start(1, "%s", lm->membername);
                for (int dim=0; dim < ndim; ++dim) {
                    lcm_dimension_t *ld = (lcm_dimension_t *) g_ptr_array_index(lm->dimensions, dim);
                    emit_continue("[%i]", atoi(ld->size)-1);
                }
                emit_continue("%s", valueAssignment);
                if (!strcmp(lm->type->lctypename,"string")) {
                    // This is not pretty but is the simplest way to avoid mem allocation
                    for (int dim=0; dim < ndim; ++dim) {
                        lcm_dimension_t *ld = (lcm_dimension_t *) g_ptr_array_index(lm->dimensions, dim);
                        emit_continue("[%i]", atoi(ld->size)-1);
                    }
                    emit_continue(")+1)");
                }
                emit_end(";");
            }
            else {
                emit(1, "//%s is a dynamic array", lm->membername);
            }
            g_free (valueAssignment);
        }
    }
    emit(0, "");
    emit(1, "return true;");
    emit(0,"}");
    emit(0,"");
}
示例#17
0
文件: emit_c.c 项目: tbeu/lcm
static void emit_c_get_field(lcmgen_t *lcm, FILE *f, lcm_struct_t *ls)
{
    char *tn = ls->structname->lctypename;
    char *tn_ = dots_to_underscores(tn);

    emit(0,"int %s_get_field(const %s *p, int i, lcm_field_t *f)", tn_, tn_);
    emit(0,"{");
    emit(1,"if (0 > i || i >= %s_num_fields())", tn_);
    emit(2,"return 1;");
    emit(1,"");

    emit(1,"switch (i) {");
    emit(1,"");

    int num_fields = g_ptr_array_size(ls->members);
    for(int i = 0; i < num_fields; i++) {
        emit(2,"case %d: {", i);

        lcm_member_t *m = (lcm_member_t *)g_ptr_array_index(ls->members, i);

        const char *type_val = NULL;
        if(lcm_is_primitive_type(m->type->shortname)) {
            type_val = str_toupper(g_strdup_printf("LCM_FIELD_%s", m->type->shortname));
        } else {
            emit(3,"/* %s */", m->type->shortname);
            type_val = "LCM_FIELD_USER_TYPE";
        }

        emit(3,"f->name = \"%s\";", m->membername);
        emit(3,"f->type = %s;", type_val);
        emit(3,"f->typestr = \"%s\";", m->type->shortname);

        int num_dim = g_ptr_array_size(m->dimensions);
        emit(3,"f->num_dim = %d;", num_dim);

        if(num_dim != 0) {

            for(int j = 0; j < num_dim; j++) {
                lcm_dimension_t *d = (lcm_dimension_t*) g_ptr_array_index(m->dimensions, j);
                if(d->mode == LCM_VAR)
                    emit(3,"f->dim_size[%d] = p->%s;", j, d->size);
                else
                    emit(3,"f->dim_size[%d] = %s;", j, d->size);
            }

            for(int j = 0; j < num_dim; j++) {
                lcm_dimension_t *d = (lcm_dimension_t*) g_ptr_array_index(m->dimensions, j);
                emit(3,"f->dim_is_variable[%d] = %d;", j, d->mode == LCM_VAR);
            }

        }

        emit(3, "f->data = (void *) &p->%s;", m->membername);

        emit(3, "return 0;");
        emit(2,"}");
        emit(2,"");
    }
    emit(2,"default:");
    emit(3,"return 1;");
    emit(1,"}");
    emit(0,"}");
    emit(0,"");
}
示例#18
0
文件: emit_python.c 项目: OxDuke/lcm
static void
emit_python_decode_one (const lcmgen_t *lcm, FILE *f, lcm_struct_t *ls)
{
    emit(1, "def _decode_one(buf):");
    emit (2, "self = %s()", ls->structname->shortname);

    GQueue *struct_fmt = g_queue_new ();
    GQueue *struct_members = g_queue_new ();

    for (unsigned int m = 0; m < g_ptr_array_size(ls->members); m++) {
        lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, m);
        char fmt = _struct_format (lm);

        if (! lm->dimensions->len) {
            if (fmt && strcmp(lm->type->lctypename, "boolean")) {
                g_queue_push_tail (struct_fmt, GINT_TO_POINTER ((int)fmt));
                g_queue_push_tail (struct_members, lm);
            } else {
                _flush_read_struct_fmt (lcm, f, struct_fmt, struct_members);
                char *accessor = g_strdup_printf("self.%s = ", lm->membername);
                _emit_decode_one (lcm, f, ls, lm, accessor, 2, "");
                g_free(accessor);
            }
        } else {
            _flush_read_struct_fmt (lcm, f, struct_fmt, struct_members);

            GString *accessor = g_string_new ("");
            g_string_append_printf (accessor, "self.%s", lm->membername);

            // iterate through the dimensions of the member, building up
            // an accessor string, and emitting for loops
            unsigned int n;
            for (n=0; n<lm->dimensions->len-1; n++) {
                lcm_dimension_t *dim = (lcm_dimension_t *) g_ptr_array_index (lm->dimensions, n);

                if(n == 0) {
                    emit (2, "%s = []", accessor->str);
                } else {
                    emit (2+n, "%s.append([])", accessor->str);
                }

                if (dim->mode == LCM_CONST) {
                    emit (2+n, "for i%d in range(%s):", n, dim->size);
                } else {
                    emit (2+n, "for i%d in range(self.%s):", n, dim->size);
                }

                if(n > 0 && n < lm->dimensions->len-1) {
                    g_string_append_printf(accessor, "[i%d]", n-1);
                }
            }

            // last dimension.
            lcm_dimension_t *last_dim = (lcm_dimension_t *) g_ptr_array_index(lm->dimensions,
                    lm->dimensions->len - 1);
            int last_dim_fixed_len = last_dim->mode == LCM_CONST;

            if(lcm_is_primitive_type(lm->type->lctypename) && 
               0 != strcmp(lm->type->lctypename, "string")) {
                // member is a primitive non-string type.  Emit code to 
                // decode a full array in one call to struct.unpack
                if(n == 0) {
                    g_string_append_printf (accessor, " = ");
                } else {
                    g_string_append_printf (accessor, ".append(");
                }

                _emit_decode_list(lcm, f, ls, lm,
                        accessor->str, 2+n, n==0, 
                        last_dim->size, last_dim_fixed_len);
            } else {
                // member is either a string type or an inner LCM type.  Each
                // array element must be decoded individually
                if(n == 0) {
                    emit (2, "%s = []", accessor->str);
                } else {
                    emit (2+n, "%s.append ([])", accessor->str);
                    g_string_append_printf (accessor, "[i%d]", n-1);
                }
                if (last_dim_fixed_len) {
                    emit (2+n, "for i%d in range(%s):", n, last_dim->size);
                } else {
                    emit (2+n, "for i%d in range(self.%s):", n, last_dim->size);
                }
                g_string_append_printf (accessor, ".append(");
                _emit_decode_one (lcm, f, ls, lm, accessor->str, n+3, ")");
            }
            g_string_free (accessor, TRUE);
        }
    }
    _flush_read_struct_fmt (lcm, f, struct_fmt, struct_members);
    emit (2, "return self");

    g_queue_free (struct_fmt);
    g_queue_free (struct_members);
    emit (1, "_decode_one = staticmethod(_decode_one)");
    fprintf (f, "\n");
}
示例#19
0
文件: emit_cpp.c 项目: cd127/lcm-1
/** Emit header file **/
static void emit_header_start(lcmgen_t *lcmgen, FILE *f, lcm_struct_t *ls)
{
    char *tn = ls->structname->lctypename;
    char *sn = ls->structname->shortname;
    char *tn_ = dots_to_underscores(tn);

    emit_auto_generated_warning(f);

    fprintf(f, "#include <lcm/lcm_coretypes.h>\n");
    fprintf(f, "\n");
    fprintf(f, "#ifndef __%s_hpp__\n", tn_);
    fprintf(f, "#define __%s_hpp__\n", tn_);
    fprintf(f, "\n");

    // do we need to #include <vector> ?
    int emit_include_vector = 0;
    for (unsigned int mind = 0; mind < g_ptr_array_size(ls->members); mind++) {
        lcm_member_t *lm = (lcm_member_t *)g_ptr_array_index(ls->members, mind);
        if (g_ptr_array_size(lm->dimensions) != 0 &&
                !lcm_is_constant_size_array(lm) && !emit_include_vector) {
            emit(0, "#include <vector>");
            emit_include_vector = 1;
        }
    }

    emit(0, "#include <cmath>\t// For fabs to compare floats");
    emit(0, "#include <string>\t// For return type of toStr()");
    emit(0, "#include <sstream>\t// For stringstream in toStr()");

    // include header files for other LCM types
    for (unsigned int mind = 0; mind < g_ptr_array_size(ls->members); mind++) {
        lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, mind);

        if (!lcm_is_primitive_type(lm->type->lctypename) &&
                strcmp(lm->type->lctypename, ls->structname->lctypename)) {
            char *other_tn = dots_to_slashes (lm->type->lctypename);
            emit(0, "#include \"%s%s%s.hpp\"",
                 getopt_get_string(lcmgen->gopt, "cpp-include"),
                 strlen(getopt_get_string(lcmgen->gopt, "cpp-include"))>0 ? G_DIR_SEPARATOR_S : "",
                 other_tn);
            free(other_tn);
        }
    }

    fprintf(f, "\n");
    emit_package_namespace_start(lcmgen, f, ls);

    // define the class
    emit(0, "");
    emit_comment(f, 0, ls->comment);
    emit(0, "class %s", sn);
    emit(0, "{");

    // data members
    if(g_ptr_array_size(ls->members)) {
        emit(1, "public:");
        for (unsigned int mind = 0; mind < g_ptr_array_size(ls->members); mind++) {
            lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, mind);

            emit_comment(f, 2, lm->comment);
            char const* mapped_typename = map_type_name(lm->type->lctypename);
            int ndim = g_ptr_array_size(lm->dimensions);
            if (ndim == 0) {
                emit(2, "%-10s %s;", mapped_typename, lm->membername);
            } else {
                if (lcm_is_constant_size_array(lm)) {
                    emit_start(2, "%-10s %s", mapped_typename, lm->membername);
                    for (unsigned int d = 0; d < ndim; d++) {
                        lcm_dimension_t *ld = (lcm_dimension_t *) g_ptr_array_index(lm->dimensions, d);
                        emit_continue("[%s]", ld->size);
                    }
                    emit_end(";");
                } else {
                    emit_start(2, "");
                    for (unsigned int d = 0; d < ndim; d++)
                        emit_continue("std::vector< ");
                    emit_continue("%s", mapped_typename);
                    for (unsigned int d = 0; d < ndim; d++)
                        emit_continue(" >");
                    emit_end(" %s;", lm->membername);
                }
            }
            if (mind < g_ptr_array_size(ls->members) - 1) {
                emit(0, "");
            }
        }
        emit(0, "");
    }

    // constants
    if (g_ptr_array_size(ls->constants) > 0) {
        emit(1, "public:");
        for (unsigned int i = 0; i < g_ptr_array_size(ls->constants); i++) {
            lcm_constant_t *lc = (lcm_constant_t *) g_ptr_array_index(ls->constants, i);
            assert(lcm_is_legal_const_type(lc->lctypename));

            emit_comment(f, 2, lc->comment);
            // For int32_t only, we emit enums instead of static const
            // values because the former can be passed by reference while
            // the latter cannot.
            if (!strcmp(lc->lctypename, "int32_t")) {
                emit(2, "enum { %s = %s };", lc->membername, lc->val_str);
            } else {
                const char *suffix = "";
                if (!strcmp(lc->lctypename, "int64_t"))
                    suffix = "LL";
                char const* mapped_typename = map_type_name(lc->lctypename);
                char *cpp_std = getopt_get_string(lcmgen->gopt, "cpp-std");
                if(strcmp("c++98",cpp_std) && strcmp("c++11",cpp_std)) {
                    printf("%s is not a valid cpp_std. Use --cpp-std=c++98 or --cpp-std=c++11 instead\n\n", cpp_std);
                    fflush(stdout);
                    _exit(1);
                }

                if(!strcmp (cpp_std, "c++11")) {
                    emit(2, "static constexpr %-8s %s = %s%s;", mapped_typename,
                         lc->membername, lc->val_str, suffix);
                } else {
                    emit(2, "// If you're using C++11 and are getting compiler errors saying things like");
                    emit(2, "// ‘constexpr’ needed for in-class initialization of static data member");
                    emit(2, "// then re-run lcm-gen with '--cpp-std=c++11' to generate code that is");
                    emit(2, "// compliant with C++11");
                    emit(2, "static const %-8s %s = %s%s;", mapped_typename,
                         lc->membername, lc->val_str, suffix);
                }
            }
        }
        emit(0, "");
    }

    emit(1, "public:");
    emit(2, "/**");
    emit(2, " * Encode a message into binary form.");
    emit(2, " *");
    emit(2, " * @param buf The output buffer.");
    emit(2, " * @param offset Encoding starts at thie byte offset into @p buf.");
    emit(2, " * @param maxlen Maximum number of bytes to write.  This should generally be");
    emit(2, " *  equal to getEncodedSize().");
    emit(2, " * @return The number of bytes encoded, or <0 on error.");
    emit(2, " */");
    emit(2, "inline int encode(void *buf, int offset, int maxlen) const;");
    emit(0, "");
    emit(2, "/**");
    emit(2, " * Check how many bytes are required to encode this message.");
    emit(2, " */");
    emit(2, "inline int getEncodedSize() const;");
    emit(0, "");
    emit(2, "/**");
    emit(2, " * Decode a message from binary form into this instance.");
    emit(2, " *");
    emit(2, " * @param buf The buffer containing the encoded message.");
    emit(2, " * @param offset The byte offset into @p buf where the encoded message starts.");
    emit(2, " * @param maxlen The maximum number of bytes to reqad while decoding.");
    emit(2, " * @return The number of bytes decoded, or <0 if an error occured.");
    emit(2, " */");
    emit(2, "inline int decode(const void *buf, int offset, int maxlen);");
    emit(0, "");
    emit(2, "/**");
    emit(2, " * Compare two instances of the same type.");
    emit(2, " *");
    emit(2, " * @param[in] other The object to compare.");
    emit(2, " * @return true if all elements are equal, false otherwise.");
    emit(2, " */");
    emit(2, "inline bool operator==(%s const & other) const;", sn);
    emit(0, "");
    emit(2, "/**");
    emit(2, " * Construct a string from the object for debugging purposes.");
    emit(2, " * Note that arrays are cropped for readability. Only the first and last elements are shown.");
    emit(2, " *");
    emit(2, " * @param[in] layout A placeholder for the tree structure.");
    emit(2, " */");
    emit(2, "inline std::string toDebugStr(std::string const & layout=\"|-\") const;");
    emit(0, "");
    emit(2, "/**");
    emit(2, " * Initialize all values of a test object to pre-defined values.");
    emit(2, " * The values used are much more informative than using 0 because");
    emit(2, " * they are type-dependant. This way, the user knows directly whether");
    emit(2, " * the type is correct or not. Typically the default values are the");
    emit(2, " * maximum value allowed by the type minus 5, and 1.0 for float and double.");
    emit(2, " * Note that for arrays only the first and last elements are considered.");
    emit(2, " *");
    emit(2, " * @return success.");
    emit(2, " */");
    emit(2, "inline bool initTestObject();");
    emit(0, "");
    emit(2, "/**");
    emit(2, " * Increment every variable in the object.");
    emit(2, " * Works well with initTestObject() and compareTestObject().");
    emit(2, " * Note that for arrays only the first and last elements are considered.");
    emit(2, " *");
    emit(2, " * @return success.");
    emit(2, " */");
    emit(2, "inline bool incTestObject();");
    emit(0, "");
    emit(2, "/**");
    emit(2, " * Compare two instances of the same type.");
    emit(2, " * Works well with initTestObject() and incTestObject().");
    emit(2, " * Note that for arrays only the first and last elements are considered.");
    emit(2, " *");
    emit(2, " * @param[in] other The object to compare.");
    emit(2, " * @return true if all elements are equal, false otherwise.");
    emit(2, " */");
    emit(2, "inline bool compareTestObject(%s const & other) const;", sn);
    emit(0, "");
    emit(2, "/**");
    emit(2, " * Retrieve the 64-bit fingerprint identifying the structure of the message.");
    emit(2, " * Note that the fingerprint is the same for all instances of the same");
    emit(2, " * message type, and is a fingerprint on the message type definition, not on");
    emit(2, " * the message contents.");
    emit(2, " */");
    emit(2, "inline static int64_t getHash();");
    emit(0, "");
    emit(2, "/**");
    emit(2, " * Returns \"%s\"", ls->structname->shortname);
    emit(2, " */");
    emit(2, "inline static const char* getTypeName();");

    emit(0, "");
    emit(2, "// LCM support functions. Users should not call these");
    emit(2, "inline int _encodeNoHash(void *buf, int offset, int maxlen) const;");
    emit(2, "inline int _getEncodedSizeNoHash() const;");
    emit(2, "inline int _decodeNoHash(const void *buf, int offset, int maxlen);");
    emit(2, "inline static uint64_t _computeHash(const __lcm_hash_ptr *p);");
    emit(0, "};");
    emit(0, "");

    free(tn_);
}
示例#20
0
文件: emit_cpp.c 项目: cd127/lcm-1
static void _decode_recursive(lcmgen_t* lcm, FILE* f, lcm_member_t* lm, int depth)
{
    // primitive array
    if (depth+1 == g_ptr_array_size(lm->dimensions) &&
            lcm_is_primitive_type(lm->type->lctypename) &&
            strcmp(lm->type->lctypename, "string")) {
        lcm_dimension_t *dim = (lcm_dimension_t*) g_ptr_array_index(lm->dimensions, depth);

        int decode_indent = 1 + depth;
        if(!lcm_is_constant_size_array(lm)) {
            emit(1 + depth, "if(%s%s) {", dim_size_prefix(dim->size), dim->size);
            emit_start(2 + depth, "this->%s", lm->membername);
            for(int i=0; i<depth; i++)
                emit_continue("[a%d]", i);
            emit_end(".resize(%s%s);", dim_size_prefix(dim->size), dim->size);
            decode_indent++;
        }

        emit_start(decode_indent, "tlen = __%s_decode_array(buf, offset + pos, maxlen - pos, &this->%s",
                   lm->type->lctypename, lm->membername);
        for(int i=0; i<depth; i++)
            emit_continue("[a%d]", i);
        emit_end("[0], %s%s);", dim_size_prefix(dim->size), dim->size);
        emit(decode_indent, "if(tlen < 0) return tlen; else pos += tlen;");
        if(!lcm_is_constant_size_array(lm)) {
            emit(1 + depth, "}");
        }
    } else if(depth == g_ptr_array_size(lm->dimensions)) {
        if(!strcmp(lm->type->lctypename, "string")) {
            emit(1 + depth, "int32_t __elem_len;");
            emit(1 + depth, "tlen = __int32_t_decode_array(buf, offset + pos, maxlen - pos, &__elem_len, 1);");
            emit(1 + depth, "if(tlen < 0) return tlen; else pos += tlen;");
            emit(1 + depth, "if(__elem_len > maxlen - pos) return -1;");
            emit_start(1 + depth, "this->%s", lm->membername);
            for(int i=0; i<depth; i++)
                emit_continue("[a%d]", i);
            emit_end(".assign(((const char*)buf) + offset + pos, __elem_len -  1);");
            emit(1 + depth, "pos += __elem_len;");
        } else {
            emit_start(1 + depth, "tlen = this->%s", lm->membername);
            for(int i=0; i<depth; i++)
                emit_continue("[a%d]", i);
            emit_end("._decodeNoHash(buf, offset + pos, maxlen - pos);");
            emit(1 + depth, "if(tlen < 0) return tlen; else pos += tlen;");
        }
    } else {
        lcm_dimension_t *dim = (lcm_dimension_t*) g_ptr_array_index(lm->dimensions, depth);

        if(!lcm_is_constant_size_array(lm)) {
            emit_start(1+depth, "this->%s", lm->membername);
            for(int i=0; i<depth; i++) {
                emit_continue("[a%d]", i);
            }
            emit_end(".resize(%s%s);", dim_size_prefix(dim->size), dim->size);
        }
        emit(1+depth, "for (int a%d = 0; a%d < %s%s; a%d++) {",
             depth, depth, dim_size_prefix(dim->size), dim->size, depth);

        _decode_recursive(lcm, f, lm, depth+1);

        emit(1+depth, "}");
    }
}
示例#21
0
文件: emit_cpp.c 项目: cd127/lcm-1
static void emit_print(lcmgen_t *lcm, FILE *f, lcm_struct_t *ls)
{
    const char *sn = ls->structname->shortname;
    emit(0, "std::string %s::toDebugStr(std::string const & layout) const", sn);
    emit(0, "{");
    if(0 == g_ptr_array_size(ls->members)) {
        emit(1,     "return \"\";");
        emit(0,"}");
        emit(0,"");
        return;
    }
    emit(1, "std::stringstream ss(\"\");");
    // For each member
    for (unsigned int mInd = 0; mInd < g_ptr_array_size(ls->members); mInd++) {
        lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, mInd);
        uint8_t isString = (0==strcmp(lm->type->lctypename,"string"));
        int ndim = g_ptr_array_size(lm->dimensions);

        char * valueAssignment;
        char * valueAssignment2;     // Needs to be split for possibly adding array index
        if (isString) {
            valueAssignment = g_strdup_printf("= '\" << %s << \"'\"", lm->membername);
            valueAssignment2 = g_strdup_printf(" << std::endl;");
        }
        else if ( lcm_is_primitive_type(lm->type->lctypename) ) {
            valueAssignment = g_strdup_printf("= \" << std::to_string(%s", lm->membername);
            valueAssignment2 = g_strdup_printf(") << std::endl;");
        }
        else {
            valueAssignment = g_strdup_printf("\" << std::endl << %s", lm->membername);
            if (0==ndim) {
                valueAssignment2 = g_strdup_printf(".toDebugStr(\"  \"+layout);");
            }
            else {
                valueAssignment2 = g_strdup_printf(".toDebugStr(\"    \"+layout);");
            }
        }

        emit_start(1, "ss << layout << \"%s ", lm->membername);
        if (0==ndim) {
            emit_end("%s%s", valueAssignment, valueAssignment2);
        }
        else {
            // Check if it's a dynamic array, in which case we ignore it at the moment.
            uint8_t isDynamic=0;
            for (int dim=0; dim < ndim; ++dim) {
                lcm_dimension_t *ld = (lcm_dimension_t *) g_ptr_array_index(lm->dimensions, dim);
                if (!is_dim_size_fixed(ld->size)) {
                    isDynamic=1;
                    break;
                }
            }
            if (!isDynamic) {
                // End previous line so that each element is on a new line
                emit_end("\" << std::endl;");

                // Print first component in array
                emit_start(1, "ss << \"  \" << layout << \"");
                for (int dim=0; dim < ndim; ++dim) {
                    emit_continue("[0]");
                }
                emit_continue("%s", valueAssignment);
                for (int dim=0; dim < ndim; ++dim) { // Copy-paste is not pretty but is the simplest way to avoid mem allocation
                    emit_continue("[0]");
                }
                emit_end("%s", valueAssignment2);

                // Print last component in array
                emit_start(1, "ss << \"  \" << layout << \"");
                for (int dim=0; dim < ndim; ++dim) {
                    lcm_dimension_t *ld = (lcm_dimension_t *) g_ptr_array_index(lm->dimensions, dim);
                    emit_continue("[%i]", atoi(ld->size)-1);
                }
                emit_continue("%s", valueAssignment);
                for (int dim=0; dim < ndim; ++dim) { // Copy-paste is not pretty but is the simplest way to avoid mem allocation
                    lcm_dimension_t *ld = (lcm_dimension_t *) g_ptr_array_index(lm->dimensions, dim);
                    emit_continue("[%i]", atoi(ld->size)-1);
                }
                emit_end("%s", valueAssignment2);
            }
            else {
                emit_end("is a dynamic array\" << std::endl;");
            }
        }
        g_free (valueAssignment);
    }
    emit(0, "");
    emit(1, "return ss.str();");
    emit(0,"}");
    emit(0,"");
}
示例#22
0
文件: emit_cpp.c 项目: cd127/lcm-1
static void emit_init_test(lcmgen_t *lcm, FILE *f, lcm_struct_t *ls)
{
    const char *sn = ls->structname->shortname;
    emit(0, "bool %s::initTestObject()", sn);
    emit(0, "{");
    if(0 == g_ptr_array_size(ls->members)) {
        emit(1,     "return true;");
        emit(0,"}");
        emit(0,"");
        return;
    }
    // For each member
    for (unsigned int mInd = 0; mInd < g_ptr_array_size(ls->members); mInd++) {
        lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, mInd);
        char const* mapped_typename = map_type_name(lm->type->lctypename);
        char const* typeInitValue = init_test_value(mapped_typename);
        char * valueAssignment;

        // For non-primitive types, simply call object's init function
        if ( ! lcm_is_primitive_type(lm->type->lctypename) ) {
            valueAssignment = strdup(".initTestObject();");
        }
        else {
            valueAssignment = g_strdup_printf(" = %s;", typeInitValue);
        }

        int ndim = g_ptr_array_size(lm->dimensions);

        if (0==ndim) {
            emit(1, "%s%s", lm->membername, valueAssignment);
            free (valueAssignment);
        }
        else {
            // Check if it's a dynamic array, in which case we ignore it at the moment.
            uint8_t isDynamic=0;
            for (int dim=0; dim < ndim; ++dim) {
                lcm_dimension_t *ld = (lcm_dimension_t *) g_ptr_array_index(lm->dimensions, dim);
                if (!is_dim_size_fixed(ld->size)) {
                    isDynamic=1;
                    break;
                }
            }
            if (!isDynamic) {
                // Set first component in array
                emit_start(1, "%s", lm->membername);
                for (int dim=0; dim < ndim; ++dim) {
                    emit_continue("[0]");
                }
                emit_end("%s", valueAssignment);

                // Set last component in array
                emit_start(1, "%s", lm->membername);
                for (int dim=0; dim < ndim; ++dim) {
                    lcm_dimension_t *ld = (lcm_dimension_t *) g_ptr_array_index(lm->dimensions, dim);
                    emit_continue("[%i]", atoi(ld->size)-1);
                }
                emit_end("%s", valueAssignment);
            }
            else {
                emit(1, "//%s is a dynamic array", lm->membername);
            }
            g_free (valueAssignment);
            free((char*)mapped_typename);
            free((char*)typeInitValue);
        }
    }
    emit(0, "");
    emit(1, "return true;");
    emit(0,"}");
    emit(0,"");
}
示例#23
0
文件: emit_python.c 项目: OxDuke/lcm
static void
emit_python_encode_one (const lcmgen_t *lcm, FILE *f, lcm_struct_t *ls)
{
    emit(1, "def _encode_one(self, buf):");
    if(!g_ptr_array_size(ls->members))
        emit(2, "pass");

    GQueue *struct_fmt = g_queue_new ();
    GQueue *struct_members = g_queue_new ();

    for (unsigned int m = 0; m < g_ptr_array_size(ls->members); m++) {
        lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, m);
        char fmt = _struct_format (lm);

        if (! lm->dimensions->len) {
            if (fmt) {
                g_queue_push_tail (struct_fmt, GINT_TO_POINTER ((int)fmt));
                g_queue_push_tail (struct_members, lm);
            } else {
                _flush_write_struct_fmt (f, struct_fmt, struct_members);
                char *accessor = g_strdup_printf("self.%s", lm->membername);
                _emit_encode_one (lcm, f, ls, lm, accessor, 2);
                g_free(accessor);
            }
        } else {
            _flush_write_struct_fmt (f, struct_fmt, struct_members);
            GString *accessor = g_string_new ("");
            g_string_append_printf (accessor, "self.%s", lm->membername);

            unsigned int n;
            for (n=0; n<lm->dimensions->len - 1; n++) {
                lcm_dimension_t *dim = 
                    (lcm_dimension_t*) g_ptr_array_index (lm->dimensions, n);

                g_string_append_printf (accessor, "[i%d]", n);
                if (dim->mode == LCM_CONST) {
                    emit (2+n, "for i%d in range(%s):", n, dim->size);
                } else {
                    emit (2+n, "for i%d in range(self.%s):", n, dim->size);
                }
            }

            // last dimension.
            lcm_dimension_t *last_dim = (lcm_dimension_t *) g_ptr_array_index(lm->dimensions,
                    lm->dimensions->len - 1);
            int last_dim_fixed_len = last_dim->mode == LCM_CONST;

            if(lcm_is_primitive_type(lm->type->lctypename) && 
               0 != strcmp(lm->type->lctypename, "string")) {

                _emit_encode_list(lcm, f, ls, lm,
                        accessor->str, 2+n, last_dim->size, last_dim_fixed_len);
            } else {
                if (last_dim_fixed_len) {
                    emit (2+n, "for i%d in range(%s):", n, last_dim->size);
                } else {
                    emit (2+n, "for i%d in range(self.%s):", n, last_dim->size);
                }
                g_string_append_printf (accessor, "[i%d]", n);
                _emit_encode_one (lcm, f, ls, lm, accessor->str, n+3);
            }
            
            g_string_free (accessor, TRUE);
        }
    }
    _flush_write_struct_fmt (f, struct_fmt, struct_members);

    g_queue_free (struct_fmt);
    g_queue_free (struct_members);
    fprintf (f, "\n");
}
示例#24
0
文件: emit_cpp.c 项目: ahans/lcm
/** Emit header file **/
static void emit_header_start(lcmgen_t *lcmgen, FILE *f, lcm_struct_t *ls)
{
    char *tn = ls->structname->lctypename;
    char *sn = ls->structname->shortname;
    char *tn_ = dots_to_underscores(tn);

    emit_auto_generated_warning(f);

    fprintf(f, "#include <lcm/lcm_coretypes.h>\n");
    fprintf(f, "\n");
    fprintf(f, "#ifndef __%s_hpp__\n", tn_);
    fprintf(f, "#define __%s_hpp__\n", tn_);
    fprintf(f, "\n");

    // do we need to #include <vector> and/or <string>?
    int emit_include_vector = 0;
    int emit_include_string = 0;
    for (unsigned int mind = 0; mind < g_ptr_array_size(ls->members); mind++) {
        lcm_member_t *lm = (lcm_member_t *)g_ptr_array_index(ls->members, mind);
        if (g_ptr_array_size(lm->dimensions) != 0 &&
            !lcm_is_constant_size_array(lm) && !emit_include_vector) {
            emit(0, "#include <vector>");
            emit_include_vector = 1;
        }
        if(!emit_include_string &&
            !strcmp(lm->type->lctypename, "string")) {
            emit(0, "#include <string>");
            emit_include_string = 1;
        }
    }

    // include header files for other LCM types
    for (unsigned int mind = 0; mind < g_ptr_array_size(ls->members); mind++) {
        lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, mind);

        if (!lcm_is_primitive_type(lm->type->lctypename) &&
            strcmp(lm->type->lctypename, ls->structname->lctypename)) {
            char *other_tn = dots_to_slashes (lm->type->lctypename);
            emit(0, "#include \"%s%s%s.hpp\"",
                    getopt_get_string(lcmgen->gopt, "cpp-include"),
                    strlen(getopt_get_string(lcmgen->gopt, "cpp-include"))>0 ? G_DIR_SEPARATOR_S : "",
                    other_tn);
            free(other_tn);
        }
    }

    fprintf(f, "\n");
    emit_package_namespace_start(lcmgen, f, ls);

    // define the class
    emit(0, "");
    emit_comment(f, 0, ls->comment);
    emit(0, "class %s", sn);
    emit(0, "{");

    // data members
    if(g_ptr_array_size(ls->members)) {
        emit(1, "public:");
        for (unsigned int mind = 0; mind < g_ptr_array_size(ls->members); mind++) {
            lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, mind);

            emit_comment(f, 2, lm->comment);
            char* mapped_typename = map_type_name(lm->type->lctypename);
            int ndim = g_ptr_array_size(lm->dimensions);
            if (ndim == 0) {
                emit(2, "%-10s %s;", mapped_typename, lm->membername);
            } else {
                if (lcm_is_constant_size_array(lm)) {
                    emit_start(2, "%-10s %s", mapped_typename, lm->membername);
                    for (unsigned int d = 0; d < ndim; d++) {
                        lcm_dimension_t *ld = (lcm_dimension_t *) g_ptr_array_index(lm->dimensions, d);
                        emit_continue("[%s]", ld->size);
                    }
                    emit_end(";");
                } else {
                    emit_start(2, "");
                    for (unsigned int d = 0; d < ndim; d++)
                        emit_continue("std::vector< ");
                    emit_continue("%s", mapped_typename);
                    for (unsigned int d = 0; d < ndim; d++)
                        emit_continue(" >");
                    emit_end(" %s;", lm->membername);
                }
            }
            free(mapped_typename);
            if (mind < g_ptr_array_size(ls->members) - 1) {
                emit(0, "");
            }
        }
        emit(0, "");
    }

    // constants
    if (g_ptr_array_size(ls->constants) > 0) {
        emit(1, "public:");
        for (unsigned int i = 0; i < g_ptr_array_size(ls->constants); i++) {
            lcm_constant_t *lc = (lcm_constant_t *) g_ptr_array_index(ls->constants, i);
            assert(lcm_is_legal_const_type(lc->lctypename));

            emit_comment(f, 2, lc->comment);
            // For int32_t only, we emit enums instead of static const
            // values because the former can be passed by reference while
            // the latter cannot.
            if (!strcmp(lc->lctypename, "int32_t")) {
              emit(2, "enum { %s = %s };", lc->membername, lc->val_str);
            } else {
              const char *suffix = "";
              if (!strcmp(lc->lctypename, "int64_t"))
                suffix = "LL";
              char* mapped_typename = map_type_name(lc->lctypename);
              emit(2, "static const %-8s %s = %s%s;", mapped_typename,
                  lc->membername, lc->val_str, suffix);
              free(mapped_typename);
            }
        }
        emit(0, "");
    }

    emit(1, "public:");
    emit(2, "/**");
    emit(2, " * Encode a message into binary form.");
    emit(2, " *");
    emit(2, " * @param buf The output buffer.");
    emit(2, " * @param offset Encoding starts at thie byte offset into @p buf.");
    emit(2, " * @param maxlen Maximum number of bytes to write.  This should generally be");
    emit(2, " *  equal to getEncodedSize().");
    emit(2, " * @return The number of bytes encoded, or <0 on error.");
    emit(2, " */");
    emit(2, "inline int encode(void *buf, int offset, int maxlen) const;");
    emit(0, "");
    emit(2, "/**");
    emit(2, " * Check how many bytes are required to encode this message.");
    emit(2, " */");
    emit(2, "inline int getEncodedSize() const;");
    emit(0, "");
    emit(2, "/**");
    emit(2, " * Decode a message from binary form into this instance.");
    emit(2, " *");
    emit(2, " * @param buf The buffer containing the encoded message.");
    emit(2, " * @param offset The byte offset into @p buf where the encoded message starts.");
    emit(2, " * @param maxlen The maximum number of bytes to reqad while decoding.");
    emit(2, " * @return The number of bytes decoded, or <0 if an error occured.");
    emit(2, " */");
    emit(2, "inline int decode(const void *buf, int offset, int maxlen);");
    emit(0, "");
    emit(2, "/**");
    emit(2, " * Retrieve the 64-bit fingerprint identifying the structure of the message.");
    emit(2, " * Note that the fingerprint is the same for all instances of the same");
    emit(2, " * message type, and is a fingerprint on the message type definition, not on");
    emit(2, " * the message contents.");
    emit(2, " */");
    emit(2, "inline static int64_t getHash();");
    emit(0, "");
    emit(2, "/**");
    emit(2, " * Returns \"%s\"", ls->structname->shortname);
    emit(2, " */");
    emit(2, "inline static const char* getTypeName();");

    emit(0, "");
    emit(2, "// LCM support functions. Users should not call these");
    emit(2, "inline int _encodeNoHash(void *buf, int offset, int maxlen) const;");
    emit(2, "inline int _getEncodedSizeNoHash() const;");
    emit(2, "inline int _decodeNoHash(const void *buf, int offset, int maxlen);");
    emit(2, "inline static int64_t _computeHash(const __lcm_hash_ptr *p);");
    emit(0, "};");
    emit(0, "");

    free(tn_);
}