PageRenderTime 47ms CodeModel.GetById 23ms 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. #include <stdlib.h>
  17. #include <stdio.h>
  18. #include <string.h>
  19. #include "lo_types_internal.h"
  20. #include "lo/lo.h"
  21. lo_bundle lo_bundle_new(lo_timetag tt)
  22. {
  23. lo_bundle b = calloc(1, sizeof(struct _lo_bundle));
  24. b->size = 4;
  25. b->len = 0;
  26. b->ts = tt;
  27. b->msgs = calloc(b->size, sizeof(lo_message));
  28. b->paths = calloc(b->size, sizeof(char *));
  29. return b;
  30. }
  31. int lo_bundle_add_message(lo_bundle b, const char *path, lo_message m)
  32. {
  33. if (!m)
  34. return 0;
  35. if (b->len >= b->size) {
  36. b->size *= 2;
  37. b->msgs = realloc(b->msgs, b->size * sizeof(lo_message));
  38. b->paths = realloc(b->paths, b->size * sizeof(char *));
  39. if (!b->msgs || !b->paths)
  40. return -1;
  41. }
  42. b->msgs[b->len] = m;
  43. b->paths[b->len] = (char *)path;
  44. (b->len)++;
  45. return 0;
  46. }
  47. size_t lo_bundle_length(lo_bundle b)
  48. {
  49. size_t size = 16; /* "#bundle" and the timetag */
  50. int i;
  51. if (!b) {
  52. return 0;
  53. }
  54. size += b->len * 4; /* sizes */
  55. for (i = 0; i < b->len; i++) {
  56. size += lo_message_length(b->msgs[i], b->paths[i]);
  57. }
  58. return size;
  59. }
  60. void *lo_bundle_serialise(lo_bundle b, void *to, size_t *size)
  61. {
  62. size_t s, skip;
  63. int32_t *bes;
  64. int i;
  65. char *pos;
  66. lo_pcast32 be;
  67. if (!b) {
  68. return NULL;
  69. }
  70. s = lo_bundle_length(b);
  71. if (size) {
  72. *size = s;
  73. }
  74. if (!to) {
  75. to = calloc(1, s);
  76. }
  77. pos = to;
  78. strcpy(pos, "#bundle");
  79. pos += 8;
  80. be.nl = lo_htoo32(b->ts.sec);
  81. memcpy(pos, &be, 4);
  82. pos += 4;
  83. be.nl = lo_htoo32(b->ts.frac);
  84. memcpy(pos, &be, 4);
  85. pos += 4;
  86. for (i = 0; i < b->len; i++) {
  87. lo_message_serialise(b->msgs[i], b->paths[i], pos + 4, &skip);
  88. bes = (int32_t *)pos;
  89. *bes = lo_htoo32(skip);
  90. pos += skip + 4;
  91. if (pos > (char *)to + s) {
  92. fprintf(stderr, "liblo: data integrity error at message %d\n", i);
  93. return NULL;
  94. }
  95. }
  96. if (pos != (char*)to + s) {
  97. fprintf(stderr, "liblo: data integrity error\n");
  98. return NULL;
  99. }
  100. return to;
  101. }
  102. void lo_bundle_free(lo_bundle b)
  103. {
  104. if (!b) {
  105. return;
  106. }
  107. free(b->msgs);
  108. free(b->paths);
  109. free(b);
  110. }
  111. static int _lo_internal_compare_ptrs( const void* a, const void* b )
  112. {
  113. if (*(void**)a < *(void**)b) return -1;
  114. if (*(void**)a == *(void**)b) return 0;
  115. return 1;
  116. }
  117. void lo_bundle_free_messages(lo_bundle b)
  118. {
  119. int i;
  120. lo_message tmp = 0;
  121. if (!b)
  122. return;
  123. /* avoid freeing the same message twice */
  124. if (b->len > 2)
  125. qsort(b->msgs, b->len, sizeof(lo_message*), _lo_internal_compare_ptrs);
  126. for(i = 0; i < b->len; i++) {
  127. if (b->msgs[i] != tmp) {
  128. tmp = b->msgs[i];
  129. lo_message_free(b->msgs[i]);
  130. }
  131. }
  132. free(b->msgs);
  133. free(b->paths);
  134. free(b);
  135. }
  136. void lo_bundle_pp(lo_bundle b)
  137. {
  138. int i;
  139. if (!b) return;
  140. printf("bundle(%f):\n", (double)b->ts.sec + b->ts.frac / 4294967296.0);
  141. for (i = 0; i < b->len; i++) {
  142. lo_message_pp(b->msgs[i]);
  143. }
  144. printf("\n");
  145. }
  146. /* vi:set ts=8 sts=4 sw=4: */