├── stdafx.h ├── kronos.cpp ├── stdafx.cpp ├── targetver.h ├── k_util ├── k_socket.h ├── k_errno.h ├── k_errno.cpp ├── k_mutex.h ├── k_handler.h ├── k_sockaddr.h ├── k_util.h ├── k_handler.cpp ├── k_sockaddr.cpp ├── k_string.h ├── k_util.cpp ├── k_event.h ├── k_mutex.cpp ├── k_thread_task.h ├── k_string.cpp ├── k_event.cpp ├── k_socket.cpp └── k_thread_task.cpp ├── k_mobile_handler.cpp ├── ReadMe.txt ├── kronos.vcxproj.user ├── k_media_server.h ├── Makefile ├── k_accept_handler.h ├── k_media_server.cpp ├── k_mobile_handler.h ├── k_rtsp_handler.h ├── kronos.vcxproj.filters ├── kronos.vcxproj ├── k_rtsp_handler.cpp └── jsoncpp └── json ├── json-forwards.h └── json.h /stdafx.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/greenjim301/kronos/HEAD/stdafx.h -------------------------------------------------------------------------------- /kronos.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/greenjim301/kronos/HEAD/kronos.cpp -------------------------------------------------------------------------------- /stdafx.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/greenjim301/kronos/HEAD/stdafx.cpp -------------------------------------------------------------------------------- /targetver.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/greenjim301/kronos/HEAD/targetver.h -------------------------------------------------------------------------------- /k_util/k_socket.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/greenjim301/kronos/HEAD/k_util/k_socket.h -------------------------------------------------------------------------------- /k_mobile_handler.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/greenjim301/kronos/HEAD/k_mobile_handler.cpp -------------------------------------------------------------------------------- /ReadMe.txt: -------------------------------------------------------------------------------- 1 | 简单的手机推流服务器和RTSP服务器 2 | 3 | 手机采集音视频流推到该服务器 4 | 5 | RTSP客户端向该服务器请求手机采集流 6 | 7 | 简单介绍见https://blog.csdn.net/greenjim301/article/details/80563603 8 | -------------------------------------------------------------------------------- /k_util/k_errno.h: -------------------------------------------------------------------------------- 1 | #ifndef __K_ERRNO_H__ 2 | #define __K_ERRNO_H__ 3 | 4 | class k_errno 5 | { 6 | public: 7 | static int last_error(); 8 | static bool is_retry_error(int err); 9 | }; 10 | 11 | 12 | #endif -------------------------------------------------------------------------------- /kronos.vcxproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 192.168.1.101 9010 5 | WindowsLocalDebugger 6 | 7 | -------------------------------------------------------------------------------- /k_media_server.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "k_util/k_thread_task.h" 4 | #include "k_rtsp_handler.h" 5 | #include 6 | 7 | class k_media_server : public k_thread_task 8 | { 9 | public: 10 | void regist_sink(k_rtsp_handler* handler); 11 | void unregist_sink(k_rtsp_handler* handler); 12 | void on_video(uint8_t* buf, int len); 13 | void on_audio(uint8_t* buf, int len); 14 | 15 | private: 16 | std::set m_rtsp_handler; 17 | }; 18 | -------------------------------------------------------------------------------- /k_util/k_errno.cpp: -------------------------------------------------------------------------------- 1 | #include "k_errno.h" 2 | 3 | #ifdef WIN32 4 | #include 5 | #else 6 | #include 7 | #endif 8 | 9 | int k_errno::last_error() 10 | { 11 | #ifdef WIN32 12 | return WSAGetLastError(); 13 | #else 14 | return errno; 15 | #endif 16 | } 17 | 18 | bool k_errno::is_retry_error(int err) 19 | { 20 | #ifdef WIN32 21 | return err == WSAEWOULDBLOCK; 22 | //return false; 23 | #else 24 | return err == EINTR; 25 | #endif 26 | } 27 | -------------------------------------------------------------------------------- /k_util/k_mutex.h: -------------------------------------------------------------------------------- 1 | #ifndef __K_MUTEX_H__ 2 | #define __K_MUTEX_H__ 3 | 4 | #ifdef WIN32 5 | #include 6 | #include 7 | #define K_MUTEX_T HANDLE 8 | #else 9 | #include 10 | #define K_MUTEX_T pthread_mutex_t 11 | #endif 12 | 13 | class k_mutex 14 | { 15 | public: 16 | k_mutex(); 17 | ~k_mutex(); 18 | 19 | int init(); 20 | int acquire(); 21 | void release(); 22 | 23 | private: 24 | K_MUTEX_T m_mutex; 25 | }; 26 | 27 | #endif -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CXX = g++ 2 | #2、定义您自己的可执行文件名称 3 | PROGRAM_NAME=kronos 4 | ##################################################################### # 5 | #3、指定您必须生成的工程文件 6 | 7 | SOURCE = $(wildcard *.cpp) \ 8 | $(wildcard k_util/*.cpp) 9 | 10 | OBJECTS = $(SOURCE:.cpp=.o) 11 | CFLAGS = -g 12 | 13 | .PHONY: all 14 | all: $(PROGRAM_NAME) 15 | 16 | clean: 17 | @echo "[Cleanning...]" 18 | @rm -f $(OBJECTS) $(PROGRAM_NAME) 19 | 20 | %.o: %.cpp 21 | $(CXX) $(CFLAGS) -o $@ -c $< 22 | 23 | 24 | $(PROGRAM_NAME): $(OBJECTS) 25 | $(CXX) $(CFLAGS) -o $@ $^ -lpthread 26 | -------------------------------------------------------------------------------- /k_util/k_handler.h: -------------------------------------------------------------------------------- 1 | #ifndef __K_HANDLER_H__ 2 | #define __K_HANDLER_H__ 3 | 4 | class k_event; 5 | class k_thread_task; 6 | class k_socket; 7 | 8 | class k_handler 9 | { 10 | public: 11 | k_handler(); 12 | virtual ~k_handler(); 13 | 14 | virtual int handle_read(k_thread_task* task, k_event* ev, k_socket* sock) = 0; 15 | 16 | virtual void handle_del(k_thread_task* task, k_event* ev, k_socket* sock); 17 | virtual int handle_close(k_thread_task* task, k_event* ev, k_socket* sock); 18 | virtual int handle_write(k_thread_task* task, k_event* ev, k_socket* sock); 19 | }; 20 | 21 | #endif -------------------------------------------------------------------------------- /k_accept_handler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "k_util/k_handler.h" 4 | 5 | template 6 | class k_accept_handler : public k_handler 7 | { 8 | public: 9 | virtual int handle_read(k_thread_task* task, k_event* ev, k_socket* sock) 10 | { 11 | printf("accepted\n"); 12 | 13 | k_socket* accept_sock = new k_socket; 14 | k_sockaddr addr; 15 | m_read_handler = new T; 16 | 17 | sock->k_accept(addr, *accept_sock); 18 | task->add_event(accept_sock, m_read_handler, k_event::READ_MASK); 19 | 20 | return 0; 21 | } 22 | 23 | private: 24 | T* m_read_handler; 25 | }; 26 | -------------------------------------------------------------------------------- /k_util/k_sockaddr.h: -------------------------------------------------------------------------------- 1 | #ifndef __K_SOCKADDR_H__ 2 | #define __K_SOCKADDR_H__ 3 | 4 | #include 5 | #include "k_string.h" 6 | #ifdef WIN32 7 | #include 8 | #include 9 | #else 10 | #include 11 | #include 12 | #include 13 | #endif 14 | 15 | class k_sockaddr 16 | { 17 | public: 18 | k_sockaddr(); 19 | 20 | int init(int af, k_string& ip, uint16_t port); 21 | struct sockaddr* get_sockaddr(); 22 | socklen_t get_size(); 23 | socklen_t* get_size_ptr(); 24 | 25 | private: 26 | struct sockaddr_in m_sockaddr; 27 | socklen_t m_size; 28 | }; 29 | 30 | #endif -------------------------------------------------------------------------------- /k_media_server.cpp: -------------------------------------------------------------------------------- 1 | #include "k_media_server.h" 2 | 3 | void k_media_server::regist_sink(k_rtsp_handler* handler) 4 | { 5 | m_rtsp_handler.insert(handler); 6 | } 7 | 8 | void k_media_server::unregist_sink(k_rtsp_handler* handler) 9 | { 10 | m_rtsp_handler.erase(handler); 11 | } 12 | 13 | void k_media_server::on_video(uint8_t* buf, int len) 14 | { 15 | for (auto it = m_rtsp_handler.begin(); it != m_rtsp_handler.end(); ++it) 16 | { 17 | (*it)->on_video(buf, len); 18 | } 19 | } 20 | 21 | void k_media_server::on_audio(uint8_t* buf, int len) 22 | { 23 | for (auto it = m_rtsp_handler.begin(); it != m_rtsp_handler.end(); ++it) 24 | { 25 | (*it)->on_audio(buf, len); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /k_util/k_util.h: -------------------------------------------------------------------------------- 1 | #ifndef __K_UTIL_H__ 2 | #define __K_UTIL_H__ 3 | 4 | #include 5 | 6 | class k_util 7 | { 8 | public: 9 | static int init(); 10 | static void cleanup(); 11 | 12 | static void k_sleep(int seconds); 13 | 14 | static void avio_w8(uint8_t*& s, int b); 15 | static void avio_wb16(uint8_t*& s, unsigned int val); 16 | static void avio_wb32(uint8_t*& s, unsigned int val); 17 | }; 18 | 19 | #define AV_RB16(x) ((((const uint8_t*)(x))[0] << 8) | ((const uint8_t*)(x))[1]) 20 | #define AV_RB32(x) ((((const uint8_t*)(x))[0] << 24) | \ 21 | (((const uint8_t*)(x))[1] << 16) | \ 22 | (((const uint8_t*)(x))[2] << 8) | \ 23 | ((const uint8_t*)(x))[3]) 24 | 25 | #endif -------------------------------------------------------------------------------- /k_util/k_handler.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "k_handler.h" 4 | #include "k_socket.h" 5 | #include "k_thread_task.h" 6 | 7 | k_handler::k_handler() { 8 | 9 | } 10 | 11 | k_handler::~k_handler() { 12 | 13 | } 14 | 15 | void k_handler::handle_del(k_thread_task* task, k_event* ev, k_socket* sock) 16 | { 17 | printf("delete sock %p\n", sock); 18 | delete sock; 19 | delete this; 20 | } 21 | 22 | int k_handler::handle_close(k_thread_task* task, k_event* ev, k_socket* sock) 23 | { 24 | printf("close sock %p\n", sock); 25 | return task->del_event(sock); 26 | } 27 | 28 | int k_handler::handle_write(k_thread_task* task, k_event* ev, k_socket* sock) 29 | { 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /k_util/k_sockaddr.cpp: -------------------------------------------------------------------------------- 1 | #include "k_sockaddr.h" 2 | 3 | k_sockaddr::k_sockaddr() 4 | : m_size(sizeof(m_sockaddr)) 5 | { 6 | 7 | } 8 | 9 | int k_sockaddr::init(int af, k_string& ip, uint16_t port) 10 | { 11 | m_sockaddr.sin_family = af; 12 | m_sockaddr.sin_port = htons(port); 13 | 14 | int ret = inet_pton(af, ip.c_str(), &m_sockaddr.sin_addr.s_addr); 15 | if (ret != 1) 16 | { 17 | return -1; 18 | } 19 | 20 | return 0; 21 | } 22 | 23 | struct sockaddr* k_sockaddr::get_sockaddr() 24 | { 25 | return (struct sockaddr*)&m_sockaddr; 26 | } 27 | 28 | socklen_t k_sockaddr::get_size() 29 | { 30 | return m_size; 31 | } 32 | 33 | socklen_t* k_sockaddr::get_size_ptr() 34 | { 35 | return &m_size; 36 | } 37 | 38 | -------------------------------------------------------------------------------- /k_util/k_string.h: -------------------------------------------------------------------------------- 1 | #ifndef __K_STRING_H__ 2 | #define __K_STRING_H__ 3 | 4 | #include 5 | 6 | class k_string 7 | { 8 | public: 9 | k_string(); 10 | k_string(const char* str); 11 | k_string(const char* str, int size); 12 | 13 | void assign(const char* str, int size); 14 | void append(const char* str, int size); 15 | void append(uint32_t num); 16 | 17 | char* find(const char* str); 18 | 19 | const char* c_str() const; 20 | int size() const; 21 | 22 | bool operator < (const k_string& r_str) const; 23 | bool operator == (const k_string& r_str) const; 24 | 25 | private: 26 | enum 27 | { 28 | STR_MAX_LEN = 256 29 | }; 30 | 31 | char m_buf[STR_MAX_LEN]; 32 | int m_size; 33 | }; 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /k_util/k_util.cpp: -------------------------------------------------------------------------------- 1 | #include "k_util.h" 2 | #ifdef WIN32 3 | #include 4 | #endif 5 | 6 | int k_util::init() 7 | { 8 | #ifdef WIN32 9 | WSADATA wsaData; 10 | if (WSAStartup(MAKEWORD(2, 2), &wsaData)) 11 | { 12 | return -1; 13 | } 14 | #endif 15 | 16 | return 0; 17 | } 18 | 19 | void k_util::cleanup() 20 | { 21 | #ifdef WIN32 22 | WSACleanup(); 23 | #endif 24 | } 25 | 26 | void k_util::k_sleep(int seconds) 27 | { 28 | #ifdef WIN32 29 | Sleep(seconds * 1000); 30 | #else 31 | sleep(seconds); 32 | #endif 33 | } 34 | 35 | void k_util::avio_w8(uint8_t*& s, int b) 36 | { 37 | *s++ = b; 38 | } 39 | 40 | void k_util::avio_wb16(uint8_t*& s, unsigned int val) 41 | { 42 | avio_w8(s, (int)val >> 8); 43 | avio_w8(s, (uint8_t)val); 44 | } 45 | 46 | void k_util::avio_wb32(uint8_t*& s, unsigned int val) 47 | { 48 | avio_w8(s, val >> 24); 49 | avio_w8(s, (uint8_t)(val >> 16)); 50 | avio_w8(s, (uint8_t)(val >> 8)); 51 | avio_w8(s, (uint8_t)val); 52 | } 53 | 54 | -------------------------------------------------------------------------------- /k_util/k_event.h: -------------------------------------------------------------------------------- 1 | #ifndef __K_EVENT_H__ 2 | #define __K_EVENT_H__ 3 | 4 | #ifdef WIN32 5 | #include 6 | #define K_EVENT_T WSAEVENT 7 | #else 8 | #include 9 | #define K_EVENT_T epoll_event 10 | #endif 11 | 12 | #include "k_handler.h" 13 | #include "k_socket.h" 14 | 15 | class k_event 16 | { 17 | public: 18 | enum 19 | { 20 | READ_MASK = (1 << 0), 21 | WRITE_MASK = (1 << 1), 22 | ACCEPT_MASK = (1 << 3), 23 | CLOSE_MASK = (1 << 4) 24 | }; 25 | 26 | k_event(); 27 | ~k_event(); 28 | 29 | int init(k_socket* sock, k_handler* handler, uint32_t event_mask); 30 | K_EVENT_T get_event(); 31 | K_EVENT_T* get_event_ptr(); 32 | k_socket* get_socket(); 33 | uint32_t get_event_mask(); 34 | 35 | void process(k_thread_task* task, uint32_t mask); 36 | void on_del(k_thread_task* task); 37 | 38 | int parse_event_mask(K_EVENT_T event, uint32_t& mask); 39 | 40 | private: 41 | int gen_event_mask(uint32_t event_mask); 42 | 43 | private: 44 | uint32_t m_event_mask; 45 | K_EVENT_T m_event; 46 | k_handler* m_handler; 47 | k_socket* m_socket; 48 | }; 49 | 50 | #endif -------------------------------------------------------------------------------- /k_util/k_mutex.cpp: -------------------------------------------------------------------------------- 1 | #include "k_mutex.h" 2 | 3 | k_mutex::k_mutex() 4 | #ifdef WIN32 5 | : m_mutex(NULL) 6 | #endif 7 | { 8 | 9 | } 10 | 11 | k_mutex::~k_mutex() 12 | { 13 | #ifdef WIN32 14 | if (m_mutex != NULL) 15 | { 16 | CloseHandle(m_mutex); 17 | } 18 | #else 19 | pthread_mutex_destroy(&m_mutex); 20 | #endif 21 | } 22 | 23 | int k_mutex::init() 24 | { 25 | #ifdef WIN32 26 | m_mutex = CreateMutex(NULL, FALSE, NULL); 27 | if (m_mutex == NULL) 28 | { 29 | return -1; 30 | } 31 | #else 32 | if(pthread_mutex_init(&m_mutex, NULL)) 33 | { 34 | return -1; 35 | } 36 | #endif 37 | 38 | return 0; 39 | } 40 | 41 | int k_mutex::acquire() 42 | { 43 | #ifdef WIN32 44 | int ret = WaitForSingleObject(m_mutex, INFINITE); 45 | 46 | if (ret != WAIT_OBJECT_0) 47 | { 48 | return -1; 49 | } 50 | #else 51 | if(pthread_mutex_lock(&m_mutex)) 52 | { 53 | return -1; 54 | } 55 | #endif 56 | 57 | return 0; 58 | } 59 | 60 | void k_mutex::release() 61 | { 62 | #ifdef WIN32 63 | ReleaseMutex(m_mutex); 64 | #else 65 | pthread_mutex_unlock(&m_mutex); 66 | #endif 67 | } 68 | -------------------------------------------------------------------------------- /k_mobile_handler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "k_util/k_handler.h" 4 | #include 5 | #include 6 | 7 | class k_mobile_handler : public k_handler 8 | { 9 | public: 10 | k_mobile_handler(); 11 | ~k_mobile_handler(); 12 | 13 | enum 14 | { 15 | K_MSG_HEAD_LEN = sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint32_t), 16 | K_MAGIC = 0x1234, 17 | K_VIDEO = 1000, 18 | K_AUDIO = 1001, 19 | K_LOGIN = 1002, 20 | K_LOGIN_RSP = 1003 21 | }; 22 | 23 | virtual int handle_read(k_thread_task* task, k_event* ev, k_socket* sock); 24 | 25 | int incoming_msg(uint32_t msg_id, const char* buf, int len, 26 | k_thread_task* task, k_event* ev, k_socket* sock); 27 | 28 | int on_login_msg(const char* buf, int len, k_socket* sock, k_thread_task* task); 29 | int on_media_msg(k_thread_task* task, uint32_t msg_id, uint8_t* buf, int len); 30 | 31 | int ff_h264_handle_frag_packet(const uint8_t *buf, int len, 32 | int start_bit, const uint8_t *nal_header, 33 | int nal_header_len); 34 | 35 | int h264_handle_packet_fu_a(const uint8_t *buf, int len); 36 | 37 | 38 | private: 39 | char buf[4096]; 40 | char head_buf[K_MSG_HEAD_LEN]; 41 | 42 | char* m_rebuf; 43 | uint32_t m_rebuf_size; 44 | FILE* m_video_fp; 45 | FILE* m_auido_fp; 46 | }; 47 | -------------------------------------------------------------------------------- /k_rtsp_handler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "k_util/k_handler.h" 4 | #include "k_util/k_string.h" 5 | #include 6 | #include 7 | 8 | class k_rtsp_rsp 9 | { 10 | public: 11 | k_string version; 12 | k_string result; 13 | k_string describe; 14 | k_string session; 15 | k_string transport; 16 | 17 | k_string content_type; 18 | k_string content_base; 19 | 20 | k_string cseq; 21 | k_string rtsp_public; 22 | 23 | std::list sdp; 24 | }; 25 | 26 | class k_rtsp_head 27 | { 28 | public: 29 | k_string cmd; 30 | k_string url; 31 | k_string version; 32 | k_string cseq; 33 | k_string session; 34 | k_string transport; 35 | }; 36 | 37 | class k_rtsp_handler : public k_handler 38 | { 39 | public: 40 | k_rtsp_handler(); 41 | ~k_rtsp_handler(); 42 | 43 | virtual int handle_read(k_thread_task* task, k_event* ev, k_socket* sock); 44 | virtual void handle_del(k_thread_task* task, k_event* ev, k_socket* sock); 45 | 46 | void on_video(uint8_t* buf, int len); 47 | void on_audio(uint8_t* buf, int len); 48 | 49 | private: 50 | int parse_rtp_rtcp(uint8_t channel, char* buf, int len); 51 | int next_sapce(char* p, char*& p_sapce); 52 | int skip_space(char*& p); 53 | void next_end(char* p, char*& p_end); 54 | int parse_head_line(char*& p, k_rtsp_head& head); 55 | int parse_line(char*& p, k_rtsp_head& head); 56 | void append_space(char*& p); 57 | void append_line_end(char*& p); 58 | int send_rtsp_rsp(k_rtsp_rsp& rsp, k_socket* sock); 59 | int on_rtsp_head(k_rtsp_head& head, k_thread_task* task, k_socket* sock); 60 | 61 | private: 62 | char m_buf[4096 + 1]; 63 | uint32_t m_session_id; 64 | k_socket* m_sock; 65 | char* m_rebuf; 66 | int m_rebuf_size; 67 | }; -------------------------------------------------------------------------------- /k_util/k_thread_task.h: -------------------------------------------------------------------------------- 1 | #ifndef __K_THREAD_TASK_H__ 2 | #define __K_THREAD_TASK_H__ 3 | 4 | #include 5 | #include 6 | 7 | #include "k_event.h" 8 | #include "k_mutex.h" 9 | 10 | struct k_msg 11 | { 12 | int m_msg_id; 13 | void* m_data; 14 | }; 15 | 16 | struct k_add_event 17 | { 18 | k_socket* m_sock; 19 | k_handler* m_handler; 20 | uint32_t m_event_mask; 21 | }; 22 | 23 | struct k_del_event 24 | { 25 | k_socket* m_sock; 26 | }; 27 | 28 | class k_thread_task 29 | { 30 | public: 31 | k_thread_task(); 32 | virtual ~k_thread_task(); 33 | 34 | int init(); 35 | int run(); 36 | int exit(); 37 | 38 | int add_event(k_socket* sock, k_handler* handler, uint32_t event_mask); 39 | int del_event(k_socket* sock); 40 | int enque_msg(k_msg& msg); 41 | virtual int process_msg(k_msg& msg); 42 | 43 | private: 44 | class k_mq_notify_handler : public k_handler 45 | { 46 | public: 47 | int handle_read(k_thread_task* mask, k_event* ev, k_socket* sock); 48 | }; 49 | 50 | int init_msg_que_notify(); 51 | int notify_msg_que(); 52 | void clear_events(); 53 | 54 | void set_process_msg(); 55 | void reset_process_msg(); 56 | 57 | int deque_msg(k_msg& msg); 58 | int process_msg(); 59 | 60 | int add_event_impl(k_event* ev); 61 | int del_event_impl(k_event* ev); 62 | 63 | private: 64 | #ifdef WIN32 65 | k_event* m_mq_event; 66 | #else 67 | int m_epoll_fd; 68 | int m_notify_pipe[2]; 69 | k_socket* m_notify_socket; 70 | #endif 71 | 72 | typedef std::map event_map_type; 73 | event_map_type m_events; 74 | 75 | typedef std::queue msg_que_type; 76 | msg_que_type m_msg_que; 77 | k_mutex m_mq_mutex; 78 | bool m_porcess_msg; 79 | bool m_exit; 80 | }; 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /k_util/k_string.cpp: -------------------------------------------------------------------------------- 1 | #include "k_string.h" 2 | #include 3 | #include 4 | 5 | k_string::k_string() 6 | : m_size(0) 7 | { 8 | memset(m_buf, 0, STR_MAX_LEN); 9 | } 10 | 11 | k_string::k_string(const char* str) 12 | { 13 | memset(m_buf, 0, STR_MAX_LEN); 14 | int size = strlen(str); 15 | if (size < STR_MAX_LEN) 16 | { 17 | m_size = size; 18 | memcpy(m_buf, str, m_size); 19 | } 20 | else 21 | { 22 | m_size = 0; 23 | } 24 | } 25 | 26 | k_string::k_string(const char* str, int size) 27 | { 28 | this->assign(str, size); 29 | } 30 | 31 | void k_string::assign(const char* str, int size) 32 | { 33 | memset(m_buf, 0, STR_MAX_LEN); 34 | if (size < STR_MAX_LEN) 35 | { 36 | m_size = size; 37 | memcpy(m_buf, str, m_size); 38 | } 39 | else 40 | { 41 | m_size = 0; 42 | } 43 | } 44 | 45 | void k_string::append(const char* str, int size) 46 | { 47 | if (size + m_size < STR_MAX_LEN) 48 | { 49 | memcpy(m_buf + m_size, str, size); 50 | m_size += size; 51 | m_buf[m_size] = '\0'; 52 | } 53 | } 54 | 55 | void k_string::append(uint32_t num) 56 | { 57 | char nbuf[16]; 58 | int n = snprintf(nbuf, 16, "%d", num); 59 | this->append(nbuf, n); 60 | } 61 | 62 | char* k_string::find(const char* str) 63 | { 64 | return strstr(m_buf, str); 65 | } 66 | 67 | const char* k_string::c_str() const 68 | { 69 | return m_buf; 70 | } 71 | 72 | int k_string::size() const 73 | { 74 | return m_size; 75 | } 76 | 77 | bool k_string::operator<(const k_string& r_str) const 78 | { 79 | if (m_size > r_str.size()) 80 | { 81 | if (memcmp(this->c_str(), r_str.c_str(), r_str.size()) <= 0) 82 | { 83 | return true; 84 | } 85 | else 86 | { 87 | return false; 88 | } 89 | } 90 | else 91 | { 92 | if (memcmp(this->c_str(), r_str.c_str(), m_size) >= 0) 93 | { 94 | return false; 95 | } 96 | else 97 | { 98 | return true; 99 | } 100 | } 101 | } 102 | 103 | bool k_string::operator==(const k_string &r_str) const { 104 | if(m_size != r_str.size()) 105 | return false; 106 | 107 | return 0 == memcmp(m_buf, r_str.c_str(), m_size); 108 | } 109 | 110 | -------------------------------------------------------------------------------- /kronos.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | k_util 8 | 9 | 10 | k_util 11 | 12 | 13 | k_util 14 | 15 | 16 | k_util 17 | 18 | 19 | k_util 20 | 21 | 22 | k_util 23 | 24 | 25 | k_util 26 | 27 | 28 | k_util 29 | 30 | 31 | k_util 32 | 33 | 34 | jsoncpp 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | k_util 45 | 46 | 47 | k_util 48 | 49 | 50 | k_util 51 | 52 | 53 | k_util 54 | 55 | 56 | k_util 57 | 58 | 59 | k_util 60 | 61 | 62 | k_util 63 | 64 | 65 | k_util 66 | 67 | 68 | k_util 69 | 70 | 71 | jsoncpp\json 72 | 73 | 74 | jsoncpp\json 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | {4aee706e-0f12-4037-b8ff-b0f51a33a379} 84 | 85 | 86 | {317f9be2-341a-4934-ad31-367fb68ac90f} 87 | 88 | 89 | {9d390bad-c667-4472-a000-2a590c4a3cae} 90 | 91 | 92 | -------------------------------------------------------------------------------- /k_util/k_event.cpp: -------------------------------------------------------------------------------- 1 | #include "k_event.h" 2 | 3 | k_event::k_event() 4 | : m_socket(NULL) 5 | , m_handler(NULL) 6 | , m_event_mask(0) 7 | #ifdef WIN32 8 | , m_event(NULL) 9 | #endif 10 | { 11 | } 12 | 13 | k_event::~k_event() 14 | { 15 | #ifdef WIN32 16 | if (m_event) 17 | { 18 | WSACloseEvent(m_event); 19 | } 20 | #endif 21 | } 22 | 23 | int k_event::init(k_socket* sock, k_handler* handler, uint32_t event_mask) 24 | { 25 | m_socket = sock; 26 | m_handler = handler; 27 | 28 | #ifdef WIN32 29 | m_event = WSACreateEvent(); 30 | 31 | if (m_event == NULL) 32 | { 33 | return -1; 34 | } 35 | #else 36 | m_event.data.ptr = this; 37 | #endif 38 | 39 | if (m_socket && event_mask) 40 | { 41 | if (this->gen_event_mask(event_mask)) 42 | { 43 | return -1; 44 | } 45 | } 46 | 47 | return 0; 48 | } 49 | 50 | K_EVENT_T k_event::get_event() 51 | { 52 | return m_event; 53 | } 54 | 55 | void k_event::process(k_thread_task* task, uint32_t mask) 56 | { 57 | if (mask & READ_MASK) 58 | { 59 | m_handler->handle_read(task, this, m_socket); 60 | } 61 | 62 | if (mask & WRITE_MASK) 63 | { 64 | m_handler->handle_write(task, this, m_socket); 65 | } 66 | 67 | if (mask & ACCEPT_MASK) 68 | { 69 | m_handler->handle_read(task, this, m_socket); 70 | } 71 | 72 | if (mask & CLOSE_MASK) 73 | { 74 | m_handler->handle_close(task, this, m_socket); 75 | } 76 | } 77 | 78 | void k_event::on_del(k_thread_task* task) 79 | { 80 | m_handler->handle_del(task, this, m_socket); 81 | } 82 | 83 | int k_event::gen_event_mask(uint32_t event_mask) 84 | { 85 | if (event_mask & READ_MASK ) 86 | { 87 | #ifdef WIN32 88 | m_event_mask |= FD_READ; 89 | #else 90 | m_event_mask |= EPOLLIN; 91 | #endif 92 | } 93 | 94 | if (event_mask & WRITE_MASK) 95 | { 96 | #ifdef WIN32 97 | m_event_mask |= FD_WRITE; 98 | #else 99 | m_event_mask |= EPOLLOUT; 100 | #endif 101 | } 102 | 103 | if (event_mask & ACCEPT_MASK) 104 | { 105 | 106 | #ifdef WIN32 107 | m_event_mask |= FD_ACCEPT; 108 | #else 109 | m_event_mask |= EPOLLIN; 110 | #endif 111 | } 112 | 113 | #ifdef WIN32 114 | m_event_mask |= FD_CLOSE; 115 | #else 116 | m_event_mask |= EPOLLRDHUP; 117 | 118 | m_event.events = m_event_mask; 119 | #endif 120 | 121 | return 0; 122 | } 123 | 124 | k_socket *k_event::get_socket() { 125 | return m_socket; 126 | } 127 | 128 | K_EVENT_T *k_event::get_event_ptr() { 129 | return &m_event; 130 | } 131 | 132 | uint32_t k_event::get_event_mask() { 133 | return m_event_mask; 134 | } 135 | 136 | int k_event::parse_event_mask(K_EVENT_T event, uint32_t &mask) 137 | { 138 | #ifdef WIN32 139 | if (!m_socket) 140 | { 141 | mask |= READ_MASK; 142 | return 0; 143 | } 144 | 145 | WSANETWORKEVENTS events; 146 | if (WSAEnumNetworkEvents(m_socket->get_sock(), event, &events)) 147 | { 148 | return -1; 149 | } 150 | 151 | if (events.lNetworkEvents & FD_READ) 152 | { 153 | mask |= READ_MASK; 154 | 155 | if (events.iErrorCode[FD_READ_BIT]) 156 | { 157 | mask |= CLOSE_MASK; 158 | } 159 | } 160 | 161 | if (events.lNetworkEvents & FD_WRITE) 162 | { 163 | if (events.iErrorCode[FD_WRITE_BIT]) 164 | { 165 | mask |= CLOSE_MASK; 166 | } 167 | else 168 | { 169 | mask |= WRITE_MASK; 170 | } 171 | } 172 | 173 | if (events.lNetworkEvents & FD_ACCEPT) 174 | { 175 | if (events.iErrorCode[FD_ACCEPT_BIT]) 176 | { 177 | mask |= CLOSE_MASK; 178 | } 179 | else 180 | { 181 | mask |= READ_MASK; 182 | } 183 | } 184 | 185 | if (events.lNetworkEvents & FD_CLOSE) 186 | { 187 | mask |= CLOSE_MASK; 188 | 189 | if (0 == events.iErrorCode[FD_CLOSE_BIT]) 190 | { 191 | mask |= READ_MASK; 192 | } 193 | } 194 | #else 195 | uint32_t ev = event.events; 196 | 197 | if(ev & EPOLLIN) 198 | { 199 | mask |= READ_MASK; 200 | } 201 | 202 | if(ev & EPOLLOUT) 203 | { 204 | mask |= WRITE_MASK; 205 | } 206 | 207 | if(ev & EPOLLERR) 208 | { 209 | mask |= CLOSE_MASK; 210 | } 211 | 212 | if(ev & EPOLLHUP) 213 | { 214 | mask |= CLOSE_MASK; 215 | } 216 | 217 | if (ev & EPOLLRDHUP) 218 | { 219 | mask |= CLOSE_MASK; 220 | } 221 | 222 | #endif 223 | return 0; 224 | } 225 | -------------------------------------------------------------------------------- /k_util/k_socket.cpp: -------------------------------------------------------------------------------- 1 | #include "k_socket.h" 2 | #include "k_errno.h" 3 | 4 | #ifdef WIN32 5 | #define K_INVALID_SOCKET INVALID_SOCKET 6 | #else 7 | #define K_INVALID_SOCKET -1 8 | #endif 9 | 10 | k_socket::k_socket() 11 | : m_sock(K_INVALID_SOCKET) 12 | { 13 | } 14 | 15 | k_socket::~k_socket() 16 | { 17 | if (m_sock != K_INVALID_SOCKET) 18 | { 19 | #ifdef WIN32 20 | closesocket(m_sock); 21 | #else 22 | close(m_sock); 23 | #endif 24 | } 25 | } 26 | 27 | void k_socket::set_sock(int sock) 28 | { 29 | m_sock = sock; 30 | } 31 | 32 | int k_socket::get_sock() 33 | { 34 | return m_sock; 35 | } 36 | 37 | int k_socket::init(int af, int type) 38 | { 39 | m_sock = socket(af, type, 0); 40 | if (m_sock == K_INVALID_SOCKET) 41 | { 42 | return -1; 43 | } 44 | 45 | return 0; 46 | } 47 | 48 | int k_socket::k_bind(k_sockaddr& sock_addr) 49 | { 50 | int ret = bind(m_sock, sock_addr.get_sockaddr(), sock_addr.get_size()); 51 | if (ret) 52 | { 53 | return -1; 54 | } 55 | 56 | return 0; 57 | } 58 | 59 | int k_socket::k_listen() 60 | { 61 | int ret = listen(m_sock, SOMAXCONN); 62 | 63 | return ret; 64 | } 65 | 66 | int k_socket::k_accept(k_sockaddr& sock_addr, k_socket& sock) 67 | { 68 | while (true) 69 | { 70 | int fd = accept(m_sock, sock_addr.get_sockaddr(), sock_addr.get_size_ptr()); 71 | 72 | if (fd != K_INVALID_SOCKET) 73 | { 74 | sock.set_sock(fd); 75 | 76 | return 0; 77 | } 78 | else 79 | { 80 | int err = k_errno::last_error(); 81 | if (k_errno::is_retry_error(err)) 82 | { 83 | continue; 84 | } 85 | 86 | return -1; 87 | } 88 | } 89 | } 90 | 91 | int k_socket::k_connect(k_sockaddr& sock_addr) 92 | { 93 | while (true) 94 | { 95 | int ret = connect(m_sock, sock_addr.get_sockaddr(), sock_addr.get_size()); 96 | 97 | if (ret) 98 | { 99 | int err = k_errno::last_error(); 100 | if (k_errno::is_retry_error(err)) 101 | { 102 | continue; 103 | } 104 | } 105 | 106 | return ret; 107 | } 108 | } 109 | 110 | int k_socket::k_send(char* buf, int buf_size) 111 | { 112 | int ret; 113 | int offset = 0; 114 | 115 | do 116 | { 117 | ret = send(m_sock, buf + offset, buf_size - offset, 0); 118 | if (ret < 0) 119 | { 120 | int err = k_errno::last_error(); 121 | if (k_errno::is_retry_error(err)) 122 | { 123 | continue; 124 | } 125 | else 126 | { 127 | break; 128 | } 129 | } 130 | else 131 | { 132 | offset += ret; 133 | } 134 | 135 | } while (offset != buf_size); 136 | 137 | if (offset != buf_size) 138 | { 139 | return ret; 140 | } 141 | else 142 | { 143 | return offset; 144 | } 145 | } 146 | 147 | int k_socket::k_recv(char* buf, int buf_size) 148 | { 149 | while (true) 150 | { 151 | int ret = recv(m_sock, buf, buf_size, 0); 152 | 153 | if (ret < 0) 154 | { 155 | int err = k_errno::last_error(); 156 | if (k_errno::is_retry_error(err)) 157 | { 158 | continue; 159 | } 160 | } 161 | 162 | return ret; 163 | } 164 | } 165 | 166 | int k_socket::k_recv_n(char* buf, int buf_size) 167 | { 168 | int offset = 0; 169 | int ret; 170 | 171 | while (offset < buf_size) 172 | { 173 | ret = this->k_recv(buf + offset, buf_size - offset); 174 | if (ret <= 0) 175 | { 176 | return -1; 177 | } 178 | offset += ret; 179 | } 180 | 181 | return 0; 182 | } 183 | 184 | int k_socket::k_setopt(int level, int optname, const char *optval, socklen_t optlen) 185 | { 186 | return setsockopt(m_sock, level, optname, optval, optlen); 187 | } 188 | 189 | #ifndef WIN32 190 | int k_socket::k_write(char* buf, int buf_size) 191 | { 192 | return write(m_sock, buf, buf_size); 193 | } 194 | 195 | int k_socket::k_read(char* buf, int buf_size) 196 | { 197 | return read(m_sock, buf, buf_size); 198 | } 199 | #endif 200 | 201 | int k_socket::k_recvfrom(char* buf, int buf_size, k_sockaddr& from_addr) 202 | { 203 | while (true) 204 | { 205 | int ret = recvfrom(m_sock, buf, buf_size, 0, 206 | from_addr.get_sockaddr(), from_addr.get_size_ptr()); 207 | 208 | if (ret < 0) 209 | { 210 | int err = k_errno::last_error(); 211 | if (k_errno::is_retry_error(err)) 212 | { 213 | continue; 214 | } 215 | } 216 | 217 | return ret; 218 | } 219 | 220 | } 221 | 222 | int k_socket::k_sendto(char* buf, int buf_size, k_sockaddr& to_addr) 223 | { 224 | int ret; 225 | int offset = 0; 226 | 227 | do 228 | { 229 | ret = sendto(m_sock, buf + offset, buf_size - offset, 0, 230 | to_addr.get_sockaddr(), to_addr.get_size()); 231 | if (ret < 0) 232 | { 233 | int err = k_errno::last_error(); 234 | if (k_errno::is_retry_error(err)) 235 | { 236 | continue; 237 | } 238 | else 239 | { 240 | break; 241 | } 242 | } 243 | else 244 | { 245 | offset += ret; 246 | } 247 | 248 | } while (offset != buf_size); 249 | 250 | if (offset != buf_size) 251 | { 252 | return ret; 253 | } 254 | else 255 | { 256 | return offset; 257 | } 258 | } 259 | -------------------------------------------------------------------------------- /kronos.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | {338E9007-FF0E-457B-91C3-008554E47272} 59 | Win32Proj 60 | kronos 61 | 8.1 62 | 63 | 64 | 65 | Application 66 | true 67 | v140 68 | Unicode 69 | 70 | 71 | Application 72 | false 73 | v140 74 | true 75 | Unicode 76 | 77 | 78 | Application 79 | true 80 | v140 81 | Unicode 82 | 83 | 84 | Application 85 | false 86 | v140 87 | true 88 | Unicode 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | true 110 | 111 | 112 | true 113 | 114 | 115 | false 116 | 117 | 118 | false 119 | 120 | 121 | 122 | 123 | 124 | Level3 125 | Disabled 126 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 127 | true 128 | ..\osip\include;jsoncpp 129 | 130 | 131 | Console 132 | true 133 | ..\exosip\platform\vsnet\v140\Win32\Debug;%(AdditionalLibraryDirectories) 134 | osipparser2.lib;Ws2_32.lib;%(AdditionalDependencies) 135 | 136 | 137 | 138 | 139 | 140 | 141 | Level3 142 | Disabled 143 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 144 | true 145 | 146 | 147 | Console 148 | true 149 | 150 | 151 | 152 | 153 | Level3 154 | 155 | 156 | MaxSpeed 157 | true 158 | true 159 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 160 | true 161 | 162 | 163 | Console 164 | true 165 | true 166 | true 167 | 168 | 169 | 170 | 171 | Level3 172 | 173 | 174 | MaxSpeed 175 | true 176 | true 177 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 178 | true 179 | 180 | 181 | Console 182 | true 183 | true 184 | true 185 | 186 | 187 | 188 | 189 | 190 | -------------------------------------------------------------------------------- /k_util/k_thread_task.cpp: -------------------------------------------------------------------------------- 1 | #include "k_thread_task.h" 2 | #include "k_errno.h" 3 | 4 | #ifdef WIN32 5 | #include 6 | #include 7 | #define THREAD_RPOC_RETURN DWORD WINAPI 8 | #else 9 | #include 10 | #include 11 | #include 12 | #define THREAD_RPOC_RETURN void* 13 | #define MAX_EPOLL_EVENTS 1024 14 | #endif 15 | 16 | 17 | static THREAD_RPOC_RETURN ThreadProc(void* lpParameter) 18 | { 19 | k_thread_task* task = static_cast(lpParameter); 20 | 21 | task->run(); 22 | 23 | delete task; 24 | return 0; 25 | } 26 | 27 | k_thread_task::k_thread_task() 28 | : m_porcess_msg(false) 29 | , m_exit(false) 30 | #ifndef WIN32 31 | , m_notify_socket(NULL) 32 | #endif 33 | { 34 | } 35 | 36 | k_thread_task::~k_thread_task() 37 | { 38 | this->clear_events(); 39 | 40 | #ifndef WIN32 41 | if (m_notify_socket) 42 | { 43 | delete m_notify_socket; 44 | } 45 | #endif 46 | } 47 | 48 | int k_thread_task::init() 49 | { 50 | if (m_mq_mutex.init()) 51 | { 52 | return -1; 53 | } 54 | 55 | if (this->init_msg_que_notify()) 56 | { 57 | return -1; 58 | } 59 | 60 | #ifdef WIN32 61 | HANDLE hd = CreateThread(NULL, 0, ThreadProc, this, 0, NULL); 62 | if (hd == NULL) 63 | { 64 | return -1; 65 | } 66 | #else 67 | pthread_t tid; 68 | if (pthread_create(&tid, NULL, ThreadProc, this)) 69 | { 70 | close(m_epoll_fd); 71 | return -1; 72 | } 73 | #endif 74 | 75 | return 0; 76 | } 77 | 78 | int k_thread_task::run() 79 | { 80 | #ifdef WIN32 81 | WSAEVENT event_array[MAXIMUM_WAIT_OBJECTS]; 82 | k_event* k_event_array[MAXIMUM_WAIT_OBJECTS]; 83 | int event_nums; 84 | 85 | for (;;) 86 | { 87 | event_nums = 0; 88 | 89 | for (event_map_type::iterator it = m_events.begin(); it != m_events.end(); ++it) 90 | { 91 | k_event* ev = it->second; 92 | k_event_array[event_nums] = ev; 93 | event_array[event_nums] = ev->get_event(); 94 | ++event_nums; 95 | } 96 | 97 | int ret = WaitForMultipleObjectsEx(event_nums, event_array, FALSE, INFINITE, FALSE); 98 | if (ret == WAIT_FAILED) 99 | { 100 | return -1; 101 | } 102 | else if (ret == WAIT_TIMEOUT) 103 | { 104 | continue; 105 | } 106 | else if (ret == WAIT_IO_COMPLETION) 107 | { 108 | continue; 109 | } 110 | else if (ret >= WAIT_ABANDONED_0) 111 | { 112 | continue; 113 | } 114 | else 115 | { 116 | ret -= WAIT_OBJECT_0; 117 | k_event* ev = k_event_array[ret]; 118 | 119 | uint32_t mask = 0; 120 | if(0 == ev->parse_event_mask(ev->get_event(), mask)) 121 | { 122 | ev->process(this, mask); 123 | } 124 | } 125 | 126 | if (m_porcess_msg) 127 | { 128 | if (this->process_msg()) 129 | { 130 | break; 131 | } 132 | } 133 | } 134 | #else 135 | epoll_event event_array[MAX_EPOLL_EVENTS]; 136 | 137 | for (;;) 138 | { 139 | int ret = epoll_wait(m_epoll_fd, event_array, MAX_EPOLL_EVENTS, -1); 140 | 141 | if (ret == 0) 142 | { 143 | continue; 144 | } 145 | else if(ret == -1) 146 | { 147 | int err = k_errno::last_error(); 148 | if(k_errno::is_retry_error(err)) 149 | { 150 | continue; 151 | } 152 | 153 | break; 154 | } 155 | else 156 | { 157 | for (int i = 0; i < ret; ++i) 158 | { 159 | epoll_event& event = event_array[i]; 160 | k_event* ev = static_cast (event.data.ptr); 161 | 162 | uint32_t mask = 0; 163 | if(0 == ev->parse_event_mask(event, mask)) 164 | { 165 | ev->process(this, mask); 166 | } 167 | } 168 | } 169 | 170 | if (m_porcess_msg) 171 | { 172 | if (this->process_msg()) 173 | { 174 | break; 175 | } 176 | } 177 | } 178 | 179 | close(m_epoll_fd); 180 | #endif 181 | 182 | return 0; 183 | } 184 | 185 | int k_thread_task::add_event(k_socket* sock, k_handler* handler, uint32_t event_mask) 186 | { 187 | k_add_event* add = new k_add_event; 188 | add->m_sock = sock; 189 | add->m_handler = handler; 190 | add->m_event_mask = event_mask; 191 | k_msg msg = { 1, add }; 192 | 193 | if (this->enque_msg(msg)) 194 | { 195 | delete add; 196 | 197 | return -1; 198 | } 199 | 200 | return 0; 201 | } 202 | 203 | int k_thread_task::del_event(k_socket* sock) 204 | { 205 | k_del_event* del = new k_del_event; 206 | del->m_sock = sock ; 207 | k_msg msg = { 2, del }; 208 | 209 | if (this->enque_msg(msg)) 210 | { 211 | delete del; 212 | 213 | return -1; 214 | } 215 | 216 | return 0; 217 | } 218 | 219 | int k_thread_task::exit() 220 | { 221 | k_msg msg = { 3, NULL }; 222 | 223 | return this->enque_msg(msg); 224 | } 225 | 226 | int k_thread_task::enque_msg(k_msg& msg) 227 | { 228 | int ret = m_mq_mutex.acquire(); 229 | if (ret) 230 | { 231 | return -1; 232 | } 233 | 234 | if (m_exit) 235 | { 236 | printf("exiting\n"); 237 | m_mq_mutex.release(); 238 | return -1; 239 | } 240 | 241 | if (msg.m_msg_id == 3)//exit 242 | { 243 | m_exit = true; 244 | } 245 | 246 | m_msg_que.push(msg); 247 | 248 | if (!m_porcess_msg) 249 | { 250 | if (this->notify_msg_que()) 251 | { 252 | //error 253 | } 254 | } 255 | 256 | m_mq_mutex.release(); 257 | 258 | return 0; 259 | } 260 | 261 | int k_thread_task::init_msg_que_notify() 262 | { 263 | #ifdef WIN32 264 | k_mq_notify_handler* handler = new k_mq_notify_handler; 265 | m_mq_event = new k_event; 266 | 267 | if (m_mq_event->init(NULL, handler, k_event::READ_MASK)) 268 | { 269 | m_mq_event->on_del(this); 270 | delete m_mq_event; 271 | 272 | return -1; 273 | } 274 | 275 | m_events.insert(event_map_type::value_type(NULL, m_mq_event)); 276 | 277 | #else 278 | m_epoll_fd = epoll_create(1); 279 | 280 | if (m_epoll_fd == -1) 281 | { 282 | return -1; 283 | } 284 | 285 | if (pipe(m_notify_pipe)) 286 | { 287 | close(m_epoll_fd); 288 | return -1; 289 | } 290 | 291 | k_socket* sock = new k_socket; 292 | m_notify_socket = new k_socket; 293 | 294 | sock->set_sock(m_notify_pipe[0]); 295 | m_notify_socket->set_sock(m_notify_pipe[1]); 296 | 297 | k_mq_notify_handler* handler = new k_mq_notify_handler; 298 | k_event* ev = new k_event; 299 | 300 | if (ev->init(sock, handler, k_event::READ_MASK)) 301 | { 302 | ev->on_del(this); 303 | delete ev; 304 | delete m_notify_socket; 305 | close(m_epoll_fd); 306 | 307 | return -1; 308 | } 309 | 310 | if (this->add_event_impl(ev)) 311 | { 312 | ev->on_del(this); 313 | delete ev; 314 | delete m_notify_socket; 315 | close(m_epoll_fd); 316 | 317 | return -1; 318 | } 319 | 320 | m_events.insert(event_map_type::value_type(sock, ev)); 321 | #endif 322 | 323 | return 0; 324 | } 325 | 326 | void k_thread_task::set_process_msg() 327 | { 328 | m_porcess_msg = true; 329 | } 330 | 331 | void k_thread_task::reset_process_msg() 332 | { 333 | m_porcess_msg = false; 334 | } 335 | 336 | int k_thread_task::deque_msg(k_msg& msg) 337 | { 338 | int ret = m_mq_mutex.acquire(); 339 | if (ret) 340 | { 341 | return -1; 342 | } 343 | 344 | ret = m_msg_que.size(); 345 | 346 | if(ret) 347 | { 348 | msg = m_msg_que.front(); 349 | m_msg_que.pop(); 350 | } 351 | 352 | m_mq_mutex.release(); 353 | 354 | return ret; 355 | } 356 | 357 | int k_thread_task::process_msg() 358 | { 359 | k_msg msg; 360 | int ret = 0; 361 | do 362 | { 363 | ret = this->deque_msg(msg); 364 | if (ret > 0) 365 | { 366 | this->process_msg(msg); 367 | } 368 | } while (ret > 0); 369 | 370 | this->reset_process_msg(); 371 | 372 | return m_exit ? -1 : 0; 373 | } 374 | 375 | int k_thread_task::process_msg(k_msg& msg) 376 | { 377 | switch (msg.m_msg_id) 378 | { 379 | case 1: 380 | { 381 | k_add_event* add = static_cast(msg.m_data); 382 | k_event* ev = new k_event; 383 | 384 | if(ev->init(add->m_sock, add->m_handler, add->m_event_mask)) 385 | { 386 | ev->on_del(this); 387 | delete add; 388 | delete ev; 389 | 390 | return -1; 391 | } 392 | 393 | if (this->add_event_impl(ev)) 394 | { 395 | ev->on_del(this); 396 | delete add; 397 | delete ev; 398 | 399 | return -1; 400 | } 401 | 402 | m_events.insert(event_map_type::value_type(add->m_sock, ev)); 403 | 404 | delete add; 405 | return 0; 406 | } 407 | break; 408 | 409 | case 2: 410 | { 411 | k_del_event* del = static_cast(msg.m_data); 412 | k_socket* sock = del->m_sock; 413 | 414 | event_map_type::iterator it = m_events.find(sock); 415 | if (it != m_events.end()) 416 | { 417 | k_event* ev = it->second; 418 | 419 | this->del_event_impl(ev); 420 | ev->on_del(this); 421 | 422 | m_events.erase(it); 423 | delete ev; 424 | } 425 | 426 | delete del; 427 | return 0; 428 | } 429 | break; 430 | 431 | case 3: 432 | { 433 | this->clear_events(); 434 | return 0; 435 | } 436 | break; 437 | 438 | default: 439 | return 0; 440 | } 441 | } 442 | 443 | int k_thread_task::notify_msg_que() 444 | { 445 | #ifdef WIN32 446 | if (!SetEvent(m_mq_event->get_event())) 447 | { 448 | return -1; 449 | } 450 | #else 451 | char c = 0; 452 | if (sizeof(char) != m_notify_socket->k_write(&c, sizeof(char))) 453 | { 454 | printf("send notify failed, err:%d\n", k_errno::last_error()); 455 | return -1; 456 | } 457 | #endif 458 | 459 | return 0; 460 | } 461 | 462 | void k_thread_task::clear_events() 463 | { 464 | std::vector events; 465 | for (event_map_type::iterator it = m_events.begin(); it != m_events.end(); ++it) 466 | { 467 | events.push_back(it->second); 468 | } 469 | 470 | m_events.clear(); 471 | 472 | for (std::vector::iterator it = events.begin(); 473 | it != events.end(); ++it) 474 | { 475 | k_event* ev = *it; 476 | ev->on_del(this); 477 | delete ev; 478 | } 479 | } 480 | 481 | int k_thread_task::add_event_impl(k_event *ev) 482 | { 483 | #ifdef WIN32 484 | if(!ev->get_socket()) 485 | { 486 | return 0; 487 | } 488 | 489 | if (WSAEventSelect(ev->get_socket()->get_sock(), ev->get_event(), 490 | ev->get_event_mask())) 491 | { 492 | return -1; 493 | } 494 | #else 495 | if(epoll_ctl(m_epoll_fd, EPOLL_CTL_ADD, 496 | ev->get_socket()->get_sock(), ev->get_event_ptr())) 497 | { 498 | return -1; 499 | } 500 | 501 | #endif 502 | return 0; 503 | } 504 | 505 | int k_thread_task::del_event_impl(k_event *ev) 506 | { 507 | #ifdef WIN32 508 | #else 509 | if(epoll_ctl(m_epoll_fd, EPOLL_CTL_DEL, 510 | ev->get_socket()->get_sock(), ev->get_event_ptr())) 511 | { 512 | return -1; 513 | } 514 | 515 | #endif 516 | return 0; 517 | } 518 | 519 | int k_thread_task::k_mq_notify_handler::handle_read( 520 | k_thread_task* task, k_event* ev, k_socket* sock) 521 | { 522 | #ifdef WIN32 523 | ResetEvent(ev->get_event()); 524 | #else 525 | char c; 526 | sock->k_read(&c, sizeof(char)); 527 | #endif 528 | 529 | task->set_process_msg(); 530 | 531 | return 0; 532 | } 533 | -------------------------------------------------------------------------------- /k_rtsp_handler.cpp: -------------------------------------------------------------------------------- 1 | #include "k_rtsp_handler.h" 2 | #include "k_util/k_socket.h" 3 | #include "k_media_server.h" 4 | #include "k_util/k_util.h" 5 | #include 6 | 7 | #define DEF_CSEQ "CSeq" 8 | #define DEF_TRANSPORT "Transport" 9 | #define DEF_SESSION "Session" 10 | 11 | #define DEF_OPTIONS "OPTIONS" 12 | #define DEF_DESCRIBE "DESCRIBE" 13 | #define DEF_SETUP "SETUP" 14 | #define DEF_PLAY "PLAY" 15 | #define DEF_TEARDOWN "TEARDOWN" 16 | #define DEF_GET_PARAMETER "GET_PARAMETER" 17 | #define DEF_SET_PARAMETER "SET_PARAMETER" 18 | 19 | k_rtsp_handler::k_rtsp_handler() 20 | : m_session_id(0) 21 | , m_sock(NULL) 22 | , m_rebuf(NULL) 23 | , m_rebuf_size(0) 24 | { 25 | 26 | } 27 | 28 | k_rtsp_handler::~k_rtsp_handler() 29 | { 30 | if (m_rebuf) 31 | { 32 | free(m_rebuf); 33 | } 34 | } 35 | 36 | int k_rtsp_handler::next_sapce(char* p, char*& p_sapce) 37 | { 38 | while (*p != '\0' 39 | && *p != ' ' 40 | && *p != '\r' 41 | && *p != '\n') 42 | ++p; 43 | 44 | if (*p != ' ') 45 | { 46 | //err 47 | return -1; 48 | } 49 | 50 | p_sapce = p; 51 | return 0; 52 | } 53 | 54 | int k_rtsp_handler::skip_space(char*& p) 55 | { 56 | while (*p == ' ') 57 | ++p; 58 | 59 | if (*p == '\0' || *p == '\r' || *p == '\n') 60 | { 61 | //err 62 | return -1; 63 | } 64 | 65 | return 0; 66 | } 67 | 68 | void k_rtsp_handler::next_end(char* p, char*& p_end) 69 | { 70 | while (*p != '\0' 71 | && *p != '\r' 72 | && *p != '\n') 73 | ++p; 74 | 75 | p_end = p; 76 | } 77 | 78 | int k_rtsp_handler::parse_head_line(char*& p, k_rtsp_head& head) 79 | { 80 | char* p_space; 81 | if (next_sapce(p, p_space)) 82 | { 83 | return -1; 84 | } 85 | 86 | head.cmd.assign(p, p_space - p); 87 | 88 | p = p_space; 89 | if (skip_space(p)) 90 | { 91 | return -1; 92 | } 93 | 94 | if (next_sapce(p, p_space)) 95 | { 96 | return -1; 97 | } 98 | 99 | head.url.assign(p, p_space - p); 100 | 101 | p = p_space; 102 | if (skip_space(p)) 103 | { 104 | return -1; 105 | } 106 | 107 | next_end(p, p_space); 108 | 109 | head.version.assign(p, p_space - p); 110 | 111 | if (*p_space == '\r') 112 | { 113 | p = p_space + 2; 114 | } 115 | else 116 | { 117 | p = p_space + 1; 118 | } 119 | 120 | return 0; 121 | } 122 | 123 | int k_rtsp_handler::parse_line(char*& p, k_rtsp_head& head) 124 | { 125 | if (0 == memcmp(p, DEF_CSEQ, strlen(DEF_CSEQ))) 126 | { 127 | char* p_end; 128 | next_end(p, p_end); 129 | 130 | head.cseq.assign(p, p_end - p); 131 | p = p_end; 132 | } 133 | else if (0 == memcmp(p, DEF_TRANSPORT, strlen(DEF_TRANSPORT))) 134 | { 135 | char* p_end; 136 | next_end(p, p_end); 137 | 138 | head.transport.assign(p, p_end - p); 139 | p = p_end; 140 | } 141 | else if (0 == memcmp(p, DEF_SESSION, strlen(DEF_SESSION))) 142 | { 143 | char* p_end; 144 | next_end(p, p_end); 145 | 146 | head.session.assign(p, p_end - p); 147 | p = p_end; 148 | } 149 | else 150 | { 151 | next_end(p, p); 152 | } 153 | 154 | if (*p == '\r') 155 | { 156 | p = p + 2; 157 | } 158 | else 159 | { 160 | p = p + 1; 161 | } 162 | 163 | return 0; 164 | } 165 | 166 | void k_rtsp_handler::append_space(char*& p) 167 | { 168 | *p = ' '; 169 | ++p; 170 | } 171 | 172 | void k_rtsp_handler::append_line_end(char*& p) 173 | { 174 | *p = '\r'; 175 | ++p; 176 | *p = '\n'; 177 | ++p; 178 | } 179 | 180 | int k_rtsp_handler::send_rtsp_rsp(k_rtsp_rsp& rsp, k_socket* sock) 181 | { 182 | char buf[4096]; 183 | char* p = buf; 184 | 185 | memcpy(p, rsp.version.c_str(), rsp.version.size()); 186 | p += rsp.version.size(); 187 | append_space(p); 188 | 189 | memcpy(p, rsp.result.c_str(), rsp.result.size()); 190 | p += rsp.result.size(); 191 | append_space(p); 192 | 193 | 194 | memcpy(p, rsp.describe.c_str(), rsp.describe.size()); 195 | p += rsp.describe.size(); 196 | append_line_end(p); 197 | 198 | memcpy(p, rsp.cseq.c_str(), rsp.cseq.size()); 199 | p += rsp.cseq.size(); 200 | append_line_end(p); 201 | 202 | if (rsp.rtsp_public.size()) 203 | { 204 | memcpy(p, rsp.rtsp_public.c_str(), rsp.rtsp_public.size()); 205 | p += rsp.rtsp_public.size(); 206 | append_line_end(p); 207 | } 208 | 209 | if (rsp.session.size()) 210 | { 211 | memcpy(p, rsp.session.c_str(), rsp.session.size()); 212 | p += rsp.session.size(); 213 | append_line_end(p); 214 | } 215 | 216 | if (rsp.transport.size()) 217 | { 218 | memcpy(p, rsp.transport.c_str(), rsp.transport.size()); 219 | p += rsp.transport.size(); 220 | append_line_end(p); 221 | } 222 | 223 | if (rsp.content_type.size()) 224 | { 225 | memcpy(p, rsp.content_type.c_str(), rsp.content_type.size()); 226 | p += rsp.content_type.size(); 227 | append_line_end(p); 228 | } 229 | 230 | if (rsp.content_base.size()) 231 | { 232 | memcpy(p, rsp.content_base.c_str(), rsp.content_base.size()); 233 | p += rsp.content_base.size(); 234 | append_line_end(p); 235 | } 236 | 237 | if (rsp.sdp.size()) 238 | { 239 | char sdp[1024]; 240 | char* p_sdp = sdp; 241 | for (auto it = rsp.sdp.begin(); it != rsp.sdp.end(); ++it) 242 | { 243 | memcpy(p_sdp, it->c_str(), it->size()); 244 | p_sdp += it->size(); 245 | append_line_end(p_sdp); 246 | } 247 | 248 | int sdp_len = p_sdp - sdp; 249 | int nn = snprintf(p, 32, "Content-Length: %d\r\n\r\n", sdp_len); 250 | p += nn; 251 | 252 | memcpy(p, sdp, sdp_len); 253 | p += sdp_len; 254 | } 255 | else 256 | { 257 | append_line_end(p); 258 | } 259 | 260 | int len = p - buf; 261 | buf[len] = '\0'; 262 | printf("%s\n\n", buf); 263 | 264 | if (len != sock->k_send(buf, len)) 265 | { 266 | printf("send err\n"); 267 | return -1; 268 | } 269 | 270 | return 0; 271 | } 272 | 273 | int k_rtsp_handler::on_rtsp_head(k_rtsp_head& head, k_thread_task* task, k_socket* sock) 274 | { 275 | k_rtsp_rsp rsp; 276 | 277 | rsp.version = head.version; 278 | rsp.cseq = head.cseq; 279 | rsp.result = "200"; 280 | rsp.describe = "OK"; 281 | rsp.session = head.session; 282 | 283 | if (0 == memcmp(head.cmd.c_str(), DEF_OPTIONS, strlen(DEF_OPTIONS))) 284 | { 285 | rsp.rtsp_public = "Public: OPTIONS, DESCRIBE, SETUP, TEARDOWN, \ 286 | PLAY, GET_PARAMETER, SET_PARAMETER"; 287 | } 288 | else if (0 == memcmp(head.cmd.c_str(), DEF_DESCRIBE, strlen(DEF_DESCRIBE))) 289 | { 290 | rsp.content_type = "Content-Type: application/sdp"; 291 | rsp.content_base = "Content-Base: "; 292 | rsp.content_base.append(head.url.c_str(), head.url.size()); 293 | rsp.content_base.append("/", 1); 294 | 295 | rsp.sdp.push_back("v=0"); 296 | rsp.sdp.push_back("o=LS 0 0 IN IP4 0.0.0.0"); 297 | rsp.sdp.push_back("s=LS RTSP SDP"); 298 | rsp.sdp.push_back("c=IN IP4 0.0.0.0"); 299 | rsp.sdp.push_back("t=0 0"); 300 | rsp.sdp.push_back("a=range:npt=0-"); 301 | rsp.sdp.push_back("a=control:*"); 302 | 303 | rsp.sdp.push_back("m=video 0 RTP/AVP 96"); 304 | rsp.sdp.push_back("a=control:track1"); 305 | rsp.sdp.push_back("a=rtpmap:96 H264/90000"); 306 | rsp.sdp.push_back("a=fmtp:96 profile-level-id=;sprop-parameter-sets=;packetization-mode=0"); 307 | 308 | rsp.sdp.push_back("m=audio 0 RTP/AVP 97"); 309 | rsp.sdp.push_back("a=control:track2"); 310 | rsp.sdp.push_back("a=rtpmap:97 MPEG4-GENERIC/44100/1"); 311 | 312 | k_string aac_fmtp = "a=fmtp:97 profile-level-id=15;mode=AAC-hbr;\ 313 | sizelength=13;indexlength=3;indexdeltalength=3;config="; 314 | 315 | static int const samplingFrequencyTable[16] = { 316 | 96000, 88200, 64000, 48000, 317 | 44100, 32000, 24000, 22050, 318 | 16000, 12000, 11025, 8000, 319 | 7350, 0, 0, 0 320 | }; 321 | 322 | uint8_t audioSpecificConfig[2]; 323 | uint8_t audioObjectType = 2; 324 | uint8_t samplingFrequencyIndex; 325 | uint8_t channelConfiguration = 1; 326 | 327 | for (samplingFrequencyIndex = 0; samplingFrequencyIndex < 16; ++samplingFrequencyIndex) 328 | { 329 | if (samplingFrequencyTable[samplingFrequencyIndex] == 44100) 330 | { 331 | break; 332 | } 333 | } 334 | 335 | char fConfigStr[16]; 336 | audioSpecificConfig[0] = (audioObjectType << 3) | (samplingFrequencyIndex >> 1); 337 | audioSpecificConfig[1] = (samplingFrequencyIndex << 7) | (channelConfiguration << 3); 338 | snprintf(fConfigStr, 16, "%02x%02x", audioSpecificConfig[0], audioSpecificConfig[1]); 339 | 340 | aac_fmtp.append(fConfigStr, strlen(fConfigStr)); 341 | rsp.sdp.push_back(aac_fmtp); 342 | } 343 | else if (0 == memcmp(head.cmd.c_str(), DEF_SETUP, strlen(DEF_SETUP))) 344 | { 345 | char* p = head.transport.find("interleaved="); 346 | if (!p) 347 | { 348 | rsp.result = "461"; 349 | rsp.describe = "Unsupported transport"; 350 | } 351 | else 352 | { 353 | rsp.transport = head.transport; 354 | if (rsp.session.size() == 0) 355 | { 356 | rsp.session = "Session: "; 357 | rsp.session.append(++m_session_id); 358 | } 359 | } 360 | } 361 | else if (0 == memcmp(head.cmd.c_str(), DEF_PLAY, strlen(DEF_PLAY))) 362 | { 363 | k_media_server* server = dynamic_cast(task); 364 | server->regist_sink(this); 365 | } 366 | else if (0 == memcmp(head.cmd.c_str(), DEF_TEARDOWN, strlen(DEF_TEARDOWN))) 367 | { 368 | send_rtsp_rsp(rsp, sock); 369 | task->del_event(sock); 370 | return -1; 371 | } 372 | 373 | return send_rtsp_rsp(rsp, sock); 374 | } 375 | 376 | int k_rtsp_handler::handle_read(k_thread_task* task, k_event* ev, k_socket* sock) 377 | { 378 | m_sock = sock; 379 | int ret = sock->k_recv(m_buf, 4096); 380 | 381 | if (ret <= 0) 382 | { 383 | printf("rev ret:%d\n", ret); 384 | task->del_event(sock); 385 | return -1; 386 | } 387 | 388 | m_buf[ret] = '\0'; 389 | printf("%s\n\n", m_buf); 390 | 391 | char* p = m_buf; 392 | 393 | while (ret > 0) 394 | { 395 | if (*p == '$') 396 | { 397 | if (ret < 4) 398 | { 399 | printf("head lt 4\n"); 400 | return -1; 401 | } 402 | uint8_t channel = *(p + 1); 403 | int len = AV_RB16(p + 2); 404 | 405 | p += 4; 406 | ret -= 4; 407 | 408 | if (ret < len) 409 | { 410 | int32_t need = len - ret; 411 | 412 | if (len > m_rebuf_size) 413 | { 414 | if (m_rebuf) 415 | { 416 | free(m_rebuf); 417 | } 418 | 419 | m_rebuf = (char*)malloc(len); 420 | m_rebuf_size = len; 421 | } 422 | 423 | memcpy(m_rebuf, p, ret); 424 | if (sock->k_recv_n(m_rebuf + ret, need)) 425 | { 426 | printf("recv_n half failed\n"); 427 | return -1; 428 | } 429 | 430 | p = m_rebuf; 431 | ret = len; 432 | } 433 | 434 | if (this->parse_rtp_rtcp(channel, p, len)) 435 | { 436 | return -1; 437 | } 438 | 439 | p += len; 440 | ret -= len; 441 | } 442 | else 443 | { 444 | char* p_head_end = strstr(p, "\r\n\r\n"); 445 | if (!p_head_end) 446 | { 447 | printf("header not complete:%s\n", p); 448 | return -1; 449 | } 450 | 451 | ret -= p_head_end - p + strlen("\r\n\r\n"); 452 | 453 | bool parsed_head_line = false; 454 | k_rtsp_head head; 455 | 456 | while(p < p_head_end) 457 | { 458 | if (!parsed_head_line) 459 | { 460 | if (parse_head_line(p, head)) 461 | { 462 | return -1; 463 | } 464 | parsed_head_line = true; 465 | } 466 | else 467 | { 468 | parse_line(p, head); 469 | } 470 | } 471 | 472 | p = p_head_end + strlen("\r\n\r\n"); 473 | 474 | if (on_rtsp_head(head, task, sock)) 475 | { 476 | return -1; 477 | } 478 | } 479 | } 480 | 481 | return 0; 482 | } 483 | 484 | void k_rtsp_handler::handle_del(k_thread_task* task, k_event* ev, k_socket* sock) 485 | { 486 | k_media_server* server = dynamic_cast(task); 487 | server->unregist_sink(this); 488 | 489 | k_handler::handle_del(task, ev, sock); 490 | } 491 | 492 | void k_rtsp_handler::on_video(uint8_t* buf, int len) 493 | { 494 | buf -= 4; 495 | *buf++ = '$'; 496 | *buf++ = 0; 497 | k_util::avio_wb16(buf, len); 498 | 499 | buf -= 4; 500 | len += 4; 501 | 502 | if (len != m_sock->k_send((char*)buf, len)) 503 | { 504 | printf("send video err\n"); 505 | } 506 | } 507 | 508 | void k_rtsp_handler::on_audio(uint8_t* buf, int len) 509 | { 510 | buf -= 4; 511 | *buf++ = '$'; 512 | *buf++ = 2; 513 | k_util::avio_wb16(buf, len); 514 | 515 | buf -= 4; 516 | len += 4; 517 | 518 | if (len != m_sock->k_send((char*)buf, len)) 519 | { 520 | printf("send video err\n"); 521 | } 522 | } 523 | 524 | int k_rtsp_handler::parse_rtp_rtcp(uint8_t channel, char* buf, int len) 525 | { 526 | return 0; 527 | } 528 | -------------------------------------------------------------------------------- /jsoncpp/json/json-forwards.h: -------------------------------------------------------------------------------- 1 | /// Json-cpp amalgamated forward header (http://jsoncpp.sourceforge.net/). 2 | /// It is intended to be used with #include "json/json-forwards.h" 3 | /// This header provides forward declaration for all JsonCpp types. 4 | 5 | // ////////////////////////////////////////////////////////////////////// 6 | // Beginning of content of file: LICENSE 7 | // ////////////////////////////////////////////////////////////////////// 8 | 9 | /* 10 | The JsonCpp library's source code, including accompanying documentation, 11 | tests and demonstration applications, are licensed under the following 12 | conditions... 13 | 14 | Baptiste Lepilleur and The JsonCpp Authors explicitly disclaim copyright in all 15 | jurisdictions which recognize such a disclaimer. In such jurisdictions, 16 | this software is released into the Public Domain. 17 | 18 | In jurisdictions which do not recognize Public Domain property (e.g. Germany as of 19 | 2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur and 20 | The JsonCpp Authors, and is released under the terms of the MIT License (see below). 21 | 22 | In jurisdictions which recognize Public Domain property, the user of this 23 | software may choose to accept it either as 1) Public Domain, 2) under the 24 | conditions of the MIT License (see below), or 3) under the terms of dual 25 | Public Domain/MIT License conditions described here, as they choose. 26 | 27 | The MIT License is about as close to Public Domain as a license can get, and is 28 | described in clear, concise terms at: 29 | 30 | http://en.wikipedia.org/wiki/MIT_License 31 | 32 | The full text of the MIT License follows: 33 | 34 | ======================================================================== 35 | Copyright (c) 2007-2010 Baptiste Lepilleur and The JsonCpp Authors 36 | 37 | Permission is hereby granted, free of charge, to any person 38 | obtaining a copy of this software and associated documentation 39 | files (the "Software"), to deal in the Software without 40 | restriction, including without limitation the rights to use, copy, 41 | modify, merge, publish, distribute, sublicense, and/or sell copies 42 | of the Software, and to permit persons to whom the Software is 43 | furnished to do so, subject to the following conditions: 44 | 45 | The above copyright notice and this permission notice shall be 46 | included in all copies or substantial portions of the Software. 47 | 48 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 49 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 50 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 51 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 52 | BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 53 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 54 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 55 | SOFTWARE. 56 | ======================================================================== 57 | (END LICENSE TEXT) 58 | 59 | The MIT license is compatible with both the GPL and commercial 60 | software, affording one all of the rights of Public Domain with the 61 | minor nuisance of being required to keep the above copyright notice 62 | and license text in the source code. Note also that by accepting the 63 | Public Domain "license" you can re-license your copy using whatever 64 | license you like. 65 | 66 | */ 67 | 68 | // ////////////////////////////////////////////////////////////////////// 69 | // End of content of file: LICENSE 70 | // ////////////////////////////////////////////////////////////////////// 71 | 72 | 73 | 74 | 75 | 76 | #ifndef JSON_FORWARD_AMALGAMATED_H_INCLUDED 77 | # define JSON_FORWARD_AMALGAMATED_H_INCLUDED 78 | /// If defined, indicates that the source file is amalgamated 79 | /// to prevent private header inclusion. 80 | #define JSON_IS_AMALGAMATION 81 | 82 | // ////////////////////////////////////////////////////////////////////// 83 | // Beginning of content of file: include/json/config.h 84 | // ////////////////////////////////////////////////////////////////////// 85 | 86 | // Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors 87 | // Distributed under MIT license, or public domain if desired and 88 | // recognized in your jurisdiction. 89 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 90 | 91 | #ifndef JSON_CONFIG_H_INCLUDED 92 | #define JSON_CONFIG_H_INCLUDED 93 | #include 94 | #include //typedef String 95 | #include //typedef int64_t, uint64_t 96 | 97 | /// If defined, indicates that json library is embedded in CppTL library. 98 | //# define JSON_IN_CPPTL 1 99 | 100 | /// If defined, indicates that json may leverage CppTL library 101 | //# define JSON_USE_CPPTL 1 102 | /// If defined, indicates that cpptl vector based map should be used instead of 103 | /// std::map 104 | /// as Value container. 105 | //# define JSON_USE_CPPTL_SMALLMAP 1 106 | 107 | // If non-zero, the library uses exceptions to report bad input instead of C 108 | // assertion macros. The default is to use exceptions. 109 | #ifndef JSON_USE_EXCEPTION 110 | #define JSON_USE_EXCEPTION 1 111 | #endif 112 | 113 | /// If defined, indicates that the source file is amalgamated 114 | /// to prevent private header inclusion. 115 | /// Remarks: it is automatically defined in the generated amalgamated header. 116 | // #define JSON_IS_AMALGAMATION 117 | 118 | #ifdef JSON_IN_CPPTL 119 | #include 120 | #ifndef JSON_USE_CPPTL 121 | #define JSON_USE_CPPTL 1 122 | #endif 123 | #endif 124 | 125 | #ifdef JSON_IN_CPPTL 126 | #define JSON_API CPPTL_API 127 | #elif defined(JSON_DLL_BUILD) 128 | #if defined(_MSC_VER) || defined(__MINGW32__) 129 | #define JSON_API __declspec(dllexport) 130 | #define JSONCPP_DISABLE_DLL_INTERFACE_WARNING 131 | #endif // if defined(_MSC_VER) 132 | #elif defined(JSON_DLL) 133 | #if defined(_MSC_VER) || defined(__MINGW32__) 134 | #define JSON_API __declspec(dllimport) 135 | #define JSONCPP_DISABLE_DLL_INTERFACE_WARNING 136 | #endif // if defined(_MSC_VER) 137 | #endif // ifdef JSON_IN_CPPTL 138 | #if !defined(JSON_API) 139 | #define JSON_API 140 | #endif 141 | 142 | // If JSON_NO_INT64 is defined, then Json only support C++ "int" type for 143 | // integer 144 | // Storages, and 64 bits integer support is disabled. 145 | // #define JSON_NO_INT64 1 146 | 147 | #if defined(_MSC_VER) // MSVC 148 | # if _MSC_VER <= 1200 // MSVC 6 149 | // Microsoft Visual Studio 6 only support conversion from __int64 to double 150 | // (no conversion from unsigned __int64). 151 | # define JSON_USE_INT64_DOUBLE_CONVERSION 1 152 | // Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255' 153 | // characters in the debug information) 154 | // All projects I've ever seen with VS6 were using this globally (not bothering 155 | // with pragma push/pop). 156 | # pragma warning(disable : 4786) 157 | # endif // MSVC 6 158 | 159 | # if _MSC_VER >= 1500 // MSVC 2008 160 | /// Indicates that the following function is deprecated. 161 | # define JSONCPP_DEPRECATED(message) __declspec(deprecated(message)) 162 | # endif 163 | 164 | #endif // defined(_MSC_VER) 165 | 166 | // In c++11 the override keyword allows you to explicitly define that a function 167 | // is intended to override the base-class version. This makes the code more 168 | // manageable and fixes a set of common hard-to-find bugs. 169 | #if __cplusplus >= 201103L 170 | # define JSONCPP_OVERRIDE override 171 | # define JSONCPP_NOEXCEPT noexcept 172 | # define JSONCPP_OP_EXPLICIT explicit 173 | #elif defined(_MSC_VER) && _MSC_VER > 1600 && _MSC_VER < 1900 174 | # define JSONCPP_OVERRIDE override 175 | # define JSONCPP_NOEXCEPT throw() 176 | # if _MSC_VER >= 1800 // MSVC 2013 177 | # define JSONCPP_OP_EXPLICIT explicit 178 | # else 179 | # define JSONCPP_OP_EXPLICIT 180 | # endif 181 | #elif defined(_MSC_VER) && _MSC_VER >= 1900 182 | # define JSONCPP_OVERRIDE override 183 | # define JSONCPP_NOEXCEPT noexcept 184 | # define JSONCPP_OP_EXPLICIT explicit 185 | #else 186 | # define JSONCPP_OVERRIDE 187 | # define JSONCPP_NOEXCEPT throw() 188 | # define JSONCPP_OP_EXPLICIT 189 | #endif 190 | 191 | #ifndef JSON_HAS_RVALUE_REFERENCES 192 | 193 | #if defined(_MSC_VER) && _MSC_VER >= 1600 // MSVC >= 2010 194 | #define JSON_HAS_RVALUE_REFERENCES 1 195 | #endif // MSVC >= 2010 196 | 197 | #ifdef __clang__ 198 | #if __has_feature(cxx_rvalue_references) 199 | #define JSON_HAS_RVALUE_REFERENCES 1 200 | #endif // has_feature 201 | 202 | #elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc) 203 | #if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L) 204 | #define JSON_HAS_RVALUE_REFERENCES 1 205 | #endif // GXX_EXPERIMENTAL 206 | 207 | #endif // __clang__ || __GNUC__ 208 | 209 | #endif // not defined JSON_HAS_RVALUE_REFERENCES 210 | 211 | #ifndef JSON_HAS_RVALUE_REFERENCES 212 | #define JSON_HAS_RVALUE_REFERENCES 0 213 | #endif 214 | 215 | #ifdef __clang__ 216 | # if __has_extension(attribute_deprecated_with_message) 217 | # define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message))) 218 | # endif 219 | #elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc) 220 | # if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) 221 | # define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message))) 222 | # elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) 223 | # define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__)) 224 | # endif // GNUC version 225 | #endif // __clang__ || __GNUC__ 226 | 227 | #if !defined(JSONCPP_DEPRECATED) 228 | #define JSONCPP_DEPRECATED(message) 229 | #endif // if !defined(JSONCPP_DEPRECATED) 230 | 231 | #if __GNUC__ >= 6 232 | # define JSON_USE_INT64_DOUBLE_CONVERSION 1 233 | #endif 234 | 235 | #if !defined(JSON_IS_AMALGAMATION) 236 | 237 | # include "version.h" 238 | 239 | # if JSONCPP_USING_SECURE_MEMORY 240 | # include "allocator.h" //typedef Allocator 241 | # endif 242 | 243 | #endif // if !defined(JSON_IS_AMALGAMATION) 244 | 245 | namespace Json { 246 | typedef int Int; 247 | typedef unsigned int UInt; 248 | #if defined(JSON_NO_INT64) 249 | typedef int LargestInt; 250 | typedef unsigned int LargestUInt; 251 | #undef JSON_HAS_INT64 252 | #else // if defined(JSON_NO_INT64) 253 | // For Microsoft Visual use specific types as long long is not supported 254 | #if defined(_MSC_VER) // Microsoft Visual Studio 255 | typedef __int64 Int64; 256 | typedef unsigned __int64 UInt64; 257 | #else // if defined(_MSC_VER) // Other platforms, use long long 258 | typedef int64_t Int64; 259 | typedef uint64_t UInt64; 260 | #endif // if defined(_MSC_VER) 261 | typedef Int64 LargestInt; 262 | typedef UInt64 LargestUInt; 263 | #define JSON_HAS_INT64 264 | #endif // if defined(JSON_NO_INT64) 265 | #if JSONCPP_USING_SECURE_MEMORY 266 | #define JSONCPP_STRING std::basic_string, Json::SecureAllocator > 267 | #define JSONCPP_OSTRINGSTREAM std::basic_ostringstream, Json::SecureAllocator > 268 | #define JSONCPP_OSTREAM std::basic_ostream> 269 | #define JSONCPP_ISTRINGSTREAM std::basic_istringstream, Json::SecureAllocator > 270 | #define JSONCPP_ISTREAM std::istream 271 | #else 272 | #define JSONCPP_STRING std::string 273 | #define JSONCPP_OSTRINGSTREAM std::ostringstream 274 | #define JSONCPP_OSTREAM std::ostream 275 | #define JSONCPP_ISTRINGSTREAM std::istringstream 276 | #define JSONCPP_ISTREAM std::istream 277 | #endif // if JSONCPP_USING_SECURE_MEMORY 278 | } // end namespace Json 279 | 280 | #endif // JSON_CONFIG_H_INCLUDED 281 | 282 | // ////////////////////////////////////////////////////////////////////// 283 | // End of content of file: include/json/config.h 284 | // ////////////////////////////////////////////////////////////////////// 285 | 286 | 287 | 288 | 289 | 290 | 291 | // ////////////////////////////////////////////////////////////////////// 292 | // Beginning of content of file: include/json/forwards.h 293 | // ////////////////////////////////////////////////////////////////////// 294 | 295 | // Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors 296 | // Distributed under MIT license, or public domain if desired and 297 | // recognized in your jurisdiction. 298 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 299 | 300 | #ifndef JSON_FORWARDS_H_INCLUDED 301 | #define JSON_FORWARDS_H_INCLUDED 302 | 303 | #if !defined(JSON_IS_AMALGAMATION) 304 | #include "config.h" 305 | #endif // if !defined(JSON_IS_AMALGAMATION) 306 | 307 | namespace Json { 308 | 309 | // writer.h 310 | class FastWriter; 311 | class StyledWriter; 312 | 313 | // reader.h 314 | class Reader; 315 | 316 | // features.h 317 | class Features; 318 | 319 | // value.h 320 | typedef unsigned int ArrayIndex; 321 | class StaticString; 322 | class Path; 323 | class PathArgument; 324 | class Value; 325 | class ValueIteratorBase; 326 | class ValueIterator; 327 | class ValueConstIterator; 328 | 329 | } // namespace Json 330 | 331 | #endif // JSON_FORWARDS_H_INCLUDED 332 | 333 | // ////////////////////////////////////////////////////////////////////// 334 | // End of content of file: include/json/forwards.h 335 | // ////////////////////////////////////////////////////////////////////// 336 | 337 | 338 | 339 | 340 | 341 | #endif //ifndef JSON_FORWARD_AMALGAMATED_H_INCLUDED 342 | -------------------------------------------------------------------------------- /jsoncpp/json/json.h: -------------------------------------------------------------------------------- 1 | /// Json-cpp amalgamated header (http://jsoncpp.sourceforge.net/). 2 | /// It is intended to be used with #include "json/json.h" 3 | 4 | // ////////////////////////////////////////////////////////////////////// 5 | // Beginning of content of file: LICENSE 6 | // ////////////////////////////////////////////////////////////////////// 7 | 8 | /* 9 | The JsonCpp library's source code, including accompanying documentation, 10 | tests and demonstration applications, are licensed under the following 11 | conditions... 12 | 13 | Baptiste Lepilleur and The JsonCpp Authors explicitly disclaim copyright in all 14 | jurisdictions which recognize such a disclaimer. In such jurisdictions, 15 | this software is released into the Public Domain. 16 | 17 | In jurisdictions which do not recognize Public Domain property (e.g. Germany as of 18 | 2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur and 19 | The JsonCpp Authors, and is released under the terms of the MIT License (see below). 20 | 21 | In jurisdictions which recognize Public Domain property, the user of this 22 | software may choose to accept it either as 1) Public Domain, 2) under the 23 | conditions of the MIT License (see below), or 3) under the terms of dual 24 | Public Domain/MIT License conditions described here, as they choose. 25 | 26 | The MIT License is about as close to Public Domain as a license can get, and is 27 | described in clear, concise terms at: 28 | 29 | http://en.wikipedia.org/wiki/MIT_License 30 | 31 | The full text of the MIT License follows: 32 | 33 | ======================================================================== 34 | Copyright (c) 2007-2010 Baptiste Lepilleur and The JsonCpp Authors 35 | 36 | Permission is hereby granted, free of charge, to any person 37 | obtaining a copy of this software and associated documentation 38 | files (the "Software"), to deal in the Software without 39 | restriction, including without limitation the rights to use, copy, 40 | modify, merge, publish, distribute, sublicense, and/or sell copies 41 | of the Software, and to permit persons to whom the Software is 42 | furnished to do so, subject to the following conditions: 43 | 44 | The above copyright notice and this permission notice shall be 45 | included in all copies or substantial portions of the Software. 46 | 47 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 48 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 49 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 50 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 51 | BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 52 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 53 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 54 | SOFTWARE. 55 | ======================================================================== 56 | (END LICENSE TEXT) 57 | 58 | The MIT license is compatible with both the GPL and commercial 59 | software, affording one all of the rights of Public Domain with the 60 | minor nuisance of being required to keep the above copyright notice 61 | and license text in the source code. Note also that by accepting the 62 | Public Domain "license" you can re-license your copy using whatever 63 | license you like. 64 | 65 | */ 66 | 67 | // ////////////////////////////////////////////////////////////////////// 68 | // End of content of file: LICENSE 69 | // ////////////////////////////////////////////////////////////////////// 70 | 71 | 72 | 73 | 74 | 75 | #ifndef JSON_AMALGAMATED_H_INCLUDED 76 | # define JSON_AMALGAMATED_H_INCLUDED 77 | /// If defined, indicates that the source file is amalgamated 78 | /// to prevent private header inclusion. 79 | #define JSON_IS_AMALGAMATION 80 | 81 | // ////////////////////////////////////////////////////////////////////// 82 | // Beginning of content of file: include/json/version.h 83 | // ////////////////////////////////////////////////////////////////////// 84 | 85 | // DO NOT EDIT. This file (and "version") is generated by CMake. 86 | // Run CMake configure step to update it. 87 | #ifndef JSON_VERSION_H_INCLUDED 88 | # define JSON_VERSION_H_INCLUDED 89 | 90 | # define JSONCPP_VERSION_STRING "1.8.4" 91 | # define JSONCPP_VERSION_MAJOR 1 92 | # define JSONCPP_VERSION_MINOR 8 93 | # define JSONCPP_VERSION_PATCH 4 94 | # define JSONCPP_VERSION_QUALIFIER 95 | # define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8)) 96 | 97 | #ifdef JSONCPP_USING_SECURE_MEMORY 98 | #undef JSONCPP_USING_SECURE_MEMORY 99 | #endif 100 | #define JSONCPP_USING_SECURE_MEMORY 0 101 | // If non-zero, the library zeroes any memory that it has allocated before 102 | // it frees its memory. 103 | 104 | #endif // JSON_VERSION_H_INCLUDED 105 | 106 | // ////////////////////////////////////////////////////////////////////// 107 | // End of content of file: include/json/version.h 108 | // ////////////////////////////////////////////////////////////////////// 109 | 110 | 111 | 112 | 113 | 114 | 115 | // ////////////////////////////////////////////////////////////////////// 116 | // Beginning of content of file: include/json/config.h 117 | // ////////////////////////////////////////////////////////////////////// 118 | 119 | // Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors 120 | // Distributed under MIT license, or public domain if desired and 121 | // recognized in your jurisdiction. 122 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 123 | 124 | #ifndef JSON_CONFIG_H_INCLUDED 125 | #define JSON_CONFIG_H_INCLUDED 126 | #include 127 | #include //typedef String 128 | #include //typedef int64_t, uint64_t 129 | 130 | /// If defined, indicates that json library is embedded in CppTL library. 131 | //# define JSON_IN_CPPTL 1 132 | 133 | /// If defined, indicates that json may leverage CppTL library 134 | //# define JSON_USE_CPPTL 1 135 | /// If defined, indicates that cpptl vector based map should be used instead of 136 | /// std::map 137 | /// as Value container. 138 | //# define JSON_USE_CPPTL_SMALLMAP 1 139 | 140 | // If non-zero, the library uses exceptions to report bad input instead of C 141 | // assertion macros. The default is to use exceptions. 142 | #ifndef JSON_USE_EXCEPTION 143 | #define JSON_USE_EXCEPTION 1 144 | #endif 145 | 146 | /// If defined, indicates that the source file is amalgamated 147 | /// to prevent private header inclusion. 148 | /// Remarks: it is automatically defined in the generated amalgamated header. 149 | // #define JSON_IS_AMALGAMATION 150 | 151 | #ifdef JSON_IN_CPPTL 152 | #include 153 | #ifndef JSON_USE_CPPTL 154 | #define JSON_USE_CPPTL 1 155 | #endif 156 | #endif 157 | 158 | #ifdef JSON_IN_CPPTL 159 | #define JSON_API CPPTL_API 160 | #elif defined(JSON_DLL_BUILD) 161 | #if defined(_MSC_VER) || defined(__MINGW32__) 162 | #define JSON_API __declspec(dllexport) 163 | #define JSONCPP_DISABLE_DLL_INTERFACE_WARNING 164 | #endif // if defined(_MSC_VER) 165 | #elif defined(JSON_DLL) 166 | #if defined(_MSC_VER) || defined(__MINGW32__) 167 | #define JSON_API __declspec(dllimport) 168 | #define JSONCPP_DISABLE_DLL_INTERFACE_WARNING 169 | #endif // if defined(_MSC_VER) 170 | #endif // ifdef JSON_IN_CPPTL 171 | #if !defined(JSON_API) 172 | #define JSON_API 173 | #endif 174 | 175 | // If JSON_NO_INT64 is defined, then Json only support C++ "int" type for 176 | // integer 177 | // Storages, and 64 bits integer support is disabled. 178 | // #define JSON_NO_INT64 1 179 | 180 | #if defined(_MSC_VER) // MSVC 181 | # if _MSC_VER <= 1200 // MSVC 6 182 | // Microsoft Visual Studio 6 only support conversion from __int64 to double 183 | // (no conversion from unsigned __int64). 184 | # define JSON_USE_INT64_DOUBLE_CONVERSION 1 185 | // Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255' 186 | // characters in the debug information) 187 | // All projects I've ever seen with VS6 were using this globally (not bothering 188 | // with pragma push/pop). 189 | # pragma warning(disable : 4786) 190 | # endif // MSVC 6 191 | 192 | # if _MSC_VER >= 1500 // MSVC 2008 193 | /// Indicates that the following function is deprecated. 194 | # define JSONCPP_DEPRECATED(message) __declspec(deprecated(message)) 195 | # endif 196 | 197 | #endif // defined(_MSC_VER) 198 | 199 | // In c++11 the override keyword allows you to explicitly define that a function 200 | // is intended to override the base-class version. This makes the code more 201 | // manageable and fixes a set of common hard-to-find bugs. 202 | #if __cplusplus >= 201103L 203 | # define JSONCPP_OVERRIDE override 204 | # define JSONCPP_NOEXCEPT noexcept 205 | # define JSONCPP_OP_EXPLICIT explicit 206 | #elif defined(_MSC_VER) && _MSC_VER > 1600 && _MSC_VER < 1900 207 | # define JSONCPP_OVERRIDE override 208 | # define JSONCPP_NOEXCEPT throw() 209 | # if _MSC_VER >= 1800 // MSVC 2013 210 | # define JSONCPP_OP_EXPLICIT explicit 211 | # else 212 | # define JSONCPP_OP_EXPLICIT 213 | # endif 214 | #elif defined(_MSC_VER) && _MSC_VER >= 1900 215 | # define JSONCPP_OVERRIDE override 216 | # define JSONCPP_NOEXCEPT noexcept 217 | # define JSONCPP_OP_EXPLICIT explicit 218 | #else 219 | # define JSONCPP_OVERRIDE 220 | # define JSONCPP_NOEXCEPT throw() 221 | # define JSONCPP_OP_EXPLICIT 222 | #endif 223 | 224 | #ifndef JSON_HAS_RVALUE_REFERENCES 225 | 226 | #if defined(_MSC_VER) && _MSC_VER >= 1600 // MSVC >= 2010 227 | #define JSON_HAS_RVALUE_REFERENCES 1 228 | #endif // MSVC >= 2010 229 | 230 | #ifdef __clang__ 231 | #if __has_feature(cxx_rvalue_references) 232 | #define JSON_HAS_RVALUE_REFERENCES 1 233 | #endif // has_feature 234 | 235 | #elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc) 236 | #if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L) 237 | #define JSON_HAS_RVALUE_REFERENCES 1 238 | #endif // GXX_EXPERIMENTAL 239 | 240 | #endif // __clang__ || __GNUC__ 241 | 242 | #endif // not defined JSON_HAS_RVALUE_REFERENCES 243 | 244 | #ifndef JSON_HAS_RVALUE_REFERENCES 245 | #define JSON_HAS_RVALUE_REFERENCES 0 246 | #endif 247 | 248 | #ifdef __clang__ 249 | # if __has_extension(attribute_deprecated_with_message) 250 | # define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message))) 251 | # endif 252 | #elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc) 253 | # if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) 254 | # define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message))) 255 | # elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) 256 | # define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__)) 257 | # endif // GNUC version 258 | #endif // __clang__ || __GNUC__ 259 | 260 | #if !defined(JSONCPP_DEPRECATED) 261 | #define JSONCPP_DEPRECATED(message) 262 | #endif // if !defined(JSONCPP_DEPRECATED) 263 | 264 | #if __GNUC__ >= 6 265 | # define JSON_USE_INT64_DOUBLE_CONVERSION 1 266 | #endif 267 | 268 | #if !defined(JSON_IS_AMALGAMATION) 269 | 270 | # include "version.h" 271 | 272 | # if JSONCPP_USING_SECURE_MEMORY 273 | # include "allocator.h" //typedef Allocator 274 | # endif 275 | 276 | #endif // if !defined(JSON_IS_AMALGAMATION) 277 | 278 | namespace Json { 279 | typedef int Int; 280 | typedef unsigned int UInt; 281 | #if defined(JSON_NO_INT64) 282 | typedef int LargestInt; 283 | typedef unsigned int LargestUInt; 284 | #undef JSON_HAS_INT64 285 | #else // if defined(JSON_NO_INT64) 286 | // For Microsoft Visual use specific types as long long is not supported 287 | #if defined(_MSC_VER) // Microsoft Visual Studio 288 | typedef __int64 Int64; 289 | typedef unsigned __int64 UInt64; 290 | #else // if defined(_MSC_VER) // Other platforms, use long long 291 | typedef int64_t Int64; 292 | typedef uint64_t UInt64; 293 | #endif // if defined(_MSC_VER) 294 | typedef Int64 LargestInt; 295 | typedef UInt64 LargestUInt; 296 | #define JSON_HAS_INT64 297 | #endif // if defined(JSON_NO_INT64) 298 | #if JSONCPP_USING_SECURE_MEMORY 299 | #define JSONCPP_STRING std::basic_string, Json::SecureAllocator > 300 | #define JSONCPP_OSTRINGSTREAM std::basic_ostringstream, Json::SecureAllocator > 301 | #define JSONCPP_OSTREAM std::basic_ostream> 302 | #define JSONCPP_ISTRINGSTREAM std::basic_istringstream, Json::SecureAllocator > 303 | #define JSONCPP_ISTREAM std::istream 304 | #else 305 | #define JSONCPP_STRING std::string 306 | #define JSONCPP_OSTRINGSTREAM std::ostringstream 307 | #define JSONCPP_OSTREAM std::ostream 308 | #define JSONCPP_ISTRINGSTREAM std::istringstream 309 | #define JSONCPP_ISTREAM std::istream 310 | #endif // if JSONCPP_USING_SECURE_MEMORY 311 | } // end namespace Json 312 | 313 | #endif // JSON_CONFIG_H_INCLUDED 314 | 315 | // ////////////////////////////////////////////////////////////////////// 316 | // End of content of file: include/json/config.h 317 | // ////////////////////////////////////////////////////////////////////// 318 | 319 | 320 | 321 | 322 | 323 | 324 | // ////////////////////////////////////////////////////////////////////// 325 | // Beginning of content of file: include/json/forwards.h 326 | // ////////////////////////////////////////////////////////////////////// 327 | 328 | // Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors 329 | // Distributed under MIT license, or public domain if desired and 330 | // recognized in your jurisdiction. 331 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 332 | 333 | #ifndef JSON_FORWARDS_H_INCLUDED 334 | #define JSON_FORWARDS_H_INCLUDED 335 | 336 | #if !defined(JSON_IS_AMALGAMATION) 337 | #include "config.h" 338 | #endif // if !defined(JSON_IS_AMALGAMATION) 339 | 340 | namespace Json { 341 | 342 | // writer.h 343 | class FastWriter; 344 | class StyledWriter; 345 | 346 | // reader.h 347 | class Reader; 348 | 349 | // features.h 350 | class Features; 351 | 352 | // value.h 353 | typedef unsigned int ArrayIndex; 354 | class StaticString; 355 | class Path; 356 | class PathArgument; 357 | class Value; 358 | class ValueIteratorBase; 359 | class ValueIterator; 360 | class ValueConstIterator; 361 | 362 | } // namespace Json 363 | 364 | #endif // JSON_FORWARDS_H_INCLUDED 365 | 366 | // ////////////////////////////////////////////////////////////////////// 367 | // End of content of file: include/json/forwards.h 368 | // ////////////////////////////////////////////////////////////////////// 369 | 370 | 371 | 372 | 373 | 374 | 375 | // ////////////////////////////////////////////////////////////////////// 376 | // Beginning of content of file: include/json/features.h 377 | // ////////////////////////////////////////////////////////////////////// 378 | 379 | // Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors 380 | // Distributed under MIT license, or public domain if desired and 381 | // recognized in your jurisdiction. 382 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 383 | 384 | #ifndef CPPTL_JSON_FEATURES_H_INCLUDED 385 | #define CPPTL_JSON_FEATURES_H_INCLUDED 386 | 387 | #if !defined(JSON_IS_AMALGAMATION) 388 | #include "forwards.h" 389 | #endif // if !defined(JSON_IS_AMALGAMATION) 390 | 391 | #pragma pack(push, 8) 392 | 393 | namespace Json { 394 | 395 | /** \brief Configuration passed to reader and writer. 396 | * This configuration object can be used to force the Reader or Writer 397 | * to behave in a standard conforming way. 398 | */ 399 | class JSON_API Features { 400 | public: 401 | /** \brief A configuration that allows all features and assumes all strings 402 | * are UTF-8. 403 | * - C & C++ comments are allowed 404 | * - Root object can be any JSON value 405 | * - Assumes Value strings are encoded in UTF-8 406 | */ 407 | static Features all(); 408 | 409 | /** \brief A configuration that is strictly compatible with the JSON 410 | * specification. 411 | * - Comments are forbidden. 412 | * - Root object must be either an array or an object value. 413 | * - Assumes Value strings are encoded in UTF-8 414 | */ 415 | static Features strictMode(); 416 | 417 | /** \brief Initialize the configuration like JsonConfig::allFeatures; 418 | */ 419 | Features(); 420 | 421 | /// \c true if comments are allowed. Default: \c true. 422 | bool allowComments_; 423 | 424 | /// \c true if root must be either an array or an object value. Default: \c 425 | /// false. 426 | bool strictRoot_; 427 | 428 | /// \c true if dropped null placeholders are allowed. Default: \c false. 429 | bool allowDroppedNullPlaceholders_; 430 | 431 | /// \c true if numeric object key are allowed. Default: \c false. 432 | bool allowNumericKeys_; 433 | }; 434 | 435 | } // namespace Json 436 | 437 | #pragma pack(pop) 438 | 439 | #endif // CPPTL_JSON_FEATURES_H_INCLUDED 440 | 441 | // ////////////////////////////////////////////////////////////////////// 442 | // End of content of file: include/json/features.h 443 | // ////////////////////////////////////////////////////////////////////// 444 | 445 | 446 | 447 | 448 | 449 | 450 | // ////////////////////////////////////////////////////////////////////// 451 | // Beginning of content of file: include/json/value.h 452 | // ////////////////////////////////////////////////////////////////////// 453 | 454 | // Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors 455 | // Distributed under MIT license, or public domain if desired and 456 | // recognized in your jurisdiction. 457 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 458 | 459 | #ifndef CPPTL_JSON_H_INCLUDED 460 | #define CPPTL_JSON_H_INCLUDED 461 | 462 | #if !defined(JSON_IS_AMALGAMATION) 463 | #include "forwards.h" 464 | #endif // if !defined(JSON_IS_AMALGAMATION) 465 | #include 466 | #include 467 | #include 468 | 469 | #ifndef JSON_USE_CPPTL_SMALLMAP 470 | #include 471 | #else 472 | #include 473 | #endif 474 | #ifdef JSON_USE_CPPTL 475 | #include 476 | #endif 477 | 478 | //Conditional NORETURN attribute on the throw functions would: 479 | // a) suppress false positives from static code analysis 480 | // b) possibly improve optimization opportunities. 481 | #if !defined(JSONCPP_NORETURN) 482 | # if defined(_MSC_VER) 483 | # define JSONCPP_NORETURN __declspec(noreturn) 484 | # elif defined(__GNUC__) 485 | # define JSONCPP_NORETURN __attribute__ ((__noreturn__)) 486 | # else 487 | # define JSONCPP_NORETURN 488 | # endif 489 | #endif 490 | 491 | // Disable warning C4251: : needs to have dll-interface to 492 | // be used by... 493 | #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 494 | #pragma warning(push) 495 | #pragma warning(disable : 4251) 496 | #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 497 | 498 | #pragma pack(push, 8) 499 | 500 | /** \brief JSON (JavaScript Object Notation). 501 | */ 502 | namespace Json { 503 | 504 | /** Base class for all exceptions we throw. 505 | * 506 | * We use nothing but these internally. Of course, STL can throw others. 507 | */ 508 | class JSON_API Exception : public std::exception { 509 | public: 510 | Exception(JSONCPP_STRING const& msg); 511 | ~Exception() JSONCPP_NOEXCEPT JSONCPP_OVERRIDE; 512 | char const* what() const JSONCPP_NOEXCEPT JSONCPP_OVERRIDE; 513 | protected: 514 | JSONCPP_STRING msg_; 515 | }; 516 | 517 | /** Exceptions which the user cannot easily avoid. 518 | * 519 | * E.g. out-of-memory (when we use malloc), stack-overflow, malicious input 520 | * 521 | * \remark derived from Json::Exception 522 | */ 523 | class JSON_API RuntimeError : public Exception { 524 | public: 525 | RuntimeError(JSONCPP_STRING const& msg); 526 | }; 527 | 528 | /** Exceptions thrown by JSON_ASSERT/JSON_FAIL macros. 529 | * 530 | * These are precondition-violations (user bugs) and internal errors (our bugs). 531 | * 532 | * \remark derived from Json::Exception 533 | */ 534 | class JSON_API LogicError : public Exception { 535 | public: 536 | LogicError(JSONCPP_STRING const& msg); 537 | }; 538 | 539 | /// used internally 540 | JSONCPP_NORETURN void throwRuntimeError(JSONCPP_STRING const& msg); 541 | /// used internally 542 | JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& msg); 543 | 544 | /** \brief Type of the value held by a Value object. 545 | */ 546 | enum ValueType { 547 | nullValue = 0, ///< 'null' value 548 | intValue, ///< signed integer value 549 | uintValue, ///< unsigned integer value 550 | realValue, ///< double value 551 | stringValue, ///< UTF-8 string value 552 | booleanValue, ///< bool value 553 | arrayValue, ///< array value (ordered list) 554 | objectValue ///< object value (collection of name/value pairs). 555 | }; 556 | 557 | enum CommentPlacement { 558 | commentBefore = 0, ///< a comment placed on the line before a value 559 | commentAfterOnSameLine, ///< a comment just after a value on the same line 560 | commentAfter, ///< a comment on the line after a value (only make sense for 561 | /// root value) 562 | numberOfCommentPlacement 563 | }; 564 | 565 | /** \brief Type of precision for formatting of real values. 566 | */ 567 | enum PrecisionType { 568 | significantDigits = 0, ///< we set max number of significant digits in string 569 | decimalPlaces ///< we set max number of digits after "." in string 570 | }; 571 | 572 | //# ifdef JSON_USE_CPPTL 573 | // typedef CppTL::AnyEnumerator EnumMemberNames; 574 | // typedef CppTL::AnyEnumerator EnumValues; 575 | //# endif 576 | 577 | /** \brief Lightweight wrapper to tag static string. 578 | * 579 | * Value constructor and objectValue member assignment takes advantage of the 580 | * StaticString and avoid the cost of string duplication when storing the 581 | * string or the member name. 582 | * 583 | * Example of usage: 584 | * \code 585 | * Json::Value aValue( StaticString("some text") ); 586 | * Json::Value object; 587 | * static const StaticString code("code"); 588 | * object[code] = 1234; 589 | * \endcode 590 | */ 591 | class JSON_API StaticString { 592 | public: 593 | explicit StaticString(const char* czstring) : c_str_(czstring) {} 594 | 595 | operator const char*() const { return c_str_; } 596 | 597 | const char* c_str() const { return c_str_; } 598 | 599 | private: 600 | const char* c_str_; 601 | }; 602 | 603 | /** \brief Represents a JSON value. 604 | * 605 | * This class is a discriminated union wrapper that can represents a: 606 | * - signed integer [range: Value::minInt - Value::maxInt] 607 | * - unsigned integer (range: 0 - Value::maxUInt) 608 | * - double 609 | * - UTF-8 string 610 | * - boolean 611 | * - 'null' 612 | * - an ordered list of Value 613 | * - collection of name/value pairs (javascript object) 614 | * 615 | * The type of the held value is represented by a #ValueType and 616 | * can be obtained using type(). 617 | * 618 | * Values of an #objectValue or #arrayValue can be accessed using operator[]() 619 | * methods. 620 | * Non-const methods will automatically create the a #nullValue element 621 | * if it does not exist. 622 | * The sequence of an #arrayValue will be automatically resized and initialized 623 | * with #nullValue. resize() can be used to enlarge or truncate an #arrayValue. 624 | * 625 | * The get() methods can be used to obtain default value in the case the 626 | * required element does not exist. 627 | * 628 | * It is possible to iterate over the list of a #objectValue values using 629 | * the getMemberNames() method. 630 | * 631 | * \note #Value string-length fit in size_t, but keys must be < 2^30. 632 | * (The reason is an implementation detail.) A #CharReader will raise an 633 | * exception if a bound is exceeded to avoid security holes in your app, 634 | * but the Value API does *not* check bounds. That is the responsibility 635 | * of the caller. 636 | */ 637 | class JSON_API Value { 638 | friend class ValueIteratorBase; 639 | public: 640 | typedef std::vector Members; 641 | typedef ValueIterator iterator; 642 | typedef ValueConstIterator const_iterator; 643 | typedef Json::UInt UInt; 644 | typedef Json::Int Int; 645 | #if defined(JSON_HAS_INT64) 646 | typedef Json::UInt64 UInt64; 647 | typedef Json::Int64 Int64; 648 | #endif // defined(JSON_HAS_INT64) 649 | typedef Json::LargestInt LargestInt; 650 | typedef Json::LargestUInt LargestUInt; 651 | typedef Json::ArrayIndex ArrayIndex; 652 | 653 | // Required for boost integration, e. g. BOOST_TEST 654 | typedef std::string value_type; 655 | 656 | static const Value& null; ///< We regret this reference to a global instance; prefer the simpler Value(). 657 | static const Value& nullRef; ///< just a kludge for binary-compatibility; same as null 658 | static Value const& nullSingleton(); ///< Prefer this to null or nullRef. 659 | 660 | /// Minimum signed integer value that can be stored in a Json::Value. 661 | static const LargestInt minLargestInt; 662 | /// Maximum signed integer value that can be stored in a Json::Value. 663 | static const LargestInt maxLargestInt; 664 | /// Maximum unsigned integer value that can be stored in a Json::Value. 665 | static const LargestUInt maxLargestUInt; 666 | 667 | /// Minimum signed int value that can be stored in a Json::Value. 668 | static const Int minInt; 669 | /// Maximum signed int value that can be stored in a Json::Value. 670 | static const Int maxInt; 671 | /// Maximum unsigned int value that can be stored in a Json::Value. 672 | static const UInt maxUInt; 673 | 674 | #if defined(JSON_HAS_INT64) 675 | /// Minimum signed 64 bits int value that can be stored in a Json::Value. 676 | static const Int64 minInt64; 677 | /// Maximum signed 64 bits int value that can be stored in a Json::Value. 678 | static const Int64 maxInt64; 679 | /// Maximum unsigned 64 bits int value that can be stored in a Json::Value. 680 | static const UInt64 maxUInt64; 681 | #endif // defined(JSON_HAS_INT64) 682 | 683 | /// Default precision for real value for string representation. 684 | static const UInt defaultRealPrecision; 685 | 686 | // Workaround for bug in the NVIDIAs CUDA 9.1 nvcc compiler 687 | // when using gcc and clang backend compilers. CZString 688 | // cannot be defined as private. See issue #486 689 | #ifdef __NVCC__ 690 | public: 691 | #else 692 | private: 693 | #endif 694 | #ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION 695 | class CZString { 696 | public: 697 | enum DuplicationPolicy { 698 | noDuplication = 0, 699 | duplicate, 700 | duplicateOnCopy 701 | }; 702 | CZString(ArrayIndex index); 703 | CZString(char const* str, unsigned length, DuplicationPolicy allocate); 704 | CZString(CZString const& other); 705 | #if JSON_HAS_RVALUE_REFERENCES 706 | CZString(CZString&& other); 707 | #endif 708 | ~CZString(); 709 | CZString& operator=(const CZString& other); 710 | 711 | #if JSON_HAS_RVALUE_REFERENCES 712 | CZString& operator=(CZString&& other); 713 | #endif 714 | 715 | bool operator<(CZString const& other) const; 716 | bool operator==(CZString const& other) const; 717 | ArrayIndex index() const; 718 | //const char* c_str() const; ///< \deprecated 719 | char const* data() const; 720 | unsigned length() const; 721 | bool isStaticString() const; 722 | 723 | private: 724 | void swap(CZString& other); 725 | 726 | struct StringStorage { 727 | unsigned policy_: 2; 728 | unsigned length_: 30; // 1GB max 729 | }; 730 | 731 | char const* cstr_; // actually, a prefixed string, unless policy is noDup 732 | union { 733 | ArrayIndex index_; 734 | StringStorage storage_; 735 | }; 736 | }; 737 | 738 | public: 739 | #ifndef JSON_USE_CPPTL_SMALLMAP 740 | typedef std::map ObjectValues; 741 | #else 742 | typedef CppTL::SmallMap ObjectValues; 743 | #endif // ifndef JSON_USE_CPPTL_SMALLMAP 744 | #endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION 745 | 746 | public: 747 | /** \brief Create a default Value of the given type. 748 | 749 | This is a very useful constructor. 750 | To create an empty array, pass arrayValue. 751 | To create an empty object, pass objectValue. 752 | Another Value can then be set to this one by assignment. 753 | This is useful since clear() and resize() will not alter types. 754 | 755 | Examples: 756 | \code 757 | Json::Value null_value; // null 758 | Json::Value arr_value(Json::arrayValue); // [] 759 | Json::Value obj_value(Json::objectValue); // {} 760 | \endcode 761 | */ 762 | Value(ValueType type = nullValue); 763 | Value(Int value); 764 | Value(UInt value); 765 | #if defined(JSON_HAS_INT64) 766 | Value(Int64 value); 767 | Value(UInt64 value); 768 | #endif // if defined(JSON_HAS_INT64) 769 | Value(double value); 770 | Value(const char* value); ///< Copy til first 0. (NULL causes to seg-fault.) 771 | Value(const char* begin, const char* end); ///< Copy all, incl zeroes. 772 | /** \brief Constructs a value from a static string. 773 | 774 | * Like other value string constructor but do not duplicate the string for 775 | * internal storage. The given string must remain alive after the call to this 776 | * constructor. 777 | * \note This works only for null-terminated strings. (We cannot change the 778 | * size of this class, so we have nowhere to store the length, 779 | * which might be computed later for various operations.) 780 | * 781 | * Example of usage: 782 | * \code 783 | * static StaticString foo("some text"); 784 | * Json::Value aValue(foo); 785 | * \endcode 786 | */ 787 | Value(const StaticString& value); 788 | Value(const JSONCPP_STRING& value); ///< Copy data() til size(). Embedded zeroes too. 789 | #ifdef JSON_USE_CPPTL 790 | Value(const CppTL::ConstString& value); 791 | #endif 792 | Value(bool value); 793 | /// Deep copy. 794 | Value(const Value& other); 795 | #if JSON_HAS_RVALUE_REFERENCES 796 | /// Move constructor 797 | Value(Value&& other); 798 | #endif 799 | ~Value(); 800 | 801 | /// Deep copy, then swap(other). 802 | /// \note Over-write existing comments. To preserve comments, use #swapPayload(). 803 | Value& operator=(Value other); 804 | 805 | /// Swap everything. 806 | void swap(Value& other); 807 | /// Swap values but leave comments and source offsets in place. 808 | void swapPayload(Value& other); 809 | 810 | /// copy everything. 811 | void copy(const Value& other); 812 | /// copy values but leave comments and source offsets in place. 813 | void copyPayload(const Value& other); 814 | 815 | ValueType type() const; 816 | 817 | /// Compare payload only, not comments etc. 818 | bool operator<(const Value& other) const; 819 | bool operator<=(const Value& other) const; 820 | bool operator>=(const Value& other) const; 821 | bool operator>(const Value& other) const; 822 | bool operator==(const Value& other) const; 823 | bool operator!=(const Value& other) const; 824 | int compare(const Value& other) const; 825 | 826 | const char* asCString() const; ///< Embedded zeroes could cause you trouble! 827 | #if JSONCPP_USING_SECURE_MEMORY 828 | unsigned getCStringLength() const; //Allows you to understand the length of the CString 829 | #endif 830 | JSONCPP_STRING asString() const; ///< Embedded zeroes are possible. 831 | /** Get raw char* of string-value. 832 | * \return false if !string. (Seg-fault if str or end are NULL.) 833 | */ 834 | bool getString( 835 | char const** begin, char const** end) const; 836 | #ifdef JSON_USE_CPPTL 837 | CppTL::ConstString asConstString() const; 838 | #endif 839 | Int asInt() const; 840 | UInt asUInt() const; 841 | #if defined(JSON_HAS_INT64) 842 | Int64 asInt64() const; 843 | UInt64 asUInt64() const; 844 | #endif // if defined(JSON_HAS_INT64) 845 | LargestInt asLargestInt() const; 846 | LargestUInt asLargestUInt() const; 847 | float asFloat() const; 848 | double asDouble() const; 849 | bool asBool() const; 850 | 851 | bool isNull() const; 852 | bool isBool() const; 853 | bool isInt() const; 854 | bool isInt64() const; 855 | bool isUInt() const; 856 | bool isUInt64() const; 857 | bool isIntegral() const; 858 | bool isDouble() const; 859 | bool isNumeric() const; 860 | bool isString() const; 861 | bool isArray() const; 862 | bool isObject() const; 863 | 864 | bool isConvertibleTo(ValueType other) const; 865 | 866 | /// Number of values in array or object 867 | ArrayIndex size() const; 868 | 869 | /// \brief Return true if empty array, empty object, or null; 870 | /// otherwise, false. 871 | bool empty() const; 872 | 873 | /// Return !isNull() 874 | JSONCPP_OP_EXPLICIT operator bool() const; 875 | 876 | /// Remove all object members and array elements. 877 | /// \pre type() is arrayValue, objectValue, or nullValue 878 | /// \post type() is unchanged 879 | void clear(); 880 | 881 | /// Resize the array to size elements. 882 | /// New elements are initialized to null. 883 | /// May only be called on nullValue or arrayValue. 884 | /// \pre type() is arrayValue or nullValue 885 | /// \post type() is arrayValue 886 | void resize(ArrayIndex size); 887 | 888 | /// Access an array element (zero based index ). 889 | /// If the array contains less than index element, then null value are 890 | /// inserted 891 | /// in the array so that its size is index+1. 892 | /// (You may need to say 'value[0u]' to get your compiler to distinguish 893 | /// this from the operator[] which takes a string.) 894 | Value& operator[](ArrayIndex index); 895 | 896 | /// Access an array element (zero based index ). 897 | /// If the array contains less than index element, then null value are 898 | /// inserted 899 | /// in the array so that its size is index+1. 900 | /// (You may need to say 'value[0u]' to get your compiler to distinguish 901 | /// this from the operator[] which takes a string.) 902 | Value& operator[](int index); 903 | 904 | /// Access an array element (zero based index ) 905 | /// (You may need to say 'value[0u]' to get your compiler to distinguish 906 | /// this from the operator[] which takes a string.) 907 | const Value& operator[](ArrayIndex index) const; 908 | 909 | /// Access an array element (zero based index ) 910 | /// (You may need to say 'value[0u]' to get your compiler to distinguish 911 | /// this from the operator[] which takes a string.) 912 | const Value& operator[](int index) const; 913 | 914 | /// If the array contains at least index+1 elements, returns the element 915 | /// value, 916 | /// otherwise returns defaultValue. 917 | Value get(ArrayIndex index, const Value& defaultValue) const; 918 | /// Return true if index < size(). 919 | bool isValidIndex(ArrayIndex index) const; 920 | /// \brief Append value to array at the end. 921 | /// 922 | /// Equivalent to jsonvalue[jsonvalue.size()] = value; 923 | Value& append(const Value& value); 924 | 925 | #if JSON_HAS_RVALUE_REFERENCES 926 | Value& append(Value&& value); 927 | #endif 928 | 929 | /// Access an object value by name, create a null member if it does not exist. 930 | /// \note Because of our implementation, keys are limited to 2^30 -1 chars. 931 | /// Exceeding that will cause an exception. 932 | Value& operator[](const char* key); 933 | /// Access an object value by name, returns null if there is no member with 934 | /// that name. 935 | const Value& operator[](const char* key) const; 936 | /// Access an object value by name, create a null member if it does not exist. 937 | /// \param key may contain embedded nulls. 938 | Value& operator[](const JSONCPP_STRING& key); 939 | /// Access an object value by name, returns null if there is no member with 940 | /// that name. 941 | /// \param key may contain embedded nulls. 942 | const Value& operator[](const JSONCPP_STRING& key) const; 943 | /** \brief Access an object value by name, create a null member if it does not 944 | exist. 945 | 946 | * If the object has no entry for that name, then the member name used to store 947 | * the new entry is not duplicated. 948 | * Example of use: 949 | * \code 950 | * Json::Value object; 951 | * static const StaticString code("code"); 952 | * object[code] = 1234; 953 | * \endcode 954 | */ 955 | Value& operator[](const StaticString& key); 956 | #ifdef JSON_USE_CPPTL 957 | /// Access an object value by name, create a null member if it does not exist. 958 | Value& operator[](const CppTL::ConstString& key); 959 | /// Access an object value by name, returns null if there is no member with 960 | /// that name. 961 | const Value& operator[](const CppTL::ConstString& key) const; 962 | #endif 963 | /// Return the member named key if it exist, defaultValue otherwise. 964 | /// \note deep copy 965 | Value get(const char* key, const Value& defaultValue) const; 966 | /// Return the member named key if it exist, defaultValue otherwise. 967 | /// \note deep copy 968 | /// \note key may contain embedded nulls. 969 | Value get(const char* begin, const char* end, const Value& defaultValue) const; 970 | /// Return the member named key if it exist, defaultValue otherwise. 971 | /// \note deep copy 972 | /// \param key may contain embedded nulls. 973 | Value get(const JSONCPP_STRING& key, const Value& defaultValue) const; 974 | #ifdef JSON_USE_CPPTL 975 | /// Return the member named key if it exist, defaultValue otherwise. 976 | /// \note deep copy 977 | Value get(const CppTL::ConstString& key, const Value& defaultValue) const; 978 | #endif 979 | /// Most general and efficient version of isMember()const, get()const, 980 | /// and operator[]const 981 | /// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30 982 | Value const* find(char const* begin, char const* end) const; 983 | /// Most general and efficient version of object-mutators. 984 | /// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30 985 | /// \return non-zero, but JSON_ASSERT if this is neither object nor nullValue. 986 | Value const* demand(char const* begin, char const* end); 987 | /// \brief Remove and return the named member. 988 | /// 989 | /// Do nothing if it did not exist. 990 | /// \return the removed Value, or null. 991 | /// \pre type() is objectValue or nullValue 992 | /// \post type() is unchanged 993 | /// \deprecated 994 | void removeMember(const char* key); 995 | /// Same as removeMember(const char*) 996 | /// \param key may contain embedded nulls. 997 | /// \deprecated 998 | void removeMember(const JSONCPP_STRING& key); 999 | /// Same as removeMember(const char* begin, const char* end, Value* removed), 1000 | /// but 'key' is null-terminated. 1001 | bool removeMember(const char* key, Value* removed); 1002 | /** \brief Remove the named map member. 1003 | 1004 | Update 'removed' iff removed. 1005 | \param key may contain embedded nulls. 1006 | \return true iff removed (no exceptions) 1007 | */ 1008 | bool removeMember(JSONCPP_STRING const& key, Value* removed); 1009 | /// Same as removeMember(JSONCPP_STRING const& key, Value* removed) 1010 | bool removeMember(const char* begin, const char* end, Value* removed); 1011 | /** \brief Remove the indexed array element. 1012 | 1013 | O(n) expensive operations. 1014 | Update 'removed' iff removed. 1015 | \return true iff removed (no exceptions) 1016 | */ 1017 | bool removeIndex(ArrayIndex i, Value* removed); 1018 | 1019 | /// Return true if the object has a member named key. 1020 | /// \note 'key' must be null-terminated. 1021 | bool isMember(const char* key) const; 1022 | /// Return true if the object has a member named key. 1023 | /// \param key may contain embedded nulls. 1024 | bool isMember(const JSONCPP_STRING& key) const; 1025 | /// Same as isMember(JSONCPP_STRING const& key)const 1026 | bool isMember(const char* begin, const char* end) const; 1027 | #ifdef JSON_USE_CPPTL 1028 | /// Return true if the object has a member named key. 1029 | bool isMember(const CppTL::ConstString& key) const; 1030 | #endif 1031 | 1032 | /// \brief Return a list of the member names. 1033 | /// 1034 | /// If null, return an empty list. 1035 | /// \pre type() is objectValue or nullValue 1036 | /// \post if type() was nullValue, it remains nullValue 1037 | Members getMemberNames() const; 1038 | 1039 | //# ifdef JSON_USE_CPPTL 1040 | // EnumMemberNames enumMemberNames() const; 1041 | // EnumValues enumValues() const; 1042 | //# endif 1043 | 1044 | /// \deprecated Always pass len. 1045 | JSONCPP_DEPRECATED("Use setComment(JSONCPP_STRING const&) instead.") 1046 | void setComment(const char* comment, CommentPlacement placement); 1047 | /// Comments must be //... or /* ... */ 1048 | void setComment(const char* comment, size_t len, CommentPlacement placement); 1049 | /// Comments must be //... or /* ... */ 1050 | void setComment(const JSONCPP_STRING& comment, CommentPlacement placement); 1051 | bool hasComment(CommentPlacement placement) const; 1052 | /// Include delimiters and embedded newlines. 1053 | JSONCPP_STRING getComment(CommentPlacement placement) const; 1054 | 1055 | JSONCPP_STRING toStyledString() const; 1056 | 1057 | const_iterator begin() const; 1058 | const_iterator end() const; 1059 | 1060 | iterator begin(); 1061 | iterator end(); 1062 | 1063 | // Accessors for the [start, limit) range of bytes within the JSON text from 1064 | // which this value was parsed, if any. 1065 | void setOffsetStart(ptrdiff_t start); 1066 | void setOffsetLimit(ptrdiff_t limit); 1067 | ptrdiff_t getOffsetStart() const; 1068 | ptrdiff_t getOffsetLimit() const; 1069 | 1070 | private: 1071 | void initBasic(ValueType type, bool allocated = false); 1072 | void dupPayload(const Value& other); 1073 | void releasePayload(); 1074 | void dupMeta(const Value& other); 1075 | 1076 | Value& resolveReference(const char* key); 1077 | Value& resolveReference(const char* key, const char* end); 1078 | 1079 | struct CommentInfo { 1080 | CommentInfo(); 1081 | ~CommentInfo(); 1082 | 1083 | void setComment(const char* text, size_t len); 1084 | 1085 | char* comment_; 1086 | }; 1087 | 1088 | // struct MemberNamesTransform 1089 | //{ 1090 | // typedef const char *result_type; 1091 | // const char *operator()( const CZString &name ) const 1092 | // { 1093 | // return name.c_str(); 1094 | // } 1095 | //}; 1096 | 1097 | union ValueHolder { 1098 | LargestInt int_; 1099 | LargestUInt uint_; 1100 | double real_; 1101 | bool bool_; 1102 | char* string_; // actually ptr to unsigned, followed by str, unless !allocated_ 1103 | ObjectValues* map_; 1104 | } value_; 1105 | ValueType type_ : 8; 1106 | unsigned int allocated_ : 1; // Notes: if declared as bool, bitfield is useless. 1107 | // If not allocated_, string_ must be null-terminated. 1108 | CommentInfo* comments_; 1109 | 1110 | // [start, limit) byte offsets in the source JSON text from which this Value 1111 | // was extracted. 1112 | ptrdiff_t start_; 1113 | ptrdiff_t limit_; 1114 | }; 1115 | 1116 | /** \brief Experimental and untested: represents an element of the "path" to 1117 | * access a node. 1118 | */ 1119 | class JSON_API PathArgument { 1120 | public: 1121 | friend class Path; 1122 | 1123 | PathArgument(); 1124 | PathArgument(ArrayIndex index); 1125 | PathArgument(const char* key); 1126 | PathArgument(const JSONCPP_STRING& key); 1127 | 1128 | private: 1129 | enum Kind { 1130 | kindNone = 0, 1131 | kindIndex, 1132 | kindKey 1133 | }; 1134 | JSONCPP_STRING key_; 1135 | ArrayIndex index_; 1136 | Kind kind_; 1137 | }; 1138 | 1139 | /** \brief Experimental and untested: represents a "path" to access a node. 1140 | * 1141 | * Syntax: 1142 | * - "." => root node 1143 | * - ".[n]" => elements at index 'n' of root node (an array value) 1144 | * - ".name" => member named 'name' of root node (an object value) 1145 | * - ".name1.name2.name3" 1146 | * - ".[0][1][2].name1[3]" 1147 | * - ".%" => member name is provided as parameter 1148 | * - ".[%]" => index is provied as parameter 1149 | */ 1150 | class JSON_API Path { 1151 | public: 1152 | Path(const JSONCPP_STRING& path, 1153 | const PathArgument& a1 = PathArgument(), 1154 | const PathArgument& a2 = PathArgument(), 1155 | const PathArgument& a3 = PathArgument(), 1156 | const PathArgument& a4 = PathArgument(), 1157 | const PathArgument& a5 = PathArgument()); 1158 | 1159 | const Value& resolve(const Value& root) const; 1160 | Value resolve(const Value& root, const Value& defaultValue) const; 1161 | /// Creates the "path" to access the specified node and returns a reference on 1162 | /// the node. 1163 | Value& make(Value& root) const; 1164 | 1165 | private: 1166 | typedef std::vector InArgs; 1167 | typedef std::vector Args; 1168 | 1169 | void makePath(const JSONCPP_STRING& path, const InArgs& in); 1170 | void addPathInArg(const JSONCPP_STRING& path, 1171 | const InArgs& in, 1172 | InArgs::const_iterator& itInArg, 1173 | PathArgument::Kind kind); 1174 | void invalidPath(const JSONCPP_STRING& path, int location); 1175 | 1176 | Args args_; 1177 | }; 1178 | 1179 | /** \brief base class for Value iterators. 1180 | * 1181 | */ 1182 | class JSON_API ValueIteratorBase { 1183 | public: 1184 | typedef std::bidirectional_iterator_tag iterator_category; 1185 | typedef unsigned int size_t; 1186 | typedef int difference_type; 1187 | typedef ValueIteratorBase SelfType; 1188 | 1189 | bool operator==(const SelfType& other) const { return isEqual(other); } 1190 | 1191 | bool operator!=(const SelfType& other) const { return !isEqual(other); } 1192 | 1193 | difference_type operator-(const SelfType& other) const { 1194 | return other.computeDistance(*this); 1195 | } 1196 | 1197 | /// Return either the index or the member name of the referenced value as a 1198 | /// Value. 1199 | Value key() const; 1200 | 1201 | /// Return the index of the referenced Value, or -1 if it is not an arrayValue. 1202 | UInt index() const; 1203 | 1204 | /// Return the member name of the referenced Value, or "" if it is not an 1205 | /// objectValue. 1206 | /// \note Avoid `c_str()` on result, as embedded zeroes are possible. 1207 | JSONCPP_STRING name() const; 1208 | 1209 | /// Return the member name of the referenced Value. "" if it is not an 1210 | /// objectValue. 1211 | /// \deprecated This cannot be used for UTF-8 strings, since there can be embedded nulls. 1212 | JSONCPP_DEPRECATED("Use `key = name();` instead.") 1213 | char const* memberName() const; 1214 | /// Return the member name of the referenced Value, or NULL if it is not an 1215 | /// objectValue. 1216 | /// \note Better version than memberName(). Allows embedded nulls. 1217 | char const* memberName(char const** end) const; 1218 | 1219 | protected: 1220 | Value& deref() const; 1221 | 1222 | void increment(); 1223 | 1224 | void decrement(); 1225 | 1226 | difference_type computeDistance(const SelfType& other) const; 1227 | 1228 | bool isEqual(const SelfType& other) const; 1229 | 1230 | void copy(const SelfType& other); 1231 | 1232 | private: 1233 | Value::ObjectValues::iterator current_; 1234 | // Indicates that iterator is for a null value. 1235 | bool isNull_; 1236 | 1237 | public: 1238 | // For some reason, BORLAND needs these at the end, rather 1239 | // than earlier. No idea why. 1240 | ValueIteratorBase(); 1241 | explicit ValueIteratorBase(const Value::ObjectValues::iterator& current); 1242 | }; 1243 | 1244 | /** \brief const iterator for object and array value. 1245 | * 1246 | */ 1247 | class JSON_API ValueConstIterator : public ValueIteratorBase { 1248 | friend class Value; 1249 | 1250 | public: 1251 | typedef const Value value_type; 1252 | //typedef unsigned int size_t; 1253 | //typedef int difference_type; 1254 | typedef const Value& reference; 1255 | typedef const Value* pointer; 1256 | typedef ValueConstIterator SelfType; 1257 | 1258 | ValueConstIterator(); 1259 | ValueConstIterator(ValueIterator const& other); 1260 | 1261 | private: 1262 | /*! \internal Use by Value to create an iterator. 1263 | */ 1264 | explicit ValueConstIterator(const Value::ObjectValues::iterator& current); 1265 | public: 1266 | SelfType& operator=(const ValueIteratorBase& other); 1267 | 1268 | SelfType operator++(int) { 1269 | SelfType temp(*this); 1270 | ++*this; 1271 | return temp; 1272 | } 1273 | 1274 | SelfType operator--(int) { 1275 | SelfType temp(*this); 1276 | --*this; 1277 | return temp; 1278 | } 1279 | 1280 | SelfType& operator--() { 1281 | decrement(); 1282 | return *this; 1283 | } 1284 | 1285 | SelfType& operator++() { 1286 | increment(); 1287 | return *this; 1288 | } 1289 | 1290 | reference operator*() const { return deref(); } 1291 | 1292 | pointer operator->() const { return &deref(); } 1293 | }; 1294 | 1295 | /** \brief Iterator for object and array value. 1296 | */ 1297 | class JSON_API ValueIterator : public ValueIteratorBase { 1298 | friend class Value; 1299 | 1300 | public: 1301 | typedef Value value_type; 1302 | typedef unsigned int size_t; 1303 | typedef int difference_type; 1304 | typedef Value& reference; 1305 | typedef Value* pointer; 1306 | typedef ValueIterator SelfType; 1307 | 1308 | ValueIterator(); 1309 | explicit ValueIterator(const ValueConstIterator& other); 1310 | ValueIterator(const ValueIterator& other); 1311 | 1312 | private: 1313 | /*! \internal Use by Value to create an iterator. 1314 | */ 1315 | explicit ValueIterator(const Value::ObjectValues::iterator& current); 1316 | public: 1317 | SelfType& operator=(const SelfType& other); 1318 | 1319 | SelfType operator++(int) { 1320 | SelfType temp(*this); 1321 | ++*this; 1322 | return temp; 1323 | } 1324 | 1325 | SelfType operator--(int) { 1326 | SelfType temp(*this); 1327 | --*this; 1328 | return temp; 1329 | } 1330 | 1331 | SelfType& operator--() { 1332 | decrement(); 1333 | return *this; 1334 | } 1335 | 1336 | SelfType& operator++() { 1337 | increment(); 1338 | return *this; 1339 | } 1340 | 1341 | reference operator*() const { return deref(); } 1342 | 1343 | pointer operator->() const { return &deref(); } 1344 | }; 1345 | 1346 | inline void swap(Value& a, Value& b) { a.swap(b); } 1347 | 1348 | } // namespace Json 1349 | 1350 | #pragma pack(pop) 1351 | 1352 | #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 1353 | #pragma warning(pop) 1354 | #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 1355 | 1356 | #endif // CPPTL_JSON_H_INCLUDED 1357 | 1358 | // ////////////////////////////////////////////////////////////////////// 1359 | // End of content of file: include/json/value.h 1360 | // ////////////////////////////////////////////////////////////////////// 1361 | 1362 | 1363 | 1364 | 1365 | 1366 | 1367 | // ////////////////////////////////////////////////////////////////////// 1368 | // Beginning of content of file: include/json/reader.h 1369 | // ////////////////////////////////////////////////////////////////////// 1370 | 1371 | // Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors 1372 | // Distributed under MIT license, or public domain if desired and 1373 | // recognized in your jurisdiction. 1374 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 1375 | 1376 | #ifndef CPPTL_JSON_READER_H_INCLUDED 1377 | #define CPPTL_JSON_READER_H_INCLUDED 1378 | 1379 | #if !defined(JSON_IS_AMALGAMATION) 1380 | #include "features.h" 1381 | #include "value.h" 1382 | #endif // if !defined(JSON_IS_AMALGAMATION) 1383 | #include 1384 | #include 1385 | #include 1386 | #include 1387 | #include 1388 | 1389 | // Disable warning C4251: : needs to have dll-interface to 1390 | // be used by... 1391 | #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 1392 | #pragma warning(push) 1393 | #pragma warning(disable : 4251) 1394 | #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 1395 | 1396 | #pragma pack(push, 8) 1397 | 1398 | namespace Json { 1399 | 1400 | /** \brief Unserialize a JSON document into a 1401 | *Value. 1402 | * 1403 | * \deprecated Use CharReader and CharReaderBuilder. 1404 | */ 1405 | class JSON_API Reader { 1406 | public: 1407 | typedef char Char; 1408 | typedef const Char* Location; 1409 | 1410 | /** \brief An error tagged with where in the JSON text it was encountered. 1411 | * 1412 | * The offsets give the [start, limit) range of bytes within the text. Note 1413 | * that this is bytes, not codepoints. 1414 | * 1415 | */ 1416 | struct StructuredError { 1417 | ptrdiff_t offset_start; 1418 | ptrdiff_t offset_limit; 1419 | JSONCPP_STRING message; 1420 | }; 1421 | 1422 | /** \brief Constructs a Reader allowing all features 1423 | * for parsing. 1424 | */ 1425 | JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead") 1426 | Reader(); 1427 | 1428 | /** \brief Constructs a Reader allowing the specified feature set 1429 | * for parsing. 1430 | */ 1431 | JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead") 1432 | Reader(const Features& features); 1433 | 1434 | /** \brief Read a Value from a JSON 1435 | * document. 1436 | * \param document UTF-8 encoded string containing the document to read. 1437 | * \param root [out] Contains the root value of the document if it was 1438 | * successfully parsed. 1439 | * \param collectComments \c true to collect comment and allow writing them 1440 | * back during 1441 | * serialization, \c false to discard comments. 1442 | * This parameter is ignored if 1443 | * Features::allowComments_ 1444 | * is \c false. 1445 | * \return \c true if the document was successfully parsed, \c false if an 1446 | * error occurred. 1447 | */ 1448 | bool 1449 | parse(const std::string& document, Value& root, bool collectComments = true); 1450 | 1451 | /** \brief Read a Value from a JSON 1452 | document. 1453 | * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the 1454 | document to read. 1455 | * \param endDoc Pointer on the end of the UTF-8 encoded string of the 1456 | document to read. 1457 | * Must be >= beginDoc. 1458 | * \param root [out] Contains the root value of the document if it was 1459 | * successfully parsed. 1460 | * \param collectComments \c true to collect comment and allow writing them 1461 | back during 1462 | * serialization, \c false to discard comments. 1463 | * This parameter is ignored if 1464 | Features::allowComments_ 1465 | * is \c false. 1466 | * \return \c true if the document was successfully parsed, \c false if an 1467 | error occurred. 1468 | */ 1469 | bool parse(const char* beginDoc, 1470 | const char* endDoc, 1471 | Value& root, 1472 | bool collectComments = true); 1473 | 1474 | /// \brief Parse from input stream. 1475 | /// \see Json::operator>>(std::istream&, Json::Value&). 1476 | bool parse(JSONCPP_ISTREAM& is, Value& root, bool collectComments = true); 1477 | 1478 | /** \brief Returns a user friendly string that list errors in the parsed 1479 | * document. 1480 | * \return Formatted error message with the list of errors with their location 1481 | * in 1482 | * the parsed document. An empty string is returned if no error 1483 | * occurred 1484 | * during parsing. 1485 | * \deprecated Use getFormattedErrorMessages() instead (typo fix). 1486 | */ 1487 | JSONCPP_DEPRECATED("Use getFormattedErrorMessages() instead.") 1488 | JSONCPP_STRING getFormatedErrorMessages() const; 1489 | 1490 | /** \brief Returns a user friendly string that list errors in the parsed 1491 | * document. 1492 | * \return Formatted error message with the list of errors with their location 1493 | * in 1494 | * the parsed document. An empty string is returned if no error 1495 | * occurred 1496 | * during parsing. 1497 | */ 1498 | JSONCPP_STRING getFormattedErrorMessages() const; 1499 | 1500 | /** \brief Returns a vector of structured erros encounted while parsing. 1501 | * \return A (possibly empty) vector of StructuredError objects. Currently 1502 | * only one error can be returned, but the caller should tolerate 1503 | * multiple 1504 | * errors. This can occur if the parser recovers from a non-fatal 1505 | * parse error and then encounters additional errors. 1506 | */ 1507 | std::vector getStructuredErrors() const; 1508 | 1509 | /** \brief Add a semantic error message. 1510 | * \param value JSON Value location associated with the error 1511 | * \param message The error message. 1512 | * \return \c true if the error was successfully added, \c false if the 1513 | * Value offset exceeds the document size. 1514 | */ 1515 | bool pushError(const Value& value, const JSONCPP_STRING& message); 1516 | 1517 | /** \brief Add a semantic error message with extra context. 1518 | * \param value JSON Value location associated with the error 1519 | * \param message The error message. 1520 | * \param extra Additional JSON Value location to contextualize the error 1521 | * \return \c true if the error was successfully added, \c false if either 1522 | * Value offset exceeds the document size. 1523 | */ 1524 | bool pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra); 1525 | 1526 | /** \brief Return whether there are any errors. 1527 | * \return \c true if there are no errors to report \c false if 1528 | * errors have occurred. 1529 | */ 1530 | bool good() const; 1531 | 1532 | private: 1533 | enum TokenType { 1534 | tokenEndOfStream = 0, 1535 | tokenObjectBegin, 1536 | tokenObjectEnd, 1537 | tokenArrayBegin, 1538 | tokenArrayEnd, 1539 | tokenString, 1540 | tokenNumber, 1541 | tokenTrue, 1542 | tokenFalse, 1543 | tokenNull, 1544 | tokenArraySeparator, 1545 | tokenMemberSeparator, 1546 | tokenComment, 1547 | tokenError 1548 | }; 1549 | 1550 | class Token { 1551 | public: 1552 | TokenType type_; 1553 | Location start_; 1554 | Location end_; 1555 | }; 1556 | 1557 | class ErrorInfo { 1558 | public: 1559 | Token token_; 1560 | JSONCPP_STRING message_; 1561 | Location extra_; 1562 | }; 1563 | 1564 | typedef std::deque Errors; 1565 | 1566 | bool readToken(Token& token); 1567 | void skipSpaces(); 1568 | bool match(Location pattern, int patternLength); 1569 | bool readComment(); 1570 | bool readCStyleComment(); 1571 | bool readCppStyleComment(); 1572 | bool readString(); 1573 | void readNumber(); 1574 | bool readValue(); 1575 | bool readObject(Token& token); 1576 | bool readArray(Token& token); 1577 | bool decodeNumber(Token& token); 1578 | bool decodeNumber(Token& token, Value& decoded); 1579 | bool decodeString(Token& token); 1580 | bool decodeString(Token& token, JSONCPP_STRING& decoded); 1581 | bool decodeDouble(Token& token); 1582 | bool decodeDouble(Token& token, Value& decoded); 1583 | bool decodeUnicodeCodePoint(Token& token, 1584 | Location& current, 1585 | Location end, 1586 | unsigned int& unicode); 1587 | bool decodeUnicodeEscapeSequence(Token& token, 1588 | Location& current, 1589 | Location end, 1590 | unsigned int& unicode); 1591 | bool addError(const JSONCPP_STRING& message, Token& token, Location extra = 0); 1592 | bool recoverFromError(TokenType skipUntilToken); 1593 | bool addErrorAndRecover(const JSONCPP_STRING& message, 1594 | Token& token, 1595 | TokenType skipUntilToken); 1596 | void skipUntilSpace(); 1597 | Value& currentValue(); 1598 | Char getNextChar(); 1599 | void 1600 | getLocationLineAndColumn(Location location, int& line, int& column) const; 1601 | JSONCPP_STRING getLocationLineAndColumn(Location location) const; 1602 | void addComment(Location begin, Location end, CommentPlacement placement); 1603 | void skipCommentTokens(Token& token); 1604 | 1605 | static bool containsNewLine(Location begin, Location end); 1606 | static JSONCPP_STRING normalizeEOL(Location begin, Location end); 1607 | 1608 | typedef std::stack Nodes; 1609 | Nodes nodes_; 1610 | Errors errors_; 1611 | JSONCPP_STRING document_; 1612 | Location begin_; 1613 | Location end_; 1614 | Location current_; 1615 | Location lastValueEnd_; 1616 | Value* lastValue_; 1617 | JSONCPP_STRING commentsBefore_; 1618 | Features features_; 1619 | bool collectComments_; 1620 | }; // Reader 1621 | 1622 | /** Interface for reading JSON from a char array. 1623 | */ 1624 | class JSON_API CharReader { 1625 | public: 1626 | virtual ~CharReader() {} 1627 | /** \brief Read a Value from a JSON 1628 | document. 1629 | * The document must be a UTF-8 encoded string containing the document to read. 1630 | * 1631 | * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the 1632 | document to read. 1633 | * \param endDoc Pointer on the end of the UTF-8 encoded string of the 1634 | document to read. 1635 | * Must be >= beginDoc. 1636 | * \param root [out] Contains the root value of the document if it was 1637 | * successfully parsed. 1638 | * \param errs [out] Formatted error messages (if not NULL) 1639 | * a user friendly string that lists errors in the parsed 1640 | * document. 1641 | * \return \c true if the document was successfully parsed, \c false if an 1642 | error occurred. 1643 | */ 1644 | virtual bool parse( 1645 | char const* beginDoc, char const* endDoc, 1646 | Value* root, JSONCPP_STRING* errs) = 0; 1647 | 1648 | class JSON_API Factory { 1649 | public: 1650 | virtual ~Factory() {} 1651 | /** \brief Allocate a CharReader via operator new(). 1652 | * \throw std::exception if something goes wrong (e.g. invalid settings) 1653 | */ 1654 | virtual CharReader* newCharReader() const = 0; 1655 | }; // Factory 1656 | }; // CharReader 1657 | 1658 | /** \brief Build a CharReader implementation. 1659 | 1660 | Usage: 1661 | \code 1662 | using namespace Json; 1663 | CharReaderBuilder builder; 1664 | builder["collectComments"] = false; 1665 | Value value; 1666 | JSONCPP_STRING errs; 1667 | bool ok = parseFromStream(builder, std::cin, &value, &errs); 1668 | \endcode 1669 | */ 1670 | class JSON_API CharReaderBuilder : public CharReader::Factory { 1671 | public: 1672 | // Note: We use a Json::Value so that we can add data-members to this class 1673 | // without a major version bump. 1674 | /** Configuration of this builder. 1675 | These are case-sensitive. 1676 | Available settings (case-sensitive): 1677 | - `"collectComments": false or true` 1678 | - true to collect comment and allow writing them 1679 | back during serialization, false to discard comments. 1680 | This parameter is ignored if allowComments is false. 1681 | - `"allowComments": false or true` 1682 | - true if comments are allowed. 1683 | - `"strictRoot": false or true` 1684 | - true if root must be either an array or an object value 1685 | - `"allowDroppedNullPlaceholders": false or true` 1686 | - true if dropped null placeholders are allowed. (See StreamWriterBuilder.) 1687 | - `"allowNumericKeys": false or true` 1688 | - true if numeric object keys are allowed. 1689 | - `"allowSingleQuotes": false or true` 1690 | - true if '' are allowed for strings (both keys and values) 1691 | - `"stackLimit": integer` 1692 | - Exceeding stackLimit (recursive depth of `readValue()`) will 1693 | cause an exception. 1694 | - This is a security issue (seg-faults caused by deeply nested JSON), 1695 | so the default is low. 1696 | - `"failIfExtra": false or true` 1697 | - If true, `parse()` returns false when extra non-whitespace trails 1698 | the JSON value in the input string. 1699 | - `"rejectDupKeys": false or true` 1700 | - If true, `parse()` returns false when a key is duplicated within an object. 1701 | - `"allowSpecialFloats": false or true` 1702 | - If true, special float values (NaNs and infinities) are allowed 1703 | and their values are lossfree restorable. 1704 | 1705 | You can examine 'settings_` yourself 1706 | to see the defaults. You can also write and read them just like any 1707 | JSON Value. 1708 | \sa setDefaults() 1709 | */ 1710 | Json::Value settings_; 1711 | 1712 | CharReaderBuilder(); 1713 | ~CharReaderBuilder() JSONCPP_OVERRIDE; 1714 | 1715 | CharReader* newCharReader() const JSONCPP_OVERRIDE; 1716 | 1717 | /** \return true if 'settings' are legal and consistent; 1718 | * otherwise, indicate bad settings via 'invalid'. 1719 | */ 1720 | bool validate(Json::Value* invalid) const; 1721 | 1722 | /** A simple way to update a specific setting. 1723 | */ 1724 | Value& operator[](JSONCPP_STRING key); 1725 | 1726 | /** Called by ctor, but you can use this to reset settings_. 1727 | * \pre 'settings' != NULL (but Json::null is fine) 1728 | * \remark Defaults: 1729 | * \snippet src/lib_json/json_reader.cpp CharReaderBuilderDefaults 1730 | */ 1731 | static void setDefaults(Json::Value* settings); 1732 | /** Same as old Features::strictMode(). 1733 | * \pre 'settings' != NULL (but Json::null is fine) 1734 | * \remark Defaults: 1735 | * \snippet src/lib_json/json_reader.cpp CharReaderBuilderStrictMode 1736 | */ 1737 | static void strictMode(Json::Value* settings); 1738 | }; 1739 | 1740 | /** Consume entire stream and use its begin/end. 1741 | * Someday we might have a real StreamReader, but for now this 1742 | * is convenient. 1743 | */ 1744 | bool JSON_API parseFromStream( 1745 | CharReader::Factory const&, 1746 | JSONCPP_ISTREAM&, 1747 | Value* root, std::string* errs); 1748 | 1749 | /** \brief Read from 'sin' into 'root'. 1750 | 1751 | Always keep comments from the input JSON. 1752 | 1753 | This can be used to read a file into a particular sub-object. 1754 | For example: 1755 | \code 1756 | Json::Value root; 1757 | cin >> root["dir"]["file"]; 1758 | cout << root; 1759 | \endcode 1760 | Result: 1761 | \verbatim 1762 | { 1763 | "dir": { 1764 | "file": { 1765 | // The input stream JSON would be nested here. 1766 | } 1767 | } 1768 | } 1769 | \endverbatim 1770 | \throw std::exception on parse error. 1771 | \see Json::operator<<() 1772 | */ 1773 | JSON_API JSONCPP_ISTREAM& operator>>(JSONCPP_ISTREAM&, Value&); 1774 | 1775 | } // namespace Json 1776 | 1777 | #pragma pack(pop) 1778 | 1779 | #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 1780 | #pragma warning(pop) 1781 | #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 1782 | 1783 | #endif // CPPTL_JSON_READER_H_INCLUDED 1784 | 1785 | // ////////////////////////////////////////////////////////////////////// 1786 | // End of content of file: include/json/reader.h 1787 | // ////////////////////////////////////////////////////////////////////// 1788 | 1789 | 1790 | 1791 | 1792 | 1793 | 1794 | // ////////////////////////////////////////////////////////////////////// 1795 | // Beginning of content of file: include/json/writer.h 1796 | // ////////////////////////////////////////////////////////////////////// 1797 | 1798 | // Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors 1799 | // Distributed under MIT license, or public domain if desired and 1800 | // recognized in your jurisdiction. 1801 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 1802 | 1803 | #ifndef JSON_WRITER_H_INCLUDED 1804 | #define JSON_WRITER_H_INCLUDED 1805 | 1806 | #if !defined(JSON_IS_AMALGAMATION) 1807 | #include "value.h" 1808 | #endif // if !defined(JSON_IS_AMALGAMATION) 1809 | #include 1810 | #include 1811 | #include 1812 | 1813 | // Disable warning C4251: : needs to have dll-interface to 1814 | // be used by... 1815 | #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) && defined(_MSC_VER) 1816 | #pragma warning(push) 1817 | #pragma warning(disable : 4251) 1818 | #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 1819 | 1820 | #pragma pack(push, 8) 1821 | 1822 | namespace Json { 1823 | 1824 | class Value; 1825 | 1826 | /** 1827 | 1828 | Usage: 1829 | \code 1830 | using namespace Json; 1831 | void writeToStdout(StreamWriter::Factory const& factory, Value const& value) { 1832 | std::unique_ptr const writer( 1833 | factory.newStreamWriter()); 1834 | writer->write(value, &std::cout); 1835 | std::cout << std::endl; // add lf and flush 1836 | } 1837 | \endcode 1838 | */ 1839 | class JSON_API StreamWriter { 1840 | protected: 1841 | JSONCPP_OSTREAM* sout_; // not owned; will not delete 1842 | public: 1843 | StreamWriter(); 1844 | virtual ~StreamWriter(); 1845 | /** Write Value into document as configured in sub-class. 1846 | Do not take ownership of sout, but maintain a reference during function. 1847 | \pre sout != NULL 1848 | \return zero on success (For now, we always return zero, so check the stream instead.) 1849 | \throw std::exception possibly, depending on configuration 1850 | */ 1851 | virtual int write(Value const& root, JSONCPP_OSTREAM* sout) = 0; 1852 | 1853 | /** \brief A simple abstract factory. 1854 | */ 1855 | class JSON_API Factory { 1856 | public: 1857 | virtual ~Factory(); 1858 | /** \brief Allocate a CharReader via operator new(). 1859 | * \throw std::exception if something goes wrong (e.g. invalid settings) 1860 | */ 1861 | virtual StreamWriter* newStreamWriter() const = 0; 1862 | }; // Factory 1863 | }; // StreamWriter 1864 | 1865 | /** \brief Write into stringstream, then return string, for convenience. 1866 | * A StreamWriter will be created from the factory, used, and then deleted. 1867 | */ 1868 | JSONCPP_STRING JSON_API writeString(StreamWriter::Factory const& factory, Value const& root); 1869 | 1870 | 1871 | /** \brief Build a StreamWriter implementation. 1872 | 1873 | Usage: 1874 | \code 1875 | using namespace Json; 1876 | Value value = ...; 1877 | StreamWriterBuilder builder; 1878 | builder["commentStyle"] = "None"; 1879 | builder["indentation"] = " "; // or whatever you like 1880 | std::unique_ptr writer( 1881 | builder.newStreamWriter()); 1882 | writer->write(value, &std::cout); 1883 | std::cout << std::endl; // add lf and flush 1884 | \endcode 1885 | */ 1886 | class JSON_API StreamWriterBuilder : public StreamWriter::Factory { 1887 | public: 1888 | // Note: We use a Json::Value so that we can add data-members to this class 1889 | // without a major version bump. 1890 | /** Configuration of this builder. 1891 | Available settings (case-sensitive): 1892 | - "commentStyle": "None" or "All" 1893 | - "indentation": "". 1894 | - Setting this to an empty string also omits newline characters. 1895 | - "enableYAMLCompatibility": false or true 1896 | - slightly change the whitespace around colons 1897 | - "dropNullPlaceholders": false or true 1898 | - Drop the "null" string from the writer's output for nullValues. 1899 | Strictly speaking, this is not valid JSON. But when the output is being 1900 | fed to a browser's JavaScript, it makes for smaller output and the 1901 | browser can handle the output just fine. 1902 | - "useSpecialFloats": false or true 1903 | - If true, outputs non-finite floating point values in the following way: 1904 | NaN values as "NaN", positive infinity as "Infinity", and negative infinity 1905 | as "-Infinity". 1906 | - "precision": int 1907 | - Number of precision digits for formatting of real values. 1908 | - "precisionType": "significant"(default) or "decimal" 1909 | - Type of precision for formatting of real values. 1910 | 1911 | You can examine 'settings_` yourself 1912 | to see the defaults. You can also write and read them just like any 1913 | JSON Value. 1914 | \sa setDefaults() 1915 | */ 1916 | Json::Value settings_; 1917 | 1918 | StreamWriterBuilder(); 1919 | ~StreamWriterBuilder() JSONCPP_OVERRIDE; 1920 | 1921 | /** 1922 | * \throw std::exception if something goes wrong (e.g. invalid settings) 1923 | */ 1924 | StreamWriter* newStreamWriter() const JSONCPP_OVERRIDE; 1925 | 1926 | /** \return true if 'settings' are legal and consistent; 1927 | * otherwise, indicate bad settings via 'invalid'. 1928 | */ 1929 | bool validate(Json::Value* invalid) const; 1930 | /** A simple way to update a specific setting. 1931 | */ 1932 | Value& operator[](JSONCPP_STRING key); 1933 | 1934 | /** Called by ctor, but you can use this to reset settings_. 1935 | * \pre 'settings' != NULL (but Json::null is fine) 1936 | * \remark Defaults: 1937 | * \snippet src/lib_json/json_writer.cpp StreamWriterBuilderDefaults 1938 | */ 1939 | static void setDefaults(Json::Value* settings); 1940 | }; 1941 | 1942 | /** \brief Abstract class for writers. 1943 | * \deprecated Use StreamWriter. (And really, this is an implementation detail.) 1944 | */ 1945 | class JSONCPP_DEPRECATED("Use StreamWriter instead") JSON_API Writer { 1946 | public: 1947 | virtual ~Writer(); 1948 | 1949 | virtual JSONCPP_STRING write(const Value& root) = 0; 1950 | }; 1951 | 1952 | /** \brief Outputs a Value in JSON format 1953 | *without formatting (not human friendly). 1954 | * 1955 | * The JSON document is written in a single line. It is not intended for 'human' 1956 | *consumption, 1957 | * but may be useful to support feature such as RPC where bandwidth is limited. 1958 | * \sa Reader, Value 1959 | * \deprecated Use StreamWriterBuilder. 1960 | */ 1961 | #if defined(_MSC_VER) 1962 | #pragma warning(push) 1963 | #pragma warning(disable:4996) // Deriving from deprecated class 1964 | #endif 1965 | class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API FastWriter : public Writer { 1966 | public: 1967 | FastWriter(); 1968 | ~FastWriter() JSONCPP_OVERRIDE {} 1969 | 1970 | void enableYAMLCompatibility(); 1971 | 1972 | /** \brief Drop the "null" string from the writer's output for nullValues. 1973 | * Strictly speaking, this is not valid JSON. But when the output is being 1974 | * fed to a browser's JavaScript, it makes for smaller output and the 1975 | * browser can handle the output just fine. 1976 | */ 1977 | void dropNullPlaceholders(); 1978 | 1979 | void omitEndingLineFeed(); 1980 | 1981 | public: // overridden from Writer 1982 | JSONCPP_STRING write(const Value& root) JSONCPP_OVERRIDE; 1983 | 1984 | private: 1985 | void writeValue(const Value& value); 1986 | 1987 | JSONCPP_STRING document_; 1988 | bool yamlCompatibilityEnabled_; 1989 | bool dropNullPlaceholders_; 1990 | bool omitEndingLineFeed_; 1991 | }; 1992 | #if defined(_MSC_VER) 1993 | #pragma warning(pop) 1994 | #endif 1995 | 1996 | /** \brief Writes a Value in JSON format in a 1997 | *human friendly way. 1998 | * 1999 | * The rules for line break and indent are as follow: 2000 | * - Object value: 2001 | * - if empty then print {} without indent and line break 2002 | * - if not empty the print '{', line break & indent, print one value per 2003 | *line 2004 | * and then unindent and line break and print '}'. 2005 | * - Array value: 2006 | * - if empty then print [] without indent and line break 2007 | * - if the array contains no object value, empty array or some other value 2008 | *types, 2009 | * and all the values fit on one lines, then print the array on a single 2010 | *line. 2011 | * - otherwise, it the values do not fit on one line, or the array contains 2012 | * object or non empty array, then print one value per line. 2013 | * 2014 | * If the Value have comments then they are outputed according to their 2015 | *#CommentPlacement. 2016 | * 2017 | * \sa Reader, Value, Value::setComment() 2018 | * \deprecated Use StreamWriterBuilder. 2019 | */ 2020 | #if defined(_MSC_VER) 2021 | #pragma warning(push) 2022 | #pragma warning(disable:4996) // Deriving from deprecated class 2023 | #endif 2024 | class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API StyledWriter : public Writer { 2025 | public: 2026 | StyledWriter(); 2027 | ~StyledWriter() JSONCPP_OVERRIDE {} 2028 | 2029 | public: // overridden from Writer 2030 | /** \brief Serialize a Value in JSON format. 2031 | * \param root Value to serialize. 2032 | * \return String containing the JSON document that represents the root value. 2033 | */ 2034 | JSONCPP_STRING write(const Value& root) JSONCPP_OVERRIDE; 2035 | 2036 | private: 2037 | void writeValue(const Value& value); 2038 | void writeArrayValue(const Value& value); 2039 | bool isMultilineArray(const Value& value); 2040 | void pushValue(const JSONCPP_STRING& value); 2041 | void writeIndent(); 2042 | void writeWithIndent(const JSONCPP_STRING& value); 2043 | void indent(); 2044 | void unindent(); 2045 | void writeCommentBeforeValue(const Value& root); 2046 | void writeCommentAfterValueOnSameLine(const Value& root); 2047 | bool hasCommentForValue(const Value& value); 2048 | static JSONCPP_STRING normalizeEOL(const JSONCPP_STRING& text); 2049 | 2050 | typedef std::vector ChildValues; 2051 | 2052 | ChildValues childValues_; 2053 | JSONCPP_STRING document_; 2054 | JSONCPP_STRING indentString_; 2055 | unsigned int rightMargin_; 2056 | unsigned int indentSize_; 2057 | bool addChildValues_; 2058 | }; 2059 | #if defined(_MSC_VER) 2060 | #pragma warning(pop) 2061 | #endif 2062 | 2063 | /** \brief Writes a Value in JSON format in a 2064 | human friendly way, 2065 | to a stream rather than to a string. 2066 | * 2067 | * The rules for line break and indent are as follow: 2068 | * - Object value: 2069 | * - if empty then print {} without indent and line break 2070 | * - if not empty the print '{', line break & indent, print one value per 2071 | line 2072 | * and then unindent and line break and print '}'. 2073 | * - Array value: 2074 | * - if empty then print [] without indent and line break 2075 | * - if the array contains no object value, empty array or some other value 2076 | types, 2077 | * and all the values fit on one lines, then print the array on a single 2078 | line. 2079 | * - otherwise, it the values do not fit on one line, or the array contains 2080 | * object or non empty array, then print one value per line. 2081 | * 2082 | * If the Value have comments then they are outputed according to their 2083 | #CommentPlacement. 2084 | * 2085 | * \sa Reader, Value, Value::setComment() 2086 | * \deprecated Use StreamWriterBuilder. 2087 | */ 2088 | #if defined(_MSC_VER) 2089 | #pragma warning(push) 2090 | #pragma warning(disable:4996) // Deriving from deprecated class 2091 | #endif 2092 | class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API StyledStreamWriter { 2093 | public: 2094 | /** 2095 | * \param indentation Each level will be indented by this amount extra. 2096 | */ 2097 | StyledStreamWriter(JSONCPP_STRING indentation = "\t"); 2098 | ~StyledStreamWriter() {} 2099 | 2100 | public: 2101 | /** \brief Serialize a Value in JSON format. 2102 | * \param out Stream to write to. (Can be ostringstream, e.g.) 2103 | * \param root Value to serialize. 2104 | * \note There is no point in deriving from Writer, since write() should not 2105 | * return a value. 2106 | */ 2107 | void write(JSONCPP_OSTREAM& out, const Value& root); 2108 | 2109 | private: 2110 | void writeValue(const Value& value); 2111 | void writeArrayValue(const Value& value); 2112 | bool isMultilineArray(const Value& value); 2113 | void pushValue(const JSONCPP_STRING& value); 2114 | void writeIndent(); 2115 | void writeWithIndent(const JSONCPP_STRING& value); 2116 | void indent(); 2117 | void unindent(); 2118 | void writeCommentBeforeValue(const Value& root); 2119 | void writeCommentAfterValueOnSameLine(const Value& root); 2120 | bool hasCommentForValue(const Value& value); 2121 | static JSONCPP_STRING normalizeEOL(const JSONCPP_STRING& text); 2122 | 2123 | typedef std::vector ChildValues; 2124 | 2125 | ChildValues childValues_; 2126 | JSONCPP_OSTREAM* document_; 2127 | JSONCPP_STRING indentString_; 2128 | unsigned int rightMargin_; 2129 | JSONCPP_STRING indentation_; 2130 | bool addChildValues_ : 1; 2131 | bool indented_ : 1; 2132 | }; 2133 | #if defined(_MSC_VER) 2134 | #pragma warning(pop) 2135 | #endif 2136 | 2137 | #if defined(JSON_HAS_INT64) 2138 | JSONCPP_STRING JSON_API valueToString(Int value); 2139 | JSONCPP_STRING JSON_API valueToString(UInt value); 2140 | #endif // if defined(JSON_HAS_INT64) 2141 | JSONCPP_STRING JSON_API valueToString(LargestInt value); 2142 | JSONCPP_STRING JSON_API valueToString(LargestUInt value); 2143 | JSONCPP_STRING JSON_API valueToString(double value, unsigned int precision = Value::defaultRealPrecision, 2144 | PrecisionType precisionType = PrecisionType::significantDigits); 2145 | JSONCPP_STRING JSON_API valueToString(bool value); 2146 | JSONCPP_STRING JSON_API valueToQuotedString(const char* value); 2147 | 2148 | /// \brief Output using the StyledStreamWriter. 2149 | /// \see Json::operator>>() 2150 | JSON_API JSONCPP_OSTREAM& operator<<(JSONCPP_OSTREAM&, const Value& root); 2151 | 2152 | } // namespace Json 2153 | 2154 | #pragma pack(pop) 2155 | 2156 | #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 2157 | #pragma warning(pop) 2158 | #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 2159 | 2160 | #endif // JSON_WRITER_H_INCLUDED 2161 | 2162 | // ////////////////////////////////////////////////////////////////////// 2163 | // End of content of file: include/json/writer.h 2164 | // ////////////////////////////////////////////////////////////////////// 2165 | 2166 | 2167 | 2168 | 2169 | 2170 | 2171 | // ////////////////////////////////////////////////////////////////////// 2172 | // Beginning of content of file: include/json/assertions.h 2173 | // ////////////////////////////////////////////////////////////////////// 2174 | 2175 | // Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors 2176 | // Distributed under MIT license, or public domain if desired and 2177 | // recognized in your jurisdiction. 2178 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 2179 | 2180 | #ifndef CPPTL_JSON_ASSERTIONS_H_INCLUDED 2181 | #define CPPTL_JSON_ASSERTIONS_H_INCLUDED 2182 | 2183 | #include 2184 | #include 2185 | 2186 | #if !defined(JSON_IS_AMALGAMATION) 2187 | #include "config.h" 2188 | #endif // if !defined(JSON_IS_AMALGAMATION) 2189 | 2190 | /** It should not be possible for a maliciously designed file to 2191 | * cause an abort() or seg-fault, so these macros are used only 2192 | * for pre-condition violations and internal logic errors. 2193 | */ 2194 | #if JSON_USE_EXCEPTION 2195 | 2196 | // @todo <= add detail about condition in exception 2197 | # define JSON_ASSERT(condition) \ 2198 | {if (!(condition)) {Json::throwLogicError( "assert json failed" );}} 2199 | 2200 | # define JSON_FAIL_MESSAGE(message) \ 2201 | { \ 2202 | JSONCPP_OSTRINGSTREAM oss; oss << message; \ 2203 | Json::throwLogicError(oss.str()); \ 2204 | abort(); \ 2205 | } 2206 | 2207 | #else // JSON_USE_EXCEPTION 2208 | 2209 | # define JSON_ASSERT(condition) assert(condition) 2210 | 2211 | // The call to assert() will show the failure message in debug builds. In 2212 | // release builds we abort, for a core-dump or debugger. 2213 | # define JSON_FAIL_MESSAGE(message) \ 2214 | { \ 2215 | JSONCPP_OSTRINGSTREAM oss; oss << message; \ 2216 | assert(false && oss.str().c_str()); \ 2217 | abort(); \ 2218 | } 2219 | 2220 | 2221 | #endif 2222 | 2223 | #define JSON_ASSERT_MESSAGE(condition, message) \ 2224 | if (!(condition)) { \ 2225 | JSON_FAIL_MESSAGE(message); \ 2226 | } 2227 | 2228 | #endif // CPPTL_JSON_ASSERTIONS_H_INCLUDED 2229 | 2230 | // ////////////////////////////////////////////////////////////////////// 2231 | // End of content of file: include/json/assertions.h 2232 | // ////////////////////////////////////////////////////////////////////// 2233 | 2234 | 2235 | 2236 | 2237 | 2238 | #endif //ifndef JSON_AMALGAMATED_H_INCLUDED 2239 | --------------------------------------------------------------------------------