Small source movements (ccn_* to ccn/). Small change of NameBuilder implementation
diff --git a/model/ccn/ccn_name_util.c b/model/ccn/ccn_name_util.c
new file mode 100644
index 0000000..94f3991
--- /dev/null
+++ b/model/ccn/ccn_name_util.c
@@ -0,0 +1,326 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2011 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
+ */
+
+#include "ccn_name_util.h"
+#include "ccn_coding.h"
+#include "ccn_charbuf.h"
+#include "ccn_indexbuf.h"
+#include <string.h>
+#include <stdlib.h>
+#include "ccn_random.h"
+#include "ccn.h"
+
+/**
+ * @file ccn_name_util.c
+ * @brief Support for manipulating ccnb-encoded Names.
+ *
+ * Part of the CCNx C Library.
+ *
+ * Copyright (C) 2008-2010 Palo Alto Research Center, Inc.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details. You should have received
+ * a copy of the GNU Lesser General Public License along with this library;
+ * if not, write to the Free Software Foundation, Inc., 51 Franklin Street,
+ * Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+//#include <ccn/ccn.h>
+
+/**
+ * Reset charbuf to represent an empty Name in binary format.
+ * @returns 0, or -1 for error.
+ */
+int
+ccn_name_init(struct ccn_charbuf *c)
+{
+ int res;
+ c->length = 0;
+ res = ccn_charbuf_append_tt(c, CCN_DTAG_Name, CCN_DTAG);
+ if (res == -1) return(res);
+ res = ccn_charbuf_append_closer(c);
+ return(res);
+}
+
+/**
+ * Add a Component to a Name.
+ *
+ * The component is an arbitrary string of n octets, no escaping required.
+ * @returns 0, or -1 for error.
+ */
+int
+ccn_name_append(struct ccn_charbuf *c, const void *component, size_t n)
+{
+ int res;
+ const unsigned char closer[2] = {CCN_CLOSE, CCN_CLOSE};
+ if (c->length < 2 || c->buf[c->length-1] != closer[1])
+ return(-1);
+ c->length -= 1;
+ ccn_charbuf_reserve(c, n + 8);
+ res = ccn_charbuf_append_tt(c, CCN_DTAG_Component, CCN_DTAG);
+ if (res == -1) return(res);
+ res = ccn_charbuf_append_tt(c, n, CCN_BLOB);
+ if (res == -1) return(res);
+ res = ccn_charbuf_append(c, component, n);
+ if (res == -1) return(res);
+ res = ccn_charbuf_append(c, closer, sizeof(closer));
+ return(res);
+}
+
+/**
+ * Add a Component that is a NUL-terminated string.
+ *
+ * The component added consists of the bytes of the string without the NUL.
+ * This function is convenient for those applications that construct
+ * component names from simple strings.
+ * @returns 0, or -1 for error.
+ */
+int
+ccn_name_append_str(struct ccn_charbuf *c, const char *s)
+{
+ return(ccn_name_append(c, s, strlen(s)));
+}
+
+/**
+ * Add a binary Component to a ccnb-encoded Name
+ *
+ * These are special components used for marking versions, fragments, etc.
+ * @returns 0, or -1 for error
+ * see doc/technical/NameConventions.html
+ */
+int
+ccn_name_append_numeric(struct ccn_charbuf *c,
+ enum ccn_marker marker, unsigned long long value)
+{
+ //uintmax_t v;
+ unsigned long long v;
+ int i;
+ char b[32];
+
+ for (v = value, i = sizeof(b); v != 0 && i > 0; i--, v >>= 8)
+ b[i-1] = v & 0xff;
+ if (i < 1)
+ return(-1);
+ if (marker >= 0)
+ b[--i] = marker;
+ return(ccn_name_append(c, b + i, sizeof(b) - i));
+}
+
+/**
+ * Add nonce Component to ccnb-encoded Name
+ *
+ * Uses %C1.N namespace.
+ * @returns 0, or -1 for error
+ * see doc/technical/NameConventions.html
+ */
+int
+ccn_name_append_nonce(struct ccn_charbuf *c)
+{
+ const unsigned char pre[4] = { CCN_MARKER_CONTROL, '.', 'N', 0 };
+ unsigned char b[15];
+
+ memcpy(b, pre, sizeof(pre));
+ ccn_random_bytes(b + sizeof(pre), sizeof(b) - sizeof(pre));
+ return(ccn_name_append(c, b, sizeof(b)));
+}
+
+/**
+ * Add sequence of ccnb-encoded Components to a ccnb-encoded Name.
+ *
+ * start and stop are offsets from ccnb
+ * @returns 0, or -1 for obvious error
+ */
+int
+ccn_name_append_components(struct ccn_charbuf *c,
+ const unsigned char *ccnb,
+ size_t start, size_t stop)
+{
+ int res;
+ if (c->length < 2 || start > stop)
+ return(-1);
+ c->length -= 1;
+ ccn_charbuf_reserve(c, stop - start + 1);
+ res = ccn_charbuf_append(c, ccnb + start, stop - start);
+ if (res == -1) return(res);
+ res = ccn_charbuf_append_closer(c);
+ return(res);
+}
+
+/**
+ * Extract a pointer to and size of component at
+ * given index i. The first component is index 0.
+ * @returns 0, or -1 for error.
+ */
+int
+ccn_name_comp_get(const unsigned char *data,
+ const struct ccn_indexbuf *indexbuf,
+ unsigned int i,
+ const unsigned char **comp, size_t *size)
+{
+ int len;
+ struct ccn_buf_decoder decoder;
+ struct ccn_buf_decoder *d;
+ /* indexbuf should have an extra value marking end of last component,
+ so we need to use last 2 values */
+ if (indexbuf->n < 2 || i > indexbuf->n - 2) {
+ /* There isn't a component at this index */
+ return(-1);
+ }
+ len = indexbuf->buf[i + 1]-indexbuf->buf[i];
+ d = ccn_buf_decoder_start(&decoder, data + indexbuf->buf[i], len);
+ if (ccn_buf_match_dtag(d, CCN_DTAG_Component)) {
+ ccn_buf_advance(d);
+ if (ccn_buf_match_blob(d, comp, size))
+ return(0);
+ *comp = d->buf + d->decoder.index;
+ *size = 0;
+ ccn_buf_check_close(d);
+ if (d->decoder.state >= 0)
+ return(0);
+ }
+ return(-1);
+}
+
+int
+ccn_name_comp_strcmp(const unsigned char *data,
+ const struct ccn_indexbuf *indexbuf,
+ unsigned int i, const char *val)
+{
+ const unsigned char *comp_ptr;
+ size_t comp_size;
+
+ // XXX - We probably want somewhat different semantics in the API -
+ // comparing a string against a longer string with a 0 byte should
+ // not claim equality.
+ if (ccn_name_comp_get(data, indexbuf, i, &comp_ptr, &comp_size) == 0)
+ return(strncmp(val, (const char *)comp_ptr, comp_size));
+ /* Probably no such component, say query is greater-than */
+ return(1);
+}
+
+/**
+ * Find Component boundaries in a ccnb-encoded Name.
+ *
+ * Thin veneer over ccn_parse_Name().
+ * components arg may be NULL to just do a validity check
+ *
+ * @returns -1 for error, otherwise the number of Components.
+ */
+int
+ccn_name_split(const struct ccn_charbuf *c, struct ccn_indexbuf *components)
+{
+ struct ccn_buf_decoder decoder;
+ struct ccn_buf_decoder *d;
+ d = ccn_buf_decoder_start(&decoder, c->buf, c->length);
+ return(ccn_parse_Name(d, components));
+}
+
+/**
+ * Chop the name down to n components.
+ * @param c contains a ccnb-encoded Name
+ * @param components may be NULL; if provided it must be consistent with
+ * some prefix of the name, and is updated accordingly.
+ * @param n is the number or components to leave, or, if negative, specifies
+ * how many components to remove,
+ e.g. -1 will remove just the last component.
+ * @returns -1 for error, otherwise the new number of Components
+ */
+int
+ccn_name_chop(struct ccn_charbuf *c, struct ccn_indexbuf *components, int n)
+{
+ if (components == NULL) {
+ int res;
+ components = ccn_indexbuf_create();
+ if (components == NULL)
+ return(-1);
+ res = ccn_name_split(c, components);
+ if (res >= 0)
+ res = ccn_name_chop(c, components, n);
+ ccn_indexbuf_destroy(&components);
+ return(res);
+ }
+ /* Fix up components if needed. We could be a little smarter about this. */
+ if (components->n == 0 || components->buf[components->n-1] + 1 != c->length)
+ if (ccn_name_split(c, components) < 0)
+ return(-1);
+ if (n < 0)
+ n += (components->n - 1); /* APL-style indexing */
+ if (n < 0)
+ return(-1);
+ if (n < (int)(components->n)) {
+ c->length = components->buf[n];
+ ccn_charbuf_append_value(c, CCN_CLOSE, 1);
+ components->n = n + 1;
+ return(n);
+ }
+ return(-1);
+}
+
+/**
+ * Advance the last Component of a Name to the next possible value.
+ * @param c contains a ccnb-encoded Name to be updated.
+ * @returns -1 for error, otherwise the number of Components
+ */
+int
+ccn_name_next_sibling(struct ccn_charbuf *c)
+{
+ int res = -1;
+ struct ccn_indexbuf *ndx;
+ unsigned char *lastcomp = NULL;
+ size_t lastcompsize = 0;
+ size_t i;
+ int carry;
+ struct ccn_charbuf *newcomp;
+
+ ndx = ccn_indexbuf_create();
+ if (ndx == NULL) goto Finish;
+ res = ccn_name_split(c, ndx);
+ if (res <= 0) {
+ res = -1;
+ goto Finish;
+ }
+ res = ccn_ref_tagged_BLOB(CCN_DTAG_Component, c->buf,
+ ndx->buf[res-1], ndx->buf[res],
+ (const unsigned char **)&lastcomp,
+ &lastcompsize);
+ if (res < 0) goto Finish;
+ for (carry = 1, i = lastcompsize; carry && i > 0; i--) {
+ carry = (((++lastcomp[i-1]) & 0xFF) == 0x00);
+ }
+ if (carry) {
+ newcomp = ccn_charbuf_create();
+ res |= ccn_charbuf_append_value(newcomp, 0, 1);
+ res |= ccn_charbuf_append(newcomp, lastcomp, lastcompsize);
+ res |= ccn_name_chop(c, ndx, ndx->n - 2);
+ res |= ccn_name_append(c, newcomp->buf, newcomp->length);
+ ccn_charbuf_destroy(&newcomp);
+ if (res < 0) goto Finish;
+ }
+ res = ndx->n - 1;
+Finish:
+ ccn_indexbuf_destroy(&ndx);
+ return(res);
+}
+