CSL  5.2
bundle.c
Go to the documentation of this file.
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 
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 
37 int 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 
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 
74 void *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 
128 {
129  if (!b) {
130  return;
131  }
132 
133  free(b->msgs);
134  free(b->paths);
135  free(b);
136 }
137 
138 static 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 
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 
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: */