mirror of
https://github.com/stefanocasazza/ULib.git
synced 2025-09-28 19:05:55 +08:00
sync
This commit is contained in:
parent
ee3e6f5741
commit
117008cfbc
2
configure
vendored
2
configure
vendored
|
@ -1762,7 +1762,7 @@ Optional Features:
|
|||
--enable-stdcpp compile with stdc++ runtime overhead [default=yes]
|
||||
--enable-debug compile for debugging [default=no]
|
||||
--enable-unaligned compile for target that allows unaligned reads and writes [default=yes]
|
||||
--enable-apexmem use apex_memmove written by Trevor Herselman in 2014 [default=yes]
|
||||
--enable-apexmem use apex_memmove written by Trevor Herselman in 2014 [default=no]
|
||||
--enable-thread enable build of thread support [default=yes]
|
||||
--enable-pth always use GNU pth for threading [default=no]
|
||||
--enable-examples enable building of examples [default=yes]
|
||||
|
|
|
@ -672,7 +672,7 @@ else
|
|||
fi
|
||||
|
||||
AC_MSG_CHECKING(for apex memcpy/memmove)
|
||||
AC_ARG_ENABLE(apexmem, [ --enable-apexmem use apex_memmove written by Trevor Herselman in 2014 [[default=yes]]])
|
||||
AC_ARG_ENABLE(apexmem, [ --enable-apexmem use apex_memmove written by Trevor Herselman in 2014 [[default=no]]])
|
||||
|
||||
if test -z "$enable_apexmem"; then
|
||||
enable_apexmem="no"
|
||||
|
|
|
@ -35,9 +35,9 @@
|
|||
# ifndef LINUX_VERSION_CODE
|
||||
# error "You need to use at least 2.0 Linux kernel."
|
||||
# endif
|
||||
# ifdef U_APEX_ENABLE
|
||||
# include <ulib/base/apex/apex_memmove.h>
|
||||
# endif
|
||||
# ifdef U_APEX_ENABLE
|
||||
# include <ulib/base/apex/apex_memmove.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef USE_LIBSSL
|
||||
|
|
|
@ -19,73 +19,103 @@
|
|||
#undef GCC_VERSION
|
||||
#include <ulib/base/base.h>
|
||||
|
||||
#define U_hash_size(n) (1U<<(n))
|
||||
#define U_hash_mask(n) (U_hash_size(n)-1U)
|
||||
|
||||
/* get next prime number for container */
|
||||
|
||||
#define U_GET_NEXT_PRIME_NUMBER(sz) ((sz) <= 53U ? 97U : \
|
||||
(sz) <= 97U ? 193U : \
|
||||
(sz) <= 193U ? 389U : \
|
||||
(sz) <= 389U ? 769U : \
|
||||
(sz) <= 769U ? 1543U : \
|
||||
(sz) <= 1543U ? 3079U : \
|
||||
(sz) <= 3079U ? 6151U : \
|
||||
(sz) <= 6151U ? 12289U : \
|
||||
(sz) <= 12289U ? 24593U : \
|
||||
(sz) <= 24593U ? 49157U : \
|
||||
(sz) <= 49157U ? 98317U : \
|
||||
(sz) <= 98317U ? 196613U : \
|
||||
(sz) <= 196613U ? 393241U : \
|
||||
(sz) <= 393241U ? 786433U : \
|
||||
(sz) <= 786433U ? 1572869U : \
|
||||
(sz) <= 1572869U ? 3145739U : \
|
||||
(sz) <= 3145739U ? 6291469U : \
|
||||
(sz) <= 6291469U ? 12582917U : \
|
||||
(sz) <= 12582917U ? 25165843U : \
|
||||
(sz) <= 25165843U ? 50331653U : \
|
||||
(sz) <= 50331653U ? 100663319U : \
|
||||
(sz) <= 100663319U ? 201326611U : \
|
||||
(sz) <= 201326611U ? 402653189U : \
|
||||
(sz) <= 402653189U ? 805306457U : \
|
||||
(sz) <= 805306457U ? 805306457U : \
|
||||
(sz) <= 1610612741U ? 3221225473U : 4294967291U)
|
||||
#define U_GET_NEXT_PRIME_NUMBER(sz) \
|
||||
((sz) <= 53U ? 97U : \
|
||||
(sz) <= 97U ? 193U : \
|
||||
(sz) <= 193U ? 389U : \
|
||||
(sz) <= 389U ? 769U : \
|
||||
(sz) <= 769U ? 1543U : \
|
||||
(sz) <= 1543U ? 3079U : \
|
||||
(sz) <= 3079U ? 6151U : \
|
||||
(sz) <= 6151U ? 12289U : \
|
||||
(sz) <= 12289U ? 24593U : \
|
||||
(sz) <= 24593U ? 49157U : \
|
||||
(sz) <= 49157U ? 98317U : \
|
||||
(sz) <= 98317U ? 196613U : \
|
||||
(sz) <= 196613U ? 393241U : \
|
||||
(sz) <= 393241U ? 786433U : \
|
||||
(sz) <= 786433U ? 1572869U : \
|
||||
(sz) <= 1572869U ? 3145739U : \
|
||||
(sz) <= 3145739U ? 6291469U : \
|
||||
(sz) <= 6291469U ? 12582917U : \
|
||||
(sz) <= 12582917U ? 25165843U : \
|
||||
(sz) <= 25165843U ? 50331653U : \
|
||||
(sz) <= 50331653U ? 100663319U : \
|
||||
(sz) <= 100663319U ? 201326611U : \
|
||||
(sz) <= 201326611U ? 402653189U : \
|
||||
(sz) <= 402653189U ? 805306457U : \
|
||||
(sz) <= 805306457U ? 805306457U : \
|
||||
(sz) <= 1610612741U ? 3221225473U : 4294967291U)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
U_EXPORT uint32_t u_random( uint32_t val) __pure; /* quick 4byte hashing function */
|
||||
/* hash variable-length key into 32-bit value */
|
||||
|
||||
static inline uint32_t u_xxhash32(const unsigned char* restrict t, uint32_t tlen) { return XXH32(t, tlen, u_seed_hash); }
|
||||
static inline uint32_t u_xxhash64(const unsigned char* restrict t, uint32_t tlen)
|
||||
{ return (uint32_t)(((XXH64(t, tlen, u_seed_hash) * (1578233944ULL << 32 | 194370989ULL)) + (20591ULL << 16)) >> 32); }
|
||||
|
||||
#ifdef USE_HARDWARE_CRC32
|
||||
static inline uint32_t u_crc32(const unsigned char* restrict bp, uint32_t len)
|
||||
{
|
||||
U_INTERNAL_TRACE("u_crc32(%.*s,%u)", U_min(len,128), bp, len)
|
||||
|
||||
uint32_t h1 = 0xABAD1DEA;
|
||||
|
||||
# ifdef HAVE_ARCH64
|
||||
while (len >= sizeof(uint64_t))
|
||||
{
|
||||
h1 = __builtin_ia32_crc32di(h1, u_get_unalignedp64(bp));
|
||||
|
||||
bp += sizeof(uint64_t);
|
||||
len -= sizeof(uint64_t);
|
||||
}
|
||||
# endif
|
||||
while (len >= sizeof(uint32_t))
|
||||
{
|
||||
h1 = __builtin_ia32_crc32si(h1, u_get_unalignedp32(bp));
|
||||
|
||||
bp += sizeof(uint32_t);
|
||||
len -= sizeof(uint32_t);
|
||||
}
|
||||
|
||||
if (len >= sizeof(uint16_t))
|
||||
{
|
||||
h1 = __builtin_ia32_crc32hi(h1, u_get_unalignedp16(bp));
|
||||
|
||||
bp += sizeof(uint16_t);
|
||||
len -= sizeof(uint16_t);
|
||||
}
|
||||
|
||||
if (len) h1 = __builtin_ia32_crc32qi(h1, *bp);
|
||||
|
||||
U_INTERNAL_PRINT("h1 = %u", h1)
|
||||
|
||||
U_INTERNAL_ASSERT_MAJOR(h1, 0)
|
||||
|
||||
return h1;
|
||||
}
|
||||
|
||||
static inline uint32_t u_hash(const unsigned char* restrict t, uint32_t tlen) { return u_crc32(t, tlen); }
|
||||
#elif defined(HAVE_ARCH64)
|
||||
static inline uint32_t u_hash(const unsigned char* restrict t, uint32_t tlen) { return u_xxhash64(t, tlen); }
|
||||
# else
|
||||
static inline uint32_t u_hash(const unsigned char* restrict t, uint32_t tlen) { return u_xxhash32(t, tlen); }
|
||||
#endif
|
||||
|
||||
U_EXPORT uint32_t u_hash_ignore_case(const unsigned char* restrict t, uint32_t tlen) __pure;
|
||||
|
||||
U_EXPORT uint32_t u_cdb_hash(const unsigned char* restrict t, uint32_t tlen, int flags) __pure;
|
||||
|
||||
U_EXPORT uint32_t u_random(uint32_t val) __pure; /* quick 4byte hashing function */
|
||||
#ifdef HAVE_ARCH64
|
||||
U_EXPORT uint32_t u_random64(uint64_t ptr) __pure;
|
||||
#endif
|
||||
static inline double u_randomd(uint32_t a) { return (1.0/4294967296.0) * u_random(a); } /* Map hash value into number 0.0 <= n < 1.0 */
|
||||
|
||||
/* hash variable-length key into 32-bit value */
|
||||
|
||||
U_EXPORT uint32_t murmurhash3_x86_32_ignore_case(unsigned char* restrict t, uint32_t tlen) __pure;
|
||||
|
||||
U_EXPORT uint32_t u_cdb_hash( unsigned char* restrict t, uint32_t tlen, int flags) __pure;
|
||||
static inline uint32_t u_hash_ignore_case(unsigned char* restrict t, uint32_t tlen) { return murmurhash3_x86_32_ignore_case(t, tlen); }
|
||||
|
||||
#ifdef USE_HARDWARE_CRC32
|
||||
U_EXPORT uint32_t u_crc32(unsigned char* restrict t, uint32_t tlen) __pure;
|
||||
|
||||
static inline uint32_t u_hash(unsigned char* restrict t, uint32_t tlen) { return u_crc32(t, tlen); }
|
||||
#else
|
||||
U_EXPORT uint32_t u_fhash(unsigned char* restrict t, uint32_t tlen) __pure;
|
||||
|
||||
# ifndef HAVE_ARCH64
|
||||
U_EXPORT uint32_t u_hash(unsigned char* restrict t, uint32_t tlen) __pure;
|
||||
# else
|
||||
U_EXPORT uint32_t murmurhash3_x86_64(unsigned char* restrict t, uint32_t tlen) __pure;
|
||||
|
||||
static inline uint32_t u_hash_old(unsigned char* restrict t, uint32_t tlen) { return murmurhash3_x86_64(t, tlen); }
|
||||
|
||||
static inline uint32_t u_hash(unsigned char* restrict t, uint32_t tlen) { return (uint32_t)(((XXH64(t,tlen,u_seed_hash) * (1578233944ULL << 32 | 194370989ULL)) + (20591U << 16)) >> 32); }
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -152,9 +152,6 @@ U_EXPORT bool u_isNumber(const char* restrict s, uint32_t n) __pure;
|
|||
U_EXPORT void u_printSize(char* restrict buffer, uint64_t bytes); /* print size using u_calcRate() */
|
||||
U_EXPORT bool u_rmatch(const char* restrict haystack, uint32_t haystack_len, const char* restrict needle, uint32_t needle_len) __pure;
|
||||
|
||||
U_EXPORT uint32_t u_findEndHeader( const char* restrict s, uint32_t n) __pure; /* find sequence of U_CRLF2 or U_LF2 */
|
||||
U_EXPORT uint32_t u_findEndHeader1(const char* restrict s, uint32_t n) __pure; /* find sequence of U_CRLF2 */
|
||||
|
||||
static inline void* u_find(const char* restrict a, uint32_t n1, const char* restrict b, uint32_t n2) /* check if string b is contained within string a */
|
||||
{
|
||||
U_INTERNAL_TRACE("u_find(%.*s,%u,%.*s,%u)", U_min(n1,128), a, n1, U_min(n2,128), b, n2)
|
||||
|
@ -166,6 +163,21 @@ static inline void* u_find(const char* restrict a, uint32_t n1, const char* rest
|
|||
return memmem(a, n1, b, n2);
|
||||
}
|
||||
|
||||
static inline uint32_t u_findEndHeader1(const char* restrict s, uint32_t n) /* find sequence of U_CRLF2 */
|
||||
{
|
||||
void* p;
|
||||
|
||||
U_INTERNAL_TRACE("u_findEndHeader1(%.*s,%u)", U_min(n,128), s, n)
|
||||
|
||||
U_INTERNAL_ASSERT_POINTER(s)
|
||||
|
||||
p = memmem(s, n, U_CONSTANT_TO_PARAM(U_CRLF2));
|
||||
|
||||
return (p ? (const char*)p - s + U_CONSTANT_SIZE(U_CRLF2) : U_NOT_FOUND);
|
||||
}
|
||||
|
||||
U_EXPORT uint32_t u_findEndHeader( const char* restrict s, uint32_t n) __pure; /* find sequence of U_CRLF2 or U_LF2 */
|
||||
|
||||
U_EXPORT bool u_endsWith(const char* restrict a, uint32_t n1, const char* restrict b, uint32_t n2) __pure; /* check if string a terminate with string b */
|
||||
U_EXPORT bool u_startsWith(const char* restrict a, uint32_t n1, const char* restrict b, uint32_t n2) __pure; /* check if string a start with string b */
|
||||
|
||||
|
|
|
@ -1214,4 +1214,49 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
#if defined(U_STDCPP_ENABLE)
|
||||
# include <vector>
|
||||
template <class T> class U_EXPORT UJsonTypeHandler<std::vector<T> > : public UJsonTypeHandler_Base {
|
||||
public:
|
||||
typedef std::vector<T> stdvector;
|
||||
|
||||
explicit UJsonTypeHandler(stdvector& val) : UJsonTypeHandler_Base(&val) {}
|
||||
|
||||
void toJSON(UValue& json)
|
||||
{
|
||||
U_TRACE(0, "UJsonTypeHandler<stdvector>::toJSON(%p)", &json)
|
||||
|
||||
U_ASSERT(json.isArray())
|
||||
|
||||
stdvector* pvec = (stdvector*)pval;
|
||||
|
||||
UValue* child;
|
||||
|
||||
for (uint32_t i = 0, n = pvec->size(); i < n; ++i)
|
||||
{
|
||||
U_NEW(UValue, child, UValue);
|
||||
|
||||
child->toJSON(UJsonTypeHandler<T>(pvec->at(i)));
|
||||
|
||||
UValue::appendNode(&json, child);
|
||||
}
|
||||
}
|
||||
|
||||
void fromJSON(UValue& json)
|
||||
{
|
||||
U_TRACE(0, "UJsonTypeHandler<stdvector>::fromJSON(%p)", &json)
|
||||
|
||||
U_ASSERT(json.isArray())
|
||||
|
||||
for (UValue* child = json.children.head; child; child = child->next)
|
||||
{
|
||||
T elem;
|
||||
|
||||
child->fromJSON(UJsonTypeHandler<T>(elem));
|
||||
|
||||
((stdvector*)pval)->push_back(elem);
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -1583,7 +1583,24 @@ public:
|
|||
uint32_t find(const char* s, uint32_t pos, uint32_t s_len, uint32_t how_much = U_NOT_FOUND) const __pure;
|
||||
uint32_t find(const UString& str, uint32_t pos = 0, uint32_t how_much = U_NOT_FOUND) const { return find(str.data(), pos, str.size(), how_much); }
|
||||
|
||||
uint32_t find(unsigned char c, uint32_t pos = 0) const __pure;
|
||||
uint32_t find(unsigned char c, uint32_t pos = 0) const
|
||||
{
|
||||
U_TRACE(0, "UString::find(%C,%u)", c, pos)
|
||||
|
||||
uint32_t sz = size(),
|
||||
ret = U_NOT_FOUND;
|
||||
|
||||
if (pos < sz)
|
||||
{
|
||||
const char* str = rep->str;
|
||||
|
||||
void* p = (void*) memchr(str + pos, c, sz - pos);
|
||||
|
||||
if (p) ret = (const char*)p - str;
|
||||
}
|
||||
|
||||
U_RETURN(ret);
|
||||
}
|
||||
|
||||
// The `rfind' function searches from end to beginning string for a specified string (possibly a single character)
|
||||
// and returns its starting position. You can supply the parameter pos to specify the position where search must begin
|
||||
|
|
|
@ -214,7 +214,7 @@ public:
|
|||
// convert tabs to spaces
|
||||
|
||||
static UString expandTab(const char* s, uint32_t n, int tab = 3);
|
||||
static UString expandTab(const UString& s, int tab = 3) { return expandTab(U_STRING_TO_PARAM(s), tab); }
|
||||
static UString expandTab(const UString& s, int tab = 3) { return expandTab(U_STRING_TO_PARAM(s), tab); }
|
||||
|
||||
// expand path (~/... and ~user/... plus $var and $var/...)
|
||||
|
||||
|
@ -223,18 +223,19 @@ public:
|
|||
|
||||
// prepare for environment variables (check if some of them need quoting...)
|
||||
|
||||
static UString prepareForEnvironmentVar(const UString& env) { return prepareForEnvironmentVar(U_STRING_TO_PARAM(env)); }
|
||||
static UString prepareForEnvironmentVar(const char* s, uint32_t n);
|
||||
|
||||
static UString prepareForEnvironmentVar(const UString& env) { return prepareForEnvironmentVar(U_STRING_TO_PARAM(env)); }
|
||||
|
||||
// expand environment variables
|
||||
|
||||
static UString getEnvironmentVar(const UString& name, const UString* env) { return getEnvironmentVar(U_STRING_TO_PARAM(name), env); }
|
||||
static UString getEnvironmentVar(const char* s, uint32_t n, const UString* env);
|
||||
static UString getEnvironmentVar(const UString& name, const UString* env) { return getEnvironmentVar(U_STRING_TO_PARAM(name), env); }
|
||||
|
||||
// recursively expand environment variables if needed
|
||||
|
||||
static UString expandEnvironmentVar(const UString& s, const UString* env) { return expandEnvironmentVar(U_STRING_TO_PARAM(s), env); }
|
||||
static UString expandEnvironmentVar(const char* s, uint32_t n, const UString* env);
|
||||
static UString expandEnvironmentVar(const UString& s, const UString* env) { return expandEnvironmentVar(U_STRING_TO_PARAM(s), env); }
|
||||
|
||||
// eval expression
|
||||
|
||||
|
@ -255,58 +256,45 @@ public:
|
|||
static UString removeEscape(const char* s, uint32_t n);
|
||||
static UString insertEscape(const char* s, uint32_t n, char delimiter = '"');
|
||||
|
||||
static UString removeEscape(const UString& s)
|
||||
{
|
||||
U_TRACE(0, "UStringExt::removeEscape(%V)", s.rep)
|
||||
|
||||
uint32_t sz = s.size();
|
||||
const char* str = s.data();
|
||||
void* ptr = (void*) memchr(str, '\\', sz);
|
||||
|
||||
return (ptr ? removeEscape(str, sz) : s);
|
||||
}
|
||||
|
||||
static UString insertEscape(const UString& s, char delimiter = '"')
|
||||
{
|
||||
U_TRACE(0, "UStringExt::insertEscape(%V,%C)", s.rep, delimiter)
|
||||
|
||||
uint32_t sz = s.size();
|
||||
const char* str = s.data();
|
||||
void* ptr = (void*) memchr(str, delimiter, sz);
|
||||
|
||||
return (ptr ? insertEscape(str, sz, delimiter) : s);
|
||||
}
|
||||
static UString removeEscape(const UString& s) { return removeEscape(U_STRING_TO_PARAM(s)); }
|
||||
static UString insertEscape(const UString& s, char delimiter = '"') { return insertEscape(U_STRING_TO_PARAM(s), delimiter); }
|
||||
|
||||
// Returns a string that has whitespace removed from the start and the end (leading and trailing)
|
||||
|
||||
static UString trim(const char* s, uint32_t n);
|
||||
|
||||
static UString trim(const UString& s) { return trim(U_STRING_TO_PARAM(s)); }
|
||||
|
||||
// Returns a string that has any printable character which is not a space or
|
||||
// an alphanumeric character removed from the start and the end (leading and trailing)
|
||||
|
||||
static UString trimPunctuation(const char* s, uint32_t n);
|
||||
|
||||
static UString trimPunctuation(const UString& s) { return trimPunctuation(U_STRING_TO_PARAM(s)); }
|
||||
|
||||
// returns a string that has whitespace removed from the start and the end, and
|
||||
// which has each sequence of internal whitespace replaced with a single space
|
||||
|
||||
static UString simplifyWhiteSpace(const char* s, uint32_t n);
|
||||
|
||||
static UString simplifyWhiteSpace(const UString& s) { return simplifyWhiteSpace(U_STRING_TO_PARAM(s)); }
|
||||
|
||||
// returns a string that has suppressed all whitespace
|
||||
|
||||
static UString removeWhiteSpace(const char* s, uint32_t n);
|
||||
|
||||
static UString removeWhiteSpace(const UString& s) { return removeWhiteSpace(U_STRING_TO_PARAM(s)); }
|
||||
|
||||
// returns a string that has suppressed repeated empty lines
|
||||
|
||||
static UString removeEmptyLine(const char* s, uint32_t n);
|
||||
|
||||
static UString removeEmptyLine(const UString& s) { return removeEmptyLine(U_STRING_TO_PARAM(s)); }
|
||||
|
||||
// Minifies CSS/JS by removing comments and whitespaces
|
||||
|
||||
static UString minifyCssJs(const char* s, uint32_t n);
|
||||
|
||||
static UString minifyCssJs(const UString& s) { return minifyCssJs(U_STRING_TO_PARAM(s)); }
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
|
|
@ -88,51 +88,9 @@ __pure uint32_t u_random64(uint64_t ptr)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_HARDWARE_CRC32
|
||||
__pure uint32_t u_crc32(unsigned char* restrict bp, uint32_t len)
|
||||
{
|
||||
U_INTERNAL_TRACE("u_crc32(%.*s,%u)", U_min(len,128), bp, len)
|
||||
|
||||
uint32_t h1 = 0xABAD1DEA;
|
||||
|
||||
# ifdef HAVE_ARCH64
|
||||
while (len >= sizeof(uint64_t))
|
||||
{
|
||||
h1 = __builtin_ia32_crc32di(h1, u_get_unalignedp64(bp));
|
||||
|
||||
bp += sizeof(uint64_t);
|
||||
len -= sizeof(uint64_t);
|
||||
}
|
||||
# endif
|
||||
while (len >= sizeof(uint32_t))
|
||||
{
|
||||
h1 = __builtin_ia32_crc32si(h1, u_get_unalignedp32(bp));
|
||||
|
||||
bp += sizeof(uint32_t);
|
||||
len -= sizeof(uint32_t);
|
||||
}
|
||||
|
||||
if (len >= sizeof(uint16_t))
|
||||
{
|
||||
h1 = __builtin_ia32_crc32hi(h1, u_get_unalignedp16(bp));
|
||||
|
||||
bp += sizeof(uint16_t);
|
||||
len -= sizeof(uint16_t);
|
||||
}
|
||||
|
||||
if (len) h1 = __builtin_ia32_crc32qi(h1, *bp);
|
||||
|
||||
U_INTERNAL_PRINT("h1 = %u", h1)
|
||||
|
||||
U_INTERNAL_ASSERT_MAJOR(h1, 0)
|
||||
|
||||
return h1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* the famous DJB hash function for strings */
|
||||
|
||||
__pure uint32_t u_cdb_hash(unsigned char* restrict t, uint32_t tlen, int flags)
|
||||
__pure uint32_t u_cdb_hash(const unsigned char* restrict t, uint32_t tlen, int flags)
|
||||
{
|
||||
uint32_t h;
|
||||
|
||||
|
@ -149,185 +107,12 @@ __pure uint32_t u_cdb_hash(unsigned char* restrict t, uint32_t tlen, int flags)
|
|||
return h;
|
||||
}
|
||||
|
||||
/* MurmurHash3 was written by Austin Appleby */
|
||||
|
||||
static inline uint32_t rotl32(uint32_t x, int8_t r) { return (x << r) | (x >> (32 - r)); }
|
||||
#if !defined(USE_HARDWARE_CRC32) && defined(HAVE_ARCH64)
|
||||
static inline uint64_t rotl64(uint64_t x, int8_t r) { return (x << r) | (x >> (64 - r)); }
|
||||
|
||||
static inline uint64_t fmix64(uint64_t k)
|
||||
__pure uint32_t u_hash_ignore_case(const unsigned char* restrict data, uint32_t len)
|
||||
{
|
||||
k ^= k >> 33;
|
||||
k *= 0xff51afd7ed558ccdULL;
|
||||
k ^= k >> 33;
|
||||
k *= 0xc4ceb9fe1a85ec53ULL;
|
||||
k ^= k >> 33;
|
||||
|
||||
return k;
|
||||
}
|
||||
|
||||
/* Block read - if your platform needs to do endian-swapping or can only handle aligned reads, do the conversion here */
|
||||
|
||||
#define getblock64(p,i) u_get_unalignedp64(p+i)
|
||||
|
||||
__pure uint32_t murmurhash3_x86_64(unsigned char* restrict bp, uint32_t len)
|
||||
{
|
||||
U_INTERNAL_TRACE("murmurhash3_x86_64(%.*s,%u,%d)", U_min(len,128), bp, len)
|
||||
|
||||
int i;
|
||||
uint64_t h1, h2, k1, k2;
|
||||
const int nblocks = len / 16;
|
||||
const uint64_t c1 = 0x87c37b91114253d5ULL,
|
||||
c2 = 0x4cf5ad432745937fULL;
|
||||
|
||||
const uint8_t* tail = (const uint8_t*)(bp + nblocks*16);
|
||||
const uint64_t* blocks = (const uint64_t*)bp;
|
||||
|
||||
h1 = h2 = u_seed_hash; /* seed */
|
||||
|
||||
/* body */
|
||||
|
||||
for (i = 0; i < nblocks; ++i)
|
||||
{
|
||||
k1 = getblock64(blocks,i*2+0);
|
||||
k2 = getblock64(blocks,i*2+1);
|
||||
|
||||
k1 *= c1; k1 = rotl64(k1,31); k1 *= c2; h1 ^= k1;
|
||||
h1 = rotl64(h1,27); h1 += h2; h1 = h1*5+0x52dce729;
|
||||
k2 *= c2; k2 = rotl64(k2,33); k2 *= c1; h2 ^= k2;
|
||||
h2 = rotl64(h2,31); h2 += h1; h2 = h2*5+0x38495ab5;
|
||||
}
|
||||
|
||||
/* tail */
|
||||
|
||||
k1 = k2 = 0;
|
||||
|
||||
switch (len & 15)
|
||||
{
|
||||
case 15: k2 ^= (uint64_t)tail[14] << 48;
|
||||
case 14: k2 ^= (uint64_t)tail[13] << 40;
|
||||
case 13: k2 ^= (uint64_t)tail[12] << 32;
|
||||
case 12: k2 ^= (uint64_t)tail[11] << 24;
|
||||
case 11: k2 ^= (uint64_t)tail[10] << 16;
|
||||
case 10: k2 ^= (uint64_t)tail[ 9] << 8;
|
||||
case 9: k2 ^= (uint64_t)tail[ 8];
|
||||
k2 *= c2; k2 = rotl64(k2,33); k2 *= c1; h2 ^= k2;
|
||||
|
||||
case 8: k1 ^= (uint64_t)tail[ 7] << 56;
|
||||
case 7: k1 ^= (uint64_t)tail[ 6] << 48;
|
||||
case 6: k1 ^= (uint64_t)tail[ 5] << 40;
|
||||
case 5: k1 ^= (uint64_t)tail[ 4] << 32;
|
||||
case 4: k1 ^= (uint64_t)tail[ 3] << 24;
|
||||
case 3: k1 ^= (uint64_t)tail[ 2] << 16;
|
||||
case 2: k1 ^= (uint64_t)tail[ 1] << 8;
|
||||
case 1: k1 ^= (uint64_t)tail[ 0];
|
||||
k1 *= c1; k1 = rotl64(k1,31); k1 *= c2; h1 ^= k1;
|
||||
}
|
||||
|
||||
/* finalization */
|
||||
|
||||
h1 ^= (uint64_t)len;
|
||||
h2 ^= (uint64_t)len;
|
||||
h1 += h2;
|
||||
h2 += h1;
|
||||
h1 = fmix64(h1);
|
||||
h2 = fmix64(h2);
|
||||
h1 += h2;
|
||||
h2 += h1;
|
||||
|
||||
U_INTERNAL_PRINT("h2 = %llu %u", h2, (uint32_t)h2)
|
||||
|
||||
U_INTERNAL_ASSERT_MAJOR(h2, 0)
|
||||
|
||||
return (uint32_t)h2;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline uint32_t fmix32(uint32_t h)
|
||||
{
|
||||
h ^= h >> 16;
|
||||
h *= 0x85ebca6b;
|
||||
h ^= h >> 13;
|
||||
h *= 0xc2b2ae35;
|
||||
h ^= h >> 16;
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
/* Block read - if your platform needs to do endian-swapping or can only handle aligned reads, do the conversion here */
|
||||
|
||||
#define getblock32(p,i) u_get_unalignedp32(p+i)
|
||||
|
||||
__pure uint32_t murmurhash3_x86_32_ignore_case(unsigned char* restrict bp, uint32_t len)
|
||||
{
|
||||
int i;
|
||||
union uucflag u;
|
||||
uint32_t h1, k1;
|
||||
const int nblocks = len / 4;
|
||||
const uint32_t c1 = 0xcc9e2d51,
|
||||
c2 = 0x1b873593;
|
||||
|
||||
const uint8_t* tail = (const uint8_t*)(bp + nblocks*4);
|
||||
const uint32_t* blocks = (const uint32_t*)tail;
|
||||
|
||||
U_INTERNAL_TRACE("murmurhash3_x86_32_ignore_case(%.*s,%u)", U_min(len,128), bp, len)
|
||||
|
||||
h1 = u_seed_hash; /* seed */
|
||||
|
||||
/* body */
|
||||
|
||||
i = -nblocks;
|
||||
|
||||
for (; i; ++i)
|
||||
{
|
||||
u.u = getblock32(blocks,i);
|
||||
u.c[0] = u__tolower(u.c[0]);
|
||||
u.c[1] = u__tolower(u.c[1]);
|
||||
u.c[2] = u__tolower(u.c[2]);
|
||||
u.c[3] = u__tolower(u.c[3]);
|
||||
k1 = u.u;
|
||||
|
||||
k1 *= c1;
|
||||
k1 = rotl32(k1,15);
|
||||
k1 *= c2;
|
||||
|
||||
h1 ^= k1;
|
||||
h1 = rotl32(h1,13);
|
||||
h1 = h1*5+0xe6546b64;
|
||||
}
|
||||
|
||||
/* tail */
|
||||
|
||||
k1 = 0;
|
||||
|
||||
switch (len & 3)
|
||||
{
|
||||
case 3: k1 ^= u__tolower(tail[2]) << 16;
|
||||
case 2: k1 ^= u__tolower(tail[1]) << 8;
|
||||
case 1: k1 ^= u__tolower(tail[0]);
|
||||
k1 *= c1; k1 = rotl32(k1,15); k1 *= c2; h1 ^= k1;
|
||||
}
|
||||
|
||||
/* finalization */
|
||||
|
||||
h1 ^= len;
|
||||
h1 = fmix32(h1);
|
||||
|
||||
U_INTERNAL_PRINT("h1 = %u", h1)
|
||||
|
||||
U_INTERNAL_ASSERT_MAJOR(h1, 0)
|
||||
|
||||
return h1;
|
||||
}
|
||||
|
||||
#if !defined(USE_HARDWARE_CRC32)
|
||||
# define get16bits(p) u_get_unalignedp16(p)
|
||||
|
||||
__pure uint32_t u_fhash(unsigned char* restrict data, uint32_t len)
|
||||
{
|
||||
uint32_t tmp, hash = len, rem = len & 3;
|
||||
|
||||
U_INTERNAL_TRACE("u_fhash(%.*s,%u,%d)", U_min(len,128), data, len)
|
||||
U_INTERNAL_TRACE("u_hash_ignore_case(%.*s,%u,%d)", U_min(len,128), data, len)
|
||||
|
||||
len >>= 2;
|
||||
|
||||
|
@ -335,8 +120,14 @@ __pure uint32_t u_fhash(unsigned char* restrict data, uint32_t len)
|
|||
|
||||
for (; len > 0; --len)
|
||||
{
|
||||
hash += get16bits(data);
|
||||
tmp = (get16bits(data+2) << 11) ^ hash;
|
||||
u.u = u_get_unalignedp32(data);
|
||||
u.c[0] = u__tolower(u.c[0]);
|
||||
u.c[1] = u__tolower(u.c[1]);
|
||||
u.c[2] = u__tolower(u.c[2]);
|
||||
u.c[3] = u__tolower(u.c[3]);
|
||||
|
||||
hash += u_get_unalignedp16(&u.lo);
|
||||
tmp = (u_get_unalignedp16(&u.hi) << 11) ^ hash;
|
||||
hash = (hash << 16) ^ tmp;
|
||||
data += 2 * sizeof(uint16_t);
|
||||
hash += hash >> 11;
|
||||
|
@ -348,16 +139,24 @@ __pure uint32_t u_fhash(unsigned char* restrict data, uint32_t len)
|
|||
{
|
||||
case 3:
|
||||
{
|
||||
hash += get16bits(data);
|
||||
u.lo = u_get_unalignedp16(data);
|
||||
u.c[0] = u__tolower(u.c[0]);
|
||||
u.c[1] = u__tolower(u.c[1]);
|
||||
|
||||
hash += u_get_unalignedp16(&u.lo);
|
||||
hash ^= hash << 16;
|
||||
hash ^= ((signed char)data[sizeof(uint16_t)]) << 18;
|
||||
hash ^= ((signed char)u__tolower(data[sizeof(uint16_t)])) << 18;
|
||||
hash += hash >> 11;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
{
|
||||
hash += get16bits(data);
|
||||
u.lo = u_get_unalignedp16(data);
|
||||
u.c[0] = u__tolower(u.c[0]);
|
||||
u.c[1] = u__tolower(u.c[1]);
|
||||
|
||||
hash += u_get_unalignedp16(&u.lo);
|
||||
hash ^= hash << 11;
|
||||
hash += hash >> 17;
|
||||
}
|
||||
|
@ -365,7 +164,7 @@ __pure uint32_t u_fhash(unsigned char* restrict data, uint32_t len)
|
|||
|
||||
case 1:
|
||||
{
|
||||
hash += (signed char)*data;
|
||||
hash += (signed char)u__tolower(*data);
|
||||
hash ^= hash << 10;
|
||||
hash += hash >> 1;
|
||||
}
|
||||
|
@ -383,15 +182,33 @@ __pure uint32_t u_fhash(unsigned char* restrict data, uint32_t len)
|
|||
return hash;
|
||||
}
|
||||
|
||||
#if !defined(HAVE_ARCH64)
|
||||
__pure uint32_t u_hash(unsigned char* restrict bp, uint32_t len)
|
||||
/* MurmurHash3 was written by Austin Appleby
|
||||
|
||||
#define getblock32(p,i) u_get_unalignedp32(p+i)
|
||||
#define getblock64(p,i) u_get_unalignedp64(p+i)
|
||||
|
||||
//#if !defined(USE_HARDWARE_CRC32) && !defined(HAVE_ARCH64)
|
||||
static inline uint32_t rotl32(uint32_t x, int8_t r) { return (x << r) | (x >> (32 - r)); }
|
||||
|
||||
static inline uint32_t fmix32(uint32_t h)
|
||||
{
|
||||
U_INTERNAL_TRACE("u_hash(%.*s,%u,%d)", U_min(len,128), bp, len)
|
||||
h ^= h >> 16;
|
||||
h *= 0x85ebca6b;
|
||||
h ^= h >> 13;
|
||||
h *= 0xc2b2ae35;
|
||||
h ^= h >> 16;
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
__pure uint32_t murmurhash3_x86_32(const unsigned char* restrict bp, uint32_t len)
|
||||
{
|
||||
U_INTERNAL_TRACE("murmurhash3_x86_32(%.*s,%u,%d)", U_min(len,128), bp, len)
|
||||
|
||||
uint8_t* tail;
|
||||
int i, nblocks;
|
||||
uint32_t* blocks;
|
||||
uint32_t c1, c2, k1, h1 = u_seed_hash; /* seed */
|
||||
uint32_t c1, c2, k1, h1 = u_seed_hash; // seed
|
||||
|
||||
if (len > 16)
|
||||
{
|
||||
|
@ -408,9 +225,9 @@ __pure uint32_t u_hash(unsigned char* restrict bp, uint32_t len)
|
|||
tail = (uint8_t*)(bp + nblocks*16);
|
||||
blocks = (uint32_t*)tail;
|
||||
|
||||
h2 = h3 = h4 = h1; /* seed */
|
||||
h2 = h3 = h4 = h1; // seed
|
||||
|
||||
/* body */
|
||||
// body
|
||||
|
||||
for (i = -nblocks; i; ++i)
|
||||
{
|
||||
|
@ -429,7 +246,7 @@ __pure uint32_t u_hash(unsigned char* restrict bp, uint32_t len)
|
|||
h4 = rotl32(h4,13); h4 += h1; h4 = h4*5+0x32ac3b17;
|
||||
}
|
||||
|
||||
/* tail */
|
||||
// tail
|
||||
|
||||
k1 = k2 = k3 = k4 = 0;
|
||||
|
||||
|
@ -459,7 +276,7 @@ __pure uint32_t u_hash(unsigned char* restrict bp, uint32_t len)
|
|||
k1 *= c1; k1 = rotl32(k1,15); k1 *= c2; h1 ^= k1;
|
||||
}
|
||||
|
||||
/* finalization */
|
||||
// finalization
|
||||
|
||||
h1 ^= (uint32_t)len; h2 ^= (uint32_t)len;
|
||||
h3 ^= (uint32_t)len; h4 ^= (uint32_t)len;
|
||||
|
@ -490,7 +307,7 @@ __pure uint32_t u_hash(unsigned char* restrict bp, uint32_t len)
|
|||
tail = (uint8_t*)(bp + nblocks*4);
|
||||
blocks = (uint32_t*)tail;
|
||||
|
||||
/* body */
|
||||
// body
|
||||
|
||||
i = -nblocks;
|
||||
|
||||
|
@ -507,7 +324,7 @@ __pure uint32_t u_hash(unsigned char* restrict bp, uint32_t len)
|
|||
h1 = h1*5+0xe6546b64;
|
||||
}
|
||||
|
||||
/* tail */
|
||||
// tail
|
||||
|
||||
k1 = 0;
|
||||
|
||||
|
@ -519,7 +336,7 @@ __pure uint32_t u_hash(unsigned char* restrict bp, uint32_t len)
|
|||
k1 *= c1; k1 = rotl32(k1,15); k1 *= c2; h1 ^= k1;
|
||||
}
|
||||
|
||||
/* finalization */
|
||||
// finalization
|
||||
|
||||
h1 ^= len;
|
||||
h1 = fmix32(h1);
|
||||
|
@ -530,5 +347,92 @@ __pure uint32_t u_hash(unsigned char* restrict bp, uint32_t len)
|
|||
|
||||
return h1;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
//#endif
|
||||
|
||||
//#if !defined(USE_HARDWARE_CRC32) && defined(HAVE_ARCH64)
|
||||
static inline uint64_t rotl64(uint64_t x, int8_t r) { return (x << r) | (x >> (64 - r)); }
|
||||
|
||||
static inline uint64_t fmix64(uint64_t k)
|
||||
{
|
||||
k ^= k >> 33;
|
||||
k *= 0xff51afd7ed558ccdULL;
|
||||
k ^= k >> 33;
|
||||
k *= 0xc4ceb9fe1a85ec53ULL;
|
||||
k ^= k >> 33;
|
||||
|
||||
return k;
|
||||
}
|
||||
|
||||
__pure uint32_t murmurhash3_x86_64(const unsigned char* restrict bp, uint32_t len)
|
||||
{
|
||||
U_INTERNAL_TRACE("murmurhash3_x86_64(%.*s,%u,%d)", U_min(len,128), bp, len)
|
||||
|
||||
int i;
|
||||
uint64_t h1, h2, k1, k2;
|
||||
const int nblocks = len / 16;
|
||||
const uint64_t c1 = 0x87c37b91114253d5ULL,
|
||||
c2 = 0x4cf5ad432745937fULL;
|
||||
|
||||
const uint8_t* tail = (const uint8_t*)(bp + nblocks*16);
|
||||
const uint64_t* blocks = (const uint64_t*)bp;
|
||||
|
||||
h1 = h2 = u_seed_hash; // seed
|
||||
|
||||
// body
|
||||
|
||||
for (i = 0; i < nblocks; ++i)
|
||||
{
|
||||
k1 = getblock64(blocks,i*2+0);
|
||||
k2 = getblock64(blocks,i*2+1);
|
||||
|
||||
k1 *= c1; k1 = rotl64(k1,31); k1 *= c2; h1 ^= k1;
|
||||
h1 = rotl64(h1,27); h1 += h2; h1 = h1*5+0x52dce729;
|
||||
k2 *= c2; k2 = rotl64(k2,33); k2 *= c1; h2 ^= k2;
|
||||
h2 = rotl64(h2,31); h2 += h1; h2 = h2*5+0x38495ab5;
|
||||
}
|
||||
|
||||
// tail
|
||||
|
||||
k1 = k2 = 0;
|
||||
|
||||
switch (len & 15)
|
||||
{
|
||||
case 15: k2 ^= (uint64_t)tail[14] << 48;
|
||||
case 14: k2 ^= (uint64_t)tail[13] << 40;
|
||||
case 13: k2 ^= (uint64_t)tail[12] << 32;
|
||||
case 12: k2 ^= (uint64_t)tail[11] << 24;
|
||||
case 11: k2 ^= (uint64_t)tail[10] << 16;
|
||||
case 10: k2 ^= (uint64_t)tail[ 9] << 8;
|
||||
case 9: k2 ^= (uint64_t)tail[ 8];
|
||||
k2 *= c2; k2 = rotl64(k2,33); k2 *= c1; h2 ^= k2;
|
||||
|
||||
case 8: k1 ^= (uint64_t)tail[ 7] << 56;
|
||||
case 7: k1 ^= (uint64_t)tail[ 6] << 48;
|
||||
case 6: k1 ^= (uint64_t)tail[ 5] << 40;
|
||||
case 5: k1 ^= (uint64_t)tail[ 4] << 32;
|
||||
case 4: k1 ^= (uint64_t)tail[ 3] << 24;
|
||||
case 3: k1 ^= (uint64_t)tail[ 2] << 16;
|
||||
case 2: k1 ^= (uint64_t)tail[ 1] << 8;
|
||||
case 1: k1 ^= (uint64_t)tail[ 0];
|
||||
k1 *= c1; k1 = rotl64(k1,31); k1 *= c2; h1 ^= k1;
|
||||
}
|
||||
|
||||
// finalization
|
||||
|
||||
h1 ^= (uint64_t)len;
|
||||
h2 ^= (uint64_t)len;
|
||||
h1 += h2;
|
||||
h2 += h1;
|
||||
h1 = fmix64(h1);
|
||||
h2 = fmix64(h2);
|
||||
h1 += h2;
|
||||
h2 += h1;
|
||||
|
||||
U_INTERNAL_PRINT("h2 = %llu %u", h2, (uint32_t)h2)
|
||||
|
||||
U_INTERNAL_ASSERT_MAJOR(h2, 0)
|
||||
|
||||
return (uint32_t)h2;
|
||||
}
|
||||
//#endif
|
||||
*/
|
||||
|
|
|
@ -572,41 +572,6 @@ char* u_getPathRelativ(const char* restrict path, uint32_t* restrict ptr_path_le
|
|||
return (char*)path;
|
||||
}
|
||||
|
||||
/* find sequence of U_CRLF2 */
|
||||
|
||||
__pure uint32_t u_findEndHeader1(const char* restrict str, uint32_t n)
|
||||
{
|
||||
const char* restrict p;
|
||||
const char* restrict end = str + n;
|
||||
const char* restrict ptr = str;
|
||||
|
||||
uint32_t pos, endHeader = U_NOT_FOUND;
|
||||
|
||||
U_INTERNAL_TRACE("u_findEndHeader1(%.*s,%u)", U_min(n,128), str, n)
|
||||
|
||||
U_INTERNAL_ASSERT_POINTER(str)
|
||||
|
||||
while (ptr < end)
|
||||
{
|
||||
p = (const char* restrict) memchr(ptr, '\r', end - ptr);
|
||||
|
||||
if (p == 0) break;
|
||||
|
||||
if (u_get_unalignedp32(p) == U_MULTICHAR_CONSTANT32('\r','\n','\r','\n'))
|
||||
{
|
||||
pos = p - str + 4;
|
||||
|
||||
if (pos <= n) endHeader = pos;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
ptr = p + 1;
|
||||
}
|
||||
|
||||
return endHeader;
|
||||
}
|
||||
|
||||
/* find sequence of U_LF2 or U_CRLF2 */
|
||||
|
||||
__pure uint32_t u_findEndHeader(const char* restrict str, uint32_t n)
|
||||
|
|
|
@ -849,7 +849,7 @@ void ULog::logResponse(const UString& data, const char* name, const char* format
|
|||
{
|
||||
u_printf_string_max_length = u_findEndHeader1(ptr, sz);
|
||||
|
||||
if (u_printf_string_max_length == -1) u_printf_string_max_length = U_min(sz,2000);
|
||||
if ((uint32_t)u_printf_string_max_length == U_NOT_FOUND) u_printf_string_max_length = U_min(sz,2000);
|
||||
|
||||
U_INTERNAL_ASSERT_MAJOR(u_printf_string_max_length, 0)
|
||||
}
|
||||
|
|
|
@ -1551,9 +1551,9 @@ bool UClientImage_Base::writeResponse()
|
|||
U_INTERNAL_ASSERT_EQUALS(nrequest, 0)
|
||||
|
||||
#if defined(USE_LIBSSL) || defined(_MSWINDOWS_)
|
||||
iBytesWrite = USocketExt::writev( socket, iov_vec+idx, iovcnt, ncount, 0);
|
||||
iBytesWrite = USocketExt::writev( socket, iov_vec+idx, iovcnt, ncount, U_ClientImage_pipeline ? U_TIMEOUT_MS : 0);
|
||||
#else
|
||||
iBytesWrite = USocketExt::_writev(socket, iov_vec+idx, iovcnt, ncount, 0);
|
||||
iBytesWrite = USocketExt::_writev(socket, iov_vec+idx, iovcnt, ncount, U_ClientImage_pipeline ? U_TIMEOUT_MS : 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -3360,7 +3360,7 @@ void UServer_Base::runLoop(const char* user)
|
|||
socket->setTcpNoDelay();
|
||||
socket->setTcpFastOpen();
|
||||
socket->setTcpDeferAccept();
|
||||
if (bssl == false) socket->setBufferSND(min_size_for_sendfile);
|
||||
if (bssl == false) socket->setBufferSND(500 * 1024); // 500k: for major size we assume is better to use sendfile()
|
||||
if (set_tcp_keep_alive ) socket->setTcpKeepAlive();
|
||||
# endif
|
||||
if (tcp_linger_set > -2) socket->setTcpLinger(tcp_linger_set);
|
||||
|
|
|
@ -1642,29 +1642,6 @@ __pure uint32_t UString::findnocase(const char* s, uint32_t pos, uint32_t s_len,
|
|||
U_RETURN(U_NOT_FOUND);
|
||||
}
|
||||
|
||||
__pure uint32_t UString::find(unsigned char c, uint32_t pos) const
|
||||
{
|
||||
U_TRACE(0, "UString::find(%C,%u)", c, pos)
|
||||
|
||||
uint32_t sz = size(),
|
||||
ret = U_NOT_FOUND;
|
||||
|
||||
const char* str = rep->str;
|
||||
|
||||
if (pos < sz)
|
||||
{
|
||||
uint32_t how_much = (sz - pos);
|
||||
|
||||
// U_INTERNAL_DUMP("how_much = %u", how_much)
|
||||
|
||||
void* p = (void*) memchr(str + pos, c, how_much);
|
||||
|
||||
if (p) ret = (const char*)p - str;
|
||||
}
|
||||
|
||||
U_RETURN(ret);
|
||||
}
|
||||
|
||||
// rfind() instead of starting at the beginning of the string and searching for the text's first occurence, starts its search at the end and returns the last occurence
|
||||
|
||||
__pure uint32_t UString::rfind(unsigned char c, uint32_t pos) const
|
||||
|
@ -1679,11 +1656,9 @@ __pure uint32_t UString::rfind(unsigned char c, uint32_t pos) const
|
|||
|
||||
if (xpos > pos) xpos = pos;
|
||||
|
||||
const char* str = rep->str;
|
||||
|
||||
for (++xpos; xpos-- > 0; )
|
||||
{
|
||||
if (str[xpos] == c) U_RETURN(xpos);
|
||||
if (rep->str[xpos] == c) U_RETURN(xpos);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1700,10 +1675,8 @@ __pure uint32_t UString::rfind(const char* s, uint32_t pos, uint32_t n) const
|
|||
{
|
||||
pos = U_min(sz - n, pos);
|
||||
|
||||
const char* str = rep->str;
|
||||
|
||||
do {
|
||||
if (memcmp(str + pos, s, n) == 0) U_RETURN(pos);
|
||||
if (memcmp(rep->str + pos, s, n) == 0) U_RETURN(pos);
|
||||
}
|
||||
while (pos-- > 0);
|
||||
}
|
||||
|
@ -1720,13 +1693,9 @@ __pure uint32_t UString::find_first_of(const char* s, uint32_t pos, uint32_t n)
|
|||
|
||||
if (n)
|
||||
{
|
||||
uint32_t sz = size();
|
||||
|
||||
const char* str = rep->str;
|
||||
|
||||
for (; pos < sz; ++pos)
|
||||
for (; pos < size(); ++pos)
|
||||
{
|
||||
if (memchr(s, str[pos], n)) U_RETURN(pos);
|
||||
if (memchr(s, rep->str[pos], n)) U_RETURN(pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1743,10 +1712,8 @@ __pure uint32_t UString::find_last_of(const char* s, uint32_t pos, uint32_t n) c
|
|||
{
|
||||
if (--sz > pos) sz = pos;
|
||||
|
||||
const char* str = rep->str;
|
||||
|
||||
do {
|
||||
if (memchr(s, str[sz], n)) U_RETURN(sz);
|
||||
if (memchr(s, rep->str[sz], n)) U_RETURN(sz);
|
||||
}
|
||||
while (sz-- != 0);
|
||||
}
|
||||
|
@ -1765,11 +1732,9 @@ __pure uint32_t UString::find_first_not_of(const char* s, uint32_t pos, uint32_t
|
|||
uint32_t sz = size(),
|
||||
xpos = pos;
|
||||
|
||||
const char* str = rep->str;
|
||||
|
||||
for (; xpos < sz; ++xpos)
|
||||
{
|
||||
if (memchr(s, str[xpos], n) == 0) U_RETURN(xpos);
|
||||
if (memchr(s, rep->str[xpos], n) == 0) U_RETURN(xpos);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1804,10 +1769,8 @@ __pure uint32_t UString::find_last_not_of(const char* s, uint32_t pos, uint32_t
|
|||
{
|
||||
if (--sz > pos) sz = pos;
|
||||
|
||||
const char* str = rep->str;
|
||||
|
||||
do {
|
||||
if (memchr(s, str[sz], n) == 0) U_RETURN(sz);
|
||||
if (memchr(s, rep->str[sz], n) == 0) U_RETURN(sz);
|
||||
}
|
||||
while (sz-- != 0);
|
||||
}
|
||||
|
|
|
@ -804,10 +804,6 @@ UString UStringExt::insertEscape(const char* s, uint32_t n, char delimiter)
|
|||
{
|
||||
U_TRACE(0, "UStringExt::insertEscape(%.*S,%u,%C)", n, s, n, delimiter)
|
||||
|
||||
U_INTERNAL_ASSERT_MAJOR_MSG(n,0,"elaborazione su stringa vuota: inserire if empty()...")
|
||||
|
||||
U_INTERNAL_ASSERT_POINTER(memchr(s, delimiter, n))
|
||||
|
||||
char* p;
|
||||
uint32_t sz, sz1 = 0;
|
||||
UString result(n * 2);
|
||||
|
@ -855,10 +851,6 @@ UString UStringExt::removeEscape(const char* s, uint32_t n)
|
|||
{
|
||||
U_TRACE(0, "UStringExt::removeEscape(%.*S,%u,%C)", n, s, n)
|
||||
|
||||
U_INTERNAL_ASSERT_MAJOR_MSG(n,0,"elaborazione su stringa vuota: inserire if empty()...")
|
||||
|
||||
U_INTERNAL_ASSERT_POINTER(memchr(s, '\\', n))
|
||||
|
||||
char* p;
|
||||
UString result(n);
|
||||
uint32_t sz, sz1 = 0;
|
||||
|
|
|
@ -93,7 +93,8 @@ static void testQuery(const UString& json, const char* cquery, const UString& ex
|
|||
int dataType = UValue::jread(json, query, result);
|
||||
|
||||
cout.write(buffer, u__snprintf(buffer, sizeof(buffer), "dataType = (%d %S) query = %V result(%u) = %V UValue::jread_elements = %d UValue::jread_error = (%d %S)\n",
|
||||
dataType, UValue::getDataTypeDescription(dataType), query.rep, result.size(), result.rep, UValue::jread_elements, UValue::jread_error, UValue::getJReadErrorDescription()));
|
||||
dataType, UValue::getDataTypeDescription(dataType), query.rep, result.size(), result.rep, UValue::jread_elements, UValue::jread_error,
|
||||
UValue::getJReadErrorDescription()));
|
||||
|
||||
U_INTERNAL_ASSERT_EQUALS(result, expected)
|
||||
}
|
||||
|
@ -108,6 +109,7 @@ static void testVector()
|
|||
UString result, vecJson = U_STRING_FROM_CONSTANT("[\"riga 1\",\"riga 2\",\"riga 3\",\"riga 4\"]");
|
||||
|
||||
ok = JSON_parse(vecJson, y);
|
||||
|
||||
U_INTERNAL_ASSERT(ok)
|
||||
|
||||
ok = (y[0] == U_STRING_FROM_CONSTANT("riga 1"));
|
||||
|
@ -122,6 +124,7 @@ static void testVector()
|
|||
y.clear();
|
||||
|
||||
ok = JSON_parse(vecJson, y);
|
||||
|
||||
U_INTERNAL_ASSERT(ok)
|
||||
|
||||
ok = (y[0] == U_STRING_FROM_CONSTANT("riga 1"));
|
||||
|
@ -135,7 +138,7 @@ static void testVector()
|
|||
|
||||
result = JSON_stringify(json_vec, y);
|
||||
|
||||
U_ASSERT( result == vecJson )
|
||||
U_ASSERT_EQUALS( result, vecJson )
|
||||
}
|
||||
|
||||
static void testMap()
|
||||
|
@ -148,6 +151,7 @@ static void testMap()
|
|||
UString result, mapJson = U_STRING_FROM_CONSTANT("{\"key1\":\"riga 1\",\"key2\":\"riga 2\",\"key3\":\"riga 3\",\"key4\":\"riga 4\"}");
|
||||
|
||||
ok = JSON_parse(mapJson, x);
|
||||
|
||||
U_INTERNAL_ASSERT(ok)
|
||||
|
||||
ok = (x["key1"] == U_STRING_FROM_CONSTANT("riga 1"));
|
||||
|
@ -162,6 +166,7 @@ static void testMap()
|
|||
x.clear();
|
||||
|
||||
ok = JSON_parse(mapJson, x);
|
||||
|
||||
U_INTERNAL_ASSERT(ok)
|
||||
|
||||
ok = (x["key1"] == U_STRING_FROM_CONSTANT("riga 1"));
|
||||
|
@ -175,7 +180,7 @@ static void testMap()
|
|||
|
||||
result = JSON_stringify(json_obj, x);
|
||||
|
||||
U_ASSERT( result.size() == mapJson.size() )
|
||||
U_ASSERT_EQUALS( result.size(), mapJson.size() )
|
||||
}
|
||||
|
||||
static void testObject()
|
||||
|
@ -188,6 +193,7 @@ static void testObject()
|
|||
UString result, reqJson = U_STRING_FROM_CONSTANT("{\"token\":\"A619828KAIJ6D3\",\"type\":\"localesData\",\"radius\":\"near\",\"location\":\"40.7831 N, 73.9712 W\"}");
|
||||
|
||||
ok = JSON_parse(reqJson, request);
|
||||
|
||||
U_INTERNAL_ASSERT(ok)
|
||||
|
||||
U_DUMP_OBJECT(request)
|
||||
|
@ -198,6 +204,7 @@ static void testObject()
|
|||
U_INTERNAL_ASSERT_EQUALS(request.location, "40.7831 N, 73.9712 W")
|
||||
|
||||
ok = JSON_parse(reqJson, request);
|
||||
|
||||
U_INTERNAL_ASSERT(ok)
|
||||
|
||||
U_DUMP_OBJECT(request)
|
||||
|
@ -209,7 +216,7 @@ static void testObject()
|
|||
|
||||
result = JSON_stringify(json_obj, request);
|
||||
|
||||
U_ASSERT( result == reqJson )
|
||||
U_ASSERT_EQUALS( result, reqJson )
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -219,6 +226,32 @@ U_EXPORT main (int argc, char* argv[])
|
|||
|
||||
U_TRACE(5, "main(%d)", argc)
|
||||
|
||||
#if defined(U_STDCPP_ENABLE) && defined(HAVE_CXX11) && defined(U_COMPILER_RANGE_FOR)
|
||||
UValue json_vec(ARRAY_VALUE);
|
||||
std::vector<unsigned int> v = {0, 1, 2, 3, 4, 5};
|
||||
UString vecJson = U_STRING_FROM_CONSTANT("[0,1,2,3,4,5]");
|
||||
|
||||
U_ASSERT_EQUALS( JSON_stringify(json_vec, v), vecJson)
|
||||
|
||||
v.clear();
|
||||
|
||||
bool ok = JSON_parse(vecJson, v);
|
||||
U_INTERNAL_ASSERT(ok)
|
||||
|
||||
ok = (v[0] == 0);
|
||||
U_INTERNAL_ASSERT(ok)
|
||||
ok = (v[1] == 1);
|
||||
U_INTERNAL_ASSERT(ok)
|
||||
ok = (v[2] == 2);
|
||||
U_INTERNAL_ASSERT(ok)
|
||||
ok = (v[3] == 3);
|
||||
U_INTERNAL_ASSERT(ok)
|
||||
ok = (v[4] == 4);
|
||||
U_INTERNAL_ASSERT(ok)
|
||||
ok = (v[5] == 5);
|
||||
U_INTERNAL_ASSERT(ok)
|
||||
#endif
|
||||
|
||||
UValue json;
|
||||
UCrono crono;
|
||||
char buffer[4096];
|
||||
|
|
Loading…
Reference in New Issue
Block a user