ocbytes.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc.
  2. See the COPYRIGHT file for more information. */
  3. #include "config.h"
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include "ocbytes.h"
  8. #ifndef TRUE
  9. #define TRUE 1
  10. #endif
  11. #ifndef FALSE
  12. #define FALSE 0
  13. #endif
  14. #define DEFAULTALLOC 1024
  15. #define ALLOCINCR 1024
  16. static int ocbytesdebug = 1;
  17. static long
  18. ocbytesfail(void)
  19. {
  20. fflush(stdout);
  21. fprintf(stderr,"bytebuffer failure\n");
  22. fflush(stderr);
  23. if(ocbytesdebug) abort();
  24. return FALSE;
  25. }
  26. OCbytes*
  27. ocbytesnew(void)
  28. {
  29. OCbytes* bb = (OCbytes*)malloc(sizeof(OCbytes));
  30. if(bb == NULL) return (OCbytes*)ocbytesfail();
  31. bb->alloc=0;
  32. bb->length=0;
  33. bb->content=NULL;
  34. bb->nonextendible = 0;
  35. return bb;
  36. }
  37. int
  38. ocbytessetalloc(OCbytes* bb, unsigned int sz)
  39. {
  40. char* newcontent;
  41. if(bb == NULL) return ocbytesfail();
  42. if(sz <= 0) {sz = (bb->alloc?2*bb->alloc:DEFAULTALLOC);}
  43. if(bb->alloc >= sz) return TRUE;
  44. if(bb->nonextendible) return ocbytesfail();
  45. newcontent=(char*)calloc(sz,sizeof(char));
  46. if(newcontent == NULL) return FALSE;
  47. if(bb->alloc > 0 && bb->length > 0 && bb->content != NULL) {
  48. memcpy((void*)newcontent,(void*)bb->content,sizeof(char)*bb->length);
  49. }
  50. if(bb->content != NULL) free(bb->content);
  51. bb->content=newcontent;
  52. bb->alloc=sz;
  53. return TRUE;
  54. }
  55. void
  56. ocbytesfree(OCbytes* bb)
  57. {
  58. if(bb == NULL) return;
  59. if(!bb->nonextendible && bb->content != NULL) free(bb->content);
  60. free(bb);
  61. }
  62. int
  63. ocbytessetlength(OCbytes* bb, unsigned int sz)
  64. {
  65. if(bb == NULL) return ocbytesfail();
  66. if(sz > bb->alloc) {if(!ocbytessetalloc(bb,sz)) return ocbytesfail();}
  67. bb->length = sz;
  68. return TRUE;
  69. }
  70. int
  71. ocbytesfill(OCbytes* bb, char fill)
  72. {
  73. unsigned int i;
  74. if(bb == NULL) return ocbytesfail();
  75. for(i=0;i<bb->length;i++) bb->content[i] = fill;
  76. return TRUE;
  77. }
  78. int
  79. ocbytesget(OCbytes* bb, unsigned int index)
  80. {
  81. if(bb == NULL) return -1;
  82. if(index >= bb->length) return -1;
  83. return bb->content[index];
  84. }
  85. int
  86. ocbytesset(OCbytes* bb, unsigned int index, char elem)
  87. {
  88. if(bb == NULL) return ocbytesfail();
  89. if(index >= bb->length) return ocbytesfail();
  90. bb->content[index] = elem;
  91. return TRUE;
  92. }
  93. int
  94. ocbytesappend(OCbytes* bb, char elem)
  95. {
  96. if(bb == NULL) return ocbytesfail();
  97. /* We need space for the char + null */
  98. while(bb->length+1 >= bb->alloc) {
  99. if(!ocbytessetalloc(bb,0)) return ocbytesfail();
  100. }
  101. bb->content[bb->length] = elem;
  102. bb->length++;
  103. bb->content[bb->length] = '\0';
  104. return TRUE;
  105. }
  106. /* This assumes s is a null terminated string*/
  107. int
  108. ocbytescat(OCbytes* bb, char* s)
  109. {
  110. ocbytesappendn(bb,(void*)s,strlen(s)+1); /* include trailing null*/
  111. /* back up over the trailing null*/
  112. if(bb->length == 0) return ocbytesfail();
  113. bb->length--;
  114. return 1;
  115. }
  116. int
  117. ocbytesappendn(OCbytes* bb, void* elem, unsigned int n)
  118. {
  119. if(bb == NULL || elem == NULL) return ocbytesfail();
  120. if(n == 0) {n = strlen((char*)elem);}
  121. while(!ocbytesavail(bb,n+1)) {
  122. if(!ocbytessetalloc(bb,0)) return ocbytesfail();
  123. }
  124. memcpy((void*)&bb->content[bb->length],(void*)elem,n);
  125. bb->length += n;
  126. bb->content[bb->length] = '\0';
  127. return TRUE;
  128. }
  129. int
  130. ocbytesprepend(OCbytes* bb, char elem)
  131. {
  132. int i; /* do not make unsigned */
  133. if(bb == NULL) return ocbytesfail();
  134. if(bb->length >= bb->alloc) if(!ocbytessetalloc(bb,0)) return ocbytesfail();
  135. /* could we trust memcpy? instead */
  136. for(i=bb->alloc;i>=1;i--) {bb->content[i]=bb->content[i-1];}
  137. bb->content[0] = elem;
  138. bb->length++;
  139. return TRUE;
  140. }
  141. char*
  142. ocbytesdup(OCbytes* bb)
  143. {
  144. char* result = (char*)malloc(bb->length+1);
  145. memcpy((void*)result,(const void*)bb->content,bb->length);
  146. result[bb->length] = '\0'; /* just in case it is a string*/
  147. return result;
  148. }
  149. char*
  150. ocbytesextract(OCbytes* bb)
  151. {
  152. char* result = bb->content;
  153. bb->alloc = 0;
  154. bb->length = 0;
  155. bb->content = NULL;
  156. return result;
  157. }
  158. int
  159. ocbytessetcontents(OCbytes* bb, char* contents, unsigned int alloc)
  160. {
  161. if(bb == NULL) return ocbytesfail();
  162. ocbytesclear(bb);
  163. if(!bb->nonextendible && bb->content != NULL) free(bb->content);
  164. bb->content = contents;
  165. bb->length = 0;
  166. bb->alloc = alloc;
  167. bb->nonextendible = 1;
  168. return 1;
  169. }