summaryrefslogtreecommitdiff
path: root/node/Dictionary.hpp
diff options
context:
space:
mode:
authorAdam Ierymenko <adam.ierymenko@zerotier.com>2018-04-25 06:39:02 -0700
committerGitHub <noreply@github.com>2018-04-25 06:39:02 -0700
commit42ec780a6f6eedef4d8b1d8218bd72fc6ed75cc0 (patch)
tree7bf86c4d92d6a0f77eced79bfc33313c62c7b6dd /node/Dictionary.hpp
parent18c9dc8a0649c866eff9f299f20fa5b19c502e52 (diff)
parent4608880fb06700822d01e9e5d6729fcdeb82b64b (diff)
downloadinfinitytier-42ec780a6f6eedef4d8b1d8218bd72fc6ed75cc0.tar.gz
infinitytier-42ec780a6f6eedef4d8b1d8218bd72fc6ed75cc0.zip
Merge branch 'dev' into netbsd-support
Diffstat (limited to 'node/Dictionary.hpp')
-rw-r--r--node/Dictionary.hpp157
1 files changed, 76 insertions, 81 deletions
diff --git a/node/Dictionary.hpp b/node/Dictionary.hpp
index 59fc4bbf..f89b6ffc 100644
--- a/node/Dictionary.hpp
+++ b/node/Dictionary.hpp
@@ -1,6 +1,6 @@
/*
* ZeroTier One - Network Virtualization Everywhere
- * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
+ * Copyright (C) 2011-2018 ZeroTier, Inc. https://www.zerotier.com/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -14,6 +14,14 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * --
+ *
+ * You can be released from the requirements of the license by purchasing
+ * a commercial license. Buying such a license is mandatory as soon as you
+ * develop commercial closed-source software that incorporates or links
+ * directly against ZeroTier software without disclosing the source code
+ * of your own application.
*/
#ifndef ZT_DICTIONARY_HPP
@@ -54,35 +62,29 @@ template<unsigned int C>
class Dictionary
{
public:
- Dictionary()
- {
- _d[0] = (char)0;
- }
-
- Dictionary(const char *s)
- {
- Utils::scopy(_d,sizeof(_d),s);
- }
-
+ Dictionary() { memset(_d,0,sizeof(_d)); }
+ Dictionary(const char *s) { this->load(s); }
Dictionary(const char *s,unsigned int len)
{
- if (len > (C-1))
- len = C-1;
- memcpy(_d,s,len);
- _d[len] = (char)0;
- }
-
- Dictionary(const Dictionary &d)
- {
- Utils::scopy(_d,sizeof(_d),d._d);
+ for(unsigned int i=0;i<C;++i) {
+ if ((s)&&(i < len)) {
+ if (!(_d[i] = *s))
+ s = (const char *)0;
+ else ++s;
+ } else _d[i] = (char)0;
+ }
+ _d[C - 1] = (char)0;
}
+ Dictionary(const Dictionary &d) { memcpy(_d,d._d,C); }
inline Dictionary &operator=(const Dictionary &d)
{
- Utils::scopy(_d,sizeof(_d),d._d);
+ memcpy(_d,d._d,C);
return *this;
}
+ inline operator bool() const { return (_d[0] != 0); }
+
/**
* Load a dictionary from a C-string
*
@@ -91,7 +93,15 @@ public:
*/
inline bool load(const char *s)
{
- return Utils::scopy(_d,sizeof(_d),s);
+ for(unsigned int i=0;i<C;++i) {
+ if (s) {
+ if (!(_d[i] = *s))
+ s = (const char *)0;
+ else ++s;
+ } else _d[i] = (char)0;
+ }
+ _d[C - 1] = (char)0;
+ return (!s);
}
/**
@@ -99,7 +109,7 @@ public:
*/
inline void clear()
{
- _d[0] = (char)0;
+ memset(_d,0,sizeof(_d));
}
/**
@@ -163,12 +173,12 @@ public:
j = 0;
esc = false;
++p;
- while ((*p != 0)&&(*p != '\r')&&(*p != '\n')) {
+ while ((*p != 0)&&(*p != 13)&&(*p != 10)) {
if (esc) {
esc = false;
switch(*p) {
- case 'r': dest[j++] = '\r'; break;
- case 'n': dest[j++] = '\n'; break;
+ case 'r': dest[j++] = 13; break;
+ case 'n': dest[j++] = 10; break;
case '0': dest[j++] = (char)0; break;
case 'e': dest[j++] = '='; break;
default: dest[j++] = *p; break;
@@ -194,7 +204,7 @@ public:
dest[j] = (char)0;
return j;
} else {
- while ((*p)&&(*p != '\r')&&(*p != '\n')) {
+ while ((*p)&&(*p != 13)&&(*p != 10)) {
if (++p == eof) {
dest[0] = (char)0;
return -1;
@@ -266,6 +276,21 @@ public:
}
/**
+ * Get an unsigned int64 stored as hex in the dictionary
+ *
+ * @param key Key to look up
+ * @param dfl Default value or 0 if unspecified
+ * @return Decoded hex UInt value or 'dfl' if not found
+ */
+ inline int64_t getI(const char *key,int64_t dfl = 0) const
+ {
+ char tmp[128];
+ if (this->get(key,tmp,sizeof(tmp)) >= 1)
+ return Utils::hexStrTo64(tmp);
+ return dfl;
+ }
+
+ /**
* Add a new key=value pair
*
* If the key is already present this will append another, but the first
@@ -286,7 +311,7 @@ public:
unsigned int j = i;
if (j > 0) {
- _d[j++] = '\n';
+ _d[j++] = (char)10;
if (j == C) {
_d[i] = (char)0;
return false;
@@ -313,8 +338,8 @@ public:
while ( ((vlen < 0)&&(*p)) || (k < vlen) ) {
switch(*p) {
case 0:
- case '\r':
- case '\n':
+ case 13:
+ case 10:
case '\\':
case '=':
_d[j++] = '\\';
@@ -324,8 +349,8 @@ public:
}
switch(*p) {
case 0: _d[j++] = '0'; break;
- case '\r': _d[j++] = 'r'; break;
- case '\n': _d[j++] = 'n'; break;
+ case 13: _d[j++] = 'r'; break;
+ case 10: _d[j++] = 'n'; break;
case '\\': _d[j++] = '\\'; break;
case '=': _d[j++] = 'e'; break;
}
@@ -368,8 +393,21 @@ public:
inline bool add(const char *key,uint64_t value)
{
char tmp[32];
- Utils::snprintf(tmp,sizeof(tmp),"%llx",(unsigned long long)value);
- return this->add(key,tmp,-1);
+ return this->add(key,Utils::hex(value,tmp),-1);
+ }
+
+ /**
+ * Add a 64-bit integer (unsigned) as a hex value
+ */
+ inline bool add(const char *key,int64_t value)
+ {
+ char tmp[32];
+ if (value >= 0) {
+ return this->add(key,Utils::hex((uint64_t)value,tmp),-1);
+ } else {
+ tmp[0] = '-';
+ return this->add(key,Utils::hex((uint64_t)(value * -1),tmp+1),-1);
+ }
}
/**
@@ -378,8 +416,7 @@ public:
inline bool add(const char *key,const Address &a)
{
char tmp[32];
- Utils::snprintf(tmp,sizeof(tmp),"%.10llx",(unsigned long long)a.toInt());
- return this->add(key,tmp,-1);
+ return this->add(key,Utils::hex(a.toInt(),tmp),-1);
}
/**
@@ -404,55 +441,13 @@ public:
}
/**
- * Erase a key from this dictionary
- *
- * Use this before add() to ensure that a key is replaced if it might
- * already be present.
- *
- * @param key Key to erase
- * @return True if key was found and erased
- */
- inline bool erase(const char *key)
- {
- char d2[C];
- char *saveptr = (char *)0;
- unsigned int d2ptr = 0;
- bool found = false;
- for(char *f=Utils::stok(_d,"\r\n",&saveptr);(f);f=Utils::stok((char *)0,"\r\n",&saveptr)) {
- if (*f) {
- const char *p = f;
- const char *k = key;
- while ((*k)&&(*p)) {
- if (*k != *p)
- break;
- ++k;
- ++p;
- }
- if (*k) {
- p = f;
- while (*p)
- d2[d2ptr++] = *(p++);
- d2[d2ptr++] = '\n';
- } else {
- found = true;
- }
- }
- }
- d2[d2ptr++] = (char)0;
- memcpy(_d,d2,d2ptr);
- return found;
- }
-
- /**
- * @return Dictionary data as a 0-terminated C-string
- */
- inline const char *data() const { return _d; }
-
- /**
* @return Value of C template parameter
*/
inline unsigned int capacity() const { return C; }
+ inline const char *data() const { return _d; }
+ inline char *unsafeData() { return _d; }
+
private:
char _d[C];
};