00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <string.h>
00021 #include <stdlib.h>
00022 #include <ccn/ccn.h>
00023 #include <ccn/charbuf.h>
00024 #include <ccn/coding.h>
00025 #include <ccn/indexbuf.h>
00026 #include <ccn/random.h>
00027
00028
00029
00030
00031
00032 int
00033 ccn_name_init(struct ccn_charbuf *c)
00034 {
00035 int res;
00036 c->length = 0;
00037 res = ccn_charbuf_append_tt(c, CCN_DTAG_Name, CCN_DTAG);
00038 if (res == -1) return(res);
00039 res = ccn_charbuf_append_closer(c);
00040 return(res);
00041 }
00042
00043
00044
00045
00046
00047
00048
00049 int
00050 ccn_name_append(struct ccn_charbuf *c, const void *component, size_t n)
00051 {
00052 int res;
00053 const unsigned char closer[2] = {CCN_CLOSE, CCN_CLOSE};
00054 if (c->length < 2 || c->buf[c->length-1] != closer[1])
00055 return(-1);
00056 c->length -= 1;
00057 ccn_charbuf_reserve(c, n + 8);
00058 res = ccn_charbuf_append_tt(c, CCN_DTAG_Component, CCN_DTAG);
00059 if (res == -1) return(res);
00060 res = ccn_charbuf_append_tt(c, n, CCN_BLOB);
00061 if (res == -1) return(res);
00062 res = ccn_charbuf_append(c, component, n);
00063 if (res == -1) return(res);
00064 res = ccn_charbuf_append(c, closer, sizeof(closer));
00065 return(res);
00066 }
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 int
00077 ccn_name_append_str(struct ccn_charbuf *c, const char *s)
00078 {
00079 return(ccn_name_append(c, s, strlen(s)));
00080 }
00081
00082
00083
00084
00085
00086
00087
00088
00089 int
00090 ccn_name_append_numeric(struct ccn_charbuf *c,
00091 enum ccn_marker marker, uintmax_t value)
00092 {
00093 uintmax_t v;
00094 int i;
00095 char b[32];
00096
00097 for (v = value, i = sizeof(b); v != 0 && i > 0; i--, v >>= 8)
00098 b[i-1] = v & 0xff;
00099 if (i < 1)
00100 return(-1);
00101 if (marker >= 0)
00102 b[--i] = marker;
00103 return(ccn_name_append(c, b + i, sizeof(b) - i));
00104 }
00105
00106
00107
00108
00109
00110
00111
00112
00113 int
00114 ccn_name_append_nonce(struct ccn_charbuf *c)
00115 {
00116 const unsigned char pre[4] = { CCN_MARKER_CONTROL, '.', 'N', 0 };
00117 unsigned char b[15];
00118
00119 memcpy(b, pre, sizeof(pre));
00120 ccn_random_bytes(b + sizeof(pre), sizeof(b) - sizeof(pre));
00121 return(ccn_name_append(c, b, sizeof(b)));
00122 }
00123
00124
00125
00126
00127
00128
00129
00130 int
00131 ccn_name_append_components(struct ccn_charbuf *c,
00132 const unsigned char *ccnb,
00133 size_t start, size_t stop)
00134 {
00135 int res;
00136 if (c->length < 2 || start > stop)
00137 return(-1);
00138 c->length -= 1;
00139 ccn_charbuf_reserve(c, stop - start + 1);
00140 res = ccn_charbuf_append(c, ccnb + start, stop - start);
00141 if (res == -1) return(res);
00142 res = ccn_charbuf_append_closer(c);
00143 return(res);
00144 }
00145
00146
00147
00148
00149
00150
00151 int
00152 ccn_name_comp_get(const unsigned char *data,
00153 const struct ccn_indexbuf *indexbuf,
00154 unsigned int i,
00155 const unsigned char **comp, size_t *size)
00156 {
00157 int len;
00158 struct ccn_buf_decoder decoder;
00159 struct ccn_buf_decoder *d;
00160
00161
00162 if (indexbuf->n < 2 || i > indexbuf->n - 2) {
00163
00164 return(-1);
00165 }
00166 len = indexbuf->buf[i + 1]-indexbuf->buf[i];
00167 d = ccn_buf_decoder_start(&decoder, data + indexbuf->buf[i], len);
00168 if (ccn_buf_match_dtag(d, CCN_DTAG_Component)) {
00169 ccn_buf_advance(d);
00170 if (ccn_buf_match_blob(d, comp, size))
00171 return(0);
00172 *comp = d->buf + d->decoder.index;
00173 *size = 0;
00174 ccn_buf_check_close(d);
00175 if (d->decoder.state >= 0)
00176 return(0);
00177 }
00178 return(-1);
00179 }
00180
00181 int
00182 ccn_name_comp_strcmp(const unsigned char *data,
00183 const struct ccn_indexbuf *indexbuf,
00184 unsigned int i, const char *val)
00185 {
00186 const unsigned char *comp_ptr;
00187 size_t comp_size;
00188
00189
00190
00191
00192 if (ccn_name_comp_get(data, indexbuf, i, &comp_ptr, &comp_size) == 0)
00193 return(strncmp(val, (const char *)comp_ptr, comp_size));
00194
00195 return(1);
00196 }
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206 int
00207 ccn_name_split(const struct ccn_charbuf *c, struct ccn_indexbuf *components)
00208 {
00209 struct ccn_buf_decoder decoder;
00210 struct ccn_buf_decoder *d;
00211 d = ccn_buf_decoder_start(&decoder, c->buf, c->length);
00212 return(ccn_parse_Name(d, components));
00213 }
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 int
00226 ccn_name_chop(struct ccn_charbuf *c, struct ccn_indexbuf *components, int n)
00227 {
00228 if (components == NULL) {
00229 int res;
00230 components = ccn_indexbuf_create();
00231 if (components == NULL)
00232 return(-1);
00233 res = ccn_name_split(c, components);
00234 if (res >= 0)
00235 res = ccn_name_chop(c, components, n);
00236 ccn_indexbuf_destroy(&components);
00237 return(res);
00238 }
00239
00240 if (components->n == 0 || components->buf[components->n-1] + 1 != c->length)
00241 if (ccn_name_split(c, components) < 0)
00242 return(-1);
00243 if (n < 0)
00244 n += (components->n - 1);
00245 if (n < 0)
00246 return(-1);
00247 if (n < components->n) {
00248 c->length = components->buf[n];
00249 ccn_charbuf_append_value(c, CCN_CLOSE, 1);
00250 components->n = n + 1;
00251 return(n);
00252 }
00253 return(-1);
00254 }
00255
00256
00257
00258
00259
00260
00261 int
00262 ccn_name_next_sibling(struct ccn_charbuf *c)
00263 {
00264 int res = -1;
00265 struct ccn_indexbuf *ndx;
00266 unsigned char *lastcomp = NULL;
00267 size_t lastcompsize = 0;
00268 size_t i;
00269 int carry;
00270 struct ccn_charbuf *newcomp;
00271
00272 ndx = ccn_indexbuf_create();
00273 if (ndx == NULL) goto Finish;
00274 res = ccn_name_split(c, ndx);
00275 if (res <= 0) {
00276 res = -1;
00277 goto Finish;
00278 }
00279 res = ccn_ref_tagged_BLOB(CCN_DTAG_Component, c->buf,
00280 ndx->buf[res-1], ndx->buf[res],
00281 (const unsigned char **)&lastcomp,
00282 &lastcompsize);
00283 if (res < 0) goto Finish;
00284 for (carry = 1, i = lastcompsize; carry && i > 0; i--) {
00285 carry = (((++lastcomp[i-1]) & 0xFF) == 0x00);
00286 }
00287 if (carry) {
00288 newcomp = ccn_charbuf_create();
00289 res |= ccn_charbuf_append_value(newcomp, 0, 1);
00290 res |= ccn_charbuf_append(newcomp, lastcomp, lastcompsize);
00291 res |= ccn_name_chop(c, ndx, ndx->n - 2);
00292 res |= ccn_name_append(c, newcomp->buf, newcomp->length);
00293 ccn_charbuf_destroy(&newcomp);
00294 if (res < 0) goto Finish;
00295 }
00296 res = ndx->n - 1;
00297 Finish:
00298 ccn_indexbuf_destroy(&ndx);
00299 return(res);
00300 }