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