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 "ocbytes.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 ocbytesdebug = 1;
21
22static long
23ocbytesfail(void)
24{
25    fflush(stdout);
26    fprintf(stderr,"bytebuffer failure\n");
27    fflush(stderr);
28    if(ocbytesdebug) abort();
29    return FALSE;
30}
31
32OCbytes*
33ocbytesnew(void)
34{
35  OCbytesbb = (OCbytes*)malloc(sizeof(OCbytes));
36  if(bb == NULL) return (OCbytes*)ocbytesfail();
37  bb->alloc=0;
38  bb->length=0;
39  bb->content=NULL;
40  bb->nonextendible = 0;
41  return bb;
42}
43
44int
45ocbytessetalloc(OCbytesbb, size_t sz)
46{
47  char* newcontent;
48  if(bb == NULL) return ocbytesfail();
49  if(sz <= 0) {sz = (bb->alloc?2*bb->alloc:DEFAULTALLOC);}
50  if(bb->alloc >= sz) return TRUE;
51  if(bb->nonextendible) return ocbytesfail();
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
64ocbytesfree(OCbytesbb)
65{
66  if(bb == NULL) return;
67  if(!bb->nonextendible && bb->content != NULL) free(bb->content);
68  free(bb);
69}
70
71int
72ocbytessetlength(OCbytesbb, size_t sz)
73{
74  if(bb == NULL) return ocbytesfail();
75  if(bb->length < sz) {
76      if(sz > bb->alloc) {if(!ocbytessetalloc(bb,sz)) return ocbytesfail();}
77  }
78  bb->length = sz;
79  return TRUE;
80}
81
82int
83ocbytesfill(OCbytesbb, char fill)
84{
85  size_t i;
86  if(bb == NULL) return ocbytesfail();
87  for(i=0;i<bb->length;i++) bb->content[i] = fill;
88  return TRUE;
89}
90
91int
92ocbytesget(OCbytesbb, size_t index)
93{
94  if(bb == NULL) return -1;
95  if(index >= bb->length) return -1;
96  return bb->content[index];
97}
98
99int
100ocbytesset(OCbytesbb, size_t index, char elem)
101{
102  if(bb == NULL) return ocbytesfail();
103  if(index >= bb->length) return ocbytesfail();
104  bb->content[index] = elem;
105  return TRUE;
106}
107
108int
109ocbytesappend(OCbytesbb, int elem)
110{
111  if(bb == NULL) return ocbytesfail();
112  /* We need space for the char + null */
113  while(bb->length+1 >= bb->alloc) {
114 if(!ocbytessetalloc(bb,0)) return ocbytesfail();
115  }
116  bb->content[bb->length] = (char)elem;
117  bb->length++;
118  bb->content[bb->length] = '\0';
119  return TRUE;
120}
121
122/* This assumes s is a null terminated string*/
123int
124ocbytescat(OCbytesbb, const char* s)
125{
126    ocbytesappendn(bb,(void*)s,strlen(s)+1); /* include trailing null*/
127    /* back up over the trailing null*/
128    if(bb->length == 0) return ocbytesfail();
129    bb->length--;
130    return 1;
131}
132
133int
134ocbytesappendn(OCbytesbb, const void* elem, size_t n)
135{
136  if(bb == NULL || elem == NULL) return ocbytesfail();
137  if(n == 0) {n = strlen((char*)elem);}
138  while(!ocbytesavail(bb,n+1)) {
139    if(!ocbytessetalloc(bb,0)) return ocbytesfail();
140  }
141  memcpy((void*)&bb->content[bb->length],(void*)elem,n);
142  bb->length += n;
143  bb->content[bb->length] = '\0';
144  return TRUE;
145}
146
147int
148ocbytesprepend(OCbytesbb, char elem)
149{
150  int i; /* do not make unsigned */
151  if(bb == NULL) return ocbytesfail();
152  if(bb->length >= bb->alloc) if(!ocbytessetalloc(bb,0)) return ocbytesfail();
153  /* could we trust memcpy? instead */
154  for(i=bb->alloc;i>=1;i--) {bb->content[i]=bb->content[i-1];}
155  bb->content[0] = elem;
156  bb->length++;
157  return TRUE;
158}
159
160char*
161ocbytesdup(OCbytesbb)
162{
163    char* result = (char*)malloc(bb->length+1);
164    memcpy((void*)result,(const void*)bb->content,bb->length);
165    result[bb->length] = '\0'; /* just in case it is a string*/
166    return result;
167}
168
169char*
170ocbytesextract(OCbytesbb)
171{
172    char* result = bb->content;
173    bb->alloc = 0;
174    bb->length = 0;
175    bb->content = NULL;
176    return result;
177}
178
179int
180ocbytessetcontents(OCbytesbb, char* contents, size_t alloc)
181{
182    if(bb == NULL) return ocbytesfail();
183    ocbytesclear(bb);
184    if(!bb->nonextendible && bb->content != NULL) free(bb->content);
185    bb->content = contents;
186    bb->length = 0;
187    bb->alloc = alloc;
188    bb->nonextendible = 1;
189    return 1;
190}
191
192/* Null terminate the byte string without extending its length */
193/* For debugging */
194int
195ocbytesnull(OCbytesbb)
196{
197    ocbytesappend(bb,'\0');
198    bb->length--;
199    return 1;
200}
201


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