PageRenderTime 19ms CodeModel.GetById 11ms app.highlight 6ms RepoModel.GetById 0ms app.codeStats 0ms

/liblo-0.26/src/bundle.c

#
C | 181 lines | 129 code | 35 blank | 17 comment | 24 complexity | 30b8ee11d27abf175cce0bb90acf42bf MD5 | raw file
Possible License(s): LGPL-2.1
  1/*
  2 *  Copyright (C) 2004 Steve Harris
  3 *
  4 *  This program is free software; you can redistribute it and/or modify
  5 *  it under the terms of the GNU Lesser General Public License as
  6 *  published by the Free Software Foundation; either version 2.1 of the
  7 *  License, or (at your option) any later version.
  8 *
  9 *  This program is distributed in the hope that it will be useful,
 10 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 11 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 12 *  GNU Lesser General Public License for more details.
 13 *
 14 *  $Id$
 15 */
 16
 17#include <stdlib.h>
 18#include <stdio.h>
 19#include <string.h>
 20
 21#include "lo_types_internal.h"
 22#include "lo/lo.h"
 23
 24lo_bundle lo_bundle_new(lo_timetag tt)
 25{
 26    lo_bundle b = calloc(1, sizeof(struct _lo_bundle));
 27
 28    b->size = 4;
 29    b->len = 0;
 30    b->ts = tt;
 31    b->msgs = calloc(b->size, sizeof(lo_message));
 32    b->paths = calloc(b->size, sizeof(char *));
 33
 34    return b;
 35}
 36
 37int lo_bundle_add_message(lo_bundle b, const char *path, lo_message m)
 38{
 39    if (!m)
 40    	return 0;
 41
 42    if (b->len >= b->size) {
 43	b->size *= 2;
 44	b->msgs = realloc(b->msgs, b->size * sizeof(lo_message));
 45	b->paths = realloc(b->paths, b->size * sizeof(char *));
 46    if (!b->msgs || !b->paths)
 47        return -1;
 48    }
 49
 50    b->msgs[b->len] = m;
 51    b->paths[b->len] = (char *)path;
 52
 53    (b->len)++;
 54    return 0;
 55}
 56
 57size_t lo_bundle_length(lo_bundle b)
 58{
 59    size_t size = 16; /* "#bundle" and the timetag */
 60    int i;
 61
 62    if (!b) {
 63	return 0;
 64    }
 65
 66    size += b->len * 4; /* sizes */
 67    for (i = 0; i < b->len; i++) {
 68	size += lo_message_length(b->msgs[i], b->paths[i]);
 69    }
 70
 71    return size;
 72}
 73
 74void *lo_bundle_serialise(lo_bundle b, void *to, size_t *size)
 75{
 76    size_t s, skip;
 77    int32_t *bes;
 78    int i;
 79    char *pos;
 80    lo_pcast32 be;
 81
 82    if (!b) {
 83	return NULL;
 84    }
 85
 86    s = lo_bundle_length(b);
 87    if (size) {
 88	*size = s;
 89    }
 90
 91    if (!to) {
 92	to = calloc(1, s);
 93    }
 94
 95    pos = to;
 96    strcpy(pos, "#bundle");
 97    pos += 8;
 98	
 99    be.nl = lo_htoo32(b->ts.sec);
100    memcpy(pos, &be, 4);
101    pos += 4;
102    be.nl = lo_htoo32(b->ts.frac);
103    memcpy(pos, &be, 4);
104    pos += 4;
105
106    for (i = 0; i < b->len; i++) {
107	lo_message_serialise(b->msgs[i], b->paths[i], pos + 4, &skip);
108	bes = (int32_t *)pos;
109	*bes = lo_htoo32(skip);
110	pos += skip + 4;
111
112	if (pos > (char *)to + s) {
113	    fprintf(stderr, "liblo: data integrity error at message %d\n", i);
114
115	    return NULL;
116	}
117    }
118    if (pos != (char*)to + s) {
119	fprintf(stderr, "liblo: data integrity error\n");
120
121	return NULL;
122    }
123
124    return to;
125}
126
127void lo_bundle_free(lo_bundle b)
128{
129    if (!b) {
130	return;
131    }
132
133    free(b->msgs);
134    free(b->paths);
135    free(b);
136}
137
138static int _lo_internal_compare_ptrs( const void* a, const void* b )
139{
140    if (*(void**)a <  *(void**)b) return -1;
141    if (*(void**)a == *(void**)b) return 0;
142    return 1;
143}
144
145void lo_bundle_free_messages(lo_bundle b)
146{
147    int i;
148    lo_message tmp = 0;
149
150    if (!b)
151        return;
152
153    /* avoid freeing the same message twice */
154    if (b->len > 2)
155        qsort(b->msgs, b->len, sizeof(lo_message*), _lo_internal_compare_ptrs);
156
157    for(i = 0; i < b->len; i++) {
158        if (b->msgs[i] != tmp) {
159            tmp = b->msgs[i];
160            lo_message_free(b->msgs[i]);
161        }
162    }
163    free(b->msgs);
164    free(b->paths);
165    free(b);
166}
167
168void lo_bundle_pp(lo_bundle b)
169{
170    int i;
171
172    if (!b) return;
173
174    printf("bundle(%f):\n", (double)b->ts.sec + b->ts.frac / 4294967296.0);
175    for (i = 0; i < b->len; i++) {
176	lo_message_pp(b->msgs[i]);
177    }
178    printf("\n");
179}
180
181/* vi:set ts=8 sts=4 sw=4: */