feat add pugixml
This commit is contained in:
parent
ec2263538d
commit
47c6fcf536
1254
3party/kcp/ikcp.c
Normal file
1254
3party/kcp/ikcp.c
Normal file
File diff suppressed because it is too large
Load Diff
396
3party/kcp/ikcp.h
Normal file
396
3party/kcp/ikcp.h
Normal file
@ -0,0 +1,396 @@
|
|||||||
|
//=====================================================================
|
||||||
|
//
|
||||||
|
// KCP - A Better ARQ Protocol Implementation
|
||||||
|
// skywind3000 (at) gmail.com, 2010-2011
|
||||||
|
//
|
||||||
|
// Features:
|
||||||
|
// + Average RTT reduce 30% - 40% vs traditional ARQ like tcp.
|
||||||
|
// + Maximum RTT reduce three times vs tcp.
|
||||||
|
// + Lightweight, distributed as a single source file.
|
||||||
|
//
|
||||||
|
//=====================================================================
|
||||||
|
#ifndef __IKCP_H__
|
||||||
|
#define __IKCP_H__
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
//=====================================================================
|
||||||
|
// 32BIT INTEGER DEFINITION
|
||||||
|
//=====================================================================
|
||||||
|
#ifndef __INTEGER_32_BITS__
|
||||||
|
#define __INTEGER_32_BITS__
|
||||||
|
#if defined(_WIN64) || defined(WIN64) || defined(__amd64__) || defined(__x86_64) || defined(__x86_64__) \
|
||||||
|
|| defined(_M_IA64) || defined(_M_AMD64)
|
||||||
|
typedef unsigned int ISTDUINT32;
|
||||||
|
typedef int ISTDINT32;
|
||||||
|
#elif defined(_WIN32) || defined(WIN32) || defined(__i386__) || defined(__i386) || defined(_M_X86)
|
||||||
|
typedef unsigned long ISTDUINT32;
|
||||||
|
typedef long ISTDINT32;
|
||||||
|
#elif defined(__MACOS__)
|
||||||
|
typedef UInt32 ISTDUINT32;
|
||||||
|
typedef SInt32 ISTDINT32;
|
||||||
|
#elif defined(__APPLE__) && defined(__MACH__)
|
||||||
|
#include <sys/types.h>
|
||||||
|
typedef u_int32_t ISTDUINT32;
|
||||||
|
typedef int32_t ISTDINT32;
|
||||||
|
#elif defined(__BEOS__)
|
||||||
|
#include <sys/inttypes.h>
|
||||||
|
typedef u_int32_t ISTDUINT32;
|
||||||
|
typedef int32_t ISTDINT32;
|
||||||
|
#elif (defined(_MSC_VER) || defined(__BORLANDC__)) && (!defined(__MSDOS__))
|
||||||
|
typedef unsigned __int32 ISTDUINT32;
|
||||||
|
typedef __int32 ISTDINT32;
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
#include <stdint.h>
|
||||||
|
typedef uint32_t ISTDUINT32;
|
||||||
|
typedef int32_t ISTDINT32;
|
||||||
|
#else
|
||||||
|
typedef unsigned long ISTDUINT32;
|
||||||
|
typedef long ISTDINT32;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//=====================================================================
|
||||||
|
// Integer Definition
|
||||||
|
//=====================================================================
|
||||||
|
#ifndef __IINT8_DEFINED
|
||||||
|
#define __IINT8_DEFINED
|
||||||
|
typedef char IINT8;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __IUINT8_DEFINED
|
||||||
|
#define __IUINT8_DEFINED
|
||||||
|
typedef unsigned char IUINT8;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __IUINT16_DEFINED
|
||||||
|
#define __IUINT16_DEFINED
|
||||||
|
typedef unsigned short IUINT16;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __IINT16_DEFINED
|
||||||
|
#define __IINT16_DEFINED
|
||||||
|
typedef short IINT16;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __IINT32_DEFINED
|
||||||
|
#define __IINT32_DEFINED
|
||||||
|
typedef ISTDINT32 IINT32;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __IUINT32_DEFINED
|
||||||
|
#define __IUINT32_DEFINED
|
||||||
|
typedef ISTDUINT32 IUINT32;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __IINT64_DEFINED
|
||||||
|
#define __IINT64_DEFINED
|
||||||
|
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||||
|
typedef __int64 IINT64;
|
||||||
|
#else
|
||||||
|
typedef long long IINT64;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __IUINT64_DEFINED
|
||||||
|
#define __IUINT64_DEFINED
|
||||||
|
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||||
|
typedef unsigned __int64 IUINT64;
|
||||||
|
#else
|
||||||
|
typedef unsigned long long IUINT64;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INLINE
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
|
||||||
|
#if (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))
|
||||||
|
#define INLINE __inline__ __attribute__((always_inline))
|
||||||
|
#else
|
||||||
|
#define INLINE __inline__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif (defined(_MSC_VER) || defined(__BORLANDC__) || defined(__WATCOMC__))
|
||||||
|
#define INLINE __inline
|
||||||
|
#else
|
||||||
|
#define INLINE
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (!defined(__cplusplus)) && (!defined(inline))
|
||||||
|
#define inline INLINE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//=====================================================================
|
||||||
|
// QUEUE DEFINITION
|
||||||
|
//=====================================================================
|
||||||
|
#ifndef __IQUEUE_DEF__
|
||||||
|
#define __IQUEUE_DEF__
|
||||||
|
|
||||||
|
struct IQUEUEHEAD {
|
||||||
|
struct IQUEUEHEAD *next, *prev;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct IQUEUEHEAD iqueue_head;
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// queue init
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
#define IQUEUE_HEAD_INIT(name) \
|
||||||
|
{ \
|
||||||
|
&(name), &(name) \
|
||||||
|
}
|
||||||
|
#define IQUEUE_HEAD(name) struct IQUEUEHEAD name = IQUEUE_HEAD_INIT(name)
|
||||||
|
|
||||||
|
#define IQUEUE_INIT(ptr) ((ptr)->next = (ptr), (ptr)->prev = (ptr))
|
||||||
|
|
||||||
|
#define IOFFSETOF(TYPE, MEMBER) ((size_t) & ((TYPE *) 0)->MEMBER)
|
||||||
|
|
||||||
|
#define ICONTAINEROF(ptr, type, member) ((type *) (((char *) ((type *) ptr)) - IOFFSETOF(type, member)))
|
||||||
|
|
||||||
|
#define IQUEUE_ENTRY(ptr, type, member) ICONTAINEROF(ptr, type, member)
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// queue operation
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
#define IQUEUE_ADD(node, head) \
|
||||||
|
((node)->prev = (head), (node)->next = (head)->next, (head)->next->prev = (node), (head)->next = (node))
|
||||||
|
|
||||||
|
#define IQUEUE_ADD_TAIL(node, head) \
|
||||||
|
((node)->prev = (head)->prev, (node)->next = (head), (head)->prev->next = (node), (head)->prev = (node))
|
||||||
|
|
||||||
|
#define IQUEUE_DEL_BETWEEN(p, n) ((n)->prev = (p), (p)->next = (n))
|
||||||
|
|
||||||
|
#define IQUEUE_DEL(entry) \
|
||||||
|
((entry)->next->prev = (entry)->prev, (entry)->prev->next = (entry)->next, (entry)->next = 0, (entry)->prev = 0)
|
||||||
|
|
||||||
|
#define IQUEUE_DEL_INIT(entry) \
|
||||||
|
do { \
|
||||||
|
IQUEUE_DEL(entry); \
|
||||||
|
IQUEUE_INIT(entry); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define IQUEUE_IS_EMPTY(entry) ((entry) == (entry)->next)
|
||||||
|
|
||||||
|
#define iqueue_init IQUEUE_INIT
|
||||||
|
#define iqueue_entry IQUEUE_ENTRY
|
||||||
|
#define iqueue_add IQUEUE_ADD
|
||||||
|
#define iqueue_add_tail IQUEUE_ADD_TAIL
|
||||||
|
#define iqueue_del IQUEUE_DEL
|
||||||
|
#define iqueue_del_init IQUEUE_DEL_INIT
|
||||||
|
#define iqueue_is_empty IQUEUE_IS_EMPTY
|
||||||
|
|
||||||
|
#define IQUEUE_FOREACH(iterator, head, TYPE, MEMBER) \
|
||||||
|
for ((iterator) = iqueue_entry((head)->next, TYPE, MEMBER); &((iterator)->MEMBER) != (head); \
|
||||||
|
(iterator) = iqueue_entry((iterator)->MEMBER.next, TYPE, MEMBER))
|
||||||
|
|
||||||
|
#define iqueue_foreach(iterator, head, TYPE, MEMBER) IQUEUE_FOREACH(iterator, head, TYPE, MEMBER)
|
||||||
|
|
||||||
|
#define iqueue_foreach_entry(pos, head) for ((pos) = (head)->next; (pos) != (head); (pos) = (pos)->next)
|
||||||
|
|
||||||
|
#define __iqueue_splice(list, head) \
|
||||||
|
do { \
|
||||||
|
iqueue_head *first = (list)->next, *last = (list)->prev; \
|
||||||
|
iqueue_head *at = (head)->next; \
|
||||||
|
(first)->prev = (head), (head)->next = (first); \
|
||||||
|
(last)->next = (at), (at)->prev = (last); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define iqueue_splice(list, head) \
|
||||||
|
do { \
|
||||||
|
if (!iqueue_is_empty(list)) __iqueue_splice(list, head); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define iqueue_splice_init(list, head) \
|
||||||
|
do { \
|
||||||
|
iqueue_splice(list, head); \
|
||||||
|
iqueue_init(list); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(disable : 4311)
|
||||||
|
#pragma warning(disable : 4312)
|
||||||
|
#pragma warning(disable : 4996)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// BYTE ORDER & ALIGNMENT
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
#ifndef IWORDS_BIG_ENDIAN
|
||||||
|
#ifdef _BIG_ENDIAN_
|
||||||
|
#if _BIG_ENDIAN_
|
||||||
|
#define IWORDS_BIG_ENDIAN 1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifndef IWORDS_BIG_ENDIAN
|
||||||
|
#if defined(__hppa__) || defined(__m68k__) || defined(mc68000) || defined(_M_M68K) \
|
||||||
|
|| (defined(__MIPS__) && defined(__MIPSEB__)) || defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) \
|
||||||
|
|| defined(__sparc__) || defined(__powerpc__) || defined(__mc68000__) || defined(__s390x__) || defined(__s390__)
|
||||||
|
#define IWORDS_BIG_ENDIAN 1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifndef IWORDS_BIG_ENDIAN
|
||||||
|
#define IWORDS_BIG_ENDIAN 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef IWORDS_MUST_ALIGN
|
||||||
|
#if defined(__i386__) || defined(__i386) || defined(_i386_)
|
||||||
|
#define IWORDS_MUST_ALIGN 0
|
||||||
|
#elif defined(_M_IX86) || defined(_X86_) || defined(__x86_64__)
|
||||||
|
#define IWORDS_MUST_ALIGN 0
|
||||||
|
#elif defined(__amd64) || defined(__amd64__)
|
||||||
|
#define IWORDS_MUST_ALIGN 0
|
||||||
|
#else
|
||||||
|
#define IWORDS_MUST_ALIGN 1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//=====================================================================
|
||||||
|
// SEGMENT
|
||||||
|
//=====================================================================
|
||||||
|
struct IKCPSEG {
|
||||||
|
struct IQUEUEHEAD node;
|
||||||
|
IUINT32 conv;
|
||||||
|
IUINT32 cmd;
|
||||||
|
IUINT32 frg;
|
||||||
|
IUINT32 wnd;
|
||||||
|
IUINT32 ts;
|
||||||
|
IUINT32 sn;
|
||||||
|
IUINT32 una;
|
||||||
|
IUINT32 len;
|
||||||
|
IUINT32 resendts;
|
||||||
|
IUINT32 rto;
|
||||||
|
IUINT32 fastack;
|
||||||
|
IUINT32 xmit;
|
||||||
|
char data[1];
|
||||||
|
};
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// IKCPCB
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
struct IKCPCB {
|
||||||
|
IUINT32 conv, mtu, mss, state;
|
||||||
|
IUINT32 snd_una, snd_nxt, rcv_nxt;
|
||||||
|
IUINT32 ts_recent, ts_lastack, ssthresh;
|
||||||
|
IINT32 rx_rttval, rx_srtt, rx_rto, rx_minrto;
|
||||||
|
IUINT32 snd_wnd, rcv_wnd, rmt_wnd, cwnd, probe;
|
||||||
|
IUINT32 current, interval, ts_flush, xmit;
|
||||||
|
IUINT32 nrcv_buf, nsnd_buf;
|
||||||
|
IUINT32 nrcv_que, nsnd_que;
|
||||||
|
IUINT32 nodelay, updated;
|
||||||
|
IUINT32 ts_probe, probe_wait;
|
||||||
|
IUINT32 dead_link, incr;
|
||||||
|
struct IQUEUEHEAD snd_queue;
|
||||||
|
struct IQUEUEHEAD rcv_queue;
|
||||||
|
struct IQUEUEHEAD snd_buf;
|
||||||
|
struct IQUEUEHEAD rcv_buf;
|
||||||
|
IUINT32 *acklist;
|
||||||
|
IUINT32 ackcount;
|
||||||
|
IUINT32 ackblock;
|
||||||
|
void *user;
|
||||||
|
char *buffer;
|
||||||
|
int fastresend;
|
||||||
|
int fastlimit;
|
||||||
|
int nocwnd, stream;
|
||||||
|
int logmask;
|
||||||
|
int (*output)(const char *buf, int len, struct IKCPCB *kcp, void *user);
|
||||||
|
void (*writelog)(const char *log, struct IKCPCB *kcp, void *user);
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct IKCPCB ikcpcb;
|
||||||
|
|
||||||
|
#define IKCP_LOG_OUTPUT 1
|
||||||
|
#define IKCP_LOG_INPUT 2
|
||||||
|
#define IKCP_LOG_SEND 4
|
||||||
|
#define IKCP_LOG_RECV 8
|
||||||
|
#define IKCP_LOG_IN_DATA 16
|
||||||
|
#define IKCP_LOG_IN_ACK 32
|
||||||
|
#define IKCP_LOG_IN_PROBE 64
|
||||||
|
#define IKCP_LOG_IN_WINS 128
|
||||||
|
#define IKCP_LOG_OUT_DATA 256
|
||||||
|
#define IKCP_LOG_OUT_ACK 512
|
||||||
|
#define IKCP_LOG_OUT_PROBE 1024
|
||||||
|
#define IKCP_LOG_OUT_WINS 2048
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// interface
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
// create a new kcp control object, 'conv' must equal in two endpoint
|
||||||
|
// from the same connection. 'user' will be passed to the output callback
|
||||||
|
// output callback can be setup like this: 'kcp->output = my_udp_output'
|
||||||
|
ikcpcb *ikcp_create(IUINT32 conv, void *user);
|
||||||
|
|
||||||
|
// release kcp control object
|
||||||
|
void ikcp_release(ikcpcb *kcp);
|
||||||
|
|
||||||
|
// set output callback, which will be invoked by kcp
|
||||||
|
void ikcp_setoutput(ikcpcb *kcp, int (*output)(const char *buf, int len, ikcpcb *kcp, void *user));
|
||||||
|
|
||||||
|
// user/upper level recv: returns size, returns below zero for EAGAIN
|
||||||
|
int ikcp_recv(ikcpcb *kcp, char *buffer, int len);
|
||||||
|
|
||||||
|
// user/upper level send, returns below zero for error
|
||||||
|
int ikcp_send(ikcpcb *kcp, const char *buffer, int len);
|
||||||
|
|
||||||
|
// update state (call it repeatedly, every 10ms-100ms), or you can ask
|
||||||
|
// ikcp_check when to call it again (without ikcp_input/_send calling).
|
||||||
|
// 'current' - current timestamp in millisec.
|
||||||
|
void ikcp_update(ikcpcb *kcp, IUINT32 current);
|
||||||
|
|
||||||
|
// Determine when should you invoke ikcp_update:
|
||||||
|
// returns when you should invoke ikcp_update in millisec, if there
|
||||||
|
// is no ikcp_input/_send calling. you can call ikcp_update in that
|
||||||
|
// time, instead of call update repeatly.
|
||||||
|
// Important to reduce unnacessary ikcp_update invoking. use it to
|
||||||
|
// schedule ikcp_update (eg. implementing an epoll-like mechanism,
|
||||||
|
// or optimize ikcp_update when handling massive kcp connections)
|
||||||
|
IUINT32 ikcp_check(const ikcpcb *kcp, IUINT32 current);
|
||||||
|
|
||||||
|
// when you received a low level packet (eg. UDP packet), call it
|
||||||
|
int ikcp_input(ikcpcb *kcp, const char *data, long size);
|
||||||
|
|
||||||
|
// flush pending data
|
||||||
|
void ikcp_flush(ikcpcb *kcp);
|
||||||
|
|
||||||
|
// check the size of next message in the recv queue
|
||||||
|
int ikcp_peeksize(const ikcpcb *kcp);
|
||||||
|
|
||||||
|
// change MTU size, default is 1400
|
||||||
|
int ikcp_setmtu(ikcpcb *kcp, int mtu);
|
||||||
|
|
||||||
|
// set maximum window size: sndwnd=32, rcvwnd=32 by default
|
||||||
|
int ikcp_wndsize(ikcpcb *kcp, int sndwnd, int rcvwnd);
|
||||||
|
|
||||||
|
// get how many packet is waiting to be sent
|
||||||
|
int ikcp_waitsnd(const ikcpcb *kcp);
|
||||||
|
|
||||||
|
// fastest: ikcp_nodelay(kcp, 1, 20, 2, 1)
|
||||||
|
// nodelay: 0:disable(default), 1:enable
|
||||||
|
// interval: internal update timer interval in millisec, default is 100ms
|
||||||
|
// resend: 0:disable fast resend(default), 1:enable fast resend
|
||||||
|
// nc: 0:normal congestion control(default), 1:disable congestion control
|
||||||
|
int ikcp_nodelay(ikcpcb *kcp, int nodelay, int interval, int resend, int nc);
|
||||||
|
|
||||||
|
void ikcp_log(ikcpcb *kcp, int mask, const char *fmt, ...);
|
||||||
|
|
||||||
|
// setup allocator
|
||||||
|
void ikcp_allocator(void *(*new_malloc)(size_t), void (*new_free)(void *));
|
||||||
|
|
||||||
|
// read conv
|
||||||
|
IUINT32 ikcp_getconv(const void *ptr);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
10
3party/kcp/kcp.h
Normal file
10
3party/kcp/kcp.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#ifndef SLED__3PARTY_KCP_KCP_H
|
||||||
|
#define SLED__3PARTY_KCP_KCP_H
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace sled {
|
||||||
|
class KCP {};
|
||||||
|
}// namespace sled
|
||||||
|
|
||||||
|
#endif// SLED__3PARTY_KCP_KCP_H
|
@ -100,7 +100,8 @@ target_sources(
|
|||||||
src/sled/time_utils.cc
|
src/sled/time_utils.cc
|
||||||
src/sled/units/time_delta.cc
|
src/sled/units/time_delta.cc
|
||||||
src/sled/units/timestamp.cc
|
src/sled/units/timestamp.cc
|
||||||
src/sled/uri.cc)
|
src/sled/uri.cc
|
||||||
|
src/sled/nonstd/pugixml/pugixml.cpp)
|
||||||
|
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
sled
|
sled
|
||||||
@ -199,6 +200,7 @@ if(SLED_BUILD_TESTS)
|
|||||||
src/sled/system/thread_pool_test.cc)
|
src/sled/system/thread_pool_test.cc)
|
||||||
sled_add_test(NAME sled_event_bus_test SRCS
|
sled_add_test(NAME sled_event_bus_test SRCS
|
||||||
src/sled/event_bus/event_bus_test.cc)
|
src/sled/event_bus/event_bus_test.cc)
|
||||||
|
sled_add_test(NAME sled_pugixml_test SRCS tests/pugixml_test.cc)
|
||||||
sled_add_test(NAME sled_lua_test SRCS tests/lua_test.cc)
|
sled_add_test(NAME sled_lua_test SRCS tests/lua_test.cc)
|
||||||
sled_add_test(NAME sled_move_on_copy_test SRCS
|
sled_add_test(NAME sled_move_on_copy_test SRCS
|
||||||
src/sled/utility/move_on_copy_test.cc)
|
src/sled/utility/move_on_copy_test.cc)
|
||||||
|
31
src/sled/metric/counter.cc
Normal file
31
src/sled/metric/counter.cc
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#include "counter.h"
|
||||||
|
|
||||||
|
namespace sled {
|
||||||
|
namespace metric {
|
||||||
|
void
|
||||||
|
Counter::Increment()
|
||||||
|
{
|
||||||
|
gauge_.Increment();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Counter::Increment(double value)
|
||||||
|
{
|
||||||
|
if (value < 0) { return; }
|
||||||
|
gauge_.Increment(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Counter::Reset()
|
||||||
|
{
|
||||||
|
gauge_.Set(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
Counter::Value() const
|
||||||
|
{
|
||||||
|
return gauge_.Value();
|
||||||
|
}
|
||||||
|
|
||||||
|
}// namespace metric
|
||||||
|
}// namespace sled
|
26
src/sled/metric/counter.h
Normal file
26
src/sled/metric/counter.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#ifndef SLED_METRIC_COUNTER_H
|
||||||
|
#define SLED_METRIC_COUNTER_H
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "gauge.h"
|
||||||
|
|
||||||
|
namespace sled {
|
||||||
|
namespace metric {
|
||||||
|
|
||||||
|
class Counter {
|
||||||
|
public:
|
||||||
|
Counter() = default;
|
||||||
|
void Increment();
|
||||||
|
void Increment(double value);
|
||||||
|
void Reset();
|
||||||
|
|
||||||
|
double Value() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Gauge gauge_{0.0};
|
||||||
|
};
|
||||||
|
|
||||||
|
}// namespace metric
|
||||||
|
}// namespace sled
|
||||||
|
|
||||||
|
#endif// SLED_METRIC_COUNTER_H
|
58
src/sled/metric/gauge.cc
Normal file
58
src/sled/metric/gauge.cc
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#include "gauge.h"
|
||||||
|
|
||||||
|
namespace sled {
|
||||||
|
namespace metric {
|
||||||
|
Gauge::Gauge(double value) : value_(value) {}
|
||||||
|
|
||||||
|
void
|
||||||
|
Gauge::Increment()
|
||||||
|
{
|
||||||
|
Change(1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Gauge::Increment(double value)
|
||||||
|
{
|
||||||
|
Change(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Gauge::Decrement()
|
||||||
|
{
|
||||||
|
Change(-1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Gauge::Decrement(double value)
|
||||||
|
{
|
||||||
|
Change(-1.0 * value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Gauge::Set(double value)
|
||||||
|
{
|
||||||
|
value_.store(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Gauge::SetToCurrentTime()
|
||||||
|
{
|
||||||
|
const auto time = std::time(nullptr);
|
||||||
|
Set(static_cast<double>(time));
|
||||||
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
Gauge::Value() const
|
||||||
|
{
|
||||||
|
return value_.load();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Gauge::Change(double delta)
|
||||||
|
{
|
||||||
|
auto current = value_.load();
|
||||||
|
while (!value_.compare_exchange_weak(current, current + delta)) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
}// namespace metric
|
||||||
|
}// namespace sled
|
32
src/sled/metric/gauge.h
Normal file
32
src/sled/metric/gauge.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#ifndef SLED_METRIC_GAUGE_H
|
||||||
|
#define SLED_METRIC_GAUGE_H
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace sled {
|
||||||
|
namespace metric {
|
||||||
|
class Gauge {
|
||||||
|
public:
|
||||||
|
Gauge() = default;
|
||||||
|
explicit Gauge(double value);
|
||||||
|
|
||||||
|
void Increment();
|
||||||
|
void Increment(double value);
|
||||||
|
|
||||||
|
void Decrement();
|
||||||
|
void Decrement(double value);
|
||||||
|
|
||||||
|
void Set(double value);
|
||||||
|
// set the gauge to the current unix timestamp
|
||||||
|
void SetToCurrentTime();
|
||||||
|
|
||||||
|
double Value() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Change(double delta);
|
||||||
|
std::atomic<double> value_{0.0};
|
||||||
|
};
|
||||||
|
}// namespace metric
|
||||||
|
}// namespace sled
|
||||||
|
|
||||||
|
#endif// SLED_METRIC_GAUGE_H
|
32
src/sled/metric/histogram.h
Normal file
32
src/sled/metric/histogram.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#ifndef SLED_METRIC_HISTOGRAMH
|
||||||
|
#define SLED_METRIC_HISTOGRAMH
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "counter.h"
|
||||||
|
#include "sled/synchronization/mutex.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace sled {
|
||||||
|
namespace metric {
|
||||||
|
class Histogram {
|
||||||
|
public:
|
||||||
|
using BucketBoundaries = std::vector<double>;
|
||||||
|
|
||||||
|
explicit Histogram(const BucketBoundaries &bucket_boundaries);
|
||||||
|
explicit Histogram(BucketBoundaries &&bucket_boundaries);
|
||||||
|
|
||||||
|
void Observe(double value);
|
||||||
|
void ObserveMutiple(const std::vector<double> &bucket_increments, double sum_of_values);
|
||||||
|
void Reset();
|
||||||
|
|
||||||
|
private:
|
||||||
|
mutable Mutex mutex_;
|
||||||
|
BucketBoundaries bucket_boundaries_;
|
||||||
|
std::vector<Counter> bucket_counts_;
|
||||||
|
Gauge sum_;
|
||||||
|
};
|
||||||
|
}// namespace metric
|
||||||
|
}// namespace sled
|
||||||
|
|
||||||
|
#endif// SLED_METRIC_HISTOGRAMH
|
77
src/sled/nonstd/pugixml/pugiconfig.hpp
Normal file
77
src/sled/nonstd/pugixml/pugiconfig.hpp
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
/**
|
||||||
|
* pugixml parser - version 1.14
|
||||||
|
* --------------------------------------------------------
|
||||||
|
* Copyright (C) 2006-2023, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
|
||||||
|
* Report bugs and download new versions at https://pugixml.org/
|
||||||
|
*
|
||||||
|
* This library is distributed under the MIT License. See notice at the end
|
||||||
|
* of this file.
|
||||||
|
*
|
||||||
|
* This work is based on the pugxml parser, which is:
|
||||||
|
* Copyright (C) 2003, by Kristen Wegner (kristen@tima.net)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HEADER_PUGICONFIG_HPP
|
||||||
|
#define HEADER_PUGICONFIG_HPP
|
||||||
|
|
||||||
|
// Uncomment this to enable wchar_t mode
|
||||||
|
// #define PUGIXML_WCHAR_MODE
|
||||||
|
|
||||||
|
// Uncomment this to enable compact mode
|
||||||
|
// #define PUGIXML_COMPACT
|
||||||
|
|
||||||
|
// Uncomment this to disable XPath
|
||||||
|
// #define PUGIXML_NO_XPATH
|
||||||
|
|
||||||
|
// Uncomment this to disable STL
|
||||||
|
// #define PUGIXML_NO_STL
|
||||||
|
|
||||||
|
// Uncomment this to disable exceptions
|
||||||
|
// #define PUGIXML_NO_EXCEPTIONS
|
||||||
|
|
||||||
|
// Set this to control attributes for public classes/functions, i.e.:
|
||||||
|
// #define PUGIXML_API __declspec(dllexport) // to export all public symbols from DLL
|
||||||
|
// #define PUGIXML_CLASS __declspec(dllimport) // to import all classes from DLL
|
||||||
|
// #define PUGIXML_FUNCTION __fastcall // to set calling conventions to all public functions to fastcall
|
||||||
|
// In absence of PUGIXML_CLASS/PUGIXML_FUNCTION definitions PUGIXML_API is used instead
|
||||||
|
|
||||||
|
// Tune these constants to adjust memory-related behavior
|
||||||
|
// #define PUGIXML_MEMORY_PAGE_SIZE 32768
|
||||||
|
// #define PUGIXML_MEMORY_OUTPUT_STACK 10240
|
||||||
|
// #define PUGIXML_MEMORY_XPATH_PAGE_SIZE 4096
|
||||||
|
|
||||||
|
// Tune this constant to adjust max nesting for XPath queries
|
||||||
|
// #define PUGIXML_XPATH_DEPTH_LIMIT 1024
|
||||||
|
|
||||||
|
// Uncomment this to switch to header-only version
|
||||||
|
// #define PUGIXML_HEADER_ONLY
|
||||||
|
|
||||||
|
// Uncomment this to enable long long support
|
||||||
|
// #define PUGIXML_HAS_LONG_LONG
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2006-2023 Arseny Kapoulkine
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use,
|
||||||
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following
|
||||||
|
* conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||||
|
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
13226
src/sled/nonstd/pugixml/pugixml.cpp
Normal file
13226
src/sled/nonstd/pugixml/pugixml.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1516
src/sled/nonstd/pugixml/pugixml.hpp
Normal file
1516
src/sled/nonstd/pugixml/pugixml.hpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -8,6 +8,7 @@
|
|||||||
#include "sled/nonstd/expected.h"
|
#include "sled/nonstd/expected.h"
|
||||||
#include "sled/nonstd/fsm.h"
|
#include "sled/nonstd/fsm.h"
|
||||||
#include "sled/nonstd/inja.h"
|
#include "sled/nonstd/inja.h"
|
||||||
|
#include "sled/nonstd/pugixml/pugixml.hpp"
|
||||||
#include "sled/nonstd/string_view.h"
|
#include "sled/nonstd/string_view.h"
|
||||||
#include "toml.hpp"
|
#include "toml.hpp"
|
||||||
|
|
||||||
|
48
tests/pugixml_test.cc
Normal file
48
tests/pugixml_test.cc
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#include <sled/sled.h>
|
||||||
|
|
||||||
|
static constexpr char kXmlA[] =
|
||||||
|
R"(<?xml version="1.0"?>
|
||||||
|
<root>
|
||||||
|
<str>hello</str>
|
||||||
|
<node id="1">text1</node>
|
||||||
|
<node id="2">text2</node>
|
||||||
|
<node id="3">text3</node>
|
||||||
|
</root>
|
||||||
|
)";
|
||||||
|
|
||||||
|
static constexpr char kXmlB[] =
|
||||||
|
R"(<?xml version="1.0"?>
|
||||||
|
<root>
|
||||||
|
<level1>
|
||||||
|
<level2>
|
||||||
|
<node id="1">text1</node>
|
||||||
|
<node id="2">text2</node>
|
||||||
|
<node id="3">text3</node>
|
||||||
|
</level2>
|
||||||
|
</level1>
|
||||||
|
</root>)";
|
||||||
|
|
||||||
|
TEST_SUITE("pugixml")
|
||||||
|
{
|
||||||
|
TEST_CASE("xpath query")
|
||||||
|
{
|
||||||
|
pugi::xml_document doc;
|
||||||
|
pugi::xml_parse_result result = doc.load_string(kXmlA);
|
||||||
|
CHECK(result);
|
||||||
|
pugi::xpath_node_set nodes = doc.select_nodes("//node");
|
||||||
|
CHECK_EQ(nodes.size(), 3);
|
||||||
|
CHECK_EQ(nodes[0].node().attribute("id").as_int(), 1);
|
||||||
|
CHECK_EQ(nodes[1].node().attribute("id").as_int(), 2);
|
||||||
|
CHECK_EQ(nodes[2].node().attribute("id").as_int(), 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("xpath *")
|
||||||
|
{
|
||||||
|
pugi::xml_document doc;
|
||||||
|
pugi::xml_parse_result result = doc.load_string(kXmlA);
|
||||||
|
CHECK(result);
|
||||||
|
pugi::xpath_node_set nodes = doc.select_nodes("/*/str");
|
||||||
|
CHECK(nodes.size() == 1);
|
||||||
|
CHECK_EQ(std::string("hello"), nodes[0].node().text().as_string());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user