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,""); }
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, "}"); }
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,""); }
void encode_recursive(zcmgen_t *zcm, zcm_member_t *lm, FILE *f, primitive_info_t *pinfo, char *accessor, int depth) { // base case: primitive array if (depth+1 == g_ptr_array_size(lm->dimensions) && pinfo != NULL) { char accessor_array[1024]; make_accessor_array(lm, "", accessor_array); if (!strcmp(pinfo->storage, "byte")) { zcm_dimension_t *dim = (zcm_dimension_t*) g_ptr_array_index(lm->dimensions, depth); if (dim->mode == ZCM_VAR) { emit(2+depth, "if (this.%s > 0)", dim->size); emit(3+depth, "outs.write(this.%s, 0, %s);", accessor_array, dim->size); } else { emit(2+depth, "outs.write(this.%s, 0, %s);", accessor_array, dim->size); } return; } // some other kind of primitive array. // This seems to be slower than the default (and is untested for correctness), hence it is disabled. if (0 && !strcmp(pinfo->storage, "float")) { zcm_dimension_t *dim = (zcm_dimension_t*) g_ptr_array_index(lm->dimensions, depth); emit(2+depth, "{ ByteBuffer bbuf = ByteBuffer.allocate(%s%s*4); bbuf.order(ByteOrder.BIG_ENDIAN); ", dim_size_prefix(dim->size), dim->size); emit(2+depth, " bbuf.asFloatBuffer().put(this.%s);", accessor_array); emit(2+depth, " outs.write(bbuf.array()); }"); return; } } // base case: generic if (depth == g_ptr_array_size(lm->dimensions)) { emit_start(2 + g_ptr_array_size(lm->dimensions),""); if (pinfo != NULL) freplace(f, pinfo->encode, accessor); else freplace(f, "#._encodeRecursive(outs);", accessor); emit_end(" "); return; } zcm_dimension_t *dim = (zcm_dimension_t*) g_ptr_array_index(lm->dimensions, depth); emit(2+depth, "for (int %c = 0; %c < %s%s; %c++) {", 'a'+depth, 'a'+depth, dim_size_prefix(dim->size), dim->size, 'a'+depth); encode_recursive(zcm, lm, f, pinfo, accessor, depth+1); emit(2+depth, "}"); }
void decode_recursive(zcmgen_t *zcm, zcm_member_t *lm, FILE *f, primitive_info_t *pinfo, char *accessor, int depth) { // base case: primitive array if (depth+1 == g_ptr_array_size(lm->dimensions) && pinfo != NULL) { char accessor_array[1024]; make_accessor_array(lm, "", accessor_array); // byte array if (!strcmp(pinfo->storage, "byte")) { zcm_dimension_t *dim = (zcm_dimension_t*) g_ptr_array_index(lm->dimensions, depth); emit_start(2+depth, "ins.readFully(this.%s, 0, %s);", accessor_array, dim->size); return; } // some other kind of primitive array. // This seems to be slower than the default (and is untested for correctness), hence it is disabled. if (0 && !strcmp(pinfo->storage, "float")) { zcm_dimension_t *dim = (zcm_dimension_t*) g_ptr_array_index(lm->dimensions, depth); emit(2+depth, "{ byte bb[] = new byte[%s%s*4]; ins.readFully(bb); ByteBuffer bbuf = ByteBuffer.wrap(bb); bbuf.order(ByteOrder.BIG_ENDIAN); ", dim_size_prefix(dim->size), dim->size); emit(2+depth, " bbuf.asFloatBuffer().get(this.%s); }", accessor_array); return; } } // base case: generic if (depth == g_ptr_array_size(lm->dimensions)) { emit_start(2 + g_ptr_array_size(lm->dimensions),""); if (pinfo != NULL) freplace(f, pinfo->decode, accessor); else { emit_continue("%s = %s._decodeRecursiveFactory(ins);", accessor, make_fqn(zcm, lm->type->lctypename)); } emit_end(""); return; } zcm_dimension_t *dim = (zcm_dimension_t*) g_ptr_array_index(lm->dimensions, depth); emit(2+depth, "for (int %c = 0; %c < %s%s; %c++) {", 'a'+depth, 'a'+depth, dim_size_prefix(dim->size), dim->size, 'a'+depth); decode_recursive(zcm, lm, f, pinfo, accessor, depth+1); emit(2+depth, "}"); }
void copy_recursive(zcmgen_t *zcm, zcm_member_t *lm, FILE *f, primitive_info_t *pinfo, char *accessor, int depth) { // base case: primitive array if (depth+1 == g_ptr_array_size(lm->dimensions) && pinfo != NULL) { char accessor_array[1024]; make_accessor_array(lm, "", accessor_array); // one method works for all primitive types, yay! zcm_dimension_t *dim = (zcm_dimension_t*) g_ptr_array_index(lm->dimensions, depth); if (dim->mode == ZCM_VAR) { emit(2+depth, "if (this.%s > 0)", dim->size); emit_start(3+depth, "System.arraycopy(this.%s, 0, outobj.%s, 0, %s%s);", accessor_array, accessor_array, dim_size_prefix(dim->size), dim->size); } else { emit_start(2+depth, "System.arraycopy(this.%s, 0, outobj.%s, 0, %s%s);", accessor_array, accessor_array, dim_size_prefix(dim->size), dim->size); } return; } // base case: generic if (depth == g_ptr_array_size(lm->dimensions)) { if (pinfo != NULL) { emit_start(2+g_ptr_array_size(lm->dimensions), "outobj.%s", lm->membername); for (unsigned int i = 0; i < g_ptr_array_size(lm->dimensions); i++) { emit_continue("[%c]", 'a'+i); } emit_continue(" = this.%s", lm->membername); for (unsigned int i = 0; i < g_ptr_array_size(lm->dimensions); i++) { emit_continue("[%c]", 'a'+i); } emit_end(";"); } else { emit(2+depth, "outobj.%s = this.%s.copy();", accessor, accessor); } return; } zcm_dimension_t *dim = (zcm_dimension_t*) g_ptr_array_index(lm->dimensions, depth); emit(2+depth, "for (int %c = 0; %c < %s%s; %c++) {", 'a'+depth, 'a'+depth, dim_size_prefix(dim->size), dim->size, 'a'+depth); copy_recursive(zcm, lm, f, pinfo, accessor, depth+1); emit(2+depth, "}"); }
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, "}"); } }