|
@@ -26,9 +26,6 @@
|
|
|
|
|
|
#include <stdint.h>
|
|
#include <stdint.h>
|
|
|
|
|
|
-// Can be increased if it's ever needed, but not too much.
|
|
|
|
-#define ZT_DICTIONARY_MAX_SIZE 8194
|
|
|
|
-
|
|
|
|
namespace ZeroTier {
|
|
namespace ZeroTier {
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -48,7 +45,10 @@ namespace ZeroTier {
|
|
*
|
|
*
|
|
* There is code to test and fuzz this in selftest.cpp. Fuzzing a blob of
|
|
* There is code to test and fuzz this in selftest.cpp. Fuzzing a blob of
|
|
* pointer tricks like this is important after any modifications.
|
|
* pointer tricks like this is important after any modifications.
|
|
|
|
+ *
|
|
|
|
+ * @tparam C Dictionary max capacity in bytes
|
|
*/
|
|
*/
|
|
|
|
+template<unsigned int C>
|
|
class Dictionary
|
|
class Dictionary
|
|
{
|
|
{
|
|
public:
|
|
public:
|
|
@@ -64,8 +64,8 @@ public:
|
|
|
|
|
|
Dictionary(const char *s,unsigned int len)
|
|
Dictionary(const char *s,unsigned int len)
|
|
{
|
|
{
|
|
- memcpy(_d,s,(len > ZT_DICTIONARY_MAX_SIZE) ? (unsigned int)ZT_DICTIONARY_MAX_SIZE : len);
|
|
|
|
- _d[ZT_DICTIONARY_MAX_SIZE-1] = (char)0;
|
|
|
|
|
|
+ memcpy(_d,s,(len > C) ? (unsigned int)C : len);
|
|
|
|
+ _d[C-1] = (char)0;
|
|
}
|
|
}
|
|
|
|
|
|
Dictionary(const Dictionary &d)
|
|
Dictionary(const Dictionary &d)
|
|
@@ -83,7 +83,7 @@ public:
|
|
* Load a dictionary from a C-string
|
|
* Load a dictionary from a C-string
|
|
*
|
|
*
|
|
* @param s Dictionary in string form
|
|
* @param s Dictionary in string form
|
|
- * @return False if 's' was longer than ZT_DICTIONARY_MAX_SIZE
|
|
|
|
|
|
+ * @return False if 's' was longer than our capacity
|
|
*/
|
|
*/
|
|
inline bool load(const char *s)
|
|
inline bool load(const char *s)
|
|
{
|
|
{
|
|
@@ -103,11 +103,11 @@ public:
|
|
*/
|
|
*/
|
|
inline unsigned int sizeBytes() const
|
|
inline unsigned int sizeBytes() const
|
|
{
|
|
{
|
|
- for(unsigned int i=0;i<ZT_DICTIONARY_MAX_SIZE;++i) {
|
|
|
|
|
|
+ for(unsigned int i=0;i<C;++i) {
|
|
if (!_d[i])
|
|
if (!_d[i])
|
|
return i;
|
|
return i;
|
|
}
|
|
}
|
|
- return ZT_DICTIONARY_MAX_SIZE;
|
|
|
|
|
|
+ return C;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -194,9 +194,10 @@ public:
|
|
* @param key Key to get
|
|
* @param key Key to get
|
|
* @param dest Destination buffer
|
|
* @param dest Destination buffer
|
|
* @return True if key was found (if false, dest will be empty)
|
|
* @return True if key was found (if false, dest will be empty)
|
|
|
|
+ * @tparam BC Buffer capacity (usually inferred)
|
|
*/
|
|
*/
|
|
- template<unsigned int C>
|
|
|
|
- inline bool get(const char *key,Buffer<C> &dest) const
|
|
|
|
|
|
+ template<unsigned int BC>
|
|
|
|
+ inline bool get(const char *key,Buffer<BC> &dest) const
|
|
{
|
|
{
|
|
const int r = this->get(key,const_cast<char *>(reinterpret_cast<const char *>(dest.data())),C);
|
|
const int r = this->get(key,const_cast<char *>(reinterpret_cast<const char *>(dest.data())),C);
|
|
if (r >= 0) {
|
|
if (r >= 0) {
|
|
@@ -254,13 +255,13 @@ public:
|
|
*/
|
|
*/
|
|
inline bool add(const char *key,const char *value,int vlen = -1)
|
|
inline bool add(const char *key,const char *value,int vlen = -1)
|
|
{
|
|
{
|
|
- for(unsigned int i=0;i<ZT_DICTIONARY_MAX_SIZE;++i) {
|
|
|
|
|
|
+ for(unsigned int i=0;i<C;++i) {
|
|
if (!_d[i]) {
|
|
if (!_d[i]) {
|
|
unsigned int j = i;
|
|
unsigned int j = i;
|
|
|
|
|
|
if (j > 0) {
|
|
if (j > 0) {
|
|
_d[j++] = '\n';
|
|
_d[j++] = '\n';
|
|
- if (j == ZT_DICTIONARY_MAX_SIZE) {
|
|
|
|
|
|
+ if (j == C) {
|
|
_d[i] = (char)0;
|
|
_d[i] = (char)0;
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
@@ -269,14 +270,14 @@ public:
|
|
const char *p = key;
|
|
const char *p = key;
|
|
while (*p) {
|
|
while (*p) {
|
|
_d[j++] = *(p++);
|
|
_d[j++] = *(p++);
|
|
- if (j == ZT_DICTIONARY_MAX_SIZE) {
|
|
|
|
|
|
+ if (j == C) {
|
|
_d[i] = (char)0;
|
|
_d[i] = (char)0;
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
_d[j++] = '=';
|
|
_d[j++] = '=';
|
|
- if (j == ZT_DICTIONARY_MAX_SIZE) {
|
|
|
|
|
|
+ if (j == C) {
|
|
_d[i] = (char)0;
|
|
_d[i] = (char)0;
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
@@ -291,7 +292,7 @@ public:
|
|
case '\\':
|
|
case '\\':
|
|
case '=':
|
|
case '=':
|
|
_d[j++] = '\\';
|
|
_d[j++] = '\\';
|
|
- if (j == ZT_DICTIONARY_MAX_SIZE) {
|
|
|
|
|
|
+ if (j == C) {
|
|
_d[i] = (char)0;
|
|
_d[i] = (char)0;
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
@@ -302,14 +303,14 @@ public:
|
|
case '\\': _d[j++] = '\\'; break;
|
|
case '\\': _d[j++] = '\\'; break;
|
|
case '=': _d[j++] = 'e'; break;
|
|
case '=': _d[j++] = 'e'; break;
|
|
}
|
|
}
|
|
- if (j == ZT_DICTIONARY_MAX_SIZE) {
|
|
|
|
|
|
+ if (j == C) {
|
|
_d[i] = (char)0;
|
|
_d[i] = (char)0;
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
default:
|
|
default:
|
|
_d[j++] = *p;
|
|
_d[j++] = *p;
|
|
- if (j == ZT_DICTIONARY_MAX_SIZE) {
|
|
|
|
|
|
+ if (j == C) {
|
|
_d[i] = (char)0;
|
|
_d[i] = (char)0;
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
@@ -356,10 +357,12 @@ public:
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * Add a binary buffer
|
|
|
|
|
|
+ * Add a binary buffer's contents as a value
|
|
|
|
+ *
|
|
|
|
+ * @tparam BC Buffer capacity (usually inferred)
|
|
*/
|
|
*/
|
|
- template<unsigned int C>
|
|
|
|
- inline bool add(const char *key,const Buffer<C> &value)
|
|
|
|
|
|
+ template<unsigned int BC>
|
|
|
|
+ inline bool add(const char *key,const Buffer<BC> &value)
|
|
{
|
|
{
|
|
return this->add(key,(const char *)value.data(),(int)value.size());
|
|
return this->add(key,(const char *)value.data(),(int)value.size());
|
|
}
|
|
}
|
|
@@ -385,7 +388,7 @@ public:
|
|
*/
|
|
*/
|
|
inline bool erase(const char *key)
|
|
inline bool erase(const char *key)
|
|
{
|
|
{
|
|
- char d2[ZT_DICTIONARY_MAX_SIZE];
|
|
|
|
|
|
+ char d2[C];
|
|
char *saveptr = (char *)0;
|
|
char *saveptr = (char *)0;
|
|
unsigned int d2ptr = 0;
|
|
unsigned int d2ptr = 0;
|
|
bool found = false;
|
|
bool found = false;
|
|
@@ -419,8 +422,13 @@ public:
|
|
*/
|
|
*/
|
|
inline const char *data() const { return _d; }
|
|
inline const char *data() const { return _d; }
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * @return Value of C template parameter
|
|
|
|
+ */
|
|
|
|
+ inline unsigned int capacity() const { return C; }
|
|
|
|
+
|
|
private:
|
|
private:
|
|
- char _d[ZT_DICTIONARY_MAX_SIZE];
|
|
|
|
|
|
+ char _d[C];
|
|
};
|
|
};
|
|
|
|
|
|
} // namespace ZeroTier
|
|
} // namespace ZeroTier
|