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


HyperKWIC - Version 7.20DA executed at 11:37 on 27 Oct 2017 | Polyhedron Solutions - INTERNAL USE | COMMERCIAL (Any O/S) SN 4AKIed