ccn_reg_mgmt.c

Go to the documentation of this file.
00001 /**
00002  * @file ccn_reg_mgmt.c
00003  * @brief Support for parsing and creating ForwardingEntry elements.
00004  * 
00005  * Part of the CCNx C Library.
00006  *
00007  * Copyright (C) 2009 Palo Alto Research Center, Inc.
00008  *
00009  * This library is free software; you can redistribute it and/or modify it
00010  * under the terms of the GNU Lesser General Public License version 2.1
00011  * as published by the Free Software Foundation.
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00015  * Lesser General Public License for more details. You should have received
00016  * a copy of the GNU Lesser General Public License along with this library;
00017  * if not, write to the Free Software Foundation, Inc., 51 Franklin Street,
00018  * Fifth Floor, Boston, MA 02110-1301 USA.
00019  */
00020 #include <stddef.h>
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023 #include <string.h>
00024 
00025 #include <ccn/ccn.h>
00026 #include <ccn/charbuf.h>
00027 #include <ccn/reg_mgmt.h>
00028 
00029 struct ccn_forwarding_entry *
00030 ccn_forwarding_entry_parse(const unsigned char *p, size_t size)
00031 {
00032     struct ccn_buf_decoder decoder;
00033     struct ccn_buf_decoder *d = ccn_buf_decoder_start(&decoder, p, size);
00034     struct ccn_charbuf *store = ccn_charbuf_create();
00035     struct ccn_forwarding_entry *result;
00036     const unsigned char *val;
00037     size_t sz;
00038     size_t start;
00039     size_t end;
00040     int action_off = -1;
00041     int ccnd_id_off = -1;
00042     
00043     if (store == NULL)
00044         return(NULL);
00045     result = calloc(1, sizeof(*result));
00046     if (result == NULL) {
00047         ccn_charbuf_destroy(&store);
00048         return(NULL);
00049     }
00050     if (ccn_buf_match_dtag(d, CCN_DTAG_ForwardingEntry)) {
00051         ccn_buf_advance(d);
00052         action_off = ccn_parse_tagged_string(d, CCN_DTAG_Action, store);
00053         if (ccn_buf_match_dtag(d, CCN_DTAG_Name)) {
00054             result->name_prefix = ccn_charbuf_create();
00055             start = d->decoder.token_index;
00056             ccn_parse_Name(d, NULL);
00057             end = d->decoder.token_index;
00058             ccn_charbuf_append(result->name_prefix, p + start, end - start);
00059         }
00060         else
00061             result->name_prefix = NULL;
00062         if (ccn_buf_match_dtag(d, CCN_DTAG_PublisherPublicKeyDigest)) {
00063             ccn_buf_advance(d);
00064             if (ccn_buf_match_blob(d, &val, &sz)) {
00065                 ccn_buf_advance(d);
00066                 if (sz != 32)
00067                     d->decoder.state = -__LINE__;
00068             }
00069             ccn_buf_check_close(d);
00070             if (d->decoder.state >= 0) {
00071                 ccnd_id_off = store->length;
00072                 ccn_charbuf_append(store, val, sz);
00073                 result->ccnd_id_size = sz;
00074             }
00075         }
00076         result->faceid = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_FaceID);
00077         result->flags = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_ForwardingFlags);
00078         result->lifetime = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_FreshnessSeconds);
00079         ccn_buf_check_close(d);
00080     }
00081     else
00082         d->decoder.state = -__LINE__;
00083     
00084     if (d->decoder.index != size || !CCN_FINAL_DSTATE(d->decoder.state) ||
00085         store->length > sizeof(result->store))
00086         ccn_forwarding_entry_destroy(&result);
00087     else {
00088         char *b = (char *)result->store;
00089         memcpy(b, store->buf, store->length);
00090         result->action = (action_off == -1) ? NULL : b + action_off;
00091         result->ccnd_id = (ccnd_id_off == -1) ? NULL : result->store + ccnd_id_off;
00092     }
00093     ccn_charbuf_destroy(&store);
00094     return(result);
00095 }
00096 
00097 /**
00098  * Destroy the result of ccn_forwarding_entry_parse().
00099  */
00100 void
00101 ccn_forwarding_entry_destroy(struct ccn_forwarding_entry **pfe)
00102 {
00103     if (*pfe == NULL)
00104         return;
00105     ccn_charbuf_destroy(&(*pfe)->name_prefix);
00106     free(*pfe);
00107     *pfe = NULL;
00108 }
00109 
00110 int
00111 ccnb_append_forwarding_entry(struct ccn_charbuf *c,
00112                              const struct ccn_forwarding_entry *fe)
00113 {
00114     int res;
00115     res = ccnb_element_begin(c, CCN_DTAG_ForwardingEntry);
00116     if (fe->action != NULL)
00117         res |= ccnb_tagged_putf(c, CCN_DTAG_Action, "%s",
00118                                    fe->action);
00119     if (fe->name_prefix != NULL && fe->name_prefix->length > 0)
00120         res |= ccn_charbuf_append(c, fe->name_prefix->buf,
00121                                      fe->name_prefix->length);
00122     if (fe->ccnd_id_size != 0)
00123         res |= ccnb_append_tagged_blob(c, CCN_DTAG_PublisherPublicKeyDigest,
00124                                           fe->ccnd_id, fe->ccnd_id_size);
00125     if (fe->faceid != ~0)
00126         res |= ccnb_tagged_putf(c, CCN_DTAG_FaceID, "%u",
00127                                    fe->faceid);
00128     if (fe->flags >= 0)
00129         res |= ccnb_tagged_putf(c, CCN_DTAG_ForwardingFlags, "%d",
00130                                    fe->flags);
00131     if (fe->lifetime >= 0)
00132         res |= ccnb_tagged_putf(c, CCN_DTAG_FreshnessSeconds, "%d",
00133                                    fe->lifetime);
00134     res |= ccnb_element_end(c);
00135     return(res);
00136 }
Generated on Fri May 13 16:27:03 2011 for Content-Centric Networking in C by  doxygen 1.6.3