1
0
mirror of https://github.com/stefanocasazza/ULib.git synced 2025-09-28 19:05:55 +08:00
This commit is contained in:
stefanocasazza 2016-09-12 16:09:48 +02:00
parent 723d527766
commit a25cad5520
36 changed files with 1485 additions and 688 deletions

View File

@ -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 \

View File

@ -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
View File

@ -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";

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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))
{ {

View File

@ -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...)

View File

@ -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;
} }

View File

@ -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);

View 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]);
}

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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);

View File

@ -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

View 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

View File

@ -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

View File

@ -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);
} }

View File

@ -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);

View File

@ -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();
--> -->

View File

@ -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);

View File

@ -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)

View File

@ -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)
{ {

View File

@ -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();

View File

@ -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) = 

View File

@ -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

View File

@ -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.");

View File

@ -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

View 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" }

View 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" }

View File

@ -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"}]

View File

@ -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

View File

@ -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();