00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <stdarg.h>
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023 #include <string.h>
00024 #include <sys/time.h>
00025 #include <ccn/charbuf.h>
00026
00027 struct ccn_charbuf *
00028 ccn_charbuf_create(void)
00029 {
00030 struct ccn_charbuf *c;
00031 c = calloc(1, sizeof(*c));
00032 return(c);
00033 }
00034
00035 struct ccn_charbuf *
00036 ccn_charbuf_create_n(size_t n)
00037 {
00038 struct ccn_charbuf *c;
00039 c = malloc(sizeof(*c));
00040 if (c == NULL) return (NULL);
00041 c->length = 0;
00042 c->limit = n;
00043 if (n == 0) {
00044 c->buf = NULL;
00045 return(c);
00046 }
00047 c->buf = malloc(n);
00048 if (c->buf == NULL) {
00049 free(c);
00050 c = NULL;
00051 }
00052 return(c);
00053 }
00054
00055 void
00056 ccn_charbuf_destroy(struct ccn_charbuf **cbp)
00057 {
00058 struct ccn_charbuf *c = *cbp;
00059 if (c != NULL) {
00060 if (c->buf != NULL)
00061 free(c->buf);
00062 free(c);
00063 *cbp = NULL;
00064 }
00065 }
00066
00067
00068
00069
00070 unsigned char *
00071 ccn_charbuf_reserve(struct ccn_charbuf *c, size_t n)
00072 {
00073 size_t newsz = n + c->length;
00074 unsigned char *buf = c->buf;
00075 if (newsz < n)
00076 return(NULL);
00077 if (newsz > c->limit) {
00078 if (2 * c->limit > newsz)
00079 newsz = 2 * c->limit;
00080 #ifdef CCN_NOREALLOC
00081 buf = malloc(newsz);
00082 if (buf == NULL)
00083 return(NULL);
00084 memcpy(buf, c->buf, c->limit);
00085 free(c->buf);
00086 #else
00087 buf = realloc(c->buf, newsz);
00088 if (buf == NULL)
00089 return(NULL);
00090 #endif
00091 memset(buf + c->limit, 0, newsz - c->limit);
00092 c->buf = buf;
00093 c->limit = newsz;
00094 }
00095 buf += c->length;
00096 return(buf);
00097 }
00098
00099 void ccn_charbuf_reset(struct ccn_charbuf *c)
00100 {
00101 if (c == NULL) {
00102 return;
00103 }
00104 c->length = 0;
00105 }
00106
00107 int
00108 ccn_charbuf_append(struct ccn_charbuf *c, const void *p, size_t n)
00109 {
00110 unsigned char *dst = ccn_charbuf_reserve(c, n);
00111 if (dst == NULL)
00112 return(-1);
00113 memcpy(dst, p, n);
00114 c->length += n;
00115 return(0);
00116 }
00117
00118 int
00119 ccn_charbuf_append_value(struct ccn_charbuf *c, unsigned val, unsigned n)
00120 {
00121 unsigned char *dst;
00122 unsigned i;
00123 if (n > sizeof(val))
00124 return(-1);
00125 dst = ccn_charbuf_reserve(c, n);
00126 if (dst == NULL)
00127 return(-1);
00128 for (i = 0; i < n; i++)
00129 dst[i] = (unsigned char)(val >> (8 * (n-1-i)));
00130 c->length += n;
00131 return(0);
00132 }
00133
00134 int
00135 ccn_charbuf_append_charbuf(struct ccn_charbuf *c, const struct ccn_charbuf *in)
00136 {
00137 return(ccn_charbuf_append(c, in->buf, in->length));
00138 }
00139
00140 int
00141 ccn_charbuf_append_string(struct ccn_charbuf *c, const char *s)
00142 {
00143 return(ccn_charbuf_append(c, s, strlen(s)));
00144 }
00145
00146 int
00147 ccn_charbuf_putf(struct ccn_charbuf *c, const char *fmt, ...)
00148 {
00149 int sz;
00150 va_list ap;
00151 char *buf;
00152 buf = (char *)ccn_charbuf_reserve(c, strlen(fmt) + 10);
00153 if (buf == NULL) return(-1);
00154 va_start(ap, fmt);
00155 sz = vsnprintf(buf, c->limit - c->length, fmt, ap);
00156 va_end(ap);
00157 if (sz < 0)
00158 return(sz);
00159 if (c->length + sz < c->limit) {
00160 c->length += sz;
00161 return(sz);
00162 }
00163 va_end(ap);
00164 buf = (char *)ccn_charbuf_reserve(c, sz + 1);
00165 if (buf == NULL) return(-1);
00166 va_start(ap, fmt);
00167 sz = vsnprintf(buf, c->limit - c->length, fmt, ap);
00168 va_end(ap);
00169 if (c->length + sz < c->limit) {
00170 c->length += sz;
00171 return(sz);
00172 }
00173 return(-1);
00174 }
00175
00176
00177 int
00178 ccn_charbuf_append_datetime(struct ccn_charbuf *c, time_t secs, int nsecs)
00179 {
00180 char timestring[32];
00181 int timelen;
00182 struct tm time_tm;
00183 int res;
00184
00185 timelen = strftime(timestring, sizeof(timestring),
00186 "%FT%T", gmtime_r(&secs, &time_tm));
00187 if (timelen >= sizeof(timestring))
00188 return(-1);
00189 if (nsecs != 0) {
00190 if (nsecs < 0 || nsecs >= 1000000000)
00191 return(-1);
00192 timelen += snprintf(×tring[timelen], sizeof(timestring) - timelen,
00193 ".%09d", nsecs);
00194 if (timelen >= sizeof(timestring))
00195 return(-1);
00196 while (timestring[timelen - 1] == '0') timelen--;
00197 }
00198 timestring[timelen++] = 'Z';
00199 res = ccn_charbuf_append(c, timestring, timelen);
00200 return (res);
00201 }
00202
00203 char *
00204 ccn_charbuf_as_string(struct ccn_charbuf *c)
00205 {
00206 unsigned char *r;
00207 r = ccn_charbuf_reserve(c, 1);
00208 if (r == NULL)
00209 return(NULL);
00210 r[0] = 0;
00211 return((char *)c->buf);
00212 }