int main(int argc, char **argv) { // create a bundle and add messages to it t_osc_bndl_u *bndl_u = osc_bundle_u_alloc(); t_osc_msg_u *m1 = osc_message_u_alloc(); osc_message_u_setAddress(m1, "/foo"); osc_message_u_appendFloat(m1, 3.14); osc_bundle_u_addMsg(bndl_u, m1); t_osc_msg_u *m2 = osc_message_u_allocWithString("/bar", "whatevs"); osc_bundle_u_addMsg(bndl_u, m2); t_osc_msg_u *m3 = osc_message_u_allocWithAddress("/bloo"); t_osc_atom_u *a = osc_atom_u_allocWithInt32(12); osc_message_u_appendAtom(m3, a); osc_bundle_u_addMsg(bndl_u, m3); // serialize the bundle long len = osc_bundle_u_nserialize(NULL, 0, bndl_u); char bndl_s[len]; osc_bundle_u_nserialize(bndl_s, len, bndl_u); // free the original unserialized bundle osc_bundle_u_free(bndl_u); bndl_u = NULL; // deserialize the serialized bundle osc_bundle_s_deserialize(len, bndl_s, &bndl_u); // iterate over messages in a serialized bundle t_osc_bndl_it_s *b_it_s = osc_bndl_it_s_get(len, bndl_s); while(osc_bndl_it_s_hasNext(b_it_s)){ t_osc_msg_s *m = osc_bndl_it_s_next(b_it_s); printf("%s\n", osc_message_s_getAddress(m)); } osc_bndl_it_s_destroy(b_it_s); // turn a serialized bundle into printable text long tlen = osc_bundle_s_nformat(NULL, 0, len, bndl_s, 0); char text[tlen + 1]; osc_bundle_s_nformat(text, tlen, len, bndl_s, 0); printf("\nBUNDLE:\n"); printf("%s\n", text); printf("\n"); // turn text into an unserialized bundle t_osc_bndl_u *bndl_u_2 = NULL; char *text2 = "/jean : [1, 2, 3], /john : 6.66, /jeremy : \"is cool\""; osc_parser_parseString(strlen(text2), text2, &bndl_u_2); // iterate over messages in an unserialized bundle t_osc_bndl_it_u *b_it_u = osc_bndl_it_u_get(bndl_u_2); while(osc_bndl_it_u_hasNext(b_it_u)){ t_osc_msg_u *m = osc_bndl_it_u_next(b_it_u); printf("%s has typetags ", osc_message_u_getAddress(m)); // iterate over atoms in list t_osc_msg_it_u *m_it_u = osc_msg_it_u_get(m); while(osc_msg_it_u_hasNext(m_it_u)){ t_osc_atom_u *a = osc_msg_it_u_next(m_it_u); printf("%c", osc_atom_u_getTypetag(a)); } osc_msg_it_u_destroy(m_it_u); printf("\n"); } osc_bndl_it_u_destroy(b_it_u); }
static t_osc_err osc_bundle_u_flatten_impl(t_osc_bndl_u **dest, t_osc_bndl_u *src, int maxlevel, int level, char *prefix, char *sep, int remove_enclosing_address_if_empty) { if(!sep){ sep = ""; } if(!(*dest)){ *dest = osc_bundle_u_alloc(); } t_osc_bndl_it_u *bit = osc_bndl_it_u_get(src); while(osc_bndl_it_u_hasNext(bit)){ t_osc_msg_u *m = osc_bndl_it_u_next(bit); t_osc_msg_u *mcopy = NULL; osc_message_u_deepCopy(&mcopy, m); if((level < maxlevel) || (maxlevel <= 0)){ t_osc_msg_it_u *mit = osc_msg_it_u_get(mcopy); while(osc_msg_it_u_hasNext(mit)){ t_osc_atom_u *a = osc_msg_it_u_next(mit); if(osc_atom_u_getTypetag(a) == OSC_BUNDLE_TYPETAG){ osc_message_u_removeAtom(mcopy, a); t_osc_bndl_u *bu = osc_atom_u_getBndl(a); /* t_osc_bndl_u *bu = NULL; osc_bundle_s_deserialize(osc_bundle_s_getLen(b), osc_bundle_s_getPtr(b), &bu); */ t_osc_err e; if(prefix){ int prefixlen = strlen(prefix) + strlen(osc_message_u_getAddress(mcopy)) + strlen(sep); char pfx[prefixlen + 1]; sprintf(pfx, "%s%s%s", prefix, sep, osc_message_u_getAddress(mcopy)); e = osc_bundle_u_flatten_impl(dest, bu, maxlevel, level + 1, pfx, sep, remove_enclosing_address_if_empty); }else{ e = osc_bundle_u_flatten_impl(dest, bu, maxlevel, level + 1, osc_message_u_getAddress(mcopy), sep, remove_enclosing_address_if_empty); } if(e){ return e; } osc_atom_u_free(a); } } osc_msg_it_u_destroy(mit); } if(!remove_enclosing_address_if_empty || osc_message_u_getArgCount(mcopy) > 0){ if(prefix){ int newaddresslen = strlen(prefix) + strlen(osc_message_u_getAddress(mcopy)) + strlen(sep); char newaddress[newaddresslen + 1]; sprintf(newaddress, "%s%s%s", prefix, sep, osc_message_u_getAddress(mcopy)); osc_message_u_setAddress(mcopy, newaddress); } osc_bundle_u_addMsgWithoutDups(*dest, mcopy); }else{ osc_message_u_free(mcopy); } } osc_bndl_it_u_destroy(bit); return OSC_ERR_NONE; }
//void odowncast_fullPacket(t_odowncast *x, long len, long ptr) void odowncast_fullPacket(t_odowncast *x, t_symbol *msg, int argc, t_atom *argv) { OMAX_UTIL_GET_LEN_AND_PTR; t_osc_bndl_u *b = osc_bundle_s_deserialize(len, ptr); if(!b){ object_error((t_object *)x, "invalid OSC packet"); return; } /* if(x->flatten_nested_bundles){ t_osc_bndl_u *bf = NULL; e = osc_bundle_u_flatten(&bf, b } */ t_osc_bndl_u **nestedbundles = NULL; int nnestedbundles = 0, nestedbundles_buflen = 0; t_osc_bndl_it_u *bit = osc_bndl_it_u_get(b); t_osc_timetag timetag = OSC_TIMETAG_NULL; while(osc_bndl_it_u_hasNext(bit)){ t_osc_msg_u *m = osc_bndl_it_u_next(bit); t_osc_msg_it_u *mit = osc_msg_it_u_get(m); while(osc_msg_it_u_hasNext(mit)){ t_osc_atom_u *a = osc_msg_it_u_next(mit); int i = 0; switch(osc_atom_u_getTypetag(a)){ case 'c': case 'C': case 'I': case 'h': case 'H': case 'u': case 'U': case 'N': case 'T': case 'F': if(x->ints){ osc_atom_u_setInt32(a, osc_atom_u_getInt32(a)); } break; case 'd': if(x->doubles){ osc_atom_u_setFloat(a, osc_atom_u_getFloat(a)); } break; case OSC_BUNDLE_TYPETAG: if(x->bundles){ if(!nestedbundles || nnestedbundles == nestedbundles_buflen){ nestedbundles = (t_osc_bndl_u **)osc_mem_resize(nestedbundles, (nestedbundles_buflen + 16) * sizeof(char *)); } nestedbundles[nnestedbundles++] = osc_atom_u_getBndl(a); osc_message_u_removeAtom(m, a); } break; case OSC_TIMETAG_TYPETAG: #if OSC_TIMETAG_FORMAT == OSC_TIMETAG_NTP if(x->timetags){ t_osc_timetag tt = osc_atom_u_getTimetag(a); if(x->timetag_address){ char *address = osc_message_u_getAddress(m); if(!strcmp(address, x->timetag_address->s_name)){ timetag = tt; } } t_osc_atom_u *aa = osc_atom_u_alloc(); int32_t tt1, tt2; //tt1 = (tt & 0xffffffff00000000) >> 32; //tt2 = tt & 0xffffffff; tt1 = osc_timetag_ntp_getSeconds(tt); tt2 = osc_timetag_ntp_getFraction(tt); osc_atom_u_setInt32(aa, ntoh32(tt1)); osc_atom_u_setInt32(a, ntoh32(tt2)); osc_message_u_insertAtom(m, aa, ++i); } #else object_error((t_object *)x, "o.downcast only supports NTP timetags"); #endif break; } i++; } osc_msg_it_u_destroy(mit); } osc_bndl_it_u_destroy(bit); t_osc_bndl_s *bs1 = osc_bundle_u_serialize(b); if(bs1){ long l = osc_bundle_s_getLen(bs1); char *p = osc_bundle_s_getPtr(bs1); memcpy(p + OSC_ID_SIZE, &timetag, sizeof(t_osc_timetag)); for(int i = 0; i < nnestedbundles; i++){ t_osc_bndl_s *bs2 = osc_bundle_u_serialize(nestedbundles[i]); if(bs2){ long ll = osc_bundle_s_getLen(bs2); char *pp = osc_bundle_s_getPtr(bs2); p = osc_mem_resize(p, l + ll); memcpy(p + l, pp, ll); l += ll; osc_bundle_s_deepFree(bs2); } } //if(x->bundle){ omax_util_outletOSC(x->outlet, l, p); /* }else{ t_osc_bndl_it_s *bit = osc_bndl_it_s_get(l, p); while(osc_bndl_it_s_hasNext(bit)){ t_osc_msg_s *m = osc_bndl_it_s_next(bit); long ml = osc_message_s_getSize(m); char *mp = osc_message_s_getAddress(m); omax_util_outletOSC(x->outlet, ml, mp); } osc_bndl_it_s_destroy(bit); } */ osc_bundle_s_deepFree(bs1); } osc_bundle_u_free(b); }