mirror of
https://github.com/stefanocasazza/ULib.git
synced 2025-09-28 19:05:55 +08:00
sync
This commit is contained in:
parent
723d527766
commit
a25cad5520
|
@ -71,6 +71,7 @@ cleandist:
|
||||||
$(distdir)/tests/ulib/tmp/* \
|
$(distdir)/tests/ulib/tmp/* \
|
||||||
$(distdir)/tests/ulib/private/* \
|
$(distdir)/tests/ulib/private/* \
|
||||||
$(distdir)/tests/ulib/CApath/*.*0 \
|
$(distdir)/tests/ulib/CApath/*.*0 \
|
||||||
|
$(distdir)/tests/ulib/ok/json.ok \
|
||||||
$(distdir)/tests/ulib/ok/timer.ok \
|
$(distdir)/tests/ulib/ok/timer.ok \
|
||||||
$(distdir)/tests/ulib/ok/socket.ok \
|
$(distdir)/tests/ulib/ok/socket.ok \
|
||||||
$(distdir)/tests/ulib/ok/interrupt.ok \
|
$(distdir)/tests/ulib/ok/interrupt.ok \
|
||||||
|
|
|
@ -1008,6 +1008,7 @@ cleandist:
|
||||||
$(distdir)/tests/ulib/tmp/* \
|
$(distdir)/tests/ulib/tmp/* \
|
||||||
$(distdir)/tests/ulib/private/* \
|
$(distdir)/tests/ulib/private/* \
|
||||||
$(distdir)/tests/ulib/CApath/*.*0 \
|
$(distdir)/tests/ulib/CApath/*.*0 \
|
||||||
|
$(distdir)/tests/ulib/ok/json.ok \
|
||||||
$(distdir)/tests/ulib/ok/timer.ok \
|
$(distdir)/tests/ulib/ok/timer.ok \
|
||||||
$(distdir)/tests/ulib/ok/socket.ok \
|
$(distdir)/tests/ulib/ok/socket.ok \
|
||||||
$(distdir)/tests/ulib/ok/interrupt.ok \
|
$(distdir)/tests/ulib/ok/interrupt.ok \
|
||||||
|
|
10
configure
vendored
10
configure
vendored
|
@ -27597,11 +27597,17 @@ $as_echo "yes" >&6; }
|
||||||
|
|
||||||
$as_echo "#define USE_LIBCURL 1" >>confdefs.h
|
$as_echo "#define USE_LIBCURL 1" >>confdefs.h
|
||||||
|
|
||||||
libcurl_version=$($curldir/bin/curl-config --version 2>/dev/null | sed -e "s/libcurl //g")
|
if test x_$PKG_CONFIG != x_no; then
|
||||||
|
libcurl_version=$(pkg-config --modversion libcurl)
|
||||||
|
fi
|
||||||
|
if test -z "${libcurl_version}"; then
|
||||||
|
libcurl_version=$($curldir/bin/curl-config --version 2>/dev/null | sed -e "s/libcurl //g")
|
||||||
|
fi
|
||||||
if test -z "${libcurl_version}"; then
|
if test -z "${libcurl_version}"; then
|
||||||
libcurl_version="unknown"
|
libcurl_version="unknown"
|
||||||
fi
|
fi
|
||||||
ULIB_LIBS="-lcurl $ULIB_LIBS";
|
libcurl_linking=$($curldir/bin/curl-config --libs 2>/dev/null)
|
||||||
|
ULIB_LIBS="$libcurl_linking $ULIB_LIBS";
|
||||||
if test $curldir != "${CROSS_ENVIRONMENT}/" -a $curldir != "${CROSS_ENVIRONMENT}/usr" -a $curldir != "${CROSS_ENVIRONMENT}/usr/local"; then
|
if test $curldir != "${CROSS_ENVIRONMENT}/" -a $curldir != "${CROSS_ENVIRONMENT}/usr" -a $curldir != "${CROSS_ENVIRONMENT}/usr/local"; then
|
||||||
CPPFLAGS="$CPPFLAGS -I$curldir/include";
|
CPPFLAGS="$CPPFLAGS -I$curldir/include";
|
||||||
LDFLAGS="$LDFLAGS -L$curldir/lib -Wl,-R$curldir/lib";
|
LDFLAGS="$LDFLAGS -L$curldir/lib -Wl,-R$curldir/lib";
|
||||||
|
|
|
@ -1204,7 +1204,7 @@ void PEC_report::loadFiles()
|
||||||
|
|
||||||
dirwalk.walk();
|
dirwalk.walk();
|
||||||
|
|
||||||
u_printSize(buffer, bytes);
|
(void) u_printSize(buffer, bytes);
|
||||||
|
|
||||||
U_MESSAGE("checked %u file(s) - skipped %u file(s)\n"
|
U_MESSAGE("checked %u file(s) - skipped %u file(s)\n"
|
||||||
"start processing %u file(s) for %s of data...", nfiles, nskipped, tfile->size(), buffer);
|
"start processing %u file(s) for %s of data...", nfiles, nskipped, tfile->size(), buffer);
|
||||||
|
|
|
@ -13,7 +13,8 @@ extern U_EXPORT pvPFpvpvs apex_memmove;
|
||||||
* apex_memmove written by Trevor Herselman in 2014
|
* apex_memmove written by Trevor Herselman in 2014
|
||||||
*
|
*
|
||||||
* FORCE `CDECL` calling convention on 32-bit builds on our function pointers, because we need it to match the original `std::memmove` definition;
|
* FORCE `CDECL` calling convention on 32-bit builds on our function pointers, because we need it to match the original `std::memmove` definition;
|
||||||
* in-case the user specified a different default function calling convention! (I specified __fastcall as my default calling convention and got errors! So I needed to add this!)
|
* in-case the user specified a different default function calling convention! (I specified __fastcall as my default calling convention and got errors!
|
||||||
|
* So I needed to add this!)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
U_EXPORT void apex_memmove_dispatcher(void);
|
U_EXPORT void apex_memmove_dispatcher(void);
|
||||||
|
|
|
@ -148,6 +148,7 @@ typedef bool (*bPFpcpv) (const char*,const void*);
|
||||||
typedef void (*vPFpvpc) (void*,char*);
|
typedef void (*vPFpvpc) (void*,char*);
|
||||||
typedef void (*vPFpvpv) (void*,void*);
|
typedef void (*vPFpvpv) (void*,void*);
|
||||||
|
|
||||||
|
typedef uint32_t (*uPFdpc) (double,char*);
|
||||||
typedef uint32_t (*uPFu32pc) (uint32_t,char*);
|
typedef uint32_t (*uPFu32pc) (uint32_t,char*);
|
||||||
typedef uint32_t (*uPFu64pc) (uint64_t,char*);
|
typedef uint32_t (*uPFu64pc) (uint64_t,char*);
|
||||||
|
|
||||||
|
@ -264,43 +265,6 @@ U_EXPORT const char* u_basename(const char* restrict path) __pure;
|
||||||
U_EXPORT const char* u_getsuffix(const char* restrict path, uint32_t len) __pure;
|
U_EXPORT const char* u_getsuffix(const char* restrict path, uint32_t len) __pure;
|
||||||
U_EXPORT bool u_is_overlap(const char* restrict dst, const char* restrict src, size_t n);
|
U_EXPORT bool u_is_overlap(const char* restrict dst, const char* restrict src, size_t n);
|
||||||
|
|
||||||
/* conversion number to string */
|
|
||||||
extern U_EXPORT uPFu32pc u_num2str32;
|
|
||||||
extern U_EXPORT uPFu64pc u_num2str64;
|
|
||||||
extern U_EXPORT const char u_ctn2s[200];
|
|
||||||
|
|
||||||
static inline uint32_t u_num2str32s(int32_t num, char* restrict cp)
|
|
||||||
{
|
|
||||||
uint32_t bsign = (num < 0);
|
|
||||||
|
|
||||||
U_INTERNAL_TRACE("u_num2str32s(%u,%p)", num, cp)
|
|
||||||
|
|
||||||
if (bsign)
|
|
||||||
{
|
|
||||||
num = -num;
|
|
||||||
|
|
||||||
*cp++ = '-';
|
|
||||||
}
|
|
||||||
|
|
||||||
return bsign + u_num2str32(num, cp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t u_num2str64s(int64_t num, char* restrict cp)
|
|
||||||
{
|
|
||||||
uint32_t bsign = (num < 0LL);
|
|
||||||
|
|
||||||
U_INTERNAL_TRACE("u_num2str64s(%lld,%p)", num, cp)
|
|
||||||
|
|
||||||
if (bsign)
|
|
||||||
{
|
|
||||||
num = -num;
|
|
||||||
|
|
||||||
*cp++ = '-';
|
|
||||||
}
|
|
||||||
|
|
||||||
return bsign + u_num2str64(num, cp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Location info */
|
/* Location info */
|
||||||
extern U_EXPORT uint32_t u_num_line;
|
extern U_EXPORT uint32_t u_num_line;
|
||||||
extern U_EXPORT const char* restrict u_name_file;
|
extern U_EXPORT const char* restrict u_name_file;
|
||||||
|
@ -479,6 +443,69 @@ static inline void u_gettimenow(void)
|
||||||
#endif
|
#endif
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* conversion number to string */
|
||||||
|
extern U_EXPORT uPFdpc u_dbl2str;
|
||||||
|
extern U_EXPORT uPFu32pc u_num2str32;
|
||||||
|
extern U_EXPORT uPFu64pc u_num2str64;
|
||||||
|
extern U_EXPORT const char u_ctn2s[200];
|
||||||
|
|
||||||
|
static inline uint32_t u_num2str32s(int32_t num, char* restrict cp)
|
||||||
|
{
|
||||||
|
uint32_t bsign = (num < 0);
|
||||||
|
|
||||||
|
U_INTERNAL_TRACE("u_num2str32s(%u,%p)", num, cp)
|
||||||
|
|
||||||
|
if (bsign)
|
||||||
|
{
|
||||||
|
num = -num;
|
||||||
|
|
||||||
|
*cp++ = '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
return bsign + u_num2str32(num, cp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t u_num2str64s(int64_t num, char* restrict cp)
|
||||||
|
{
|
||||||
|
uint32_t bsign = (num < 0);
|
||||||
|
|
||||||
|
U_INTERNAL_TRACE("u_num2str64s(%lld,%p)", num, cp)
|
||||||
|
|
||||||
|
if (bsign)
|
||||||
|
{
|
||||||
|
num = -num;
|
||||||
|
|
||||||
|
*cp++ = '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
return bsign + u_num2str64(num, cp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t u_dtoa(double num, char* restrict cp)
|
||||||
|
{
|
||||||
|
uint32_t bsign;
|
||||||
|
|
||||||
|
U_INTERNAL_TRACE("u_dtoa(%g,%p)", num, cp)
|
||||||
|
|
||||||
|
if (num == 0)
|
||||||
|
{
|
||||||
|
u_put_unalignedp32(cp, U_MULTICHAR_CONSTANT32('0','.','0','\0'));
|
||||||
|
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
bsign = (num < 0);
|
||||||
|
|
||||||
|
if (bsign)
|
||||||
|
{
|
||||||
|
num = -num;
|
||||||
|
|
||||||
|
*cp++ = '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
return bsign + u_dbl2str(num, cp);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -61,10 +61,10 @@ static inline uint32_t u_xxhash64(const unsigned char* restrict t, uint32_t tlen
|
||||||
#ifdef USE_HARDWARE_CRC32
|
#ifdef USE_HARDWARE_CRC32
|
||||||
static inline uint32_t u_crc32(const unsigned char* restrict bp, uint32_t len)
|
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;
|
uint32_t h1 = 0xABAD1DEA;
|
||||||
|
|
||||||
|
U_INTERNAL_TRACE("u_crc32(%.*s,%u)", U_min(len,128), bp, len)
|
||||||
|
|
||||||
# ifdef HAVE_ARCH64
|
# ifdef HAVE_ARCH64
|
||||||
while (len >= sizeof(uint64_t))
|
while (len >= sizeof(uint64_t))
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
|
|
||||||
#ifdef DEBUG_DEBUG
|
#ifdef DEBUG_DEBUG
|
||||||
# define U_INTERNAL_TRACE(format,args...) u_internal_print(false, format"\n" , ##args);
|
# define U_INTERNAL_TRACE(format,args...) u_internal_print(false, format"\n" , ##args);
|
||||||
# define U_INTERNAL_PRINT(format,args...) U_INTERNAL_TRACE(format,args)
|
# define U_INTERNAL_PRINT(format,args...) u_internal_print(false, format"\n" , ##args);
|
||||||
#else
|
#else
|
||||||
# define U_INTERNAL_TRACE(format,args...)
|
# define U_INTERNAL_TRACE(format,args...)
|
||||||
# define U_INTERNAL_PRINT(format,args...)
|
# define U_INTERNAL_PRINT(format,args...)
|
||||||
|
|
|
@ -147,7 +147,7 @@ U_EXPORT uint32_t u_memory_dump(char* restrict bp, unsigned char* restrict cp, u
|
||||||
|
|
||||||
U_EXPORT int u_getScreenWidth(void) __pure; /* Determine the width of the terminal we're running on */
|
U_EXPORT int u_getScreenWidth(void) __pure; /* Determine the width of the terminal we're running on */
|
||||||
U_EXPORT bool u_isNumber(const char* restrict s, uint32_t n) __pure;
|
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 uint32_t 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 bool u_rmatch(const char* restrict haystack, uint32_t haystack_len, const char* restrict needle, uint32_t needle_len) __pure;
|
||||||
|
|
||||||
U_EXPORT const char* u_get_mimetype(const char* restrict suffix, int* pmime_index);
|
U_EXPORT const char* u_get_mimetype(const char* restrict suffix, int* pmime_index);
|
||||||
|
@ -518,9 +518,13 @@ static inline unsigned long u_strtoul(const char* restrict s, const char* restri
|
||||||
|
|
||||||
U_INTERNAL_ASSERT_POINTER(s)
|
U_INTERNAL_ASSERT_POINTER(s)
|
||||||
U_INTERNAL_ASSERT_POINTER(e)
|
U_INTERNAL_ASSERT_POINTER(e)
|
||||||
U_INTERNAL_ASSERT(u__isdigit(*s))
|
|
||||||
|
|
||||||
for (c = *s; s != e; c = *++s) val = (c - '0') + (val * 10UL);
|
for (c = *s; s != e; c = *++s)
|
||||||
|
{
|
||||||
|
U_INTERNAL_ASSERT(u__isdigit(*s))
|
||||||
|
|
||||||
|
val = (c - '0') + (val * 10UL);
|
||||||
|
}
|
||||||
|
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
@ -534,9 +538,13 @@ static inline uint64_t u_strtoull(const char* restrict s, const char* restrict e
|
||||||
|
|
||||||
U_INTERNAL_ASSERT_POINTER(s)
|
U_INTERNAL_ASSERT_POINTER(s)
|
||||||
U_INTERNAL_ASSERT_POINTER(e)
|
U_INTERNAL_ASSERT_POINTER(e)
|
||||||
U_INTERNAL_ASSERT(u__isdigit(*s))
|
|
||||||
|
|
||||||
for (c = *s; s != e; c = *++s) val = (c - '0') + (val * 10ULL);
|
for (c = *s; s != e; c = *++s)
|
||||||
|
{
|
||||||
|
U_INTERNAL_ASSERT(u__isdigit(*s))
|
||||||
|
|
||||||
|
val = (c - '0') + (val * 10ULL);
|
||||||
|
}
|
||||||
|
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
|
@ -509,6 +509,38 @@ private:
|
||||||
WiAuthVirtualAccessPoint& operator=(const WiAuthVirtualAccessPoint&) { return *this; }
|
WiAuthVirtualAccessPoint& operator=(const WiAuthVirtualAccessPoint&) { return *this; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static uint32_t findAnagrafica(const UString& _ip)
|
||||||
|
{
|
||||||
|
U_TRACE(5, "::findAnagrafica(%V)", _ip.rep)
|
||||||
|
|
||||||
|
uint32_t pos = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 10.8.0.156 172.16.156.0/24 111
|
||||||
|
* 159.213.248.233,172.25.0.0/22,213
|
||||||
|
*/
|
||||||
|
|
||||||
|
loop:
|
||||||
|
pos = db_anagrafica->find(_ip, pos);
|
||||||
|
|
||||||
|
U_INTERNAL_DUMP("pos = %u", pos)
|
||||||
|
|
||||||
|
if (pos != U_NOT_FOUND)
|
||||||
|
{
|
||||||
|
pos += _ip.size();
|
||||||
|
|
||||||
|
char c = db_anagrafica->c_char(pos);
|
||||||
|
|
||||||
|
if (c != ',' &&
|
||||||
|
u__isspace(c) == false)
|
||||||
|
{
|
||||||
|
goto loop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
U_RETURN(pos);
|
||||||
|
}
|
||||||
|
|
||||||
class WiAuthNodog : public UDataStorage {
|
class WiAuthNodog : public UDataStorage {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -868,7 +900,7 @@ public:
|
||||||
U_INTERNAL_ASSERT(*ap_address)
|
U_INTERNAL_ASSERT(*ap_address)
|
||||||
|
|
||||||
int op = -1;
|
int op = -1;
|
||||||
WiAuthAccessPoint* p;
|
uint32_t pos;
|
||||||
|
|
||||||
if (ap_label->empty()) (void) ap_label->assign(U_CONSTANT_TO_PARAM("ap"));
|
if (ap_label->empty()) (void) ap_label->assign(U_CONSTANT_TO_PARAM("ap"));
|
||||||
|
|
||||||
|
@ -907,53 +939,51 @@ public:
|
||||||
{
|
{
|
||||||
if (ap_address_trust == false) U_RETURN(false);
|
if (ap_address_trust == false) U_RETURN(false);
|
||||||
|
|
||||||
|
sz = 0;
|
||||||
op = RDB_INSERT;
|
op = RDB_INSERT;
|
||||||
port = _port;
|
port = _port;
|
||||||
status = 0;
|
status = 0;
|
||||||
hostname = (*ap_hostname ? *ap_hostname : U_STRING_FROM_CONSTANT("hostname_empty"));
|
hostname = (*ap_hostname ? *ap_hostname : U_STRING_FROM_CONSTANT("hostname_empty"));
|
||||||
last_info = since = start = u_now->tv_sec;
|
start =
|
||||||
|
since =
|
||||||
sz = 1;
|
last_info = u_now->tv_sec;
|
||||||
index_access_point = 0;
|
|
||||||
|
|
||||||
vec_access_point.clear();
|
vec_access_point.clear();
|
||||||
|
|
||||||
U_NEW(WiAuthAccessPoint, p, WiAuthAccessPoint(*ap_label));
|
if (db_anagrafica == 0 ||
|
||||||
|
(pos = findAnagrafica(*ap_address), pos == U_NOT_FOUND))
|
||||||
vec_access_point.push_back(p);
|
|
||||||
|
|
||||||
if (db_anagrafica)
|
|
||||||
{
|
{
|
||||||
/**
|
addAccessPoint();
|
||||||
* 10.8.0.156 172.16.156.0/24 111
|
}
|
||||||
* 159.213.248.233 172.25.0.0/22 213
|
else
|
||||||
*/
|
{
|
||||||
|
bool bcsv = (db_anagrafica->c_char(pos) == ',');
|
||||||
|
|
||||||
uint32_t pos = db_anagrafica->find(*ap_address);
|
U_INTERNAL_DUMP("bcsv = %b", bcsv)
|
||||||
|
|
||||||
U_INTERNAL_DUMP("pos = %d", pos)
|
UString netmask;
|
||||||
|
UTokenizer tok(db_anagrafica->substr(pos));
|
||||||
|
|
||||||
if (pos != U_NOT_FOUND)
|
if (bcsv) tok.setDelimiter(",\n");
|
||||||
|
|
||||||
|
(void) tok.next(netmask, (bool*)0);
|
||||||
|
(void) tok.next(*ap_label, (bool*)0);
|
||||||
|
|
||||||
|
U_INTERNAL_ASSERT(netmask)
|
||||||
|
U_INTERNAL_ASSERT(*ap_label)
|
||||||
|
|
||||||
|
addAccessPoint();
|
||||||
|
|
||||||
|
while (tok.next(*ip, (bool*)0) &&
|
||||||
|
ap_address->equal(*ip))
|
||||||
{
|
{
|
||||||
pos += ap_address->size();
|
(void) tok.next(netmask, (bool*)0);
|
||||||
|
(void) tok.next(*ap_label, (bool*)0);
|
||||||
|
|
||||||
while (u__islterm(db_anagrafica->c_char(pos)) == false) ++pos;
|
U_INTERNAL_ASSERT(netmask)
|
||||||
|
U_INTERNAL_ASSERT(*ap_label)
|
||||||
|
|
||||||
UTokenizer tok(db_anagrafica->substr(pos));
|
addAccessPoint();
|
||||||
|
|
||||||
while (tok.next(*ip, (bool*)0) &&
|
|
||||||
ap_address->equal(*ip))
|
|
||||||
{
|
|
||||||
UString netmask, label;
|
|
||||||
|
|
||||||
(void) tok.next(netmask, (bool*)0);
|
|
||||||
(void) tok.next(*ap_label, (bool*)0);
|
|
||||||
|
|
||||||
U_INTERNAL_ASSERT(netmask)
|
|
||||||
U_INTERNAL_ASSERT(*ap_label)
|
|
||||||
|
|
||||||
addAccessPoint();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1179,14 +1209,45 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void writeToLOG(const char* op)
|
||||||
|
{
|
||||||
|
U_TRACE(5, "WiAuthUser::writeToLOG(%S)", op)
|
||||||
|
|
||||||
|
U_INTERNAL_ASSERT_POINTER(op)
|
||||||
|
|
||||||
|
getDone();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Example
|
||||||
|
* -----------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
* 2012/08/08 14:56:00 op: PASS_AUTH, uid: 33437934, ap: 00@10.8.1.2, ip: 172.16.1.172, mac: 00:14:a5:6e:9c:cb, time: 233, traffic: 342, policy: DAILY consume: true
|
||||||
|
* -----------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
U_INTERNAL_ASSERT(_mac)
|
||||||
|
U_INTERNAL_ASSERT(*time_done)
|
||||||
|
U_INTERNAL_ASSERT(*traffic_done)
|
||||||
|
|
||||||
|
ULog::log(file_LOG->getFd(), "op: %s, uid: %v, ap: %v, ip: %v, mac: %v, time: %v, traffic: %v, policy: %v",
|
||||||
|
op, uid->rep, getAP().rep, _ip.rep, _mac.rep, time_done->rep, traffic_done->rep, getPolicy().rep);
|
||||||
|
}
|
||||||
|
|
||||||
const char* updateCounter(const UString& logout, long time_connected, uint64_t traffic, bool& ask_logout)
|
const char* updateCounter(const UString& logout, long time_connected, uint64_t traffic, bool& ask_logout)
|
||||||
{
|
{
|
||||||
U_TRACE(5, "WiAuthUser::updateCounter(%V,%ld,%llu,%b)", logout.rep, time_connected, traffic, ask_logout)
|
U_TRACE(5, "WiAuthUser::updateCounter(%V,%ld,%llu,%b)", logout.rep, time_connected, traffic, ask_logout)
|
||||||
|
|
||||||
const char* write_to_log = 0;
|
const char* write_to_log = 0;
|
||||||
|
|
||||||
_time_done += time_connected;
|
uint32_t time_done_save = _time_done;
|
||||||
_traffic_done += traffic;
|
uint64_t traffic_done_save = _traffic_done;
|
||||||
|
|
||||||
|
_time_done = time_connected;
|
||||||
|
_traffic_done = traffic;
|
||||||
|
|
||||||
|
writeToLOG("INFO");
|
||||||
|
|
||||||
|
_time_done += time_done_save;
|
||||||
|
_traffic_done += traffic_done_save;
|
||||||
|
|
||||||
if (consume)
|
if (consume)
|
||||||
{
|
{
|
||||||
|
@ -1575,29 +1636,6 @@ next:
|
||||||
if (op == RDB_REPLACE) (void) db_user->putDataStorage( *uid);
|
if (op == RDB_REPLACE) (void) db_user->putDataStorage( *uid);
|
||||||
else (void) db_user->insertDataStorage(*uid);
|
else (void) db_user->insertDataStorage(*uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeToLOG(const char* op)
|
|
||||||
{
|
|
||||||
U_TRACE(5, "WiAuthUser::writeToLOG(%S)", op)
|
|
||||||
|
|
||||||
U_INTERNAL_ASSERT_POINTER(op)
|
|
||||||
|
|
||||||
getDone();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Example
|
|
||||||
* -----------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
* 2012/08/08 14:56:00 op: PASS_AUTH, uid: 33437934, ap: 00@10.8.1.2, ip: 172.16.1.172, mac: 00:14:a5:6e:9c:cb, time: 233, traffic: 342, policy: DAILY consume: true
|
|
||||||
* -----------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
U_INTERNAL_ASSERT(_mac)
|
|
||||||
U_INTERNAL_ASSERT(*time_done)
|
|
||||||
U_INTERNAL_ASSERT(*traffic_done)
|
|
||||||
|
|
||||||
ULog::log(file_LOG->getFd(), "op: %s, uid: %v, ap: %v, ip: %v, mac: %v, time: %v, traffic: %v, policy: %v",
|
|
||||||
op, uid->rep, getAP().rep, _ip.rep, _mac.rep, time_done->rep, traffic_done->rep, getPolicy().rep);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static UString getUserName()
|
static UString getUserName()
|
||||||
|
@ -1934,16 +1972,7 @@ static int checkForUserPolicy(UStringRep* key, UStringRep* data)
|
||||||
{
|
{
|
||||||
*uid = db_user->getKeyID();
|
*uid = db_user->getKeyID();
|
||||||
|
|
||||||
if (user_rec->connected)
|
if (user_rec->connected) user_rec->writeToLOG("RST_POLICY");
|
||||||
{
|
|
||||||
uint64_t traffic = user_rec->_traffic_done / (1024ULL * 1024ULL);
|
|
||||||
|
|
||||||
if (traffic)
|
|
||||||
{
|
|
||||||
U_LOGGER("*** checkForUserPolicy() UID(%v) IP(%v) MAC(%v) AP(%v) POLICY(%v) traffic: %llu ***",
|
|
||||||
uid->rep, user_rec->_ip.rep, user_rec->_mac.rep, user_rec->nodog.rep, user_rec->_policy.rep, traffic);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
user_rec->_time_done =
|
user_rec->_time_done =
|
||||||
user_rec->_time_consumed = 0;
|
user_rec->_time_consumed = 0;
|
||||||
|
@ -3291,7 +3320,7 @@ static bool checkTimeRequest()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ko = (ts->empty() && db_anagrafica);
|
ko = ts->empty();
|
||||||
|
|
||||||
if (ko)
|
if (ko)
|
||||||
{
|
{
|
||||||
|
@ -4498,30 +4527,53 @@ static void GET_get_config()
|
||||||
|
|
||||||
if (db_anagrafica)
|
if (db_anagrafica)
|
||||||
{
|
{
|
||||||
/**
|
pos = findAnagrafica(*ip);
|
||||||
* 10.8.0.156 172.16.156.0/24 111
|
|
||||||
* 159.213.248.233 172.25.0.0/22 213
|
|
||||||
*/
|
|
||||||
|
|
||||||
pos = db_anagrafica->find(*ip);
|
|
||||||
|
|
||||||
U_INTERNAL_DUMP("pos = %d", pos)
|
|
||||||
|
|
||||||
if (pos != U_NOT_FOUND)
|
if (pos != U_NOT_FOUND)
|
||||||
{
|
{
|
||||||
pos += ip->size();
|
bool bcsv = (db_anagrafica->c_char(pos) == ',');
|
||||||
|
|
||||||
while (u__isspace(db_anagrafica->c_char(pos)) == false) ++pos;
|
U_INTERNAL_DUMP("bcsv = %b", bcsv)
|
||||||
|
|
||||||
UString netmask, label;
|
UString netmask, label;
|
||||||
UTokenizer tok(db_anagrafica->substr(pos));
|
UTokenizer tok(db_anagrafica->substr(pos));
|
||||||
|
|
||||||
|
if (bcsv) tok.setDelimiter(",\n");
|
||||||
|
|
||||||
(void) tok.next(netmask, (bool*)0);
|
(void) tok.next(netmask, (bool*)0);
|
||||||
(void) tok.next( label, (bool*)0);
|
(void) tok.next( label, (bool*)0);
|
||||||
|
|
||||||
U_INTERNAL_ASSERT(label)
|
U_INTERNAL_ASSERT(label)
|
||||||
U_INTERNAL_ASSERT(netmask)
|
U_INTERNAL_ASSERT(netmask)
|
||||||
|
|
||||||
|
if (bcsv)
|
||||||
|
{
|
||||||
|
UString _ip;
|
||||||
|
UVector<UString> vnetmask, vlabel;
|
||||||
|
|
||||||
|
vlabel.push(label);
|
||||||
|
vnetmask.push(netmask);
|
||||||
|
|
||||||
|
while (tok.next(_ip, (bool*)0) &&
|
||||||
|
ip->equal(_ip))
|
||||||
|
{
|
||||||
|
(void) tok.next(netmask, (bool*)0);
|
||||||
|
(void) tok.next( label, (bool*)0);
|
||||||
|
|
||||||
|
U_INTERNAL_ASSERT(label)
|
||||||
|
U_INTERNAL_ASSERT(netmask)
|
||||||
|
|
||||||
|
vlabel.push(label);
|
||||||
|
vnetmask.push(netmask);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vlabel.size() > 1)
|
||||||
|
{
|
||||||
|
label = vlabel.join(' ');
|
||||||
|
netmask = vnetmask.join(' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_body = UStringExt::substitute(_body, U_CONSTANT_TO_PARAM("172.<CCC>.<DDD>.0/24"), U_STRING_TO_PARAM(netmask));
|
_body = UStringExt::substitute(_body, U_CONSTANT_TO_PARAM("172.<CCC>.<DDD>.0/24"), U_STRING_TO_PARAM(netmask));
|
||||||
|
|
||||||
buffer.snprintf("LOCAL_NETWORK_LABEL \"%v\"", label.rep);
|
buffer.snprintf("LOCAL_NETWORK_LABEL \"%v\"", label.rep);
|
||||||
|
|
397
include/ulib/utility/dtoa_milo.h
Normal file
397
include/ulib/utility/dtoa_milo.h
Normal file
|
@ -0,0 +1,397 @@
|
||||||
|
// https://github.com/amdn/dtoa-benchmark
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <assert.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#include "msinttypes/stdint.h"
|
||||||
|
#include <intrin.h>
|
||||||
|
#else
|
||||||
|
#include <stdint.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define UINT64_C2(h, l) ((static_cast<uint64_t>(h) << 32) | static_cast<uint64_t>(l))
|
||||||
|
|
||||||
|
struct DiyFp {
|
||||||
|
DiyFp() {}
|
||||||
|
|
||||||
|
DiyFp(uint64_t _f, int _e) : f(_f), e(_e) {}
|
||||||
|
|
||||||
|
DiyFp(double d) {
|
||||||
|
union {
|
||||||
|
double d;
|
||||||
|
uint64_t u64;
|
||||||
|
} u = { d };
|
||||||
|
|
||||||
|
int biased_e = (u.u64 & kDpExponentMask) >> kDpSignificandSize;
|
||||||
|
uint64_t significand = (u.u64 & kDpSignificandMask);
|
||||||
|
if (biased_e != 0) {
|
||||||
|
f = significand + kDpHiddenBit;
|
||||||
|
e = biased_e - kDpExponentBias;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
f = significand;
|
||||||
|
e = kDpMinExponent + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DiyFp operator-(const DiyFp& rhs) const {
|
||||||
|
assert(e == rhs.e);
|
||||||
|
assert(f >= rhs.f);
|
||||||
|
return DiyFp(f - rhs.f, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
DiyFp operator*(const DiyFp& rhs) const {
|
||||||
|
#if defined(_MSC_VER) && defined(_M_AMD64)
|
||||||
|
uint64_t h;
|
||||||
|
uint64_t l = _umul128(f, rhs.f, &h);
|
||||||
|
if (l & (uint64_t(1) << 63)) // rounding
|
||||||
|
h++;
|
||||||
|
return DiyFp(h, e + rhs.e + 64);
|
||||||
|
#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__)
|
||||||
|
unsigned __int128 p = static_cast<unsigned __int128>(f) * static_cast<unsigned __int128>(rhs.f);
|
||||||
|
uint64_t h = p >> 64;
|
||||||
|
uint64_t l = static_cast<uint64_t>(p);
|
||||||
|
if (l & (uint64_t(1) << 63)) // rounding
|
||||||
|
h++;
|
||||||
|
return DiyFp(h, e + rhs.e + 64);
|
||||||
|
#else
|
||||||
|
const uint64_t M32 = 0xFFFFFFFF;
|
||||||
|
const uint64_t a = f >> 32;
|
||||||
|
const uint64_t b = f & M32;
|
||||||
|
const uint64_t c = rhs.f >> 32;
|
||||||
|
const uint64_t d = rhs.f & M32;
|
||||||
|
const uint64_t ac = a * c;
|
||||||
|
const uint64_t bc = b * c;
|
||||||
|
const uint64_t ad = a * d;
|
||||||
|
const uint64_t bd = b * d;
|
||||||
|
uint64_t tmp = (bd >> 32) + (ad & M32) + (bc & M32);
|
||||||
|
tmp += 1U << 31; /// mult_round
|
||||||
|
return DiyFp(ac + (ad >> 32) + (bc >> 32) + (tmp >> 32), e + rhs.e + 64);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
DiyFp Normalize() const {
|
||||||
|
#if defined(_MSC_VER) && defined(_M_AMD64)
|
||||||
|
unsigned long index;
|
||||||
|
_BitScanReverse64(&index, f);
|
||||||
|
return DiyFp(f << (63 - index), e - (63 - index));
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
int s = __builtin_clzll(f);
|
||||||
|
return DiyFp(f << s, e - s);
|
||||||
|
#else
|
||||||
|
DiyFp res = *this;
|
||||||
|
while (!(res.f & kDpHiddenBit)) {
|
||||||
|
res.f <<= 1;
|
||||||
|
res.e--;
|
||||||
|
}
|
||||||
|
res.f <<= (kDiySignificandSize - kDpSignificandSize - 1);
|
||||||
|
res.e = res.e - (kDiySignificandSize - kDpSignificandSize - 1);
|
||||||
|
return res;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
DiyFp NormalizeBoundary() const {
|
||||||
|
#if defined(_MSC_VER) && defined(_M_AMD64)
|
||||||
|
unsigned long index;
|
||||||
|
_BitScanReverse64(&index, f);
|
||||||
|
return DiyFp (f << (63 - index), e - (63 - index));
|
||||||
|
#else
|
||||||
|
DiyFp res = *this;
|
||||||
|
while (!(res.f & (kDpHiddenBit << 1))) {
|
||||||
|
res.f <<= 1;
|
||||||
|
res.e--;
|
||||||
|
}
|
||||||
|
res.f <<= (kDiySignificandSize - kDpSignificandSize - 2);
|
||||||
|
res.e = res.e - (kDiySignificandSize - kDpSignificandSize - 2);
|
||||||
|
return res;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void NormalizedBoundaries(DiyFp* minus, DiyFp* plus) const {
|
||||||
|
DiyFp pl = DiyFp((f << 1) + 1, e - 1).NormalizeBoundary();
|
||||||
|
DiyFp mi = (f == kDpHiddenBit) ? DiyFp((f << 2) - 1, e - 2) : DiyFp((f << 1) - 1, e - 1);
|
||||||
|
mi.f <<= mi.e - pl.e;
|
||||||
|
mi.e = pl.e;
|
||||||
|
*plus = pl;
|
||||||
|
*minus = mi;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const int kDiySignificandSize = 64;
|
||||||
|
static const int kDpSignificandSize = 52;
|
||||||
|
static const int kDpExponentBias = 0x3FF + kDpSignificandSize;
|
||||||
|
static const int kDpMinExponent = -kDpExponentBias;
|
||||||
|
static const uint64_t kDpExponentMask = UINT64_C2(0x7FF00000, 0x00000000);
|
||||||
|
static const uint64_t kDpSignificandMask = UINT64_C2(0x000FFFFF, 0xFFFFFFFF);
|
||||||
|
static const uint64_t kDpHiddenBit = UINT64_C2(0x00100000, 0x00000000);
|
||||||
|
|
||||||
|
uint64_t f;
|
||||||
|
int e;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline DiyFp GetCachedPower(int e, int* K) {
|
||||||
|
// 10^-348, 10^-340, ..., 10^340
|
||||||
|
static const uint64_t kCachedPowers_F[] = {
|
||||||
|
UINT64_C2(0xfa8fd5a0, 0x081c0288), UINT64_C2(0xbaaee17f, 0xa23ebf76),
|
||||||
|
UINT64_C2(0x8b16fb20, 0x3055ac76), UINT64_C2(0xcf42894a, 0x5dce35ea),
|
||||||
|
UINT64_C2(0x9a6bb0aa, 0x55653b2d), UINT64_C2(0xe61acf03, 0x3d1a45df),
|
||||||
|
UINT64_C2(0xab70fe17, 0xc79ac6ca), UINT64_C2(0xff77b1fc, 0xbebcdc4f),
|
||||||
|
UINT64_C2(0xbe5691ef, 0x416bd60c), UINT64_C2(0x8dd01fad, 0x907ffc3c),
|
||||||
|
UINT64_C2(0xd3515c28, 0x31559a83), UINT64_C2(0x9d71ac8f, 0xada6c9b5),
|
||||||
|
UINT64_C2(0xea9c2277, 0x23ee8bcb), UINT64_C2(0xaecc4991, 0x4078536d),
|
||||||
|
UINT64_C2(0x823c1279, 0x5db6ce57), UINT64_C2(0xc2109436, 0x4dfb5637),
|
||||||
|
UINT64_C2(0x9096ea6f, 0x3848984f), UINT64_C2(0xd77485cb, 0x25823ac7),
|
||||||
|
UINT64_C2(0xa086cfcd, 0x97bf97f4), UINT64_C2(0xef340a98, 0x172aace5),
|
||||||
|
UINT64_C2(0xb23867fb, 0x2a35b28e), UINT64_C2(0x84c8d4df, 0xd2c63f3b),
|
||||||
|
UINT64_C2(0xc5dd4427, 0x1ad3cdba), UINT64_C2(0x936b9fce, 0xbb25c996),
|
||||||
|
UINT64_C2(0xdbac6c24, 0x7d62a584), UINT64_C2(0xa3ab6658, 0x0d5fdaf6),
|
||||||
|
UINT64_C2(0xf3e2f893, 0xdec3f126), UINT64_C2(0xb5b5ada8, 0xaaff80b8),
|
||||||
|
UINT64_C2(0x87625f05, 0x6c7c4a8b), UINT64_C2(0xc9bcff60, 0x34c13053),
|
||||||
|
UINT64_C2(0x964e858c, 0x91ba2655), UINT64_C2(0xdff97724, 0x70297ebd),
|
||||||
|
UINT64_C2(0xa6dfbd9f, 0xb8e5b88f), UINT64_C2(0xf8a95fcf, 0x88747d94),
|
||||||
|
UINT64_C2(0xb9447093, 0x8fa89bcf), UINT64_C2(0x8a08f0f8, 0xbf0f156b),
|
||||||
|
UINT64_C2(0xcdb02555, 0x653131b6), UINT64_C2(0x993fe2c6, 0xd07b7fac),
|
||||||
|
UINT64_C2(0xe45c10c4, 0x2a2b3b06), UINT64_C2(0xaa242499, 0x697392d3),
|
||||||
|
UINT64_C2(0xfd87b5f2, 0x8300ca0e), UINT64_C2(0xbce50864, 0x92111aeb),
|
||||||
|
UINT64_C2(0x8cbccc09, 0x6f5088cc), UINT64_C2(0xd1b71758, 0xe219652c),
|
||||||
|
UINT64_C2(0x9c400000, 0x00000000), UINT64_C2(0xe8d4a510, 0x00000000),
|
||||||
|
UINT64_C2(0xad78ebc5, 0xac620000), UINT64_C2(0x813f3978, 0xf8940984),
|
||||||
|
UINT64_C2(0xc097ce7b, 0xc90715b3), UINT64_C2(0x8f7e32ce, 0x7bea5c70),
|
||||||
|
UINT64_C2(0xd5d238a4, 0xabe98068), UINT64_C2(0x9f4f2726, 0x179a2245),
|
||||||
|
UINT64_C2(0xed63a231, 0xd4c4fb27), UINT64_C2(0xb0de6538, 0x8cc8ada8),
|
||||||
|
UINT64_C2(0x83c7088e, 0x1aab65db), UINT64_C2(0xc45d1df9, 0x42711d9a),
|
||||||
|
UINT64_C2(0x924d692c, 0xa61be758), UINT64_C2(0xda01ee64, 0x1a708dea),
|
||||||
|
UINT64_C2(0xa26da399, 0x9aef774a), UINT64_C2(0xf209787b, 0xb47d6b85),
|
||||||
|
UINT64_C2(0xb454e4a1, 0x79dd1877), UINT64_C2(0x865b8692, 0x5b9bc5c2),
|
||||||
|
UINT64_C2(0xc83553c5, 0xc8965d3d), UINT64_C2(0x952ab45c, 0xfa97a0b3),
|
||||||
|
UINT64_C2(0xde469fbd, 0x99a05fe3), UINT64_C2(0xa59bc234, 0xdb398c25),
|
||||||
|
UINT64_C2(0xf6c69a72, 0xa3989f5c), UINT64_C2(0xb7dcbf53, 0x54e9bece),
|
||||||
|
UINT64_C2(0x88fcf317, 0xf22241e2), UINT64_C2(0xcc20ce9b, 0xd35c78a5),
|
||||||
|
UINT64_C2(0x98165af3, 0x7b2153df), UINT64_C2(0xe2a0b5dc, 0x971f303a),
|
||||||
|
UINT64_C2(0xa8d9d153, 0x5ce3b396), UINT64_C2(0xfb9b7cd9, 0xa4a7443c),
|
||||||
|
UINT64_C2(0xbb764c4c, 0xa7a44410), UINT64_C2(0x8bab8eef, 0xb6409c1a),
|
||||||
|
UINT64_C2(0xd01fef10, 0xa657842c), UINT64_C2(0x9b10a4e5, 0xe9913129),
|
||||||
|
UINT64_C2(0xe7109bfb, 0xa19c0c9d), UINT64_C2(0xac2820d9, 0x623bf429),
|
||||||
|
UINT64_C2(0x80444b5e, 0x7aa7cf85), UINT64_C2(0xbf21e440, 0x03acdd2d),
|
||||||
|
UINT64_C2(0x8e679c2f, 0x5e44ff8f), UINT64_C2(0xd433179d, 0x9c8cb841),
|
||||||
|
UINT64_C2(0x9e19db92, 0xb4e31ba9), UINT64_C2(0xeb96bf6e, 0xbadf77d9),
|
||||||
|
UINT64_C2(0xaf87023b, 0x9bf0ee6b)
|
||||||
|
};
|
||||||
|
static const int16_t kCachedPowers_E[] = {
|
||||||
|
-1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980,
|
||||||
|
-954, -927, -901, -874, -847, -821, -794, -768, -741, -715,
|
||||||
|
-688, -661, -635, -608, -582, -555, -529, -502, -475, -449,
|
||||||
|
-422, -396, -369, -343, -316, -289, -263, -236, -210, -183,
|
||||||
|
-157, -130, -103, -77, -50, -24, 3, 30, 56, 83,
|
||||||
|
109, 136, 162, 189, 216, 242, 269, 295, 322, 348,
|
||||||
|
375, 402, 428, 455, 481, 508, 534, 561, 588, 614,
|
||||||
|
641, 667, 694, 720, 747, 774, 800, 827, 853, 880,
|
||||||
|
907, 933, 960, 986, 1013, 1039, 1066
|
||||||
|
};
|
||||||
|
|
||||||
|
//int k = static_cast<int>(ceil((-61 - e) * 0.30102999566398114)) + 374;
|
||||||
|
double dk = (-61 - e) * 0.30102999566398114 + 347; // dk must be positive, so can do ceiling in positive
|
||||||
|
int k = static_cast<int>(dk);
|
||||||
|
if (k != dk)
|
||||||
|
k++;
|
||||||
|
|
||||||
|
unsigned index = static_cast<unsigned>((k >> 3) + 1);
|
||||||
|
*K = -(-348 + static_cast<int>(index << 3)); // decimal exponent no need lookup table
|
||||||
|
|
||||||
|
assert(index < sizeof(kCachedPowers_F) / sizeof(kCachedPowers_F[0]));
|
||||||
|
return DiyFp(kCachedPowers_F[index], kCachedPowers_E[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void GrisuRound(char* buffer, int len, uint64_t delta, uint64_t rest, uint64_t ten_kappa, uint64_t wp_w) {
|
||||||
|
while (rest < wp_w && delta - rest >= ten_kappa &&
|
||||||
|
(rest + ten_kappa < wp_w || /// closer
|
||||||
|
wp_w - rest > rest + ten_kappa - wp_w)) {
|
||||||
|
buffer[len - 1]--;
|
||||||
|
rest += ten_kappa;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline unsigned CountDecimalDigit32(uint32_t n) {
|
||||||
|
// Simple pure C++ implementation was faster than __builtin_clz version in this situation.
|
||||||
|
if (n < 10) return 1;
|
||||||
|
if (n < 100) return 2;
|
||||||
|
if (n < 1000) return 3;
|
||||||
|
if (n < 10000) return 4;
|
||||||
|
if (n < 100000) return 5;
|
||||||
|
if (n < 1000000) return 6;
|
||||||
|
if (n < 10000000) return 7;
|
||||||
|
if (n < 100000000) return 8;
|
||||||
|
if (n < 1000000000) return 9;
|
||||||
|
return 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buffer, int* len, int* K) {
|
||||||
|
static const uint32_t kPow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
|
||||||
|
const DiyFp one(uint64_t(1) << -Mp.e, Mp.e);
|
||||||
|
const DiyFp wp_w = Mp - W;
|
||||||
|
uint32_t p1 = static_cast<uint32_t>(Mp.f >> -one.e);
|
||||||
|
uint64_t p2 = Mp.f & (one.f - 1);
|
||||||
|
int kappa = static_cast<int>(CountDecimalDigit32(p1));
|
||||||
|
*len = 0;
|
||||||
|
|
||||||
|
while (kappa > 0) {
|
||||||
|
uint32_t d;
|
||||||
|
switch (kappa) {
|
||||||
|
case 10: d = p1 / 1000000000; p1 %= 1000000000; break;
|
||||||
|
case 9: d = p1 / 100000000; p1 %= 100000000; break;
|
||||||
|
case 8: d = p1 / 10000000; p1 %= 10000000; break;
|
||||||
|
case 7: d = p1 / 1000000; p1 %= 1000000; break;
|
||||||
|
case 6: d = p1 / 100000; p1 %= 100000; break;
|
||||||
|
case 5: d = p1 / 10000; p1 %= 10000; break;
|
||||||
|
case 4: d = p1 / 1000; p1 %= 1000; break;
|
||||||
|
case 3: d = p1 / 100; p1 %= 100; break;
|
||||||
|
case 2: d = p1 / 10; p1 %= 10; break;
|
||||||
|
case 1: d = p1; p1 = 0; break;
|
||||||
|
default:
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
__assume(0);
|
||||||
|
#elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
|
||||||
|
__builtin_unreachable();
|
||||||
|
#else
|
||||||
|
d = 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (d || *len)
|
||||||
|
buffer[(*len)++] = '0' + static_cast<char>(d);
|
||||||
|
kappa--;
|
||||||
|
uint64_t tmp = (static_cast<uint64_t>(p1) << -one.e) + p2;
|
||||||
|
if (tmp <= delta) {
|
||||||
|
*K += kappa;
|
||||||
|
GrisuRound(buffer, *len, delta, tmp, static_cast<uint64_t>(kPow10[kappa]) << -one.e, wp_w.f);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// kappa = 0
|
||||||
|
for (;;) {
|
||||||
|
p2 *= 10;
|
||||||
|
delta *= 10;
|
||||||
|
char d = static_cast<char>(p2 >> -one.e);
|
||||||
|
if (d || *len)
|
||||||
|
buffer[(*len)++] = '0' + d;
|
||||||
|
p2 &= one.f - 1;
|
||||||
|
kappa--;
|
||||||
|
if (p2 < delta) {
|
||||||
|
*K += kappa;
|
||||||
|
GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * kPow10[-kappa]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Grisu2(double value, char* buffer, int* length, int* K) {
|
||||||
|
const DiyFp v(value);
|
||||||
|
DiyFp w_m, w_p;
|
||||||
|
v.NormalizedBoundaries(&w_m, &w_p);
|
||||||
|
|
||||||
|
const DiyFp c_mk = GetCachedPower(w_p.e, K);
|
||||||
|
const DiyFp W = v.Normalize() * c_mk;
|
||||||
|
DiyFp Wp = w_p * c_mk;
|
||||||
|
DiyFp Wm = w_m * c_mk;
|
||||||
|
Wm.f++;
|
||||||
|
Wp.f--;
|
||||||
|
DigitGen(W, Wp, Wp.f - Wm.f, buffer, length, K);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const char* GetDigitsLut() {
|
||||||
|
static const char cDigitsLut[200] = {
|
||||||
|
'0', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '0', '6', '0', '7', '0', '8', '0', '9',
|
||||||
|
'1', '0', '1', '1', '1', '2', '1', '3', '1', '4', '1', '5', '1', '6', '1', '7', '1', '8', '1', '9',
|
||||||
|
'2', '0', '2', '1', '2', '2', '2', '3', '2', '4', '2', '5', '2', '6', '2', '7', '2', '8', '2', '9',
|
||||||
|
'3', '0', '3', '1', '3', '2', '3', '3', '3', '4', '3', '5', '3', '6', '3', '7', '3', '8', '3', '9',
|
||||||
|
'4', '0', '4', '1', '4', '2', '4', '3', '4', '4', '4', '5', '4', '6', '4', '7', '4', '8', '4', '9',
|
||||||
|
'5', '0', '5', '1', '5', '2', '5', '3', '5', '4', '5', '5', '5', '6', '5', '7', '5', '8', '5', '9',
|
||||||
|
'6', '0', '6', '1', '6', '2', '6', '3', '6', '4', '6', '5', '6', '6', '6', '7', '6', '8', '6', '9',
|
||||||
|
'7', '0', '7', '1', '7', '2', '7', '3', '7', '4', '7', '5', '7', '6', '7', '7', '7', '8', '7', '9',
|
||||||
|
'8', '0', '8', '1', '8', '2', '8', '3', '8', '4', '8', '5', '8', '6', '8', '7', '8', '8', '8', '9',
|
||||||
|
'9', '0', '9', '1', '9', '2', '9', '3', '9', '4', '9', '5', '9', '6', '9', '7', '9', '8', '9', '9'
|
||||||
|
};
|
||||||
|
return cDigitsLut;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint32_t WriteExponent(int K, char* buffer) {
|
||||||
|
char* start = buffer;
|
||||||
|
|
||||||
|
if (K < 0) {
|
||||||
|
*buffer++ = '-';
|
||||||
|
K = -K;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (K >= 100) {
|
||||||
|
*buffer++ = '0' + static_cast<char>(K / 100);
|
||||||
|
K %= 100;
|
||||||
|
const char* d = GetDigitsLut() + K * 2;
|
||||||
|
*buffer++ = d[0];
|
||||||
|
*buffer++ = d[1];
|
||||||
|
}
|
||||||
|
else if (K >= 10) {
|
||||||
|
const char* d = GetDigitsLut() + K * 2;
|
||||||
|
*buffer++ = d[0];
|
||||||
|
*buffer++ = d[1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*buffer++ = '0' + static_cast<char>(K);
|
||||||
|
|
||||||
|
return buffer - start;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint32_t Prettify(char* buffer, int length, int k)
|
||||||
|
{
|
||||||
|
const int kk = length + k; // 10^(kk-1) <= v < 10^kk
|
||||||
|
|
||||||
|
if (length <= kk && kk <= 21)
|
||||||
|
{
|
||||||
|
// 1234e7 -> 12340000000
|
||||||
|
for (int i = length; i < kk; i++) buffer[i] = '0';
|
||||||
|
|
||||||
|
buffer[kk] = '.';
|
||||||
|
buffer[kk + 1] = '0';
|
||||||
|
|
||||||
|
return kk + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 < kk && kk <= 21)
|
||||||
|
{
|
||||||
|
// 1234e-2 -> 12.34
|
||||||
|
memmove(&buffer[kk + 1], &buffer[kk], length - kk);
|
||||||
|
|
||||||
|
buffer[kk] = '.';
|
||||||
|
|
||||||
|
return length + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-6 < kk && kk <= 0)
|
||||||
|
{
|
||||||
|
// 1234e-6 -> 0.001234
|
||||||
|
const int offset = 2 - kk;
|
||||||
|
memmove(&buffer[offset], &buffer[0], length);
|
||||||
|
|
||||||
|
buffer[0] = '0';
|
||||||
|
buffer[1] = '.';
|
||||||
|
|
||||||
|
for (int i = 2; i < offset; i++) buffer[i] = '0';
|
||||||
|
|
||||||
|
return length + offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length == 1)
|
||||||
|
{
|
||||||
|
// 1e30
|
||||||
|
buffer[1] = 'e';
|
||||||
|
|
||||||
|
return 2 + WriteExponent(kk - 1, &buffer[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1234e30 -> 1.234e33
|
||||||
|
memmove(&buffer[2], &buffer[1], length - 1);
|
||||||
|
buffer[1] = '.';
|
||||||
|
buffer[length + 1] = 'e';
|
||||||
|
|
||||||
|
return length + 2 + WriteExponent(kk - 1, &buffer[0 + length + 2]);
|
||||||
|
}
|
|
@ -81,22 +81,9 @@ public:
|
||||||
{
|
{
|
||||||
U_TRACE(0, "UStringExt::printSize(%I)", n)
|
U_TRACE(0, "UStringExt::printSize(%I)", n)
|
||||||
|
|
||||||
UString x(22U);
|
|
||||||
|
|
||||||
u_printSize(x.data(), n);
|
|
||||||
|
|
||||||
x.size_adjust();
|
|
||||||
|
|
||||||
U_RETURN_STRING(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
static UString numberToString(double n)
|
|
||||||
{
|
|
||||||
U_TRACE(0, "UStringExt::numberToString(%f)", n)
|
|
||||||
|
|
||||||
UString x(32U);
|
UString x(32U);
|
||||||
|
|
||||||
x.snprintf("%f", n);
|
x.rep->_length = u_printSize(x.data(), n);
|
||||||
|
|
||||||
U_RETURN_STRING(x);
|
U_RETURN_STRING(x);
|
||||||
}
|
}
|
||||||
|
@ -114,9 +101,21 @@ public:
|
||||||
|
|
||||||
static UString numberToString(uint64_t n);
|
static UString numberToString(uint64_t n);
|
||||||
|
|
||||||
|
static UString numberToString(double n)
|
||||||
|
{
|
||||||
|
U_TRACE(0, "UStringExt::numberToString(%f)", n)
|
||||||
|
|
||||||
|
UString x(32U);
|
||||||
|
char* ptr = x.data();
|
||||||
|
|
||||||
|
ptr[(x.rep->_length = u_dtoa(n, ptr))] = '\0';
|
||||||
|
|
||||||
|
U_RETURN_STRING(x);
|
||||||
|
}
|
||||||
|
|
||||||
static UString stringFromNumber(long n)
|
static UString stringFromNumber(long n)
|
||||||
{
|
{
|
||||||
U_TRACE(0, "UStringExt::stringFromNumber(%lld)", n)
|
U_TRACE(0, "UStringExt::stringFromNumber(%ld)", n)
|
||||||
|
|
||||||
UString x(22U);
|
UString x(22U);
|
||||||
|
|
||||||
|
@ -133,20 +132,24 @@ public:
|
||||||
{
|
{
|
||||||
U_TRACE(0, "UStringExt::appendNumber32(%V,%u)", s.rep, number)
|
U_TRACE(0, "UStringExt::appendNumber32(%V,%u)", s.rep, number)
|
||||||
|
|
||||||
char buffer[10];
|
uint32_t sz = s.size();
|
||||||
char* ptr = buffer;
|
char* ptr = s.c_pointer(sz);
|
||||||
|
|
||||||
(void) s.append(buffer, u_num2str32(number, ptr));
|
s.rep->_length = sz + u_num2str32(number, ptr);
|
||||||
|
|
||||||
|
U_INTERNAL_ASSERT(s.invariant())
|
||||||
}
|
}
|
||||||
|
|
||||||
static void appendNumber64(UString& s, uint64_t number)
|
static void appendNumber64(UString& s, uint64_t number)
|
||||||
{
|
{
|
||||||
U_TRACE(0, "UStringExt::appendNumber64(%V,%llu)", s.rep, number)
|
U_TRACE(0, "UStringExt::appendNumber64(%V,%llu)", s.rep, number)
|
||||||
|
|
||||||
char buffer[22];
|
uint32_t sz = s.size();
|
||||||
char* ptr = buffer;
|
char* ptr = s.c_pointer(sz);
|
||||||
|
|
||||||
(void) s.append(buffer, u_num2str64(number, ptr));
|
s.rep->_length = sz + u_num2str64(number, ptr);
|
||||||
|
|
||||||
|
U_INTERNAL_ASSERT(s.invariant())
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert letter to upper or lower case
|
// convert letter to upper or lower case
|
||||||
|
|
|
@ -484,11 +484,17 @@ dnl libssh_version=$(grep LIBSFTP_VERSION $sshdir/include/libssh/sftp.h | cut -
|
||||||
echo "${T_MD}libcurl found in $curldir${T_ME}"
|
echo "${T_MD}libcurl found in $curldir${T_ME}"
|
||||||
USE_LIBCURL=yes
|
USE_LIBCURL=yes
|
||||||
AC_DEFINE(USE_LIBCURL, 1, [Define if enable libcurL support])
|
AC_DEFINE(USE_LIBCURL, 1, [Define if enable libcurL support])
|
||||||
libcurl_version=$($curldir/bin/curl-config --version 2>/dev/null | sed -e "s/libcurl //g")
|
if test x_$PKG_CONFIG != x_no; then
|
||||||
|
libcurl_version=$(pkg-config --modversion libcurl)
|
||||||
|
fi
|
||||||
|
if test -z "${libcurl_version}"; then
|
||||||
|
libcurl_version=$($curldir/bin/curl-config --version 2>/dev/null | sed -e "s/libcurl //g")
|
||||||
|
fi
|
||||||
if test -z "${libcurl_version}"; then
|
if test -z "${libcurl_version}"; then
|
||||||
libcurl_version="unknown"
|
libcurl_version="unknown"
|
||||||
fi
|
fi
|
||||||
ULIB_LIBS="-lcurl $ULIB_LIBS";
|
libcurl_linking=$($curldir/bin/curl-config --libs 2>/dev/null)
|
||||||
|
ULIB_LIBS="$libcurl_linking $ULIB_LIBS";
|
||||||
if test $curldir != "${CROSS_ENVIRONMENT}/" -a $curldir != "${CROSS_ENVIRONMENT}/usr" -a $curldir != "${CROSS_ENVIRONMENT}/usr/local"; then
|
if test $curldir != "${CROSS_ENVIRONMENT}/" -a $curldir != "${CROSS_ENVIRONMENT}/usr" -a $curldir != "${CROSS_ENVIRONMENT}/usr/local"; then
|
||||||
CPPFLAGS="$CPPFLAGS -I$curldir/include";
|
CPPFLAGS="$CPPFLAGS -I$curldir/include";
|
||||||
LDFLAGS="$LDFLAGS -L$curldir/lib -Wl,-R$curldir/lib";
|
LDFLAGS="$LDFLAGS -L$curldir/lib -Wl,-R$curldir/lib";
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -680,24 +680,32 @@ double u_calcRate(uint64_t bytes, uint32_t msecs, int* restrict units)
|
||||||
return rate;
|
return rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
void u_printSize(char* restrict buffer, uint64_t bytes)
|
uint32_t u_printSize(char* restrict buffer, uint64_t bytes)
|
||||||
{
|
{
|
||||||
int units;
|
int units;
|
||||||
double size;
|
double size;
|
||||||
|
uint32_t len;
|
||||||
|
|
||||||
U_INTERNAL_TRACE("u_printSize(%p,%llu)", buffer, bytes)
|
U_INTERNAL_TRACE("u_printSize(%p,%llu)", buffer, bytes)
|
||||||
|
|
||||||
if (bytes == 0)
|
if (bytes == 0)
|
||||||
{
|
{
|
||||||
u__strcpy(buffer, "0 Byte");
|
u_put_unalignedp32(buffer, U_MULTICHAR_CONSTANT32('0',' ','B','y'));
|
||||||
|
u_put_unalignedp16(buffer+4, U_MULTICHAR_CONSTANT16('t','e'));
|
||||||
|
|
||||||
return;
|
len = 6;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size = u_calcRate(bytes, 1000, &units);
|
||||||
|
|
||||||
|
len = (units ? sprintf(buffer, "%5.2f %s", size, u_short_units[units])
|
||||||
|
: sprintf(buffer, "%7.0f Bytes", size));
|
||||||
}
|
}
|
||||||
|
|
||||||
size = u_calcRate(bytes, 1000, &units);
|
buffer[len] = '\0';
|
||||||
|
|
||||||
if (units) (void) sprintf(buffer, "%5.2f %s", size, u_short_units[units]);
|
return len;
|
||||||
else (void) sprintf(buffer, "%7.0f Bytes", size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t u_memory_dump(char* restrict bp, unsigned char* restrict cp, uint32_t n)
|
uint32_t u_memory_dump(char* restrict bp, unsigned char* restrict cp, uint32_t n)
|
||||||
|
|
|
@ -134,7 +134,7 @@ U_NO_EXPORT size_t UCURL::writeFunction(void* ptr, size_t size, size_t nmemb, vo
|
||||||
|
|
||||||
size_t len = size * nmemb;
|
size_t len = size * nmemb;
|
||||||
|
|
||||||
(void) ((UCURL*)obj)->response.reserve(((UCURL*)obj)->response.size() + len);
|
(void) ((UCURL*)obj)->response.reserve(len);
|
||||||
|
|
||||||
((UCURL*)obj)->response.append((const char*)ptr, len);
|
((UCURL*)obj)->response.append((const char*)ptr, len);
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,9 @@
|
||||||
# include "./itoa.cpp"
|
# include "./itoa.cpp"
|
||||||
static uint32_t itoa32(uint32_t num, char* restrict cp) { return itoa_fwd(num, cp) - cp; }
|
static uint32_t itoa32(uint32_t num, char* restrict cp) { return itoa_fwd(num, cp) - cp; }
|
||||||
static uint32_t itoa64(uint64_t num, char* restrict cp) { return itoa_fwd(num, cp) - cp; }
|
static uint32_t itoa64(uint64_t num, char* restrict cp) { return itoa_fwd(num, cp) - cp; }
|
||||||
# endif
|
# elif (defined(i386) || defined(__amd64) || defined(_M_IX86) || defined(_M_X64)) && !defined(HAVE_OLD_IOSTREAM) && !defined(_MSWINDOWS_) && defined(HAVE_ARCH64)
|
||||||
|
# include "./itoa_sse2.cpp"
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
U_EXPORT bool __cxa_guard_acquire() { return 1; }
|
U_EXPORT bool __cxa_guard_acquire() { return 1; }
|
||||||
U_EXPORT bool __cxa_guard_release() { return 1; }
|
U_EXPORT bool __cxa_guard_release() { return 1; }
|
||||||
|
@ -33,7 +35,6 @@ U_EXPORT void* operator new( size_t n) { return malloc(n); }
|
||||||
U_EXPORT void* operator new[](size_t n) { return malloc(n); }
|
U_EXPORT void* operator new[](size_t n) { return malloc(n); }
|
||||||
U_EXPORT void operator delete( void* p) { free(p); }
|
U_EXPORT void operator delete( void* p) { free(p); }
|
||||||
U_EXPORT void operator delete[](void* p) { free(p); }
|
U_EXPORT void operator delete[](void* p) { free(p); }
|
||||||
|
|
||||||
# ifdef __MINGW32__
|
# ifdef __MINGW32__
|
||||||
U_EXPORT void operator delete( void* p, unsigned int) { free(p); }
|
U_EXPORT void operator delete( void* p, unsigned int) { free(p); }
|
||||||
U_EXPORT void operator delete[](void* p, unsigned int) { free(p); }
|
U_EXPORT void operator delete[](void* p, unsigned int) { free(p); }
|
||||||
|
@ -70,7 +71,7 @@ void ULib_init_openssl()
|
||||||
// is responsible for seeding the PRNG by calling RAND_add()
|
// is responsible for seeding the PRNG by calling RAND_add()
|
||||||
|
|
||||||
# ifdef _MSWINDOWS_
|
# ifdef _MSWINDOWS_
|
||||||
U_SYSCALL_VOID(srand, "%ld", u_start_time); // seed with time
|
U_SYSCALL_VOID(srand, "%ld", u_seed_hash);
|
||||||
|
|
||||||
while (RAND_status() == 0) // Seed PRNG only if needed
|
while (RAND_status() == 0) // Seed PRNG only if needed
|
||||||
{
|
{
|
||||||
|
@ -84,13 +85,29 @@ void ULib_init_openssl()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_OLD_IOSTREAM
|
||||||
|
# include <ulib/utility/dtoa_milo.h>
|
||||||
|
static uint32_t dtoa_milo(double value, char* buffer) { int length, K; Grisu2(value, buffer, &length, &K); return Prettify(buffer, length, K); }
|
||||||
|
#endif
|
||||||
|
|
||||||
void ULib_init()
|
void ULib_init()
|
||||||
{
|
{
|
||||||
U_TRACE_NO_PARAM(1, "ULib_init()")
|
U_TRACE_NO_PARAM(1, "ULib_init()")
|
||||||
|
|
||||||
|
// conversion number to string
|
||||||
|
|
||||||
|
#ifndef HAVE_OLD_IOSTREAM
|
||||||
|
u_dbl2str = dtoa_milo;
|
||||||
|
#endif
|
||||||
#if defined(HAVE_CXX14) && GCC_VERSION_NUM > 60100
|
#if defined(HAVE_CXX14) && GCC_VERSION_NUM > 60100
|
||||||
u_num2str32 = itoa32;
|
u_num2str32 = itoa32;
|
||||||
u_num2str64 = itoa64;
|
u_num2str64 = itoa64;
|
||||||
|
#elif (defined(i386) || defined(__amd64) || defined(_M_IX86) || defined(_M_X64)) && !defined(HAVE_OLD_IOSTREAM) && !defined(_MSWINDOWS_) && defined(HAVE_ARCH64)
|
||||||
|
if (u_flag_sse >= 2)
|
||||||
|
{
|
||||||
|
u_num2str32 = utoa32_sse2;
|
||||||
|
u_num2str64 = utoa64_sse2;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
307
src/ulib/internal/itoa_sse2.cpp
Normal file
307
src/ulib/internal/itoa_sse2.cpp
Normal file
|
@ -0,0 +1,307 @@
|
||||||
|
// SSE2 implementation according to http://0x80.pl/articles/sse-itoa.html
|
||||||
|
// Modifications: (1) fix incorrect digits (2) accept all ranges (3) write to user provided buffer.
|
||||||
|
|
||||||
|
#if defined(i386) || defined(__amd64) || defined(_M_IX86) || defined(_M_X64)
|
||||||
|
|
||||||
|
#include <emmintrin.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#include "intrin.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#define ALIGN_PRE __declspec(align(16))
|
||||||
|
#define ALIGN_SUF
|
||||||
|
#else
|
||||||
|
#define ALIGN_PRE
|
||||||
|
#define ALIGN_SUF __attribute__ ((aligned(16)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static const uint32_t kDiv10000 = 0xd1b71759;
|
||||||
|
ALIGN_PRE static const uint32_t kDiv10000Vector[4] ALIGN_SUF = { kDiv10000, kDiv10000, kDiv10000, kDiv10000 };
|
||||||
|
ALIGN_PRE static const uint32_t k10000Vector[4] ALIGN_SUF = { 10000, 10000, 10000, 10000 };
|
||||||
|
ALIGN_PRE static const uint16_t kDivPowersVector[8] ALIGN_SUF = { 8389, 5243, 13108, 32768, 8389, 5243, 13108, 32768 }; // 10^3, 10^2, 10^1, 10^0
|
||||||
|
ALIGN_PRE static const uint16_t kShiftPowersVector[8] ALIGN_SUF = {
|
||||||
|
1 << (16 - (23 + 2 - 16)),
|
||||||
|
1 << (16 - (19 + 2 - 16)),
|
||||||
|
1 << (16 - 1 - 2),
|
||||||
|
1 << (15),
|
||||||
|
1 << (16 - (23 + 2 - 16)),
|
||||||
|
1 << (16 - (19 + 2 - 16)),
|
||||||
|
1 << (16 - 1 - 2),
|
||||||
|
1 << (15)
|
||||||
|
};
|
||||||
|
ALIGN_PRE static const uint16_t k10Vector[8] ALIGN_SUF = { 10, 10, 10, 10, 10, 10, 10, 10 };
|
||||||
|
ALIGN_PRE static const char kAsciiZero[16] ALIGN_SUF = { '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0' };
|
||||||
|
|
||||||
|
inline __pure __m128i Convert8DigitsSSE2(uint32_t value) {
|
||||||
|
|
||||||
|
// abcd, efgh = abcdefgh divmod 10000
|
||||||
|
const __m128i abcdefgh = _mm_cvtsi32_si128(value);
|
||||||
|
const __m128i abcd = _mm_srli_epi64(_mm_mul_epu32(abcdefgh, reinterpret_cast<const __m128i*>(kDiv10000Vector)[0]), 45);
|
||||||
|
const __m128i efgh = _mm_sub_epi32(abcdefgh, _mm_mul_epu32(abcd, reinterpret_cast<const __m128i*>(k10000Vector)[0]));
|
||||||
|
|
||||||
|
// v1 = [ abcd, efgh, 0, 0, 0, 0, 0, 0 ]
|
||||||
|
const __m128i v1 = _mm_unpacklo_epi16(abcd, efgh);
|
||||||
|
|
||||||
|
// v1a = v1 * 4 = [ abcd * 4, efgh * 4, 0, 0, 0, 0, 0, 0 ]
|
||||||
|
const __m128i v1a = _mm_slli_epi64(v1, 2);
|
||||||
|
|
||||||
|
// v2 = [ abcd * 4, abcd * 4, abcd * 4, abcd * 4, efgh * 4, efgh * 4, efgh * 4, efgh * 4 ]
|
||||||
|
const __m128i v2a = _mm_unpacklo_epi16(v1a, v1a);
|
||||||
|
const __m128i v2 = _mm_unpacklo_epi32(v2a, v2a);
|
||||||
|
|
||||||
|
// v4 = v2 div 10^3, 10^2, 10^1, 10^0 = [ a, ab, abc, abcd, e, ef, efg, efgh ]
|
||||||
|
const __m128i v3 = _mm_mulhi_epu16(v2, reinterpret_cast<const __m128i*>(kDivPowersVector)[0]);
|
||||||
|
const __m128i v4 = _mm_mulhi_epu16(v3, reinterpret_cast<const __m128i*>(kShiftPowersVector)[0]);
|
||||||
|
|
||||||
|
// v5 = v4 * 10 = [ a0, ab0, abc0, abcd0, e0, ef0, efg0, efgh0 ]
|
||||||
|
const __m128i v5 = _mm_mullo_epi16(v4, reinterpret_cast<const __m128i*>(k10Vector)[0]);
|
||||||
|
|
||||||
|
// v6 = v5 << 16 = [ 0, a0, ab0, abc0, 0, e0, ef0, efg0 ]
|
||||||
|
const __m128i v6 = _mm_slli_epi64(v5, 16);
|
||||||
|
|
||||||
|
// v7 = v4 - v6 = { a, b, c, d, e, f, g, h }
|
||||||
|
const __m128i v7 = _mm_sub_epi16(v4, v6);
|
||||||
|
|
||||||
|
return v7;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline __pure __m128i ShiftDigits_SSE2(__m128i a, unsigned digit) {
|
||||||
|
switch (digit) {
|
||||||
|
case 0: return a;
|
||||||
|
case 1: return _mm_srli_si128(a, 1);
|
||||||
|
case 2: return _mm_srli_si128(a, 2);
|
||||||
|
case 3: return _mm_srli_si128(a, 3);
|
||||||
|
case 4: return _mm_srli_si128(a, 4);
|
||||||
|
case 5: return _mm_srli_si128(a, 5);
|
||||||
|
case 6: return _mm_srli_si128(a, 6);
|
||||||
|
case 7: return _mm_srli_si128(a, 7);
|
||||||
|
case 8: return _mm_srli_si128(a, 8);
|
||||||
|
}
|
||||||
|
return a; // should not execute here.
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t utoa32_sse2(uint32_t value, char* buffer)
|
||||||
|
{
|
||||||
|
char* start = buffer;
|
||||||
|
|
||||||
|
if (value < 10000)
|
||||||
|
{
|
||||||
|
const uint32_t d1 = (value / 100) << 1;
|
||||||
|
const uint32_t d2 = (value % 100) << 1;
|
||||||
|
|
||||||
|
if (value >= 1000) *buffer++ = u_ctn2s[d1];
|
||||||
|
if (value >= 100) *buffer++ = u_ctn2s[d1+1];
|
||||||
|
if (value >= 10) *buffer++ = u_ctn2s[d2];
|
||||||
|
*buffer++ = u_ctn2s[d2+1];
|
||||||
|
|
||||||
|
return (buffer - start);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value < 100000000)
|
||||||
|
{
|
||||||
|
// Experiment shows that in this case SSE2 is slower
|
||||||
|
# if 0
|
||||||
|
const __m128i a = Convert8DigitsSSE2(value);
|
||||||
|
|
||||||
|
// Convert to bytes, add '0'
|
||||||
|
const __m128i va = _mm_add_epi8(_mm_packus_epi16(a, _mm_setzero_si128()), reinterpret_cast<const __m128i*>(kAsciiZero)[0]);
|
||||||
|
|
||||||
|
// Count number of digit
|
||||||
|
const unsigned mask = _mm_movemask_epi8(_mm_cmpeq_epi8(va, reinterpret_cast<const __m128i*>(kAsciiZero)[0]));
|
||||||
|
unsigned long digit;
|
||||||
|
# ifdef _MSC_VER
|
||||||
|
_BitScanForward(&digit, ~mask | 0x8000);
|
||||||
|
# else
|
||||||
|
digit = __builtin_ctz(~mask | 0x8000);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
// Shift digits to the beginning
|
||||||
|
__m128i result = ShiftDigits_SSE2(va, digit);
|
||||||
|
//__m128i result = _mm_srl_epi64(va, _mm_cvtsi32_si128(digit * 8));
|
||||||
|
_mm_storel_epi64(reinterpret_cast<__m128i*>(buffer), result);
|
||||||
|
|
||||||
|
return (buffer + 8 - digit - start);
|
||||||
|
# else
|
||||||
|
// value = bbbbcccc
|
||||||
|
const uint32_t b = value / 10000;
|
||||||
|
const uint32_t c = value % 10000;
|
||||||
|
|
||||||
|
const uint32_t d1 = (b / 100) << 1;
|
||||||
|
const uint32_t d2 = (b % 100) << 1;
|
||||||
|
|
||||||
|
const uint32_t d3 = (c / 100);
|
||||||
|
const uint32_t d4 = (c % 100);
|
||||||
|
|
||||||
|
if (value >= 10000000) *buffer++ = u_ctn2s[d1];
|
||||||
|
if (value >= 1000000) *buffer++ = u_ctn2s[d1+1];
|
||||||
|
if (value >= 100000) *buffer++ = u_ctn2s[d2];
|
||||||
|
*buffer++ = u_ctn2s[d2+1];
|
||||||
|
|
||||||
|
U_NUM2STR16(buffer, d3);
|
||||||
|
U_NUM2STR16(buffer+2, d4);
|
||||||
|
|
||||||
|
return (buffer + 4 - start);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// value = aabbbbbbbb in decimal
|
||||||
|
|
||||||
|
const uint32_t a = value / 100000000; // 1 to 42
|
||||||
|
value %= 100000000;
|
||||||
|
|
||||||
|
if (a < 10) *buffer++ = '0' + (char)a;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
U_NUM2STR16(buffer, a);
|
||||||
|
|
||||||
|
buffer += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
const __m128i b = Convert8DigitsSSE2(value);
|
||||||
|
const __m128i ba = _mm_add_epi8(_mm_packus_epi16(_mm_setzero_si128(), b), reinterpret_cast<const __m128i*>(kAsciiZero)[0]);
|
||||||
|
const __m128i result = _mm_srli_si128(ba, 8);
|
||||||
|
|
||||||
|
_mm_storel_epi64(reinterpret_cast<__m128i*>(buffer), result);
|
||||||
|
|
||||||
|
return (buffer + 8 - start);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t utoa64_sse2(uint64_t value, char* buffer)
|
||||||
|
{
|
||||||
|
char* start = buffer;
|
||||||
|
|
||||||
|
if (value < 100000000)
|
||||||
|
{
|
||||||
|
uint32_t v = static_cast<uint32_t>(value);
|
||||||
|
|
||||||
|
if (v < 10000)
|
||||||
|
{
|
||||||
|
const uint32_t d1 = (v / 100) << 1;
|
||||||
|
const uint32_t d2 = (v % 100) << 1;
|
||||||
|
|
||||||
|
if (v >= 1000) *buffer++ = u_ctn2s[d1];
|
||||||
|
if (v >= 100) *buffer++ = u_ctn2s[d1+1];
|
||||||
|
if (v >= 10) *buffer++ = u_ctn2s[d2];
|
||||||
|
*buffer++ = u_ctn2s[d2+1];
|
||||||
|
|
||||||
|
return (buffer - start);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Experiment shows that in this case SSE2 is slower
|
||||||
|
# if 0
|
||||||
|
const __m128i a = Convert8DigitsSSE2(v);
|
||||||
|
|
||||||
|
// Convert to bytes, add '0'
|
||||||
|
const __m128i va = _mm_add_epi8(_mm_packus_epi16(a, _mm_setzero_si128()), reinterpret_cast<const __m128i*>(kAsciiZero)[0]);
|
||||||
|
|
||||||
|
// Count number of digit
|
||||||
|
const unsigned mask = _mm_movemask_epi8(_mm_cmpeq_epi8(va, reinterpret_cast<const __m128i*>(kAsciiZero)[0]));
|
||||||
|
unsigned long digit;
|
||||||
|
# ifdef _MSC_VER
|
||||||
|
_BitScanForward(&digit, ~mask | 0x8000);
|
||||||
|
# else
|
||||||
|
digit = __builtin_ctz(~mask | 0x8000);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
// Shift digits to the beginning
|
||||||
|
__m128i result = ShiftDigits_SSE2(va, digit);
|
||||||
|
_mm_storel_epi64(reinterpret_cast<__m128i*>(buffer), result);
|
||||||
|
|
||||||
|
return (buffer + 8 - digit - start);
|
||||||
|
# else
|
||||||
|
// value = bbbbcccc
|
||||||
|
const uint32_t b = v / 10000;
|
||||||
|
const uint32_t c = v % 10000;
|
||||||
|
|
||||||
|
const uint32_t d1 = (b / 100) << 1;
|
||||||
|
const uint32_t d2 = (b % 100) << 1;
|
||||||
|
|
||||||
|
const uint32_t d3 = (c / 100);
|
||||||
|
const uint32_t d4 = (c % 100);
|
||||||
|
|
||||||
|
if (value >= 10000000) *buffer++ = u_ctn2s[d1];
|
||||||
|
if (value >= 1000000) *buffer++ = u_ctn2s[d1+1];
|
||||||
|
if (value >= 100000) *buffer++ = u_ctn2s[d2];
|
||||||
|
*buffer++ = u_ctn2s[d2+1];
|
||||||
|
|
||||||
|
U_NUM2STR16(buffer, d3);
|
||||||
|
U_NUM2STR16(buffer+2, d4);
|
||||||
|
|
||||||
|
return (buffer + 4 - start);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value < 10000000000000000)
|
||||||
|
{
|
||||||
|
const uint32_t v0 = static_cast<uint32_t>(value / 100000000);
|
||||||
|
const uint32_t v1 = static_cast<uint32_t>(value % 100000000);
|
||||||
|
|
||||||
|
const __m128i a0 = Convert8DigitsSSE2(v0);
|
||||||
|
const __m128i a1 = Convert8DigitsSSE2(v1);
|
||||||
|
|
||||||
|
// Convert to bytes, add '0'
|
||||||
|
const __m128i va = _mm_add_epi8(_mm_packus_epi16(a0, a1), reinterpret_cast<const __m128i*>(kAsciiZero)[0]);
|
||||||
|
|
||||||
|
// Count number of digit
|
||||||
|
const unsigned mask = _mm_movemask_epi8(_mm_cmpeq_epi8(va, reinterpret_cast<const __m128i*>(kAsciiZero)[0]));
|
||||||
|
# ifdef _MSC_VER
|
||||||
|
unsigned long digit;
|
||||||
|
_BitScanForward(&digit, ~mask | 0x8000);
|
||||||
|
# else
|
||||||
|
unsigned digit = __builtin_ctz(~mask | 0x8000);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
// Shift digits to the beginning
|
||||||
|
__m128i result = ShiftDigits_SSE2(va, digit);
|
||||||
|
_mm_storeu_si128(reinterpret_cast<__m128i*>(buffer), result);
|
||||||
|
|
||||||
|
return (buffer + 16 - digit - start);
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint32_t a = static_cast<uint32_t>(value / 10000000000000000); // 1 to 1844
|
||||||
|
value %= 10000000000000000;
|
||||||
|
|
||||||
|
if (a < 10) *buffer++ = '0' + (char)a;
|
||||||
|
else if (a < 100)
|
||||||
|
{
|
||||||
|
U_NUM2STR16(buffer, a);
|
||||||
|
|
||||||
|
buffer += 2;
|
||||||
|
}
|
||||||
|
else if (a < 1000)
|
||||||
|
{
|
||||||
|
*buffer++ = '0' + static_cast<char>(a / 100);
|
||||||
|
|
||||||
|
const uint32_t i = (a % 100);
|
||||||
|
|
||||||
|
U_NUM2STR16(buffer, i);
|
||||||
|
|
||||||
|
buffer += 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const uint32_t i = (a / 100);
|
||||||
|
const uint32_t j = (a % 100);
|
||||||
|
|
||||||
|
U_NUM2STR16(buffer, i);
|
||||||
|
U_NUM2STR16(buffer+2, j);
|
||||||
|
|
||||||
|
buffer += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint32_t v0 = static_cast<uint32_t>(value / 100000000);
|
||||||
|
const uint32_t v1 = static_cast<uint32_t>(value % 100000000);
|
||||||
|
|
||||||
|
const __m128i a0 = Convert8DigitsSSE2(v0);
|
||||||
|
const __m128i a1 = Convert8DigitsSSE2(v1);
|
||||||
|
|
||||||
|
// Convert to bytes, add '0'
|
||||||
|
const __m128i va = _mm_add_epi8(_mm_packus_epi16(a0, a1), reinterpret_cast<const __m128i*>(kAsciiZero)[0]);
|
||||||
|
_mm_storeu_si128(reinterpret_cast<__m128i*>(buffer), va);
|
||||||
|
|
||||||
|
return (buffer + 16 - start);
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -896,11 +896,10 @@ void UValue::stringify(UString& result, UValue& _value)
|
||||||
|
|
||||||
bool bcomma;
|
bool bcomma;
|
||||||
char* presult;
|
char* presult;
|
||||||
const char* ch;
|
|
||||||
char buffer[32];
|
|
||||||
UString* pstring;
|
UString* pstring;
|
||||||
const char* last_nonzero;
|
uint32_t pos, sz, keysz;
|
||||||
uint32_t n, pos, sz, keysz;
|
|
||||||
|
(void) result.reserve(32);
|
||||||
|
|
||||||
U_INTERNAL_DUMP("dispatch_table[%d] = %p &&case_null = %p", _value.type_, dispatch_table[_value.type_], &&case_null)
|
U_INTERNAL_DUMP("dispatch_table[%d] = %p &&case_null = %p", _value.type_, dispatch_table[_value.type_], &&case_null)
|
||||||
|
|
||||||
|
@ -928,94 +927,88 @@ case_uchar:
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case_short:
|
case_short:
|
||||||
(void) result.append(buffer, u_num2str32s(_value.value.short_, buffer));
|
presult = result.c_pointer(sz = result.size());
|
||||||
|
|
||||||
|
result.rep->_length = sz + u_num2str32s(_value.value.short_, presult);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case_ushort:
|
case_ushort:
|
||||||
(void) result.append(buffer, u_num2str32(_value.value.ushort_, buffer));
|
presult = result.c_pointer(sz = result.size());
|
||||||
|
|
||||||
|
result.rep->_length = sz + u_num2str32(_value.value.ushort_, presult);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case_int:
|
case_int:
|
||||||
(void) result.append(buffer, u_num2str32s(_value.value.int_, buffer));
|
presult = result.c_pointer(sz = result.size());
|
||||||
|
|
||||||
|
result.rep->_length = sz + u_num2str32s(_value.value.int_, presult);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case_uint:
|
case_uint:
|
||||||
(void) result.append(buffer, u_num2str32s(_value.value.uint_, buffer));
|
presult = result.c_pointer(sz = result.size());
|
||||||
|
|
||||||
|
result.rep->_length = sz + u_num2str32(_value.value.uint_, presult);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case_long:
|
case_long:
|
||||||
(void) result.append(buffer, u_num2str64s(_value.value.long_, buffer));
|
presult = result.c_pointer(sz = result.size());
|
||||||
|
|
||||||
|
result.rep->_length = sz + u_num2str64s(_value.value.long_, presult);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case_ulong:
|
case_ulong:
|
||||||
(void) result.append(buffer, u_num2str64s(_value.value.ulong_, buffer));
|
presult = result.c_pointer(sz = result.size());
|
||||||
|
|
||||||
|
result.rep->_length = sz + u_num2str64(_value.value.ulong_, presult);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case_llong:
|
case_llong:
|
||||||
(void) result.append(buffer, u_num2str64s(_value.value.llong_, buffer));
|
presult = result.c_pointer(sz = result.size());
|
||||||
|
|
||||||
|
result.rep->_length = sz + u_num2str64s(_value.value.llong_, presult);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case_ullong:
|
case_ullong:
|
||||||
(void) result.append(buffer, u_num2str64s(_value.value.ullong_, buffer));
|
presult = result.c_pointer(sz = result.size());
|
||||||
|
|
||||||
|
result.rep->_length = sz + u_num2str64(_value.value.ullong_, presult);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case_float:
|
case_float:
|
||||||
n = u__snprintf(buffer, sizeof(buffer), "%#.6f", _value.value.float_);
|
presult = result.c_pointer(sz = result.size());
|
||||||
|
|
||||||
goto next;
|
result.rep->_length = sz + u_dtoa(_value.value.float_, presult);
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
case_double:
|
case_double:
|
||||||
n = u__snprintf(buffer, sizeof(buffer), "%#.16g", _value.value.real_);
|
presult = result.c_pointer(sz = result.size());
|
||||||
|
|
||||||
goto next;
|
result.rep->_length = sz + u_dtoa(_value.value.real_, presult);
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
case_ldouble:
|
case_ldouble:
|
||||||
n = u__snprintf(buffer, sizeof(buffer), "%#.16g", _value.value.lreal_);
|
presult = result.c_pointer(sz = result.size());
|
||||||
|
|
||||||
next:
|
result.rep->_length = sz + u_dtoa(_value.value.lreal_, presult);
|
||||||
ch = buffer + n - 1;
|
|
||||||
|
|
||||||
if (*ch == '0')
|
|
||||||
{
|
|
||||||
while (ch > buffer && *ch == '0') --ch;
|
|
||||||
|
|
||||||
last_nonzero = ch;
|
|
||||||
|
|
||||||
while (ch >= buffer)
|
|
||||||
{
|
|
||||||
char c = *ch;
|
|
||||||
|
|
||||||
if (u__isdigit(c))
|
|
||||||
{
|
|
||||||
--ch;
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c == '.') n = last_nonzero - buffer + 2; // Truncate zeroes to save bytes in output, but keep one
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
(void) result.append(buffer, n);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case_string:
|
case_string:
|
||||||
pstring = (UString*)_value.value.ptr_;
|
pstring = (UString*)_value.value.ptr_;
|
||||||
|
|
||||||
(void) result.reserve((sz = result.size()) + (keysz = pstring->size()) * 6);
|
(void) result.reserve((keysz = pstring->size()) * 6);
|
||||||
|
|
||||||
presult = result.c_pointer(sz);
|
presult = result.c_pointer(sz = result.size());
|
||||||
|
|
||||||
result.rep->_length = sz + emitString((const unsigned char*)pstring->data(), keysz, presult);
|
result.rep->_length = sz + emitString((const unsigned char*)pstring->data(), keysz, presult);
|
||||||
|
|
||||||
|
@ -1044,9 +1037,9 @@ case_object:
|
||||||
{
|
{
|
||||||
U_INTERNAL_ASSERT_POINTER(member->key)
|
U_INTERNAL_ASSERT_POINTER(member->key)
|
||||||
|
|
||||||
(void) result.reserve((sz = result.size()) + (keysz = member->key->size()) * 6);
|
(void) result.reserve((keysz = member->key->size()) * 6);
|
||||||
|
|
||||||
presult = result.c_pointer(sz);
|
presult = result.c_pointer(sz = result.size());
|
||||||
|
|
||||||
if (bcomma == false) bcomma = true;
|
if (bcomma == false) bcomma = true;
|
||||||
else
|
else
|
||||||
|
@ -2110,55 +2103,53 @@ const char* UValue::getJReadErrorDescription()
|
||||||
"End of object found" // 14
|
"End of object found" // 14
|
||||||
};
|
};
|
||||||
|
|
||||||
const char* descr = (jread_error >= 0 && jread_error <= 14 ? errlist[jread_error] : "Unknown jread error");
|
const char* descr = (jread_error >= 0 && (int)U_NUM_ELEMENTS(errlist) ? errlist[jread_error] : "Unknown jread error");
|
||||||
|
|
||||||
U_RETURN(descr);
|
U_RETURN(descr);
|
||||||
}
|
}
|
||||||
|
|
||||||
# define U_VAL_ENTRY(n) n: descr = #n; break
|
|
||||||
|
|
||||||
const char* UValue::getDataTypeDescription(int type)
|
const char* UValue::getDataTypeDescription(int type)
|
||||||
{
|
{
|
||||||
U_TRACE(0, "UValue::getDataTypeDescription(%d)", type)
|
U_TRACE(0, "UValue::getDataTypeDescription(%d)", type)
|
||||||
|
|
||||||
const char* descr;
|
struct data_type_info {
|
||||||
|
int value; // The numeric value
|
||||||
|
const char* name; // The equivalent symbolic value
|
||||||
|
};
|
||||||
|
|
||||||
switch (type)
|
static const struct data_type_info data_type_table[] = {
|
||||||
{
|
U_ENTRY(NULL_VALUE),
|
||||||
case U_VAL_ENTRY(NULL_VALUE);
|
U_ENTRY(BOOLEAN_VALUE),
|
||||||
case U_VAL_ENTRY(BOOLEAN_VALUE);
|
U_ENTRY(CHAR_VALUE),
|
||||||
case U_VAL_ENTRY(CHAR_VALUE);
|
U_ENTRY(UCHAR_VALUE),
|
||||||
case U_VAL_ENTRY(UCHAR_VALUE);
|
U_ENTRY(SHORT_VALUE),
|
||||||
case U_VAL_ENTRY(SHORT_VALUE);
|
U_ENTRY(USHORT_VALUE),
|
||||||
case U_VAL_ENTRY(USHORT_VALUE);
|
U_ENTRY(INT_VALUE),
|
||||||
case U_VAL_ENTRY(INT_VALUE);
|
U_ENTRY(UINT_VALUE),
|
||||||
case U_VAL_ENTRY(UINT_VALUE);
|
U_ENTRY(LONG_VALUE),
|
||||||
case U_VAL_ENTRY(LONG_VALUE);
|
U_ENTRY(ULONG_VALUE),
|
||||||
case U_VAL_ENTRY(ULONG_VALUE);
|
U_ENTRY(LLONG_VALUE),
|
||||||
case U_VAL_ENTRY(LLONG_VALUE);
|
U_ENTRY(ULLONG_VALUE),
|
||||||
case U_VAL_ENTRY(ULLONG_VALUE);
|
U_ENTRY(FLOAT_VALUE),
|
||||||
case U_VAL_ENTRY(FLOAT_VALUE);
|
U_ENTRY(REAL_VALUE),
|
||||||
case U_VAL_ENTRY(REAL_VALUE);
|
U_ENTRY(LREAL_VALUE),
|
||||||
case U_VAL_ENTRY(LREAL_VALUE);
|
U_ENTRY(STRING_VALUE),
|
||||||
case U_VAL_ENTRY(STRING_VALUE);
|
U_ENTRY(ARRAY_VALUE),
|
||||||
case U_VAL_ENTRY(ARRAY_VALUE);
|
U_ENTRY(OBJECT_VALUE),
|
||||||
case U_VAL_ENTRY(OBJECT_VALUE);
|
U_ENTRY(NUMBER_VALUE),
|
||||||
case U_VAL_ENTRY(NUMBER_VALUE);
|
U_ENTRY(U_JR_EOL),
|
||||||
case U_VAL_ENTRY(U_JR_EOL);
|
U_ENTRY(U_JR_COLON),
|
||||||
case U_VAL_ENTRY(U_JR_COLON);
|
U_ENTRY(U_JR_COMMA),
|
||||||
case U_VAL_ENTRY(U_JR_COMMA);
|
U_ENTRY(U_JR_EARRAY),
|
||||||
case U_VAL_ENTRY(U_JR_EARRAY);
|
U_ENTRY(U_JR_QPARAM),
|
||||||
case U_VAL_ENTRY(U_JR_QPARAM);
|
U_ENTRY(U_JR_EOBJECT)
|
||||||
case U_VAL_ENTRY(U_JR_EOBJECT);
|
};
|
||||||
|
|
||||||
default: descr = "Data type unknown";
|
const char* descr = (type >= 0 && type < (int)U_NUM_ELEMENTS(data_type_table) ? data_type_table[type].name : "Data type unknown");
|
||||||
}
|
|
||||||
|
|
||||||
U_RETURN(descr);
|
U_RETURN(descr);
|
||||||
}
|
}
|
||||||
|
|
||||||
# undef U_VAL_ENTRY
|
|
||||||
|
|
||||||
const char* UValue::dump(bool _reset) const
|
const char* UValue::dump(bool _reset) const
|
||||||
{
|
{
|
||||||
#ifdef U_STDCPP_ENABLE
|
#ifdef U_STDCPP_ENABLE
|
||||||
|
|
|
@ -28,7 +28,7 @@ bool UREDISClient_Base::connect(const char* phost, unsigned int _port)
|
||||||
|
|
||||||
if (env_redis_host == 0)
|
if (env_redis_host == 0)
|
||||||
{
|
{
|
||||||
UClient_Base::response.snprintf("connection disabled");
|
(void) UClient_Base::response.replace(U_CONSTANT_TO_PARAM("connection disabled"));
|
||||||
|
|
||||||
U_RETURN(false);
|
U_RETURN(false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1481,10 +1481,11 @@ void UNoCatPlugIn::addPeerInfo(int disconnected)
|
||||||
U_INTERNAL_ASSERT(u_now->tv_sec >= peer->ctime)
|
U_INTERNAL_ASSERT(u_now->tv_sec >= peer->ctime)
|
||||||
|
|
||||||
char* ptr;
|
char* ptr;
|
||||||
uint32_t sz;
|
|
||||||
char buffer[64];
|
char buffer[64];
|
||||||
UString info = (*vinfo_data)[U_peer_index_AUTH], str = UStringExt::substitute(peer->mac, ':', U_CONSTANT_TO_PARAM("%3A"));
|
UString info = (*vinfo_data)[U_peer_index_AUTH], str = UStringExt::substitute(peer->mac, ':', U_CONSTANT_TO_PARAM("%3A"));
|
||||||
|
|
||||||
|
uint32_t sz = info.size();
|
||||||
|
|
||||||
U_INTERNAL_DUMP("U_peer_index_AUTH = %u info = %V peer->ip = %V", U_peer_index_AUTH, info.rep, peer->ip.rep)
|
U_INTERNAL_DUMP("U_peer_index_AUTH = %u info = %V peer->ip = %V", U_peer_index_AUTH, info.rep, peer->ip.rep)
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -1500,7 +1501,7 @@ void UNoCatPlugIn::addPeerInfo(int disconnected)
|
||||||
// /info?Mac=98%3A0c%3A82%3A76%3A3b%3A39&ip=172.16.1.8&gateway=172.16.1.254%3A5280&ap=ap%4010.8.0.1&User=1212&logout=-1&connected=3&traffic=0
|
// /info?Mac=98%3A0c%3A82%3A76%3A3b%3A39&ip=172.16.1.8&gateway=172.16.1.254%3A5280&ap=ap%4010.8.0.1&User=1212&logout=-1&connected=3&traffic=0
|
||||||
// ------------------------------------------------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
(void) info.reserve((sz = info.size()) + 200U);
|
(void) info.reserve(200U);
|
||||||
|
|
||||||
info.snprintf_add("%.*sMac=%v&ip=%v&", (sz > 0), "&", str.rep, peer->ip.rep);
|
info.snprintf_add("%.*sMac=%v&ip=%v&", (sz > 0), "&", str.rep, peer->ip.rep);
|
||||||
|
|
||||||
|
@ -1557,10 +1558,11 @@ void UNoCatPlugIn::addPeerRoaming()
|
||||||
U_INTERNAL_ASSERT(peer->mac)
|
U_INTERNAL_ASSERT(peer->mac)
|
||||||
U_INTERNAL_ASSERT(peer->user)
|
U_INTERNAL_ASSERT(peer->user)
|
||||||
|
|
||||||
uint32_t sz;
|
|
||||||
char buffer[64];
|
char buffer[64];
|
||||||
UString data = (*vroaming_data)[U_peer_index_AUTH], str = UStringExt::substitute(peer->mac, ':', U_CONSTANT_TO_PARAM("%3A"));
|
UString data = (*vroaming_data)[U_peer_index_AUTH], str = UStringExt::substitute(peer->mac, ':', U_CONSTANT_TO_PARAM("%3A"));
|
||||||
|
|
||||||
|
uint32_t sz = data.size();
|
||||||
|
|
||||||
U_INTERNAL_DUMP("U_peer_index_AUTH = %u data = %V peer->ip = %V", U_peer_index_AUTH, data.rep, peer->ip.rep)
|
U_INTERNAL_DUMP("U_peer_index_AUTH = %u data = %V peer->ip = %V", U_peer_index_AUTH, data.rep, peer->ip.rep)
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -1573,7 +1575,7 @@ void UNoCatPlugIn::addPeerRoaming()
|
||||||
// /roaming?Mac=98%3A0c%3A82%3A76%3A3b%3A39&ip=172.16.1.8&gateway=172.16.1.254%3A5280&ap=ap%4010.8.0.1&User=1212
|
// /roaming?Mac=98%3A0c%3A82%3A76%3A3b%3A39&ip=172.16.1.8&gateway=172.16.1.254%3A5280&ap=ap%4010.8.0.1&User=1212
|
||||||
// -------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
(void) data.reserve((sz = data.size()) + 200U);
|
(void) data.reserve(200U);
|
||||||
|
|
||||||
data.snprintf_add("%.*sMac=%v&ip=%v&", (sz > 0), "&", str.rep, peer->ip.rep);
|
data.snprintf_add("%.*sMac=%v&ip=%v&", (sz > 0), "&", str.rep, peer->ip.rep);
|
||||||
|
|
||||||
|
|
|
@ -253,11 +253,7 @@ private:
|
||||||
HTTP2Push& operator=(const HTTP2Push&) { return *this; }
|
HTTP2Push& operator=(const HTTP2Push&) { return *this; }
|
||||||
};
|
};
|
||||||
|
|
||||||
static UValue* pvalue;
|
|
||||||
static Request* prequest;
|
|
||||||
static UMongoDBClient* mc;
|
static UMongoDBClient* mc;
|
||||||
static Response* presponse;
|
|
||||||
static UVector<Response*>* pvresponse;
|
|
||||||
|
|
||||||
static void usp_init_businesses()
|
static void usp_init_businesses()
|
||||||
{
|
{
|
||||||
|
@ -289,11 +285,6 @@ static void usp_fork_businesses()
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
U_NEW(Request, prequest, Request);
|
|
||||||
U_NEW(Response, presponse, Response);
|
|
||||||
U_NEW(UValue, pvalue, UValue(ARRAY_VALUE));
|
|
||||||
U_NEW(UVector<Response*>, pvresponse, UVector<Response*>);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -302,14 +293,6 @@ static void usp_end_businesses()
|
||||||
U_TRACE(5, "::usp_end_businesses()")
|
U_TRACE(5, "::usp_end_businesses()")
|
||||||
|
|
||||||
delete mc;
|
delete mc;
|
||||||
|
|
||||||
if (pvalue)
|
|
||||||
{
|
|
||||||
delete pvalue;
|
|
||||||
delete prequest;
|
|
||||||
delete presponse;
|
|
||||||
delete pvresponse;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
-->
|
-->
|
||||||
|
@ -317,43 +300,18 @@ static void usp_end_businesses()
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
-->
|
-->
|
||||||
<!--#code
|
<!--#code
|
||||||
if (USP_JSON_REQUEST_PARSE(*prequest))
|
UString type;
|
||||||
|
|
||||||
|
if (USP_JFIND_REQUEST("type", type))
|
||||||
{
|
{
|
||||||
uint32_t i, n;
|
if (type.equal(U_CONSTANT_TO_PARAM("localesData")))
|
||||||
|
|
||||||
// 1) identify user by TOKEN
|
|
||||||
|
|
||||||
(void) mc->findAll(); // mc->find(prequest->token);
|
|
||||||
|
|
||||||
for (i = 0, n = mc->vitem.size(); i < n; ++i)
|
|
||||||
{
|
{
|
||||||
JSON_parse(mc->vitem[i], *presponse);
|
Response response;
|
||||||
|
|
||||||
// 2) Filter by RADIUS around LOCATION
|
USP_JSON_OBJ_stringify(Response, response);
|
||||||
|
}
|
||||||
if (true)
|
else if (type.equal(U_CONSTANT_TO_PARAM("remoteData")))
|
||||||
{
|
{
|
||||||
Response* nresponse;
|
|
||||||
|
|
||||||
U_NEW(Response, nresponse, Response(*presponse));
|
|
||||||
|
|
||||||
pvresponse->push_back(nresponse);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
n = pvresponse->size();
|
|
||||||
|
|
||||||
// 3) sort list by ranking algorithm
|
|
||||||
|
|
||||||
pvresponse->sort(Response::cmp_obj);
|
|
||||||
|
|
||||||
// 4) return first 20 businesses
|
|
||||||
|
|
||||||
if (n > 20) pvresponse->erase(20, n);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
USP_JSON_stringify(*pvalue, UVector<Response*>, *pvresponse);
|
|
||||||
|
|
||||||
pvalue->clear();
|
|
||||||
pvresponse->clear();
|
|
||||||
-->
|
-->
|
||||||
|
|
|
@ -45,10 +45,10 @@ void UOrmDriverSqlite::handlerError()
|
||||||
U_ENTRY(SQLITE_PERM), /* Access permission denied */
|
U_ENTRY(SQLITE_PERM), /* Access permission denied */
|
||||||
U_ENTRY(SQLITE_ABORT), /* Callback routine requested an abort */
|
U_ENTRY(SQLITE_ABORT), /* Callback routine requested an abort */
|
||||||
U_ENTRY(SQLITE_BUSY), /* The database file is locked */
|
U_ENTRY(SQLITE_BUSY), /* The database file is locked */
|
||||||
U_ENTRY(SQLITE_LOCKED), /* A table in the database is locked */
|
U_ENTRY(SQLITE_LOCKED), /* A table in the database is locked */
|
||||||
U_ENTRY(SQLITE_NOMEM), /* A malloc() failed */
|
U_ENTRY(SQLITE_NOMEM), /* A malloc() failed */
|
||||||
U_ENTRY(SQLITE_READONLY), /* Attempt to write a readonly database */
|
U_ENTRY(SQLITE_READONLY), /* Attempt to write a readonly database */
|
||||||
U_ENTRY(SQLITE_INTERRUPT), /* Operation terminated by sqlite3_interrupt()*/
|
U_ENTRY(SQLITE_INTERRUPT), /* Operation terminated by sqlite3_interrupt()*/
|
||||||
U_ENTRY(SQLITE_IOERR), /* Some kind of disk I/O error occurred */
|
U_ENTRY(SQLITE_IOERR), /* Some kind of disk I/O error occurred */
|
||||||
U_ENTRY(SQLITE_CORRUPT), /* The database disk image is malformed */
|
U_ENTRY(SQLITE_CORRUPT), /* The database disk image is malformed */
|
||||||
U_ENTRY(SQLITE_NOTFOUND), /* Unknown opcode in sqlite3_file_control() */
|
U_ENTRY(SQLITE_NOTFOUND), /* Unknown opcode in sqlite3_file_control() */
|
||||||
|
@ -56,24 +56,24 @@ void UOrmDriverSqlite::handlerError()
|
||||||
U_ENTRY(SQLITE_CANTOPEN), /* Unable to open the database file */
|
U_ENTRY(SQLITE_CANTOPEN), /* Unable to open the database file */
|
||||||
U_ENTRY(SQLITE_PROTOCOL), /* Database lock protocol error */
|
U_ENTRY(SQLITE_PROTOCOL), /* Database lock protocol error */
|
||||||
U_ENTRY(SQLITE_EMPTY), /* Database is empty */
|
U_ENTRY(SQLITE_EMPTY), /* Database is empty */
|
||||||
U_ENTRY(SQLITE_SCHEMA), /* The database schema changed */
|
U_ENTRY(SQLITE_SCHEMA), /* The database schema changed */
|
||||||
U_ENTRY(SQLITE_TOOBIG), /* String or BLOB exceeds size limit */
|
U_ENTRY(SQLITE_TOOBIG), /* String or BLOB exceeds size limit */
|
||||||
U_ENTRY(SQLITE_CONSTRAINT), /* Abort due to constraint violation */
|
U_ENTRY(SQLITE_CONSTRAINT), /* Abort due to constraint violation */
|
||||||
U_ENTRY(SQLITE_MISMATCH), /* Data type mismatch */
|
U_ENTRY(SQLITE_MISMATCH), /* Data type mismatch */
|
||||||
U_ENTRY(SQLITE_MISUSE), /* Library used incorrectly */
|
U_ENTRY(SQLITE_MISUSE), /* Library used incorrectly */
|
||||||
U_ENTRY(SQLITE_NOLFS), /* Uses OS features not supported on host */
|
U_ENTRY(SQLITE_NOLFS), /* Uses OS features not supported on host */
|
||||||
U_ENTRY(SQLITE_AUTH), /* Authorization denied */
|
U_ENTRY(SQLITE_AUTH), /* Authorization denied */
|
||||||
U_ENTRY(SQLITE_FORMAT), /* Auxiliary database format error */
|
U_ENTRY(SQLITE_FORMAT), /* Auxiliary database format error */
|
||||||
U_ENTRY(SQLITE_RANGE), /* 2nd parameter to sqlite3_bind out of range */
|
U_ENTRY(SQLITE_RANGE), /* 2nd parameter to sqlite3_bind out of range */
|
||||||
U_ENTRY(SQLITE_NOTADB), /* File opened that is not a database file */
|
U_ENTRY(SQLITE_NOTADB), /* File opened that is not a database file */
|
||||||
# ifdef SQLITE_NOTICE
|
# ifdef SQLITE_NOTICE
|
||||||
U_ENTRY(SQLITE_NOTICE), /* Notifications from sqlite3_log() */
|
U_ENTRY(SQLITE_NOTICE), /* Notifications from sqlite3_log() */
|
||||||
# endif
|
# endif
|
||||||
# ifdef SQLITE_WARNING
|
# ifdef SQLITE_WARNING
|
||||||
U_ENTRY(SQLITE_WARNING), /* Warnings from sqlite3_log() */
|
U_ENTRY(SQLITE_WARNING), /* Warnings from sqlite3_log() */
|
||||||
# endif
|
# endif
|
||||||
U_ENTRY(SQLITE_ROW), /* sqlite3_step() has another row ready */
|
U_ENTRY(SQLITE_ROW), /* sqlite3_step() has another row ready */
|
||||||
U_ENTRY(SQLITE_DONE) /* sqlite3_step() has finished executing */
|
U_ENTRY(SQLITE_DONE) /* sqlite3_step() has finished executing */
|
||||||
};
|
};
|
||||||
|
|
||||||
if (UOrmDriver::errmsg == 0) UOrmDriver::errmsg = U_SYSCALL(sqlite3_errmsg, "%p", (sqlite3*)UOrmDriver::connection);
|
if (UOrmDriver::errmsg == 0) UOrmDriver::errmsg = U_SYSCALL(sqlite3_errmsg, "%p", (sqlite3*)UOrmDriver::connection);
|
||||||
|
|
|
@ -1923,7 +1923,7 @@ float UStringRep::strtof() const
|
||||||
char* endptr;
|
char* endptr;
|
||||||
float result = ::strtof(str, &endptr);
|
float result = ::strtof(str, &endptr);
|
||||||
|
|
||||||
U_INTERNAL_ASSERT_MINOR(endptr, eos)
|
U_INTERNAL_ASSERT(endptr <= eos)
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
U_INTERNAL_DUMP("errno = %d", errno)
|
U_INTERNAL_DUMP("errno = %d", errno)
|
||||||
|
@ -1951,7 +1951,7 @@ double UStringRep::strtod() const
|
||||||
char* endptr;
|
char* endptr;
|
||||||
double result = ::strtod(str, &endptr);
|
double result = ::strtod(str, &endptr);
|
||||||
|
|
||||||
U_INTERNAL_ASSERT_MINOR(endptr, eos)
|
U_INTERNAL_ASSERT(endptr <= eos)
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
U_INTERNAL_DUMP("errno = %d", errno)
|
U_INTERNAL_DUMP("errno = %d", errno)
|
||||||
|
|
|
@ -146,8 +146,8 @@ UString UStringExt::numberToString(uint64_t n)
|
||||||
{
|
{
|
||||||
U_TRACE(0, "UStringExt::numberToString(%llu)", n)
|
U_TRACE(0, "UStringExt::numberToString(%llu)", n)
|
||||||
|
|
||||||
unsigned int i;
|
|
||||||
UString x(32U);
|
UString x(32U);
|
||||||
|
unsigned int i;
|
||||||
uint64_t u = 1024ULL;
|
uint64_t u = 1024ULL;
|
||||||
|
|
||||||
for (i = 0; i < U_CONSTANT_SIZE("bKMGTPEZY"); ++i)
|
for (i = 0; i < U_CONSTANT_SIZE("bKMGTPEZY"); ++i)
|
||||||
|
@ -189,7 +189,7 @@ UString UStringExt::expandTab(const char* s, uint32_t n, int tab)
|
||||||
{
|
{
|
||||||
len = _end - start;
|
len = _end - start;
|
||||||
|
|
||||||
(void) x.reserve(x.size() + len + tab);
|
(void) x.reserve(len + tab);
|
||||||
|
|
||||||
if (len)
|
if (len)
|
||||||
{
|
{
|
||||||
|
@ -242,7 +242,7 @@ UString UStringExt::substitute(const char* s, uint32_t n, const char* a, uint32_
|
||||||
|
|
||||||
U_INTERNAL_DUMP("start = %u _end = %u len = %u", start, _end, len)
|
U_INTERNAL_DUMP("start = %u _end = %u len = %u", start, _end, len)
|
||||||
|
|
||||||
(void) x.reserve(x.size() + len + n2);
|
(void) x.reserve(len + n2);
|
||||||
|
|
||||||
if (len)
|
if (len)
|
||||||
{
|
{
|
||||||
|
|
|
@ -3843,7 +3843,6 @@ manage:
|
||||||
|
|
||||||
#if defined(DEBUG) && !defined(U_STATIC_ONLY)
|
#if defined(DEBUG) && !defined(U_STATIC_ONLY)
|
||||||
if (file_data == 0 &&
|
if (file_data == 0 &&
|
||||||
isGETorHEAD() &&
|
|
||||||
U_http_is_nocache_file &&
|
U_http_is_nocache_file &&
|
||||||
file->getSuffix().empty())
|
file->getSuffix().empty())
|
||||||
{
|
{
|
||||||
|
@ -3862,6 +3861,8 @@ manage:
|
||||||
manageDataForCache();
|
manageDataForCache();
|
||||||
|
|
||||||
U_INTERNAL_ASSERT_POINTER(file_data)
|
U_INTERNAL_ASSERT_POINTER(file_data)
|
||||||
|
|
||||||
|
UClientImage_Base::setRequestInFileCache();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -4846,7 +4847,8 @@ void UHTTP::clearSessionSSL()
|
||||||
* in pair with user login, and sends session id to browser in response as cookie. Browser stores cookie.
|
* in pair with user login, and sends session id to browser in response as cookie. Browser stores cookie.
|
||||||
* 3) User visits any page on this domain and browser sends a cookie to server for each request.
|
* 3) User visits any page on this domain and browser sends a cookie to server for each request.
|
||||||
* 4) ULib server checks if cookie has been sent, if such cookie exists in server storage with pair with login. Identifies user, provides access to his private content.
|
* 4) ULib server checks if cookie has been sent, if such cookie exists in server storage with pair with login. Identifies user, provides access to his private content.
|
||||||
* 5) Logout button removes the cookie from browser and sid-login pair from server storage. Browser does not send cookies, server does not see it and does not see sid-login pair
|
* 5) Logout button removes the cookie from browser and sid-login pair from server storage. Browser does not send cookies, server does not see it and does not see
|
||||||
|
* sid-login pair
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void UHTTP::addSetCookie(const UString& cookie)
|
void UHTTP::addSetCookie(const UString& cookie)
|
||||||
|
@ -5391,7 +5393,7 @@ __pure int UHTTP::getFormFirstNumericValue(int _min, int _max)
|
||||||
|
|
||||||
U_INTERNAL_DUMP("query = %.*S", U_HTTP_QUERY_TO_TRACE)
|
U_INTERNAL_DUMP("query = %.*S", U_HTTP_QUERY_TO_TRACE)
|
||||||
|
|
||||||
do { ++ptr; } while (*ptr != '=');
|
ptr = (const char*) memchr(ptr, '=', U_http_info.query_len);
|
||||||
|
|
||||||
if (u__isdigit(*++ptr))
|
if (u__isdigit(*++ptr))
|
||||||
{
|
{
|
||||||
|
@ -5516,6 +5518,7 @@ uint32_t UHTTP::processForm()
|
||||||
{
|
{
|
||||||
U_ASSERT(isPOST())
|
U_ASSERT(isPOST())
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
// POST
|
// POST
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// Content-Type: application/x-www-form-urlencoded OR multipart/form-data...
|
// Content-Type: application/x-www-form-urlencoded OR multipart/form-data...
|
||||||
|
@ -5773,7 +5776,10 @@ void UHTTP::handlerResponse()
|
||||||
{
|
{
|
||||||
U_INTERNAL_DUMP("U_http_method_not_implemented = %b", U_http_method_not_implemented)
|
U_INTERNAL_DUMP("U_http_method_not_implemented = %b", U_http_method_not_implemented)
|
||||||
|
|
||||||
if (U_http_method_not_implemented) (void) UClientImage_Base::wbuffer->assign(U_CONSTANT_TO_PARAM("Your browser request a method that this server has not implemented"));
|
if (U_http_method_not_implemented)
|
||||||
|
{
|
||||||
|
(void) UClientImage_Base::wbuffer->assign(U_CONSTANT_TO_PARAM("Your browser request a method that this server has not implemented"));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
(void) UClientImage_Base::wbuffer->assign(U_CONSTANT_TO_PARAM("Allow: "
|
(void) UClientImage_Base::wbuffer->assign(U_CONSTANT_TO_PARAM("Allow: "
|
||||||
|
@ -6194,21 +6200,30 @@ void UHTTP::setDynamicResponse()
|
||||||
|
|
||||||
ptr = ext->data();
|
ptr = ext->data();
|
||||||
|
|
||||||
#ifdef USE_LIBZ
|
#ifndef USE_LIBZ
|
||||||
|
bool bcompress = false;
|
||||||
|
#else
|
||||||
bool bcompress = (U_http_is_accept_gzip &&
|
bool bcompress = (U_http_is_accept_gzip &&
|
||||||
UClientImage_Base::wbuffer->size() > (U_http_info.endHeader + U_MIN_SIZE_FOR_DEFLATE));
|
UClientImage_Base::wbuffer->size() > (U_http_info.endHeader + U_MIN_SIZE_FOR_DEFLATE));
|
||||||
#else
|
|
||||||
bool bcompress = false;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
U_INTERNAL_DUMP("bcompress = %b", bcompress)
|
U_INTERNAL_DUMP("bcompress = %b", bcompress)
|
||||||
|
|
||||||
if (U_http_info.endHeader)
|
if (U_http_info.endHeader)
|
||||||
{
|
{
|
||||||
U_INTERNAL_ASSERT_MAJOR(clength, U_http_info.endHeader)
|
U_INTERNAL_ASSERT(clength >= U_http_info.endHeader)
|
||||||
|
|
||||||
clength -= U_http_info.endHeader;
|
clength -= U_http_info.endHeader;
|
||||||
|
|
||||||
|
if (clength == 0) // no response
|
||||||
|
{
|
||||||
|
UClientImage_Base::body->clear(); // clean body to avoid writev() in response...
|
||||||
|
|
||||||
|
UClientImage_Base::wbuffer->clear();
|
||||||
|
|
||||||
|
goto no_response;
|
||||||
|
}
|
||||||
|
|
||||||
pEndHeader = UClientImage_Base::wbuffer->data();
|
pEndHeader = UClientImage_Base::wbuffer->data();
|
||||||
|
|
||||||
if (bcompress == false) goto no_compress;
|
if (bcompress == false) goto no_compress;
|
||||||
|
@ -6338,6 +6353,7 @@ end:
|
||||||
|
|
||||||
ext->size_adjust(ptr1);
|
ext->size_adjust(ptr1);
|
||||||
|
|
||||||
|
no_response:
|
||||||
handlerResponse();
|
handlerResponse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8903,7 +8919,7 @@ U_NO_EXPORT void UHTTP::setCGIShellScript(UString& command)
|
||||||
c = (memchr(ptr, '"', sz) ? '\'' : '"');
|
c = (memchr(ptr, '"', sz) ? '\'' : '"');
|
||||||
}
|
}
|
||||||
|
|
||||||
(void) command.reserve(command.size() + sz + 4U);
|
(void) command.reserve(sz + 4U);
|
||||||
|
|
||||||
command.snprintf_add(" %c%.*s%c ", c, sz, ptr, c);
|
command.snprintf_add(" %c%.*s%c ", c, sz, ptr, c);
|
||||||
}
|
}
|
||||||
|
@ -9440,7 +9456,9 @@ loop:
|
||||||
|
|
||||||
UClientImage_Base::body->clear();
|
UClientImage_Base::body->clear();
|
||||||
|
|
||||||
(void) set_cookie->append(UClientImage_Base::wbuffer->data(), sz - U_CONSTANT_SIZE(U_CRLF)); // NB: we use the var 'set_cookie' for opportunism within handlerResponse()...
|
// NB: we use the var 'set_cookie' for opportunism within handlerResponse()...
|
||||||
|
|
||||||
|
(void) set_cookie->append(UClientImage_Base::wbuffer->data(), sz - U_CONSTANT_SIZE(U_CRLF));
|
||||||
|
|
||||||
setResponse();
|
setResponse();
|
||||||
|
|
||||||
|
|
|
@ -94,7 +94,6 @@ prefix 6d 6o 6x 6X 6u
|
||||||
123.456 should be 123.456
|
123.456 should be 123.456
|
||||||
10 should be 10
|
10 should be 10
|
||||||
0.02 should be 0.02
|
0.02 should be 0.02
|
||||||
0.10000000000000001
|
|
||||||
Test ok.
|
Test ok.
|
||||||
sprintf (buf, "%07llo", 040000000000ll) = 40000000000
|
sprintf (buf, "%07llo", 040000000000ll) = 40000000000
|
||||||
printf ("%c", 257) =
|
printf ("%c", 257) =
|
||||||
|
|
|
@ -9,4 +9,4 @@ start_msg sprintf
|
||||||
start_prg sprintf
|
start_prg sprintf
|
||||||
|
|
||||||
# Test against expected output
|
# Test against expected output
|
||||||
test_output_wc w sprintf
|
test_output_diff sprintf
|
||||||
|
|
|
@ -138,8 +138,6 @@ static void test3(void)
|
||||||
char buf[200];
|
char buf[200];
|
||||||
const char* tmp;
|
const char* tmp;
|
||||||
|
|
||||||
printf("%.17f\n",(1.0/x/10.0+1.0)*x-x);
|
|
||||||
|
|
||||||
u__snprintf(buf,sizeof(buf),"%*s%*s%*s",-1,"one",-20,"two",-30,"three");
|
u__snprintf(buf,sizeof(buf),"%*s%*s%*s",-1,"one",-20,"two",-30,"three");
|
||||||
result |= strcmp(buf, "onetwo three ");
|
result |= strcmp(buf, "onetwo three ");
|
||||||
tmp = (result != 0 ? "Test failed!" : "Test ok.");
|
tmp = (result != 0 ? "Test failed!" : "Test ok.");
|
||||||
|
|
|
@ -50,8 +50,8 @@ DIR_CMD="../../examples/userver"
|
||||||
|
|
||||||
start_prg_background userver_tcp -c inp/webserver.cfg
|
start_prg_background userver_tcp -c inp/webserver.cfg
|
||||||
|
|
||||||
send_req $NCAT localhost 8080 inp/http/businesses.req businesses 2
|
send_req $NCAT localhost 8080 inp/http/businesses1.req businesses 2
|
||||||
send_req $NCAT localhost 8080 inp/http/businesses.req businesses 2
|
send_req $NCAT localhost 8080 inp/http/businesses2.req businesses 2
|
||||||
|
|
||||||
kill_prg userver_tcp TERM
|
kill_prg userver_tcp TERM
|
||||||
|
|
||||||
|
|
7
tests/examples/inp/http/businesses1.req
Normal file
7
tests/examples/inp/http/businesses1.req
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
POST /servlet/businesses HTTP/1.1
|
||||||
|
Host: localhost:8080
|
||||||
|
Connection: Keep-Alive
|
||||||
|
Content-Type: application/jsonrequest
|
||||||
|
Content-Length: 106
|
||||||
|
|
||||||
|
{ "token": "A619828KAIJ6D3", "type": "localesData", "radius": "near", "location": "40.7831 N, 73.9712 W" }
|
7
tests/examples/inp/http/businesses2.req
Normal file
7
tests/examples/inp/http/businesses2.req
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
POST /servlet/businesses HTTP/1.1
|
||||||
|
Host: localhost:8080
|
||||||
|
Connection: Keep-Alive
|
||||||
|
Content-Type: application/jsonrequest
|
||||||
|
Content-Length: 106
|
||||||
|
|
||||||
|
{ "token": "A619828KAIJ6D3", "type": "localesDita", "radius": "near", "location": "40.7831 N, 73.9712 W" }
|
|
@ -1,15 +1,13 @@
|
||||||
HTTP/1.1 200 OK
|
HTTP/1.1 200 OK
|
||||||
Date: Thu, 21 Apr 2016 13:40:48 GMT
|
Date: Sat, 10 Sep 2016 16:16:24 GMT
|
||||||
Server: ULib
|
Server: ULib
|
||||||
Connection: close
|
Connection: close
|
||||||
Content-Length: 418
|
Content-Length: 56
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
|
|
||||||
[{"name":"Business 1","rating":"Red","address":"123 park lane, New York, NY, USA 10028","phone":"12126465788","url":"www.business1.com"},{"name":"Business 2","rating":"Yellow","address":"837 mott street, New York, NY, USA 10019","phone":"12124829384","url":"www.business2.com"},{"name":"Business 3","rating":"Green","address":"838 mott street, New York, NY, USA 10019","phone":"12124829385","url":"www.business3.com"}]HTTP/1.1 200 OK
|
{"name":"","rating":"","address":"","phone":"","url":""}HTTP/1.1 200 OK
|
||||||
Date: Thu, 21 Apr 2016 13:40:49 GMT
|
Date: Sat, 10 Sep 2016 16:16:24 GMT
|
||||||
Server: ULib
|
Server: ULib
|
||||||
Connection: close
|
Connection: close
|
||||||
Content-Length: 418
|
Content-Length: 0
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
[{"name":"Business 1","rating":"Red","address":"123 park lane, New York, NY, USA 10028","phone":"12126465788","url":"www.business1.com"},{"name":"Business 2","rating":"Yellow","address":"837 mott street, New York, NY, USA 10019","phone":"12124829384","url":"www.business2.com"},{"name":"Business 3","rating":"Green","address":"838 mott street, New York, NY, USA 10019","phone":"12124829385","url":"www.business3.com"}]
|
|
|
@ -16,4 +16,4 @@ unset UMEMPOOL
|
||||||
start_prg json < inp/json.input
|
start_prg json < inp/json.input
|
||||||
|
|
||||||
# Test against expected output
|
# Test against expected output
|
||||||
test_output_wc l json
|
test_output_diff json
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -270,12 +270,24 @@ U_EXPORT main (int argc, char* argv[])
|
||||||
"\"hits\":{\"total\":1,\"max_score\":1.0,\"hits\":[{\"_index\":\"tfb\",\"_type\":\"world\",\"_id\":\"6464\",\"_score\":1.0,"
|
"\"hits\":{\"total\":1,\"max_score\":1.0,\"hits\":[{\"_index\":\"tfb\",\"_type\":\"world\",\"_id\":\"6464\",\"_score\":1.0,"
|
||||||
"\"_source\":{ \"randomNumber\" : 9342 }}]}}"), filename, content, array, result, result1;
|
"\"_source\":{ \"randomNumber\" : 9342 }}]}}"), filename, content, array, result, result1;
|
||||||
|
|
||||||
(void) UValue::jread(searchJson, U_STRING_FROM_CONSTANT("{'randomNumber'"), result);
|
(void) UValue::jfind(searchJson, U_CONSTANT_TO_PARAM("randomNumber"), result);
|
||||||
|
|
||||||
cout.write(buffer, u__snprintf(buffer, sizeof(buffer), "randomNumber = %V\n", result.rep));
|
cout.write(buffer, u__snprintf(buffer, sizeof(buffer), "randomNumber = %V\n", result.rep));
|
||||||
|
|
||||||
result.clear();
|
result.clear();
|
||||||
|
|
||||||
|
int city;
|
||||||
|
double pricePoint;
|
||||||
|
|
||||||
|
(void) UValue::jfind(U_STRING_FROM_CONSTANT("{ \"pricePoint\" : 2.48333333333333, \"socialWeight\" : 8.75832720587083, \"gender\" : 0, \"lessThan16\" : false }"),
|
||||||
|
U_CONSTANT_TO_PARAM("pricePoint"), pricePoint);
|
||||||
|
|
||||||
|
U_INTERNAL_ASSERT_EQUALS(pricePoint, 2.48333333333333)
|
||||||
|
|
||||||
|
(void) UValue::jfind(U_STRING_FROM_CONSTANT("{ \"cityKey\" : 0 }"), U_CONSTANT_TO_PARAM("cityKey"), city);
|
||||||
|
|
||||||
|
U_INTERNAL_ASSERT_EQUALS(city, 0)
|
||||||
|
|
||||||
testMap();
|
testMap();
|
||||||
testVector();
|
testVector();
|
||||||
testObject();
|
testObject();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user