summaryrefslogtreecommitdiffstats
path: root/lib/elstring.h
diff options
context:
space:
mode:
authorChris Hall <chris.hall@highwayman.com>2010-12-21 11:12:30 +0000
committerChris Hall <chris.hall@highwayman.com>2010-12-21 11:12:30 +0000
commit121f2f888e02a28e7896f84dde019cb320f0b11d (patch)
tree99c3913759b80894b1cb83a508036223b9c98f5a /lib/elstring.h
parentd475a0f198f880595eb27e44008e5de3aad25d73 (diff)
downloadquagga-121f2f888e02a28e7896f84dde019cb320f0b11d.tar.bz2
quagga-121f2f888e02a28e7896f84dde019cb320f0b11d.tar.xz
Creation of pipework branch
Diffstat (limited to 'lib/elstring.h')
-rw-r--r--lib/elstring.h354
1 files changed, 354 insertions, 0 deletions
diff --git a/lib/elstring.h b/lib/elstring.h
new file mode 100644
index 00000000..051e5962
--- /dev/null
+++ b/lib/elstring.h
@@ -0,0 +1,354 @@
+/* Length/String string handling -- header
+ * Copyright (C) 2009 Chris Hall (GMCH), Highwayman
+ *
+ * This file is part of GNU Zebra.
+ *
+ * GNU Zebra is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * GNU Zebra 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 GNU Zebra; see the file COPYING. If not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _ZEBRA_ELSTRING_H
+#define _ZEBRA_ELSTRING_H
+
+#include "misc.h"
+#include "zassert.h"
+#include "memory.h"
+
+/*==============================================================================
+ * This is some very simple support for strings which are Length/Body
+ * objects.
+ *
+ * NB: this object knows NOTHING about memory allocation etc. The objective
+ * is the simplest possible encapsulation of strings which are NOT '\0'
+ * terminated.
+ *
+ *
+ *
+ */
+struct elstring
+{
+ union
+ {
+ void* v ; /* may be NULL iff len == 0 */
+ const void* cv ;
+ } body ;
+
+ ulen len ;
+ bool term ; /* true <=> body is '\0' terminated */
+} ;
+
+typedef struct elstring elstring_t[1] ;
+typedef struct elstring* elstring ;
+
+/* Setting an elstring object to all zeros is enough to initialise it to
+ * an empty string.
+ */
+enum
+{
+ ELSTRING_INIT_ALL_ZEROS = true
+} ;
+
+/*------------------------------------------------------------------------------
+ * Various forms of body -- NB:
+ */
+
+Inline void*
+els_body_nn(elstring els)
+{
+ return els->body.v ;
+} ;
+
+Inline void*
+els_body(elstring els)
+{
+ return (els != NULL) ? els_body_nn(els) : NULL ;
+} ;
+
+Inline ulen
+els_len_nn(elstring els)
+{
+ return els->len ;
+} ;
+
+Inline ulen
+els_len(elstring els)
+{
+ return (els != NULL) ? els_len_nn(els) : 0 ;
+} ;
+
+Inline bool
+els_term_nn(elstring els)
+{
+ return els->term ;
+} ;
+
+Inline bool
+els_term(elstring els)
+{
+ return (els != NULL) ? els_term_nn(els) : false ;
+} ;
+
+/*==============================================================================
+ * All so simple that everything is implemented as Inline
+ */
+
+/*------------------------------------------------------------------------------
+ * Initialise or create a new elstring
+ */
+Inline elstring
+els_init_new(elstring els)
+{
+ if (els == NULL)
+ els = XCALLOC(MTYPE_TMP, sizeof(elstring_t)) ;
+ else
+ memset(els, 0, sizeof(elstring_t)) ;
+
+ confirm(ELSTRING_INIT_ALL_ZEROS) ;
+
+ return els ;
+} ;
+
+/*------------------------------------------------------------------------------
+ * Set elstring value from ordinary string.
+ *
+ * NB: elstring MUST NOT be NULL.
+ *
+ * NB: treats str == NULL as a zero length string.
+ *
+ * NB: sets "term" unless str == NULL.
+ */
+Inline void
+els_set_nn(elstring els, const void* str)
+{
+ els->body.cv = str ;
+ els->len = (str != NULL) ? strlen(str) : 0 ;
+ els->term = (str != NULL) ;
+} ;
+
+/*------------------------------------------------------------------------------
+ * Set elstring value from ordinary string.
+ *
+ * Creates elstring object if required (ie if els == NULL).
+ *
+ * See: els_set_nn.
+ */
+Inline elstring
+els_set(elstring els, const void* str)
+{
+ if (els == NULL)
+ els = XCALLOC(MTYPE_TMP, sizeof(elstring_t)) ;
+
+ els_set_nn(els, str) ;
+
+ return els ;
+} ;
+
+/*------------------------------------------------------------------------------
+ * Set elstring value from body + length.
+ *
+ * NB: sets term = false.
+ *
+ * NB: elstring MUST NOT be NULL.
+ *
+ * NB: treats str == NULL as a zero length string.
+ */
+Inline void
+els_set_n_nn(elstring els, const void* body, ulen len)
+{
+ els->body.cv = body ;
+ els->len = len ;
+ els->term = false ;
+} ;
+
+/*------------------------------------------------------------------------------
+ * Set elstring value from body + length.
+ *
+ * Creates elstring object if required (ie if els == NULL).
+ *
+ * See els_set_n_nn.
+ */
+Inline elstring
+els_set_n(elstring els, const void* body, ulen len)
+{
+ if (els == NULL)
+ els = XCALLOC(MTYPE_TMP, sizeof(elstring_t)) ;
+
+ els_set_n_nn(els, body, len) ;
+
+ return els ;
+} ;
+
+/*------------------------------------------------------------------------------
+ * Clear contents of an elstring (if any)
+ *
+ * NB: it is the callers responsibility to free the contents of the elstring.
+ * if that is required, before freeing the elstring itself.
+ */
+Inline void
+els_clear(elstring els)
+{
+ if (els != NULL)
+ {
+ els->body.v = NULL ;
+ els->len = 0 ;
+ els->term = false ;
+ } ;
+} ;
+
+/*------------------------------------------------------------------------------
+ * Release dynamically allocated elstring.
+ *
+ * Returns NULL.
+ *
+ * NB: it is the callers responsibility to free the contents of the elstring.
+ * if that is required, before freeing the elstring itself.
+ */
+Inline elstring
+els_free(elstring els)
+{
+ if (els != NULL)
+ XFREE(MTYPE_TMP, els) ;
+
+ return NULL ;
+} ;
+
+/*------------------------------------------------------------------------------
+ * Set elstring length. And set term false.
+ *
+ * NB: it is the caller's responsibility to set a valid length !!
+ *
+ * NB: elstring MUST NOT be NULL.
+ */
+Inline void
+els_set_len_nn(elstring els, ulen len)
+{
+ els->len = len ;
+ els->term = false ;
+} ;
+
+/*------------------------------------------------------------------------------
+ * Set elstring body. And set term false.
+ *
+ * NB: it is the caller's responsibility to set a valid body !!
+ *
+ * NB: elstring MUST NOT be NULL.
+ */
+Inline void
+els_set_body_nn(elstring els, const void* body)
+{
+ els->body.cv = body ;
+ els->term = false ;
+} ;
+
+/*------------------------------------------------------------------------------
+ * Set elstring terminated.
+ *
+ * NB: it is the caller's responsibility to set a valid body !!
+ *
+ * NB: elstring MUST NOT be NULL.
+ */
+Inline void
+els_set_term_nn(elstring els, bool term)
+{
+ els->term = term ;
+} ;
+
+/*------------------------------------------------------------------------------
+ * Compare two elstrings -- returns the usual -ve, 0, +ve cmp result.
+ */
+Inline int
+els_cmp(elstring a, elstring b)
+{
+ const uchar* ap ;
+ const uchar* bp ;
+ ulen al, bl ;
+ ulen n ;
+
+ ap = els_body(a) ;
+ bp = els_body(b) ;
+ al = els_len(a) ;
+ bl = els_len(b) ;
+
+ n = (al <= bl) ? al : bl ;
+
+ while (n)
+ {
+ int d = *ap++ - *bp++ ;
+ if (d != 0)
+ return d ;
+ --n ;
+ } ;
+
+ return al < bl ? -1 : (al == bl) ? 0 : +1 ;
+} ;
+
+/*------------------------------------------------------------------------------
+ * Are two elstrings equal ? -- returns true if strings equal.
+ */
+Inline bool
+els_equal(elstring a, elstring b)
+{
+ const uchar* ap ;
+ const uchar* bp ;
+ ulen n ;
+
+ n = els_len(b) ;
+ if (n != els_len(a))
+ return false ;
+
+ ap = els_body(a) ;
+ bp = els_body(b) ;
+
+ while (n)
+ {
+ if (*ap++ != *bp++)
+ return false ;
+ --n ;
+ } ;
+
+ return true ;
+} ;
+
+/*------------------------------------------------------------------------------
+ * Is 'b' a leading substring of 'a' ? -- returns true if it is.
+ *
+ * If 'b' is empty it is always a leading substring.
+ */
+Inline int
+els_substring(elstring a, elstring b)
+{
+ const uchar* ap ;
+ const uchar* bp ;
+ ulen n ;
+
+ n = els_len(b) ;
+ if (n > els_len(a))
+ return false ;
+
+ ap = els_body(a) ;
+ bp = els_body(b) ;
+
+ while (n)
+ {
+ if (*ap++ != *bp++)
+ return false ;
+ --n ;
+ } ;
+
+ return true ;
+} ;
+
+#endif /* _ZEBRA_ELSTRING_H */
+