ncbytes.c 4.1 KB

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