commit 1f6df320923e306d673a0f7525babc030000189e Author: songtianlun Date: Tue Dec 20 17:31:11 2022 +0800 clean and init practice repo diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..85f3cc3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.vscode +.DS_Store +*.swp +.idea diff --git a/README.md b/README.md new file mode 100644 index 0000000..aff8fd8 --- /dev/null +++ b/README.md @@ -0,0 +1,19 @@ +# Dev Practice + +- `compress` : a way to compress +- cpp: Some demo for c++ +- gcc: Study gcc +- glog: a example to glog in use +- go: some demo fo go +- makefile_1: some demo for c project +- mult-progress: some demo for mult progress +- multthread: some demo for mult thread +- python: some demo fo python +- socket: some demo for socket connect +- Switch_DEMO: some demo for Switch +- system-test: some demo for system in use +- tcp: some demo for tcp connect +- tcp_relay-master: a github project for tcp +- test: some demo +- zmq: some demo for zmq +- system_status: get system status use the C diff --git a/sftp-config.json b/sftp-config.json new file mode 100644 index 0000000..0a651cc --- /dev/null +++ b/sftp-config.json @@ -0,0 +1,45 @@ +{ + // The tab key will cycle through the settings when first created + // Visit https://codexns.io/products/sftp_for_subime/settings for help + + // sftp, ftp or ftps + "type": "sftp", + + "save_before_upload": true, + "upload_on_save": false, + "sync_down_on_open": false, + "sync_skip_deletes": false, + "sync_same_age": true, + "confirm_downloads": false, + "confirm_sync": true, + "confirm_overwrite_newer": false, + + "host": "192.168.5.129", + "user": "root", + "password": "wuzhou@stl", + //"port": "22", + + "remote_path": "/root/dev-go/", + "ignore_regexes": [ + "\\.sublime-(project|workspace)", "sftp-config(-alt\\d?)?\\.json", + "sftp-settings\\.json", "/venv/", "\\.svn/", "\\.hg/", "\\.git/", + "\\.bzr", "_darcs", "CVS", "\\.DS_Store", "Thumbs\\.db", "desktop\\.ini" + ], + //"file_permissions": "664", + //"dir_permissions": "775", + + //"extra_list_connections": 0, + + "connect_timeout": 30, + //"keepalive": 120, + //"ftp_passive_mode": true, + //"ftp_obey_passive_host": false, + //"ssh_key_file": "~/.ssh/id_rsa", + //"sftp_flags": ["-F", "/path/to/ssh_config"], + + //"preserve_modification_times": false, + //"remote_time_offset_in_hours": 0, + //"remote_encoding": "utf-8", + //"remote_locale": "C", + //"allow_config_upload": false, +} diff --git a/study_clang/BitArithmetic/README.md b/study_clang/BitArithmetic/README.md new file mode 100644 index 0000000..f258ec4 --- /dev/null +++ b/study_clang/BitArithmetic/README.md @@ -0,0 +1,8 @@ +# 位运算实现四则运算 + +尝试进行各种情况下位运算实现的四则运算和原生四则运算的速度。 + +## 结论 + +- C程序下乘除2,位运算更快。 +- 其他情况下位运算提供的四则运算速度较慢。 diff --git a/study_clang/BitArithmetic/a.out b/study_clang/BitArithmetic/a.out new file mode 100755 index 0000000..1e6b9b3 Binary files /dev/null and b/study_clang/BitArithmetic/a.out differ diff --git a/study_clang/BitArithmetic/bitCal b/study_clang/BitArithmetic/bitCal new file mode 100755 index 0000000..1e6b9b3 Binary files /dev/null and b/study_clang/BitArithmetic/bitCal differ diff --git a/study_clang/BitArithmetic/bitCal.c b/study_clang/BitArithmetic/bitCal.c new file mode 100644 index 0000000..1214e16 --- /dev/null +++ b/study_clang/BitArithmetic/bitCal.c @@ -0,0 +1,105 @@ +/************************************************************************* + > File Name: bitCal.c + > Author: TL Song + > Mail: songtianlun@frytea.com + > Created Time: Fri 28 Aug 2020 12:58:40 AM UTC + ************************************************************************/ + +#include + +#include + +/* + *功能: 两个数相加 + *@num1, @num2 加法的两个操作数 + *返回值 : 两个num的相加后的值 + */ +int Add(int num1, int num2) +{ + int exclusive_val = num1; //异或值 + int carry_val = num2; //进位值 + + exclusive_val = num1 ^ num2; //取第一次异或值(没有进位的异或就是相加) + carry_val = (num1 & num2) << 1; //取第一次进位值 + + //进位值为0是循环终止条件 + while (carry_val) + { + int temp = exclusive_val; + exclusive_val = exclusive_val ^ carry_val; //异或值与进位值进行异或 + carry_val = (temp & carry_val) << 1; + + } + return exclusive_val; +} + +/* + *功能: 减法 + *算法: A - B = A + B(补码) = A + (B反码 + 1) = A + (~B + 1) + *@num1, @num2; 减法的两个操作数 + *返回值: 两个数的相减值 + */ +int Sub(int num1, int num2) +{ + int temp = Add(~num2, 1); //取反与求补差1 + return Add(num1, temp); +} + +/* + *功能: 除法 + *算法: A 除 B 的意义就是看A里有多少个B,可以通过A - B实现。 + * A一直循环减B,直到结果小于0。循环的次数就是结果。 + *@num1, @num2; 除法的两个操作数 + *返回值: 两个数的相除值 + */ +int div(int num1, int num2) +{ + int count = 0; + while (1) + { + if ((num1 = Sub(num1, num2)) < 0) + { + break; + } + count++; + } + return count; +} + +/* +*功能: 乘法 +*算法: A 乘 B 的意义就是A个B累加,定义一个累加器count = 1; +* 可以通过循环A次累加B相加实现。 +*@num1, @num2; 乘法的两个操作数 +*返回值: 两个数的相乘值 +*/ +int mult(int num1, int num2) +{ + int count = 0; + int result = 0; + int temp = num2; + while (1) + { + if (num1 == count) + { + break; + } + result = Add(result, temp); + count++; + } + return result; +} +int main(void) +{ + int num1, num2; + while (1) + { + printf("请输入两个整数: \n"); + scanf("%d%d", &num1, &num2); + printf("%d + %d = %d\n", num1, num2, Add(num1, num2)); + printf("%d - %d = %d\n", num1, num2, Sub(num1, num2)); + printf("%d * %d = %d\n", num1, num2, mult(num1, num2)); + printf("%d / %d = %d\n", num1, num2, div(num1, num2)); + } + return 0; +} diff --git a/study_clang/BitArithmetic/main b/study_clang/BitArithmetic/main new file mode 100755 index 0000000..53a5b3b Binary files /dev/null and b/study_clang/BitArithmetic/main differ diff --git a/study_clang/BitArithmetic/main.cpp b/study_clang/BitArithmetic/main.cpp new file mode 100644 index 0000000..29fb929 --- /dev/null +++ b/study_clang/BitArithmetic/main.cpp @@ -0,0 +1,209 @@ +/************************************************************************* + > File Name: main.c + > Author: TL Song + > Mail: songtianlun@frytea.com + > Created Time: Thu 27 Aug 2020 12:08:59 PM UTC + ************************************************************************/ + +#include +#include +#include +#include + +using namespace std; + +int bitAdd(int num1, int num2) +{ + int exclusive_val = num1; //异或值 + int carry_val = num2; //进位值 + + exclusive_val = num1 ^ num2; //取第一次异或值(没有进位的异或就是相加) + carry_val = (num1 & num2) << 1; //取第一次进位值 + + //进位值为0是循环终止条件 + while (carry_val) + { + int temp = exclusive_val; + exclusive_val = exclusive_val ^ carry_val; //异或值与进位值进行异或 + carry_val = (temp & carry_val) << 1; + + } + return exclusive_val; + +} + +int add(int a, int b) +{ + return a+b; +} + +int bitSubtraction(int num1, int num2) +{ + int temp = bitAdd(~num2, 1); //取反与求补差1 + return bitAdd(num1, temp); +} + +int subtraction(int a, int b) +{ + return a - b; +} + +int bitDivide(int x, int y) { + int ans=0; + for(int i=31;i>=0;i--) + { + // //比较x是否大于y的(1<>i) >=y ) + { + ans+=(1<>1); + } + return ans; +} + +int mulTwo(int n) +{ + return n << 1; +} + +int divTwo(int n) +{ + return n >> 1; +} + +int getAverage(int x, int y) +{ + return ( x + y ) >> 1; +} + +int main() +{ + int i; + int a,b; + int result; + int num = 10000000; + clock_t start, finish; + double duration; + + //printf("Test Add:\n"); + printf("Please Enter the num1: "); + scanf("%d",&a); + printf("Please Enter the num2: "); + scanf("%d",&b); + + printf("---------------------------------------------------------------------------------------------\n"); + start = clock(); + for(i=0;i Bit add calculation %d times total time: %f, Last result: %d\n", num,duration,result); + + start = clock(); + for(i=0;i Direct add calculation %d times total time: %f, Last result: %d\n", num,duration,result); + printf("---------------------------------------------------------------------------------------------\n"); + start = clock(); + for(i=0;i Bit multiply calculation %d times total time: %f, Last result: %d\n", num,duration,result); + + start = clock(); + for(i=0;i Direct multiply calculation %d times total time: %f, Last result: %d\n", num,duration,result); + printf("---------------------------------------------------------------------------------------------\n"); + start = clock(); + for(i=0;i Bit divide calculation %d times total time: %f, Last result: %d\n", num,duration,result); + start = clock(); + for(i=0;i Direct divide calculation %d times total time: %f, Last result: %d\n", num,duration,result); + printf("---------------------------------------------------------------------------------------------\n"); + start = clock(); + for(i=0;i Bit multiply 2 calculation %d times total time: %f, Last result: %d\n", num,duration,result); + + start = clock(); + for(i=0;i Direct multiply 2 calculation %d times total time: %f, Last result: %d\n", num,duration,result); + printf("---------------------------------------------------------------------------------------------\n"); + + start = clock(); + for(i=0;i Bit divide 2 calculation %d times total time: %f, Last result: %d\n", num,duration,result); + + start = clock(); + for(i=0;i Direct divide 2 calculation %d times total time: %f, Last result: %d\n", num,duration,result); + + + printf("---------------------------------------------------------------------------------------------\n"); + start = clock(); + for(i=0;i Bit average calculation %d times total time: %f, Last result: %d\n", num,duration,result); + + start = clock(); + for(i=0;i Direct average calculation %d times total time: %f, Last result: %d\n", num,duration,result); + printf("---------------------------------------------------------------------------------------------\n"); +} + + diff --git a/study_clang/Makefile b/study_clang/Makefile new file mode 100644 index 0000000..b10df75 --- /dev/null +++ b/study_clang/Makefile @@ -0,0 +1,22 @@ +# Batch Single C file MakeFile + +# 指定CPU架构 Architecture -> ARCH +ARCH ?= +CC = $(ARCH)gcc +SUFFIX = .c +CFLAGS += -Wall -g +LD = + +CUR_SOURCE = $(wildcard *$(SUFFIX)) +CUR_TARGETS = $(patsubst %$(SUFFIX), %, $(CUR_SOURCE)) + +all:$(CUR_TARGETS) + +# %:%.c 是一个表示与目标相同 文件的模式变量 +$(CUR_TARGETS):%:%$(SUFFIX) + $(CC) $< $(CFLAGS) -o $@ $(LD) + +# 指定伪目标 +.PHONY:clean all + clean: + -rm -rf $(TARGETS) diff --git a/study_clang/Mimic/OperateNos/FOperateNos.cpp b/study_clang/Mimic/OperateNos/FOperateNos.cpp new file mode 100644 index 0000000..bafead7 --- /dev/null +++ b/study_clang/Mimic/OperateNos/FOperateNos.cpp @@ -0,0 +1,93 @@ +/************************************************************************* + > File Name : OperateNos.cpp + > Author : TL Song + > EMail : songtianlun@frytea.com + > Created Time : Thu 03 Dec 2020 09:13:38 AM CST + ************************************************************************/ + +#include "FOperateNos.h" + +int FOperateNos::StartNos(int iNosIdx) +{ + // char szmsg[1024] = {0}; + // strcpy(szmsg,"Start Nos"); + Web_Msg_T webMsg; + memset(&webMsg, 0x00, sizeof(webMsg)); + webMsg.nos_id = iNosIdx; + webMsg.nos_op = NOS_POWER_ON; + SendCmdToShd(&webMsg, sizeof(webMsg)); + std::cout << "Nos" << webMsg.nos_id << " will be power on, result " << webMsg.result << std::endl; +} + +int FOperateNos::StopNos(int iNosIdx) +{ + Web_Msg_T webMsg; + memset(&webMsg, 0x00, sizeof(webMsg)); + webMsg.nos_id = iNosIdx; + webMsg.nos_op = NOS_POWER_OFF; + SendCmdToShd(&webMsg, sizeof(webMsg)); + std::cout << "Nos" << webMsg.nos_id << " will be power off, result " << webMsg.result << std::endl; +} + +int FOperateNos::RestartNos(int iNosIdx) +{ + Web_Msg_T webMsg; + memset(&webMsg, 0x00, sizeof(webMsg)); + webMsg.nos_id = iNosIdx; + webMsg.nos_op = NOS_RESTART; + SendCmdToShd(&webMsg, sizeof(webMsg)); + std::cout << "Nos" << webMsg.nos_id << " will be restart, result " << webMsg.result << std::endl; +} + +void FOperateNos::Init() +{ + reader = INIReader("operate_nos_conf.ini"); + if (reader.ParseError() < 0) + std::cout << "Can't load 'test.ini'\n"; + std::cout << "Init F Operate Nos" << std::endl; + InitSocket(); +} + +void FOperateNos::InitSocket() +{ + char szPubKey[64] = {0}; + char szPriKey[64] = {0}; + char szSerKey[64] = {0}; + char szaddr[128] = {0}; + + ctx = zmq_ctx_new(); + sock = zmq_socket(ctx, ZMQ_REQ); + strcpy(szSerKey, ZMQ_PUBLIC_KEY_1); + snprintf(szaddr, sizeof(szaddr), "tcp://%s:%d", \ + reader.Get("general", "shd_ip", "UNKNOWN").c_str(), \ + reader.GetInteger("general", "shd_port", -1) + ); + + std::cout << "Connect to zmq server : " << szaddr << std::endl; + // 加密 + // zmq_setsockopt(sock, ZMQ_CURVE_SERVERKEY, szSerKey, strlen(szSerKey)); + // zmq_curve_keypair(szPubKey, szPriKey); + // zmq_setsockopt(sock, ZMQ_CURVE_PUBLICKEY, szPubKey, strlen(szPubKey)); + // zmq_setsockopt(sock, ZMQ_CURVE_SECRETKEY, szPriKey, strlen(szPriKey)); + zmq_connect(sock, szaddr); + + // 超时 + unsigned int uiTimeout = 30 * 1000; + zmq_setsockopt(sock, ZMQ_RCVTIMEO, &uiTimeout, sizeof(uiTimeout)); +} +void FOperateNos::DestroySocket() +{ + zmq_close(sock); + zmq_ctx_term(ctx); + zmq_ctx_destroy(ctx); +} +int FOperateNos::SendCmdToShd(void * sMsg, int iMsgLen) +{ + int iResult; + iResult = zmq_send(sock, sMsg, iMsgLen, 0); + if(0 > iResult) + std::cout << "Send Msg To Shd Error, Code " << iResult << std::endl; + iResult = zmq_recv(sock, sMsg, iMsgLen, 0); + if(0 > iResult) + std::cout << "Recv Msg From Shd Error, Code " << iResult << std::endl; +} \ No newline at end of file diff --git a/study_clang/Mimic/OperateNos/FOperateNos.h b/study_clang/Mimic/OperateNos/FOperateNos.h new file mode 100644 index 0000000..6463136 --- /dev/null +++ b/study_clang/Mimic/OperateNos/FOperateNos.h @@ -0,0 +1,486 @@ +/************************************************************************* + > File Name : OperateNos.h + > Author : TL Song + > EMail : songtianlun@frytea.com + > Created Time : Thu 03 Dec 2020 09:13:48 AM CST + ************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#define ZMQ_PUBLIC_KEY_1 "@M[-VQ%R2MKguD/h/0w7.fNq%GGjV!1Q:bVeu*u>" +#define ZMQ_PRIVATE_KEY_1 "S*{[[V$7f<(jAp^]M>I!n?dN]SXgB]" + +#define WEB_EXEC_FAILED 201 +#define WEB_EXEC_SUCCES 202 + +typedef enum Web_Op_E +{ + NOS_POWER_ON=1, + NOS_POWER_OFF, + NOS_RESTART +}Web_Op_T; + +typedef struct Web_Msg_S +{ + unsigned int nos_id; + Web_Op_T nos_op; + unsigned int result; //0:defaule 201:failed 202:succeed +}Web_Msg_T; + +// INIReader.h https://github.com/jtilly/inih +#ifndef __INI_H__ +#define __INI_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int (*ini_handler)(void* user, const char* section, + const char* name, const char* value); +typedef char* (*ini_reader)(char* str, int num, void* stream); +int ini_parse(const char* filename, ini_handler handler, void* user); +int ini_parse_file(FILE* file, ini_handler handler, void* user); +int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler, + void* user); +#ifndef INI_ALLOW_MULTILINE +#define INI_ALLOW_MULTILINE 1 +#endif + +#ifndef INI_ALLOW_BOM +#define INI_ALLOW_BOM 1 +#endif + +#ifndef INI_ALLOW_INLINE_COMMENTS +#define INI_ALLOW_INLINE_COMMENTS 1 +#endif +#ifndef INI_INLINE_COMMENT_PREFIXES +#define INI_INLINE_COMMENT_PREFIXES ";" +#endif + +/* Nonzero to use stack, zero to use heap (malloc/free). */ +#ifndef INI_USE_STACK +#define INI_USE_STACK 1 +#endif + +/* Stop parsing on first error (default is to keep parsing). */ +#ifndef INI_STOP_ON_FIRST_ERROR +#define INI_STOP_ON_FIRST_ERROR 0 +#endif + +/* Maximum line length for any line in INI file. */ +#ifndef INI_MAX_LINE +#define INI_MAX_LINE 200 +#endif + +#ifdef __cplusplus +} +#endif + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + +#if !INI_USE_STACK +#include +#endif + +#define MAX_SECTION 50 +#define MAX_NAME 50 + +/* Strip whitespace chars off end of given string, in place. Return s. */ +inline static char* rstrip(char* s) +{ + char* p = s + strlen(s); + while (p > s && isspace((unsigned char)(*--p))) + *p = '\0'; + return s; +} + +/* Return pointer to first non-whitespace char in given string. */ +inline static char* lskip(const char* s) +{ + while (*s && isspace((unsigned char)(*s))) + s++; + return (char*)s; +} + +/* Return pointer to first char (of chars) or inline comment in given string, + or pointer to null at end of string if neither found. Inline comment must + be prefixed by a whitespace character to register as a comment. */ +inline static char* find_chars_or_comment(const char* s, const char* chars) +{ +#if INI_ALLOW_INLINE_COMMENTS + int was_space = 0; + while (*s && (!chars || !strchr(chars, *s)) && + !(was_space && strchr(INI_INLINE_COMMENT_PREFIXES, *s))) { + was_space = isspace((unsigned char)(*s)); + s++; + } +#else + while (*s && (!chars || !strchr(chars, *s))) { + s++; + } +#endif + return (char*)s; +} + +/* Version of strncpy that ensures dest (size bytes) is null-terminated. */ +inline static char* strncpy0(char* dest, const char* src, size_t size) +{ + strncpy(dest, src, size); + dest[size - 1] = '\0'; + return dest; +} + +/* See documentation in header file. */ +inline int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler, + void* user) +{ + /* Uses a fair bit of stack (use heap instead if you need to) */ +#if INI_USE_STACK + char line[INI_MAX_LINE]; +#else + char* line; +#endif + char section[MAX_SECTION] = ""; + char prev_name[MAX_NAME] = ""; + + char* start; + char* end; + char* name; + char* value; + int lineno = 0; + int error = 0; + +#if !INI_USE_STACK + line = (char*)malloc(INI_MAX_LINE); + if (!line) { + return -2; + } +#endif + + /* Scan through stream line by line */ + while (reader(line, INI_MAX_LINE, stream) != NULL) { + lineno++; + + start = line; +#if INI_ALLOW_BOM + if (lineno == 1 && (unsigned char)start[0] == 0xEF && + (unsigned char)start[1] == 0xBB && + (unsigned char)start[2] == 0xBF) { + start += 3; + } +#endif + start = lskip(rstrip(start)); + + if (*start == ';' || *start == '#') { + /* Per Python configparser, allow both ; and # comments at the + start of a line */ + } +#if INI_ALLOW_MULTILINE + else if (*prev_name && *start && start > line) { + +#if INI_ALLOW_INLINE_COMMENTS + end = find_chars_or_comment(start, NULL); + if (*end) + *end = '\0'; + rstrip(start); +#endif + + /* Non-blank line with leading whitespace, treat as continuation + of previous name's value (as per Python configparser). */ + if (!handler(user, section, prev_name, start) && !error) + error = lineno; + } +#endif + else if (*start == '[') { + /* A "[section]" line */ + end = find_chars_or_comment(start + 1, "]"); + if (*end == ']') { + *end = '\0'; + strncpy0(section, start + 1, sizeof(section)); + *prev_name = '\0'; + } + else if (!error) { + /* No ']' found on section line */ + error = lineno; + } + } + else if (*start) { + /* Not a comment, must be a name[=:]value pair */ + end = find_chars_or_comment(start, "=:"); + if (*end == '=' || *end == ':') { + *end = '\0'; + name = rstrip(start); + value = lskip(end + 1); +#if INI_ALLOW_INLINE_COMMENTS + end = find_chars_or_comment(value, NULL); + if (*end) + *end = '\0'; +#endif + rstrip(value); + + /* Valid name[=:]value pair found, call handler */ + strncpy0(prev_name, name, sizeof(prev_name)); + if (!handler(user, section, name, value) && !error) + error = lineno; + } + else if (!error) { + /* No '=' or ':' found on name[=:]value line */ + error = lineno; + } + } + +#if INI_STOP_ON_FIRST_ERROR + if (error) + break; +#endif + } + +#if !INI_USE_STACK + free(line); +#endif + + return error; +} + +/* See documentation in header file. */ +inline int ini_parse_file(FILE* file, ini_handler handler, void* user) +{ + return ini_parse_stream((ini_reader)fgets, file, handler, user); +} + +/* See documentation in header file. */ +inline int ini_parse(const char* filename, ini_handler handler, void* user) +{ + FILE* file; + int error; + + file = fopen(filename, "r"); + if (!file) + return -1; + error = ini_parse_file(file, handler, user); + fclose(file); + return error; +} + +#endif /* __INI_H__ */ + + +#ifndef __INIREADER_H__ +#define __INIREADER_H__ + +#include +#include +#include + +// Read an INI file into easy-to-access name/value pairs. (Note that I've gone +// for simplicity here rather than speed, but it should be pretty decent.) +class INIReader +{ +public: + // Empty Constructor + INIReader() {}; + + // Construct INIReader and parse given filename. See ini.h for more info + // about the parsing. + INIReader(std::string filename); + + // Construct INIReader and parse given file. See ini.h for more info + // about the parsing. + INIReader(FILE *file); + + // Return the result of ini_parse(), i.e., 0 on success, line number of + // first error on parse error, or -1 on file open error. + int ParseError() const; + + // Return the list of sections found in ini file + const std::set& Sections() const; + + // Get a string value from INI file, returning default_value if not found. + std::string Get(std::string section, std::string name, + std::string default_value) const; + + // Get an integer (long) value from INI file, returning default_value if + // not found or not a valid integer (decimal "1234", "-1234", or hex "0x4d2"). + long GetInteger(std::string section, std::string name, long default_value) const; + + // Get a real (floating point double) value from INI file, returning + // default_value if not found or not a valid floating point value + // according to strtod(). + double GetReal(std::string section, std::string name, double default_value) const; + + // Get a single precision floating point number value from INI file, returning + // default_value if not found or not a valid floating point value + // according to strtof(). + float GetFloat(std::string section, std::string name, float default_value) const; + + // Get a boolean value from INI file, returning default_value if not found or if + // not a valid true/false value. Valid true values are "true", "yes", "on", "1", + // and valid false values are "false", "no", "off", "0" (not case sensitive). + bool GetBoolean(std::string section, std::string name, bool default_value) const; + +protected: + int _error; + std::map _values; + std::set _sections; + static std::string MakeKey(std::string section, std::string name); + static int ValueHandler(void* user, const char* section, const char* name, + const char* value); +}; + +#endif // __INIREADER_H__ + + +#ifndef __INIREADER__ +#define __INIREADER__ + +#include +#include +#include + +inline INIReader::INIReader(std::string filename) +{ + _error = ini_parse(filename.c_str(), ValueHandler, this); +} + +inline INIReader::INIReader(FILE *file) +{ + _error = ini_parse_file(file, ValueHandler, this); +} + +inline int INIReader::ParseError() const +{ + return _error; +} + +inline const std::set& INIReader::Sections() const +{ + return _sections; +} + +inline std::string INIReader::Get(std::string section, std::string name, std::string default_value) const +{ + std::string key = MakeKey(section, name); + return _values.count(key) ? _values.at(key) : default_value; +} + +inline long INIReader::GetInteger(std::string section, std::string name, long default_value) const +{ + std::string valstr = Get(section, name, ""); + const char* value = valstr.c_str(); + char* end; + // This parses "1234" (decimal) and also "0x4D2" (hex) + long n = strtol(value, &end, 0); + return end > value ? n : default_value; +} + +inline double INIReader::GetReal(std::string section, std::string name, double default_value) const +{ + std::string valstr = Get(section, name, ""); + const char* value = valstr.c_str(); + char* end; + double n = strtod(value, &end); + return end > value ? n : default_value; +} + +inline float INIReader::GetFloat(std::string section, std::string name, float default_value) const +{ + std::string valstr = Get(section, name, ""); + const char* value = valstr.c_str(); + char* end; + float n = strtof(value, &end); + return end > value ? n : default_value; +} + +inline bool INIReader::GetBoolean(std::string section, std::string name, bool default_value) const +{ + std::string valstr = Get(section, name, ""); + // Convert to lower case to make string comparisons case-insensitive + std::transform(valstr.begin(), valstr.end(), valstr.begin(), ::tolower); + if (valstr == "true" || valstr == "yes" || valstr == "on" || valstr == "1") + return true; + else if (valstr == "false" || valstr == "no" || valstr == "off" || valstr == "0") + return false; + else + return default_value; +} + +inline std::string INIReader::MakeKey(std::string section, std::string name) +{ + std::string key = section + "=" + name; + // Convert to lower case to make section/name lookups case-insensitive + std::transform(key.begin(), key.end(), key.begin(), ::tolower); + return key; +} + +inline int INIReader::ValueHandler(void* user, const char* section, const char* name, + const char* value) +{ + INIReader* reader = (INIReader*)user; + std::string key = MakeKey(section, name); + if (reader->_values[key].size() > 0) + reader->_values[key] += "\n"; + reader->_values[key] += value; + reader->_sections.insert(section); + return 1; +} +#endif // __INIREADER__ + + +// 单实例模板类 饿汉模式 +#ifndef __SINGLETON_CLASS_H__ +#define __SINGLETON_CLASS_H__ +template +class singleton +{ +private: + static T* p; //标志指针 + +public: + static T* instance(); //得到类型为T对象的方法 +}; + +template +T* singleton::p = new T(); //不管外部是否要使用对象,进入main函数前就生成T对象,p指向该对象的地址 + +template +T* singleton::instance() +{ + return p; +} +#endif /* __SINGLETON_CLASS_H__ */ + +#ifndef FOPERATENOS_H +#define FOPERATENOS_H +class FOperateNos +{ +public: + FOperateNos(){}; + virtual ~FOperateNos(){ + DestroySocket(); + }; + +public: + void Init(); + int StartNos(int iNosIdx); + int StopNos(int iNosIdx); + int RestartNos(int iNosIdx); + +private: + void InitSocket(); + void DestroySocket(); + int SendCmdToShd(void * sMsg, int iMsgLen); + friend class singleton; + +private: + void * ctx; + void *sock; + INIReader reader; +}; +#endif /* FOPERATENOS_H */ \ No newline at end of file diff --git a/study_clang/Mimic/OperateNos/Makefile b/study_clang/Mimic/OperateNos/Makefile new file mode 100644 index 0000000..7739689 --- /dev/null +++ b/study_clang/Mimic/OperateNos/Makefile @@ -0,0 +1,20 @@ +# Author: Tianlun Song, songtianlun@frytea.com, In Nov 22, 2020. +ARCH ?= +CC = $(ARCH)g++ +SUFFIX = .cpp +CFLAGS += -g -L ./ +LD = -lzmq + +CUR_SOURCE = $(wildcard *.cpp) +# CUR_SOURCE = main.cpp FOperateNos.cpp +CUR_TARGETS = ./operate_nos + +all:$(CUR_TARGETS) + +$(CUR_TARGETS):$(CUR_SOURCE) + $(CC) $^ $(CFLAGS) -o $@ $(LD) + +# 指定伪目标 +.PHONY:clean all + clean: + -rm -rf $(TARGETS) diff --git a/study_clang/Mimic/OperateNos/main.cpp b/study_clang/Mimic/OperateNos/main.cpp new file mode 100644 index 0000000..eaf3135 --- /dev/null +++ b/study_clang/Mimic/OperateNos/main.cpp @@ -0,0 +1,40 @@ +/************************************************************************* + > File Name : main.cpp + > Author : TL Song + > EMail : songtianlun@frytea.com + > Created Time : Thu 03 Dec 2020 09:43:19 AM CST + ************************************************************************/ + +#include "FOperateNos.h" +/* + s_web_to_shd_addr=30.30.30.202:8201 + + 通信格式: + #define WEB_EXEC_FAILED 201 + #define WEB_EXEC_SUCCES 202 + + typedef enum Web_Op_E + { + NOS_POWER_ON=1, + NOS_POWER_OFF, + NOS_RESTART + }Web_Op_T; + + typedef struct Web_Msg_S + { + unsigned int nos_id; + Web_Op_T nos_op; + unsigned int result; //0:defaule 201:failed 202:succeed + }Web_Msg_T; +*/ +int main(int argc, char* argv[]) +{ + singleton::instance()->Init(); + sleep(1); + singleton::instance()->StartNos(1); + sleep(1); + singleton::instance()->StopNos(2); + sleep(1); + singleton::instance()->RestartNos(3); + return 0; +} \ No newline at end of file diff --git a/study_clang/Mimic/OperateNos/operate_nos b/study_clang/Mimic/OperateNos/operate_nos new file mode 100755 index 0000000..ea98aec Binary files /dev/null and b/study_clang/Mimic/OperateNos/operate_nos differ diff --git a/study_clang/Mimic/OperateNos/operate_nos_conf.ini b/study_clang/Mimic/OperateNos/operate_nos_conf.ini new file mode 100644 index 0000000..9517ae0 --- /dev/null +++ b/study_clang/Mimic/OperateNos/operate_nos_conf.ini @@ -0,0 +1,6 @@ +; Config file for OperateNos +; Author: Tianlun Song. songtianlun@frytea.com. + +[general] ; General configuration +shd_ip=30.30.30.202 ; SHD IP +shd_port=8201 ; SHD Port \ No newline at end of file diff --git a/study_clang/Mimic/OperateNos/test_server/Makefile b/study_clang/Mimic/OperateNos/test_server/Makefile new file mode 100644 index 0000000..2011657 --- /dev/null +++ b/study_clang/Mimic/OperateNos/test_server/Makefile @@ -0,0 +1,22 @@ +# Batch Single C file MakeFile + +# 指定CPU架构 Architecture -> ARCH +ARCH ?= +CC = $(ARCH)gcc +SUFFIX = .c +CFLAGS += -Wall -g -lzmq -lpthread +LD = + +CUR_SOURCE = $(wildcard *$(SUFFIX)) +CUR_TARGETS = $(patsubst %$(SUFFIX), %, $(CUR_SOURCE)) + +all:$(CUR_TARGETS) + +# %:%.c 是一个表示与目标相同 文件的模式变量 +$(CUR_TARGETS):%:%$(SUFFIX) + $(CC) $< $(CFLAGS) -o $@ $(LD) + +# 指定伪目标 +.PHONY:clean all + clean: + -rm -rf $(TARGETS) \ No newline at end of file diff --git a/study_clang/Mimic/OperateNos/test_server/server b/study_clang/Mimic/OperateNos/test_server/server new file mode 100755 index 0000000..61b6884 Binary files /dev/null and b/study_clang/Mimic/OperateNos/test_server/server differ diff --git a/study_clang/Mimic/OperateNos/test_server/server.c b/study_clang/Mimic/OperateNos/test_server/server.c new file mode 100644 index 0000000..d27bf8a --- /dev/null +++ b/study_clang/Mimic/OperateNos/test_server/server.c @@ -0,0 +1,76 @@ +/************************************************************************* + > File Name : server.c + > Author : TL Song + > EMail : songtianlun@frytea.com + > Created Time : Wed 02 Dec 2020 04:50:40 PM CST + ************************************************************************/ + +#include +#include +#include + +#define ZMQ_PUBLIC_KEY_1 "@M[-VQ%R2MKguD/h/0w7.fNq%GGjV!1Q:bVeu*u>" +#define ZMQ_PRIVATE_KEY_1 "S*{[[V$7f<(jAp^]M>I!n?dN]SXgB]" + +#define ZMQ_PUBLIC_KEY_2 "p=lDOa9WKUKz!I9{G)uPX4@&CrV-(>tDg:kaSGzE" +#define ZMQ_PRIVATE_KEY_2 "q0]#)iuwR*H5hz.} +# DM-SW6620-32X2Q-Mimic-Switch +> 一些关于 `DM-SW6620-32X2Q` 拟态交换机的代码。 + +- monitor_system_status: 监控系统状况,并向裁决模块发送系统状态报文。 +- judge_status: 裁决模块中的系统状态裁决。 \ No newline at end of file diff --git a/study_clang/Mimic/Switch_DEMO/globalvar.py b/study_clang/Mimic/Switch_DEMO/globalvar.py new file mode 100644 index 0000000..fda60bd --- /dev/null +++ b/study_clang/Mimic/Switch_DEMO/globalvar.py @@ -0,0 +1,53 @@ +class GlobalVar: + proxy_interface = "ens8" + nos1_interface = "ens8f5" + nos2_interface = "ens8f5" + nos3_interface = "ens8f5" + nos4_interface = "ens8f5" + master_nos_interface = "ens8f5" + master_nos_vlan = "200" + nos_ip = "192.168.11.1" + +#def set_db_handle(db): +# GlobalVar.db_handle = db +def get_proxy_interface(): + return GlobalVar.proxy_interface + +def get_nos1_interface(): + return GlobalVar.nos1_interface + +def get_nos2_interface(): + return GlobalVar.nos2_interface + +def get_nos3_interface(): + return GlobalVar.nos3_interface + +def get_nos4_interface(): + return GlobalVar.nos4_interface + +def get_master_nos_interface(): + fileHandle = open ('nos.conf','r') + nos = fileHandle.read (1) + fileHandle.close() + if nos == "1": + GlobalVar.master_nos_interface = GlobalVar.nos1_interface + elif nos == "2": + GlobalVar.master_nos_interface = GlobalVar.nos2_interface + elif nos == "3": + GlobalVar.master_nos_interface = GlobalVar.nos3_interface + elif nos == "4": + GlobalVar.master_nos_interface = GlobalVar.nos4_interface + else: + GlobalVar.master_nos_interface = GlobalVar.nos1_interface + return GlobalVar.master_nos_interface + +def get_master_nos_vlan(): + fileHandle = open ('nos_vlan.conf','r') + nosvlan = fileHandle.read (3) + fileHandle.close() + GlobalVar.master_nos_vlan = nosvlan + return GlobalVar.master_nos_vlan + +def get_nos_ip(): + return GlobalVar.nos_ip + diff --git a/study_clang/Mimic/Switch_DEMO/init.sh b/study_clang/Mimic/Switch_DEMO/init.sh new file mode 100644 index 0000000..8763bfa --- /dev/null +++ b/study_clang/Mimic/Switch_DEMO/init.sh @@ -0,0 +1,166 @@ +#!/bin/bash + +#---------------------------------------------------------------------------------------------------------------------------------------------- +# +# 1、 judgeMasterNos.py 先启动,以后台方式启动; +# 2、 judgeMasterNos.py启动以后,sleep 2秒后,再启动arpProxy.py;同时通过ps命令查看arpProxy.py进程是否存在,如果不存在将启动失败信息写入到当前目录下的log中; +# 3、 arpProxy.py启动以后,sleep 2秒后,再启动icmpProxy.py;同时通过ps命令查看icmpProxy.py进程是否存在,如果不存在将启动失败信息写入到当前目录下的log中; +# 4、 icmpProxy.py启动以后,sleep 2秒后,再启动udpProxy.py;同时通过ps命令查看udpProxy.py进程是否存在,如果不存在将启动失败信息写入到当前目录下的log中; +# 5、 udpProxy.py启动以后,sleep 2秒后,再启动tcpProxy.py;同时通过ps命令查看tcpProxy.py进程是否存在,如果不存在将启动失败信息写入到当前目录下的log中; +# 6、 判断arpProxy.py、icmpProxy.py、udpProxy.py、tcpProxy.py四个进程是否存在,如果不存在,将错误信息写入到log中。 +# +#---------------------------------------------------------------------------------------------------------------------------------------------- + +#cmdpre="awk '/" +#cmdsuf="/' awk.temp" +log_mod="init_err" #用于分支不同的log格式 + +#在启动时的log记录 +function log() +{ + ERR_LOGFILE="error.log" + echo "[$pro] failed." + CUR_TIME=`date +'%Y-%m-%d %H-%M-%S'` + + if [ -f $ERR_LOGFILE ];then + echo "[$pro] started failed at time $CUR_TIME" >> error.log; + fi +} + +#在最后检查时的log记录 +function log_check() +{ + ERR_LOGFILE="error.log" + echo "[$pro] don't exist." + CUR_TIME=`date +'%Y-%m-%d %H-%M-%S'` + + if [ -f $ERR_LOGFILE ];then + echo "[$pro] don't exist at time $CUR_TIME" >> error.log; + fi +} + +#判断是否从ps中抓取到进程,没有则调用log +function isNull() +{ + if [ "$a" = "" ];then + + if [ $log_mod = "init_err" ];then + log + else + log_check + fi + fi +} + +#启动一个进程,然后启动后抓取ps +function start() +{ + sleep 2 + echo "[$pro] init..." + if [ -f "${pro}.pyc" ];then + $s python ${pro}.pyc >/dev/null 2>&1 & + ps a > ps.temp + awk '{print $6}' 'ps.temp' > awk.temp + #cmd=${cmdpre}${pro}${cmdsuf} #尝试用连接的方法将awk组合命令,但是会报错 + + fi +} + +#'sudo' 命令前缀 +s='' + +# 1、 + +if [ -f "judgeMasterNos.pyc" ];then + $s nohup python judgeMasterNos.pyc >/dev/null 2>&1 & +fi + +# 2、 + +pro="arpProxy" +start +a=`awk '/arpProxy/' 'awk.temp'` #因为命令中不能引用变量所以在这里分别写。 +isNull +# 3、 + +pro="icmpProxy" +start +a=`awk '/icmpProxy/' 'awk.temp'` +isNull + +# 4、 + + +pro="udpProxy" +start +a=`awk '/udpProxy/' 'awk.temp'` +isNull + +# 5、 + + +pro="tcpProxy" +start +a=`awk '/tcpProxy/' 'awk.temp'` +isNull + +pro="sshRelay" +start +a=`awk '/sshRelay/' 'awk.temp'` +isNull + +pro="pro_mimic" +start +a=`awk '/pro_mimic/' 'awk.temp'` +isNull + +pro="rip_mimic" +start +a=`awk '/rip_mimic/' 'awk.temp'` +isNull +# 6、 + +#改变log格式 +log_mod="check" + +ps a > ps.temp +awk '{print $6}' 'ps.temp' > awk.temp + +pro="arpProxy" +a=`awk '/arpProxy/' 'awk.temp'` +isNull +# 6、 + +#改变log格式 +log_mod="check" + +ps a > ps.temp +awk '{print $6}' 'ps.temp' > awk.temp + +pro="arpProxy" +a=`awk '/arpProxy/' 'awk.temp'` +isNull + +pro="icmpProxy" +a=`awk '/icmpProxy/' 'awk.temp'` +isNull + +pro="udpProxy" +a=`awk '/udpProxy/' 'awk.temp'` +isNull + +pro="tcpProxy" +a=`awk '/tcpProxy/' 'awk.temp'` +isNull + +pro="sshRelay" +a=`awk '/sshRelay/' 'awk.temp'` +isNull + +pro="pro_mimic" +a=`awk '/pro_mimic/' 'awk.temp'` +isNull + +pro="rip_mimic" +a=`awk '/rip_mimic/' 'awk.temp'` +isNull diff --git a/study_clang/Mimic/Switch_DEMO/judgeMasterNos.py b/study_clang/Mimic/Switch_DEMO/judgeMasterNos.py new file mode 100644 index 0000000..611da63 --- /dev/null +++ b/study_clang/Mimic/Switch_DEMO/judgeMasterNos.py @@ -0,0 +1,54 @@ +#!/usr/bin/python +# -*- coding: UTF-8 -*- + +import MySQLdb +import random + +#db_ip = "localhost" +db_ip = "192.168.134.84" + +# 打开数据库连接 +db = MySQLdb.connect(db_ip, "root", "123456", "nosdb", charset='utf8' ) +# 使用cursor()方法获取操作游标 +cursor = db.cursor() +# 使用execute方法执行SQL语句 +cursor.execute("select * from masternos order by id DESC limit 1 ") +# 使用 fetchone() 方法获取一条数据 +data = cursor.fetchone() +# 关闭数据库连接 +db.close() + +#print " id : %d " % data[0] +#print "type: %d" % data[1] +#print "nos:%d" % data[3] +#print "mark:%s" % data[2] + + + + +master_nos = 1; #the default master nos is nos1 +if data[1] == 0: # give the nos by admin + master_nos = data[2] +elif data[1] == 1: #give the nos with random + master_nos = random.randint(1,4) + #print "master_nos random:",master_nos + +#根据主执行体确定vlanID +if master_nos == 1: + vlanID = 200 +elif master_nos == 2: + vlanID = 300 +elif master_nos == 3: + vlanID = 400 +elif master_nos == 4: + vlanID = 500 +else: + vlanID = 200 + +fileHandle = open ('nos.conf', 'w' ) +fileHandle.write (str(master_nos)) +fileHandle.close() + +fileHandle = open ('nos_vlan.conf', 'w' ) +fileHandle.write (str(vlanID)) +fileHandle.close() diff --git a/study_clang/Mimic/Switch_DEMO/nos.conf b/study_clang/Mimic/Switch_DEMO/nos.conf new file mode 100644 index 0000000..d8263ee --- /dev/null +++ b/study_clang/Mimic/Switch_DEMO/nos.conf @@ -0,0 +1 @@ +2 \ No newline at end of file diff --git a/study_clang/Mimic/Switch_DEMO/udpProxy.py b/study_clang/Mimic/Switch_DEMO/udpProxy.py new file mode 100644 index 0000000..c73b41e --- /dev/null +++ b/study_clang/Mimic/Switch_DEMO/udpProxy.py @@ -0,0 +1,78 @@ +from scapy.all import * +import pcappy as pcap +import threading +import multiprocessing +import time +import globalvar as GlobalVar +from icmpProxy import getPortIp + +conf.use_pcap = True + +proxy_interface = str(GlobalVar.get_proxy_interface()) +nos1_interface = str(GlobalVar.get_nos1_interface()) +nos2_interface = str(GlobalVar.get_nos2_interface()) +nos3_interface = str(GlobalVar.get_nos3_interface()) +nos4_interface = str(GlobalVar.get_nos4_interface()) + +master_nos_interface = str(GlobalVar.get_master_nos_interface()) +master_nos_vlan = (GlobalVar.get_master_nos_vlan()) + + +def proxy_udploop(): + print 'proxy begin receive udp' + sniff(prn=dealProxyPacket, filter="ether[13]>0x00 and ether[13]<0x15 and ether[28]=0x08 and ether[29]=0x00 and ether[39]=0x11", iface=proxy_interface) + + +def dealProxyPacket(pkt): + pkt_str = str(pkt) + new_pkt = pkt.__class__(pkt_str[16:]) + #print new_pkt.show() + pkt_hex = pkt_str[:16].encode('hex') + ftag = int(int(pkt_hex[26], 16)*16) + int(pkt_hex[27], 16) + + sourth_pkt = Ether(src=new_pkt[Ether].src, dst=new_pkt[Ether].dst)/Dot1Q(vlan=int(master_nos_vlan)+ftag)/new_pkt.payload + + #print pkt4.show() + sendp(sourth_pkt, count=1, iface=master_nos_interface) + + +def master_nos_udploop(): + ipFilterList = getPortIp() + filterStr = "udp and (ip src " + str(GlobalVar.get_nos_ip()) + for i in ipFilterList: + filterStr += " or ip src " + i + filterStr += ")" + + print 'master nos begin receive udp' + sniff(prn=dealMasterNosPacket, filter=filterStr, iface=master_nos_interface) + #sniff(prn=dealMasterNosPacket,filter="vlan",iface=master_nos_interface) + + +def dealMasterNosPacket(pkt): + #print pkt.show() + if int(pkt[Dot1Q].vlan) > int(master_nos_vlan) and int(pkt[Dot1Q].vlan) < (int(master_nos_vlan)+18): + portVlan = (int(pkt[Dot1Q].vlan) - int(master_nos_vlan) + 1000) + pkt[Dot1Q].vlan = portVlan + print pkt.show() + sendp(pkt, count=1, iface=proxy_interface) + + +def main(): + p1 = multiprocessing.Process(target = proxy_udploop) + p1.start() + + p2 = multiprocessing.Process(target = master_nos_udploop) + p2.start() + +#t2 =threading.Thread(target=proxy_udpploop) +#t2.start() + +#t4 =threading.Thread(target=master_nos_udpploop) +#t4.start() + + +if __name__ == "__main__": + main() + + + diff --git a/study_clang/Mimic/app_migrate_class/Makefile b/study_clang/Mimic/app_migrate_class/Makefile new file mode 100644 index 0000000..70e6326 --- /dev/null +++ b/study_clang/Mimic/app_migrate_class/Makefile @@ -0,0 +1,22 @@ +# Batch Single C file MakeFile + +# 指定CPU架构 Architecture -> ARCH +ARCH ?= +CC = $(ARCH)g++ +SUFFIX = .cpp +CFLAGS += -Wall -g -std=c++11 +LD = -lcriu + +CUR_SOURCE = $(wildcard *$(SUFFIX)) +CUR_TARGETS = $(patsubst %$(SUFFIX), %, $(CUR_SOURCE)) + +all:$(CUR_TARGETS) + +# %:%.c 是一个表示与目标相同 文件的模式变量 +$(CUR_TARGETS):%:%$(SUFFIX) + $(CC) $< $(CFLAGS) -o $@ $(LD) + +# 指定伪目标 +.PHONY:clean all + clean: + -rm -rf $(TARGETS) \ No newline at end of file diff --git a/study_clang/Mimic/app_migrate_class/lib/criu.h b/study_clang/Mimic/app_migrate_class/lib/criu.h new file mode 100644 index 0000000..6b823a5 --- /dev/null +++ b/study_clang/Mimic/app_migrate_class/lib/criu.h @@ -0,0 +1,281 @@ +/* + * (C) Copyright 2013 Parallels, Inc. (www.parallels.com). + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser General Public License + * (LGPL) version 2.1 which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-2.1.html + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, you can find it here: + * www.gnu.org/licenses/lgpl.html + */ + +#ifndef __CRIU_LIB_H__ +#define __CRIU_LIB_H__ + +#include + +//#include "version.h" +#include + + +#ifdef __GNUG__ + extern "C" { +#endif + +enum criu_service_comm { + CRIU_COMM_SK, + CRIU_COMM_FD, + CRIU_COMM_BIN +}; + +enum criu_cg_mode { + CRIU_CG_MODE_IGNORE, + CRIU_CG_MODE_NONE, + CRIU_CG_MODE_PROPS, + CRIU_CG_MODE_SOFT, + CRIU_CG_MODE_FULL, + CRIU_CG_MODE_STRICT, + CRIU_CG_MODE_DEFAULT, +}; + +enum criu_pre_dump_mode { + CRIU_PRE_DUMP_SPLICE = 1, + CRIU_PRE_DUMP_READ = 2 +}; + +int criu_set_service_address(const char *path); +void criu_set_service_fd(int fd); +int criu_set_service_binary(const char *path); + +/* + * Set opts to defaults. _Must_ be called first before using any functions from + * the list down below. 0 on success, -1 on fail. + */ +int criu_init_opts(void); +void criu_free_opts(void); + +void criu_set_pid(int pid); +void criu_set_images_dir_fd(int fd); /* must be set for dump/restore */ +int criu_set_parent_images(const char *path); +void criu_set_work_dir_fd(int fd); +void criu_set_leave_running(bool leave_running); +void criu_set_ext_unix_sk(bool ext_unix_sk); +int criu_add_unix_sk(unsigned int inode); +void criu_set_tcp_established(bool tcp_established); +void criu_set_tcp_skip_in_flight(bool tcp_skip_in_flight); +void criu_set_tcp_close(bool tcp_close); +void criu_set_weak_sysctls(bool val); +void criu_set_evasive_devices(bool evasive_devices); +void criu_set_shell_job(bool shell_job); +void criu_set_orphan_pts_master(bool orphan_pts_master); +void criu_set_file_locks(bool file_locks); +void criu_set_track_mem(bool track_mem); +void criu_set_auto_dedup(bool auto_dedup); +void criu_set_force_irmap(bool force_irmap); +void criu_set_link_remap(bool link_remap); +void criu_set_log_level(int log_level); +int criu_set_log_file(const char *log_file); +void criu_set_cpu_cap(unsigned int cap); +int criu_set_root(const char *root); +void criu_set_manage_cgroups(bool manage); +void criu_set_manage_cgroups_mode(enum criu_cg_mode mode); +int criu_set_freeze_cgroup(const char *name); +int criu_set_lsm_profile(const char *name); +void criu_set_timeout(unsigned int timeout); +void criu_set_auto_ext_mnt(bool val); +void criu_set_ext_sharing(bool val); +void criu_set_ext_masters(bool val); +int criu_set_exec_cmd(int argc, char *argv[]); +int criu_add_ext_mount(const char *key, const char *val); +int criu_add_veth_pair(const char *in, const char *out); +int criu_add_cg_root(const char *ctrl, const char *path); +int criu_add_enable_fs(const char *fs); +int criu_add_skip_mnt(const char *mnt); +void criu_set_ghost_limit(unsigned int limit); +int criu_add_irmap_path(const char *path); +int criu_add_inherit_fd(int fd, const char *key); +int criu_add_external(const char *key); +int criu_set_page_server_address_port(const char *address, int port); +int criu_set_pre_dump_mode(enum criu_pre_dump_mode mode); + +/* + * The criu_notify_arg_t na argument is an opaque + * value that callbacks (cb-s) should pass into + * criu_notify_xxx() calls to fetch arbitrary values + * from notification. If the value is not available + * some non-existing one is reported. + */ + +typedef struct _CriuNotify *criu_notify_arg_t; +void criu_set_notify_cb(int (*cb)(char *action, criu_notify_arg_t na)); + +/* Get pid of root task. 0 if not available */ +int criu_notify_pid(criu_notify_arg_t na); + +/* + * If CRIU sends and FD in the case of 'orphan-pts-master', + * this FD can be retrieved with criu_get_orphan_pts_master_fd(). + * + * If no FD has been received this will return -1. + * + * To make sure the FD returned is valid this function has to be + * called after the callback with the 'action' 'orphan-pts-master'. + */ +int criu_get_orphan_pts_master_fd(void); + +/* Here is a table of return values and errno's of functions + * from the list down below. + * + * Return value errno Description + * ---------------------------------------------------------------------------- + * 0 undefined Success. + * + * >0 undefined Success(criu_restore() only). + * + * -BADE rpc err (0 for now) RPC has returned fail. + * + * -ECONNREFUSED errno Unable to connect to CRIU. + * + * -ECOMM errno Unable to send/recv msg to/from CRIU. + * + * -EINVAL undefined CRIU doesn't support this type of request. + * You should probably update CRIU. + * + * -EBADMSG undefined Unexpected response from CRIU. + * You should probably update CRIU. + */ +int criu_check(void); +int criu_dump(void); +int criu_restore(void); +int criu_restore_child(void); + +/* + * Perform dumping but with preliminary iterations. Each + * time an iteration ends the ->more callback is called. + * The callback's return value is + * - positive -- one more iteration starts + * - zero -- final dump is performed and call exits + * - negative -- dump is aborted, the value is returned + * back from criu_dump_iters + * + * The @pi argument is an opaque value that caller may + * use to request pre-dump statistics (not yet implemented). + */ +typedef void *criu_predump_info; +int criu_dump_iters(int (*more)(criu_predump_info pi)); + +/* + * Get the version of the actual binary used for RPC. + * + * As this library is just forwarding all tasks to an + * independent (of this library) CRIU binary, the actual + * version of the CRIU binary can be different then the + * hardcoded values in the libary (version.h). + * To be able to easily check the version of the CRIU binary + * the function criu_get_version() returns the version + * in the following format: + * + * (major * 10000) + (minor * 100) + sublevel + * + * If the CRIU binary has been built from a git checkout + * minor will increased by one. + */ +int criu_get_version(void); + +/* + * Check if the version of the CRIU binary is at least + * 'minimum'. Version has to be in the same format as + * described for criu_get_version(). + * + * Returns 1 if CRIU is at least 'minimum'. + * Returns 0 if CRIU is too old. + * Returns < 0 if there was an error. + */ +int criu_check_version(int minimum); + +/* + * Same as the list above, but lets you have your very own options + * structure and lets you set individual options in it. + */ +typedef struct criu_opts criu_opts; + +int criu_local_init_opts(criu_opts **opts); +void criu_local_free_opts(criu_opts *opts); + +int criu_local_set_service_address(criu_opts *opts, const char *path); +void criu_local_set_service_fd(criu_opts *opts, int fd); + +void criu_local_set_service_fd(criu_opts *opts, int fd); + +void criu_local_set_pid(criu_opts *opts, int pid); +void criu_local_set_images_dir_fd(criu_opts *opts, int fd); /* must be set for dump/restore */ +int criu_local_set_parent_images(criu_opts *opts, const char *path); +int criu_local_set_service_binary(criu_opts *opts, const char *path); +void criu_local_set_work_dir_fd(criu_opts *opts, int fd); +void criu_local_set_leave_running(criu_opts *opts, bool leave_running); +void criu_local_set_ext_unix_sk(criu_opts *opts, bool ext_unix_sk); +int criu_local_add_unix_sk(criu_opts *opts, unsigned int inode); +void criu_local_set_tcp_established(criu_opts *opts, bool tcp_established); +void criu_local_set_tcp_skip_in_flight(criu_opts *opts, bool tcp_skip_in_flight); +void criu_local_set_tcp_close(criu_opts *opts, bool tcp_close); +void criu_local_set_weak_sysctls(criu_opts *opts, bool val); +void criu_local_set_evasive_devices(criu_opts *opts, bool evasive_devices); +void criu_local_set_shell_job(criu_opts *opts, bool shell_job); +void criu_local_set_orphan_pts_master(criu_opts *opts, bool orphan_pts_master); +void criu_local_set_file_locks(criu_opts *opts, bool file_locks); +void criu_local_set_track_mem(criu_opts *opts, bool track_mem); +void criu_local_set_auto_dedup(criu_opts *opts, bool auto_dedup); +void criu_local_set_force_irmap(criu_opts *opts, bool force_irmap); +void criu_local_set_link_remap(criu_opts *opts, bool link_remap); +void criu_local_set_log_level(criu_opts *opts, int log_level); +int criu_local_set_log_file(criu_opts *opts, const char *log_file); +void criu_local_set_cpu_cap(criu_opts *opts, unsigned int cap); +int criu_local_set_root(criu_opts *opts, const char *root); +void criu_local_set_manage_cgroups(criu_opts *opts, bool manage); +void criu_local_set_manage_cgroups_mode(criu_opts *opts, enum criu_cg_mode mode); +int criu_local_set_freeze_cgroup(criu_opts *opts, const char *name); +int criu_local_set_lsm_profile(criu_opts *opts, const char *name); +void criu_local_set_timeout(criu_opts *opts, unsigned int timeout); +void criu_local_set_auto_ext_mnt(criu_opts *opts, bool val); +void criu_local_set_ext_sharing(criu_opts *opts, bool val); +void criu_local_set_ext_masters(criu_opts *opts, bool val); +int criu_local_set_exec_cmd(criu_opts *opts, int argc, char *argv[]); +int criu_local_add_ext_mount(criu_opts *opts, const char *key, const char *val); +int criu_local_add_veth_pair(criu_opts *opts, const char *in, const char *out); +int criu_local_add_cg_root(criu_opts *opts, const char *ctrl, const char *path); +int criu_local_add_enable_fs(criu_opts *opts, const char *fs); +int criu_local_add_skip_mnt(criu_opts *opts, const char *mnt); +void criu_local_set_ghost_limit(criu_opts *opts, unsigned int limit); +int criu_local_add_irmap_path(criu_opts *opts, const char *path); +int criu_local_add_cg_props(criu_opts *opts, const char *stream); +int criu_local_add_cg_props_file(criu_opts *opts, const char *path); +int criu_local_add_cg_dump_controller(criu_opts *opts, const char *name); +int criu_local_add_cg_yard(criu_opts *opts, const char *path); +int criu_local_add_inherit_fd(criu_opts *opts, int fd, const char *key); +int criu_local_add_external(criu_opts *opts, const char *key); +int criu_local_set_page_server_address_port(criu_opts *opts, const char *address, int port); +int criu_local_set_pre_dump_mode(criu_opts *opts, enum criu_pre_dump_mode mode); + +void criu_local_set_notify_cb(criu_opts *opts, int (*cb)(char *action, criu_notify_arg_t na)); + +int criu_local_check(criu_opts *opts); +int criu_local_dump(criu_opts *opts); +int criu_local_restore(criu_opts *opts); +int criu_local_restore_child(criu_opts *opts); +int criu_local_dump_iters(criu_opts *opts, int (*more)(criu_predump_info pi)); + +int criu_local_get_version(criu_opts *opts); +int criu_local_check_version(criu_opts *opts, int minimum); + +#ifdef __GNUG__ +} +#endif + +#endif /* __CRIU_LIB_H__ */ diff --git a/study_clang/Mimic/app_migrate_class/lib/libcriu.so b/study_clang/Mimic/app_migrate_class/lib/libcriu.so new file mode 100644 index 0000000..497be19 Binary files /dev/null and b/study_clang/Mimic/app_migrate_class/lib/libcriu.so differ diff --git a/study_clang/Mimic/app_migrate_class/migrate b/study_clang/Mimic/app_migrate_class/migrate new file mode 100755 index 0000000..343a7a1 Binary files /dev/null and b/study_clang/Mimic/app_migrate_class/migrate differ diff --git a/study_clang/Mimic/app_migrate_class/migrate_criu b/study_clang/Mimic/app_migrate_class/migrate_criu new file mode 100755 index 0000000..617b34d Binary files /dev/null and b/study_clang/Mimic/app_migrate_class/migrate_criu differ diff --git a/study_clang/Mimic/app_migrate_class/migrate_criu.cpp b/study_clang/Mimic/app_migrate_class/migrate_criu.cpp new file mode 100644 index 0000000..1a18031 --- /dev/null +++ b/study_clang/Mimic/app_migrate_class/migrate_criu.cpp @@ -0,0 +1,387 @@ +/************************************************************************* + > File Name: migrate.cpp + > Author: TianLun Song + > Mail: songtianlun@frytea.com + > Blog: https://blog.frytea.com + > Created Time: Wed 23 Dec 2020 07:10:09 PM CST + ************************************************************************/ + +#include +#include /* sort() */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class CMigrateApp +{ +#define CRIU_BINARY "/usr/sbin/criu" +#define CRIU_DIR "/tmp/criu" +#define IMG_DIR "images" +#define DUMP_LOG_FILE "dump.log" +#define RESTORE_LOG_FILE "restore.log" +#define RESTORE_PID_FILE "restore.pid" +#define INHERIT_FD_OPTION "--inherit-fd" +#define OLD_LOG_FILE "/tmp/criu/oldlog" +#define NEW_LOG_FILE "/tmp/criu/newlog" + +public: + // CMigrateApp(int iPid = 0); + CMigrateApp(char *sCMD, int iPid = 0); + ~CMigrateApp(){} + char *GetCMD(); + char *GetImgDir(); + int Checkout(); + int Restore(); + int GetPid(); + int GetUnixNum(); + +private: + int GetPidByCMD(char * sCMD); + int SetPidByCMD(char * sCMD); + void GetCMDByPid(int iPid, char *sCMD); + int isUnixActivity(unsigned int iNode, char * cPid); + int SetUnixByPid(int iPid); + void Mkdir_safe(char *dirname, int mode); + +private: + int i_criu_pid; + int i_unix_num; + char s_criu_cmd[64]; + char s_criu_pid[8]; + char s_criu_img[64]; + char s_criu_dump_log[64]; + char s_criu_restore_log[64]; + char s_criu_restore_pidfile[64]; + char s_external_sk_ino[1024]; + char s_inh_unixsk_arg[1024]; + const char *s_dump_argv[15] = { + "criu", "dump", "-j", + "-D", s_criu_img, "-o", s_criu_dump_log, + "-v4", "-x", "--lib /root/stl/lib", + "--tcp-established", + s_external_sk_ino, + "-t", s_criu_pid, + NULL }; + const char *s_restore_argv[18] = { + "criu", "restore", "-d","-j", + "-D", s_criu_img, "-o", s_criu_restore_log, + "--pidfile", s_criu_restore_pidfile, + "-v4", "-x", "--lib /root/stl/lib", + "--tcp-established", + s_inh_unixsk_arg, + NULL }; +}; + +CMigrateApp::CMigrateApp(char* sCMD, int iPid) +{ + char sMkdir[64] = {0}; + + // init data + memset(s_criu_img, 0x00, sizeof s_criu_img); + memset(s_criu_dump_log, 0x00, sizeof s_criu_dump_log); + memset(s_criu_restore_log, 0x00, sizeof s_criu_restore_log); + memset(s_criu_restore_pidfile, 0x00, sizeof s_criu_restore_pidfile); + memset(s_criu_cmd, 0x00, sizeof s_criu_cmd); + i_criu_pid = 0; + i_unix_num = 0; + memset(s_criu_pid, 0x00, sizeof s_criu_pid); + memset(s_external_sk_ino, 0x00, sizeof s_external_sk_ino); + memset(s_inh_unixsk_arg, 0x00, sizeof s_inh_unixsk_arg); + + if( 0 != iPid ) + { + GetCMDByPid(iPid, s_criu_cmd); + i_criu_pid = iPid; + snprintf(s_criu_pid, sizeof s_criu_pid, "%d", i_criu_pid); + } + else if( NULL != sCMD ) + { + strcpy(s_criu_cmd, sCMD); + SetPidByCMD(s_criu_cmd); + } + else + { + printf("Error of [iPid: %d] or [sCMD: %s] ", iPid, sCMD); + } + + snprintf(s_criu_img, sizeof s_criu_img, "%s/%s/%s", CRIU_DIR, s_criu_cmd, IMG_DIR); + snprintf(s_criu_dump_log, sizeof s_criu_dump_log, "%s/%s/%s", CRIU_DIR, s_criu_cmd, DUMP_LOG_FILE); + snprintf(s_criu_restore_log, sizeof s_criu_restore_log, "%s/%s/%s", CRIU_DIR, s_criu_cmd, RESTORE_LOG_FILE); + snprintf(s_criu_restore_pidfile, sizeof s_criu_restore_pidfile, "%s/%s/%s", CRIU_DIR, s_criu_cmd, RESTORE_PID_FILE); + i_unix_num = SetUnixByPid(i_criu_pid); + // printf("PCMD: %s, Unix Sum: %d\n",sCMD, i_unix_num); + + sprintf(sMkdir,"mkdir -p %s &", s_criu_img); + system(sMkdir); + printf("App will be to Migrate: [iPid: %d] [CMD: %s] [Unix Num: %d]\n", i_criu_pid, s_criu_cmd, i_unix_num); +} + +int CMigrateApp::Checkout() +{ + char sCmd[2048] = {0}; + char sCpCMd[64] = {0}; + if(0 >= i_criu_pid) + { + printf("Error Pid! Dump failed!\n"); + return -1; + } + + for (int i = 0; s_dump_argv[i] != NULL; i++) + sprintf(sCmd, "%s %s", sCmd, s_dump_argv[i]); + strcat(sCmd,"&"); + printf("Dump [CMD:%s] [PID:%d] [Unix Num:%d] cmd: %s\n",s_criu_cmd,i_criu_pid, i_unix_num, sCmd); + system(sCmd); + + snprintf(sCpCMd, sizeof sCpCMd, "cp /tmp/1 /tmp/criu/%s/", s_criu_cmd); + system(sCpCMd); + return 0; +} + +int CMigrateApp::Restore() +{ + char sCmd[2048] = {0}; + char sCpCmd[64] = {0}; + if(0 >= i_criu_pid) + { + printf("Error Pid! Restore neet to right dump!\n"); + return -1; + } + for (int i = 0; s_restore_argv[i] != NULL; i++) + sprintf(sCmd, "%s %s", sCmd, s_restore_argv[i]); + strcat(sCmd,"&"); + /* 进程有几个socket就创建几次 */ + for (int i = 0; i < i_unix_num; i++) + socket(AF_UNIX, SOCK_STREAM, 0); + /* 将该进程转储时的/tmp/1 复制到指定路径下 */ + snprintf(sCpCmd, sizeof sCpCmd, "cp /tmp/criu/%s/1 /tmp/1", s_criu_cmd); + system(sCpCmd); + system("chmod 644 /tmp/1"); + /* 恢复 */ + printf("Restore [CMD:%s] [Unix Num:%d] cmd: %s\n",s_criu_cmd, i_unix_num, sCmd); + system(sCmd); + return 0; +} + +int CMigrateApp::GetPidByCMD(char *sCMD) +{ + char cPid[62] = {0}; + char sSeekCmd[64] = {0}; + FILE *fPid = NULL; + int iPid = -1; + sprintf(sSeekCmd, "pgrep %s | head -1",sCMD); + fPid = popen(sSeekCmd, "r"); + if(NULL == fPid) + return -1; + fgets(cPid, sizeof(cPid), fPid); + iPid = atoi(cPid); + // printf("SeekCmd: %s, Pid: %d, cPid: %s\n",sSeekCmd,iPid,cPid); + return iPid; +} +void CMigrateApp::GetCMDByPid(int iPid, char *sCMD) +{ + FILE *fcmd = NULL; + char sGetCMD[64] = {0}; + snprintf(sGetCMD, sizeof sGetCMD, "grep 'Name' /proc/%d/status | awk '{print $2}'", iPid); + fcmd = popen(sGetCMD, "r"); + fgets(sCMD, sizeof(sCMD), fcmd); +} +int CMigrateApp::SetPidByCMD(char *sCMD) +{ + char cPid[62] = {0}; + char sSeekCmd[64] = {0}; + FILE *fPid = NULL; + int iPid = -1; + sprintf(sSeekCmd, "pgrep %s | head -1", sCMD); + fPid = popen(sSeekCmd, "r"); + if(NULL == fPid) + return -1; + fgets(cPid, sizeof(cPid), fPid); + iPid = atoi(cPid); + + i_criu_pid = atoi(cPid); + snprintf(s_criu_pid, sizeof s_criu_pid, "%d", iPid); + // strcpy(s_criu_pid, cPid); + pclose(fPid); + //printf("SeekCmd: %s, Pid: %d, cPid: %s\n",sSeekCmd,iPid,cPid); + return iPid; +} +int CMigrateApp::SetUnixByPid(int iPid) +{ + char sUnixStatCmd[64] = {0}; + char sNowCriuUnixCmd[64] = {0}; + char sNosRestoreUnixCmd[64] = {0}; + FILE *fpUnixStat; + int iFdNum = 3; + char tmp[2048]; //存储每一行输出 + unsigned int iNode; + int iSumUnix = 0; + // int i = 0; + + if( iPid <=0 ) + return 0; + + sprintf(sUnixStatCmd, "cat /proc/%d/net/unix | awk '{print $7}'", iPid); + fpUnixStat = popen(sUnixStatCmd, "r"); + if (fpUnixStat == NULL) { + return -1; + } + // 跳过第一条无效数据 + fgets(tmp, sizeof(tmp) - 1, fpUnixStat); + // i = 0; + // 输出检查状态 + // printf("check unix .."); + // fflush(stdout); + while (fgets(tmp, sizeof(tmp) - 1, fpUnixStat)) { + // 输出检查状态 + // switch(i++){ + // case 1: + // printf("."); + // fflush(stdout); + // break; + // case 5: + // printf("\b"); + // fflush(stdout); + // break; + // case 10: + // i=0; + // default: + // break; + // }; + sscanf(tmp, "%u", &iNode); + if(!isUnixActivity(iNode,s_criu_cmd)) + continue; + if(iNode==0) + continue; + // printf("iPid: %d, Unix iNode: %d, is activity.\n", iPid,iNode); + snprintf(sNowCriuUnixCmd, sizeof(sNowCriuUnixCmd), "--ext-unix-sk=%u ", + (unsigned int)iNode); + snprintf(sNowCriuUnixCmd, sizeof(sNowCriuUnixCmd), "--external unix[%u] ", + (unsigned int)iNode); + snprintf(sNosRestoreUnixCmd, sizeof sNosRestoreUnixCmd, "--inherit-fd fd[%d]:socket:[%u] ", + iFdNum++,(unsigned int)iNode); + strcat(s_external_sk_ino, sNowCriuUnixCmd); + strcat(s_inh_unixsk_arg, sNosRestoreUnixCmd); + iSumUnix++; + } + // printf("\r"); // 清空 check unix 状态字符打印 + pclose(fpUnixStat); + return iSumUnix; +} +int CMigrateApp::isUnixActivity(unsigned int iNode, char * cPid) +{ + char sCheckUnixCmd[64] = {0}; + FILE *fpCheckUnix; + char tmp[2048]; + // 检查当前 unix socket 是否处于活跃状态 + sprintf(sCheckUnixCmd, "netstat -xap | grep %s | grep %u", cPid, iNode); + fpCheckUnix = popen(sCheckUnixCmd, "r"); + if (fpCheckUnix == NULL) { + return -1; + } + memset(tmp, 0x0, sizeof(tmp)); + fgets(tmp, sizeof(tmp) - 1, fpCheckUnix); + pclose(fpCheckUnix); + printf("Check Cmd: %s, Rst len: %d", sCheckUnixCmd, (int)strlen(tmp)); + fflush(stdout); + printf("%40s\r"," "); // 使用空格清理脏字符并回退光标至行首 + fflush(stdout); + if(strlen(tmp)>1) + return 1; + return 0; +} +int CMigrateApp::GetPid() +{ + return i_criu_pid; +} +int CMigrateApp::GetUnixNum() +{ + return i_unix_num; +} +char *CMigrateApp::GetCMD() +{ + return s_criu_cmd; +} +char *CMigrateApp::GetImgDir() +{ + return s_criu_img; +} + +void CMigrateApp::Mkdir_safe(char *dirname, int mode) +{ + if (mkdir(dirname, mode) == -1 && errno != EEXIST) + printf("Success to mkdir dirname=%s mode=0x%x\n", dirname, mode); + else + printf("Fail to make dir %s", dirname); +} + +// 自定义对象比较函数(根据unix个数排序) +bool cmp(CMigrateApp a, CMigrateApp b) +{ + return a.GetUnixNum() < b.GetUnixNum(); +} +void MigrateMySelf() +{ + char sRestoreCmd[128] = {0}; + CMigrateApp CMigrateMySelf(NULL, getpid()); + snprintf(sRestoreCmd, sizeof sRestoreCmd, "criu restore -D %s -j", CMigrateMySelf.GetImgDir()); + printf("Run cmd when restore: %s\n", sRestoreCmd); + CMigrateMySelf.Checkout(); +} + +int main() +{ + char piggie_cmd[21][64] = { + /* create ipc unix socket */ + "arpd", "dhcp", "lldpd", "ospfd", "ripd", "snmptrap", "rmon", "ripngd", "mstp", "lag","master","zebra","pidmonitor", + "ntpclient", "snmpd", "udpsvd", "brctl", "l2monitor", "vtysh", "configmanage", "udhcpd"}; + std::vector vMigrateApps; + + // 清空进程检查点数据文件夹,避免遗留文件影响进程恢复 + system("rm -rf /tmp/criu/*"); + + for(int i = 0; i < 21; i++) + { + CMigrateApp iC(piggie_cmd[i]); + vMigrateApps.push_back(iC); + // printf("%s [PID %d] will be push back, vector size: %d\n", iC.GetCMD(),iC.GetPid(), (int)vMigrateApps.size()); + } + + printf("-----------------------after sort-----------------------\n"); + for(auto v : vMigrateApps) + { + printf("[%s:%d] has %d unix socket\n", v.GetCMD(), v.GetPid(), v.GetUnixNum()); + } + // sort(vMigrateApps.begin(), vMigrateApps.end(),cmp); + printf("-------------------------- dump -------------------------\n"); + for(auto v : vMigrateApps) + { + v.Checkout(); + } + for(int j=10;j>0;j--) + { + printf("Waiting for start restore....%d\n",j); + if(j==5) + MigrateMySelf(); + sleep(1); + } + + printf("Enter any character to continue\n"); + getchar(); + printf("------------------------ restore ------------------------\n"); + for(auto v : vMigrateApps) + { + if(v.GetPid()<=0) + { + printf("failed to dump, jump %s.\n", v.GetCMD()); + continue; + } + v.Restore(); + } + return 0; +} diff --git a/study_clang/Mimic/app_migrate_class/migrate_libcriu b/study_clang/Mimic/app_migrate_class/migrate_libcriu new file mode 100755 index 0000000..4eddf9e Binary files /dev/null and b/study_clang/Mimic/app_migrate_class/migrate_libcriu differ diff --git a/study_clang/Mimic/app_migrate_class/migrate_libcriu.cpp b/study_clang/Mimic/app_migrate_class/migrate_libcriu.cpp new file mode 100644 index 0000000..9b2174b --- /dev/null +++ b/study_clang/Mimic/app_migrate_class/migrate_libcriu.cpp @@ -0,0 +1,149 @@ +/************************************************************************* + > File Name: migrate.cpp + > Author: TianLun Song + > Mail: songtianlun@frytea.com + > Blog: https://blog.frytea.com + > Created Time: Wed 23 Dec 2020 07:10:09 PM CST + ************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +class CMigrateApp +{ + public: + CMigrateApp(int iPid = 0); + CMigrateApp(char *sPid); + ~CMigrateApp(); + int Checkout(); + int Restore(); + int GetPid(); + + private: + int GetPidByCMD(char * sCMD); + + private: + char criu_dir[64]; + char criu_server[64]; + char criu_log[64]; + char criu_cmd[64]; + int criu_log_level; + int criu_pid; +}; + + +CMigrateApp::CMigrateApp(int iPid) +{ + strcpy(criu_dir, "./migrate_imgs"); + strcpy(criu_server, "/root/criu_service.socket"); + strcpy(criu_log, "criu.log"); + criu_log_level = 4; + criu_pid = iPid; + + + + criu_init_opts(); + criu_set_service_address(criu_server); + int fd = open(criu_dir, O_DIRECTORY); + criu_set_images_dir_fd(fd); + + criu_set_log_file(criu_log); + criu_set_log_level(criu_log_level); + + criu_set_shell_job(true); +} + +CMigrateApp::CMigrateApp(char* sPid) +{ + char sMkdir[64] = {0}; + + strcpy(criu_dir, "/root/migrate_imgs/"); + strcpy(criu_server, "/root/criu_service.socket"); + strcpy(criu_log, "criu.log"); + criu_log_level = 4; + + strcpy(criu_cmd, sPid); + strcat(criu_dir, sPid); + sprintf(sMkdir,"%s %s", "mkdir -p", criu_dir); + system(sMkdir); + + criu_pid = GetPidByCMD(criu_cmd); + //cout << "Pid: " << criu_pid << endl; + + + criu_init_opts(); + criu_set_service_address(criu_server); + int fd = open(criu_dir, O_DIRECTORY); + criu_set_images_dir_fd(fd); + + criu_set_log_file(criu_log); + criu_set_log_level(criu_log_level); + + criu_set_shell_job(true); + criu_set_ext_unix_sk(true); +} + +int CMigrateApp::Checkout() +{ + if(0 >= criu_pid) + { + //cout << "Error Pid! Dump failed!" << endl; + return -1; + } + criu_set_pid(criu_pid); + return criu_dump(); +} + +int CMigrateApp::Restore() +{ + return criu_restore(); +} + +int CMigrateApp::GetPidByCMD(char *sCMD) +{ + char cPid[62] = {0}; + char sSeekCmd[64] = {0}; + FILE *fPid = NULL; + int iPid = -1; + sprintf(sSeekCmd, "%s %s %s", "pgrep", sCMD, "| head -1"); + fPid = popen(sSeekCmd, "r"); + if(NULL == fPid) + return -1; + fgets(cPid, sizeof(cPid), fPid); + iPid = atoi(cPid); + //cout << "SeekCmd: " << sSeekCmd << ", Pid: " << iPid << ", cPid: " << cPid << endl; + return iPid; +} +int CMigrateApp::GetPid() +{ + return criu_pid; +} + +int main() +{ + char piggie_cmd[21][64] = { + "arpd","dhcp","lldpd","ntpclient","ripd","snmpd","udpsvd", + "brctl","l2monitor","master ","ospfd","ripngd","snmptrap","vtysh", + "configmanage","lag","mstp","pidmonitor","rmon","udhcpd","zebra"}; + CMigrateApp * migrate_app[21]; + + for(int i = 0; i < 21; i++) + { + migrate_app[i] = new CMigrateApp(piggie_cmd[i]); + // int iRet = 0; + cout << "Dump " << piggie_cmd[i] << "[ID:" << migrate_app[i]->GetPid() << "]" << " Result: " << migrate_app[i]->Checkout() << endl; + //sleep(1); + //cout << "Restore " << piggie_cmd[i] << " Result: " << migrate_app[i]->Restore() << endl; + //sleep(5); + } + return 0; +} \ No newline at end of file diff --git a/study_clang/Mimic/compress/main b/study_clang/Mimic/compress/main new file mode 100755 index 0000000..53b45d7 Binary files /dev/null and b/study_clang/Mimic/compress/main differ diff --git a/study_clang/Mimic/compress/main.c b/study_clang/Mimic/compress/main.c new file mode 100644 index 0000000..3acb33d --- /dev/null +++ b/study_clang/Mimic/compress/main.c @@ -0,0 +1,141 @@ +/************************************************************************* + > File Name : main.c + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Fri 03 Jul 2020 08:38:34 AM CST + ************************************************************************/ + +#include +#include +#include +#include +#include + +#define dPrint(fmt, ...) do{fprintf(stderr, "[%s:%d] " fmt "\r\n", __FUNCTION__, __LINE__, ##__VA_ARGS__);}while(0) +#define HexPrint(_buf, _len) \ +{\ + int _m_i = 0;\ + char *_m_buf = (char *)(_buf);\ + int _m_len = (int)(_len);\ + printf("[%s:%d] \r\n", __FUNCTION__, __LINE__);\ + printf("*****************************\n");\ + for(_m_i = 0; _m_i < _m_len; _m_i++)\ + {\ + printf("\033[32m%02x \033[0m", _m_buf[_m_i] & 0xff);\ + if(!((_m_i+1) % 10)) printf("\n");\ + }\ + printf("\nsize = %d\n*****************************\n", _m_len);\ +} + +int data_compress(char *idata, int ilen, char *odata, int *olen) +{ + z_stream z = {0}; + + z.next_in = idata; + z.avail_in = ilen; + z.next_out = odata; + z.avail_out = *olen; + + /* 使用最高压缩比 */ + if (deflateInit(&z, Z_BEST_COMPRESSION) != Z_OK) { + printf("deflateInit failed!\n"); + return -1; + } + + if (deflate(&z, Z_NO_FLUSH) != Z_OK) { + printf("deflate Z_NO_FLUSH failed!\n"); + return -1; + } + + if (deflate(&z, Z_FINISH) != Z_STREAM_END) { + printf("deflate Z_FINISH failed!\n"); + return -1; + } + + if (deflateEnd(&z) != Z_OK) { + printf("deflateEnd failed!\n"); + return -1; + } + + *olen = *olen - z.avail_out; + + return 0; +} + + +int data_decompress(char *idata, int ilen, char *odata, int *olen) +{ + z_stream z = {0}; + + z.next_in = idata; + z.avail_in = ilen; + z.next_out = odata; + z.avail_out = *olen; + + if (inflateInit(&z) != Z_OK) { + printf("inflateInit failed!\n"); + return -1; + } + + if (inflate(&z, Z_NO_FLUSH) != Z_STREAM_END) { + printf("inflate Z_NO_FLUSH failed!\n"); + return -1; + } + + if (inflate(&z, Z_FINISH) != Z_STREAM_END) { + printf("inflate Z_FINISH failed!\n"); + return -1; + } + + if (inflateEnd(&z) != Z_OK) { + printf("inflateEnd failed!\n"); + return -1; + } + + *olen = *olen - z.avail_out; + + return 0; +} + +//char data[] = "\nYouth\n\nYouth is not a time of life; it is a state of mind; it is not a matter of rosy cheeks, red lips and supple knees; it is a matter of the will, a quality of the imagination, a vigor of the emotions; it is the freshness of the deep springs of life.\n\nYouth means a temperamental predominance of courage over timidity, of the appetite for adventure over the love of ease. This often exists in a man of 60 more than a boy of 20. Nobody grows old merely by a number of years. We grow old by deserting our ideals.\n\nYears may wrinkle the skin, but to give up enthusiasm wrinkles the soul. Worry, fear, self-distrust bows the heart and turns the spirit back to dust.\n\nWhether 60 or 16, there is in every human being’s heart the lure of wonders, the unfailing appetite for what’s next and the joy of the game of living. In the center of your heart and my heart, there is a wireless station; so long as it receives messages of beauty, hope, courage and power from man and from the infinite, so long as you are young.\n\nWhen your aerials are down, and your spirit is covered with snows of cynicism and the ice of pessimism, then you’ve grown old, even at 20; but as long as your aerials are up, to catch waves of optimism, there’s hope you may die young at 80."; +char data[] = "aaaaaaaabbbbbbbbbbbbbbccccccccccccccc"; +int main(int argc, char **argv) +{ + int compress_len, decompress_len; +// unsigned char data[1024] = {0}; + unsigned char compress_buf[2048] = {0}; + unsigned char decompress_buf[4096] = {0}; + +// memset(data, 0x00, sizeof(data)); + memset(compress_buf, 0x00, sizeof(compress_buf)); + memset(decompress_buf, 0x00, sizeof(decompress_buf)); + +// data[0] = 0x01; +// data[777] = 0x02; + + dPrint("... origin data ..."); + HexPrint(data, sizeof(data)); + + /* 压缩数据 */ + compress_len = sizeof(compress_buf); + if (data_compress(data, sizeof(data), + compress_buf, &compress_len) < 0) { + return -1; + } + + dPrint("... compress data ..."); + HexPrint(compress_buf, compress_len); + + /* 解压缩数据 */ + decompress_len = sizeof(decompress_buf); + if (data_decompress(compress_buf, compress_len, + decompress_buf, &decompress_len) < 0) { + return -1; + } + + dPrint("... decompress data ..."); + HexPrint(decompress_buf, decompress_len); + + return 0; +} + diff --git a/study_clang/Mimic/container_migrate/migrate.cpp b/study_clang/Mimic/container_migrate/migrate.cpp new file mode 100644 index 0000000..e0f30f5 --- /dev/null +++ b/study_clang/Mimic/container_migrate/migrate.cpp @@ -0,0 +1,13 @@ +/************************************************************************* + > File Name: migrate.cpp + > Author: TianLun Song + > Mail: songtianlun@frytea.com + > Blog: https://blog.frytea.com + > Created Time: Wed 23 Dec 2020 07:10:09 PM CST + ************************************************************************/ +#include "migrate.h" + +CMigrateApp::CMigrateApp() +{ + +} diff --git a/study_clang/Mimic/container_migrate/migrate.h b/study_clang/Mimic/container_migrate/migrate.h new file mode 100644 index 0000000..fb93dbb --- /dev/null +++ b/study_clang/Mimic/container_migrate/migrate.h @@ -0,0 +1,17 @@ +/************************************************************************* + > File Name: migrate.h + > Author: TianLun Song + > Mail: songtianlun@frytea.com + > Blog: https://blog.frytea.com + > Created Time: Wed 23 Dec 2020 07:10:09 PM CST + ************************************************************************/ +#include + +using namespace std; + +class CMigrateApp +{ + public: + CMigrateApp(); + ~CMigrateApp(); +}; diff --git a/study_clang/Mimic/container_migrate/migrate.py b/study_clang/Mimic/container_migrate/migrate.py new file mode 100644 index 0000000..5597ac4 --- /dev/null +++ b/study_clang/Mimic/container_migrate/migrate.py @@ -0,0 +1,19 @@ +#!/bin/python +# Author: Tianlun Song +# Blog: https://blog.frytea.com +# Time:2020-12-23 18:48:06 +# Name:migrate.py +# Version:V1.0 +# Description:This is a production script. + +import os + +list_apps = [ \ + "piggie", \ + "while"] + +dict_apps = {} + +i = 0; + + diff --git a/study_clang/Mimic/judge_sysinfo/CJudgeSysInfo.cpp b/study_clang/Mimic/judge_sysinfo/CJudgeSysInfo.cpp new file mode 100644 index 0000000..d7170fa --- /dev/null +++ b/study_clang/Mimic/judge_sysinfo/CJudgeSysInfo.cpp @@ -0,0 +1,11 @@ +/************************************************************************* + > File Name: CJudgeSysInfo.cpp + > Author: SongTL + > Mail: songtianlun@comleader.com.cn + > Created Time: 2020年07月21日 星期二 11时41分51秒 + ************************************************************************/ + +#include ""CJudgeSysInfo.h" + +using namespace std; + diff --git a/study_clang/Mimic/judge_sysinfo/CJudgeSysInfo.h b/study_clang/Mimic/judge_sysinfo/CJudgeSysInfo.h new file mode 100644 index 0000000..edc7356 --- /dev/null +++ b/study_clang/Mimic/judge_sysinfo/CJudgeSysInfo.h @@ -0,0 +1,43 @@ +/************************************************************************* + > File Name: CJudgeSysInfo.h + > Author: SongTL + > Mail: songtianlun@comleader.com.cn + > Created Time: 2020年07月21日 星期二 11时44分09秒 + ************************************************************************/ + +#include +using namespace std; + +struct Msg +{ + uint uiType; + uint uiCpuRate; + uint uiMemRate; + uint uiTcpEstablishNum; + uint uiRunningProcessNum; + uint uiCronNum; + char szPasswdMd5[16]; +}; + +struct stProcessState +{ + uint uiType; + uint uiProcessId; + uint uiProcessState; +}; + +struct stFileNum +{ + uint uiType; + uint szPath[32]; + uint uiFileNum; +}; + +struct stLogMsg +{ + uint uiType; + char szLogFile[32]; + char szMsg[128]; +}; + +class diff --git a/study_clang/Mimic/message_queue/CMessageQueue.cpp b/study_clang/Mimic/message_queue/CMessageQueue.cpp new file mode 100644 index 0000000..ab4c515 --- /dev/null +++ b/study_clang/Mimic/message_queue/CMessageQueue.cpp @@ -0,0 +1,13 @@ +/************************************************************************* + > File Name: CMessageQueue.cpp + > Author: SongTL + > Mail: songtianlun@comleader.com.cn + > Created Time: 2020年07月21日 星期二 16时38分21秒 + ************************************************************************/ + +#include + + + +using namespace std; + diff --git a/study_clang/Mimic/message_queue/CMessageQueue.h b/study_clang/Mimic/message_queue/CMessageQueue.h new file mode 100644 index 0000000..75169c2 --- /dev/null +++ b/study_clang/Mimic/message_queue/CMessageQueue.h @@ -0,0 +1,28 @@ +/************************************************************************* + > File Name: CMessageQueue.h + > Author: SongTL + > Mail: songtianlun@comleader.com.cn + > Created Time: 2020年07月21日 星期二 16时46分37秒 + ************************************************************************/ + +#ifndef CMESSAGEQUEUE_H +#define CMESSAGEQUEUE_H + +template +class ConcurrentQueue +{ + ConcurrentQueue& operator = (const ConcurrentQueue&) = delete; + ConcurrentQueue(const ConcurrentQueue& other) = delete; + + public: + ConcurrentQueue() : _queue(), _mutex(), _condition() {} + virtual ~ConcurrentQueue() {} + + void Push(Type record) + { + std::lock_guard lock(_mutex); + _queue.push(record); + _condition.notify_one(); + } +} +#endif diff --git a/study_clang/Mimic/message_queue/message_queue b/study_clang/Mimic/message_queue/message_queue new file mode 100755 index 0000000..bc85439 Binary files /dev/null and b/study_clang/Mimic/message_queue/message_queue differ diff --git a/study_clang/Mimic/message_queue/message_queue_test.cpp b/study_clang/Mimic/message_queue/message_queue_test.cpp new file mode 100644 index 0000000..db7669e --- /dev/null +++ b/study_clang/Mimic/message_queue/message_queue_test.cpp @@ -0,0 +1,84 @@ +/************************************************************************* + > File Name: message_queue.cpp + > Author: SongTL + > Mail: songtianlun@comleader.com.cn + > Created Time: 2020年07月21日 星期二 16时19分21秒 + ************************************************************************/ +# ifndef MSGQUEUE_H +# define MSGQUEUE_H + +#include +#include +#include // usleep +#include // threads +#include +#include // messages +#include // the message queue + +using namespace std; + +pthread_mutex_t msgmutex = PTHREAD_MUTEX_INITIALIZER; + +queue msgq; + +void *msgreceiver(void *arg) +{ + long qsize; + string nextmsg; + while (true) + { + if (msgq.empty()) + { + usleep(10000); // sleep 0.01 sec before trying again + continue; + } + + // we end up here because there was something in the msg queue + pthread_mutex_lock( & msgmutex); + qsize = msgq.size(); + if (qsize > 5) + cout << "Queue size: " << qsize << endl; + nextmsg = msgq.front(); // get next message in queue + msgq.pop(); // remove it from the queue + pthread_mutex_unlock( & msgmutex); + + cout << "Processing value " << nextmsg << endl; + usleep(2000000); + } + pthread_exit((void * )0); +} // msgreceiver() + + void *msgtransmitter(void *arg) + { + string nextmsg; + while (true) + { + cin >> nextmsg; + pthread_mutex_lock( & msgmutex); + msgq.push(nextmsg); // push message onto the queue + pthread_mutex_unlock( & msgmutex); + } + pthread_exit((void * )0); + } // msgtransmitter() + + int main() + { + pthread_t thr; + + // Create threads + if (pthread_create( & thr, NULL, msgreceiver, NULL) || + pthread_create( & thr, NULL, msgtransmitter, NULL)) + { + cout << " cannot make thread\n"; + exit(1); + } + + /* + * At this point the main thread can perform its actions or end + */ + cout << "** Main thread ends **\n"; + pthread_exit((void * )0); + +} + + # endif // MSGQUEUE_H diff --git a/study_clang/Mimic/monitor_system_status/Config.ini b/study_clang/Mimic/monitor_system_status/Config.ini new file mode 100644 index 0000000..e2fa476 --- /dev/null +++ b/study_clang/Mimic/monitor_system_status/Config.ini @@ -0,0 +1,16 @@ +; Config file for monitor.cpp +[common] + +[key_resources] +cron_sum = ; +cron_dir = ; + +[key_files] +path_sum = ; +path_dir = ; +executable_sum = ; +executable_dir = ; +user_dir_sum = ; +user_dir_dir = ; +boot_sum = ; +boot_dir = ; \ No newline at end of file diff --git a/study_clang/Mimic/monitor_system_status/Makefile b/study_clang/Mimic/monitor_system_status/Makefile new file mode 100644 index 0000000..486cb41 --- /dev/null +++ b/study_clang/Mimic/monitor_system_status/Makefile @@ -0,0 +1,5 @@ +CC=g++ +monirot:monitor.cpp + $(CC) -o monitor monitor.cpp -lpthread +clean: + rm -f *.o diff --git a/study_clang/Mimic/monitor_system_status/README.md b/study_clang/Mimic/monitor_system_status/README.md new file mode 100644 index 0000000..a87c460 --- /dev/null +++ b/study_clang/Mimic/monitor_system_status/README.md @@ -0,0 +1,63 @@ + + +# Monitor System Status + +## 详述 + +监控模块共包含四个进程: + + - 关键进程运行状态监控 + - 关键系统资源 + - 关键路径文件 + - 敏感日志信息 + +关键进程包括: + - 管理进程 + - 协议进程 + - 本地配置管理器 + - 防火墙 + +关键系统资源包括: + - ~~CPU利用率~~ + - ~~内存利用率~~ + - ~~TCP Socket 连接数~~ + - ~~运行进程数~~ + - ~~当前用户及用户组信息(静)~~ + - ~~计划任务个数(静)~~ + + 关键路径文件包括: + - PATH下二进制文件(静) + - 关键可执行文件校验值(静) + - 用户目录下文件数目(静) + - 开机启动文件(静) + +敏感日志信息包括: + - 开机登录日志 + - 历史命令信息 + +> (静)表示监控信息为静态,只需将该值与预设值做比较;此外的信息均为动态信息,采用阈值比对、执行体间横向比对和执行体历史信息纵向比对等方法。 + +## 开发日志 + - 2020年07月20日 + - 实现获取用户组信息 + - 实现计划任务获取 + - 实现格式化获取当前时间 + - 2020年07月18日 + - 实现获取运行进程数 + - 实现用户信息读取及分词 + - 2020年07月17日 + - 实现内存利用率计算 + - 实现获取TCP Socket 连接数 + - 2020年07月16日 + - 实现CPU利用率计算 + - 2020年07月15日 + - 完成主体框架 + - 定义部分结构体和函数 + + diff --git a/study_clang/Mimic/monitor_system_status/ini/INIReader.h b/study_clang/Mimic/monitor_system_status/ini/INIReader.h new file mode 100644 index 0000000..11f3191 --- /dev/null +++ b/study_clang/Mimic/monitor_system_status/ini/INIReader.h @@ -0,0 +1,462 @@ +// Read an INI file into easy-to-access name/value pairs. + +// inih and INIReader are released under the New BSD license (see LICENSE.txt). +// Go to the project home page for more info: +// +// https://github.com/benhoyt/inih +/* inih -- simple .INI file parser + +inih is released under the New BSD license (see LICENSE.txt). Go to the project +home page for more info: + +https://github.com/benhoyt/inih + +*/ + +#ifndef __INI_H__ +#define __INI_H__ + +/* Make this header file easier to include in C++ code */ +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* Typedef for prototype of handler function. */ +typedef int (*ini_handler)(void* user, const char* section, + const char* name, const char* value); + +/* Typedef for prototype of fgets-style reader function. */ +typedef char* (*ini_reader)(char* str, int num, void* stream); + +/* Parse given INI-style file. May have [section]s, name=value pairs + (whitespace stripped), and comments starting with ';' (semicolon). Section + is "" if name=value pair parsed before any section heading. name:value + pairs are also supported as a concession to Python's configparser. + + For each name=value pair parsed, call handler function with given user + pointer as well as section, name, and value (data only valid for duration + of handler call). Handler should return nonzero on success, zero on error. + + Returns 0 on success, line number of first error on parse error (doesn't + stop on first error), -1 on file open error, or -2 on memory allocation + error (only when INI_USE_STACK is zero). +*/ +int ini_parse(const char* filename, ini_handler handler, void* user); + +/* Same as ini_parse(), but takes a FILE* instead of filename. This doesn't + close the file when it's finished -- the caller must do that. */ +int ini_parse_file(FILE* file, ini_handler handler, void* user); + +/* Same as ini_parse(), but takes an ini_reader function pointer instead of + filename. Used for implementing custom or string-based I/O. */ +int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler, + void* user); + +/* Nonzero to allow multi-line value parsing, in the style of Python's + configparser. If allowed, ini_parse() will call the handler with the same + name for each subsequent line parsed. */ +#ifndef INI_ALLOW_MULTILINE +#define INI_ALLOW_MULTILINE 1 +#endif + +/* Nonzero to allow a UTF-8 BOM sequence (0xEF 0xBB 0xBF) at the start of + the file. See http://code.google.com/p/inih/issues/detail?id=21 */ +#ifndef INI_ALLOW_BOM +#define INI_ALLOW_BOM 1 +#endif + +/* Nonzero to allow inline comments (with valid inline comment characters + specified by INI_INLINE_COMMENT_PREFIXES). Set to 0 to turn off and match + Python 3.2+ configparser behaviour. */ +#ifndef INI_ALLOW_INLINE_COMMENTS +#define INI_ALLOW_INLINE_COMMENTS 1 +#endif +#ifndef INI_INLINE_COMMENT_PREFIXES +#define INI_INLINE_COMMENT_PREFIXES ";" +#endif + +/* Nonzero to use stack, zero to use heap (malloc/free). */ +#ifndef INI_USE_STACK +#define INI_USE_STACK 1 +#endif + +/* Stop parsing on first error (default is to keep parsing). */ +#ifndef INI_STOP_ON_FIRST_ERROR +#define INI_STOP_ON_FIRST_ERROR 0 +#endif + +/* Maximum line length for any line in INI file. */ +#ifndef INI_MAX_LINE +#define INI_MAX_LINE 200 +#endif + +#ifdef __cplusplus +} +#endif + +/* inih -- simple .INI file parser + +inih is released under the New BSD license (see LICENSE.txt). Go to the project +home page for more info: + +https://github.com/benhoyt/inih + +*/ + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include +#include +#include + +#if !INI_USE_STACK +#include +#endif + +#define MAX_SECTION 50 +#define MAX_NAME 50 + +/* Strip whitespace chars off end of given string, in place. Return s. */ +inline static char* rstrip(char* s) +{ + char* p = s + strlen(s); + while (p > s && isspace((unsigned char)(*--p))) + *p = '\0'; + return s; +} + +/* Return pointer to first non-whitespace char in given string. */ +inline static char* lskip(const char* s) +{ + while (*s && isspace((unsigned char)(*s))) + s++; + return (char*)s; +} + +/* Return pointer to first char (of chars) or inline comment in given string, + or pointer to null at end of string if neither found. Inline comment must + be prefixed by a whitespace character to register as a comment. */ +inline static char* find_chars_or_comment(const char* s, const char* chars) +{ +#if INI_ALLOW_INLINE_COMMENTS + int was_space = 0; + while (*s && (!chars || !strchr(chars, *s)) && + !(was_space && strchr(INI_INLINE_COMMENT_PREFIXES, *s))) { + was_space = isspace((unsigned char)(*s)); + s++; + } +#else + while (*s && (!chars || !strchr(chars, *s))) { + s++; + } +#endif + return (char*)s; +} + +/* Version of strncpy that ensures dest (size bytes) is null-terminated. */ +inline static char* strncpy0(char* dest, const char* src, size_t size) +{ + strncpy(dest, src, size); + dest[size - 1] = '\0'; + return dest; +} + +/* See documentation in header file. */ +inline int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler, + void* user) +{ + /* Uses a fair bit of stack (use heap instead if you need to) */ +#if INI_USE_STACK + char line[INI_MAX_LINE]; +#else + char* line; +#endif + char section[MAX_SECTION] = ""; + char prev_name[MAX_NAME] = ""; + + char* start; + char* end; + char* name; + char* value; + int lineno = 0; + int error = 0; + +#if !INI_USE_STACK + line = (char*)malloc(INI_MAX_LINE); + if (!line) { + return -2; + } +#endif + + /* Scan through stream line by line */ + while (reader(line, INI_MAX_LINE, stream) != NULL) { + lineno++; + + start = line; +#if INI_ALLOW_BOM + if (lineno == 1 && (unsigned char)start[0] == 0xEF && + (unsigned char)start[1] == 0xBB && + (unsigned char)start[2] == 0xBF) { + start += 3; + } +#endif + start = lskip(rstrip(start)); + + if (*start == ';' || *start == '#') { + /* Per Python configparser, allow both ; and # comments at the + start of a line */ + } +#if INI_ALLOW_MULTILINE + else if (*prev_name && *start && start > line) { + +#if INI_ALLOW_INLINE_COMMENTS + end = find_chars_or_comment(start, NULL); + if (*end) + *end = '\0'; + rstrip(start); +#endif + + /* Non-blank line with leading whitespace, treat as continuation + of previous name's value (as per Python configparser). */ + if (!handler(user, section, prev_name, start) && !error) + error = lineno; + } +#endif + else if (*start == '[') { + /* A "[section]" line */ + end = find_chars_or_comment(start + 1, "]"); + if (*end == ']') { + *end = '\0'; + strncpy0(section, start + 1, sizeof(section)); + *prev_name = '\0'; + } + else if (!error) { + /* No ']' found on section line */ + error = lineno; + } + } + else if (*start) { + /* Not a comment, must be a name[=:]value pair */ + end = find_chars_or_comment(start, "=:"); + if (*end == '=' || *end == ':') { + *end = '\0'; + name = rstrip(start); + value = lskip(end + 1); +#if INI_ALLOW_INLINE_COMMENTS + end = find_chars_or_comment(value, NULL); + if (*end) + *end = '\0'; +#endif + rstrip(value); + + /* Valid name[=:]value pair found, call handler */ + strncpy0(prev_name, name, sizeof(prev_name)); + if (!handler(user, section, name, value) && !error) + error = lineno; + } + else if (!error) { + /* No '=' or ':' found on name[=:]value line */ + error = lineno; + } + } + +#if INI_STOP_ON_FIRST_ERROR + if (error) + break; +#endif + } + +#if !INI_USE_STACK + free(line); +#endif + + return error; +} + +/* See documentation in header file. */ +inline int ini_parse_file(FILE* file, ini_handler handler, void* user) +{ + return ini_parse_stream((ini_reader)fgets, file, handler, user); +} + +/* See documentation in header file. */ +inline int ini_parse(const char* filename, ini_handler handler, void* user) +{ + FILE* file; + int error; + + file = fopen(filename, "r"); + if (!file) + return -1; + error = ini_parse_file(file, handler, user); + fclose(file); + return error; +} + +#endif /* __INI_H__ */ + + +#ifndef __INIREADER_H__ +#define __INIREADER_H__ + +#include +#include +#include + +// Read an INI file into easy-to-access name/value pairs. (Note that I've gone +// for simplicity here rather than speed, but it should be pretty decent.) +class INIReader +{ +public: + // Empty Constructor + INIReader() {}; + + // Construct INIReader and parse given filename. See ini.h for more info + // about the parsing. + INIReader(std::string filename); + + // Construct INIReader and parse given file. See ini.h for more info + // about the parsing. + INIReader(FILE *file); + + // Return the result of ini_parse(), i.e., 0 on success, line number of + // first error on parse error, or -1 on file open error. + int ParseError() const; + + // Return the list of sections found in ini file + const std::set& Sections() const; + + // Get a string value from INI file, returning default_value if not found. + std::string Get(std::string section, std::string name, + std::string default_value) const; + + // Get an integer (long) value from INI file, returning default_value if + // not found or not a valid integer (decimal "1234", "-1234", or hex "0x4d2"). + long GetInteger(std::string section, std::string name, long default_value) const; + + // Get a real (floating point double) value from INI file, returning + // default_value if not found or not a valid floating point value + // according to strtod(). + double GetReal(std::string section, std::string name, double default_value) const; + + // Get a single precision floating point number value from INI file, returning + // default_value if not found or not a valid floating point value + // according to strtof(). + float GetFloat(std::string section, std::string name, float default_value) const; + + // Get a boolean value from INI file, returning default_value if not found or if + // not a valid true/false value. Valid true values are "true", "yes", "on", "1", + // and valid false values are "false", "no", "off", "0" (not case sensitive). + bool GetBoolean(std::string section, std::string name, bool default_value) const; + +protected: + int _error; + std::map _values; + std::set _sections; + static std::string MakeKey(std::string section, std::string name); + static int ValueHandler(void* user, const char* section, const char* name, + const char* value); +}; + +#endif // __INIREADER_H__ + + +#ifndef __INIREADER__ +#define __INIREADER__ + +#include +#include +#include + +inline INIReader::INIReader(std::string filename) +{ + _error = ini_parse(filename.c_str(), ValueHandler, this); +} + +inline INIReader::INIReader(FILE *file) +{ + _error = ini_parse_file(file, ValueHandler, this); +} + +inline int INIReader::ParseError() const +{ + return _error; +} + +inline const std::set& INIReader::Sections() const +{ + return _sections; +} + +inline std::string INIReader::Get(std::string section, std::string name, std::string default_value) const +{ + std::string key = MakeKey(section, name); + return _values.count(key) ? _values.at(key) : default_value; +} + +inline long INIReader::GetInteger(std::string section, std::string name, long default_value) const +{ + std::string valstr = Get(section, name, ""); + const char* value = valstr.c_str(); + char* end; + // This parses "1234" (decimal) and also "0x4D2" (hex) + long n = strtol(value, &end, 0); + return end > value ? n : default_value; +} + +inline double INIReader::GetReal(std::string section, std::string name, double default_value) const +{ + std::string valstr = Get(section, name, ""); + const char* value = valstr.c_str(); + char* end; + double n = strtod(value, &end); + return end > value ? n : default_value; +} + +inline float INIReader::GetFloat(std::string section, std::string name, float default_value) const +{ + std::string valstr = Get(section, name, ""); + const char* value = valstr.c_str(); + char* end; + float n = strtof(value, &end); + return end > value ? n : default_value; +} + +inline bool INIReader::GetBoolean(std::string section, std::string name, bool default_value) const +{ + std::string valstr = Get(section, name, ""); + // Convert to lower case to make string comparisons case-insensitive + std::transform(valstr.begin(), valstr.end(), valstr.begin(), ::tolower); + if (valstr == "true" || valstr == "yes" || valstr == "on" || valstr == "1") + return true; + else if (valstr == "false" || valstr == "no" || valstr == "off" || valstr == "0") + return false; + else + return default_value; +} + +inline std::string INIReader::MakeKey(std::string section, std::string name) +{ + std::string key = section + "=" + name; + // Convert to lower case to make section/name lookups case-insensitive + std::transform(key.begin(), key.end(), key.begin(), ::tolower); + return key; +} + +inline int INIReader::ValueHandler(void* user, const char* section, const char* name, + const char* value) +{ + INIReader* reader = (INIReader*)user; + std::string key = MakeKey(section, name); + if (reader->_values[key].size() > 0) + reader->_values[key] += "\n"; + reader->_values[key] += value; + reader->_sections.insert(section); + return 1; +} + +#endif // __INIREADER__ diff --git a/study_clang/Mimic/monitor_system_status/monitor b/study_clang/Mimic/monitor_system_status/monitor new file mode 100755 index 0000000..ca01b58 Binary files /dev/null and b/study_clang/Mimic/monitor_system_status/monitor differ diff --git a/study_clang/Mimic/monitor_system_status/monitor.cpp b/study_clang/Mimic/monitor_system_status/monitor.cpp new file mode 100644 index 0000000..ca07dac --- /dev/null +++ b/study_clang/Mimic/monitor_system_status/monitor.cpp @@ -0,0 +1,377 @@ +/* =============================================================================================== +* +* Filename: monitor.cpp +* +* Description: Monitor the operating status of the system and publish it. +* +* Version: 0.1 +* Created: 2020年07月15日 10时21分 +* Revision: none +* Compiler: gcc/g++ +* Link: -lpthread +* +* Author: songtianlun, songtianlun@comleader.com.cn +* Organization: IEUCD +* +* ===============================================================================================*/ + +#include "monitor.h" + +int main (void) +{ + int key_process_ret, key_sys_value_ret, key_files_ret, key_log_ret; + pthread_t key_process_pth, key_sys_value_pth, key_files_pth, key_log_pth; //线程ID变量 + + init_config("Config.ini"); + + // 参数:创建的线程ID,线程参数,调用函数,函数参数 + key_process_ret = pthread_create(&key_process_pth,NULL,monitor_key_process,NULL); + key_sys_value_ret = pthread_create(&key_sys_value_pth,NULL,monitor_key_sys_value,NULL); + key_files_ret = pthread_create(&key_files_pth,NULL,monitor_key_files,NULL); + key_log_ret = pthread_create(&key_log_pth,NULL,monitor_key_log,NULL); + + pthread_join(key_process_pth, NULL); // 等待线程结束 + pthread_join(key_sys_value_pth, NULL); + pthread_join(key_files_pth, NULL); + pthread_join(key_log_pth, NULL); + + return 0; +} + +void *monitor_key_process(void *args) +{ + printf("Start the new thread to monitor key process.\n"); +} + +void *monitor_key_sys_value(void *args) +{ + Cpu_info ocpu,ncpu; + Mem_info omem; + User_info users[50]; + Group_info groups[50]; + char crontabs[100][200]; + float cpu_occupy = 0; + float mem_occupy = 0; + int sum_tcp_socket = 0; + int sum_progress = 0; + int sum_user = 0; + int sum_group = 0; + int sum_crontab = 0; + memset(&users,0,sizeof(users)); + printf("Start the new thread to monitor key system values.\n"); + while(1) + { + // printf("-------------------- CPU occupy -------------------\n"); + get_cpu_occupy(&ocpu); + sleep(1); + get_cpu_occupy(&ncpu); + cpu_occupy = cal_cpu_occupy(&ocpu, &ncpu); + // printf("-------------------- Mem occupy -------------------\n"); + get_mem_occupy(&omem); + mem_occupy = cal_mem_occupy(&omem); + sum_tcp_socket = get_tcp_socket_sum(); + sum_progress = get_progress_sum(); + sum_user = get_users(users); + sum_group = get_groups(groups); + sum_crontab = get_crontab(crontabs); + + // system("clear"); + printf("-------------------- Monitor Info -------------------\n"); + print_now_time(); + printf("CPU Usage(%) : %4.2f\n", cpu_occupy); + printf("Mem Usage(%) : %4.2f\n", mem_occupy); + printf("Tcp Socket Establish : %d\n", sum_tcp_socket); + printf("Sum of progress : %d\n", sum_progress); + printf("Sum of Users : %d\n", sum_user); + printf("Sum of Groups : %d\n", sum_group); + printf("Sum of Crontabs : %d\n", sum_crontab); + printf("--------------------- User List --------------------\n"); + for(int i=0;iname, &o->user, &o->nice, &o->system, &o->idle, &o->iowait, &o->irq, &o->softirq, &o->stealstolen, &o->guest, &o->guest_nice); + // printf("name=%s, user=%d, nice=%d, system=%d, idle=%d, iowait=%d, irq=%d, softirq=%d, stralstolen=%d, guest=%d, guest_nice=%d\n", o->name, o->user, o->nice, o->system, o->idle, o->iowait, o->irq, o->softirq, o->stealstolen, o->guest, o->guest_nice); + fclose(fd); +} + +float cal_cpu_occupy (Cpu_info *o, Cpu_info *n) +{ + int ototal, ntotal; + int oused, nused; + + ototal = (o->user + o->nice + o->system + o->idle + o->iowait + o-> irq + o-> softirq + o->stealstolen + o->guest + o->guest_nice); + ntotal = (n->user + n->nice + n->system + n->idle + n->iowait + n-> irq + n-> softirq + n->stealstolen + n->guest + n->guest_nice); + + oused = ototal - o->idle; + nused = ntotal - n->idle; + + // printf("ototal time: %d\n", ototal); + // printf("ntotal time: %d\n", ntotal); + + // printf("oused time: %d\n", oused); + // printf("nused time: %d\n", nused); + + return (100.0 * (nused - oused) / (ntotal - ototal)); +} + +void get_mem_occupy (Mem_info *o) +{ + FILE* fpMemInfo = fopen("/proc/meminfo", "r"); + if (NULL == fpMemInfo) + { + return ; + } + int i = 0; + int value; + char name[1024]; + char line[1024]; + int nFiledNumber = 2; + int nMemberNumber = 5; + while (fgets(line, sizeof(line) - 1, fpMemInfo)) + { + if (sscanf(line, "%s%u", name, &value) != nFiledNumber) + { + continue; + } + if (0 == strcmp(name, "MemTotal:")) + { + ++i; + o->total = value; + } + else if (0 == strcmp(name, "MemFree:")) + { + ++i; + o->free = value; + } + else if (0 == strcmp(name, "MemAvailable:")) + { + ++i; + o->available = value; + } + else if (0 == strcmp(name, "Buffers:")) + { + ++i; + o->buffers = value; + } + else if (0 == strcmp(name, "Cached:")) + { + ++i; + o->cached = value; + } + if (i == nMemberNumber) + { + break; + } + } + // system("free"); + // system("cat /proc/meminfo"); + // printf("MemTotal : %d\n",o->total); + // printf("MemFree : %d\n",o->free); + // printf("MemAvailable : %d\n",o->available); + // printf("MemBuffers : %d\n",o->buffers); + // printf("MemCached : %d\n",o->cached); + // printf("MemSwapCached : %d\n",o->swap_cached); + // printf("MemSwapTotal : %d\n",o->swap_total); + // printf("MemSwapFree : %d\n",o->swap_free); + fclose(fpMemInfo); +} + +float cal_mem_occupy(Mem_info *o) +{ + return (100.0 * (o->total - o->available) / o->total); +} + +int get_tcp_socket_sum () +{ + int socket_num=0; + FILE *tcp; + char tmp[1024]; //设置一个合适的长度,以存储每一行输出 + int value; + char name[1024]; + tcp = popen("netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'", "r"); + if (tcp == NULL) { + return 0; + } + + while (fgets(tmp, sizeof(tmp) - 1, tcp)) { + if (sscanf(tmp, "%s %u", name, &value) != 2) + { + continue; + } + if (0 == strcmp(name, "ESTABLISHED")) + { + socket_num = value; + break; + } + } + pclose(tcp); + return socket_num; +} +int get_progress_sum () +{ + int progress_num=0; + FILE *progress; + char tmp[1024]; + progress = popen("ps -ef| wc -l", "r"); + if (progress == NULL) { + return 0; + } + fgets(tmp, sizeof(tmp) - 1, progress); + sscanf(tmp, "%u", &progress_num); + + pclose(progress); + return progress_num; +} +int get_users (User_info users[]) +{ + char line[10240]; + char *name = NULL; + char *passwd = NULL; + char *cid; + char *cgroup_id; + int i=0; + FILE* fpUserInfo = fopen("/etc/passwd", "r"); + if (NULL == fpUserInfo) + { + return -1; + } + while (fgets(line, sizeof(line) - 1, fpUserInfo)) + { + // printf("%s",line); + name = strtok(line, ":"); + passwd = strtok(NULL, ":"); + cid = strtok(NULL, ":"); + cgroup_id = strtok(NULL, ":"); + strcpy(users[i].name, name); + strcpy(users[i].passwd, passwd); + strcpy(users[i].cid,cid); + strcpy(users[i].cgroup_id,cgroup_id); + // printf("user name=%s, user id=%s, user group id=%s\n",users[i].name,users[i].cid,users[i].cgroup_id); + i++; + } + fclose(fpUserInfo); + return i; +} +int get_groups (Group_info groups[]) +{ + char line[10240]; + char *name = NULL; + char *passwd = NULL; + char *gid; + int i=0; + FILE* fpGroupInfo = fopen("/etc/group", "r"); + if (NULL == fpGroupInfo) + { + return -1; + } + while (fgets(line, sizeof(line) - 1, fpGroupInfo)) + { + // printf("%s",line); + name = strtok(line, ":"); + passwd = strtok(NULL, ":"); + gid = strtok(NULL, ":"); + strcpy(groups[i].name, name); + strcpy(groups[i].passwd, passwd); + strcpy(groups[i].gid,gid); + // printf("group name=%s, group id=%s\n",groups[i].name,groups[i].gid); + i++; + } + fclose(fpGroupInfo); + return i; +} +int get_crontab(char crontab[][200]) +{ + int sum_crontab=0; + FILE *fpCrontab; + char tmp[10240]; //设置一个合适的长度,以存储每一行输出 + char info[1024]; + fpCrontab = popen("cat /etc/passwd | cut -f 1 -d : |xargs -I {} crontab -l -u {}", "r"); + if (fpCrontab == NULL) { + return -1; + } + + while (fgets(tmp, sizeof(tmp) - 1, fpCrontab)) { + sscanf(tmp, "%[^ ]", info); + if(!strcmp(info,"no")) + continue; + strcpy(crontab[sum_crontab++],tmp); + } + pclose(fpCrontab); + return sum_crontab; +} +/* +* === FUNCTION ====================================================================== +* Name: print_now_time +* Description: 获取并格式化打印当前时间。 +* ===================================================================================== +*/ +void print_now_time() +{ + time_t rawtime; + struct tm * timeinfo; + char buffer [128]; + + time (&rawtime); + // printf("%ld\n", rawtime); + + timeinfo = localtime (&rawtime); + strftime (buffer,sizeof(buffer),"Now is %Y/%m/%d %H:%M:%S",timeinfo); + printf("%s\n", buffer); +} + +/* +* === FUNCTION ====================================================================== +* Name: split +* Description: 将str字符以spl分割,存于dst中,并返回子字符串数量 +* ===================================================================================== +*/ +int split(char dst[][80], char* str, const char* spl) +{ + int n = 0; + char *result = NULL; + result = strtok(str, spl); + while( result != NULL ) + { + strcpy(dst[n++], result); + result = strtok(NULL, spl); + } + return n; +} \ No newline at end of file diff --git a/study_clang/Mimic/monitor_system_status/monitor.h b/study_clang/Mimic/monitor_system_status/monitor.h new file mode 100644 index 0000000..eaba1cd --- /dev/null +++ b/study_clang/Mimic/monitor_system_status/monitor.h @@ -0,0 +1,109 @@ +/* =============================================================================================== +* +* Filename: monitor.h +* +* Description: Declare monitoring module functions and dependencies. +* +* Version: 0.1 +* Created: 2020年07月15日 10时21分 +* Revision: none +* Compiler: gcc +* Link: -lpthread +* +* Author: songtianlun, songtianlun@comleader.com.cn +* Organization: IEUCD +* +* ===============================================================================================*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ini/INIReader.h" + +#define MAXBUFSIZE 1024 + +struct KEY_PROCESS +{ + int sum_monitor; + int num_normal; + int num_abnormal; + int pid_abnormal[10]; + char Char; + short Short; + long Long; + float Float; + double Double; + char String[100]; +}; +struct CPU_INFO +{ + char name[10]; + unsigned int user; + unsigned int nice; + unsigned int system; + unsigned int idle; + unsigned int iowait; + unsigned int irq; + unsigned int softirq; + unsigned int stealstolen; + unsigned int guest; + unsigned int guest_nice; +}; +struct MEM_INFO +{ + unsigned int total; + unsigned int free; + unsigned int buffers; + unsigned int cached; + unsigned int swap_cached; + unsigned int swap_total; + unsigned int swap_free; + unsigned int available; +}; +struct USERS_INFO +{ + char name[50]; + char passwd[10]; + char cid[10]; + char cgroup_id[10]; +}; +struct GROUPS_INFO +{ + char name[50]; + char passwd[10]; + char gid[10]; +}; + + +typedef struct KEY_PROCESS Key_process; +typedef struct CPU_INFO Cpu_info; +typedef struct MEM_INFO Mem_info; +typedef struct USERS_INFO User_info; +typedef struct GROUPS_INFO Group_info; + +void *monitor_key_process(void *args); +void *monitor_key_sys_value(void *args); +void *monitor_key_files(void *args); +void *monitor_key_log(void *args); +int init_config(char *conf_path); + +void get_cpu_occupy (Cpu_info *o); +float cal_cpu_occupy(Cpu_info *, Cpu_info *); +void get_mem_occupy (Mem_info *o); +float cal_mem_occupy(Mem_info *); +int get_tcp_socket_sum (); +int get_progress_sum (); +int get_users (User_info users[]); +int get_groups (Group_info groups[]); +int get_crontab (char crontab[][200]); + +void print_now_time(); +int split(char dst[][80], char* str, const char* spl); diff --git a/study_clang/Mimic/nos_monitor/Makefile b/study_clang/Mimic/nos_monitor/Makefile new file mode 100644 index 0000000..5bc6d60 --- /dev/null +++ b/study_clang/Mimic/nos_monitor/Makefile @@ -0,0 +1,21 @@ +# Author: Tianlun Song, songtianlun@frytea.com, In Nov 22, 2020. +ARCH ?= +CC = $(ARCH)gcc +SUFFIX = .c +CFLAGS += -g -lzmq -lpthread -L/usr/local/lib -std=gnu11 +LD = -I/usr/local/include -Wl,-rpath=/usr/local/lib/ + +CUR_SOURCE = $(wildcard *$(SUFFIX)) +# CUR_TARGETS = $(patsubst %$(SUFFIX), %, $(CUR_SOURCE)) +CUR_TARGETS = ./monitsys + +all:$(CUR_TARGETS) + +# %:%.c 是一个表示与目标相同文件的模式变量 +$(CUR_TARGETS):%:%$(SUFFIX) + $(CC) $< $(CFLAGS) -o $@ $(LD) + +# 指定伪目标 +.PHONY:clean all + clean: + -rm -rf $(TARGETS) diff --git a/study_clang/Mimic/nos_monitor/README.md b/study_clang/Mimic/nos_monitor/README.md new file mode 100644 index 0000000..a0d3db0 --- /dev/null +++ b/study_clang/Mimic/nos_monitor/README.md @@ -0,0 +1,23 @@ +# Nos Monitor + +The app of Nos System State Monitor. + +- Author : Zhanglong Cheng. +- Company: PML. + +## Usage + +``` +# Step 1: Build +$ make + +# Step 2: Edit config file, initip.ini + +# Step 3: Install +$ mkdir /root/monitor +$ cp monitsys /root/monitor/ +$ cp initip.ini /root/monitor/ + +# Step 4: Run +$ /root/monitor/monitsys & +``` \ No newline at end of file diff --git a/study_clang/Mimic/nos_monitor/cpumem.c b/study_clang/Mimic/nos_monitor/cpumem.c new file mode 100644 index 0000000..d189a52 --- /dev/null +++ b/study_clang/Mimic/nos_monitor/cpumem.c @@ -0,0 +1,1493 @@ +#include "monitsys.h" + +#define EVENT_NUM 12 +#define BUF_SIZE 1024 +//gcc cpumem.c -lzmq -lpthread -L/usr/local/lib -I/usr/local/include -Wl,-rpath=/usr/local/lib/ -o cpumem +// #define fb_debug(fmt, arg...) \ +// do{\ +// printf("%s %d : ", __FILE__, __LINE__); \ +// printf(fmt, ##arg); \ +// printf("\n"); \ +// }while(0) + +// #define fb_assert(x, info) \ +// do{\ +// if(!(x)) { \ +// fb_debug(info); \ +// return -1;\ +// } \ +// }while(0) + +char *event_str[EVENT_NUM] = +{ + "IN_ACCESS", + "IN_MODIFY", + "IN_ATTRIB", + "IN_CLOSE_WRITE", + "IN_CLOSE_NOWRITE", + "IN_OPEN", + "IN_MOVED_FROM", + "IN_MOVED_TO", + "IN_CREATE", + "IN_DELETE", + "IN_DELETE_SELF", + "IN_MOVE_SELF" +}; + +int lastnum = 0,lastlognum = 0,newloginnum = 0,lastloginnum = 0; + + typedef struct CPU_PACKED + { + char name[20]; // + unsigned int user; + unsigned int nice; + unsigned int system; + unsigned int idle; + }CPU_OCCUPY; + + typedef struct + { + uint uiType; // 1 + char szip[32]; + struct timeval stRcvTime; + uint uiCpuRate; + uint uiMemRate; + uint uiTcpEstablishNum; + uint uiRunningProcessNum; + uint uiCronNum; + char szPasswdMd5[64]; + char szGroupMd5[64]; + }Msgreport; + + typedef struct + { + uint uiType;//2 + char szIp[32]; + struct timeval stRcvTime; + char uiProcessname[32]; + uint uiProcessState;// 0 mains enable,1 disable + }stProcessState; + + typedef struct + { + uint uiType; //3 + char szIp[32]; + struct timeval stRcvTime; + char szFileName[32]; //filename modified + //char eventType[16]; //eventType of filename + char szFileMd5[64]; //md5num of file name + }stFileState; + + typedef struct + { + uint uiType; //4 + char szIp[32]; + struct timeval stRcvTime; + char szPath[32]; //监控路径 + char szFileName[32]; //增加或删除的文件名称 + uint uiFileNum; //当前文件夹下文件数量 + }stFileNum; + + + typedef struct + { + uint uiType;//5 + char szIp[32]; + struct timeval stRcvTime; + char szLogFile[32]; + char szMsg[5][128]; + }stLogMsg; + +//stLogMsg *syslogreport,commendlog; + float cal_cpuoccupy(CPU_OCCUPY *o,CPU_OCCUPY *n) + { + unsigned long od,nd; + unsigned long id,sd; + float cpu_use = 0; + od = (unsigned long)(o->user + o->nice + o->system + o->idle); + nd = (unsigned long)(n->user + n->nice + n->system + n->idle); + id = (unsigned long)(n->nice - o->nice); + sd = (unsigned long)(n->idle - o->idle); + if((nd-od) != 0) + cpu_use = (float)(((nd-od)-sd))*100/(nd-od); + else + cpu_use = 0; + + return cpu_use; + + + } + + int judgeiflogin() + { + FILE *fd = NULL; + char buff[180],*num=NULL, *cmd=NULL,*cur,bu[180]; + int i = 0,le = 0,newnum = 0, devalue = 0, t = 0, len = 0; + // system("who /var/log/wtmp | wc -l > /home/czl/tengswitch/login.txt"); + // fd = fopen("/home/czl/tengswitch/login.txt","r"); + if(NULL==(fd = popen(" who /var/log/wtmp | wc -l ","r"))) + { + fprintf(stdout,"execute command failed: "); + return 0; + } + + // fd = popen("history | tail -n 6","r"); + fgets(buff,sizeof(buff),fd); + // printf("string in buff is:%s\n", buff); + // sscanf(buff,"%s %s",bu,&commendlog->szMsg[0][0]); + // printf("newnum in bu is :%s\n", bu); + + newnum = atoi(buff); + printf("newnum in bu is :%d\n", newnum); + fclose(fd); + return newnum; + } + + + // stLogMsg *judgelogin() + + +/* + void judgelogin() + { + FILE *fd; + memset(&commendlog,0,sizeof(stLogMsg)); + // stLogMsg commendlog ; + // commendlog = (stLogMsg*)malloc(sizeof(stLogMsg)); + // memset(commendlog,0, sizeof(stLogMsg)); + commendlog.uiType = 5; + stpcpy(commendlog.szIp,"172.171.17.213"); + gettimeofday(&commendlog.stRcvTime,NULL); + stpcpy(commendlog.szLogFile,"/log/wtmp"); + char buff[180],*num=NULL, *cmd=NULL,*cur,bu[180]; + int i = 0,le = 0,newnum = 0, devalue = 0, t = 0, len = 0; + // system("who /var/log/wtmp | wc -l > /home/czl/tengswitch/login.txt"); + fd = fopen("/home/czl/tengswitch/login.txt","r"); + // fd = popen("history | tail -n 6","r"); + // fgets(buff,sizeof(buff),fd); + // printf("string in buff is:%s\n", buff); + // sscanf(buff,"%s %s",bu,&commendlog->szMsg[0][0]); + // printf("newnum in bu is :%s\n", bu); + + // newnum = atoi(buff); + + devalue = newloginnum - lastloginnum; + + if (devalue > 5 || devalue < 0) + { + printf("devalue in loop1 is :%d\n", devalue); + //sprintf(cmd,"who /var/log/wtmp |",); + system("who /var/log/wtmp | tail -n 6 > /home/czl/tengswitch/login.txt"); + + + fgets(buff,sizeof(buff),fd); + for(le=0;le < 5; le++) + { + buff[180] = '0'; + // sscanf(buff,"%s",&commendlog->szMsg[0][le]); + fgets(buff,sizeof(buff),fd); + memcpy(&commendlog.szMsg[le],buff,strlen(buff)); + //printf("size of buff is %d \n",sizeof(buff)); + //printf("strlen of buff is %d \n",strlen(buff)); + printf("log in 1struct is %s",&commendlog.szMsg[le]); + + } + printf("have come here \n"); + } + else if (devalue <= 5 || devalue > 0) + { + + sprintf(bu,"who /var/log/wtmp | tail -n %d > /home/czl/tengswitch/login.txt",devalue+1); + //printf("bu is :%s\n", bu); + + + printf("devalue in loop2 is :%d\n", devalue); + // cmd =&bu[0]; + //memcpy(cmd,bu,strlen(bu)); + //printf("cmd is :%d\n", cmd); + system(bu); + fgets(buff,sizeof(buff),fd); + + for(le=0; le < devalue; le++) + { + buff[180] = '0'; + fgets(buff,sizeof(buff),fd); + memcpy(&commendlog.szMsg[le],buff,strlen(buff)); + printf("log in 2 struct is %s \n",&commendlog.szMsg[le]); + } + + } + + // printf("newnum is :%d\n", newnum); + // return &commendlog; + + fclose(fd); + // printf("end of loop\n"); + // lastlognum = newnum; + } + + */ + stLogMsg judgelogin(char *ip) + { + stLogMsg getlogin; + // getlogin = (stLogMsg*)malloc(sizeof(stLogMsg)); + FILE *fd; + // memset(&commendlog,0,sizeof(stLogMsg)); + memset(&getlogin,0,sizeof(stLogMsg)); + // stLogMsg commendlog ; + // commendlog = (stLogMsg*)malloc(sizeof(stLogMsg)); + // memset(commendlog,0, sizeof(stLogMsg)); + getlogin.uiType = 5; + stpcpy(getlogin.szIp,ip); + gettimeofday(&getlogin.stRcvTime,NULL); + stpcpy(getlogin.szLogFile,"login"); + char buff[180],*num=NULL, *cmd=NULL,*cur,bu[180]; + int i = 0,le = 0,newnum = 0, devalue = 0, t = 0, len = 0; + system("who /var/log/wtmp | wc -l > /root/czl/login.txt"); + fd = fopen("/root/cheng/login.txt","r"); + // fd = popen("history | tail -n 6","r"); + // fgets(buff,sizeof(buff),fd); + // printf("string in buff is:%s\n", buff); + // sscanf(buff,"%s %s",bu,&commendlog->szMsg[0][0]); + // printf("newnum in bu is :%s\n", bu); + + // newnum = atoi(buff); + + devalue = newloginnum - lastloginnum; + + if (devalue > 5 || devalue < 0) + { + printf("devalue in loop1 is :%d\n", devalue); + //sprintf(cmd,"who /var/log/wtmp |",); + system("who /var/log/wtmp | tail -n 6 > /root/czl/login.txt"); + + + fgets(buff,sizeof(buff),fd); + for(le=0;le < 5; le++) + { + buff[180] = '0'; + // sscanf(buff,"%s",&commendlog->szMsg[0][le]); + fgets(buff,sizeof(buff),fd); + memset(&getlogin.szMsg[le],0,sizeof(getlogin.szMsg[le])); + memcpy(&getlogin.szMsg[le],buff,strlen(buff)); + //printf("size of buff is %d \n",sizeof(buff)); + //printf("strlen of buff is %d \n",strlen(buff)); + //printf("log in 1struct is %s",&getlogin->szMsg[le]); + + } + //printf("have come here \n"); + } + else if (devalue <= 5 || devalue > 0) + { + memset(&getlogin.szMsg[0],0,5*sizeof(getlogin.szMsg[le])); + sprintf(bu,"who /var/log/wtmp | tail -n %d > /root/czl/login.txt",devalue+1); + //printf("bu is :%s\n", bu); + + + printf("devalue in loop2 is :%d\n", devalue); + // cmd =&bu[0]; + //memcpy(cmd,bu,strlen(bu)); + //printf("cmd is :%d\n", cmd); + system(bu); + fgets(buff,sizeof(buff),fd); + + for(le=0; le < devalue; le++) + { + buff[180] = '0'; + fgets(buff,sizeof(buff),fd); + memset(&getlogin.szMsg[le],0,sizeof(getlogin.szMsg[le])); + memcpy(&getlogin.szMsg[le],buff,strlen(buff)); + //printf("log in 2 struct is %s \n",&getlogin->szMsg[le]); + } + + } + + // printf("newnum is :%d\n", newnum); + // printf("msg login in function type is %d\nip is %s\nfilename is %s\n ",getlogin->uiType,getlogin->szIp,getlogin->szLogFile); + // printf("szMsg0 is %s\n",getlogin->szMsg[0]); + // printf("szMsg1 is %s\n",getlogin->szMsg[1]); + // printf("szMsg2 is %s\n",getlogin->szMsg[2]); + // printf("szMsg3 is %s\n",getlogin->szMsg[3]); + // printf("szMsg4 is %s\n",getlogin->szMsg[4]); + + + + + + fclose(fd); + return getlogin; + + // lastlognum = newnum; + } + + /* + void judgecommend() + { + stLogMsg *commendlog = NULL;//, *pst=NULL; + FILE *fd; + char buff[180],*num, *cmd,*cur,bu[180]; + int i = 0,le = 0,newnum = 0, devalue = 0, t = 0, len = 0; + const char s[2] = " "; + commendlog = (stLogMsg*)malloc(sizeof(stLogMsg)); + memset(commendlog,0, sizeof(stLogMsg)); + + //system("history | tail -n 6 > /home/czl/tengswitch/history.txt"); + system("who /var/log/wtmp > /home/czl/tengswitch/history.txt"); + while(1) + { + + } + fd = fopen("/home/czl/tengswitch/history.txt","r"); + // fd = popen("history | tail -n 6","r"); + fgets(buff,sizeof(buff),fd); + printf("string in buff is:%s\n", buff); + sscanf(buff,"%s %s",bu,&commendlog->szMsg[0][0]); + // printf("newnum in bu is :%s\n", bu); + + newnum = atoi(bu); + devalue = newnum - lastnum; + printf("devalue before loop is %d\n",devalue); + printf("begin to loop\n"); + for(le = 0; le < 5; le++) + { + memset(commendlog,0, sizeof(stLogMsg)); + buff[180] = '0'; + fgets(buff,sizeof(buff),fd); + if(le < 5-devalue ) + continue; + printf("%s\n", buff); + cur = &buff[0]; + for(i=0;i<10;i++) + { + // printf("%d\n", i); + if (*cur == ' ') + t++; + if (t == 2) + num = ++cur; + if (t == 4) + { + cmd = ++cur; + break; + } + cur++; + } + + // printf("%s\n", num); + + printf("%s\n", cmd); + len =strlen(cmd); + memcpy(&commendlog->szMsg[0][le],cmd,len); + + printf("string in struct is %s\n", &commendlog->szMsg[0][le]); + // printf("4%c\n", buff[3]); + // printf("5%c\n", buff[4]); + // printf("6%c\n", buff[5]); + // printf("7%c\n", buff[6]); + // printf("8%c\n", buff[7]); + // printf("9%c\n", buff[8]); + // num = strtok(buff,s); + //printf( "%s\n",num); + + //cmd = strtok(NULL,s); + // strcpy(bu, strtok(NULL, " ")); + // printf("%s\n", num); + //sscanf(buff,"%s %s",num, commendlog->szMsg[0][0]); + // pis =&commendlog[0]; + // commendlog->uiType = 1; + // printf("%s %s\n", num , commendlog->szMsg[0][0]); + // printf("%d \n", commendlog->uiType); + } + fclose(fd); + printf("end of loop\n"); + lastnum = newnum; + } +*/ + void getPidByName(pid_t *pid, char *task_name) + { + DIR *dir; + struct dirent *ptr; + FILE *fp; + char filepath[50]; + char cur_task_name[50]; + char buf[BUF_SIZE]; + dir = opendir("/proc"); + if (NULL != dir) + { + while ((ptr = readdir(dir)) != NULL) //循环读取/proc下的每一个文件/文件夹 + { + //如果读取到的是"."或者".."则跳过,读取到的不是文件夹名字也跳过 + if ((strcmp(ptr->d_name, ".") == 0) || (strcmp(ptr->d_name, "..") == 0)) + continue; + if (DT_DIR != ptr->d_type) + continue; + sprintf(filepath, "/proc/%s/status", ptr->d_name);//生成要读取的文件的路径 + fp = fopen(filepath, "r"); + if (NULL != fp) + { + if( fgets(buf, BUF_SIZE-1, fp)== NULL ) + { + fclose(fp); + continue; + } + sscanf(buf, "%*s %s", cur_task_name); //如果文件内容满足要求则打印路径的名字(即进程的PID) + if (!strcmp(task_name, cur_task_name)) + { + sscanf(ptr->d_name, "%d", pid); + } + fclose(fp); + } + } + closedir(dir); + } + } + + + void get_cpuoccupy(CPU_OCCUPY *cpust) + { + + FILE *fd; + int n; + char buff[256]; + CPU_OCCUPY *cpu_occupy; + cpu_occupy = cpust; + + fd = fopen("/proc/stat","r"); + + fgets(buff,sizeof(buff),fd); + sscanf(buff,"%s %u %u %u %u",cpu_occupy->name,&cpu_occupy->user,&cpu_occupy->nice,&cpu_occupy->system,&cpu_occupy->idle); + // printf("%s %u %u %u %u\n",cpu_occupy->name,cpu_occupy->user,cpu_occupy->nice,cpu_occupy->system,cpu_occupy->idle); + fclose(fd); + + } + + int firewallcharge() + { + + FILE *fd; + int n; + char buff[16]; + char buff1[16]; + // char buff2[16]; + char buff2[16] = "active"; + // system("systemctl status firewalld.service | grep Active > /home/czl/tengswitch/firewall.txt"); + // system("chmod 777 firewall.txt"); + //fd = fopen("/home/czl/tengswitch/firewall.txt","r"); + // changed 20200813 + if(NULL==(fd = popen("systemctl status firewalld.service | grep Active","r"))) + { + fprintf(stdout,"execute command failed: "); + return 0; + } + //fgets(buff,sizeof(buff),fd); + fscanf(fd,"%s %s",buff,buff1); + // printf("%s %s\n",buff,buff1); + n = strcmp(buff1,buff2); + fclose(fd); + if( n == 0 ) + { + //printf("firewall enable\n"); + return 0; + } + else + { + //printf("firewall disable\n"); + return 1; + } + + + } + + + unsigned int processnum() + { + + FILE *fd,*fd1; + unsigned int pronum; + char buff[16]; + char buff1[16]; + + // system("ps -auxw | wc -l >/home/czl/tengswitch/process_num.txt"); + //system("chmod 777 /home/czl/tengswitch/process_num.txt"); + //fd = fopen("/home/czl/tengswitch/process_num.txt","r"); + + if(NULL==(fd = popen("ps -auxw | wc -l","r"))) + { + fprintf(stdout,"execute command failed: "); + return 0; + } + + + if(fd == NULL) + { + printf("

open file:process_num.txt error

"); + exit(0); + } + ///fgets(buff,sizeof(buff),fd); + fscanf(fd,"%s",buff); + pronum = atoi(buff); + fclose(fd); + return pronum; + } + + + unsigned int uiCronNum() + { + + FILE *fd = NULL,*fd1 = NULL; + unsigned int cronum = 0; + char buff[64]="\0"; + char buff1[64]="\0"; + + system("crontab -l > /root/cheng/cron.txt 2>&1"); + system("chmod 777 /root/cheng/cron.txt"); + fd = fopen("/root/cheng/cron.txt","r"); + + + while(NULL != fgets(buff,sizeof(buff),fd)) + { + cronum++; + continue; + + + } + if(cronum == 1) + cronum = 0; + // printf("There is no date"); + + // if(NULL==(fd = popen("crontab -l","r"))) + + //{ + // fprintf(stdout,"execute crontab failed: "); + //return 0; + //} + + + //fgets(buff,sizeof(buff),fd); +// fscanf(fd, "%s",buff); + // pronum = atoi(buff); +// if(buff[0] != 'n') + + //printf("buff is %s \n ",buff); + + fclose(fd); + return cronum; + } + + + unsigned int processnum_tcp() + { + + FILE *fd,*fd1; + unsigned int pronum,tcpnum; + char buff[16]; + char buff1[16]; + //netstat -an |grep 'ESTABLISHED' |grep 'tcp' |wc -l + // system("netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' > /home/czl/tengswitch/processtcp.txt"); + // system("chmod 777 /home/czl/tengswitch/processtcp.txt"); + // fd = fopen("/home/czl/tengswitch/processtcp.txt","r"); + if(NULL==(fd = popen(" netstat -an |grep 'ESTABLISHED' |grep 'tcp' |wc -l ","r"))) + { + fprintf(stdout,"execute command failed: "); + return 0; + } + fscanf(fd,"%s %s",buff,buff1); + tcpnum = atoi(buff1); + // printf("%d\n",tcpnum); + + fclose(fd); + return tcpnum; + } + + + + double get_memoccupy() + { + double memory_have = 0; + //system("free -m | grep Mem > memory.txt"); + //system("chmod 777 memory.txt"); + FILE * fp = NULL; + //fp = fopen ("memory.txt", "r"); + + if(NULL==(fp = popen("free -m | grep Mem","r"))) + { + fprintf(stdout,"execute command failed: "); + return 0; + } + + //if(fp == NULL) + //{ + // printf("

open file:memory.txt error

"); + // return 0; + //} + char s1[20] = {0}; + unsigned int total = 0; + unsigned int used = 0; + fscanf(fp, "%s %d %d", s1, &total, &used); + //printf("name: %s\n total:%d\n used:%d\n",s1,total,used); + fclose(fp); + fp = NULL; + memory_have = ((100 * used) / total); + + return memory_have; + } + + char *get_md5passwd() + { + char md5num[64] = {0}; + char filename[48] = {0}; + int n; + // system("md5sum /etc/passwd > passwd.txt"); + // system("chmod 777 passwd.txt"); + FILE * fp = NULL; + // fp = fopen ("passwd.txt", "r"); + // if(fp == NULL) + // { + // printf("

open file:passwd.txt error

"); + // return 0; + // } + if(NULL==(fp = popen("md5sum /etc/passwd","r"))) + { + fprintf(stdout,"execute command failed: "); + return NULL; + } + fscanf(fp, "%s %s", md5num, filename); + //printf("passwd md5num in function is: %s\n",md5num); + fclose(fp); + //md5num[32]='\0'; + //n = strlen(md5num); + // printf("len of passwd is %d\n",n); + //fp = NULL; + return md5num; + } + + char *get_md5group() + { + FILE * fp = NULL; + char md5group[64] = {0}; + char filename[48] = {0}; + int n; + // system("md5sum /etc/group > group.txt"); + //system("chmod 777 group.txt"); + + if(NULL==(fp=popen("md5sum /etc/group","r"))) + { + fprintf(stdout,"execute command failed: "); + return NULL; + } + + + // fp = fopen ("group.txt", "r"); +// if(fp == NULL) + //{ + // printf("

open file:group.txt error

"); + // return 0; + //} + fscanf(fp, "%s %s", md5group, filename); + //printf("group md5num in function is: %s\n",md5group); + fclose(fp); + //fp = NULL; + //n = strlen(md5num); + // printf("length of md5passwd is: %s\n",n); + // md5group[32]='\0'; + return md5group; + } + + + FILE *getshellvalue(char *pcmd) +{ + FILE * fstream = NULL; + + if(NULL == (fstream = popen(pcmd,"r"))) + { + fprintf(stdout,"execute command failed: "); + return NULL; + } + + //pcmd = "ls -trl | awk '{print $9}'"; + + return fstream; +} + + void *get_historycmd(void *arg) + { + int fd,wd,len,nread,i; + char buf[BUFSIZ]; + struct inotify_event *event; + stLogMsg stlogmsg; + FILE * fnsteam = NULL; + const char *ip = "10.10.10.201"; + int port = 7002; + char *pcip; + pcip = (char *)arg; + + void * ctx = zmq_ctx_new(); + fb_assert(ctx, "create zmq context faild"); + + void *sock = zmq_socket(ctx, ZMQ_REQ); + fb_assert(sock, "create zmq socket faild"); + + char szaddr[128] = {0}; + char cmdbuff[128] = {0}; + char cmd[128] = {0}; + snprintf(szaddr, sizeof(szaddr), "tcp://%s:%d", ip, port); + + {//加密相关代码 + char szmsg[1024] = {0}; + //此密钥为服务端产生的公钥 + strcpy(szmsg, "p=lDOa9WKUKz!I9{G)uPX4@&CrV-(>tDg:kaSGzE"); + zmq_setsockopt(sock, ZMQ_CURVE_SERVERKEY, szmsg, strlen(szmsg)); + + char szpubkey[64] = {0}; + char szprikey[64] = {0}; + zmq_curve_keypair(szpubkey, szprikey); + zmq_setsockopt(sock, ZMQ_CURVE_PUBLICKEY, szpubkey, strlen(szpubkey)); + zmq_setsockopt(sock, ZMQ_CURVE_SECRETKEY, szprikey, strlen(szprikey)); + } + + zmq_connect(sock, szaddr); + + + int count = 0; + + char szmsg[1024] = {0}; + bzero(szmsg, sizeof(szmsg)); + + fd = inotify_init(); + if (fd < 0) + { + fprintf(stderr, "inotify_init failed\n"); + return NULL; + } + + //wd = inotify_add_watch(fd, "/home/czl/test", IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO ); + //inotify_add_watch(fd, "/home/czl/tengswitch", IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO ); + wd = inotify_add_watch(fd, "/tmp/dbasky/root", IN_MODIFY | IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO); + if (wd < 0) + { + fprintf(stderr, "inotify_add_watch %s failed\n", "/tmp/dbasky/root"); + return NULL; + } + + buf[sizeof(buf) - 1] = 0; + while ((len = read(fd, buf, sizeof(buf) - 1)) > 0) + { + nread = 0; + while (len > 0) + { + event = (struct inotify_event *)&buf[nread]; + for (i = 0; imask >> i) & 1) + { + if (event->len > 0) + { + bzero(szmsg, sizeof(szmsg)); + bzero(cmdbuff, sizeof(cmdbuff)); + //fprintf(stdout, "%s --- %s\n", event->name, event_str[i]); + stlogmsg.uiType = 5; + + stpcpy(stlogmsg.szIp,pcip); + // stpcpy(stfilestate.szPath,"/home/czl/test"); + gettimeofday(&stlogmsg.stRcvTime,NULL); + //stpcpy(stlogmsg.szLogFile,event->name); + stpcpy(stlogmsg.szLogFile,"history"); + char text[128]; + stpcpy(text,event->name); + if (text[0] != '.') + + { + // zmq_send(sock, &stfilestate, sizeof(stFileState), 0); + // zmq_recv(sock, szmsg, sizeof(szmsg) - 1, 0); + printf("type is %d\n ip is %s\n filename is %s\n ",stlogmsg.uiType,stlogmsg.szIp,stlogmsg.szLogFile); + sprintf(cmd,"tac /tmp/dbasky/root/%s",event->name); + // printf("cmd in fprintf is %s",cmd); + fnsteam = getshellvalue(cmd); + count = 0; + while(NULL != fgets(cmdbuff,sizeof(cmdbuff),fnsteam)) + { + + // fgets(cmdbuff,sizeof(cmdbuff),fnsteam); + + if (count< 5 ) + { + stpcpy(stlogmsg.szMsg[count],cmdbuff); + printf("cmd in struct is %s\n",stlogmsg.szMsg[count]); + + } + else + break; + count++; + } + zmq_send(sock, &stlogmsg, sizeof(stLogMsg), 0); + zmq_recv(sock, szmsg, sizeof(szmsg) - 1, 0); + printf("return of history cmd is %s\n",szmsg); + } + fclose(fnsteam); + // printf("mestype5 recv is %s\n",szmsg); + + } + } + } + nread = nread + sizeof(struct inotify_event) + event->len; + len = len - sizeof(struct inotify_event) - event->len; + } + } + + return 0; + + } + void *monitorfile(void *arg) + { + int fd,wd,len,nread,i; + char buf[BUFSIZ]; + struct inotify_event *event; + stFileState stfilestate; + const char *ip = "10.10.10.201"; + char *pcip; + pcip = (char *)arg; + + int port = 7002; + void * ctx = zmq_ctx_new(); + fb_assert(ctx, "create zmq context faild"); + + void *sock = zmq_socket(ctx, ZMQ_REQ); + fb_assert(sock, "create zmq socket faild"); + + char szaddr[128] = {0}; + snprintf(szaddr, sizeof(szaddr), "tcp://%s:%d", ip, port); + + {//加密相关代码 + char szmsg[1024] = {0}; + //此密钥为服务端产生的公钥 + strcpy(szmsg, "p=lDOa9WKUKz!I9{G)uPX4@&CrV-(>tDg:kaSGzE"); + zmq_setsockopt(sock, ZMQ_CURVE_SERVERKEY, szmsg, strlen(szmsg)); + + char szpubkey[64] = {0}; + char szprikey[64] = {0}; + zmq_curve_keypair(szpubkey, szprikey); + zmq_setsockopt(sock, ZMQ_CURVE_PUBLICKEY, szpubkey, strlen(szpubkey)); + zmq_setsockopt(sock, ZMQ_CURVE_SECRETKEY, szprikey, strlen(szprikey)); + } + + zmq_connect(sock, szaddr); + + + int count = 0; + + char szmsg[1024] = {0}; + bzero(szmsg, sizeof(szmsg)); + + + + fd = inotify_init(); + if (fd < 0) + { + fprintf(stderr, "inotify_init failed\n"); + return NULL; + } + + //wd = inotify_add_watch(fd, "/home/czl/test", IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO ); + //inotify_add_watch(fd, "/home/czl/tengswitch", IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO ); + //wd = inotify_add_watch(fd, "/home/czl/test", IN_MODIFY); + + wd = inotify_add_watch(fd, "/etc", IN_MODIFY); + inotify_add_watch(fd, "/etc/profile.d", IN_MODIFY); + inotify_add_watch(fd, "/etc/rc.d/init.d", IN_MODIFY); + inotify_add_watch(fd, "/etc/rc.local", IN_MODIFY); + if (wd < 0) + { + fprintf(stderr, "inotify_add_watch %s failed\n", "/etc"); + return NULL; + } + + buf[sizeof(buf) - 1] = 0; + while ((len = read(fd, buf, sizeof(buf) - 1)) > 0) + { + nread = 0; + while (len > 0) + { + event = (struct inotify_event *)&buf[nread]; + for (i = 0; imask >> i) & 1) + { + if (event->len > 0) + { + bzero(szmsg, sizeof(szmsg)); + //fprintf(stdout, "%s --- %s\n", event->name, event_str[i]); + stfilestate.uiType = 3; + + stpcpy(stfilestate.szIp,pcip); + // stpcpy(stfilestate.szPath,"/home/czl/test"); + gettimeofday(&stfilestate.stRcvTime,NULL); + stpcpy(stfilestate.szFileName,event->name); + if (stfilestate.szFileName[0] != '.') + { + zmq_send(sock, &stfilestate, sizeof(stFileState), 0); + zmq_recv(sock, szmsg, sizeof(szmsg) - 1, 0); + printf("modify event happend\n"); + printf("file changed \n type is %d\n ip is %s\n filename is %s\n ",stfilestate.uiType,stfilestate.szIp,stfilestate.szFileName); + } + + // printf("mestype5 recv is %s\n",szmsg); + + } + } + } + nread = nread + sizeof(struct inotify_event) + event->len; + len = len - sizeof(struct inotify_event) - event->len; + } + } + + return 0; + + } + + void *monitorfilenum(void *arg) + { + int fd,wd,len,nread,i; + char buf[BUFSIZ],num[10]; + struct inotify_event *event; + stFileNum stfilenum; + FILE* fp = NULL; +// if (argc < 2) +// { +// fprintf(stderr, "%s path\n", argv[0]); + // return -1; + //} + char *pcip; + pcip = (char *)arg; + + const char *ip = "10.10.10.201"; + int port = 7002; + void * ctx = zmq_ctx_new(); + fb_assert(ctx, "create zmq context faild"); + + void *sock = zmq_socket(ctx, ZMQ_REQ); + fb_assert(sock, "create zmq socket faild"); + + char szaddr[128] = {0}; + snprintf(szaddr, sizeof(szaddr), "tcp://%s:%d", ip, port); + + {//加密相关代码 + char szmsg[1024] = {0}; + //此密钥为服务端产生的公钥 + strcpy(szmsg, "p=lDOa9WKUKz!I9{G)uPX4@&CrV-(>tDg:kaSGzE"); + zmq_setsockopt(sock, ZMQ_CURVE_SERVERKEY, szmsg, strlen(szmsg)); + + char szpubkey[64] = {0}; + char szprikey[64] = {0}; + zmq_curve_keypair(szpubkey, szprikey); + zmq_setsockopt(sock, ZMQ_CURVE_PUBLICKEY, szpubkey, strlen(szpubkey)); + zmq_setsockopt(sock, ZMQ_CURVE_SECRETKEY, szprikey, strlen(szprikey)); + } + + zmq_connect(sock, szaddr); + + + int count = 0; + + char szmsg[1024] = {0}; + bzero(szmsg, sizeof(szmsg)); + + fd = inotify_init(); + if (fd < 0) + { + fprintf(stderr, "inotify_init failed\n"); + return NULL; + } + + wd = inotify_add_watch(fd, "/usr/local/sbin", IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO ); + //inotify_add_watch(fd, "/home/czl/tengswitch", IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO ); + //wd = inotify_add_watch(fd, "/home/czl/test", IN_MODIFY); + if (wd < 0) + { + fprintf(stderr, "inotify_add_watch %s failed\n", "/usr/local/sbin"); + return NULL; + } + + buf[sizeof(buf) - 1] = 0; + while ((len = read(fd, buf, sizeof(buf) - 1)) > 0) + { + nread = 0; + while (len > 0) + { + event = (struct inotify_event *)&buf[nread]; + for (i = 0; imask >> i) & 1) + { + if (event->len > 0) + //fprintf(stdout, "%s --- %s\n", event->name, event_str[i]); + { + + stpcpy(stfilenum.szFileName,event->name); + if (stfilenum.szFileName[0] != '.') + { + + printf("num in test event happened \n"); + bzero(szmsg, sizeof(szmsg)); + stfilenum.uiType = 4; + stpcpy(stfilenum.szIp,pcip); + stpcpy(stfilenum.szPath,"/usr/local/sbin"); + gettimeofday(&stfilenum.stRcvTime,NULL); + + // system("ls -l /home/czl/test |grep '^-' |wc -l > /home/czl/tengswitch/filenum.txt"); + // a = fopen("/home/czl/tengswitch/filenum.txt","r"); + // if(a == NULL) + // { + // printf("

open file:filenum.txt error

"); + // exit(0); + // } + + if(NULL==( fp = popen("ls -l /usr/local/sbin |grep '^-' |wc -l ","r"))) + { + fprintf(stdout,"execute command failed: "); + return NULL; + } + + fscanf(fp,"%s",num); + //printf("filenum charged is %s\n",num); + stfilenum.uiFileNum = atoi(num); + fclose(fp); + + printf("type 4 root file num changed\n type is %d\n ip is %s\n path is %s\n filename is %s\n file num is %d\n\n\n\n",stfilenum.uiType,stfilenum.szIp,stfilenum.szPath,stfilenum.szFileName,stfilenum.uiFileNum); + zmq_send(sock, &stfilenum, sizeof(stFileNum), 0); + zmq_recv(sock, szmsg, sizeof(szmsg) - 1, 0); + printf("tpye num recv is %s\n",szmsg); + + } + + } + //else + //fprintf(stdout, "%s --- %s\n", " ", event_str[i]); + } + } + nread = nread + sizeof(struct inotify_event) + event->len; + len = len - sizeof(struct inotify_event) - event->len; + } + } + + return 0; + + } + + void *monitorhomenum(void *arg) + { + int fd,wd,len,nread,i; + char buf[BUFSIZ],num[10]; + struct inotify_event *event; + stFileNum stfilenum; + FILE* fp = NULL; +// if (argc < 2) +// { +// fprintf(stderr, "%s path\n", argv[0]); + // return -1; + //} + + char *pcip; + pcip = (char *)arg; + + const char *ip = "10.10.10.201"; + int port = 7002; + void * ctx = zmq_ctx_new(); + fb_assert(ctx, "create zmq context faild"); + + void *sock = zmq_socket(ctx, ZMQ_REQ); + fb_assert(sock, "create zmq socket faild"); + + char szaddr[128] = {0}; + snprintf(szaddr, sizeof(szaddr), "tcp://%s:%d", ip, port); + + {//加密相关代码 + char szmsg[1024] = {0}; + //此密钥为服务端产生的公钥 + strcpy(szmsg, "p=lDOa9WKUKz!I9{G)uPX4@&CrV-(>tDg:kaSGzE"); + zmq_setsockopt(sock, ZMQ_CURVE_SERVERKEY, szmsg, strlen(szmsg)); + + char szpubkey[64] = {0}; + char szprikey[64] = {0}; + zmq_curve_keypair(szpubkey, szprikey); + zmq_setsockopt(sock, ZMQ_CURVE_PUBLICKEY, szpubkey, strlen(szpubkey)); + zmq_setsockopt(sock, ZMQ_CURVE_SECRETKEY, szprikey, strlen(szprikey)); + } + + zmq_connect(sock, szaddr); + + + int count = 0; + + char szmsg[1024] = {0}; + bzero(szmsg, sizeof(szmsg)); + + fd = inotify_init(); + if (fd < 0) + { + fprintf(stderr, "inotify_init failed\n"); + return NULL; + } + + wd = inotify_add_watch(fd, "/home", IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO ); + //inotify_add_watch(fd, "/home/czl/tengswitch", IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO ); + //wd = inotify_add_watch(fd, "/home/czl/test", IN_MODIFY); + if (wd < 0) + { + fprintf(stderr, "inotify_add_watch %s failed\n", "/home"); + return NULL; + } + + buf[sizeof(buf) - 1] = 0; + while ((len = read(fd, buf, sizeof(buf) - 1)) > 0) + { + nread = 0; + while (len > 0) + { + event = (struct inotify_event *)&buf[nread]; + for (i = 0; imask >> i) & 1) + { + if (event->len > 0) + //fprintf(stdout, "%s --- %s\n", event->name, event_str[i]); + { + + stpcpy(stfilenum.szFileName,event->name); + + // system("ls -l /home/czl/test |grep '^-' |wc -l > /home/czl/tengswitch/filenum.txt"); + // a = fopen("/home/czl/tengswitch/filenum.txt","r"); + // if(a == NULL) + // { + // printf("

open file:filenum.txt error

"); + // exit(0); + // } + if (stfilenum.szFileName[0] != '.') + { + + printf("num in home event happened \n"); + bzero(szmsg, sizeof(szmsg)); + stfilenum.uiType = 4; + stpcpy(stfilenum.szIp,pcip); + stpcpy(stfilenum.szPath,"/home"); + gettimeofday(&stfilenum.stRcvTime,NULL); + + if(NULL==( fp = popen("ls -l /home |grep '^-' |wc -l ","r"))) + { + fprintf(stdout,"execute command failed: "); + return NULL; + } + + fscanf(fp,"%s",num); + //printf("filenum charged is %s\n",num); + stfilenum.uiFileNum = atoi(num); + fclose(fp); + printf("type 4 home file num changed\n type is %d\n ip is %s\n path is %s\n filename is %s\n file num is %d\n\n\n\n",stfilenum.uiType,stfilenum.szIp,stfilenum.szPath,stfilenum.szFileName,stfilenum.uiFileNum); + + zmq_send(sock, &stfilenum, sizeof(stFileNum), 0); + zmq_recv(sock, szmsg, sizeof(szmsg) - 1, 0); + printf("tpye num recv is %s\n",szmsg); + } + + } + //else + //fprintf(stdout, "%s --- %s\n", " ", event_str[i]); + } + } + nread = nread + sizeof(struct inotify_event) + event->len; + len = len - sizeof(struct inotify_event) - event->len; + } + } + + return 0; + + } + + int reportpathnum() + { + FILE *fd = NULL,*fp = NULL; + char path[1024]="\0",b[10][128],i=0,j,num[128],cmd[128] = "\0"; + unsigned int filenum = 0,allnum = 0,pathnum = 0; + if(NULL==(fd = popen("echo $PATH","r"))) + { + fprintf(stdout,"execute command failed: "); + return 0; + } + if (NULL == fgets(path,sizeof(path),fd)) + return 0; + fclose(fd); + + printf("date in path is %s\n",path); + pathnum = strlen(path); + path[pathnum-1] = '\0'; + char* token = strtok(path,":"); + while(token != NULL) + { + strcpy(b[i++],token); + token = strtok(NULL,":"); + if( i == 9 ) + break; + } + + for(j=0;jopen file:passwd.txt error

"); + return 0; + } + fscanf(fp,"%s %s %s %s",pcip,task_name,cmanager,manprocess); + fclose(fp); + while(1) + { + printf("process num is %s %s %s",task_name,cmanager,manprocess); + sleep(1); + } + pthread_t history_cmd,filecharge,filenumcharge,homenumcharge; + Msgreport mesgreport; + stProcessState processstate; + stFileNum pathreport; + stLogMsg syslogreport,commendlog; + //syslogreport = (stLogMsg*)malloc(sizeof(stLogMsg)+1); + memset(&syslogreport,0, sizeof(stLogMsg)); + void * ctx = zmq_ctx_new(); + fb_assert(ctx, "create zmq context faild"); + + void *sock = zmq_socket(ctx, ZMQ_REQ); + fb_assert(sock, "create zmq socket faild"); + + char szaddr[128] = "\0"; + snprintf(szaddr, sizeof(szaddr), "tcp://%s:%d", ip, port); + + {//加密相关代码 + char szmsg[1024] = {0}; + //此密钥为服务端产生的公钥 + strcpy(szmsg, "p=lDOa9WKUKz!I9{G)uPX4@&CrV-(>tDg:kaSGzE"); + zmq_setsockopt(sock, ZMQ_CURVE_SERVERKEY, szmsg, strlen(szmsg)); + + char szpubkey[64] = {0}; + char szprikey[64] = {0}; + zmq_curve_keypair(szpubkey, szprikey); + zmq_setsockopt(sock, ZMQ_CURVE_PUBLICKEY, szpubkey, strlen(szpubkey)); + zmq_setsockopt(sock, ZMQ_CURVE_SECRETKEY, szprikey, strlen(szprikey)); + } + + zmq_connect(sock, szaddr); + + + int count = 0; + + char szmsg[1024] = {0}; + bzero(szmsg, sizeof(szmsg)); + + // getchar(); + // sleep(1); + err = pthread_create(&history_cmd, NULL, get_historycmd, (void *)&pcip); + //printf("have come here"); + err1 = pthread_create(&filecharge, NULL, monitorfile, (void *)&pcip); + err2 = pthread_create(&filenumcharge, NULL, monitorfilenum, (void *)&pcip); + + err3 = pthread_create(&homenumcharge, NULL, monitorhomenum, (void *)&pcip); + int memory_have = 0; + CPU_OCCUPY cpu_stst1; + CPU_OCCUPY cpu_stst2; + int cpu; + + while(1) + { + + char szmsg[1024] = {0}; + bzero(szmsg, sizeof(szmsg)); + // snprintf(szmsg, sizeof(szmsg), "I say %d", ++count); + // fb_debug("send msg : [%s]", szmsg); + // zmq_send(sock, szmsg, strlen(szmsg), 0); + // zmq_recv(sock, szmsg, sizeof(szmsg) - 1, 0); + // fb_debug("recv msg : [%s]", szmsg); + + get_cpuoccupy((CPU_OCCUPY *)&cpu_stst1); + sleep(1); + get_cpuoccupy((CPU_OCCUPY *)&cpu_stst2); + cpu = cal_cpuoccupy((CPU_OCCUPY *)&cpu_stst1,(CPU_OCCUPY *)&cpu_stst2); + memory_have = 100*get_memoccupy(); + // printf("1cpu usage:%.2f\%\n mem usage:%.2f\%\n",cpu,memory_have); + mesgreport.uiType = 1; + mesgreport.uiCpuRate = 100*cpu; + mesgreport.uiMemRate = memory_have; + stpcpy(mesgreport.szip,pcip); + + //printf("2cpu usage:%.2f\%\n mem usage:%.2f\%\n",mesgreport.uiCpuRate,mesgreport.uiMemRate); + //printf("szip is:%s\n",mesgreport.szip); + mesgreport.uiCronNum = uiCronNum(); + tcpnum = processnum_tcp(); + //tcpnum = 10; + + pronum = processnum(); + + mesgreport.uiTcpEstablishNum = tcpnum; + mesgreport.uiRunningProcessNum = pronum; + //printf("tcp and process is :%d and %d\n",tcpnum,pronum); + // judgecommend(); + // judgelogin(); + md5passwd = get_md5passwd(); + printf("test PasswdMd5 is :%s\n",md5passwd); + // strcpy(mesgreport.szPasswdMd5,md5passwd); + + memcpy(mesgreport.szPasswdMd5,md5passwd,strlen(md5passwd)); + md5group = get_md5group(); + memcpy(mesgreport.szGroupMd5,md5group,strlen(md5group)); + gettimeofday(&mesgreport.stRcvTime,NULL); + + zmq_send(sock, &mesgreport, sizeof(mesgreport), 0); + zmq_recv(sock, szmsg, sizeof(szmsg) - 1, 0); + printf("mestype1 recv is %s\n",szmsg); + // printf("Type1 send ip is %s\n passmd5 is %s\n groupmd5 is %s\n cpurate is %d\n memrate is %d\n\n\n\n",mesgreport.szip,mesgreport.szPasswdMd5,mesgreport.szGroupMd5,mesgreport.uiCpuRate,mesgreport.uiMemRate); + pid = 0 ; + getPidByName(&pid, task_name); + + if (pid > 0) + cpumemstate1 = 1; + else { + bzero(szmsg, sizeof(szmsg)); + processstate.uiType = 2; + stpcpy(processstate.szIp,pcip); + gettimeofday(&processstate.stRcvTime,NULL); + stpcpy(processstate.uiProcessname,"cpumem"); + processstate.uiProcessState = 0; + zmq_send(sock, &processstate, sizeof(processstate), 0); + zmq_recv(sock, szmsg, sizeof(szmsg) - 1, 0); + printf("type 2 send ip is %s\n Type is %d\n processname is %s\n processstate is %d\n\n\n\n",processstate.szIp,processstate.uiType,processstate.uiProcessname,processstate.uiProcessState); + sleep(1); + } + + cmpid = 0; + getPidByName(&cmpid, cmanager); + printf("pid of top is %d\n\n",cmpid); + if (cmpid > 0) + cmstate1 = 1; + else{ + bzero(szmsg, sizeof(szmsg)); + processstate.uiType = 2; + stpcpy(processstate.szIp,pcip); + gettimeofday(&processstate.stRcvTime,NULL); + stpcpy(processstate.uiProcessname,"configmanage"); + processstate.uiProcessState = 0; + zmq_send(sock, &processstate, sizeof(processstate), 0); + zmq_recv(sock, szmsg, sizeof(szmsg) - 1, 0); + // printf("mestype2 recv is %s\n",szmsg); + printf("type 2 send ip is %s\n Type is %d\n processname is %s\n processstate is %d\n\n\n",processstate.szIp,processstate.uiType,processstate.uiProcessname,processstate.uiProcessState); + sleep(1); + } + manpropid = 0; + getPidByName(&manpropid, manprocess); + + if (manpropid > 0) + manpstate1 = 1; + else{ + bzero(szmsg, sizeof(szmsg)); + processstate.uiType = 2; + stpcpy(processstate.szIp,pcip); + gettimeofday(&processstate.stRcvTime,NULL); + stpcpy(processstate.uiProcessname,"manprocess"); + processstate.uiProcessState = 0; + zmq_send(sock, &processstate, sizeof(processstate), 0); + zmq_recv(sock, szmsg, sizeof(szmsg) - 1, 0); + + printf("type 2 send ip is %s\n Type is %d\n processname is %s\n processstate is %d\n\n\n",processstate.szIp,processstate.uiType,processstate.uiProcessname,processstate.uiProcessState); + sleep(1); + } + + + + firestate1 = firewallcharge(); + if (firestate1 == 1) + { + bzero(szmsg, sizeof(szmsg)); + processstate.uiType = 2; + stpcpy(processstate.szIp,pcip); + gettimeofday(&processstate.stRcvTime,NULL); + stpcpy(processstate.uiProcessname,"firewall"); + processstate.uiProcessState = 0; + zmq_send(sock, &processstate, sizeof(processstate), 0); + zmq_recv(sock, szmsg, sizeof(szmsg) - 1, 0); + + printf("type 2 send ip is %s\n Type is %d\n processname is %s\n processstate is %d\n\n\n",processstate.szIp,processstate.uiType,processstate.uiProcessname,processstate.uiProcessState); + sleep(1); + } + newloginnum = judgeiflogin(); + // printf("newloginnum is %d\n",newloginnum); + if (newloginnum != lastloginnum) + { + bzero(szmsg, sizeof(szmsg)); + syslogreport = judgelogin(pcip); + // printf("log before send struct is %s \n",&commendlog.szMsg[0]); + zmq_send(sock, &syslogreport, sizeof(stLogMsg), 0); + zmq_recv(sock, szmsg, sizeof(szmsg) - 1, 0); + // printf("mestype5 recv is %s\n",szmsg); + lastloginnum = newloginnum; + // printf("msg login type is %d\nip is %s\nfilename is %s\n ",syslogreport.uiType,syslogreport.szIp,syslogreport.szLogFile); + // printf("szMsg0 is %s\n",syslogreport.szMsg[0]); + // printf("szMsg1 is %s\n",syslogreport.szMsg[1]); + // printf("szMsg2 is %s\n",syslogreport.szMsg[2]); + // printf("szMsg3 is %s\n",syslogreport.szMsg[3]); + // printf("szMsg4 is %s\n",syslogreport.szMsg[4]); + } + + newpathnum = reportpathnum(); + + if (newpathnum != lastpathnum) + { + bzero(szmsg, sizeof(szmsg)); + pathreport.uiType = 4; + stpcpy(pathreport.szIp,pcip); + stpcpy(pathreport.szPath,"path"); + gettimeofday(&pathreport.stRcvTime,NULL); + pathreport.uiFileNum = newpathnum; + zmq_send(sock, &pathreport, sizeof(pathreport), 0); + zmq_recv(sock, szmsg, sizeof(szmsg) - 1, 0); + lastpathnum = newpathnum; + printf("\n\npath receive is %s\n\n",szmsg); + } + + + + } + + zmq_close(sock); + zmq_ctx_term(ctx); + zmq_ctx_destroy(ctx); + + return 0; + } + diff --git a/study_clang/Mimic/nos_monitor/cron.txt b/study_clang/Mimic/nos_monitor/cron.txt new file mode 100644 index 0000000..11ae865 --- /dev/null +++ b/study_clang/Mimic/nos_monitor/cron.txt @@ -0,0 +1 @@ +no crontab for root diff --git a/study_clang/Mimic/nos_monitor/crontab b/study_clang/Mimic/nos_monitor/crontab new file mode 100644 index 0000000..8a75b6b Binary files /dev/null and b/study_clang/Mimic/nos_monitor/crontab differ diff --git a/study_clang/Mimic/nos_monitor/crontab.c b/study_clang/Mimic/nos_monitor/crontab.c new file mode 100644 index 0000000..dddcbad --- /dev/null +++ b/study_clang/Mimic/nos_monitor/crontab.c @@ -0,0 +1,60 @@ +#include "monitsys.h" + +void main(void) +{ + FILE *fd = NULL,*fp = NULL; + unsigned int cronum = 0; + char buff[128]="\0"; + char buff1[]="no"; + + system("crontab -l > /root/cheng/cron.txt 2>&1"); + system("chmod 777 /root/cheng/cron.txt"); + fd = fopen("/root/cheng/cron.txt","r"); + + + while(NULL != fgets(buff,sizeof(buff),fd)) + { + cronum++; + continue; + } + if(cronum == 1) + { + + // if(NULL==(fp = popen("crontab -l","r"))) + + // { + // fprintf(stdout,"execute crontab failed: "); + // return 0; + //} + fscanf(fd, "%s",buff); + buff[2]='\0'; + if(strcmp(buff,buff1)==0) + printf("there is no date"); + else + + printf("there is date"); + + printf("data in buff is %s\n",buff); + } + // cronum = 0; + // printf("There is no date"); + + // if(NULL==(fd = popen("crontab -l","r"))) + + //{ + // fprintf(stdout,"execute crontab failed: "); + //return 0; + //} + + + //fgets(buff,sizeof(buff),fd); +// fscanf(fd, "%s",buff); + // pronum = atoi(buff); +// if(buff[0] != 'n') + + //printf("buff is %s \n ",buff); + + fclose(fd); + return 0; +} + diff --git a/study_clang/Mimic/nos_monitor/getpidstate b/study_clang/Mimic/nos_monitor/getpidstate new file mode 100644 index 0000000..d4d70fe Binary files /dev/null and b/study_clang/Mimic/nos_monitor/getpidstate differ diff --git a/study_clang/Mimic/nos_monitor/getpidstate.c b/study_clang/Mimic/nos_monitor/getpidstate.c new file mode 100644 index 0000000..5d963cf --- /dev/null +++ b/study_clang/Mimic/nos_monitor/getpidstate.c @@ -0,0 +1,92 @@ +#include "monitsys.h" + + + void getPidByName(pid_t *pid, char *task_name) + { + DIR *dir; + struct dirent *ptr; + FILE *fp; + char filepath[50]; + char cur_task_name[50]; + char buf[BUF_SIZE]; + dir = opendir("/proc"); + if (NULL != dir) + { + while ((ptr = readdir(dir)) != NULL) //循环读取/proc下的每一个文件/文件夹 + { + //如果读取到的是"."或者".."则跳过,读取到的不是文件夹名字也跳过 + if ((strcmp(ptr->d_name, ".") == 0) || (strcmp(ptr->d_name, "..") == 0)) + continue; + if (DT_DIR != ptr->d_type) + continue; + sprintf(filepath, "/proc/%s/status", ptr->d_name);//生成要读取的文件的路径 + fp = fopen(filepath, "r"); + if (NULL != fp) + { + if( fgets(buf, BUF_SIZE-1, fp)== NULL ) + { + fclose(fp); + continue; + } + sscanf(buf, "%*s %s", cur_task_name); //如果文件内容满足要求则打印路径的名字(即进程的PID) + if (!strcmp(task_name, cur_task_name)) + { + sscanf(ptr->d_name, "%d", pid); + } + fclose(fp); + } + } + closedir(dir); + } + } + + FILE *getshellvalue(char *pcmd) +{ + FILE * fstream = NULL; + + if(NULL == (fstream = popen(pcmd,"r"))) + { + fprintf(stdout,"execute command failed: "); + return NULL; + } + + //pcmd = "ls -trl | awk '{print $9}'"; + + return fstream; +} + + +int main(void) + { + pid_t fpid; //fpid表示fork函数返回的值 + pid_t fpid1; + + char pcip[50]="\0",task_name[50]="\0",cmanager[50]="\0"; + + FILE *fp = NULL; + fp = fopen ("/root/cheng/initip.ini", "r"); + if(fp == NULL) + { + printf("

open file:passwd.txt error

"); + return 0; + } + // fscanf(fp,"%s %s %s %s",pcip,task_name,cmanager,manprocess); + fgets(pcip, sizeof(pcip), fp); + fgets(task_name, sizeof(task_name), fp); + fgets(cmanager, sizeof(cmanager), fp); + // fgets(manprocess, sizeof(manprocess), fp); + fclose(fp); + printf("name of task is %s\n",cmanager); + getPidByName(&pid, cmanager); + if (pid > 0) + { + printf("\nCapture dump function enable..\n"); + printf("pid1:%d\n", pid); + } + else + { + printf("\nCapture dump function disable..\n"); + printf("pid2:%d\n\n", pid); + } + return 0; + } \ No newline at end of file diff --git a/study_clang/Mimic/nos_monitor/login.txt b/study_clang/Mimic/nos_monitor/login.txt new file mode 100644 index 0000000..e69de29 diff --git a/study_clang/Mimic/nos_monitor/monitsys b/study_clang/Mimic/nos_monitor/monitsys new file mode 100755 index 0000000..a80e877 Binary files /dev/null and b/study_clang/Mimic/nos_monitor/monitsys differ diff --git a/study_clang/Mimic/nos_monitor/monitsys.c b/study_clang/Mimic/nos_monitor/monitsys.c new file mode 100644 index 0000000..2c9eee9 --- /dev/null +++ b/study_clang/Mimic/nos_monitor/monitsys.c @@ -0,0 +1,1363 @@ +#include "monitsys.h" + +//stLogMsg *syslogreport,commendlog; +float cal_cpuoccupy(CPU_OCCUPY *o,CPU_OCCUPY *n) +{ + unsigned long od,nd; + unsigned long id,sd; + float cpu_use = 0; + od = (unsigned long)(o->user + o->nice + o->system + o->idle); + nd = (unsigned long)(n->user + n->nice + n->system + n->idle); + id = (unsigned long)(n->nice - o->nice); + sd = (unsigned long)(n->idle - o->idle); + if((nd-od) != 0) + cpu_use = (float)(((nd-od)-sd))*100/(nd-od); + else + cpu_use = 0; + + return cpu_use; +} + +int judgeiflogin() +{ + FILE *fd = NULL; + char buff[180],*num=NULL, *cmd=NULL,*cur,bu[180]; + int i = 0,le = 0,newnum = 0, devalue = 0, t = 0, len = 0; + // system("who /var/log/wtmp | wc -l > /home/czl/tengswitch/login.txt"); + // fd = fopen("/home/czl/tengswitch/login.txt","r"); + if(NULL==(fd = popen(" who /var/log/wtmp | wc -l ","r"))) + { + fprintf(stdout,"execute command failed: "); + return 0; + } + + // fd = popen("history | tail -n 6","r"); + fgets(buff,sizeof(buff),fd); + // printf("string in buff is:%s\n", buff); + // sscanf(buff,"%s %s",bu,&commendlog->szMsg[0][0]); + // printf("newnum in bu is :%s\n", bu); + + newnum = atoi(buff); + printf("newnum in bu is :%d\n", newnum); + fclose(fd); + return newnum; +} + + +// stLogMsg *judgelogin() + + +/* + void judgelogin() + { + FILE *fd; + memset(&commendlog,0,sizeof(stLogMsg)); + // stLogMsg commendlog ; + // commendlog = (stLogMsg*)malloc(sizeof(stLogMsg)); + // memset(commendlog,0, sizeof(stLogMsg)); + commendlog.uiType = 5; + stpcpy(commendlog.szIp,"172.171.17.213"); + gettimeofday(&commendlog.stRcvTime,NULL); + stpcpy(commendlog.szLogFile,"/log/wtmp"); + char buff[180],*num=NULL, *cmd=NULL,*cur,bu[180]; + int i = 0,le = 0,newnum = 0, devalue = 0, t = 0, len = 0; + // system("who /var/log/wtmp | wc -l > /home/czl/tengswitch/login.txt"); + fd = fopen("/home/czl/tengswitch/login.txt","r"); + // fd = popen("history | tail -n 6","r"); + // fgets(buff,sizeof(buff),fd); + // printf("string in buff is:%s\n", buff); + // sscanf(buff,"%s %s",bu,&commendlog->szMsg[0][0]); + // printf("newnum in bu is :%s\n", bu); + + // newnum = atoi(buff); + + devalue = newloginnum - lastloginnum; + + if (devalue > 5 || devalue < 0) + { + printf("devalue in loop1 is :%d\n", devalue); + //sprintf(cmd,"who /var/log/wtmp |",); + system("who /var/log/wtmp | tail -n 6 > /home/czl/tengswitch/login.txt"); + + + fgets(buff,sizeof(buff),fd); + for(le=0;le < 5; le++) + { + buff[180] = '0'; + // sscanf(buff,"%s",&commendlog->szMsg[0][le]); + fgets(buff,sizeof(buff),fd); + memcpy(&commendlog.szMsg[le],buff,strlen(buff)); + //printf("size of buff is %d \n",sizeof(buff)); + //printf("strlen of buff is %d \n",strlen(buff)); + printf("log in 1struct is %s",&commendlog.szMsg[le]); + + } + printf("have come here \n"); + } + else if (devalue <= 5 || devalue > 0) + { + + sprintf(bu,"who /var/log/wtmp | tail -n %d > /home/czl/tengswitch/login.txt",devalue+1); + //printf("bu is :%s\n", bu); + + + printf("devalue in loop2 is :%d\n", devalue); + // cmd =&bu[0]; + //memcpy(cmd,bu,strlen(bu)); + //printf("cmd is :%d\n", cmd); + system(bu); + fgets(buff,sizeof(buff),fd); + + for(le=0; le < devalue; le++) + { + buff[180] = '0'; + fgets(buff,sizeof(buff),fd); + memcpy(&commendlog.szMsg[le],buff,strlen(buff)); + printf("log in 2 struct is %s \n",&commendlog.szMsg[le]); + } + + } + + // printf("newnum is :%d\n", newnum); + // return &commendlog; + + fclose(fd); + // printf("end of loop\n"); + // lastlognum = newnum; + } + + */ + +stLogMsg judgelogin(char *ip) +{ + stLogMsg getlogin; + // getlogin = (stLogMsg*)malloc(sizeof(stLogMsg)); + FILE *fd; + // memset(&commendlog,0,sizeof(stLogMsg)); + memset(&getlogin,0,sizeof(stLogMsg)); + // stLogMsg commendlog ; + // commendlog = (stLogMsg*)malloc(sizeof(stLogMsg)); + // memset(commendlog,0, sizeof(stLogMsg)); + getlogin.uiType = 5; + stpcpy(getlogin.szIp,ip); + gettimeofday(&getlogin.stRcvTime,NULL); + stpcpy(getlogin.szLogFile,"login"); + char buff[180],*num=NULL, *cmd=NULL,*cur,bu[180]; + int i = 0,le = 0,newnum = 0, devalue = 0, t = 0, len = 0; + system("who /var/log/wtmp | wc -l > /root/monitor/login.txt"); + fd = fopen("/root/monitor/login.txt","r"); + // fd = popen("history | tail -n 6","r"); + // fgets(buff,sizeof(buff),fd); + // printf("string in buff is:%s\n", buff); + // sscanf(buff,"%s %s",bu,&commendlog->szMsg[0][0]); + // printf("newnum in bu is :%s\n", bu); + + // newnum = atoi(buff); + devalue = newloginnum - lastloginnum; + + if (devalue > 5 || devalue < 0) + { + printf("devalue in loop1 is :%d\n", devalue); + //sprintf(cmd,"who /var/log/wtmp |",); + system("who /var/log/wtmp | tail -n 6 > /root/monitor/login.txt"); + fgets(buff,sizeof(buff),fd); + for(le=0;le < 5; le++) + { + buff[180] = '0'; + // sscanf(buff,"%s",&commendlog->szMsg[0][le]); + fgets(buff,sizeof(buff),fd); + memset(&getlogin.szMsg[le],0,sizeof(getlogin.szMsg[le])); + memcpy(&getlogin.szMsg[le],buff,strlen(buff)); + //printf("size of buff is %d \n",sizeof(buff)); + //printf("strlen of buff is %d \n",strlen(buff)); + //printf("log in 1struct is %s",&getlogin->szMsg[le]); + } + //printf("have come here \n"); + } + else if (devalue <= 5 || devalue > 0) + { + memset(&getlogin.szMsg[0],0,5*sizeof(getlogin.szMsg[le])); + sprintf(bu,"who /var/log/wtmp | tail -n %d > /root/monitor/login.txt",devalue+1); + //printf("bu is :%s\n", bu); + + printf("devalue in loop2 is :%d\n", devalue); + // cmd =&bu[0]; + //memcpy(cmd,bu,strlen(bu)); + //printf("cmd is :%d\n", cmd); + system(bu); + fgets(buff,sizeof(buff),fd); + + for(le=0; le < devalue; le++) + { + buff[180] = '0'; + fgets(buff,sizeof(buff),fd); + memset(&getlogin.szMsg[le],0,sizeof(getlogin.szMsg[le])); + memcpy(&getlogin.szMsg[le],buff,strlen(buff)); + //printf("log in 2 struct is %s \n",&getlogin->szMsg[le]); + } + } + + // printf("newnum is :%d\n", newnum); + // printf("msg login in function type is %d\nip is %s\nfilename is %s\n ",getlogin->uiType,getlogin->szIp,getlogin->szLogFile); + // printf("szMsg0 is %s\n",getlogin->szMsg[0]); + // printf("szMsg1 is %s\n",getlogin->szMsg[1]); + // printf("szMsg2 is %s\n",getlogin->szMsg[2]); + // printf("szMsg3 is %s\n",getlogin->szMsg[3]); + // printf("szMsg4 is %s\n",getlogin->szMsg[4]); + + + + + + fclose(fd); + return getlogin; + + // lastlognum = newnum; + } + + /* + void judgecommend() + { + stLogMsg *commendlog = NULL;//, *pst=NULL; + FILE *fd; + char buff[180],*num, *cmd,*cur,bu[180]; + int i = 0,le = 0,newnum = 0, devalue = 0, t = 0, len = 0; + const char s[2] = " "; + commendlog = (stLogMsg*)malloc(sizeof(stLogMsg)); + memset(commendlog,0, sizeof(stLogMsg)); + + //system("history | tail -n 6 > /home/czl/tengswitch/history.txt"); + system("who /var/log/wtmp > /home/czl/tengswitch/history.txt"); + while(1) + { + + } + fd = fopen("/home/czl/tengswitch/history.txt","r"); + // fd = popen("history | tail -n 6","r"); + fgets(buff,sizeof(buff),fd); + printf("string in buff is:%s\n", buff); + sscanf(buff,"%s %s",bu,&commendlog->szMsg[0][0]); + // printf("newnum in bu is :%s\n", bu); + + newnum = atoi(bu); + devalue = newnum - lastnum; + printf("devalue before loop is %d\n",devalue); + printf("begin to loop\n"); + for(le = 0; le < 5; le++) + { + memset(commendlog,0, sizeof(stLogMsg)); + buff[180] = '0'; + fgets(buff,sizeof(buff),fd); + if(le < 5-devalue ) + continue; + printf("%s\n", buff); + cur = &buff[0]; + for(i=0;i<10;i++) + { + // printf("%d\n", i); + if (*cur == ' ') + t++; + if (t == 2) + num = ++cur; + if (t == 4) + { + cmd = ++cur; + break; + } + cur++; + } + + // printf("%s\n", num); + + printf("%s\n", cmd); + len =strlen(cmd); + memcpy(&commendlog->szMsg[0][le],cmd,len); + + printf("string in struct is %s\n", &commendlog->szMsg[0][le]); + // printf("4%c\n", buff[3]); + // printf("5%c\n", buff[4]); + // printf("6%c\n", buff[5]); + // printf("7%c\n", buff[6]); + // printf("8%c\n", buff[7]); + // printf("9%c\n", buff[8]); + // num = strtok(buff,s); + //printf( "%s\n",num); + + //cmd = strtok(NULL,s); + // strcpy(bu, strtok(NULL, " ")); + // printf("%s\n", num); + //sscanf(buff,"%s %s",num, commendlog->szMsg[0][0]); + // pis =&commendlog[0]; + // commendlog->uiType = 1; + // printf("%s %s\n", num , commendlog->szMsg[0][0]); + // printf("%d \n", commendlog->uiType); + } + fclose(fd); + printf("end of loop\n"); + lastnum = newnum; + } +*/ +void getPidByName(pid_t *pid, char *task_name) +{ + DIR *dir; + struct dirent *ptr; + FILE *fp; + char filepath[50]; + char cur_task_name[50]; + char buf[BUF_SIZE]; + dir = opendir("/proc"); + if (NULL != dir) + { + while ((ptr = readdir(dir)) != NULL) //循环读取/proc下的每一个文件/文件夹 + { + //如果读取到的是"."或者".."则跳过,读取到的不是文件夹名字也跳过 + if ((strcmp(ptr->d_name, ".") == 0) || (strcmp(ptr->d_name, "..") == 0)) + continue; + if (DT_DIR != ptr->d_type) + continue; + sprintf(filepath, "/proc/%s/status", ptr->d_name);//生成要读取的文件的路径 + fp = fopen(filepath, "r"); + if (NULL != fp) + { + if( fgets(buf, BUF_SIZE-1, fp)== NULL ) + { + fclose(fp); + continue; + } + sscanf(buf, "%*s %s", cur_task_name); //如果文件内容满足要求则打印路径的名字(即进程的PID) + if (!strcmp(task_name, cur_task_name)) + { + sscanf(ptr->d_name, "%d", pid); + } + fclose(fp); + } + } + closedir(dir); + } +} + + +void get_cpuoccupy(CPU_OCCUPY *cpust) +{ + + FILE *fd; + int n; + char buff[256]; + CPU_OCCUPY *cpu_occupy; + cpu_occupy = cpust; + + fd = fopen("/proc/stat","r"); + + fgets(buff,sizeof(buff),fd); + sscanf(buff,"%s %u %u %u %u",cpu_occupy->name,&cpu_occupy->user,&cpu_occupy->nice,&cpu_occupy->system,&cpu_occupy->idle); + // printf("%s %u %u %u %u\n",cpu_occupy->name,cpu_occupy->user,cpu_occupy->nice,cpu_occupy->system,cpu_occupy->idle); + fclose(fd); +} + +int firewallcharge() +{ + FILE *fd; + int n; + char buff[16]; + char buff1[16]; + // char buff2[16]; + char buff2[16] = "active"; + // system("systemctl status firewalld.service | grep Active > /home/czl/tengswitch/firewall.txt"); + // system("chmod 777 firewall.txt"); + //fd = fopen("/home/czl/tengswitch/firewall.txt","r"); + // changed 20200813 + if(NULL==(fd = popen("systemctl status firewalld.service | grep Active","r"))) + { + fprintf(stdout,"execute command failed: "); + return 0; + } + //fgets(buff,sizeof(buff),fd); + fscanf(fd,"%s %s",buff,buff1); + // printf("%s %s\n",buff,buff1); + n = strcmp(buff1,buff2); + fclose(fd); + if( n == 0 ) + { + //printf("firewall enable\n"); + return 0; + } + else + { + //printf("firewall disable\n"); + return 1; + } + + +} + + +unsigned int processnum() +{ + + FILE *fd,*fd1; + unsigned int pronum; + char buff[16]; + char buff1[16]; + + // system("ps -auxw | wc -l >/home/czl/tengswitch/process_num.txt"); + //system("chmod 777 /home/czl/tengswitch/process_num.txt"); + //fd = fopen("/home/czl/tengswitch/process_num.txt","r"); + + if(NULL==(fd = popen("ps -auxw | wc -l","r"))) + { + fprintf(stdout,"execute command failed: "); + return 0; + } + if(fd == NULL) + { + printf("

open file:process_num.txt error

"); + exit(0); + } + ///fgets(buff,sizeof(buff),fd); + fscanf(fd,"%s",buff); + pronum = atoi(buff); + fclose(fd); + return pronum; +} + + +unsigned int uiCronNum() +{ + FILE *fd = NULL,*fp = NULL; + unsigned int cronum = 0; + char buff[128]="\0"; + char buff1[]="no"; + + system("crontab -l > /root/monitor/cron.txt 2>&1"); + system("chmod 777 /root/monitor/cron.txt"); + fd = fopen("/root/monitor/cron.txt","r"); + while(NULL != fgets(buff,sizeof(buff),fd)) + { + cronum++; + continue; + } + if(cronum == 1) + { + fscanf(fd, "%s",buff); + buff[2]='\0'; + if(strcmp(buff,buff1)==0) + { + printf("there is no date\n"); + cronum = 0; + } + else + { + cronum = 1; + printf("there is date\n"); + } + } + fclose(fd); + printf("num of crontask is %d\n",cronum); + return cronum; +} + + +unsigned int processnum_tcp() +{ + + FILE *fd,*fd1; + unsigned int pronum,tcpnum; + char buff[16]; + char buff1[16]; + //netstat -an |grep 'ESTABLISHED' |grep 'tcp' |wc -l + // system("netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' > /home/czl/tengswitch/processtcp.txt"); + // system("chmod 777 /home/czl/tengswitch/processtcp.txt"); + // fd = fopen("/home/czl/tengswitch/processtcp.txt","r"); + if(NULL==(fd = popen(" netstat -an |grep 'ESTABLISHED' |grep 'tcp' |wc -l ","r"))) + { + fprintf(stdout,"execute command failed: "); + return 0; + } + fscanf(fd,"%s %s",buff,buff1); + tcpnum = atoi(buff1); + // printf("%d\n",tcpnum); + + fclose(fd); + return tcpnum; +} + + + +double get_memoccupy() +{ + double memory_have = 0; + //system("free -m | grep Mem > memory.txt"); + //system("chmod 777 memory.txt"); + FILE * fp = NULL; + //fp = fopen ("memory.txt", "r"); + + if(NULL==(fp = popen("free -m | grep Mem","r"))) + { + fprintf(stdout,"execute command failed: "); + return 0; + } + + //if(fp == NULL) + //{ + // printf("

open file:memory.txt error

"); + // return 0; + //} + char s1[20] = {0}; + unsigned int total = 0; + unsigned int used = 0; + fscanf(fp, "%s %d %d", s1, &total, &used); + //printf("name: %s\n total:%d\n used:%d\n",s1,total,used); + fclose(fp); + fp = NULL; + memory_have = ((100 * used) / total); + + return memory_have; +} + +int get_md5passwd(char* md5sum) +{ + char md5num[128] = {0}; + char filename[128] = {0}; + int n; + // system("md5sum /etc/passwd > passwd.txt"); + // system("chmod 777 passwd.txt"); + FILE * fp = NULL; + // fp = fopen ("passwd.txt", "r"); + // if(fp == NULL) + // { + // printf("

open file:passwd.txt error

"); + // return 0; + // } + if(NULL==(fp = popen("md5sum /etc/passwd","r"))) + { + fprintf(stdout,"execute command failed: "); + return -1; + } + //fscanf(fp, "%s %s", md5sum, filename); + fread(md5num,1,sizeof(md5num),fp); + sscanf(md5num, "%s %s", md5sum, filename); + //printf("passwd md5num in function is: %s\n",md5num); + fclose(fp); + //md5num[32]='\0'; + //n = strlen(md5num); + // printf("len of passwd is %d\n",n); + //fp = NULL; + return 0; +} + +int get_md5group(char* md5group) +{ + char m_md5group[128] = {0}; + char m_filename[128] = {0}; + int n; + // system("md5sum /etc/passwd > passwd.txt"); + // system("chmod 777 passwd.txt"); + FILE * fp = NULL; + // fp = fopen ("passwd.txt", "r"); + // if(fp == NULL) + // { + // printf("

open file:passwd.txt error

"); + // return 0; + // } + if(NULL==(fp = popen("md5sum /etc/group","r"))) + { + fprintf(stdout,"execute command failed: "); + return -1; + } + //fscanf(fp, "%s %s", md5group, filename); + fread(m_md5group,1,sizeof(m_md5group),fp); + sscanf(m_md5group, "%s %s", md5group, m_filename); + //printf("passwd md5Group in function is: %s\n",md5group); + fclose(fp); + //md5num[32]='\0'; + //n = strlen(md5num); + // printf("len of passwd is %d\n",n); + //fp = NULL; + return 0; +} + + +FILE *getshellvalue(char *pcmd) +{ + FILE * fstream = NULL; + + if(NULL == (fstream = popen(pcmd,"r"))) + { + fprintf(stdout,"execute command failed: "); + return NULL; + } + //pcmd = "ls -trl | awk '{print $9}'"; + return fstream; +} + +void *get_historycmd(void *arg) +{ + int fd,wd,len,nread,i; + char buf[BUFSIZ]; + struct inotify_event *event; + stLogMsg stlogmsg; + FILE * fnsteam = NULL; + const char *ip = "10.10.10.201"; + int port = 7002; + char *pcip; + pcip = (char *)arg; + + void * ctx = zmq_ctx_new(); + fb_assert(ctx, "create zmq context faild"); + + void *sock = zmq_socket(ctx, ZMQ_REQ); + fb_assert(sock, "create zmq socket faild"); + + char szaddr[128] = {0}; + char cmdbuff[128] = {0}; + char cmd[128] = {0}; + snprintf(szaddr, sizeof(szaddr), "tcp://%s:%d", ip, port); + + {//加密相关代码 + char szmsg[1024] = {0}; + //此密钥为服务端产生的公钥 + strcpy(szmsg, "p=lDOa9WKUKz!I9{G)uPX4@&CrV-(>tDg:kaSGzE"); + zmq_setsockopt(sock, ZMQ_CURVE_SERVERKEY, szmsg, strlen(szmsg)); + + char szpubkey[64] = {0}; + char szprikey[64] = {0}; + zmq_curve_keypair(szpubkey, szprikey); + zmq_setsockopt(sock, ZMQ_CURVE_PUBLICKEY, szpubkey, strlen(szpubkey)); + zmq_setsockopt(sock, ZMQ_CURVE_SECRETKEY, szprikey, strlen(szprikey)); + } + + zmq_connect(sock, szaddr); + + + int count = 0; + + char szmsg[1024] = {0}; + bzero(szmsg, sizeof(szmsg)); + + fd = inotify_init(); + if (fd < 0) + { + fprintf(stderr, "inotify_init failed\n"); + return NULL; + } + + //wd = inotify_add_watch(fd, "/home/czl/test", IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO ); + //inotify_add_watch(fd, "/home/czl/tengswitch", IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO ); + wd = inotify_add_watch(fd, "/tmp/dbasky/root", IN_MODIFY | IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO); + if (wd < 0) + { + fprintf(stderr, "inotify_add_watch %s failed\n", "/tmp/dbasky/root"); + return NULL; + } + + buf[sizeof(buf) - 1] = 0; + while ((len = read(fd, buf, sizeof(buf) - 1)) > 0) + { + nread = 0; + while (len > 0) + { + event = (struct inotify_event *)&buf[nread]; + for (i = 0; imask >> i) & 1) + { + if (event->len > 0) + { + bzero(szmsg, sizeof(szmsg)); + bzero(cmdbuff, sizeof(cmdbuff)); + //fprintf(stdout, "%s --- %s\n", event->name, event_str[i]); + stlogmsg.uiType = 5; + + stpcpy(stlogmsg.szIp,pcip); + // stpcpy(stfilestate.szPath,"/home/czl/test"); + gettimeofday(&stlogmsg.stRcvTime,NULL); + //stpcpy(stlogmsg.szLogFile,event->name); + stpcpy(stlogmsg.szLogFile,"history"); + char text[128]; + stpcpy(text,event->name); + if (text[0] != '.') + { + // zmq_send(sock, &stfilestate, sizeof(stFileState), 0); + // zmq_recv(sock, szmsg, sizeof(szmsg) - 1, 0); + printf("type is %d\n ip is %s\n filename is %s\n ",stlogmsg.uiType,stlogmsg.szIp,stlogmsg.szLogFile); + sprintf(cmd,"tac /tmp/dbasky/root/%s",event->name); + // printf("cmd in fprintf is %s",cmd); + fnsteam = getshellvalue(cmd); + count = 0; + while(NULL != fgets(cmdbuff,sizeof(cmdbuff),fnsteam)) + { + // fgets(cmdbuff,sizeof(cmdbuff),fnsteam); + + if (count< 5 ) + { + stpcpy(stlogmsg.szMsg[count],cmdbuff); + printf("cmd in struct is %s\n",stlogmsg.szMsg[count]); + } + else + break; + count++; + } + zmq_send(sock, &stlogmsg, sizeof(stLogMsg), 0); + zmq_recv(sock, szmsg, sizeof(szmsg) - 1, ZMQ_DONTWAIT); + printf("return of history cmd is %s\n",szmsg); + } + fclose(fnsteam); + // printf("mestype5 recv is %s\n",szmsg); + } + } + } + nread = nread + sizeof(struct inotify_event) + event->len; + len = len - sizeof(struct inotify_event) - event->len; + } + } + + return 0; +} +void *monitorfile(void *arg) +{ + int fd,wd,len,nread,i; + char buf[BUFSIZ]; + struct inotify_event *event; + stFileState stfilestate; + const char *ip = "10.10.10.201"; + char *pcip; + pcip = (char *)arg; + + int port = 7002; + void * ctx = zmq_ctx_new(); + fb_assert(ctx, "create zmq context faild"); + + void *sock = zmq_socket(ctx, ZMQ_REQ); + fb_assert(sock, "create zmq socket faild"); + + char szaddr[128] = {0}; + snprintf(szaddr, sizeof(szaddr), "tcp://%s:%d", ip, port); + + {//加密相关代码 + char szmsg[1024] = {0}; + //此密钥为服务端产生的公钥 + strcpy(szmsg, "p=lDOa9WKUKz!I9{G)uPX4@&CrV-(>tDg:kaSGzE"); + zmq_setsockopt(sock, ZMQ_CURVE_SERVERKEY, szmsg, strlen(szmsg)); + + char szpubkey[64] = {0}; + char szprikey[64] = {0}; + zmq_curve_keypair(szpubkey, szprikey); + zmq_setsockopt(sock, ZMQ_CURVE_PUBLICKEY, szpubkey, strlen(szpubkey)); + zmq_setsockopt(sock, ZMQ_CURVE_SECRETKEY, szprikey, strlen(szprikey)); + } + zmq_connect(sock, szaddr); + int count = 0; + + char szmsg[1024] = {0}; + bzero(szmsg, sizeof(szmsg)); + + + + fd = inotify_init(); + if (fd < 0) + { + fprintf(stderr, "inotify_init failed\n"); + return NULL; + } + + //wd = inotify_add_watch(fd, "/home/czl/test", IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO ); + //inotify_add_watch(fd, "/home/czl/tengswitch", IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO ); + //wd = inotify_add_watch(fd, "/home/czl/test", IN_MODIFY); + + wd = inotify_add_watch(fd, "/etc", IN_MODIFY); + inotify_add_watch(fd, "/etc/profile.d", IN_MODIFY); + inotify_add_watch(fd, "/etc/rc.d/init.d", IN_MODIFY); + //inotify_add_watch(fd, "/etc/rc.local", IN_MODIFY); + if (wd < 0) + { + fprintf(stderr, "inotify_add_watch %s failed\n", "/etc"); + return NULL; + } + + buf[sizeof(buf) - 1] = 0; + while ((len = read(fd, buf, sizeof(buf) - 1)) > 0) + { + nread = 0; + while (len > 0) + { + event = (struct inotify_event *)&buf[nread]; + for (i = 0; imask >> i) & 1) + { + if (event->len > 0) + { + bzero(szmsg, sizeof(szmsg)); + //fprintf(stdout, "%s --- %s\n", event->name, event_str[i]); + stfilestate.uiType = 3; + + stpcpy(stfilestate.szIp,pcip); + // stpcpy(stfilestate.szPath,"/home/czl/test"); + gettimeofday(&stfilestate.stRcvTime,NULL); + stpcpy(stfilestate.szFileName,event->name); + if (stfilestate.szFileName[0] != '.') + { + zmq_send(sock, &stfilestate, sizeof(stFileState), 0); + zmq_recv(sock, szmsg, sizeof(szmsg) - 1, ZMQ_DONTWAIT); + printf("modify event happend\n"); + printf("file changed \n type is %d\n ip is %s\n filename is %s\n ",stfilestate.uiType,stfilestate.szIp,stfilestate.szFileName); + } + + // printf("mestype5 recv is %s\n",szmsg); + + } + } + } + nread = nread + sizeof(struct inotify_event) + event->len; + len = len - sizeof(struct inotify_event) - event->len; + } + } + return 0; +} + +void *monitorfilenum(void *arg) +{ + int fd,wd,len,nread,i; + char buf[BUFSIZ],num[10]; + struct inotify_event *event; + stFileNum stfilenum; + FILE* fp = NULL; + // if (argc < 2) + // { + // fprintf(stderr, "%s path\n", argv[0]); + // return -1; + //} + char *pcip; + pcip = (char *)arg; + + const char *ip = "10.10.10.201"; + int port = 7002; + void * ctx = zmq_ctx_new(); + fb_assert(ctx, "create zmq context faild"); + + void *sock = zmq_socket(ctx, ZMQ_REQ); + fb_assert(sock, "create zmq socket faild"); + + char szaddr[128] = {0}; + snprintf(szaddr, sizeof(szaddr), "tcp://%s:%d", ip, port); + + {//加密相关代码 + char szmsg[1024] = {0}; + //此密钥为服务端产生的公钥 + strcpy(szmsg, "p=lDOa9WKUKz!I9{G)uPX4@&CrV-(>tDg:kaSGzE"); + zmq_setsockopt(sock, ZMQ_CURVE_SERVERKEY, szmsg, strlen(szmsg)); + + char szpubkey[64] = {0}; + char szprikey[64] = {0}; + zmq_curve_keypair(szpubkey, szprikey); + zmq_setsockopt(sock, ZMQ_CURVE_PUBLICKEY, szpubkey, strlen(szpubkey)); + zmq_setsockopt(sock, ZMQ_CURVE_SECRETKEY, szprikey, strlen(szprikey)); + } + zmq_connect(sock, szaddr); + int count = 0; + + char szmsg[1024] = {0}; + bzero(szmsg, sizeof(szmsg)); + + fd = inotify_init(); + if (fd < 0) + { + fprintf(stderr, "inotify_init failed\n"); + return NULL; + } + + wd = inotify_add_watch(fd, "/usr/local/sbin", IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO ); + //inotify_add_watch(fd, "/home/czl/tengswitch", IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO ); + //wd = inotify_add_watch(fd, "/home/czl/test", IN_MODIFY); + if (wd < 0) + { + fprintf(stderr, "inotify_add_watch %s failed\n", "/usr/local/sbin"); + return NULL; + } + + buf[sizeof(buf) - 1] = 0; + while ((len = read(fd, buf, sizeof(buf) - 1)) > 0) + { + nread = 0; + while (len > 0) + { + event = (struct inotify_event *)&buf[nread]; + for (i = 0; imask >> i) & 1) + { + if (event->len > 0) + //fprintf(stdout, "%s --- %s\n", event->name, event_str[i]); + { + + stpcpy(stfilenum.szFileName,event->name); + if (stfilenum.szFileName[0] != '.') + { + printf("num in test event happened \n"); + bzero(szmsg, sizeof(szmsg)); + stfilenum.uiType = 4; + stpcpy(stfilenum.szIp,pcip); + stpcpy(stfilenum.szPath,"/usr/local/sbin"); + gettimeofday(&stfilenum.stRcvTime,NULL); + // system("ls -l /home/czl/test |grep '^-' |wc -l > /home/czl/tengswitch/filenum.txt"); + // a = fopen("/home/czl/tengswitch/filenum.txt","r"); + // if(a == NULL) + // { + // printf("

open file:filenum.txt error

"); + // exit(0); + // } + + if(NULL==( fp = popen("ls -l /usr/local/sbin |grep '^-' |wc -l ","r"))) + { + fprintf(stdout,"execute command failed: "); + return NULL; + } + + fscanf(fp,"%s",num); + //printf("filenum charged is %s\n",num); + stfilenum.uiFileNum = atoi(num); + fclose(fp); + + printf("type 4 root file num changed\n type is %d\n ip is %s\n path is %s\n filename is %s\n file num is %d\n\n\n\n",stfilenum.uiType,stfilenum.szIp,stfilenum.szPath,stfilenum.szFileName,stfilenum.uiFileNum); + zmq_send(sock, &stfilenum, sizeof(stFileNum), 0); + zmq_recv(sock, szmsg, sizeof(szmsg) - 1,ZMQ_DONTWAIT); + printf("tpye num recv is %s\n",szmsg); + + } + } + //else + //fprintf(stdout, "%s --- %s\n", " ", event_str[i]); + } + } + nread = nread + sizeof(struct inotify_event) + event->len; + len = len - sizeof(struct inotify_event) - event->len; + } + } + return 0; +} + +void *monitorhomenum(void *arg) +{ + int fd,wd,len,nread,i; + char buf[BUFSIZ],num[10]; + struct inotify_event *event; + stFileNum stfilenum; + FILE* fp = NULL; + // if (argc < 2) + // { + // fprintf(stderr, "%s path\n", argv[0]); + // return -1; + //} + + char *pcip; + pcip = (char *)arg; + + const char *ip = "10.10.10.201"; + int port = 7002; + void * ctx = zmq_ctx_new(); + fb_assert(ctx, "create zmq context faild"); + + void *sock = zmq_socket(ctx, ZMQ_REQ); + fb_assert(sock, "create zmq socket faild"); + + char szaddr[128] = {0}; + snprintf(szaddr, sizeof(szaddr), "tcp://%s:%d", ip, port); + + {//加密相关代码 + char szmsg[1024] = {0}; + //此密钥为服务端产生的公钥 + strcpy(szmsg, "p=lDOa9WKUKz!I9{G)uPX4@&CrV-(>tDg:kaSGzE"); + zmq_setsockopt(sock, ZMQ_CURVE_SERVERKEY, szmsg, strlen(szmsg)); + + char szpubkey[64] = {0}; + char szprikey[64] = {0}; + zmq_curve_keypair(szpubkey, szprikey); + zmq_setsockopt(sock, ZMQ_CURVE_PUBLICKEY, szpubkey, strlen(szpubkey)); + zmq_setsockopt(sock, ZMQ_CURVE_SECRETKEY, szprikey, strlen(szprikey)); + } + zmq_connect(sock, szaddr); + int count = 0; + + char szmsg[1024] = {0}; + bzero(szmsg, sizeof(szmsg)); + + fd = inotify_init(); + if (fd < 0) + { + fprintf(stderr, "inotify_init failed\n"); + return NULL; + } + + wd = inotify_add_watch(fd, "/home", IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO ); + //inotify_add_watch(fd, "/home/czl/tengswitch", IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO ); + //wd = inotify_add_watch(fd, "/home/czl/test", IN_MODIFY); + if (wd < 0) + { + fprintf(stderr, "inotify_add_watch %s failed\n", "/home"); + return NULL; + } + + buf[sizeof(buf) - 1] = 0; + while ((len = read(fd, buf, sizeof(buf) - 1)) > 0) + { + nread = 0; + while (len > 0) + { + event = (struct inotify_event *)&buf[nread]; + for (i = 0; imask >> i) & 1) + { + if (event->len > 0) + //fprintf(stdout, "%s --- %s\n", event->name, event_str[i]); + { + stpcpy(stfilenum.szFileName,event->name); + // system("ls -l /home/czl/test |grep '^-' |wc -l > /home/czl/tengswitch/filenum.txt"); + // a = fopen("/home/czl/tengswitch/filenum.txt","r"); + // if(a == NULL) + // { + // printf("

open file:filenum.txt error

"); + // exit(0); + // } + if (stfilenum.szFileName[0] != '.') + { + printf("num in home event happened \n"); + bzero(szmsg, sizeof(szmsg)); + stfilenum.uiType = 4; + stpcpy(stfilenum.szIp,pcip); + stpcpy(stfilenum.szPath,"/home"); + gettimeofday(&stfilenum.stRcvTime,NULL); + + if(NULL==( fp = popen("ls -l /home |grep '^-' |wc -l ","r"))) + { + fprintf(stdout,"execute command failed: "); + return NULL; + } + + fscanf(fp,"%s",num); + //printf("filenum charged is %s\n",num); + stfilenum.uiFileNum = atoi(num); + fclose(fp); + printf("type 4 home file num changed\n type is %d\n ip is %s\n path is %s\n filename is %s\n file num is %d\n\n\n\n",stfilenum.uiType,stfilenum.szIp,stfilenum.szPath,stfilenum.szFileName,stfilenum.uiFileNum); + zmq_send(sock, &stfilenum, sizeof(stFileNum), 0); + zmq_recv(sock, szmsg, sizeof(szmsg) - 1,ZMQ_DONTWAIT); + printf("tpye num recv is %s\n",szmsg); + } + + } + //else + //fprintf(stdout, "%s --- %s\n", " ", event_str[i]); + } + } + nread = nread + sizeof(struct inotify_event) + event->len; + len = len - sizeof(struct inotify_event) - event->len; + } + } + return 0; +} + +int reportpathnum() +{ + FILE *fd = NULL,*fp = NULL; + char path[1024]="\0",b[10][128],i=0,j,num[128],cmd[128] = "\0"; + unsigned int filenum = 0,allnum = 0,pathnum = 0; + if(NULL==(fd = popen("echo $PATH","r"))) + { + fprintf(stdout,"execute command failed: "); + return 0; + } + if (NULL == fgets(path,sizeof(path),fd)) + return 0; + fclose(fd); + + printf("date in path is %s\n",path); + pathnum = strlen(path); + path[pathnum-1] = '\0'; + char* token = strtok(path,":"); + while(token != NULL) + { + strcpy(b[i++],token); + token = strtok(NULL,":"); + if( i == 9 ) + break; + } + + for(j=0;jopen file: /etc/nos_monitor_conf.ini error

"); + return 0; + } + // fscanf(fp,"%s %s %s %s",pcip,task_name,cmanager,manprocess); + fgets(pcip, sizeof(pcip), fp); + // while(1) + // { + // printf("\n length of pcip is %d \n",strlen(pcip)); + iplen = strlen(pcip); + pcip[iplen-1]='\0'; + // printf("\n ip get is %s \n",pcip); + // sleep(1); + // } + + fgets(task_name, sizeof(task_name), fp); + tasklen = strlen(task_name); + //printf("\n tasklen get is %d \n",tasklen); + task_name[tasklen-1]='\0'; + // printf("\n task_name get is %s \n",task_name); + + fgets(cmanager, sizeof(cmanager), fp); + cmlen = strlen(cmanager); + // printf("\n cmlen get is %d \n",cmlen); + cmanager[cmlen-1]='\0'; + //printf("\n cmanager get is %s \n",cmanager); + fgets(manprocess, sizeof(manprocess), fp); + manlen = strlen(manprocess); + // printf("\n manlen get is %d \n",manlen); + manprocess[manlen-1] = '\0'; + // printf("\n manprocess get is %s \n",manprocess); + fclose(fp); + pthread_t history_cmd,filecharge,filenumcharge,homenumcharge; + Msgreport mesgreport; + stProcessState processstate; + stFileNum pathreport; + stLogMsg syslogreport,commendlog; + //syslogreport = (stLogMsg*)malloc(sizeof(stLogMsg)+1); + memset(&syslogreport,0, sizeof(stLogMsg)); + void * ctx = zmq_ctx_new(); + fb_assert(ctx, "create zmq context faild"); + + void *sock = zmq_socket(ctx, ZMQ_REQ); + fb_assert(sock, "create zmq socket faild"); + + char szaddr[128] = "\0"; + snprintf(szaddr, sizeof(szaddr), "tcp://%s:%d", ip, port); + + {//加密相关代码 + char szmsg[1024] = {0}; + //此密钥为服务端产生的公钥 + strcpy(szmsg, "p=lDOa9WKUKz!I9{G)uPX4@&CrV-(>tDg:kaSGzE"); + zmq_setsockopt(sock, ZMQ_CURVE_SERVERKEY, szmsg, strlen(szmsg)); + + char szpubkey[64] = {0}; + char szprikey[64] = {0}; + zmq_curve_keypair(szpubkey, szprikey); + zmq_setsockopt(sock, ZMQ_CURVE_PUBLICKEY, szpubkey, strlen(szpubkey)); + zmq_setsockopt(sock, ZMQ_CURVE_SECRETKEY, szprikey, strlen(szprikey)); + } + + zmq_connect(sock, szaddr); + + + int count = 0; + char szmsg[1024] = {0}; + bzero(szmsg, sizeof(szmsg)); + // getchar(); + // sleep(1); + err = pthread_create(&history_cmd, NULL, get_historycmd, (void *)&pcip); + //printf("have come here"); + err1 = pthread_create(&filecharge, NULL, monitorfile, (void *)&pcip); + err2 = pthread_create(&filenumcharge, NULL, monitorfilenum, (void *)&pcip); + + err3 = pthread_create(&homenumcharge, NULL, monitorhomenum, (void *)&pcip); + int memory_have = 0; + CPU_OCCUPY cpu_stst1; + CPU_OCCUPY cpu_stst2; + int cpu; + + while(1) + { + char szmsg[1024] = {0}; + bzero(szmsg, sizeof(szmsg)); + // snprintf(szmsg, sizeof(szmsg), "I say %d", ++count); + // fb_debug("send msg : [%s]", szmsg); + // zmq_send(sock, szmsg, strlen(szmsg), 0); + // zmq_recv(sock, szmsg, sizeof(szmsg) - 1, 0); + // fb_debug("recv msg : [%s]", szmsg); + + get_cpuoccupy((CPU_OCCUPY *)&cpu_stst1); + sleep(1); + get_cpuoccupy((CPU_OCCUPY *)&cpu_stst2); + cpu = cal_cpuoccupy((CPU_OCCUPY *)&cpu_stst1,(CPU_OCCUPY *)&cpu_stst2); + memory_have = 100*get_memoccupy(); + // printf("1cpu usage:%.2f\%\n mem usage:%.2f\%\n",cpu,memory_have); + mesgreport.uiType = 1; + mesgreport.uiCpuRate = 100*cpu; + mesgreport.uiMemRate = memory_have; + stpcpy(mesgreport.szip,pcip); + //printf("2cpu usage:%.2f\%\n mem usage:%.2f\%\n",mesgreport.uiCpuRate,mesgreport.uiMemRate); + //printf("szip is:%s\n",mesgreport.szip); + mesgreport.uiCronNum = uiCronNum(); + tcpnum = processnum_tcp(); + //tcpnum = 10; + + pronum = processnum(); + + mesgreport.uiTcpEstablishNum = tcpnum; + mesgreport.uiRunningProcessNum = pronum; + //printf("tcp and process is :%d and %d\n",tcpnum,pronum); + // judgecommend(); + // judgelogin(); + get_md5passwd(md5passwd); + //printf("test PasswdMd5 is :%s\n",md5passwd); + // strcpy(mesgreport.szPasswdMd5,md5passwd); + + memcpy(mesgreport.szPasswdMd5,md5passwd,strlen(md5passwd)); + //md5group = get_md5group(); + get_md5group(md5group); + memcpy(mesgreport.szGroupMd5,md5group,strlen(md5group)); + gettimeofday(&mesgreport.stRcvTime,NULL); + + zmq_send(sock, &mesgreport, sizeof(mesgreport), 0); + // printf("have send success \n"); + zmq_recv(sock, szmsg, sizeof(szmsg) - 1, ZMQ_DONTWAIT); + // printf("have recv success \n"); + // printf("mestype1 recv is %s\n",szmsg); + // printf("Type1 send ip is %s\n passmd5 is %s\n groupmd5 is %s\n cpurate is %d\n memrate is %d\n\n\n\n",mesgreport.szip,mesgreport.szPasswdMd5,mesgreport.szGroupMd5,mesgreport.uiCpuRate,mesgreport.uiMemRate); + pid = 0 ; + getPidByName(&pid, task_name); + //printf("pid of monitsys is %d",pid); + if (pid > 0) + cpumemstate1 = 1; + else + { + bzero(szmsg, sizeof(szmsg)); + processstate.uiType = 2; + stpcpy(processstate.szIp,pcip); + gettimeofday(&processstate.stRcvTime,NULL); + stpcpy(processstate.uiProcessname,task_name); + processstate.uiProcessState = 0; + zmq_send(sock, &processstate, sizeof(processstate), 0); + zmq_recv(sock, szmsg, sizeof(szmsg) - 1,ZMQ_DONTWAIT); + printf("type 2 send ip is %s\n Type is %d\n processname is %s\n processstate is %d\n\n\n\n",processstate.szIp,processstate.uiType,processstate.uiProcessname,processstate.uiProcessState); + sleep(1); + } + + cmpid = 0; + getPidByName(&cmpid, cmanager); + printf("pid of top is %d\n\n",cmpid); + if (cmpid > 0) + cmstate1 = 1; + else{ + bzero(szmsg, sizeof(szmsg)); + processstate.uiType = 2; + stpcpy(processstate.szIp,pcip); + gettimeofday(&processstate.stRcvTime,NULL); + stpcpy(processstate.uiProcessname,cmanager); + processstate.uiProcessState = 0; + zmq_send(sock, &processstate, sizeof(processstate), 0); + zmq_recv(sock, szmsg, sizeof(szmsg) - 1,ZMQ_DONTWAIT); + // printf("mestype2 recv is %s\n",szmsg); + printf("type 2 send ip is %s\n Type is %d\n processname is %s\n processstate is %d\n\n\n",processstate.szIp,processstate.uiType,processstate.uiProcessname,processstate.uiProcessState); + sleep(1); + } + manpropid = 0; + getPidByName(&manpropid, manprocess); + + if (manpropid > 0) + manpstate1 = 1; + else + { + bzero(szmsg, sizeof(szmsg)); + processstate.uiType = 2; + stpcpy(processstate.szIp,pcip); + gettimeofday(&processstate.stRcvTime,NULL); + stpcpy(processstate.uiProcessname,manprocess); + processstate.uiProcessState = 0; + zmq_send(sock, &processstate, sizeof(processstate),0); + zmq_recv(sock, szmsg, sizeof(szmsg) - 1, ZMQ_DONTWAIT); + + printf("type 2 send ip is %s\n Type is %d\n processname is %s\n processstate is %d\n\n\n",processstate.szIp,processstate.uiType,processstate.uiProcessname,processstate.uiProcessState); + sleep(1); + } + + firestate1 = firewallcharge(); + if (firestate1 == 1) + { + bzero(szmsg, sizeof(szmsg)); + processstate.uiType = 2; + stpcpy(processstate.szIp,pcip); + gettimeofday(&processstate.stRcvTime,NULL); + stpcpy(processstate.uiProcessname,"firewall"); + processstate.uiProcessState = 0; + zmq_send(sock, &processstate, sizeof(processstate), 0); + zmq_recv(sock, szmsg, sizeof(szmsg) - 1,ZMQ_DONTWAIT); + printf("type 2 send ip is %s\n Type is %d\n processname is %s\n processstate is %d\n\n\n",processstate.szIp,processstate.uiType,processstate.uiProcessname,processstate.uiProcessState); + sleep(1); + } + newloginnum = judgeiflogin(); + // printf("newloginnum is %d\n",newloginnum); + if (newloginnum != lastloginnum) + { + bzero(szmsg, sizeof(szmsg)); + syslogreport = judgelogin(pcip); + // printf("log before send struct is %s \n",&commendlog.szMsg[0]); + zmq_send(sock, &syslogreport, sizeof(stLogMsg), 0); + zmq_recv(sock, szmsg, sizeof(szmsg) - 1,ZMQ_DONTWAIT); + // printf("mestype5 recv is %s\n",szmsg); + lastloginnum = newloginnum; + // printf("msg login type is %d\nip is %s\nfilename is %s\n ",syslogreport.uiType,syslogreport.szIp,syslogreport.szLogFile); + // printf("szMsg0 is %s\n",syslogreport.szMsg[0]); + // printf("szMsg1 is %s\n",syslogreport.szMsg[1]); + // printf("szMsg2 is %s\n",syslogreport.szMsg[2]); + // printf("szMsg3 is %s\n",syslogreport.szMsg[3]); + // printf("szMsg4 is %s\n",syslogreport.szMsg[4]); + } + + newpathnum = reportpathnum(); + + if (newpathnum != lastpathnum) + { + bzero(szmsg, sizeof(szmsg)); + pathreport.uiType = 4; + stpcpy(pathreport.szIp,pcip); + stpcpy(pathreport.szPath,"path"); + gettimeofday(&pathreport.stRcvTime,NULL); + pathreport.uiFileNum = newpathnum; + zmq_send(sock, &pathreport, sizeof(pathreport), 0); + zmq_recv(sock, szmsg, sizeof(szmsg) - 1,ZMQ_DONTWAIT); + lastpathnum = newpathnum; + printf("\n\npath receive is %s\n\n",szmsg); + } + } + + zmq_close(sock); + zmq_ctx_term(ctx); + zmq_ctx_destroy(ctx); + + return 0; +} \ No newline at end of file diff --git a/study_clang/Mimic/nos_monitor/monitsys.h b/study_clang/Mimic/nos_monitor/monitsys.h new file mode 100644 index 0000000..278ebbe --- /dev/null +++ b/study_clang/Mimic/nos_monitor/monitsys.h @@ -0,0 +1,111 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define EVENT_NUM 12 +#define BUF_SIZE 1024 +//gcc monitsys.c -lzmq -lpthread -L/usr/local/lib -I/usr/local/include -Wl,-rpath=/usr/local/lib/ -o monitsys +#define fb_debug(fmt, arg...) \ + do{ \ + printf("%s %d : ", __FILE__, __LINE__); \ + printf(fmt, ##arg); \ + printf("\n"); \ + }while(0) + +#define fb_assert(var, info) \ + do{ \ + if(!(var)) { \ + fb_debug(info); \ + } \ + }while(0) + +typedef unsigned int uint; + +char *event_str[EVENT_NUM] = +{ + "IN_ACCESS", + "IN_MODIFY", + "IN_ATTRIB", + "IN_CLOSE_WRITE", + "IN_CLOSE_NOWRITE", + "IN_OPEN", + "IN_MOVED_FROM", + "IN_MOVED_TO", + "IN_CREATE", + "IN_DELETE", + "IN_DELETE_SELF", + "IN_MOVE_SELF" +}; + +int lastnum = 0,lastlognum = 0,newloginnum = 0,lastloginnum = 0; + +typedef struct CPU_PACKED +{ + char name[20]; // + unsigned int user; + unsigned int nice; + unsigned int system; + unsigned int idle; +}CPU_OCCUPY; + +typedef struct +{ + uint uiType; // 1 + char szip[32]; + struct timeval stRcvTime; + uint uiCpuRate; + uint uiMemRate; + uint uiTcpEstablishNum; + uint uiRunningProcessNum; + uint uiCronNum; + char szPasswdMd5[64]; + char szGroupMd5[64]; +}Msgreport; + +typedef struct +{ + uint uiType;//2 + char szIp[32]; + struct timeval stRcvTime; + char uiProcessname[32]; + uint uiProcessState;// 0 mains enable,1 disable +}stProcessState; + +typedef struct +{ + uint uiType; //3 + char szIp[32]; + struct timeval stRcvTime; + char szFileName[32]; //filename modified + //char eventType[16]; //eventType of filename + char szFileMd5[64]; //md5num of file name +}stFileState; + +typedef struct +{ + uint uiType; //4 + char szIp[32]; + struct timeval stRcvTime; + char szPath[32]; //监控路径 + char szFileName[32]; //增加或删除的文件名称 + uint uiFileNum; //当前文件夹下文件数量 +}stFileNum; + + +typedef struct +{ + uint uiType;//5 + char szIp[32]; + struct timeval stRcvTime; + char szLogFile[32]; + char szMsg[5][128]; +}stLogMsg; \ No newline at end of file diff --git a/study_clang/Mimic/nos_monitor/nos_monitor.tar.gz b/study_clang/Mimic/nos_monitor/nos_monitor.tar.gz new file mode 100644 index 0000000..ee88cd8 Binary files /dev/null and b/study_clang/Mimic/nos_monitor/nos_monitor.tar.gz differ diff --git a/study_clang/Mimic/nos_monitor/nos_monitor_conf.ini b/study_clang/Mimic/nos_monitor/nos_monitor_conf.ini new file mode 100644 index 0000000..e1c8e60 --- /dev/null +++ b/study_clang/Mimic/nos_monitor/nos_monitor_conf.ini @@ -0,0 +1,4 @@ +10.10.10.242 +monitsys +top +systemd diff --git a/study_clang/Mimic/piggie/piggie b/study_clang/Mimic/piggie/piggie new file mode 100755 index 0000000..c264081 Binary files /dev/null and b/study_clang/Mimic/piggie/piggie differ diff --git a/study_clang/Mimic/piggie/piggie.c b/study_clang/Mimic/piggie/piggie.c new file mode 100644 index 0000000..22a270d --- /dev/null +++ b/study_clang/Mimic/piggie/piggie.c @@ -0,0 +1,55 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include + +#define STKS (4*4096) + +#ifndef CLONE_NEWPID +#define CLONE_NEWPID 0x20000000 +#endif + +int main(int argc, char **argv) +{ + //int pid; + //void *stk; + int fd, i = 0; + char log_file[] = "/var/log/piggie.log"; + + time_t t; + struct tm *timeinfo; + + //stk = mmap(NULL, STKS, PROT_READ | PROT_WRITE, + //MAP_PRIVATE | MAP_ANON | MAP_GROWSDOWN, 0, 0); + //pid = clone(do_test, stk + STKS, SIGCHLD | CLONE_NEWPID, argv[1]); + //printf("Child forked, pid %d\n", pid); + fd = open("/dev/null", O_RDONLY); + if (fd != 0) { + dup2(fd, 0); + close(fd); + } + if(NULL != argv[1]) + fd = open(argv[1], O_WRONLY | O_TRUNC | O_CREAT, 0600); + else + fd = open(log_file, O_WRONLY | O_TRUNC | O_CREAT, 0600); + + dup2(fd, 1); + dup2(fd, 2); + if (fd != 1 && fd != 2) + close(fd); + + while (1) { + sleep(1); + time(&t); + timeinfo = localtime(&t); + printf("%d %s\n", i++, asctime(timeinfo)); + fflush(stdout); + } + + + return 0; +} \ No newline at end of file diff --git a/study_clang/Mimic/piggie/piggie_thread.c b/study_clang/Mimic/piggie/piggie_thread.c new file mode 100644 index 0000000..b8fd2a4 --- /dev/null +++ b/study_clang/Mimic/piggie/piggie_thread.c @@ -0,0 +1,61 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include + +#define STKS (4*4096) + +#ifndef CLONE_NEWPID +#define CLONE_NEWPID 0x20000000 +#endif + +static int do_test(void *logf) +{ + int fd, i = 0; + time_t t; + struct tm *timeinfo; + setsid(); + + close(0); + close(1); + close(2); + + fd = open("/dev/null", O_RDONLY); + if (fd != 0) { + dup2(fd, 0); + close(fd); + } + + fd = open(logf, O_WRONLY | O_TRUNC | O_CREAT, 0600); + dup2(fd, 1); + dup2(fd, 2); + if (fd != 1 && fd != 2) + close(fd); + + while (1) { + sleep(1); + time(&t); + timeinfo = localtime(&t); + printf("%d %s\n", i++, asctime(timeinfo)); + fflush(stdout); + } + + return 0; +} + +int main(int argc, char **argv) +{ + int pid; + void *stk; + + stk = mmap(NULL, STKS, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON | MAP_GROWSDOWN, 0, 0); + pid = clone(do_test, stk + STKS, SIGCHLD | CLONE_NEWPID, argv[1]); + printf("Child forked, pid %d\n", pid); + + return 0; +} \ No newline at end of file diff --git a/study_clang/Mimic/ssh_proxy/frame_incrypt b/study_clang/Mimic/ssh_proxy/frame_incrypt new file mode 100755 index 0000000..ec7f450 Binary files /dev/null and b/study_clang/Mimic/ssh_proxy/frame_incrypt differ diff --git a/study_clang/Mimic/ssh_proxy/frame_incrypt.cpp b/study_clang/Mimic/ssh_proxy/frame_incrypt.cpp new file mode 100644 index 0000000..9cadf3e --- /dev/null +++ b/study_clang/Mimic/ssh_proxy/frame_incrypt.cpp @@ -0,0 +1,344 @@ +/***************************************************************************** + * @Author : Songsk + * @Date : 2020-07-17 00:02:36 + * @LastEditors : songshuaikang@comleader.com.cn + * @LastEditTime : 2020-07-20 23:17:04 + * @Description : file content + *******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define ACTIVE_NUM_NUM 3 +#define UNSIGNED_INT_LEN 32 +#define MAX_PADDING_SIZE 128 +#define uint unsigned int +#define uchar unsigned char + +#define _ENCRYPT(a,b,c) (a=(b^c)) +#define _DECRYPT _ENCRYPT +#define _CHECKSUM(_checksum, _cipher, _key, _len)\ + {\ + uint _m_i = 0;\ + uint sum = 0;\ + for(_m_i=0; _m_i< _len; _m_i++)\ + sum = sum + (0xffffffff & _cipher[_m_i]) + (0xffffffff & _key[_m_i]);\ + _checksum = 0xff - (0xff & (sum)) - ((sum) >> 8);\ + } +#define ENCRYPT_FUNC(_cipher, _plain, _key, _len)\ +{\ + int _m_i = 0;\ + for(_m_i=0; _m_i< _len; _m_i++)\ + _ENCRYPT(_cipher[_m_i], _plain[_m_i], _key[_m_i]);\ +} + +#define DECRYPT_FUNC(_plain, _cipher, _key, _len)\ +{\ + int _m_i = 0;\ + for(_m_i=0; _m_i< _len; _m_i++)\ + _DECRYPT( _plain[_m_i],_cipher[_m_i], _key[_m_i]);\ +} + +static unsigned int seed = 0; +#define SNAP_LEN 65536 +#define INTERFACE_STR "eth0" + +#define SHD_PRIVATE_PROTOCOL_H 0x09 + +#define HexPrint(_buf, _len) \ +{\ + int _m_i = 0;\ + char *_m_buf = (char *)(_buf);\ + int _m_len = (int)(_len);\ + printf("[%s:%d] \r\n", __FUNCTION__, __LINE__);\ + printf("***************************************************\n");\ + for(_m_i = 0; _m_i < _m_len; _m_i++)\ + {\ + if(_m_i == 0) printf("\033[31m%02x \033[0m",_m_i);\ + printf("\033[32m%02x \033[0m", _m_buf[_m_i] & 0xff);\ + if(!((_m_i+1) % 16)) printf("\n\033[31m%02x \033[0m",_m_i);\ + }\ + printf("\nsize = %d\n***************************************************\n", _m_len);\ +} + +typedef struct frame_head_t +{ + uchar dmac[6]; + uchar smac[6]; + uchar dot1q[4]; + uchar protocol[2]; + uchar padding; + uchar len; +}FRAME_HEAD_T; + +typedef struct msg_to_proxy_t +{ + uchar master_nos = 1; + uchar active_nos[3]; +}MSG_TO_PROXY_T; + +typedef struct timeval TS_TO_PROXY_T; + +typedef enum shd_action_type_e +{ + ACTION_TELL_ACTIVE_NOS =1, + ACTION_SEND_TIMESTAMP, + ACTINON_MAX +}SHD_ACTION; + +typedef enum shd_private_protocol_code_low_e +{ + PROTOCOL_TELL_ACTIVE_NOS = 0x88, + PROTOCOL_SEND_TIMESTAMP, + PROTOCOL_MAX +}SHD_PROTOCOL; + +/** + * @description: 发送数据包,发送的网卡在宏定义中指定 + * @param {pkt:数据包内容,包含包头与payload; len:数据包长度} + * @return: 0:success + */ +int send_packet_with_pcap(const uchar *pkt, uint len) +{ + static pcap_t *handle = NULL; + char dev_str[64]; + char err_buf[PCAP_ERRBUF_SIZE]; + + strcpy(dev_str, INTERFACE_STR); + if(NULL == handle) + { + handle = pcap_open_live(dev_str, SNAP_LEN, 1, 1000, err_buf); + if (handle == NULL) + { + fprintf(stderr, "Couldn't open device %s: %s\n", dev_str, err_buf); + return 0; + } + } + + return pcap_sendpacket(handle, pkt, len); +} + +/** + * @description: 随机函数,原子操作,提供一个字节的随机值 + * @param void + * @return: unsigned char + */ +uchar _random(void) +{ + seed += (unsigned int)time(0) + 781; + srand(seed); + uchar temp = (uchar)(rand()%256); + return temp; +} + +uint fill_with_random(uchar* buf , uint len) +{ + for(int i = 0; i< len; i++) + *(buf+i) =(_random()); + return len; +} + +void print_buffer_hex(const char * text, uchar * buf, uint len) +{ + printf("%s\n", text); + // for(int i = 0; i < len; i++) + // { + // printf("%2X ",buf[i]); + // if(i != 0 && i % 16 == 0) + // printf("\n"); + // } + HexPrint(buf, len); + printf("\n"); +} + +int is_unicast_macaddr(uchar * mac) +{ + if(mac[0] & 1) + return 1; + return 0; +} + +int make_frame_up(const int type, uchar *frame, uchar * ciphertext, uchar * key, uint len, uint frame_len) +{ + //int p = 0; + + /*fill buffer with random value*/ + fill_with_random(frame, frame_len); + + /*create a frame header, include Ehthernet header | vlan header | protocol code */ + FRAME_HEAD_T frame_head; + do + { + printf("."); + fill_with_random(frame_head.smac, sizeof(frame_head.smac)); + } + while (is_unicast_macaddr(frame_head.smac)); + printf("\nfill smac\n"); + do + { + printf("."); + fill_with_random(frame_head.dmac, sizeof(frame_head.dmac)); + } + while (is_unicast_macaddr(frame_head.dmac)); + printf("\nfill dmac\n"); + frame_head.dot1q[0] = 0x81; + frame_head.dot1q[1] = 0x00; + frame_head.dot1q[2] = 0x07; + frame_head.dot1q[3] = 0xd0; + frame_head.protocol[0] = 0x08; + //frame_head.protocol[1] = 0x06; + (ACTION_TELL_ACTIVE_NOS == type) ? frame_head.protocol[1] = PROTOCOL_TELL_ACTIVE_NOS : frame_head.protocol[1] = PROTOCOL_SEND_TIMESTAMP; + + /*get a padding*/ + uchar padding = 0; + while(1) + { + srand(time(NULL)); + int a = sizeof(FRAME_HEAD_T) + len * 2 + 1; + printf("a is %d, frame_len is %d\n", a, frame_len); + padding = (uchar)rand()%(frame_len + - sizeof(FRAME_HEAD_T) + - len * 2 - 1) + + sizeof(FRAME_HEAD_T); + if(padding + len * 2 > frame_len) + continue; + frame_head.padding = padding; + printf("padding is 0x%x\n", padding); + frame_head.len = len; + break; + } + + /*copy frame header and payload into buffer*/ + memcpy(frame, &frame_head, sizeof(frame_head)); + memcpy(frame + padding, ciphertext, len); + memcpy(frame + padding + len, key, len); + char checksum=0; + _CHECKSUM(checksum, ciphertext, key, len); + print_buffer_hex("计算校验和:", (unsigned char *)&checksum,sizeof(checksum)); + memcpy(frame + padding + len + len, &checksum, 1); + /*send packet finally*/ + print_buffer_hex("产生报文:", frame,frame_len); + return send_packet_with_pcap(frame, frame_len); +} + +int shd_send_cmd_to_proxy(MSG_TO_PROXY_T * msg) +{ + int ret = 0; + uchar key[sizeof(MSG_TO_PROXY_T)]; + uchar ciphertext[sizeof(MSG_TO_PROXY_T)]; + + /*get plaintext*/ + uchar plaintext[sizeof(MSG_TO_PROXY_T)]; + memcpy(plaintext, msg, sizeof(MSG_TO_PROXY_T)); + print_buffer_hex("产生明文:", plaintext, sizeof(plaintext)); + + /*create a key with random num*/ + ret = fill_with_random(key, sizeof(key)); + print_buffer_hex("产生掩码:", key, sizeof(key)); + + /*incrypt*/ + ENCRYPT_FUNC(ciphertext, plaintext, key,sizeof(MSG_TO_PROXY_T)); + print_buffer_hex("计算密文:", ciphertext, sizeof(ciphertext)); + /*create and send frame*/ + srand(seed); + uint frame_len = sizeof(FRAME_HEAD_T) //以太网帧头 + + sizeof(MSG_TO_PROXY_T) * 2 //信息量长度 + + 1 + + 10 + + rand()%MAX_PADDING_SIZE; //padding长度 + uchar * frame = (uchar*)malloc(frame_len); + ret = make_frame_up(ACTION_TELL_ACTIVE_NOS ,frame, ciphertext, key, sizeof(key), frame_len); + if(ret) + { + printf("send packet error\n"); + free(frame); + return -1; + } + free(frame); + + return 0; +} + +int shd_send_timestamp_to_nos() +{ + int ret = 0; + uchar key[sizeof(TS_TO_PROXY_T)]; + uchar ciphertext[sizeof(TS_TO_PROXY_T)]; + uchar plaintext[sizeof(TS_TO_PROXY_T)]; + + TS_TO_PROXY_T time; + gettimeofday(&time,NULL); + + memcpy(plaintext, &time, sizeof(TS_TO_PROXY_T)); + print_buffer_hex("产生明文:", plaintext, sizeof(plaintext)); + ret = fill_with_random(key, sizeof(key)); + print_buffer_hex("产生掩码:", key, sizeof(key)); + ENCRYPT_FUNC(ciphertext, plaintext, key,sizeof(TS_TO_PROXY_T)); + print_buffer_hex("计算密文:", ciphertext, sizeof(ciphertext)); + srand(seed); + int a = rand(); + printf("seed is %x, rand is %d, MAX_PADDING_SIZE is %d\n", seed, a, MAX_PADDING_SIZE); + uint frame_len = sizeof(FRAME_HEAD_T) //以太网帧头 + + sizeof(TS_TO_PROXY_T) * 2 //信息量长度 + + 1 + + 10 + + a % MAX_PADDING_SIZE; //padding长度 + printf("frame_len is %u\n", frame_len); + uchar * frame = (uchar*)malloc(frame_len); + if(NULL == frame) + { + printf("malloc error!!\n"); + }else + { + printf("frame addr is %x\n", frame); + } + + ret = make_frame_up(ACTION_SEND_TIMESTAMP,frame, ciphertext, key, sizeof(key), frame_len); + if(ret) + { + printf("send packet error\n"); + free(frame); + return -1; + } + free(frame); + return 0; +} + +int main() +{ + int ret = 0; + while(1) + { + #if 0 + #else + MSG_TO_PROXY_T msg; + msg.master_nos = 1; + msg.active_nos[0] = 1; + msg.active_nos[1] = 2; + msg.active_nos[2] = 3; + + ret = shd_send_cmd_to_proxy(&msg); + if(ret) + { + printf("cmd send error\n"); + return -1; + } + ret = shd_send_timestamp_to_nos(); + if(ret) + { + printf("cmd send error\n"); + return -1; + } + #endif + // usleep(5000); + getchar(); + } + + return 0; +} diff --git a/study_clang/Mimic/ssh_proxy/scapy_test.py b/study_clang/Mimic/ssh_proxy/scapy_test.py new file mode 100755 index 0000000..bc13fa7 --- /dev/null +++ b/study_clang/Mimic/ssh_proxy/scapy_test.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python3 +# -*- coding: UTF-8 -*- +from scapy.all import * + +def pack_callback(packet): + print ("---------------- packet -----------------") + print ( packet.show() ) + print ("-----------------------------------------") + ''' + if packet['Ether'].payload: + print (packet['Ether'].src) + print (packet['Ether'].dst) + print (packet['Ether'].type) + + if packet['ARP'].payload: + print (packet['ARP'].psrc) + print (packet['ARP'].pdst) + print (packet['ARP'].hwsrc) + print (packet['ARP'].hwdst) + ''' + time.sleep(2) + +filterstr="vlan" + +sniff(filter=filterstr,prn=pack_callback, iface='eth0', count=0) diff --git a/study_clang/Mimic/telnet_proxy/Makefile b/study_clang/Mimic/telnet_proxy/Makefile new file mode 100644 index 0000000..7926777 --- /dev/null +++ b/study_clang/Mimic/telnet_proxy/Makefile @@ -0,0 +1,22 @@ +# Batch Single C file MakeFile + +# 指定CPU架构 Architecture -> ARCH +ARCH ?= +CC = $(ARCH)gcc +SUFFIX = .c +CFLAGS += -Wall -g +LD = -lpcap -pthread + +CUR_SOURCE = $(wildcard *$(SUFFIX)) +CUR_TARGETS = $(patsubst %$(SUFFIX), %, $(CUR_SOURCE)) + +all:$(CUR_TARGETS) + +# %:%.c 是一个表示与目标相同 文件的模式变量 +$(CUR_TARGETS):%:%$(SUFFIX) + $(CC) $< $(CFLAGS) -o $@ $(LD) + +# 指定伪目标 +.PHONY:clean all + clean: + -rm -rf $(TARGETS) diff --git a/study_clang/Mimic/telnet_proxy/telnet_proxy_single b/study_clang/Mimic/telnet_proxy/telnet_proxy_single new file mode 100755 index 0000000..5b6925e Binary files /dev/null and b/study_clang/Mimic/telnet_proxy/telnet_proxy_single differ diff --git a/study_clang/Mimic/telnet_proxy/telnet_proxy_single.c b/study_clang/Mimic/telnet_proxy/telnet_proxy_single.c new file mode 100644 index 0000000..31f0120 --- /dev/null +++ b/study_clang/Mimic/telnet_proxy/telnet_proxy_single.c @@ -0,0 +1,194 @@ +/************************************************************************* + > File Name : telnet_proxy.c + > Author : TL Song + > EMail : songtianlun@frytea.com + > Created Time : Thu Feb 18 18:57:20 2021 + ************************************************************************/ +#include +#include +// #include +#include + +#define RECV_SEND_DEVICE "eth1" +#define RETU_DEVICE "linux_dal" +#define RETU_SEND_DEVICE RECV_DEVICE +#define RECV_FILTER "src host 192.168.8.123 and arp or icmp or dst port 23" +#define RETU_FILTER "" +// switch, 1、定义后以多进程模式运行;2、定义后为抓到的包追加vlan标签。 +// #define RUNNING_WITH_MULT_PROGRESS 0 +// #define GREP_WITH_MAKE_VLAN 0 + +#define SNAP_LEN 65536 +#ifndef GREP_WITH_MAKE_VLAN +#define RECV_DEVICE "eth0" +#else +#define RECV_DEVICE "eth0.3000" +#endif + +static char g_vlan_tag[4] = {0x81, 0x00, 0x0B, 0xB8}; +#define dPrint(fmt, ...) do{fprintf(stderr, "[%s:%d] " fmt "\r\n", __FUNCTION__, __LINE__, ##__VA_ARGS__);}while(0) +#define HexPrint(_buf, _len) \ +{\ + int _m_i = 0;\ + char *_m_buf = (char *)(_buf);\ + int _m_len = (int)(_len);\ + printf("[%s:%d] \r\n", __FUNCTION__, __LINE__);\ + printf("*****************************\n");\ + for(_m_i = 0; _m_i < _m_len; _m_i++)\ + {\ + printf("\033[32m%02x \033[0m", _m_buf[_m_i] & 0xff);\ + if(!((_m_i+1) % 10)) printf("\n");\ + }\ + printf("\nsize = %d\n*****************************\n", _m_len);\ +} + + char err_buf[PCAP_ERRBUF_SIZE]; + struct bpf_program fp_recv; /* The compiled filter expression */ + struct bpf_program fp_retu; /* The compiled filter expression */ + char filter_recv[] = RECV_FILTER; /* The filter expression (filter 53 port)*/ + char filter_retu[] = RETU_FILTER; /* The filter expression (filter 53 port)*/ + pcap_t *handle_recv; + pcap_t *handle_retu; + pcap_t *handle_recv_send; + bpf_u_int32 mask_recv; /* The netmask of our sniffing device */ + bpf_u_int32 mask_retu; /* The netmask of our sniffing device */ + bpf_u_int32 net_recv; /* The IP of our sniffing device */ + bpf_u_int32 net_retu; /* The IP of our sniffing device */ + +void recv_dispatcher_handler(u_char *temp1, const struct pcap_pkthdr *header, const u_char *pkt_data) +{ + // HexPrint((const char *)pkt_data, header->caplen); +#ifndef GREP_WITH_MAKE_VLAN + u_char pkt_send[header->caplen]; + memset(pkt_send, 0x00, sizeof(pkt_send)); + memcpy(pkt_send, pkt_data, header->caplen); +#else + u_char pkt_send[header->caplen + sizeof(g_vlan_tag)]; + memset(pkt_send, 0x00, sizeof(pkt_send)); + memcpy(pkt_send, pkt_data, header->caplen); + memcpy(pkt_send+16, pkt_send+12, header->caplen-12); + memcpy(pkt_send+12, g_vlan_tag, sizeof(g_vlan_tag)); +#endif + + // HexPrint((const char *)pkt_send, sizeof(pkt_send)); + dPrint("Send to %s ret : %d", RECV_SEND_DEVICE, pcap_sendpacket(handle_recv_send, pkt_send, sizeof(pkt_send)) ); +} + +void retu_dispatcher_handler(u_char *temp1, const struct pcap_pkthdr *header, const u_char *pkt_data) +{ + // HexPrint((const char *)pkt_data, header->caplen); + u_char pkt_send[header->caplen]; + memset(pkt_send, 0x00, sizeof(pkt_send)); + memcpy(pkt_send, pkt_data, header->caplen); + // HexPrint((const char *)pkt_send, sizeof(pkt_send)); + + dPrint("Send to %s ret : %d", RECV_DEVICE, pcap_sendpacket(handle_recv, pkt_send, sizeof(pkt_send)) ); +} + +// 接收前面板 eth0 发来的消息,转发到 eth1 +void *recv_handl(void *args) +{ + struct pcap_pkthdr *header; + const u_char *pkt_data; + // pcap_loop(handle_recv, -1, recv_dispatcher_handler, NULL); + while(1) + { + if(0 <= pcap_next_ex(handle_recv, &header, &pkt_data)) + dPrint("Send to %s ret : %d", RECV_SEND_DEVICE, pcap_sendpacket(handle_recv_send, pkt_data, header->caplen) ); + } + + dPrint("Capture complete."); +} + +// 接收 linux_dal 发来的流量,转发到 eth0 +void *retu_handl(void *args) +{ + pcap_loop(handle_retu, -1, retu_dispatcher_handler, NULL); + dPrint("Capture complete."); +} + +int main() +{ + pthread_t tid_retu; + + printf("Recv Device: %s\n", RECV_DEVICE); + printf("Retu Device: %s\n", RETU_DEVICE); + printf("Recv Send Device: %s\n", RECV_SEND_DEVICE); + printf("Retu Send Device: %s\n", RETU_SEND_DEVICE); + + /*get network mask*/ + if (pcap_lookupnet(RECV_DEVICE, &net_recv, &mask_recv, err_buf) == -1) { + fprintf(stderr, "Can't get netmask for device %s\n", RECV_DEVICE); + net_recv = 0; + mask_recv = 0; + } + if (pcap_lookupnet(RETU_DEVICE, &net_retu, &mask_retu, err_buf) == -1) { + fprintf(stderr, "Can't get netmask for device %s\n", RETU_DEVICE); + net_retu = 0; + mask_retu = 0; + } + /*Open the session in promiscuous mode*/ + handle_recv = pcap_open_live(RECV_DEVICE, BUFSIZ, 1, 1000, err_buf); + if (handle_recv == NULL) { + fprintf(stderr, "Couldn't open device %s: %s\n", RECV_DEVICE, err_buf); + return; + } + handle_recv_send = pcap_open_live(RECV_SEND_DEVICE, SNAP_LEN, 1, 1000, err_buf); + if (handle_recv_send == NULL) + { + fprintf(stderr, "Couldn't open device %s: %s\n", RECV_SEND_DEVICE, err_buf); + return 0; + } + handle_retu = pcap_open_live(RETU_DEVICE, BUFSIZ, 1, 1000, err_buf); + if (handle_retu == NULL) { + fprintf(stderr, "Couldn't open device %s: %s\n", RETU_DEVICE, err_buf); + return; + } + /* Compile and apply the filter */ + if (pcap_compile(handle_recv, &fp_recv, filter_recv, 0, net_recv) == -1) { + fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_recv, pcap_geterr(handle_recv)); + return; + } + if (pcap_compile(handle_retu, &fp_retu, filter_retu, 0, net_retu) == -1) { + fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_retu, pcap_geterr(handle_retu)); + return; + } + if (pcap_setfilter(handle_recv, &fp_recv) == -1) { + fprintf(stderr, "Couldn't install filter %s: %s\n", filter_recv, pcap_geterr(handle_recv)); + return; + } + if (pcap_setfilter(handle_retu, &fp_retu) == -1) { + fprintf(stderr, "Couldn't install filter %s: %s\n", filter_retu, pcap_geterr(handle_retu)); + return; + } + +#ifndef RUNNING_WITH_MULT_PROGRESS + int ret = pthread_create(&tid_retu, NULL, retu_handl, NULL); + if (ret != 0) { + printf("pthread_create error: error_code = %d\n", ret); + } + recv_handl(NULL); + pthread_exit(NULL); +#else + pid_t fpid=fork(); + if(fpid==0) + { + retu_handl(NULL); + printf("son/n"); + } + else + { + recv_handl(NULL); + printf("father/n"); + } +#endif + + /* cleanup */ + pcap_freecode(&fp_recv); + pcap_close(handle_recv); + pcap_freecode(&fp_retu); + pcap_close(handle_retu); + + dPrint("Capture complete."); + return 0; +} diff --git a/study_clang/Mimic/test_judge/Makefile b/study_clang/Mimic/test_judge/Makefile new file mode 100644 index 0000000..5be74f5 --- /dev/null +++ b/study_clang/Mimic/test_judge/Makefile @@ -0,0 +1,44 @@ + +ARCH ?= +CC = $(ARCH)g++ +STRIP = $(ARCH)strip + +#以下同根目录下的makefile的相同代码的解释 +INC_DIR=./include ../common +DIR_SRC=./src +OBJS_DIR=./obj +LD_DIR= + + +TARGETS=./judge_test + +CUR_SOURCE=$(wildcard ${DIR_SRC}/*.cpp) +CFLAGS += $(foreach dir,$(INC_DIR),-I$(dir)) +CUR_OBJS = $(patsubst $(DIR_SRC)/%.cpp, $(OBJS_DIR)/%.o, $(CUR_SOURCE)) + +CFLAGS += -Wall -std=c++11 -g +LD=-lpthread $$(mysql_config --cflags --libs) -lzmq + +all:$(TARGETS) +$(OBJS_DIR)/%.o : $(DIR_SRC)/%.cpp + @mkdir -p $(OBJS_DIR) + @$(CC) $(CFLAGS) -c $< -o $@ + @echo $(CC) $(CFLAGS) "-c" $(notdir $<) "-o" $(notdir $@) + +$(TARGETS): $(CUR_OBJS) + @$(CC) $(CUR_OBJS) -o $(TARGETS) -L$(LD_DIR) $(LD) +#@$(STRIP) $(TARGETS) + +clean: + @rm -rf $(CUR_OBJS) + @rm -rf $(TARGETS) + @rm -rf $(OBJS_DIR) + +install: + $(INSTALL) $(TARGETS) $(BIN_DIR) + +print: + @echo $(CC) $(CFLAGS) + @echo $(CUR_OBJS) + @echo $(CUR_SOURCE) + diff --git a/study_clang/Mimic/test_judge/include/CConfig.h b/study_clang/Mimic/test_judge/include/CConfig.h new file mode 100644 index 0000000..3d0a19f --- /dev/null +++ b/study_clang/Mimic/test_judge/include/CConfig.h @@ -0,0 +1,132 @@ +/************************************************************************* + > File Name : CConfig.h + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Fri 17 Jul 2020 09:31:50 AM CST + ************************************************************************/ + +#include +#include +#include +#include +#include "CJudgeUtils.h" +#include "CTypedef.h" + +class Config : public CSingleton +{ +public: + Config() {} + virtual ~Config() {} +public: + + void Init(const std::string& file_name) + { + INIReader reader; + reader.Parse(file_name); + + std::string strNosIdx; + for(int i = 0; i < NOS_MAX_NUM; i++) + { + strNosIdx.clear(); + strNosIdx = "nos" + std::to_string((i + 1)) + "_ip"; + nos_ip[i] = reader.Get("judge", strNosIdx, strNosIdx); + } + + #define _GET_JUDGE_CFG(value) value = reader.GetInt32("judge", #value, value) + _GET_JUDGE_CFG(schedule_port); + _GET_JUDGE_CFG(pluginsctrl_port); + _GET_JUDGE_CFG(sub_nos_state_port); + _GET_JUDGE_CFG(nos_num); + _GET_JUDGE_CFG(running_num); + + #undef _GET_JUDGE_CFG + + #define _GET_JUDGE_CFG(value) value = reader.Get("judge", #value, value) + _GET_JUDGE_CFG(config_manager_ip); + _GET_JUDGE_CFG(schedule_ip); + _GET_JUDGE_CFG(pluginsctrl_ip); + + #undef _GET_JUDGE_CFG + + // Judge_sys_info + #define _GET_JUDGE_SYS_INFO_CFG(value) value = reader.GetInt32("judge_sys_info", #value, value) + _GET_JUDGE_SYS_INFO_CFG(nos_report_port); + _GET_JUDGE_SYS_INFO_CFG(msg_time_out); + _GET_JUDGE_SYS_INFO_CFG(cpu_occupy_max); + _GET_JUDGE_SYS_INFO_CFG(mem_occupy_max); + _GET_JUDGE_SYS_INFO_CFG(tcp_socket_max); + _GET_JUDGE_SYS_INFO_CFG(process_max); + _GET_JUDGE_SYS_INFO_CFG(cron_max); + _GET_JUDGE_SYS_INFO_CFG(path_file_max); + _GET_JUDGE_SYS_INFO_CFG(home_file_max); + _GET_JUDGE_SYS_INFO_CFG(process_running_code); + + #undef _GET_JUDGE_SYS_INFO_CFG + + #define _GET_JUDGE_SYS_INFO_CFG(value) value = reader.Get("judge_sys_info", #value, value) + _GET_JUDGE_SYS_INFO_CFG(sys_shell_log_name); + _GET_JUDGE_SYS_INFO_CFG(sys_login_log_name); + _GET_JUDGE_SYS_INFO_CFG(user_md5); + _GET_JUDGE_SYS_INFO_CFG(group_md5); + _GET_JUDGE_SYS_INFO_CFG(config_manager_md5); + _GET_JUDGE_SYS_INFO_CFG(auto_start_md5); + _GET_JUDGE_SYS_INFO_CFG(process_manager_name); + _GET_JUDGE_SYS_INFO_CFG(process_protocol_name); + _GET_JUDGE_SYS_INFO_CFG(process_local_cfgm_name); + _GET_JUDGE_SYS_INFO_CFG(process_firewall_name); + + #undef _GET_JUDGE_SYS_INFO_CFG + + #define _GET_JUDGE_CFG(value) value = reader.GetInt32("trans", #value, value) + _GET_JUDGE_CFG(trans_send_port); + _GET_JUDGE_CFG(trans_recv_port); + + #undef _GET_JUDGE_CFG + + #define _GET_JUDGE_CFG(value) value = reader.Get("trans", #value, value) + _GET_JUDGE_CFG(trans_send_ip); + + #undef _GET_JUDGE_CFG + } + + std::string nos_ip[NOS_MAX_NUM]; + std::string config_manager_ip; + std::string schedule_ip; + std::string pluginsctrl_ip; + + std::string trans_send_ip; + + int sub_nos_state_port; + int schedule_port; + int pluginsctrl_port; + int nos_num; + int running_num; + + // Judge_sys_info + std::string sys_shell_log_name; + std::string sys_login_log_name; + std::string process_manager_name; + std::string process_protocol_name; + std::string process_local_cfgm_name; + std::string process_firewall_name; + + std::string user_md5; + std::string group_md5; + std::string config_manager_md5; + std::string auto_start_md5; + + int nos_report_port; + int msg_time_out; + int cpu_occupy_max; + int mem_occupy_max; + int tcp_socket_max; + int process_max; + int cron_max; + int path_file_max; + int home_file_max; + + int process_running_code; + + int trans_send_port; + int trans_recv_port; +}; diff --git a/study_clang/Mimic/test_judge/include/CJudgeConf.h b/study_clang/Mimic/test_judge/include/CJudgeConf.h new file mode 100644 index 0000000..1e90788 --- /dev/null +++ b/study_clang/Mimic/test_judge/include/CJudgeConf.h @@ -0,0 +1,49 @@ +/************************************************************************* + > File Name : ../include/CJudge.h + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Thu 16 Jul 2020 11:33:38 AM CST + ************************************************************************/ + +#ifndef CJUDGE_H +#define CJUDGE_H + +#include +#include "CTypedef.h" +#include "CJudgeUtils.h" + +typedef std::map > CACHE_MAP; +typedef std::vector MSG_VEC; + +struct MsgGroup +{ + CACHE_MAP cache_map; // 一组执行体消息的对比缓存 + MSG_VEC msg_vec; // 一组执行体消息源 + time_t start_ms; // 一组新消息进入起始时间 + unsigned int uiPort; // 一组消息的端口 +}; + +class JudgeConf : public CSingleton +{ +public: + JudgeConf() { } + virtual ~JudgeConf() { } + +public: + void Init(int _nos_num, int _running_num); + void Judge(); + +private: + std::map group_map; // 按iCmd划分消息组,nos端口相同 + + int nos_num; + int running_num; + + int nos_status; // 各个nos是否running TODO + +private: + int GetCacheNosNum(CACHE_MAP& map); + +}; + +#endif diff --git a/study_clang/Mimic/test_judge/include/CJudgeSysInfo.h b/study_clang/Mimic/test_judge/include/CJudgeSysInfo.h new file mode 100644 index 0000000..79a05c1 --- /dev/null +++ b/study_clang/Mimic/test_judge/include/CJudgeSysInfo.h @@ -0,0 +1,130 @@ +/************************************************************************* + > File Name : CJudgeSysInfo.h + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Fri 17 Jul 2020 09:47:20 AM CST + ************************************************************************/ + +#ifndef CJUDGE_SYS_INFO_H +#define CJUDGE_SYS_INFO_H + + +#include "CTypedef.h" +#include "CJudgeUtils.h" +#include +#include "CZeroMQ.h" + +#define MAX_MSG_BUFFER 1024 // 通信消息缓存区 +#define getbit(x,y) ((x) >> (y)&1) +#define setbit(x,y) x|=(1< SysState_MV; +typedef std::vector SysLog_MV; + +typedef struct +{ + SysState_MV sys_state_mv; + time_t start_ms; +}SysState_Group; + +typedef struct +{ + SysLog_MV sys_log_mv; + time_t start_ms; +}SysLog_Group; +*/ +class CJudgeSysInfo : public CSingleton +{ +public: + CJudgeSysInfo(); + virtual ~CJudgeSysInfo(); +public: + void Init(); + void RcvNosStateMessage(); + void Judge(); + int GetNosRunning(int nos_id); +private: + void JudgeSysState(std::vector& sys_state_v, uint& nos_time_out_bit); + void JudgeProcessState(); + void JudgeFileState(); + void JudgeFileNum(); + void JudgeSysLog(std::vector& SysShellLog_MV, std::vector& SysLoginLog_MV); + + int JudgeCpuOccupy(uint cpu_occupy, uint nos_id); + int JudgeMemOccupy(uint mem_occupy, uint nos_id); + int JudgeTcpSocket(uint tcp_establish_num, uint nos_id); + int JudgeProcessNum(uint running_process, uint nos_id); + void JudgeLoginLog(std::vector& SysLoginLog_CMV); + void JudgeShellLog(std::vector& SysShellLog_CMV); + int JudgeUserInfo(char passwd_md5[64], uint nos_id); + int JudgeGroupInfo(char group_md5[64], uint nos_id); + int JudgeCronNum(uint cron_num, uint nos_id); + void JudgePathFileNum(); + void JudgeHomeFileNum(); + void JudgeAppMd5(); + void JudgeAutoStartMd5(); + void JudgeManagerProgress(); + void JudgeProtocolProgress(); + void JudgeLocalConfigManager(); + void JudgeFirewell(); + + int SendDataToShd(const void *pvData, unsigned int uiDataLen); + int RecvDataFromShd(void *pvBuff, unsigned int uiBuffLen); + + // 消息解析函数 + SysState_T SplitMsgToSysState(char *buffer, int len_Buffer); + ProcessState_T SplitMsgToProcessState(char *buffer, int len_Buffer); + FileState_T SplitMsgToFileState(char *buffer, int len_Buffer); + FileNum_T SplitMsgToFileNum(char *buffer, int len_Buffer); + SysLog_T SplitMsgToSysLog(char *buffer, int len_Buffer); + + uint GetNosId(char ip[32]); + +private: + // 全局标志位 + uint nos_running_bit; + // 配置 + int nos_report_port; + int schedule_port; + int msg_time_out; + int nos_num; + uint running_num; + std::string schedule_ip; + + SysState_T m_SysState; // 系统运行状态消息 + ProcessState_T m_ProcessState; // 关键进程状态消息 + FileState_T m_FileState; // 关键文件状态消息 + FileNum_T m_FileNum; // 关键文件数量消息 + SysLog_T m_SysLog; // 关键日志增量消息 + + // Judge_sys_info + std::string sys_shell_log_name; + std::string sys_login_log_name; + std::string process_manager_name; + std::string process_protocol_name; + std::string process_local_cfgm_name; + std::string process_firewall_name; + + std::string user_md5; + std::string group_md5; + std::string config_manager_md5; + std::string auto_start_md5; + + uint cpu_occupy_max; + uint mem_occupy_max; + uint tcp_socket_max; + uint process_max; + uint cron_max; + uint path_file_max; + uint home_file_max; + + uint process_running_code; + + // ZeroMQ Connect + CZMQReqRep *m_pShdClient; + CZMQReqRep *m_pNosServer; +}; + + +#endif diff --git a/study_clang/Mimic/test_judge/include/CJudgeUtils.h b/study_clang/Mimic/test_judge/include/CJudgeUtils.h new file mode 100644 index 0000000..e254f2d --- /dev/null +++ b/study_clang/Mimic/test_judge/include/CJudgeUtils.h @@ -0,0 +1,140 @@ +/************************************************************************* + > File Name : CJudgeUtils.h + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Fri 17 Jul 2020 09:34:47 AM CST + ************************************************************************/ + +#ifndef _JUDGE_COMMON_H_ +#define _JUDGE_COMMON_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "CLog.h" + +class CNonCopyable +{ +protected: + CNonCopyable() {} + ~CNonCopyable() {} +private: + CNonCopyable(const CNonCopyable &); + const CNonCopyable& operator=(const CNonCopyable &); +}; + +class CMutexLockGuard:CNonCopyable +{ + public: + explicit CMutexLockGuard(pthread_mutex_t& mutex) + : m_mutex(mutex) + { + pthread_mutex_lock(&m_mutex); + } + + ~CMutexLockGuard() + { + pthread_mutex_unlock(&m_mutex); + } + +private: + pthread_mutex_t& m_mutex; +}; + +template +class CSingleton +{ +private: + static std::once_flag SingletonFlag; + static std::unique_ptr Instance; + +protected: + CSingleton() = default; + CSingleton(const T&) = delete; + CSingleton& operator=(const T&) = delete; + +public: + static T& GetInstance() + { + std::call_once(SingletonFlag, [=]() { + Instance.reset(new T); + }); + + return *(Instance.get()); + } +}; + +template std::unique_ptr CSingleton ::Instance = nullptr; +template std::once_flag CSingleton ::SingletonFlag; + +class INIReader +{ +public: + explicit INIReader() {} + ~INIReader() {} + + /// @brief 解析文件 + /// @return 0 成功 + /// @return <0 失败 + /// @note 每次调用会清除上一次的解析结果 + int32_t Parse(const std::string& filename); + + void Clear(); + + /// @brief 获取string类型字段的值,字段未配置时使用默认值 + std::string Get(const std::string& section, const std::string& name, + const std::string& default_value); + + // Get an integer (long) value from INI file, returning default_value + // if not found or not a valid integer (decimal "1234", "-1234", + // or hex "0x4d2"). + int32_t GetInt32(const std::string& section, const std::string& name, + int32_t default_value); + + uint32_t GetUInt32(const std::string& section, const std::string& name, + uint32_t default_value); + + int64_t GetInt64(const std::string& section, const std::string& name, + int64_t default_value); + + uint64_t GetUInt64(const std::string& section, const std::string& name, + uint64_t default_value); + + // Get a real (floating point double) value from INI file, returning + // default_value if not found or not a valid floating point value + // according to strtod(). + double GetReal(const std::string& section, const std::string& name, double default_value); + + // Get a boolean value from INI file, returning default_value + // if not found or if not a valid true/false value. Valid true + // values are "true", "yes", "on", "1", and valid false values are + // "false", "no", "off", "0" (not case sensitive). + bool GetBoolean(const std::string& section, const std::string& name, bool default_value); + + // Returns all the section names from the INI file, in alphabetical order, + // but in the original casing + const std::set& GetSections() const; + + // Returns all the field names from a section in the INI file, in + // alphabetical order, but in the original casing. Returns an + // empty set if the field name is unknown + std::set GetFields(const std::string& section); + + /// @brief 返回最后错误字符串描述 + /// @return 最后一次错误的信息 + const char* GetLastError() const { return m_last_error; } +private: + int32_t ParseFile(FILE* file); +private: + char m_last_error[256]; + std::set m_sections; + std::map > m_fields; +}; + +#endif diff --git a/study_clang/Mimic/test_judge/include/CLog.h b/study_clang/Mimic/test_judge/include/CLog.h new file mode 100644 index 0000000..e8c6c20 --- /dev/null +++ b/study_clang/Mimic/test_judge/include/CLog.h @@ -0,0 +1,93 @@ +/************************************************************************* + > File Name : CLog.h + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Fri 17 Jul 2020 09:33:22 AM CST + ************************************************************************/ + #ifndef CLOG_H + #define CLOG_H + +#include +#include +#include +#include +#include +#include +#include +#include + + +//颜色宏定义 +#define NONE "\033[m" +#define RED "\033[0;32;31m" +#define LIGHT_RED "\033[1;31m" +#define GREEN "\033[0;32;32m" +#define LIGHT_GREEN "\033[1;32m" +#define BLUE "\033[0;32;34m" +#define LIGHT_BLUE "\033[1;34m" +#define DARY_GRAY "\033[1;30m" +#define CYAN "\033[0;36m" +#define LIGHT_CYAN "\033[1;36m" +#define PURPLE "\033[0;35m" +#define LIGHT_PURPLE "\033[1;35m" +#define BROWN "\033[0;33m" +#define YELLOW "\033[1;33m" +#define LIGHT_GRAY "\033[0;37m" +#define WHITE "\033[1;37m" + +#define PRO_NAME "JUDGE" +#define _FUN_ __FUNCTION__ + +typedef enum tagLogLevel +{ + FATAL = 0, + ALERT, + ERROR, + WARN, + NOTICE, + INFO, + DEBUG +} CYBERER_LOG_LEVEL_E; + + +/* + * priorities/facilities are encoded into a single 32-bit quantity, where the + * bottom 3 bits are the priority (0-7) and the top 28 bits are the facility + * (0-big number). Both the priorities and the facilities map roughly + * one-to-one to strings in the syslogd(8) source code. This mapping is + * included in this file. + * + * priorities (these are ordered) + * + * #define LOG_EMERG 0 // system is unusable / + * #define LOG_ALERT 1 // action must be taken immediately / + * #define LOG_CRIT 2 // critical conditions / + * #define LOG_ERR 3 // error conditions / + * #define LOG_WARNING 4 // warning conditions / + * #define LOG_NOTICE 5 // normal but significant condition / + * #define LOG_INFO 6 // informational / + * #define LOG_DEBUG 7 // debug-level messages / +*/ +#define SLOG_EMERG LOG_EMERG /* system is unusable */ +#define SLOG_ALERT LOG_ALERT /* action must be taken immediately */ +#define SLOG_CRIT LOG_CRIT /* critical conditions */ +#define SLOG_ERR LOG_ERR /* error conditions */ +#define SLOG_WARNING LOG_WARNING /* warning conditions */ +#define SLOG_NOTICE LOG_NOTICE /* normal but significant condition */ +#define SLOG_INFO LOG_INFO /* informational */ +#define SLOG_DEBUG LOG_DEBUG /* debug-level messages */ +#define SysLog(_level, fmt, ...) \ + do{openlog("[JUDGE]", LOG_NDELAY | LOG_CONS | LOG_PID | LOG_PERROR , LOG_LOCAL5); \ + syslog(_level, "[%s:%d] " fmt "", __FILE__, __LINE__, ##__VA_ARGS__); \ + closelog();}while(0) + +extern void LogPrint(const int level,const char *proName,const char *func,const int line,const char *format, ...); +extern void BufPrint(const char *func,const int line, const char *pData, int iDataLen); + +#define cPrint(fmt, ...) do{fprintf(stderr, PRO_NAME "[%s:%d] " fmt "\r\n", __FILE__, __LINE__, ##__VA_ARGS__);}while(0) +#define dPrint(fmt, ...) do{fprintf(stderr, YELLOW PRO_NAME "[%s:%d] " fmt "\r\n" NONE, __FILE__, __LINE__, ##__VA_ARGS__);}while(0) +#define lPrint(DLevel, format, ...) LogPrint(DLevel, PRO_NAME, __FILE__, __LINE__,format, ##__VA_ARGS__) +#define bufPrint(pData, iDataLen) BufPrint(__FILE__, __LINE__, (const char *)pData, (int)iDataLen) + +#endif + diff --git a/study_clang/Mimic/test_judge/include/CMain.h b/study_clang/Mimic/test_judge/include/CMain.h new file mode 100644 index 0000000..a1b3d19 --- /dev/null +++ b/study_clang/Mimic/test_judge/include/CMain.h @@ -0,0 +1,42 @@ +/************************************************************************* + > File Name : ../include/CMain.h + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Thu 16 Jul 2020 11:32:23 AM CST + ************************************************************************/ + +#ifndef CMAIN_H +#define CMAIN_H + + #include "CJudgeUtils.h" + +class CMain : public CSingleton +{ +public: + CMain(); + virtual ~CMain(); +public: + + void Init(); + int MainProcess(); + int ReleaseSource(); + +private: + int StartThreadTasks(); + + static void *NosHostConfMsgRcvThread(void *args); + static void *NosKernelConfMsgRcvThread(void *args); + static void *NosStateRcvThread(void *args); + static void *NosSysInfoRcvThread(void *args); + static void *NosSysInfoJudgeThread(void *args); + static void *SendPluginsCtrlThread(void *args); + static void *TransNosHostDataThread(void *args); + static void *TransNosKernelDataThread(void *args); + static void *TransDataToOtherThread(void *args); + +}; + + +#endif + + diff --git a/study_clang/Mimic/test_judge/include/CMessageQueue.h b/study_clang/Mimic/test_judge/include/CMessageQueue.h new file mode 100644 index 0000000..bed5e49 --- /dev/null +++ b/study_clang/Mimic/test_judge/include/CMessageQueue.h @@ -0,0 +1,245 @@ +/************************************************************************* + > File Name : ../include/CMessageQueue.h + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Thu 16 Jul 2020 11:35:11 AM CST + ************************************************************************/ + +#ifndef CMESSAGEQUEUE_H +#define CMESSAGEQUEUE_H +#include "CTypedef.h" +#include "CJudgeUtils.h" + +template +class CMessageQueue : public CSingleton > +{ +public: + CMessageQueue(); + virtual ~CMessageQueue(); +public: + + void push(T stData,Message_QueueType_E MessageType = m_MessageTypeE); + void pop(Message_QueueType_E MessageType = m_MessageTypeE); + T& front(Message_QueueType_E MessageType = m_MessageTypeE); + T& back(Message_QueueType_E MessageType = m_MessageTypeE); + int empty(Message_QueueType_E MessageType = m_MessageTypeE); + uint size(Message_QueueType_E MessageType = m_MessageTypeE); + void remove(T stData, Message_QueueType_E MessageType = m_MessageTypeE); + +private: + + +private: + static const Message_QueueType_E m_MessageTypeE = MQT_CONFIG_E; + + pthread_mutex_t m_QueueMutex; + std::list m_queue; + + pthread_mutex_t ss_QueueMutex; + std::list q_SysState; + + pthread_mutex_t ps_QueueMutex; + std::list q_ProcessState; + + pthread_mutex_t fs_QueueMutex; + std::list q_FileState; + + pthread_mutex_t fn_QueueMutex; + std::list q_FileNum; + + pthread_mutex_t sl_QueueMutex; + std::list q_SysLog; +}; + + +template +CMessageQueue::CMessageQueue() +{ + pthread_mutex_init(&m_QueueMutex, NULL); + + pthread_mutex_init(&ss_QueueMutex, NULL); + pthread_mutex_init(&ps_QueueMutex, NULL); + pthread_mutex_init(&fs_QueueMutex, NULL); + pthread_mutex_init(&fn_QueueMutex, NULL); + pthread_mutex_init(&sl_QueueMutex, NULL); +} + +template +CMessageQueue::~CMessageQueue() +{ + pthread_mutex_destroy(&m_QueueMutex); + + pthread_mutex_destroy(&ss_QueueMutex); + pthread_mutex_destroy(&ps_QueueMutex); + pthread_mutex_destroy(&fs_QueueMutex); + pthread_mutex_destroy(&fn_QueueMutex); + pthread_mutex_destroy(&sl_QueueMutex); +} + +template +void CMessageQueue::push(T stData,Message_QueueType_E MessageType) +{ + switch(MessageType) + { +#define _MQT_PUSH(type, q, lock) \ + case MQT_##type##_E: \ + { \ + CMutexLockGuard MutexLock(lock##_QueueMutex); \ + q.push_back(stData); \ + break;\ + } + _MQT_PUSH(CONFIG, m_queue, m); + _MQT_PUSH(SYS_STATE, q_SysState, ss); + _MQT_PUSH(PROCESS_STATE, q_ProcessState, ps); + _MQT_PUSH(FILE_STATE, q_FileState, fs); + _MQT_PUSH(FILE_NUM, q_FileNum, fn); + _MQT_PUSH(SYS_LOG, q_SysLog, sl); +#undef _MQT_PUSH + default: + break; + } +} + +template +void CMessageQueue::pop(Message_QueueType_E MessageType) +{ + switch(MessageType) + { +#define _MQT_POP(type, q, lock ) \ + case MQT_##type##_E: \ + { \ + CMutexLockGuard MutexLock(lock##_QueueMutex); \ + q.pop_front(); \ + break; \ + } + _MQT_POP(CONFIG, m_queue, m); + _MQT_POP(SYS_STATE, q_SysState, ss); + _MQT_POP(PROCESS_STATE, q_ProcessState, ps); + _MQT_POP(FILE_STATE, q_FileState, fs); + _MQT_POP(FILE_NUM, q_FileNum, fn); + _MQT_POP(SYS_LOG, q_SysLog, sl); +#undef _MQT_POP + default: + break; + } + +} + +template +T& CMessageQueue::front(Message_QueueType_E MessageType) +{ + switch(MessageType) + { +#define _MQT_FRONT(type, q, lock) \ + case MQT_##type##_E: \ + { \ + CMutexLockGuard MutexLock(lock##_QueueMutex); \ + return q.front(); \ + } + _MQT_FRONT(CONFIG, m_queue, m); + _MQT_FRONT(SYS_STATE, q_SysState, ss); + _MQT_FRONT(PROCESS_STATE, q_ProcessState, ps); + _MQT_FRONT(FILE_STATE, q_FileState, fs); + _MQT_FRONT(FILE_NUM, q_FileNum, fn); + _MQT_FRONT(SYS_LOG, q_SysLog, sl); +#undef _MQT_FRONT + default: + return m_queue.front(); + } + +} + +template +T& CMessageQueue::back(Message_QueueType_E MessageType) +{ + switch(MessageType) + { +#define _MQT_BACK(type, q, lock) \ + case MQT_##type##_E: \ + { \ + CMutexLockGuard MutexLock(lock##_QueueMutex); \ + return q.back(); \ + } + _MQT_BACK(CONFIG, m_queue, m); + _MQT_BACK(SYS_STATE, q_SysState, ss); + _MQT_BACK(PROCESS_STATE, q_ProcessState, ps); + _MQT_BACK(FILE_STATE, q_FileState, fs); + _MQT_BACK(FILE_NUM, q_FileNum, fn); + _MQT_BACK(SYS_LOG, q_SysLog, sl); +#undef _MQT_BACK + default: + return m_queue.back(); + } +} + +template +int CMessageQueue::empty(Message_QueueType_E MessageType) +{ + switch(MessageType) + { +#define _MQT_EMPTY(type, q, lock) \ + case MQT_##type##_E: \ + { \ + CMutexLockGuard MutexLock(lock##_QueueMutex); \ + return q.empty(); \ + } + _MQT_EMPTY(CONFIG, m_queue, m); + _MQT_EMPTY(SYS_STATE, q_SysState, ss); + _MQT_EMPTY(PROCESS_STATE, q_ProcessState, ps); + _MQT_EMPTY(FILE_STATE, q_FileState, fs); + _MQT_EMPTY(FILE_NUM, q_FileNum, fn); + _MQT_EMPTY(SYS_LOG, q_SysLog, sl); +#undef _MQT_EMPTY + default: + return 0; + } + return 0; +} + +template +uint CMessageQueue::size(Message_QueueType_E MessageType) +{ + switch(MessageType) + { +#define _MQT_SIZE(type, q, lock) \ + case MQT_##type##_E: \ + { \ + CMutexLockGuard MutexLock(lock##_QueueMutex); \ + return q.size(); \ + } + _MQT_SIZE(CONFIG, m_queue, m); + _MQT_SIZE(SYS_STATE, q_SysState, ss); + _MQT_SIZE(PROCESS_STATE, q_ProcessState, ps); + _MQT_SIZE(FILE_STATE, q_FileState, fs); + _MQT_SIZE(FILE_NUM, q_FileNum, fn); + _MQT_SIZE(SYS_LOG, q_SysLog, sl); +#undef _MQT_SIZE + default: + return 0; + } +} + +template +void CMessageQueue::remove(T stData, Message_QueueType_E MessageType) +{ + switch(MessageType) + { +#define _MQT_REMOVE(type, q, lock) \ + case MQT_##type##_E: \ + { \ + CMutexLockGuard MutexLock(lock##_QueueMutex); \ + return q.remove(stData); \ + } + _MQT_REMOVE(CONFIG, m_queue, m); + _MQT_REMOVE(SYS_STATE, q_SysState, ss); + _MQT_REMOVE(PROCESS_STATE, q_ProcessState, ps); + _MQT_REMOVE(FILE_STATE, q_FileState, fs); + _MQT_REMOVE(FILE_NUM, q_FileNum, fn); + _MQT_REMOVE(SYS_LOG, q_SysLog, sl); +#undef _MQT_REMOVE + default: + break; + } +} +#endif + diff --git a/study_clang/Mimic/test_judge/include/CMysqlPool.h b/study_clang/Mimic/test_judge/include/CMysqlPool.h new file mode 100644 index 0000000..18075a2 --- /dev/null +++ b/study_clang/Mimic/test_judge/include/CMysqlPool.h @@ -0,0 +1,98 @@ +/************************************************************************* + > File Name : CMysqlPool.h + > Author : liuzhao + > EMail : liuzhao@comleader.com.cn + > Created Time : Fri 17 Jul 2020 09:40:09 AM CST + ************************************************************************/ + +#ifndef MYSQLPOOL_H +#define MYSQLPOOL_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "CJudgeUtils.h" + +struct MysqlResults +{ + int field_count; + int record_count; + std::vector> value; + std::vector field_name; + + MysqlResults() : field_count(0), record_count(0) {} + void Print() + { + std::cout << "[field_count:" << field_count << "]" << std::endl; + std::cout << "[record_count:" << record_count << "]" << std::endl; + int i = 0; + std::cout << "[field]" << "\t"; + for (auto v : field_name) + { + std::cout << v << "\t"; + } + std::cout << std::endl; + + for (auto v : value) + { + int j = 0; + std::cout << "[row:" << i << "]" << "\t"; + for (auto x : v) + { + std::cout << x << "\t"; + j++; + } + std::cout << std::endl; + i ++; + } + } +}; + +class MysqlPool : public CSingleton +{ +public: + MysqlPool(); + virtual ~MysqlPool(); + +public: + void executeSql(MysqlResults& results, const char* sql);//sql语句的执行函数 + void setParameter( const char* _mysqlhost, + const char* _mysqluser, + const char* _mysqlpwd, + const char* _databasename, + unsigned int _port = 0, + const char* _socket = NULL, + unsigned long _client_flag = 0, + unsigned int MAX_CONNECT = 50 ); //设置数据库参数 + private: + MYSQL* createOneConnect(); //创建一个新的连接对象 + MYSQL* getOneConnect(); //获取一个连接对象 + void close(MYSQL* conn); //关闭连接对象 + bool isEmpty(); //连接池队列池是否为空 + MYSQL* poolFront(); //连接池队列的队头 + unsigned int poolSize(); //获取连接池的大小 + void poolPop(); //弹出连接池队列的队头 + private: + std::queue mysqlpool; //连接池队列 + const char* _mysqlhost; //mysql主机地址 + const char* _mysqluser; //mysql用户名 + const char* _mysqlpwd; //mysql密码 + const char* _databasename; //要使用的mysql数据库名字 + unsigned int _port; //mysql端口 + const char* _socket; //可以设置成Socket or Pipeline,通常设置为NULL + unsigned long _client_flag; //设置为0 + unsigned int MAX_CONNECT; //同时允许最大连接对象数量 + unsigned int connect_count; //目前连接池的连接对象数量 + static std::mutex objectlock; //对象锁 + static std::mutex poollock; //连接池锁 + static MysqlPool* mysqlpool_object; //类的对象 +}; + +#endif diff --git a/study_clang/Mimic/test_judge/include/CNetManager.h b/study_clang/Mimic/test_judge/include/CNetManager.h new file mode 100644 index 0000000..b7aa233 --- /dev/null +++ b/study_clang/Mimic/test_judge/include/CNetManager.h @@ -0,0 +1,101 @@ +/************************************************************************* + > File Name : CNetManager.h + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Fri 17 Jul 2020 09:31:31 AM CST + ************************************************************************/ + +#ifndef CNETMANAGER_H +#define CNETMANAGER_H + +#include +#include "CTypedef.h" +#include "CUdpServer.h" +#include "CUdpClient.h" +#include "CZeroMQ.h" +#include "CJudgeUtils.h" + +#define PORT_BIND_SET_HOST 10014 +#define PORT_BIND_GET_HOST 10013 +#define PORT_BIND_SET_KERNEL 10012 +#define PORT_BIND_GET_KERNEL 10011 + +#define PORT_SET_HOST 10004 +#define PORT_GET_HOST 10003 +#define PORT_SET_KERNEL 10002 +#define PORT_GET_KERNEL 10001 + +class CNetManager : public CSingleton +{ +public: + CNetManager(); + virtual ~CNetManager(); +public: + int RecvDataToConfManagerHost(void *pvBuff, unsigned int uiBuffLen); + int SendDataToConfManagerHost(const void *pvData, unsigned int uiDataLen); + + int RecvDataToConfManagerKernel(void *pvBuff, unsigned int uiBuffLen); + int SendDataToConfManagerKernel(const void *pvData, unsigned int uiDataLen); + + int SendHostDataToAllNos(const void *pvData, unsigned int uiDataLen); + int SendHostDataToNos(int iNosIdx, const void *pvData, unsigned int uiDataLen); + + int SendKernelDataToAllNos(const void *pvData, unsigned int uiDataLen); + int SendKernelDataToNos(int iNosIdx, const void *pvData, unsigned int uiDataLen); + + int SendDataToShd(const void *pvData, unsigned int uiDataLen); + int RecvDataFromShd(void *pvBuff, unsigned int uiBuffLen); + + int SendDataToPCtl(const void *pvData, unsigned int uiDataLen); + int RecvDataFromPCtl(void *pvBuff, unsigned int uiBuffLen); + + void RecvNosDataHost(); + void RecvNosDataKernel(); + + void RecvNosStateFromShd(); + int GetNosStateById(int iIdx); + + int SetNosNetInfoHost(unsigned int uiIdx, const SOCKADDR_IN_T *pstInfo); + int GetNosNetInfoHost(unsigned int uiIdx, SOCKADDR_IN_T *pstInfo); + + int SetNosNetInfoKernel(unsigned int uiIdx, const SOCKADDR_IN_T *pstInfo); + int GetNosNetInfoKernel(unsigned int uiIdx, SOCKADDR_IN_T *pstInfo); + + void TransNosHostData(); + void TransNosKernelData(); + void TransBroadcastDataToOther(); + + void SendPluginsCtrl(); + +private: + int GetNosIdxBySock(SOCKADDR_IN_T *pstSockAddrIn); + +private: + pthread_mutex_t m_NosNetInfoHostMutex; + pthread_mutex_t m_NosNetInfoKernelMutex; + + SOCKADDR_IN_T m_stNosNetInfoHost[NOS_MAX_NUM]; + SOCKADDR_IN_T m_stNosNetInfoKernel[NOS_MAX_NUM]; + + CUdpClient m_ConfigManagerHost; + CUdpClient m_ConfigManagerKernel; + + CUdpServer m_NosDataHost; + CUdpServer m_NosDataKernel; + + CZMQReqRep *m_pShdClient; + CZMQReqRep *m_pPCtlClient; + CZMQSubscriber *m_pNosStateSub; + + NosState_T m_stNosState[NOS_MAX_NUM]; + + CUdpServer m_NosHostTrans; + CUdpServer m_NosKernelTrans; + + CUdpServer m_BroadcastDataTrans; +}; + + +#endif /*CNETMANAGER_H*/ + + diff --git a/study_clang/Mimic/test_judge/include/CSwitchCommon.h b/study_clang/Mimic/test_judge/include/CSwitchCommon.h new file mode 100644 index 0000000..a42e772 --- /dev/null +++ b/study_clang/Mimic/test_judge/include/CSwitchCommon.h @@ -0,0 +1,192 @@ +/************************************************************************* + > File Name : CSwitchCommon.h + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Thu 23 Jul 2020 09:13:37 AM CST + ************************************************************************/ + +#ifndef CSWITCHCOMMON_H +#define CSWITCHCOMMON_H + +#define MAX_NOS_NUM 8 + +typedef enum Judge_Error_Code_E +{ + JUDGE_ALL_SUCCESS=0, /*接收到所有执行体消息,全部一致*/ + /* + ----+----+----- + | A | B | C | 1、线上执行体为A/B/C + ----+----+----- + | 1 | 1 | 1 | 2、收到A/B/C全部一致的消息 + ----+----+----- + + uiNosIdx = 0; + */ + JUDGE_SUCC_WITH_TWO_STAGE, /*接收到所有执行体消息,有多数一致,但少数也一致*/ + /* + ----+----+---- + | A | B | C 1、线上执行体为A/B/C + ----+----+---- + | 1 | 1 | 2 2、收到的消息中,A/B全部一致 + ----+----+---- + + uiNosIdx = C; + */ + JUDGE_SUCC_WITH_MANY_STAGE, /*接收到所有执行体消息,有多数一致,但有多个少数群体*/ + /* + ----+----+----+----+----- + | A | B | C | D | E 1、线上执行体为A/B/C/D/E + ----+----+----+----+----- + | 1 | 1 | 1 | 2 | 3 2、收到的消息中,A/B/C全部一致,D/E不一致 + ----+----+----+----+----- + + uiNosIdx = D | E; + */ + JUDGE_SUCC_WITH_TIMEOUT, /*未收到所有执行体消息,全部一致*/ + /* + ----+----+----- + | A | B | C | 1、线上执行体为A/B/C + ----+----+----- + | 1 | 1 | | 2、收到A/B全部一致的消息,未收到C的消息 + ----+----+----- + + uiNosIdx = 1 << C; + */ + JUDGE_SUCC_WITH_TIMEOUT_TWO_STAGE, /*未收到所有执行体消息,有多数一致,但少数也一致*/ + /* + ----+----+----+----+----- + | A | B | C | D | E 1、线上执行体为A/B/C/D/E + ----+----+----+----+----- + | 1 | 1 | 1 | 2 | 2、收到的消息中,A/B/C全部一致,收到D的消息,E超时 + ----+----+----+----+----- + + uiNosIdx = D | E; + */ + JUDGE_SUCC_WITH_TIMEOUT_MANY_STAGE, /*未收到所有执行体消息,有多数一致,但有多个少数群体*/ + /* + ----+----+----+----+----+----+----- + | A | B | C | D | E | F | G 1、线上执行体为A/B/C/D/E/F/G + ----+----+----+----+----+----+----- + | 1 | 1 | 1 | 1 | 2 | 3 | 2、收到的消息中,A/B/C全部一致,D/E不一致,G超时 + ----+----+----+----+----+----+----- + + uiNosIdx = E | F | G; + */ + JUDGE_ALL_FAIL_WITH_DIFF, /*收到所有执行体消息,全部不一致*/ + /* + ----+----+----- + | A | B | C | 1、线上执行体为A/B/C + ----+----+----- + | 1 | 2 | 3 | 2、收到A/B/C的消息,但完全不同 + ----+----+----- + + uiNosIdx = A | B | C; + */ + JUDGE_FAIL_WITH_TWO_STAGE, /*收到所有执行体消息,分为数目相同的两个群体*/ + /* + ----+----+----+---- + | A | B | C | D 1、线上执行体为A/B/C/D + ----+----+----+---- + | 1 | 1 | 2 | 2 2、收到A/B/C/D的消息,A/B一致,C/D一致 + ----+----+----+---- + + uiNosIdx = A | B | C | D; + */ + JUDGE_FAIL_WITH_MANY_STAGE, /*收到所有执行体信息,分为多个少数群体*/ + /* + ----+----+----+----+----- + | A | B | C | D | E 1、线上执行体为A/B/C/D/E + ----+----+----+----+----- + | 1 | 1 | 2 | 2 | 3 2、收到的消息中,A/B全部一致,C/D全部一致 + ----+----+----+----+----- + + uiNosIdx = A | B | C | D | E; + */ + JUDGE_FAIL_WITH_TIMEOUT, /*未收到所有执行体消息,达不到裁决条件*/ + /* + ----+----+----- + | A | B | C | 1、线上执行体为A/B/C + ----+----+----- + | 1 | | | 2、收到A/B/C的消息,但完全不同 + ----+----+----- + + uiNosIdx = A; + */ + JUDGE_FAIL_WITH_TIMEOUT_TWO_STAGE, /*未收到所有执行体消息,分为两个少数群体*/ + /* + ----+----+----- + | A | B | C | 1、线上执行体为A/B/C + ----+----+----- + | 1 | 2 | | 2、收到A/B的消息,A/B不同, C超时 + ----+----+----- + + uiNosIdx = A | B | C; + */ + JUDGE_FAIL_WITH_TIMEOUT_MANY_STAGE, /*未收到所有执行体消息,分为多个少数群体*/ + /* + ----+----+----+----+----- + | A | B | C | D | E 1、线上执行体为A/B/C/D/E + ----+----+----+----+----- + | 1 | 1 | 2 | 2 | 2、收到的消息中,A/B全部一致,C/D全部一致,E超时 + ----+----+----+----+----- + + uiNosIdx = A | B | C | D | E; + */ + JUDGE_RET_MAX, + + JUDGE_SYS_RUNNING, /* Nos正常运行 */ + JUDGE_EXCESSIVE_CPU_OCCUPY, /*CPU占用率偏高*/ + JUDGE_EXCESSIVE_MEM_OCCUPY, /*内存占用率偏高*/ + JUDGE_EXCESSIVE_TCP_SOCKET, /*TCP SOCKET连接数过多*/ + JUDGE_EXCESSIVE_PROGRESS, /*进程总数过多*/ + JUDGE_SOMEONE_BROKEN_INTO, /*执行体被登入*/ + JUDGE_EXCEPTION_SHELL, /*执行体运行了异常的shell命令*/ + JUDGE_EXCEPTION_USER, /*执行体系统用户账户信息发生变化*/ + JUDGE_EXCEPTION_GROUP, /*执行体系统用户组信息发生变化*/ + JUDGE_CHANGE_CRON, /*计划任务个数产生变动*/ + JUDGE_CHANGE_FILE_IN_PATH, /*PATH目录下文件个数产生变动*/ + JUDGE_CHANGE_FILE_IN_HOME, /*用户目录下文件个数产生变动*/ + JUDGE_EXCEPTION_APP, /*关键可执行文件被篡改*/ + JUDGE_EXCEPTION_AUTOSTART, /*开机自启文件被篡改*/ + JUDGE_EXCEPTION_MANAGER, /*管理进程被异常停止*/ + JUDGE_EXCEPTION_PROTOCOL, /*协议进程被异常停止*/ + JUDGE_EXCEPTION_LOCAL_CONFIG_MANAGER, /*本地配置管理器被异常停止*/ + JUDGE_EXCEPTION_FIREWALL, /*防火墙被异常关闭*/ + JUDGE_TIME_OUT, /*某执行体状态信息上报超时*/ + + ERROR_CODE_MAX +}Judge_Error_Code_T; + +typedef struct Judge_Error_Msg_S +{ + Judge_Error_Code_T uiErrorCode; //错误代码 +#define NOS1_FLAG 1<<0 +#define NOS2_FLAG 1<<1 +#define NOS3_FLAG 1<<2 +#define NOS4_FLAG 1<<3 +#define NOS5_FLAG 1<<4 +#define NOS6_FLAG 1<<5 +#define NOS7_FLAG 1<<6 +#define NOS8_FLAG 1<<7 +#define NOS9_FLAG 1<<8 +#define NOS10_FLAG 1<<9 + uint uiNosIdx; + char szReserve[32]; +}Judge_Error_Msg_T; + +typedef enum { + HB_JUDGE_E = 1, + HB_SHD_E, + HB_MYSQL_E, + HB_WEB_E, + HB_CFG_MANAGER_E, + HB_MAX_E +}HEARBEAT_E; + +typedef enum { + NOS_STATE_INVALID_E, + NOS_STATE_STOP_E, + NOS_STATE_START_E +}NOS_STATE_E; + +#endif /*CSWITCHCOMMON_H*/ diff --git a/study_clang/Mimic/test_judge/include/CTypedef.h b/study_clang/Mimic/test_judge/include/CTypedef.h new file mode 100644 index 0000000..4744e3b --- /dev/null +++ b/study_clang/Mimic/test_judge/include/CTypedef.h @@ -0,0 +1,124 @@ +/************************************************************************* + > File Name : CTypedef.h + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Fri 17 Jul 2020 09:32:54 AM CST + ************************************************************************/ +#ifndef CTYPEDEF_H +#define CTYPEDEF_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include "CLog.h" +#include "CSwitchCommon.h" + +#ifndef MAX_NOS_NUM +#define NOS_MAX_NUM 8 +#else +#define NOS_MAX_NUM MAX_NOS_NUM +#endif + +#define CONF_FILE_PATH "./judge_conf.ini" + +#define JUDGE_PUBLIC_KEY (const char *)"p=lDOa9WKUKz!I9{G)uPX4@&CrV-(>tDg:kaSGzE" +#define JUDGE_PRIVATE_KEY (const char *)"q0]#)iuwR*H5hz.} File Name : CUdpClient.h + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Fri 17 Jul 2020 09:29:08 AM CST + ************************************************************************/ + +#ifndef CUDPCLIENT_H +#define CUDPCLIENT_H +#include "CTypedef.h" + + +class CUdpClient +{ +public: + CUdpClient(); + CUdpClient(const char *pcHost, unsigned int uiPort); + ~CUdpClient(); + + int CUdpRecvData(void *pcBuff, unsigned int uiBuffLen); + int CUdpSendData(const void *pcData, unsigned int uiDataLen); + int CUdpRecvData(void *pcBuff, unsigned int uiBuffLen, const char *pcHost, unsigned int uiPort); + int CUdpSendData(const void *pcData, unsigned int uiDataLen, const char *pcHost, unsigned int uiPort); + + int CUdpSetSendTimeout(unsigned int uiSeconds = 3); + int CUdpSetRecvTimeout(unsigned int uiSeconds = 3); + int CUdpSetBroadcastOpt(); + +private: + int CUdpSocket(); + int CUdpGetSockaddr(const char * pcHost, unsigned int uiPort, SOCKADDR_IN_T *pstSockaddr); + +private: + int m_iClientSock; + unsigned int m_uiPort; + unsigned char m_ucHost[16]; + SOCKADDR_IN_T m_stServerInfo; +}; + + + + + +#endif /*CUDPCLIENT_H*/ + diff --git a/study_clang/Mimic/test_judge/include/CUdpServer.h b/study_clang/Mimic/test_judge/include/CUdpServer.h new file mode 100644 index 0000000..4e2ddfe --- /dev/null +++ b/study_clang/Mimic/test_judge/include/CUdpServer.h @@ -0,0 +1,32 @@ +/************************************************************************* + > File Name : CUdpServer.h + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Fri 17 Jul 2020 09:29:21 AM CST + ************************************************************************/ +#ifndef CUDPSERVER_H +#define CUDPSERVER_H + +#include "CTypedef.h" + + +class CUdpServer +{ +public: + CUdpServer(); + CUdpServer(unsigned int uiPort); + ~CUdpServer(); + + int CUdpSocket(); + int CUdpSocket(unsigned int uiPort); + int CUdpRecvData(void *pvBuff, unsigned int uiBuffLen, SOCKADDR_IN_T *pstClientInfo); + int CUdpSendData(const void *pvData, unsigned int uiDataLen, SOCKADDR_IN_T stClientInfo); + + +private: + int m_iSerSock; + unsigned int m_uiPort; +}; + +#endif /*CUDPSERVER_H*/ + diff --git a/study_clang/Mimic/test_judge/include/CZeroMQ.h b/study_clang/Mimic/test_judge/include/CZeroMQ.h new file mode 100644 index 0000000..d4cf2cc --- /dev/null +++ b/study_clang/Mimic/test_judge/include/CZeroMQ.h @@ -0,0 +1,64 @@ +/***************************************************************************** + * @Descripttion: + * @Author: FengChao + * @Date: 2020-08-07 16:56:44 + * @LastEditors: LastEditors + * @LastEditTime: 2020-08-07 17:29:41 + *****************************************************************************/ +/************************************************************************* + > File Name : CZeroMQ.h + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Fri 17 Jul 2020 09:30:51 AM CST + ************************************************************************/ + +#ifndef CZEROMQ_H +#define CZEROMQ_H +#include + +class CZMQSubscriber +{ +public: + explicit CZMQSubscriber(const char *pcAddrPort, const char *pcPriKey = NULL, const char *pcPubKey = NULL); + ~CZMQSubscriber(); + + int SetRecvTimeout(unsigned int uiSeconds = 3); + int RecvData(void *pvBuff, unsigned int uiBuffLen); + +private: + int SocketInit(); + +private: + void *m_pvSubCtx; + void *m_pvSubSock; + std::string m_strAddrPort; + std::string m_StrPriKey; + std::string m_StrPubKey; +}; + + +class CZMQReqRep +{ +public: + explicit CZMQReqRep(int iType, const char *pcAddrPort, const char *pcPriKey = NULL, const char *pcPubKey = NULL); + ~CZMQReqRep(); + + int RecvData(void *pvBuff, unsigned int uiBuffLen); + int SendData(const void *pvData, unsigned int uiDataLen); + int SetRecvTimeout(unsigned int uiSeconds = 3); + int SetSendTimeout(unsigned int uiSeconds = 3); + +private: + int SocketInit(); + +private: + int m_iType; + void *m_pvCtx; + void *m_pvSock; + std::string m_strAddrPort; + std::string m_StrPriKey; + std::string m_StrPubKey; +}; + +#endif /*CZEROMQ_H*/ + diff --git a/study_clang/Mimic/test_judge/judge b/study_clang/Mimic/test_judge/judge new file mode 100644 index 0000000..427a227 Binary files /dev/null and b/study_clang/Mimic/test_judge/judge differ diff --git a/study_clang/Mimic/test_judge/judge_conf.ini b/study_clang/Mimic/test_judge/judge_conf.ini new file mode 100644 index 0000000..8bf2a80 --- /dev/null +++ b/study_clang/Mimic/test_judge/judge_conf.ini @@ -0,0 +1,44 @@ +[judge] +schedule_ip=30.30.30.2 +schedule_port=8100 +sub_nos_state_port=8200 + +pluginsctrl_ip=172.18.0.1 +pluginsctrl_port=8301 + +nos1_ip=10.10.10.241 +nos2_ip=10.10.10.242 +nos3_ip=10.10.10.243 +nos4_ip=10.10.10.244 + +config_manager_ip=192.168.0.250 + +running_num=3 +nos_num=3 + +[judge_sys_info] +nos_report_port=7002 +msg_time_out=3000 +sys_shell_log_name=history +sys_login_log_name=wtmp +process_manager_name=manager +process_protocol_name=protocol +process_local_cfgm_name=localcfgmanager +process_firewall=firewall + +cpu_occupy_max=900 +mem_occupy_max=900 +tcp_socket_max=30 +process_max=500 +cron_max=20 +path_file_max=500 +home_file_max=100 +user_md5=155c0f8a0aca2bfa5f2e85a32be41803 +group_md5=62bc68396162fda049d1ba7c7d04eb54 +config_manager_md5=62bc68396162fda049d1ba7c7d04eb54 +auto_start_md5=62bc68396162fda049d1ba7c7d04eb54 + +[trans] +trans_send_ip=192.168.0.250 +trans_send_port=6677 +trans_recv_port=8899 diff --git a/study_clang/Mimic/test_judge/judge_test b/study_clang/Mimic/test_judge/judge_test new file mode 100755 index 0000000..cb9f992 Binary files /dev/null and b/study_clang/Mimic/test_judge/judge_test differ diff --git a/study_clang/Mimic/test_judge/obj/CJudgeConf.o b/study_clang/Mimic/test_judge/obj/CJudgeConf.o new file mode 100644 index 0000000..82333f3 Binary files /dev/null and b/study_clang/Mimic/test_judge/obj/CJudgeConf.o differ diff --git a/study_clang/Mimic/test_judge/obj/CJudgeSysInfo.o b/study_clang/Mimic/test_judge/obj/CJudgeSysInfo.o new file mode 100644 index 0000000..bcc1c9c Binary files /dev/null and b/study_clang/Mimic/test_judge/obj/CJudgeSysInfo.o differ diff --git a/study_clang/Mimic/test_judge/obj/CJudgeUtils.o b/study_clang/Mimic/test_judge/obj/CJudgeUtils.o new file mode 100644 index 0000000..64b23a7 Binary files /dev/null and b/study_clang/Mimic/test_judge/obj/CJudgeUtils.o differ diff --git a/study_clang/Mimic/test_judge/obj/CLog.o b/study_clang/Mimic/test_judge/obj/CLog.o new file mode 100644 index 0000000..2c754c9 Binary files /dev/null and b/study_clang/Mimic/test_judge/obj/CLog.o differ diff --git a/study_clang/Mimic/test_judge/obj/CMain.o b/study_clang/Mimic/test_judge/obj/CMain.o new file mode 100644 index 0000000..0e28643 Binary files /dev/null and b/study_clang/Mimic/test_judge/obj/CMain.o differ diff --git a/study_clang/Mimic/test_judge/obj/CMessageQueue.o b/study_clang/Mimic/test_judge/obj/CMessageQueue.o new file mode 100644 index 0000000..797e0ed Binary files /dev/null and b/study_clang/Mimic/test_judge/obj/CMessageQueue.o differ diff --git a/study_clang/Mimic/test_judge/obj/CMysqlPool.o b/study_clang/Mimic/test_judge/obj/CMysqlPool.o new file mode 100644 index 0000000..02d583b Binary files /dev/null and b/study_clang/Mimic/test_judge/obj/CMysqlPool.o differ diff --git a/study_clang/Mimic/test_judge/obj/CNetManager.o b/study_clang/Mimic/test_judge/obj/CNetManager.o new file mode 100644 index 0000000..ec673c3 Binary files /dev/null and b/study_clang/Mimic/test_judge/obj/CNetManager.o differ diff --git a/study_clang/Mimic/test_judge/obj/CUdpClient.o b/study_clang/Mimic/test_judge/obj/CUdpClient.o new file mode 100644 index 0000000..499ed7f Binary files /dev/null and b/study_clang/Mimic/test_judge/obj/CUdpClient.o differ diff --git a/study_clang/Mimic/test_judge/obj/CUdpServer.o b/study_clang/Mimic/test_judge/obj/CUdpServer.o new file mode 100644 index 0000000..0006b32 Binary files /dev/null and b/study_clang/Mimic/test_judge/obj/CUdpServer.o differ diff --git a/study_clang/Mimic/test_judge/obj/CZeroMQ.o b/study_clang/Mimic/test_judge/obj/CZeroMQ.o new file mode 100644 index 0000000..53d3761 Binary files /dev/null and b/study_clang/Mimic/test_judge/obj/CZeroMQ.o differ diff --git a/study_clang/Mimic/test_judge/obj/main.o b/study_clang/Mimic/test_judge/obj/main.o new file mode 100644 index 0000000..800e2fd Binary files /dev/null and b/study_clang/Mimic/test_judge/obj/main.o differ diff --git a/study_clang/Mimic/test_judge/src/CJudgeConf.cpp b/study_clang/Mimic/test_judge/src/CJudgeConf.cpp new file mode 100644 index 0000000..2afd148 --- /dev/null +++ b/study_clang/Mimic/test_judge/src/CJudgeConf.cpp @@ -0,0 +1,334 @@ +/************************************************************************* + > File Name : CJudge.cpp + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Thu 16 Jul 2020 11:33:21 AM CST + ************************************************************************/ + +#include "CJudgeConf.h" +#include "CMessageQueue.h" +#include "CNetManager.h" +#include "CMysqlPool.h" + +#define MSG_TIMEOUT 3000 + +time_t GetTimeStampMS() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec*1000 + tv.tv_usec/1000; +} + +void JudgeConf::Init(int _nos_num, int _running_num) +{ + nos_num = _nos_num; + running_num = _running_num; + + nos_status = 0; + for (auto i = 0; i < running_num; i++) + { + nos_status |= 1 << i; + } + + group_map.clear(); +} + +int JudgeConf::GetCacheNosNum(CACHE_MAP& map) +{ + int num = 0; + for (auto &v : map) + { + num += v.second.size(); + } + return num; +} + +/* +* 其他线程 nos_status TODO +*/ +void JudgeConf::Judge() +{ + while(true) + { + time_t now_ms = GetTimeStampMS(); + if (CMessageQueue::GetInstance().empty()) + { + for (std::map::iterator it = group_map.begin(); it != group_map.end();) + { + MsgGroup& mg = it->second; + if (now_ms - mg.start_ms >= MSG_TIMEOUT) + { + // TODO 超时逻辑 + Judge_Error_Msg_T ret; + std::string succ_str; + bool succ = false; + + for (auto &v : mg.cache_map) + { + if ((int)v.second.size() >= running_num / 2 + 1) + { + succ = true; + succ_str = v.first; + break; + } + } + + // 裁决成功 str达到半数以上相同; 给ConfManager发消息 + ConfJudgeMsg_ST j2n_msg; + memset(&j2n_msg, 0, sizeof(j2n_msg)); + if (succ) + { + j2n_msg.iCmd = 1; // TODO + + /* + ConfJudgeMsg_ST j2c_msg; + memset(&j2c_msg, 0, sizeof(j2c_msg)); + + j2c_msg.iCmd = it->first; + memcpy(j2c_msg.ucData, succ_str.c_str(), succ_str.size()); + + if (mg.uiPort == PORT_BIND_SET_KERNEL) + { + CNetManager::GetInstance().SendDataToConfManagerKernel(&j2c_msg, sizeof(int) + succ_str.size()); + ConfJudgeMsg_ST c2j_msg; + if (CNetManager::GetInstance().RecvDataToConfManagerKernel(&c2j_msg, sizeof(c2j_msg)) < 0) + { + SysLog(LOG_ERR, "recv confManagerKernel error"); + } + } + else if (mg.uiPort == PORT_BIND_SET_HOST) + { + CNetManager::GetInstance().SendDataToConfManagerHost(&j2c_msg, sizeof(int) + succ_str.size()); + if (CNetManager::GetInstance().RecvDataToConfManagerHost(&j2n_msg, sizeof(j2n_msg)) < 0) + { + SysLog(LOG_ERR, "recv confManagerHost error"); + } + } + else + { + SysLog(LOG_ERR, "[uiPort:%d] error", mg.uiPort); + }*/ + } + + // 给NOS回消息 + CNetManager::GetInstance().SendHostDataToAllNos(&j2n_msg, sizeof(j2n_msg)); + + // 裁决结果给调度 + if (succ) + { + if (mg.cache_map.size() == 1) + { + ret.uiErrorCode = Judge_Error_Code_E::JUDGE_SUCC_WITH_TIMEOUT; + } + else if (mg.cache_map.size() == 2) + { + ret.uiErrorCode = Judge_Error_Code_E::JUDGE_SUCC_WITH_TIMEOUT_TWO_STAGE; + } + else + { + ret.uiErrorCode = Judge_Error_Code_E::JUDGE_SUCC_WITH_TIMEOUT_MANY_STAGE; + } + } + else + { + if (mg.cache_map.size() == 1) + { + ret.uiErrorCode = Judge_Error_Code_E::JUDGE_FAIL_WITH_TIMEOUT; + } + else if (mg.cache_map.size() == 2) + { + ret.uiErrorCode = Judge_Error_Code_E::JUDGE_FAIL_WITH_TIMEOUT_TWO_STAGE; + } + else + { + ret.uiErrorCode = Judge_Error_Code_E::JUDGE_FAIL_WITH_TIMEOUT_MANY_STAGE; + } + } + + ret.uiNosIdx = 0; + for (auto &v : mg.cache_map) + { + if ((int)v.second.size() < running_num / 2 + 1) + { + for (auto x : v.second) + { + ret.uiNosIdx |= 1 << x; + } + } + } + + int send_num = CNetManager::GetInstance().SendDataToShd(&ret, sizeof(ret)); + int recv_num = CNetManager::GetInstance().RecvDataFromShd(&ret, sizeof(ret)); + if (recv_num <= 0) + { + SysLog(LOG_ERR, "recv Shd error send_num:%d recv_num%d", send_num, recv_num); + } + + // 清理消息组缓存 + mg.cache_map.clear(); + mg.msg_vec.clear(); + SysLog(LOG_INFO, "judge [result:%d] [mask:%d] [type:%d] [succ:%d] [succ_str:%s]", + ret.uiErrorCode, ret.uiNosIdx, it->first, succ, succ_str.c_str()); + + char sql[128]; + memset(sql, 0, sizeof(sql)); + sprintf(sql, "insert into judge_info(msg, ret, mask, date) values(\"%s\", %d, %d, now())", + "TimeOut", ret.uiErrorCode, ret.uiNosIdx); + MysqlResults m; + MysqlPool::GetInstance().executeSql(m , sql); + + group_map.erase(it++); + continue; + } + it++; + } + usleep(1000); + continue; + } + else + { + NosConfMsg_ST& msg = CMessageQueue::GetInstance().front(); + msg.uiNosIdx = msg.iCmd; // TODO del + msg.iCmd = 1; // TODO del + /*if (!(nos_status & (1 << (msg.uiNosIdx - 1)))) + { + SysLog(LOG_ERR, "judge get [nosid:%d] [type:%d] [msg:%s] not running", msg.uiNosIdx, msg.iCmd, msg.ucData); + CMessageQueue::GetInstance().pop(); + continue; + }*/ + + std::string str((const char *)msg.ucData, msg.uiDataLen); + + auto it = group_map.find(msg.iCmd); + if (it == group_map.end()) + { + MsgGroup mg; + mg.start_ms = now_ms; + mg.uiPort = msg.uiPort; + mg.cache_map[str].insert(msg.uiNosIdx); + mg.msg_vec.push_back(msg); + group_map.insert(std::make_pair(msg.iCmd, mg)); + } + else + { + MsgGroup& mg = it->second; + mg.cache_map[str].insert(msg.uiNosIdx); + mg.msg_vec.push_back(msg); + + // 一组消息接收完毕, 开始裁决 + if (GetCacheNosNum(mg.cache_map) >= running_num) + { + Judge_Error_Msg_T ret; + bool succ = false; + std::string succ_str; + + for (auto &v : mg.cache_map) + { + if ((int)v.second.size() >= running_num / 2 + 1) + { + succ = true; + succ_str = v.first; + break; + } + } + + // 裁决成功 str达到半数以上相同; 给ConfManager发消息 + ConfJudgeMsg_ST j2n_msg; + memset(&j2n_msg, 0, sizeof(j2n_msg)); + if (succ) + { + j2n_msg.iCmd = 1; // TODO + + /*ConfJudgeMsg_ST j2c_msg; + memset(&j2c_msg, 0, sizeof(j2c_msg)); + + j2c_msg.iCmd = msg.iCmd; + memcpy(j2c_msg.ucData, succ_str.c_str(), succ_str.size()); + + if (mg.uiPort == PORT_BIND_SET_KERNEL) + { + CNetManager::GetInstance().SendDataToConfManagerKernel(&j2c_msg, sizeof(int) + succ_str.size()); + ConfJudgeMsg_ST j2n_msg; + if (CNetManager::GetInstance().RecvDataToConfManagerKernel(&j2n_msg, sizeof(j2n_msg)) < 0) + { + SysLog(LOG_ERR, "recv confManagerKernel error"); + } + } + else if (mg.uiPort == PORT_BIND_SET_HOST) + { + CNetManager::GetInstance().SendDataToConfManagerHost(&j2c_msg, sizeof(int) + succ_str.size()); + if (CNetManager::GetInstance().RecvDataToConfManagerHost(&j2n_msg, sizeof(j2n_msg)) < 0) + { + SysLog(LOG_ERR, "recv confManagerHost error"); + } + } + else + { + SysLog(LOG_ERR, "[uiPort:%d] error", mg.uiPort); + }*/ + } + + // 给NOS回消息 + CNetManager::GetInstance().SendHostDataToAllNos(&j2n_msg, sizeof(j2n_msg)); + + // 裁决结果给调度 + if (succ) + { + if (mg.cache_map.size() == 1) + { + ret.uiErrorCode = Judge_Error_Code_E::JUDGE_ALL_SUCCESS; + } + else if (mg.cache_map.size() == 2) + { + ret.uiErrorCode = Judge_Error_Code_E::JUDGE_SUCC_WITH_TWO_STAGE; + } + else + { + ret.uiErrorCode = Judge_Error_Code_E::JUDGE_SUCC_WITH_MANY_STAGE; + } + } + else + { + ret.uiErrorCode = Judge_Error_Code_E::JUDGE_ALL_FAIL_WITH_DIFF; + } + + ret.uiNosIdx = 0; + for (auto &v : mg.cache_map) + { + if ((int)v.second.size() < running_num / 2 + 1) + { + for (auto x : v.second) + { + ret.uiNosIdx |= 1 << x; + } + } + } + + CNetManager::GetInstance().SendDataToShd(&ret, sizeof(ret)); + if (CNetManager::GetInstance().RecvDataFromShd(&ret, sizeof(ret)) < 0) + { + SysLog(LOG_ERR, "recv Shd error"); + } + + // 清理消息组缓存 + mg.cache_map.clear(); + mg.msg_vec.clear(); + SysLog(LOG_INFO, "judge [result:%d] [mask:%d] [type:%d] [succ:%d] [succ_str:%s]", + ret.uiErrorCode, ret.uiNosIdx, it->first, succ, succ_str.c_str()); + + char sql[128]; + memset(sql, 0, sizeof(sql)); + sprintf(sql, "insert into judge_info(msg, ret, mask, date) values(\"%s\", %d, %d, now())", + "ok", ret.uiErrorCode, ret.uiNosIdx); + MysqlResults m; + MysqlPool::GetInstance().executeSql(m , sql); + + group_map.erase(it); + } + } + + SysLog(LOG_INFO, "judge get [nosid:%d] [type:%d] [msg:%s] ", msg.uiNosIdx, msg.iCmd, msg.ucData); + CMessageQueue::GetInstance().pop(); + } + } +} diff --git a/study_clang/Mimic/test_judge/src/CJudgeSysInfo.cpp b/study_clang/Mimic/test_judge/src/CJudgeSysInfo.cpp new file mode 100644 index 0000000..8ee3e66 --- /dev/null +++ b/study_clang/Mimic/test_judge/src/CJudgeSysInfo.cpp @@ -0,0 +1,623 @@ +/************************************************************************* + > File Name: CJudgeSysInfo.cpp + > Author: SongTL + > Mail: songtianlun@comleader.com.cn + > Created Time: 2020年07月22日 星期三 15时37分13秒 + ************************************************************************/ + +#include "CJudgeSysInfo.h" +#include "CConfig.h" +#include "CMessageQueue.h" +#include + +//#include "CZeroMQ.cpp" + +CJudgeSysInfo::CJudgeSysInfo() +{} + +CJudgeSysInfo::~CJudgeSysInfo() +{} + +void CJudgeSysInfo::Init() +{ + nos_report_port = Config::GetInstance().nos_report_port; + msg_time_out = Config::GetInstance().msg_time_out; + nos_num = Config::GetInstance().nos_num; + running_num = Config::GetInstance().running_num; + schedule_ip = Config::GetInstance().schedule_ip; + schedule_port = Config::GetInstance().schedule_port; + process_running_code = Config::GetInstance().process_running_code; + + sys_shell_log_name = Config::GetInstance().sys_shell_log_name; + sys_login_log_name = Config::GetInstance().sys_login_log_name; + process_manager_name = Config::GetInstance().process_manager_name; + process_protocol_name = Config::GetInstance().process_protocol_name; + process_local_cfgm_name = Config::GetInstance().process_local_cfgm_name; + process_firewall_name = Config::GetInstance().process_firewall_name; + + user_md5 = Config::GetInstance().user_md5; + group_md5 = Config::GetInstance().group_md5; + config_manager_md5 = Config::GetInstance().config_manager_md5; + auto_start_md5 = Config::GetInstance().auto_start_md5; + + cpu_occupy_max = Config::GetInstance().cpu_occupy_max; + mem_occupy_max = Config::GetInstance().mem_occupy_max; + tcp_socket_max = Config::GetInstance().tcp_socket_max; + process_max = Config::GetInstance().process_max; + cron_max = Config::GetInstance().cron_max; + path_file_max = Config::GetInstance().path_file_max; + home_file_max = Config::GetInstance().home_file_max; + + nos_running_bit = 0; + +#define _LOG_INT_CONFIG(type) \ + SysLog(LOG_DEBUG,"Load Config %s: %d", #type, type); + _LOG_INT_CONFIG(nos_report_port); + _LOG_INT_CONFIG(schedule_port); + _LOG_INT_CONFIG(msg_time_out); + _LOG_INT_CONFIG(nos_num); +#undef __LOG_INT_CONFIG + +#define _LOG_UINT_CONFIG(type) \ + SysLog(LOG_DEBUG, "Load Config %s: %d", #type, type); + _LOG_UINT_CONFIG(running_num); + _LOG_UINT_CONFIG(cpu_occupy_max); + _LOG_UINT_CONFIG(mem_occupy_max); + _LOG_UINT_CONFIG(tcp_socket_max); + _LOG_UINT_CONFIG(process_max); + _LOG_UINT_CONFIG(cron_max); + _LOG_UINT_CONFIG(path_file_max); + _LOG_UINT_CONFIG(home_file_max); +#undef __LOG_UINT_CONFIG + +#define _LOG_STRING_CONFIG(type) \ + SysLog(LOG_DEBUG, "Load Config %s: %s",#type ,type.c_str()); + _LOG_STRING_CONFIG(schedule_ip); + _LOG_STRING_CONFIG(sys_shell_log_name); + _LOG_STRING_CONFIG(sys_login_log_name); + _LOG_STRING_CONFIG(user_md5); + _LOG_STRING_CONFIG(group_md5); + _LOG_STRING_CONFIG(config_manager_md5); + _LOG_STRING_CONFIG(auto_start_md5); +#undef __LOG_STRING_CONFIG + + char ZMQAddrPort[16]; + sprintf(ZMQAddrPort, "tcp://*:%d", nos_report_port); + m_pNosServer = new CZMQReqRep(ZMQ_REP, ZMQAddrPort); + SysLog(LOG_DEBUG, "creative zmq communication with nos, port: %d", nos_report_port); + + std::string strShdSvrAddr; + strShdSvrAddr.clear(); + strShdSvrAddr = "tcp://" + schedule_ip + ":" + std::to_string(schedule_port); + m_pShdClient = new CZMQReqRep(ZMQ_REQ, strShdSvrAddr.c_str(), JUDGE_PRIVATE_KEY, JUDGE_PUBLIC_KEY); + SysLog(LOG_DEBUG, "creative zmq communication with schedule, ip %s, port: %d", schedule_ip.c_str(), nos_report_port); + } + + +void CJudgeSysInfo::RcvNosStateMessage() +{ + while(true){ + char buffer[MAX_MSG_BUFFER]; + memset(buffer, 0x00, sizeof(buffer)); + int recvNum = m_pNosServer->RecvData(buffer, MAX_MSG_BUFFER); + if(recvNum <= 0) + { + int err = errno; + SysLog(LOG_ERR, "revc nos error, recvNum%d err:%d", recvNum, err); + //sleep(1); + continue; + } + int sendNum = m_pNosServer->SendData(buffer, sizeof(buffer)); + if (recvNum <= 0) + { + int err = errno; + SysLog(LOG_ERR, "send nos error, sendNum:%d recvNum%d errno=%d", sendNum, recvNum, err); + continue; + } + if(buffer!=NULL) + { + SysLog(LOG_DEBUG, "recv msg from nos, msg type: %d", *(uint *)buffer); + switch(*(uint *)buffer) + { + case 1: + m_SysState = CJudgeSysInfo::SplitMsgToSysState(buffer, sizeof(buffer)); + CMessageQueue::GetInstance().push(m_SysState, MQT_SYS_STATE_E); + SysLog(LOG_DEBUG, "--------------------------------------------------------"); + SysLog(LOG_DEBUG, "szIP : %s", m_SysState.szIp); + SysLog(LOG_DEBUG, "stRcvTime : %ld.%ld", m_SysState.stRcvTime.tv_sec,m_SysState.stRcvTime.tv_usec); + SysLog(LOG_DEBUG, "uiCpuRate : %d", m_SysState.uiCpuRate); + SysLog(LOG_DEBUG, "uiMemRate : %d", m_SysState.uiMemRate); + SysLog(LOG_DEBUG, "uiTcpEstablishNum : %d", m_SysState.uiTcpEstablishNum); + SysLog(LOG_DEBUG, "uiRunningProcessNum : %d", m_SysState.uiRunningProcessNum); + SysLog(LOG_DEBUG, "uiCronNum : %d", m_SysState.uiCronNum); + SysLog(LOG_DEBUG, "szPasswdMd5 : %s", m_SysState.szPasswdMd5); + SysLog(LOG_DEBUG, "szGroupMd5 : %s", m_SysState.szGroupMd5); + SysLog(LOG_DEBUG, "--------------------------------------------------------"); + break; + case 2: + m_ProcessState = CJudgeSysInfo::SplitMsgToProcessState(buffer, sizeof(buffer)); + CMessageQueue::GetInstance().push(m_ProcessState, MQT_PROCESS_STATE_E); + SysLog(LOG_DEBUG, "--------------------------------------------------------"); + SysLog(LOG_DEBUG, "szIP : %s", m_ProcessState.szIp); + SysLog(LOG_DEBUG, "stRcvTime : %ld.%ld", m_ProcessState.stRcvTime.tv_sec,m_ProcessState.stRcvTime.tv_usec); + SysLog(LOG_DEBUG, "szProcessName : %s", m_ProcessState.szProcessName); + SysLog(LOG_DEBUG, "uiProcessState : %d", m_ProcessState.uiProcessState); + SysLog(LOG_DEBUG, "--------------------------------------------------------"); + break; + case 3: + m_FileState = CJudgeSysInfo::SplitMsgToFileState(buffer, sizeof(buffer)); + CMessageQueue::GetInstance().push(m_FileState, MQT_FILE_STATE_E); + break; + case 4: + m_FileNum = CJudgeSysInfo::SplitMsgToFileNum(buffer, sizeof(buffer)); + CMessageQueue::GetInstance().push(m_FileNum, MQT_FILE_NUM_E); + break; + case 5: + m_SysLog = CJudgeSysInfo::SplitMsgToSysLog(buffer, sizeof(buffer)); + CMessageQueue::GetInstance().push(m_SysLog, MQT_SYS_LOG_E); + break; + default: + break; + } + } + else + { + SysLog(LOG_ERR, "recv nos msg error"); + } + } +} + +void CJudgeSysInfo::Judge() +{ + std::vector sys_state_v; + //uint nos_running_bit = 0; + uint nos_not_time_out_bit = 0; + + std::vector sys_shell_log_v; + std::vector sys_login_log_v; + + // Check Message Queue + while(true) + { + // 系统状态裁决在收到所有执行体消息后开始 + if(CMessageQueue::GetInstance().size(MQT_SYS_STATE_E)>=running_num / 2 + 1 ) + { + JudgeSysState(sys_state_v, nos_not_time_out_bit); + } + // 系统日志分情况进行,系统命令日志在收到所有执行体信息后开始,用户登录信息立即开始裁决。 + if(!CMessageQueue::GetInstance().empty(MQT_SYS_LOG_E)) + { + JudgeSysLog(sys_shell_log_v, sys_login_log_v); + } + if(!CMessageQueue::GetInstance().empty(MQT_PROCESS_STATE_E)) + { + JudgeProcessState(); + } + if(!CMessageQueue::GetInstance().empty(MQT_FILE_STATE_E)) + { + JudgeFileState(); + } + if(!CMessageQueue::GetInstance().empty(MQT_FILE_NUM_E)) + { + JudgeFileNum(); + } + //sleep(1); + } +} + +void CJudgeSysInfo::JudgeSysState(std::vector& sys_state_v, uint& nos_not_time_out_bit) +{ + bool second_timeout = false; + uint nos_time_out_bit = 0; + + if(nos_not_time_out_bit!=0) + second_timeout = true; + while(!CMessageQueue::GetInstance().empty(MQT_SYS_STATE_E)) + { + SysState_T sys_state_t = CMessageQueue::GetInstance().front(MQT_SYS_STATE_E); + CMessageQueue::GetInstance().pop(MQT_SYS_STATE_E); + sys_state_v.push_back(sys_state_t); + + nos_not_time_out_bit |= 1<= (running_num / 2 + 1)) + { + for(auto sys_state_it=sys_state_v.begin(); sys_state_it!=sys_state_v.end(); sys_state_it++) + { + int nos_id = GetNosId(sys_state_it->szIp); + if(JudgeCpuOccupy(sys_state_it->uiCpuRate, nos_id)==0) + clrbit(nos_running_bit, nos_id); + if(JudgeMemOccupy(sys_state_it->uiMemRate, nos_id)==0) + clrbit(nos_running_bit, nos_id); + if(JudgeTcpSocket(sys_state_it->uiTcpEstablishNum, nos_id)==0) + clrbit(nos_running_bit, nos_id); + if(JudgeProcessNum(sys_state_it->uiRunningProcessNum, nos_id)==0) + clrbit(nos_running_bit, nos_id); + if(JudgeCronNum(sys_state_it->uiCronNum, nos_id)==0) + clrbit(nos_running_bit, nos_id); + if(JudgeUserInfo(sys_state_it->szPasswdMd5, nos_id)==0) + clrbit(nos_running_bit, nos_id); + if(JudgeGroupInfo(sys_state_it->szGroupMd5, nos_id)==0) + clrbit(nos_running_bit, nos_id); + } + sys_state_v.clear(); + } + // TODO normal report + if(nos_running_bit) + { + for(int i=0;i::GetInstance().empty(MQT_PROCESS_STATE_E)) + { + ProcessState_T tProcessState = CMessageQueue::GetInstance().front(MQT_PROCESS_STATE_E); + CMessageQueue::GetInstance().pop(MQT_PROCESS_STATE_E); + uint nosID = GetNosId(tProcessState.szIp); + if(tProcessState.uiProcessState != process_running_code) + { + Judge_Error_Msg_T eMsg; + if(strcmp(tProcessState.szProcessName,process_manager_name.c_str())==0) + { + eMsg.uiErrorCode = JUDGE_EXCEPTION_MANAGER; + SysLog(LOG_ERR, "Nos %d manager process exception.", nosID); + } + else if(strcmp(tProcessState.szProcessName,process_protocol_name.c_str())==0) + { + eMsg.uiErrorCode = JUDGE_EXCEPTION_PROTOCOL; + SysLog(LOG_ERR, "Nos %d protocol process exception.", nosID); + } + else if(strcmp(tProcessState.szProcessName,process_local_cfgm_name.c_str())==0) + { + eMsg.uiErrorCode = JUDGE_EXCEPTION_LOCAL_CONFIG_MANAGER; + SysLog(LOG_ERR, "Nos %d local-config-manager process exception.", nosID); + } + else if(strcmp(tProcessState.szProcessName,process_firewall_name.c_str())==0) + { + eMsg.uiErrorCode = JUDGE_EXCEPTION_FIREWALL; + SysLog(LOG_ERR, "Nos %d firewall exception.", nosID); + } + else + { + SysLog(LOG_ERR, "Recv a error process report from Nos %d.", nosID); + return; + } + eMsg.uiNosIdx = 1>>nosID; + int sendNum = SendDataToShd(&eMsg, sizeof(eMsg)); + int recvNum = RecvDataFromShd(&eMsg, sizeof(eMsg)); + if (recvNum <= 0) + { + SysLog(LOG_ERR, "recv shd error sendNum:%d recvNum%d", sendNum, recvNum); + } + } + } + //sleep(1); +} + +void CJudgeSysInfo::JudgeFileState() +{ + //sleep(1); +} + +void CJudgeSysInfo::JudgeFileNum() +{ + //sleep(1); +} + +void CJudgeSysInfo::JudgeSysLog(std::vector& SysShellLog_MV, std::vector& SysLoginLog_MV) +{ + while(!CMessageQueue::GetInstance().empty(MQT_SYS_LOG_E)) + { + SysLog_T SysLog_CT = CMessageQueue::GetInstance().front(MQT_SYS_LOG_E); + CMessageQueue::GetInstance().pop(MQT_SYS_LOG_E); + if(strcmp(SysLog_CT.szLogFile,sys_shell_log_name.c_str())==0) + { + SysShellLog_MV.push_back(SysLog_CT); + //SysLog(LOG_DEBUG, "Recv a set of sys shell log from %s",SysLog_CT.szIp); + //SysLog(LOG_DEBUG, "Size of shell log message queue: %d",SysShellLog_MV.size()); + } + else if(strcmp(SysLog_CT.szLogFile,sys_login_log_name.c_str())==0) + { + SysLoginLog_MV.push_back(SysLog_CT); + //SysLog(LOG_DEBUG, "Recv a set of sys login log from %s",SysLog_CT.szIp); + } + else + { + SysLog(LOG_ERR, "recv nos error sys_log: %s", SysLog_CT.szLogFile); + } + } + if(SysShellLog_MV.size()>=running_num) + { + JudgeShellLog(SysShellLog_MV); + SysShellLog_MV.clear(); + } + if(SysLoginLog_MV.size()>0) + { + JudgeLoginLog(SysLoginLog_MV); + SysLoginLog_MV.clear(); + } + //sleep(1); +} + +int CJudgeSysInfo::JudgeCpuOccupy(uint cpu_occupy, uint nos_id) +{ + if(cpu_occupy>cpu_occupy_max) + { + Judge_Error_Msg_T ret; + ret.uiErrorCode = Judge_Error_Code_E::JUDGE_EXCESSIVE_CPU_OCCUPY; + ret.uiNosIdx = nos_id; + SysLog(LOG_ERR, "Nos %d Cpu occupy is too hight! Used:%d", nos_id, cpu_occupy); + int sendNum = SendDataToShd(&ret, sizeof(ret)); + int recvNum = RecvDataFromShd(&ret, sizeof(ret)); + if (recvNum <= 0) + { + SysLog(LOG_ERR, "recv shd error sendNum:%d recvNum%d", sendNum, recvNum); + } + return 0; + } + return 1; +} +int CJudgeSysInfo::JudgeMemOccupy(uint mem_occupy, uint nos_id) +{ + if(mem_occupy>mem_occupy_max) + { + Judge_Error_Msg_T ret; + ret.uiErrorCode = Judge_Error_Code_E::JUDGE_EXCESSIVE_MEM_OCCUPY; + ret.uiNosIdx = nos_id; + SysLog(LOG_ERR, "Nos %d Mem occupy is too hight! Used:%d", nos_id, mem_occupy); + int sendNum = SendDataToShd(&ret, sizeof(ret)); + int recvNum = RecvDataFromShd(&ret, sizeof(ret)); + if (recvNum <= 0) + { + SysLog(LOG_ERR, "recv shd error sendNum:%d recvNum%d", sendNum, recvNum); + } + return 0; + } + return 1; +} +int CJudgeSysInfo::JudgeTcpSocket(uint tcp_establish_num, uint nos_id) +{ + if(tcp_establish_num > tcp_socket_max) + { + Judge_Error_Msg_T ret; + ret.uiErrorCode = Judge_Error_Code_E::JUDGE_EXCESSIVE_TCP_SOCKET; + ret.uiNosIdx = nos_id; + SysLog(LOG_ERR, "Nos %d build too many Tcp socket! Establish num:%d", nos_id, tcp_establish_num); + int sendNum = SendDataToShd(&ret, sizeof(ret)); + int recvNum = RecvDataFromShd(&ret, sizeof(ret)); + if (recvNum <= 0) + { + SysLog(LOG_ERR, "recv shd error sendNum:%d recvNum%d", sendNum, recvNum); + } + return 0; + } + return 1; +} +int CJudgeSysInfo::JudgeProcessNum(uint running_process_num, uint nos_id) +{ + if(running_process_num > process_max) + { + Judge_Error_Msg_T ret; + ret.uiErrorCode = Judge_Error_Code_E::JUDGE_EXCESSIVE_PROGRESS; + ret.uiNosIdx = nos_id; + SysLog(LOG_ERR, "Nos %d is starting too many Process! Process num:%d",nos_id, running_process_num); + int sendNum = SendDataToShd(&ret, sizeof(ret)); + int recvNum = RecvDataFromShd(&ret, sizeof(ret)); + if (recvNum <= 0) + { + SysLog(LOG_ERR, "recv shd error sendNum:%d recvNum%d", sendNum, recvNum); + } + return 0; + } + return 1; +} +int CJudgeSysInfo::JudgeCronNum(uint cron_num, uint nos_id) +{ + if(cron_num != cron_max) + { + Judge_Error_Msg_T ret; + ret.uiErrorCode = Judge_Error_Code_E::JUDGE_CHANGE_CRON; + ret.uiNosIdx = nos_id; + SysLog(LOG_ERR, "The number of Nos %d booting tasks bas been changed to %d, plan num is %d", nos_id, cron_num, cron_max); + int sendNum = SendDataToShd(&ret, sizeof(ret)); + int recvNum = RecvDataFromShd(&ret, sizeof(ret)); + if (recvNum <= 0) + { + SysLog(LOG_ERR, "recv shd error sendNum:%d recvNum%d", sendNum, recvNum); + } + return 0; + } + return 1; +} +int CJudgeSysInfo::JudgeUserInfo(char passwd_md5[64], uint nos_id) +{ + if(strcmp(passwd_md5, user_md5.c_str())!=0) + { + Judge_Error_Msg_T ret; + ret.uiErrorCode = Judge_Error_Code_E::JUDGE_EXCEPTION_USER; + ret.uiNosIdx = nos_id; + SysLog(LOG_ERR, "There has been a change in the nos %d user account, passwd md5 changs to: %s", nos_id, passwd_md5); + int sendNum = SendDataToShd(&ret, sizeof(ret)); + int recvNum = RecvDataFromShd(&ret, sizeof(ret)); + if (recvNum <= 0) + { + SysLog(LOG_ERR, "recv shd error sendNum:%d recvNum%d", sendNum, recvNum); + } + return 0; + } + return 1; +} +int CJudgeSysInfo::JudgeGroupInfo(char cgroup_md5[64], uint nos_id) +{ + if(strcmp(cgroup_md5, group_md5.c_str())!=0) + { + Judge_Error_Msg_T ret; + ret.uiErrorCode = Judge_Error_Code_E::JUDGE_EXCEPTION_GROUP; + ret.uiNosIdx = nos_id; + SysLog(LOG_ERR, "There has been a change in the nos %d user group, group md5 changs to: %s", nos_id, cgroup_md5); + int sendNum = SendDataToShd(&ret, sizeof(ret)); + int recvNum = RecvDataFromShd(&ret, sizeof(ret)); + if (recvNum <= 0) + { + SysLog(LOG_ERR, "recv shd error sendNum:%d recvNum%d", sendNum, recvNum); + } + return 0; + } + return 1; +} + +void CJudgeSysInfo::JudgeLoginLog(std::vector& SysLoginLog_CMV) +{ + // 遍历容器,若消息非空则向调度发送错误警报 + Judge_Error_Msg_T Msg_e; + for(auto SysLoginLog_it=SysLoginLog_CMV.begin(); SysLoginLog_it!=SysLoginLog_CMV.end(); SysLoginLog_it++) + { + Msg_e.uiErrorCode = JUDGE_SOMEONE_BROKEN_INTO; + //Msg_e.uiNosIdx = GetNosId(SysLoginLog_it->szIp); + Msg_e.uiNosIdx = 1 << GetNosId(SysLoginLog_it->szIp); + int sendNum = SendDataToShd(&Msg_e, sizeof(Msg_e)); + int recvNum = RecvDataFromShd(&Msg_e, sizeof(Msg_e)); + if (recvNum <= 0) + { + SysLog(LOG_ERR, "recv shd error sendNum:%d recvNum%d", sendNum, recvNum); + } + + for(auto &it : SysLoginLog_it->szMsg) + SysLog(LOG_ERR, "Warning, someone broke into the nos body, nos ip: %s, log: %s", SysLoginLog_it->szIp, it); + } +} +void CJudgeSysInfo::JudgeShellLog(std::vector& SysShellLog_CMV) +{ + std::map > log_map; + for(auto &SysShellLog_it : SysShellLog_CMV) + { + for(auto &p_count : SysShellLog_it.szMsg) + { + uint nos_id = GetNosId(SysShellLog_it.szIp); + log_map[(std::string)p_count].insert(nos_id); + } + } + for(auto &p_check : log_map) + { + for(auto iter=p_check.second.begin();iter!=p_check.second.end();iter++) + { + + if(p_check.second.size() < running_num / 2 + 1) + SysLog(LOG_ERR, "nos %d run an abnormal command: %s",*iter , p_check.first.c_str()); + else + SysLog(LOG_ERR, "nos %d run an command: %s",*iter , p_check.first.c_str()); + } + } + log_map.clear(); +} + +void CJudgeSysInfo::JudgePathFileNum() +{} +void CJudgeSysInfo::JudgeHomeFileNum() +{} +void CJudgeSysInfo::JudgeAppMd5() +{} +void CJudgeSysInfo::JudgeAutoStartMd5() +{} +void CJudgeSysInfo::JudgeManagerProgress() +{} +void CJudgeSysInfo::JudgeProtocolProgress() +{} +void CJudgeSysInfo::JudgeLocalConfigManager() +{} +void CJudgeSysInfo::JudgeFirewell() +{} + +SysState_T CJudgeSysInfo::SplitMsgToSysState(char *buffer, int lenBuffer) +{ + memcpy(&(m_SysState),buffer,sizeof(m_SysState)); + return m_SysState; +} +ProcessState_T CJudgeSysInfo::SplitMsgToProcessState(char *buffer, int lenBuffer) +{ + memcpy(&(m_ProcessState),buffer,sizeof(m_ProcessState)); + return m_ProcessState; +} +FileState_T CJudgeSysInfo::SplitMsgToFileState(char *buffer, int lenBuffer) +{ + memcpy(&(m_FileState),buffer,sizeof(m_FileState)); + return m_FileState; +} +FileNum_T CJudgeSysInfo::SplitMsgToFileNum(char *buffer, int lenBuffer) +{ + memcpy(&(m_FileNum),buffer,sizeof(m_FileNum)); + return m_FileNum; +} +SysLog_T CJudgeSysInfo::SplitMsgToSysLog(char *buffer, int lenBuffer) +{ + memcpy(&m_SysLog,buffer,sizeof(m_SysLog)); + return m_SysLog; +} + +uint CJudgeSysInfo::GetNosId(char ip[32]) +{ + for(int i=0; iSendData(pvData, uiDataLen); +} + +int CJudgeSysInfo::RecvDataFromShd(void *pvBuff, unsigned int uiBuffLen) +{ + return 1; + //return m_pShdClient->RecvData(pvBuff, uiBuffLen); +} + diff --git a/study_clang/Mimic/test_judge/src/CJudgeUtils.cpp b/study_clang/Mimic/test_judge/src/CJudgeUtils.cpp new file mode 100644 index 0000000..cee7bde --- /dev/null +++ b/study_clang/Mimic/test_judge/src/CJudgeUtils.cpp @@ -0,0 +1,273 @@ +#include +#include +#include +#include +#include +#include + +#include "CJudgeUtils.h" + +std::string& Ltrim(std::string& str) +{ + // NOLINT + std::string::iterator it = find_if(str.begin(), str.end(), std::not1(std::ptr_fun(::isspace))); + str.erase(str.begin(), it); + return str; +} + +std::string& Rtrim(std::string& str) +{ + // NOLINT + std::string::reverse_iterator it = find_if(str.rbegin(), + str.rend(), std::not1(std::ptr_fun(::isspace))); + + str.erase(it.base(), str.end()); + return str; +} + +std::string& Trim(std::string& str) +{ + // NOLINT + return Rtrim(Ltrim(str)); +} + +int INIReader::Parse(const std::string& filename) +{ + FILE* file = fopen(filename.c_str(), "r"); + if (NULL == file) + { + //_LOG_LAST_ERROR("open %s failed(%d:%s)", filename.c_str(), errno, strerror(errno)); + return -1; + } + + Clear(); + + int32_t ret = ParseFile(file); + + fclose(file); + + return ret; +} + +void INIReader::Clear() +{ + m_sections.clear(); + m_fields.clear(); +} + +int32_t INIReader::ParseFile(FILE* file) +{ + static const int32_t MAX_BUFF_LEN = 2048; + char buff[MAX_BUFF_LEN] = {0}; + + int32_t line_no = 0; + std::string key, value, line; + std::string utf8bom; + utf8bom.push_back(0xEF); + utf8bom.push_back(0xBB); + utf8bom.push_back(0xBF); + std::map* fields_map = NULL; + while (fgets(buff, MAX_BUFF_LEN, file) != NULL) + { + line_no++; + line = buff; + + // 0. 支持UTF-8 BOM + if (1 == line_no && line.find_first_of(utf8bom) == 0) + { + line.erase(0, 3); + } + + // 1. 去掉注释 + for (size_t i = 0; i < line.length(); ++i) + { + if (';' == line[i] || '#' == line[i]) + { + line.erase(i); + break; + } + } + + // 2. 去掉首尾空格 + Trim(line); + // 3. 去掉空行 + if (line.empty()) + { + continue; + } + + // section + if (line[0] == '[' && line[line.length() - 1] == ']') + { + std::string section(line.substr(1, line.length() - 2)); + Trim(section); + if (section.empty()) + { + return line_no; + } + m_sections.insert(section); + fields_map = &(m_fields[section]); + key.clear(); + continue; + } + + if (NULL == fields_map) + { + key.clear(); + continue; + } + + // fileds + size_t pos = line.find('='); + if (std::string::npos == pos) + { + if (!key.empty()) + { + if ((*fields_map).find(key) == fields_map->end()) + { + (*fields_map)[key] = line; + } + else + { + (*fields_map)[key] += line; + } + } + continue; + } + + key = line.substr(0, pos); + value = line.substr(pos + 1); + Trim(key); + Trim(value); + if (key.empty() || value.empty()) + { + continue; + } + + (*fields_map)[key] = value; + } + + return 0; +} + +std::string INIReader::Get(const std::string& section, const std::string& name, + const std::string& default_value) +{ + + std::map >::iterator it = m_fields.find(section); + if (m_fields.end() == it) + { + return default_value; + } + + std::map& fields_map = it->second; + std::map::iterator cit = fields_map.find(name); + if (fields_map.end() == cit) + { + return default_value; + } + + return cit->second; +} + +int32_t INIReader::GetInt32(const std::string& section, const std::string& name, int32_t default_value) +{ + std::string value = Get(section, name, ""); + + const char* begin = value.c_str(); + char* end = NULL; + + int32_t n = strtol(begin, &end, 0); + return end > begin ? n : default_value; +} + +uint32_t INIReader::GetUInt32(const std::string& section, const std::string& name, uint32_t default_value) +{ + std::string value = Get(section, name, ""); + const char* begin = value.c_str(); + char* end = NULL; + + int32_t n = strtol(begin, &end, 0); + if (end > begin && n >= 0) + { + return n; + } + return default_value; +} + +int64_t INIReader::GetInt64(const std::string& section, const std::string& name, int64_t default_value) +{ + std::string value = Get(section, name, ""); + const char* begin = value.c_str(); + char* end = NULL; + + int64_t n = strtoll(begin, &end, 0); + return end > begin ? n : default_value; +} + +uint64_t INIReader::GetUInt64(const std::string& section, const std::string& name, uint64_t default_value) +{ + std::string value = Get(section, name, ""); + const char* begin = value.c_str(); + char* end = NULL; + + int64_t n = strtoll(begin, &end, 0); + if (end > begin && n >= 0) + { + return n; + } + return default_value; +} + +double INIReader::GetReal(const std::string& section, const std::string& name, double default_value) +{ + std::string value = Get(section, name, ""); + const char* begin = value.c_str(); + char* end = NULL; + double n = strtod(begin, &end); + return end > begin ? n : default_value; +} + +bool INIReader::GetBoolean(const std::string& section, const std::string& name, bool default_value) +{ + std::string value = Get(section, name, ""); + + std::transform(value.begin(), value.end(), value.begin(), ::tolower); + if (value == "true" || value == "yes" || value == "on" || value == "1") + { + return true; + } + else if (value == "false" || value == "no" || value == "off" || value == "0") + { + return false; + } + else + { + return default_value; + } +} + +const std::set& INIReader::GetSections() const +{ + return m_sections; +} + +std::set INIReader::GetFields(const std::string& section) +{ + std::set fields; + + std::map >::iterator it = m_fields.find(section); + if (m_fields.end() == it) + { + return fields; + } + + std::map& fields_map = it->second; + std::map::iterator cit = fields_map.begin(); + for (; cit != fields_map.end(); ++cit) + { + fields.insert(cit->first); + } + + return fields; +} diff --git a/study_clang/Mimic/test_judge/src/CLog.cpp b/study_clang/Mimic/test_judge/src/CLog.cpp new file mode 100644 index 0000000..8f3e79d --- /dev/null +++ b/study_clang/Mimic/test_judge/src/CLog.cpp @@ -0,0 +1,135 @@ +/************************************************************************* + > File Name : CLog.cpp + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Fri 17 Jul 2020 05:36:24 PM CST + ************************************************************************/ + +#include "CLog.h" + +#define DEBUG_LOG //lPrint()打印开关 + +// 打印信息级别 +char *PutOutLevel[] = +{ + (char *)"[FATEL ]", + (char *)"[ALERT ]", + (char *)"[ERROR ]", + (char *)"[ WARN ]", + (char *)"[NOTICE]", + (char *)"[ INFO ]", + (char *)"[DEBUG ]" +}; + +// 打印信息颜色 +char *PutOutColor[] = +{ + (char *)LIGHT_RED, //FATEL + (char *)PURPLE, // ALERT + (char *)RED, // ERROR + (char *)YELLOW, // WARM + (char *)BLUE, // NOTICE + (char *)CYAN, // INFO + (char *)GREEN // DEBUG +}; +/***************************************************************************** + Prototype : GetTimeString + Description : 获取格式化收后的时间字符串 + Input : char *pTimeBuf + int s32Len + Output : None + Return Value : char + + History : + 1.Date : 20181011 + Author : FengChao + Modification : Created function + +*****************************************************************************/ +char *GetTimeString(char *pTimeBuf, int s32Len) +{ + char timeBuf[32] = {0}; + time_t nowTime = 0; + struct tm *pTm = NULL; + + if (s32Len < (int)sizeof(timeBuf)) + { + return NULL; + } + + nowTime = time((time_t *)NULL); + pTm = localtime(&nowTime); + if (strftime(timeBuf, sizeof(timeBuf), "%D %H:%M:%S", pTm) == 0) + { + return NULL; + } + + if(pTimeBuf != NULL) + { + memcpy(pTimeBuf, timeBuf, sizeof(timeBuf)); + } + else + { + return NULL; + } + + return pTimeBuf; +} + + +/***************************************************************************** + Prototype : + Description : + Input : None + Output : None + Return Value : int + + History : + 1.Date : 20181011 + Author : FengChao + Modification : Created function + +*****************************************************************************/ +void LogPrint(const int level,const char *proName,const char *func,const int line,const char *format, ...) +{ + #ifdef DEBUG_LOG + va_list args; + + if ((level > DEBUG) || (level < FATAL)) + { + printf("Gole Printf Input Err Level %d\n", level); + return; + } + + char timeBuf[32] = {0}; + + va_start(args, format); + printf("%s%s:%-8s: %s %s [%d]: ",PutOutColor[level],\ + GetTimeString(timeBuf,sizeof(timeBuf)),\ + PutOutLevel[level],\ + proName,func,line); + + vprintf(format, args); + printf("\r\n" NONE); + + va_end(args); + #endif +} + +void BufPrint(const char *func,const int line, const char *pData, int iDataLen) +{ + int i = 0; + + printf("[%s:%d] :\n", func, line); + printf("*****************************\n" GREEN); + for(i = 0; i < iDataLen; i++) + { + printf("%02x ", pData[i] & 0xFF); + if(!((i+1) % 10)) printf("\n"); + } + + printf("\nsize = %d\n", iDataLen); + printf(NONE "*****************************\r\n"); +} + + diff --git a/study_clang/Mimic/test_judge/src/CMain.cpp b/study_clang/Mimic/test_judge/src/CMain.cpp new file mode 100644 index 0000000..1eab886 --- /dev/null +++ b/study_clang/Mimic/test_judge/src/CMain.cpp @@ -0,0 +1,154 @@ +/************************************************************************* + > File Name : CMain.cpp + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Thu 16 Jul 2020 11:31:56 AM CST + ************************************************************************/ + +#include +#include "CMain.h" +#include "CConfig.h" +#include "CJudgeConf.h" +#include "CNetManager.h" +#include "CJudgeSysInfo.h" +#include "CMysqlPool.h" + +using namespace std; + +CMain::CMain() +{ + + +} + +CMain::~CMain() +{ + +} + +void CMain::Init() +{ + Config::GetInstance().Init(CONF_FILE_PATH); + JudgeConf::GetInstance().Init(Config::GetInstance().nos_num, Config::GetInstance().running_num); + CJudgeSysInfo::GetInstance().Init(); + + MysqlPool::GetInstance().setParameter("172.18.0.4","root","root","mimicswdb",3306,NULL,0,2); + MysqlResults m; + MysqlPool::GetInstance().executeSql(m ,"CREATE TABLE IF NOT EXISTS `judge_info`( \ + `id` INT UNSIGNED AUTO_INCREMENT, \ + `msg` VARCHAR(100) NOT NULL, \ + `ret` INT UNSIGNED, \ + `mask` INT UNSIGNED, \ + `date` DATETIME, \ + PRIMARY KEY (id) \ + ) ENGINE=InnoDB DEFAULT CHARSET=utf8;"); + + StartThreadTasks(); +} + +int CMain::MainProcess() +{ + //Judge process + while(1) + { + JudgeConf::GetInstance().Judge(); + } + + return 0; +} + +int CMain::ReleaseSource() +{ + //release source + return 0; +} + +int CMain::StartThreadTasks() +{ + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); //设置线程可分离 + + pthread_t tNosHostConfMsgRcvThread; + pthread_create(&tNosHostConfMsgRcvThread, &attr, NosHostConfMsgRcvThread, NULL); + + pthread_t tNosKernelConfMsgRcvThread; + pthread_create(&tNosKernelConfMsgRcvThread, &attr, NosKernelConfMsgRcvThread, NULL); + + pthread_t tNosStateRcvThread; + pthread_create(&tNosStateRcvThread, &attr, NosStateRcvThread, NULL); + + pthread_t tSysInfoRcvThread; + pthread_create(&tSysInfoRcvThread, &attr, NosSysInfoRcvThread, NULL); + + pthread_t tSysInfoJudgeThread; + pthread_create(&tSysInfoJudgeThread, &attr, NosSysInfoJudgeThread, NULL); + + pthread_t tSendPluginsCtrlThread; + pthread_create(&tSendPluginsCtrlThread, &attr, SendPluginsCtrlThread, NULL); + + pthread_t tTransNosHostDataThread; + pthread_create(&tTransNosHostDataThread, &attr, TransNosHostDataThread, NULL); + + pthread_t tTransNosKernelDataThread; + pthread_create(&tTransNosKernelDataThread, &attr, TransNosKernelDataThread, NULL); + + pthread_t tTransDataToOtherThread; + pthread_create(&tTransDataToOtherThread, &attr, TransDataToOtherThread, NULL); + + return 0; +} + +void *CMain::NosHostConfMsgRcvThread(void *args) +{ + CNetManager::GetInstance().RecvNosDataHost(); + return NULL; +} + +void *CMain::NosKernelConfMsgRcvThread(void *args) +{ + CNetManager::GetInstance().RecvNosDataKernel(); + return NULL; +} + +void *CMain::NosStateRcvThread(void *args) +{ + CNetManager::GetInstance().RecvNosStateFromShd(); + return NULL; +} + +void *CMain::NosSysInfoRcvThread(void *args) +{ + CJudgeSysInfo::GetInstance().RcvNosStateMessage(); + return NULL; +} + +void *CMain::NosSysInfoJudgeThread(void *args) +{ + CJudgeSysInfo::GetInstance().Judge(); + return NULL; +} + +void *CMain::SendPluginsCtrlThread(void *args) +{ + CNetManager::GetInstance().SendPluginsCtrl(); + return NULL; +} + +void *CMain::TransNosHostDataThread(void *args) +{ + CNetManager::GetInstance().TransNosHostData(); + return NULL; +} + +void *CMain::TransNosKernelDataThread(void *args) +{ + CNetManager::GetInstance().TransNosKernelData(); + return NULL; +} + +void *CMain::TransDataToOtherThread(void *args) +{ + CNetManager::GetInstance().TransBroadcastDataToOther(); + return NULL; +} diff --git a/study_clang/Mimic/test_judge/src/CMessageQueue.cpp b/study_clang/Mimic/test_judge/src/CMessageQueue.cpp new file mode 100644 index 0000000..c9a2522 --- /dev/null +++ b/study_clang/Mimic/test_judge/src/CMessageQueue.cpp @@ -0,0 +1,14 @@ +/************************************************************************* + > File Name : CMessageQueue.cpp + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Thu 16 Jul 2020 11:34:46 AM CST + ************************************************************************/ + +#include +#include "CMessageQueue.h" + +using namespace std; + + + diff --git a/study_clang/Mimic/test_judge/src/CMysqlPool.cpp b/study_clang/Mimic/test_judge/src/CMysqlPool.cpp new file mode 100644 index 0000000..4c2485e --- /dev/null +++ b/study_clang/Mimic/test_judge/src/CMysqlPool.cpp @@ -0,0 +1,230 @@ +/************************************************************************* + > File Name : CMysqlPool.cpp + > Author : liuzhao + > EMail : liuzhao@comleader.com.cn + > Created Time : Thu 16 Jul 2020 11:33:21 AM CST + ************************************************************************/ + +#include "CMysqlPool.h" +#include "CLog.h" + +std::mutex MysqlPool::poollock; + +MysqlPool::MysqlPool() {} + +/* + *配置数据库参数 + */ +void MysqlPool::setParameter( const char* mysqlhost, + const char* mysqluser, + const char* mysqlpwd, + const char* databasename, + unsigned int port, + const char* socket, + unsigned long client_flag, + unsigned int max_connect ) +{ + _mysqlhost = mysqlhost; + _mysqluser = mysqluser; + _mysqlpwd = mysqlpwd; + _databasename = databasename; + _port = port; + _socket = socket; + _client_flag = client_flag; + MAX_CONNECT = max_connect; + connect_count = 0; +} + +/* + *创建一个连接对象 + */ +MYSQL* MysqlPool::createOneConnect() +{ + MYSQL* conn = NULL; + conn = mysql_init(conn); + if (conn != NULL) + { + if (mysql_real_connect(conn, + _mysqlhost, + _mysqluser, + _mysqlpwd, + _databasename, + _port, + _socket, + _client_flag)) + { + connect_count++; + return conn; + } + else + { + SysLog(LOG_ERR, "mysql:%s", mysql_error(conn)); + return NULL; + } + } + else + { + SysLog(LOG_ERR, "mysql:init failed"); + return NULL; + } +} + +/* + *判断当前MySQL连接池的是否空 + */ +bool MysqlPool::isEmpty() +{ + return mysqlpool.empty(); +} +/* + *获取当前连接池队列的队头 + */ +MYSQL* MysqlPool::poolFront() +{ + return mysqlpool.front(); +} +/* + * + */ +unsigned int MysqlPool::poolSize() +{ + return mysqlpool.size(); +} +/* + *弹出当前连接池队列的队头 + */ +void MysqlPool::poolPop() +{ + mysqlpool.pop(); +} +/* + *获取连接对象,如果连接池中有连接,就取用;没有,就重新创建一个连接对象。 + *同时注意到MySQL的连接的时效性,即在连接队列中,连接对象在超过一定的时间后没有进行操作, + *MySQL会自动关闭连接,当然还有其他原因,比如:网络不稳定,带来的连接中断。 + *所以在获取连接对象前,需要先判断连接池中连接对象是否有效。 + *考虑到数据库同时建立的连接数量有限制,在创建新连接需提前判断当前开启的连接数不超过设定值。 + */ +MYSQL* MysqlPool::getOneConnect() +{ + poollock.lock(); + MYSQL *conn = NULL; + if (!isEmpty()) + { + while (!isEmpty() && mysql_ping(poolFront())) + { + mysql_close(poolFront()); + poolPop(); + connect_count--; + } + if (!isEmpty()) + { + conn = poolFront(); + poolPop(); + } + else + { + if (connect_count < MAX_CONNECT) + conn = createOneConnect(); + else + SysLog(LOG_ERR, "mysql:the number of mysql connections is too much!"); + } + } + else + { + if (connect_count < MAX_CONNECT) + conn = createOneConnect(); + else + SysLog(LOG_ERR, "mysql:the number of mysql connections is too much!"); + } + poollock.unlock(); + return conn; +} +/* + *将有效的链接对象放回链接池队列中,以待下次的取用。 + */ +void MysqlPool::close(MYSQL* conn) +{ + if (conn != NULL) + { + poollock.lock(); + mysqlpool.push(conn); + poollock.unlock(); + } +} +/* + * sql语句执行函数,并返回结果,没有结果的SQL语句返回空结果, + * 每次执行SQL语句都会先去连接队列中去一个连接对象, + * 执行完SQL语句,就把连接对象放回连接池队列中。 + * 返回对象用map主要考虑,用户可以通过数据库字段,直接获得查询的字。 + * 例如:m["字段"][index]。 + */ +void MysqlPool::executeSql(MysqlResults& results, const char* sql) +{ + MYSQL* conn = getOneConnect(); + if (conn) + { + mysql_query(conn, "SET NAMES UTF8"); // TODO + if (mysql_query(conn,sql) == 0) + { + MYSQL_RES *res = mysql_store_result(conn); + if (res) + { + results.field_count = (int32_t)mysql_num_fields(res); + results.record_count = (int32_t)mysql_num_rows(res); + + MYSQL_ROW row = NULL; + unsigned long *row_len = NULL; + + while ((row = mysql_fetch_row(res)) != NULL) + { + if ((row_len = mysql_fetch_lengths(res)) != NULL ) + { + std::vector f_vec; + for (auto i = 0; i < results.field_count; i++) + { + if (row[i] != NULL && row_len[i] > 0) + { + f_vec.push_back(row[i]); + } + } + results.value.push_back(f_vec); + } + } + + MYSQL_FIELD* field = NULL; + for (auto i = 0; (field = mysql_fetch_field(res)) != NULL; i++) + { + results.field_name.push_back(field->name);//field->type; + } + + mysql_free_result(res); + } + else + { + if (mysql_field_count(conn) != 0) + SysLog(LOG_ERR, "mysql:%s", mysql_error(conn)); + } + } + else + { + SysLog(LOG_ERR, "mysql:%s", mysql_error(conn)); + } + close(conn); + } + else + { + SysLog(LOG_ERR, "mysql:%s", mysql_error(conn)); + } +} +/* + * 析构函数,将连接池队列中的连接全部关闭 + */ +MysqlPool::~MysqlPool() +{ + while (poolSize() != 0) + { + mysql_close(poolFront()); + poolPop(); + connect_count--; + } +} diff --git a/study_clang/Mimic/test_judge/src/CNetManager.cpp b/study_clang/Mimic/test_judge/src/CNetManager.cpp new file mode 100644 index 0000000..cdd7982 --- /dev/null +++ b/study_clang/Mimic/test_judge/src/CNetManager.cpp @@ -0,0 +1,483 @@ +/************************************************************************* + > File Name : CNetManager.cpp + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Wed 22 Jul 2020 07:04:38 PM CST + ************************************************************************/ + +#include +#include +#include +#include +#include +#include "CNetManager.h" +#include "CLog.h" +#include "CConfig.h" +#include "CMessageQueue.h" +#include "CJudgeUtils.h" + +CNetManager::CNetManager() +{ + pthread_mutex_init(&m_NosNetInfoHostMutex, NULL); + pthread_mutex_init(&m_NosNetInfoKernelMutex, NULL); + + memset(m_stNosState, 0x00, sizeof(m_stNosState)); + memset(m_stNosNetInfoHost, 0x00, sizeof(m_stNosNetInfoHost)); + memset(m_stNosNetInfoKernel, 0x00, sizeof(m_stNosNetInfoKernel)); + + std::string strShdSvrAddr; + strShdSvrAddr.clear(); + strShdSvrAddr = "tcp://" + Config::GetInstance().schedule_ip + ":" + std::to_string(Config::GetInstance().schedule_port); + m_pShdClient = new CZMQReqRep(ZMQ_REQ, strShdSvrAddr.c_str()); + + strShdSvrAddr.clear(); + strShdSvrAddr = "tcp://" + Config::GetInstance().pluginsctrl_ip + ":" + std::to_string(Config::GetInstance().pluginsctrl_port); + m_pPCtlClient = new CZMQReqRep(ZMQ_REQ, strShdSvrAddr.c_str()); + + strShdSvrAddr.clear(); + strShdSvrAddr = "tcp://" + Config::GetInstance().schedule_ip + ":" + std::to_string(Config::GetInstance().sub_nos_state_port); + m_pNosStateSub = new CZMQSubscriber(strShdSvrAddr.c_str()); +} + +CNetManager::~CNetManager() +{ + pthread_mutex_destroy(&m_NosNetInfoHostMutex); + pthread_mutex_destroy(&m_NosNetInfoKernelMutex); + delete m_pShdClient; + delete m_pPCtlClient; +} + +int CNetManager::RecvDataToConfManagerHost(void *pvBuff, unsigned int uiBuffLen) +{ + return m_ConfigManagerHost.CUdpRecvData(pvBuff, uiBuffLen, \ + Config::GetInstance().config_manager_ip.c_str(), \ + PORT_SET_HOST); +} + +int CNetManager::SendDataToConfManagerHost(const void *pvData, unsigned int uiDataLen) +{ + return m_ConfigManagerHost.CUdpSendData(pvData, uiDataLen, \ + Config::GetInstance().config_manager_ip.c_str(), \ + PORT_SET_HOST); +} + +int CNetManager::RecvDataToConfManagerKernel(void *pvBuff, unsigned int uiBuffLen) +{ + return m_ConfigManagerHost.CUdpRecvData(pvBuff, uiBuffLen, \ + Config::GetInstance().config_manager_ip.c_str(), \ + PORT_SET_KERNEL); +} + +int CNetManager::SendDataToConfManagerKernel(const void *pvData, unsigned int uiDataLen) +{ + return m_ConfigManagerHost.CUdpSendData(pvData, uiDataLen, \ + Config::GetInstance().config_manager_ip.c_str(), \ + PORT_SET_KERNEL); +} + +int CNetManager::SendHostDataToAllNos(const void *pvData, unsigned int uiDataLen) +{ + SOCKADDR_IN_T stSockAddr; + + for(int i = 0; i < NOS_MAX_NUM; i++) + { + memset(&stSockAddr, 0x00, sizeof(stSockAddr)); + if(0 == GetNosNetInfoHost((unsigned int)(i + 1), &stSockAddr)) + { + if(stSockAddr.sin_addr.s_addr != INADDR_NONE) + { + m_NosDataHost.CUdpSendData(pvData, uiDataLen, stSockAddr); + } + } + } + + return 0; +} + +int CNetManager::SendHostDataToNos(int iNosIdx, const void *pvData, unsigned int uiDataLen) +{ + SOCKADDR_IN_T stSockAddr; + + memset(&stSockAddr, 0x00, sizeof(stSockAddr)); + if(0 != GetNosNetInfoHost((unsigned int)iNosIdx, &stSockAddr)) + { + SysLog(SLOG_ERR, "Get net info error!"); + return -1; + } + + return m_NosDataHost.CUdpSendData(pvData, uiDataLen, stSockAddr); +} + + +int CNetManager::SendKernelDataToAllNos(const void *pvData, unsigned int uiDataLen) +{ + SOCKADDR_IN_T stSockAddr; + + for(int i = 0; i < NOS_MAX_NUM; i++) + { + memset(&stSockAddr, 0x00, sizeof(stSockAddr)); + if(0 == GetNosNetInfoKernel((unsigned int)(i + 1), &stSockAddr)) + { + if(stSockAddr.sin_addr.s_addr != INADDR_NONE) + { + m_NosDataKernel.CUdpSendData(pvData, uiDataLen, stSockAddr); + } + } + } + + return 0; +} + +int CNetManager::SendKernelDataToNos(int iNosIdx, const void *pvData, unsigned int uiDataLen) +{ + SOCKADDR_IN_T stSockAddr; + + memset(&stSockAddr, 0x00, sizeof(stSockAddr)); + if(0 != GetNosNetInfoKernel((unsigned int)iNosIdx, &stSockAddr)) + { + SysLog(SLOG_ERR, "Get net info error!"); + return -1; + } + + return m_NosDataKernel.CUdpSendData(pvData, uiDataLen, stSockAddr); +} + + +int CNetManager::SendDataToShd(const void *pvData, unsigned int uiDataLen) +{ + return m_pShdClient->SendData(pvData, uiDataLen); +} + +int CNetManager::RecvDataFromShd(void *pvBuff, unsigned int uiBuffLen) +{ + return m_pShdClient->RecvData(pvBuff, uiBuffLen); +} + +int CNetManager::SendDataToPCtl(const void *pvData, unsigned int uiDataLen) +{ + return m_pPCtlClient->SendData(pvData, uiDataLen); +} + +int CNetManager::RecvDataFromPCtl(void *pvBuff, unsigned int uiBuffLen) +{ + return m_pPCtlClient->RecvData(pvBuff, uiBuffLen); +} + +int CNetManager::GetNosIdxBySock(SOCKADDR_IN_T *pstSockAddrIn) +{ + for(int i = 0; i < NOS_MAX_NUM; i++) + { + if(pstSockAddrIn->sin_addr.s_addr == inet_addr(Config::GetInstance().nos_ip[i].c_str())) + { + return (i + 1); + } + } + + return -1; +} + +void CNetManager::RecvNosDataHost() +{ + int iNosId = 0; + int inRead = 0; + NosConfMsg_ST stNosConfData; + SOCKADDR_IN_T stSockAddrIn; + + m_NosDataHost.CUdpSocket(PORT_BIND_SET_HOST); + while(1) + { + memset(&stSockAddrIn, 0x00, sizeof(stSockAddrIn)); + memset(&stNosConfData, 0x00, sizeof(stNosConfData)); + inRead = m_NosDataHost.CUdpRecvData(&stNosConfData.iCmd, sizeof(stNosConfData.ucData) + sizeof(int), &stSockAddrIn); + if (inRead <= 0) + { + int err = errno; + if (err != EAGAIN && err != EWOULDBLOCK) + { + SysLog(LOG_ERR, "[uiPort:%d] error", err); + dPrint("[RECV ERROR] inRead = %d, %d", inRead, err); + } + usleep(100); + continue; + } + else + { + //bufPrint(&stNosConfData.iCmd, inRead); + //continue; + } + iNosId = GetNosIdxBySock(&stSockAddrIn); + if((-1 != iNosId) && (NOS_MAX_NUM >= iNosId)) + { + SetNosNetInfoHost((unsigned int)iNosId, (const SOCKADDR_IN_T *)&stSockAddrIn); + } + + stNosConfData.uiNosIdx = iNosId; + gettimeofday(&stNosConfData.stRcvTime, NULL); + stNosConfData.uiPort = PORT_SET_HOST; + stNosConfData.uiDataLen = inRead - sizeof(int); + CMessageQueue::GetInstance().push(stNosConfData); + } +} + +void CNetManager::RecvNosDataKernel() +{ + int iNosId = 0; + int inRead = 0; + NosConfMsg_ST stNosConfData; + SOCKADDR_IN_T stSockAddrIn; + + m_NosDataKernel.CUdpSocket(PORT_BIND_SET_KERNEL); + while(1) + { + memset(&stSockAddrIn, 0x00, sizeof(stSockAddrIn)); + memset(&stNosConfData, 0x00, sizeof(stNosConfData)); + inRead = m_NosDataKernel.CUdpRecvData(&stNosConfData.iCmd, sizeof(stNosConfData.ucData) + sizeof(int), &stSockAddrIn); + if (inRead <= 0) + { + int err = errno; + if (err != EAGAIN && err != EWOULDBLOCK) + { + SysLog(LOG_ERR, "[uiPort:%d] error", err); + dPrint("[RECV ERROR] inRead = %d, %d", inRead, err); + } + usleep(100); + continue; + } + else + { + bufPrint(&stNosConfData.iCmd, inRead); + } + iNosId = GetNosIdxBySock(&stSockAddrIn); + if((-1 != iNosId) && (NOS_MAX_NUM >= iNosId)) + { + memcpy(&m_stNosNetInfoKernel[iNosId - 1], &stSockAddrIn, sizeof(SOCKADDR_IN_T)); + } + + stNosConfData.uiNosIdx = iNosId; + gettimeofday(&stNosConfData.stRcvTime, NULL); + stNosConfData.uiPort = PORT_SET_KERNEL; + stNosConfData.uiDataLen = inRead - sizeof(int); + CMessageQueue::GetInstance().push(stNosConfData); + } +} + + +void CNetManager::RecvNosStateFromShd() +{ + int inRead = 0; + NosState_T stNosState; + + while(1) + { + memset(&stNosState, 0x00, sizeof(stNosState)); + inRead = m_pNosStateSub->RecvData(&stNosState, sizeof(stNosState)); + if(0 < inRead) + { + if((0 < stNosState.uiNosIdx) && (NOS_MAX_NUM > stNosState.uiNosIdx)) + { + memcpy(&m_stNosState[stNosState.uiNosIdx - 1], &stNosState, sizeof(NosState_T)); + } + } + } +} + +int CNetManager::GetNosStateById(int iIdx) +{ + return m_stNosState[iIdx - 1].iState; +} + +int CNetManager::SetNosNetInfoHost(unsigned int uiIdx, const SOCKADDR_IN_T *pstInfo) +{ + if((0 > uiIdx) || (uiIdx > NOS_MAX_NUM) || (NULL == pstInfo)) + { + SysLog(SLOG_ERR, "Para is error!"); + return -1; + } + + CMutexLockGuard MutexInfo(m_NosNetInfoHostMutex); + memcpy(&m_stNosNetInfoHost[uiIdx - 1], pstInfo, sizeof(SOCKADDR_IN_T)); + char IPdotdec[20]; + inet_pton(AF_INET, IPdotdec, (void *)&(m_stNosNetInfoHost[uiIdx - 1].sin_addr)); + inet_ntop(AF_INET, (void *)&(m_stNosNetInfoHost[uiIdx - 1].sin_addr), IPdotdec, 16);// 反转换 + SysLog(SLOG_ERR, "SetNosNetInfoHost %d %s", uiIdx - 1, IPdotdec); + SysLog(LOG_ERR, "SetNosNetInfoHost [tid:%ld] [addr:%p] [lock_p:%p]", syscall(SYS_gettid), this, &m_NosNetInfoHostMutex); + + return 0; +} + +int CNetManager::GetNosNetInfoHost(unsigned int uiIdx, SOCKADDR_IN_T *pstInfo) +{ + if((0 > uiIdx) || (uiIdx > NOS_MAX_NUM) || (NULL == pstInfo)) + { + SysLog(SLOG_ERR, "Para is error!"); + return -1; + } + + CMutexLockGuard MutexInfo(m_NosNetInfoHostMutex); + char IPdotdec[20]; + inet_pton(AF_INET, IPdotdec, (void *)&(m_stNosNetInfoHost[uiIdx - 1].sin_addr)); + inet_ntop(AF_INET, (void *)&(m_stNosNetInfoHost[uiIdx - 1].sin_addr), IPdotdec, 16);// 反转换 + SysLog(SLOG_ERR, "GetNosNetInfoHost %d %s", uiIdx - 1, IPdotdec); + SysLog(LOG_ERR, "GetNosNetInfoHost tid:%ld [addr:%p] [lock_p:%p]", syscall(SYS_gettid), this, &m_NosNetInfoHostMutex); + memcpy(pstInfo, &m_stNosNetInfoHost[uiIdx - 1], sizeof(SOCKADDR_IN_T)); + + return 0; +} + +int CNetManager::SetNosNetInfoKernel(unsigned int uiIdx, const SOCKADDR_IN_T *pstInfo) +{ + if((0 > uiIdx) || (uiIdx > NOS_MAX_NUM) || (NULL == pstInfo)) + { + SysLog(SLOG_ERR, "Para is error!"); + return -1; + } + + CMutexLockGuard MutexInfo(m_NosNetInfoKernelMutex); + memcpy(&m_stNosNetInfoKernel[uiIdx - 1], pstInfo, sizeof(SOCKADDR_IN_T)); + + return 0; +} + +int CNetManager::GetNosNetInfoKernel(unsigned int uiIdx, SOCKADDR_IN_T *pstInfo) +{ + if((0 > uiIdx) || (uiIdx > NOS_MAX_NUM) || (NULL == pstInfo)) + { + SysLog(SLOG_ERR, "Para is error!"); + return -1; + } + + CMutexLockGuard MutexInfo(m_NosNetInfoKernelMutex); + memcpy(pstInfo, &m_stNosNetInfoKernel[uiIdx - 1], sizeof(SOCKADDR_IN_T)); + + return 0; +} + +void CNetManager::TransNosHostData() +{ + int inRead = 0; + unsigned char ucBuff[2048]; + SOCKADDR_IN_T stSockAddr; + CUdpClient TransClient(Config::GetInstance().config_manager_ip.c_str(), PORT_GET_HOST); + + TransClient.CUdpSetSendTimeout(0); + m_NosHostTrans.CUdpSocket(PORT_BIND_GET_HOST); + + while(1) + { + memset(ucBuff, 0x00, sizeof(ucBuff)); + inRead = m_NosHostTrans.CUdpRecvData(ucBuff, sizeof(ucBuff), &stSockAddr); + if(0 >= inRead) + { + continue; + } + + if(0 >= TransClient.CUdpSendData(ucBuff, inRead)) + { + SysLog(SLOG_ERR, "Trans host data failed!"); + continue; + } + + memset(ucBuff, 0x00, sizeof(ucBuff)); + inRead = TransClient.CUdpRecvData(ucBuff, sizeof(ucBuff)); + if(0 >= inRead) + { + SysLog(SLOG_ERR, "Trans host data failed!"); + continue; + } + + if(0 >= m_NosHostTrans.CUdpSendData(ucBuff, inRead, stSockAddr)) + { + SysLog(SLOG_ERR, "Trans host data failed!"); + continue; + } + usleep(1000); + } +} + + +void CNetManager::TransNosKernelData() +{ + int inRead = 0; + unsigned char ucBuff[2048]; + SOCKADDR_IN_T stSockAddr; + CUdpClient TransClient(Config::GetInstance().config_manager_ip.c_str(), PORT_GET_KERNEL); + + TransClient.CUdpSetSendTimeout(0); + m_NosKernelTrans.CUdpSocket(PORT_BIND_GET_KERNEL); + + while(1) + { + memset(ucBuff, 0x00, sizeof(ucBuff)); + inRead = m_NosKernelTrans.CUdpRecvData(ucBuff, sizeof(ucBuff), &stSockAddr); + if(0 >= inRead) + { + continue; + } + + if(0 >= TransClient.CUdpSendData(ucBuff, inRead)) + { + SysLog(SLOG_ERR, "Trans host data failed!"); + continue; + } + + memset(ucBuff, 0x00, sizeof(ucBuff)); + inRead = TransClient.CUdpRecvData(ucBuff, sizeof(ucBuff)); + if(0 >= inRead) + { + SysLog(SLOG_ERR, "Trans host data failed!"); + continue; + } + + if(0 >= m_NosKernelTrans.CUdpSendData(ucBuff, inRead, stSockAddr)) + { + SysLog(SLOG_ERR, "Trans host data failed!"); + continue; + } + usleep(1000); + } +} + +void CNetManager::SendPluginsCtrl() +{ + m_pPCtlClient->SetRecvTimeout(1); + m_pPCtlClient->SetSendTimeout(1); + while(1) + { + int index = HEARBEAT_E::HB_JUDGE_E; + SendDataToPCtl(&index, sizeof(index)); + if (RecvDataFromPCtl(&index, sizeof(index)) < 0) + { + SysLog(SLOG_ERR, "recv plugins ctrl error"); + } + sleep(1); + } +} + +void CNetManager::TransBroadcastDataToOther() +{ + int inRead = 0; + unsigned char ucBuff[2048]; + SOCKADDR_IN_T stSockAddr; + CUdpClient TransClient(Config::GetInstance().trans_send_ip.c_str(), Config::GetInstance().trans_send_port); + + TransClient.CUdpSetBroadcastOpt(); + TransClient.CUdpSetSendTimeout(0); + m_BroadcastDataTrans.CUdpSocket(Config::GetInstance().trans_recv_port); + + while(1) + { + memset(ucBuff, 0x00, sizeof(ucBuff)); + inRead = m_BroadcastDataTrans.CUdpRecvData(ucBuff, sizeof(ucBuff), &stSockAddr); + if(0 >= inRead) + { + continue; + } + + if(0 >= TransClient.CUdpSendData(ucBuff, inRead)) + { + SysLog(SLOG_ERR, "Trans data to other failed!"); + continue; + } + usleep(1000); + } +} diff --git a/study_clang/Mimic/test_judge/src/CUdpClient.cpp b/study_clang/Mimic/test_judge/src/CUdpClient.cpp new file mode 100644 index 0000000..9fca04e --- /dev/null +++ b/study_clang/Mimic/test_judge/src/CUdpClient.cpp @@ -0,0 +1,170 @@ +/************************************************************************* + > File Name : CUdpClient.cpp + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Tue 21 Jul 2020 02:02:08 PM CST + ************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "CUdpClient.h" +#include "CLog.h" + +CUdpClient::CUdpClient() +{ + m_iClientSock = -1; + m_uiPort = 0; + memset(m_ucHost, 0x00, sizeof(m_ucHost)); + memset(&m_stServerInfo, 0x00, sizeof(m_stServerInfo)); + CUdpSocket(); +} + +CUdpClient::CUdpClient(const char *pcHost, unsigned int uiPort) +{ + m_iClientSock = -1; + m_uiPort = uiPort; + memset(m_ucHost, 0x00, sizeof(m_ucHost)); + strcpy((char*)m_ucHost, pcHost); + memset(&m_stServerInfo, 0x00, sizeof(m_stServerInfo)); + CUdpSocket(); +} + +CUdpClient::~CUdpClient() +{ + if(0 < m_iClientSock) close(m_iClientSock); +} + +int CUdpClient::CUdpGetSockaddr(const char * pcHost, unsigned int uiPort, SOCKADDR_IN_T *pstSockaddr) +{ + SOCKADDR_IN_T stSockaddr; + + if((NULL == pcHost) || (0 == uiPort) || (NULL == pstSockaddr)) + { + SysLog(SLOG_ERR, "Para is error!"); + return -1; + } + + memset(&stSockaddr, 0x00, sizeof(stSockaddr)); + stSockaddr.sin_family = AF_INET; + stSockaddr.sin_port = htons(uiPort); + stSockaddr.sin_addr.s_addr = inet_addr(pcHost); + if(stSockaddr.sin_addr.s_addr == INADDR_NONE) + { + SysLog(SLOG_ERR, "Incorrect ip address!"); + return -1; + } + + memcpy(pstSockaddr, &stSockaddr, sizeof(SOCKADDR_IN_T)); + + return 0; +} + + +int CUdpClient::CUdpSocket() +{ + m_iClientSock = socket(AF_INET, SOCK_DGRAM, 0); + if(0 > m_iClientSock) + { + SysLog(SLOG_ERR, "Udp client socket failed!"); + return 0; + } + + CUdpSetRecvTimeout(3); + CUdpSetSendTimeout(0); + + return 0; +} + +int CUdpClient::CUdpSetSendTimeout(unsigned int uiSeconds) +{ + TIMEVAL_T stTimeout; + + stTimeout.tv_sec = uiSeconds; + stTimeout.tv_usec = 0; + + return setsockopt(m_iClientSock, SOL_SOCKET, SO_SNDTIMEO, &stTimeout, sizeof(stTimeout)); +} + +int CUdpClient::CUdpSetRecvTimeout(unsigned int uiSeconds) +{ + TIMEVAL_T stTimeout; + + stTimeout.tv_sec = uiSeconds; + stTimeout.tv_usec = 0; + + return setsockopt(m_iClientSock, SOL_SOCKET, SO_RCVTIMEO, &stTimeout, sizeof(stTimeout)); +} + +int CUdpClient::CUdpSetBroadcastOpt() +{ + int iOptval = 1; + return setsockopt(m_iClientSock, SOL_SOCKET, SO_BROADCAST | SO_REUSEADDR, &iOptval, sizeof(int)); +} + +int CUdpClient::CUdpRecvData(void *pcBuff, unsigned int uiBuffLen) +{ + return CUdpRecvData(pcBuff, uiBuffLen, (const char *)m_ucHost, m_uiPort); +} + +int CUdpClient::CUdpRecvData(void *pcBuff, unsigned int uiBuffLen, const char *pcHost, unsigned int uiPort) +{ + SOCKLEN_T stSockLen = 0; + SOCKADDR_IN_T stSockaddr; + + if((NULL == pcBuff) || (NULL == pcHost) || (0 == uiPort)) + { + SysLog(SLOG_ERR, "Para is error!"); + return -1; + } + + memset(&stSockaddr, 0x00, sizeof(stSockaddr)); + if(0 != CUdpGetSockaddr(pcHost, uiPort, &stSockaddr)) + { + SysLog(SLOG_ERR, "Get sockaddr failed!"); + return -1; + } + + stSockLen = sizeof(SOCKADDR_IN_T); + return recvfrom(m_iClientSock, pcBuff, uiBuffLen, 0, (SOCKADDR_T *)&stSockaddr, (SOCKLEN_T *)&stSockLen); +} + +int CUdpClient::CUdpSendData(const void *pcData, unsigned int uiDataLen) +{ + return CUdpSendData(pcData, uiDataLen, (const char*)m_ucHost, m_uiPort); +} + +int CUdpClient::CUdpSendData(const void *pcData, unsigned int uiDataLen, const char *pcHost, unsigned int uiPort) +{ + SOCKADDR_IN_T stSockaddr; + + if((NULL == pcData) || (NULL == pcHost) || (0 == uiPort)) + { + SysLog(SLOG_ERR, "Para is error!"); + return -1; + } + + memset(&stSockaddr, 0x00, sizeof(stSockaddr)); + if(0 != CUdpGetSockaddr(pcHost, uiPort, &stSockaddr)) + { + SysLog(SLOG_ERR, "Get sockaddr failed!"); + return -1; + } + + return sendto(m_iClientSock, pcData, uiDataLen, 0, (SOCKADDR_T *)&stSockaddr, (SOCKLEN_T)sizeof(stSockaddr)); +} + + + + diff --git a/study_clang/Mimic/test_judge/src/CUdpServer.cpp b/study_clang/Mimic/test_judge/src/CUdpServer.cpp new file mode 100644 index 0000000..b9e9c14 --- /dev/null +++ b/study_clang/Mimic/test_judge/src/CUdpServer.cpp @@ -0,0 +1,141 @@ +/************************************************************************* + > File Name : CUdpServer.cpp + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Tue 21 Jul 2020 10:31:10 AM CST + ************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "CUdpServer.h" +#include "CLog.h" + +CUdpServer::CUdpServer() +{ + m_uiPort = 0; + m_iSerSock = -1; +} + +CUdpServer::CUdpServer(unsigned int uiPort) +{ + m_uiPort = uiPort; + CUdpSocket(); +} + +CUdpServer::~CUdpServer() +{ + m_uiPort = 0; + if(0 < m_iSerSock) close(m_iSerSock); +} + +int CUdpServer::CUdpSocket() +{ + if(0 == m_uiPort) + { + SysLog(SLOG_ERR, "Para is error!"); + return -1; + } + + return CUdpSocket(m_uiPort); +} + +int CUdpServer::CUdpSocket(unsigned int uiPort) +{ + int iRet = 0; + + m_uiPort = uiPort; + if(0 == m_uiPort) + { + assert(true); + SysLog(SLOG_ERR, "Para is error!"); + return -1; + } + + m_iSerSock = socket(AF_INET, SOCK_DGRAM, 0); + if(0 > m_iSerSock) + { + SysLog(SLOG_ERR, "Udp server socket failed!"); + return -1; + } + + int flag = fcntl(m_iSerSock, F_GETFL, 0); + if (flag < 0) { + SysLog(SLOG_ERR, "fcntl F_GETFL fail!"); + return -1; + } + if (fcntl(m_iSerSock, F_SETFL, flag | O_NONBLOCK) < 0) { + SysLog(SLOG_ERR, "fcntl F_SETFL fail"); + return -1; + } + + TIMEVAL_T stTimeout; + stTimeout.tv_sec = 3; + stTimeout.tv_usec = 0; + setsockopt(m_iSerSock, SOL_SOCKET, SO_RCVTIMEO, &stTimeout, sizeof(stTimeout)); + + int iOptval = 1; + setsockopt(m_iSerSock, SOL_SOCKET, SO_REUSEADDR, &iOptval, sizeof(int)); + + struct sockaddr_in stAddr; + stAddr.sin_family = AF_INET; + stAddr.sin_port = htons(m_uiPort); + stAddr.sin_addr.s_addr = htonl(INADDR_ANY); + iRet = bind(m_iSerSock, (struct sockaddr *)&stAddr, (socklen_t)sizeof(stAddr)); + if(0 > iRet) + { + SysLog(SLOG_ERR, "Udp server bind failed!"); + return -1; + } + + return m_iSerSock; +} + +int CUdpServer::CUdpRecvData(void *pvBuff, unsigned int uiBuffLen, SOCKADDR_IN_T *pstClientInfo) +{ + int inRead = 0; + SOCKLEN_T stAddrLen; + + if((NULL == pvBuff) || (NULL == pstClientInfo)) + { + SysLog(SLOG_ERR, "Para is error!"); + return -1; + } + + stAddrLen = sizeof(SOCKADDR_IN_T); + inRead = recvfrom(m_iSerSock, pvBuff, uiBuffLen, 0, (SOCKADDR_T *)pstClientInfo,(SOCKLEN_T *)&stAddrLen); + + return inRead; +} + +int CUdpServer::CUdpSendData(const void *pvData, unsigned int uiDataLen, SOCKADDR_IN_T stClientInfo) +{ + int inSend = 0; + + if(NULL == pvData) + { + SysLog(SLOG_ERR, "Para is error!"); + return -1; + } + + inSend = sendto(m_iSerSock, pvData, uiDataLen, 0, (SOCKADDR_T *)&stClientInfo, sizeof(SOCKADDR_T)); + + return inSend; +} + + + diff --git a/study_clang/Mimic/test_judge/src/CZeroMQ.cpp b/study_clang/Mimic/test_judge/src/CZeroMQ.cpp new file mode 100644 index 0000000..8b452ca --- /dev/null +++ b/study_clang/Mimic/test_judge/src/CZeroMQ.cpp @@ -0,0 +1,222 @@ +/************************************************************************* + > File Name : CZeroMQ.cpp + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Fri 17 Jul 2020 10:00:33 AM CST + ************************************************************************/ + +#include +#include +#include "CZeroMQ.h" +#include "CLog.h" +#include "CTypedef.h" + +CZMQSubscriber::CZMQSubscriber(const char *pcAddrPort, const char *pcPriKey, const char *pcPubKey) +{ + m_strAddrPort = pcAddrPort; + m_StrPriKey.clear(); + m_StrPubKey.clear(); + if(NULL != pcPriKey) m_StrPriKey = pcPriKey; + if(NULL != pcPubKey) m_StrPubKey = pcPubKey; + m_pvSubCtx = NULL; + m_pvSubSock = NULL; + SocketInit(); +} + +CZMQSubscriber::~CZMQSubscriber() +{ + if(NULL != m_pvSubSock) zmq_close(m_pvSubSock); + if(NULL != m_pvSubCtx) zmq_ctx_destroy(m_pvSubCtx); +} + +int CZMQSubscriber::SocketInit() +{ + int iRet = 0; + + m_pvSubCtx = zmq_ctx_new(); + if(NULL == m_pvSubCtx) + { + SysLog(SLOG_ERR, "ZMQ ctx new failed!"); + return -1; + } + + m_pvSubSock = zmq_socket(m_pvSubCtx, ZMQ_SUB); + if(NULL == m_pvSubSock) + { + SysLog(SLOG_ERR, "ZMQ socket failed!"); + zmq_ctx_destroy(m_pvSubCtx); + m_pvSubCtx = NULL; + return -1; + } + + if(!m_StrPubKey.empty()) + { + zmq_setsockopt(m_pvSubSock, ZMQ_CURVE_SERVERKEY, m_StrPubKey.c_str(), m_StrPubKey.length()); + + char szPubKey[64] = {0}; + char szPriKey[64] = {0}; + zmq_curve_keypair(szPubKey, szPriKey); + zmq_setsockopt(m_pvSubSock, ZMQ_CURVE_PUBLICKEY, szPubKey, strlen(szPubKey)); + zmq_setsockopt(m_pvSubSock, ZMQ_CURVE_SECRETKEY, szPriKey, strlen(szPriKey)); + } + + iRet = zmq_connect(m_pvSubSock, m_strAddrPort.c_str()); + if(0 > iRet) + { + SysLog(SLOG_ERR, "ZMQ connect failed!"); + zmq_close(m_pvSubSock); + zmq_ctx_destroy(m_pvSubCtx); + m_pvSubCtx = NULL; + m_pvSubSock = NULL; + return -1; + } + + iRet = zmq_setsockopt(m_pvSubSock, ZMQ_SUBSCRIBE, "", 0); + if(0 != iRet) + { + SysLog(SLOG_ERR, "ZMQ set ZMQ_SUBSCRIBE failed"); + zmq_close(m_pvSubSock); + zmq_ctx_destroy(m_pvSubCtx); + m_pvSubCtx = NULL; + m_pvSubSock = NULL; + return -1; + } + + SetRecvTimeout(); + + return 0; +} + +int CZMQSubscriber::SetRecvTimeout(unsigned int uiSeconds) +{ + unsigned int uiTimeout = uiSeconds * 1000; + + return zmq_setsockopt(m_pvSubSock, ZMQ_RCVTIMEO, &uiTimeout, sizeof(uiTimeout)); +} + +int CZMQSubscriber::RecvData(void *pvBuff, unsigned int uiBuffLen) +{ + if(NULL == m_pvSubSock) SocketInit(); + + return zmq_recv(m_pvSubSock, pvBuff, uiBuffLen, 0); +} + +CZMQReqRep::CZMQReqRep(int iType, const char *pcAddrPort, const char *pcPriKey, const char *pcPubKey) +{ + m_iType = iType; + m_strAddrPort = pcAddrPort; + m_StrPriKey.clear(); + m_StrPubKey.clear(); + if(NULL != pcPriKey) m_StrPriKey = pcPriKey; + if(NULL != pcPubKey) m_StrPubKey = pcPubKey; + m_pvCtx = NULL; + m_pvSock = NULL; + SocketInit(); +} + +CZMQReqRep::~CZMQReqRep() +{ + if(NULL != m_pvSock) zmq_close(m_pvSock); + if(NULL != m_pvCtx) zmq_ctx_destroy(m_pvCtx); +} + +int CZMQReqRep::RecvData(void *pvBuff, unsigned int uiBuffLen) +{ + return zmq_recv(m_pvSock, pvBuff, uiBuffLen, 0); +} + +int CZMQReqRep::SendData(const void *pvData, unsigned int uiDataLen) +{ + return zmq_send(m_pvSock, pvData, uiDataLen, 0); +} + +int CZMQReqRep::SetRecvTimeout(unsigned int uiSeconds) +{ + unsigned int uiTimeout = uiSeconds * 1000; + + return zmq_setsockopt(m_pvSock, ZMQ_RCVTIMEO, &uiTimeout, sizeof(uiTimeout)); +} + +int CZMQReqRep::SetSendTimeout(unsigned int uiSeconds) +{ + unsigned int uiTimeout = uiSeconds * 1000; + + return zmq_setsockopt(m_pvSock, ZMQ_SNDTIMEO, &uiTimeout, sizeof(uiTimeout)); +} + +int CZMQReqRep::SocketInit() +{ + unsigned int uiTimeout = 0; + + m_pvCtx = zmq_ctx_new(); + if(NULL == m_pvCtx) + { + SysLog(SLOG_ERR, "ZMQ ctx new failed!"); + return -1; + } + + m_pvSock = zmq_socket(m_pvCtx, m_iType); + if(NULL == m_pvSock) + { + SysLog(SLOG_ERR, "ZMQ socket failed!"); + zmq_ctx_destroy(m_pvCtx); + m_pvCtx = NULL; + return -1; + } + + uiTimeout = 3*1000; + zmq_setsockopt(m_pvSock, ZMQ_LINGER, &uiTimeout, sizeof(uiTimeout)); + + SetRecvTimeout(); + SetSendTimeout(); + + int iCurveRet = 0; + if(ZMQ_REQ == m_iType) + { + if(!m_StrPubKey.empty()) + { + dPrint("ZMQ with curve."); + dPrint("Pubkey <%s> <%d>", m_StrPubKey.c_str(), m_StrPubKey.length()); + iCurveRet = zmq_setsockopt(m_pvSock, ZMQ_CURVE_SERVERKEY, m_StrPubKey.c_str(), m_StrPubKey.length()); + dPrint("iCurveRet = %d", iCurveRet); + + char szPubKey[64] = {0}; + char szPriKey[64] = {0}; + iCurveRet = zmq_curve_keypair(szPubKey, szPriKey); + zmq_setsockopt(m_pvSock, ZMQ_CURVE_PUBLICKEY, szPubKey, strlen(szPubKey)); + dPrint("iCurveRet = %d", iCurveRet); + iCurveRet = zmq_setsockopt(m_pvSock, ZMQ_CURVE_SECRETKEY, szPriKey, strlen(szPriKey)); + dPrint("iCurveRet = %d", iCurveRet); + } + if(0 > zmq_connect(m_pvSock, m_strAddrPort.c_str())) + { + zmq_close(m_pvSock); + zmq_ctx_destroy(m_pvCtx); + m_pvCtx = NULL; + m_pvSock = NULL; + return -1; + } + } + else if(ZMQ_REP == m_iType) + { + if(!m_StrPriKey.empty()) + { + int option = 1; + zmq_setsockopt(m_pvSock, ZMQ_CURVE_SERVER, &option, sizeof(option)); + zmq_setsockopt(m_pvSock, ZMQ_CURVE_SECRETKEY, m_StrPriKey.c_str(), m_StrPriKey.length()); + } + if(0 > zmq_bind(m_pvSock, m_strAddrPort.c_str())) + { + zmq_close(m_pvSock); + zmq_ctx_destroy(m_pvCtx); + m_pvCtx = NULL; + m_pvSock = NULL; + return -1; + } + } + + return 0; +} + + + diff --git a/study_clang/Mimic/test_judge/src/main.cpp b/study_clang/Mimic/test_judge/src/main.cpp new file mode 100644 index 0000000..3fc70bc --- /dev/null +++ b/study_clang/Mimic/test_judge/src/main.cpp @@ -0,0 +1,335 @@ +#include +#include + +#include "CTypedef.h" +#include "CZeroMQ.h" + +using std::cout; +using std::endl; + +CZMQReqRep *client; + +void init_file_num_msg(FileNum_T& msg) +{ + msg.uiType = 4; + strcpy(msg.szIp, "10.10.10.241"); + gettimeofday(&msg.stRcvTime,NULL); + strcpy(msg.szDirPath, "/home"); + strcpy(msg.szFileName, "add breakup"); + msg.uiFileNum = 120; +} + +void init_file_state_msg(FileState_T& msg) +{ + msg.uiType = 3; + strcpy(msg.szIp, "10.10.10.241"); + gettimeofday(&msg.stRcvTime,NULL); + strcpy(msg.szFileName, "Config Manager"); + strcpy(msg.eventType, "Modify"); + strcpy(msg.szFileMd5, "23333333333333333333333333333333"); +} + +void init_process_state_msg(ProcessState_T& msg, int id = 1) +{ + switch(id) + { + case 1: + msg.uiType = 2; + strcpy(msg.szIp, "10.10.10.241"); + gettimeofday(&msg.stRcvTime,NULL); + strcpy(msg.szProcessName, "manager"); + msg.uiProcessState=-1; + break; + case 2: + msg.uiType = 2; + strcpy(msg.szIp, "10.10.10.242"); + gettimeofday(&msg.stRcvTime,NULL); + strcpy(msg.szProcessName, "manager"); + msg.uiProcessState=-1; + break; + case 3: + msg.uiType = 2; + strcpy(msg.szIp, "10.10.10.243"); + gettimeofday(&msg.stRcvTime,NULL); + strcpy(msg.szProcessName, "manager"); + msg.uiProcessState=-1; + break; + case 4: + case 5: + default: + break; + }; +} + +void init_sys_state_msg(SysState_T& msg, int id = 1) +{ + switch(id) + { + case 1: + msg.uiType = 1; + strcpy(msg.szIp, "10.10.10.241"); + gettimeofday(&msg.stRcvTime,NULL); + msg.uiCpuRate = 600; + msg.uiMemRate = 500; + msg.uiTcpEstablishNum = 10; + msg.uiRunningProcessNum = 100; + msg.uiCronNum = 20; + strcpy(msg.szPasswdMd5, "155c0f8a0aca2bfa5f2e85a32be41803"); + strcpy(msg.szGroupMd5, "62bc68396162fda049d1ba7c7d04eb54"); + break; + case 2: + msg.uiType = 1; + strcpy(msg.szIp, "10.10.10.242"); + gettimeofday(&msg.stRcvTime,NULL); + msg.uiCpuRate = 600; + msg.uiMemRate = 500; + msg.uiTcpEstablishNum = 10; + msg.uiRunningProcessNum = 100; + msg.uiCronNum = 20; + strcpy(msg.szPasswdMd5, "155c0f8a0aca2bfa5f2e85a32be41803"); + strcpy(msg.szGroupMd5, "62bc68396162fda049d1ba7c7d04eb54"); + break; + case 3: + msg.uiType = 1; + strcpy(msg.szIp, "10.10.10.243"); + gettimeofday(&msg.stRcvTime,NULL); + msg.uiCpuRate = 600; + msg.uiMemRate = 500; + msg.uiTcpEstablishNum = 10; + msg.uiRunningProcessNum = 100; + msg.uiCronNum = 20; + strcpy(msg.szPasswdMd5, "155c0f8a0aca2bfa5f2e85a32be41803"); + strcpy(msg.szGroupMd5, "62bc68396162fda049d1ba7c7d04eb54"); + break; + case 4: + msg.uiType = 1; + strcpy(msg.szIp, "10.10.10.244"); + gettimeofday(&msg.stRcvTime,NULL); + msg.uiCpuRate = 600; + msg.uiMemRate = 500; + msg.uiTcpEstablishNum = 10; + msg.uiRunningProcessNum = 100; + msg.uiCronNum = 20; + strcpy(msg.szPasswdMd5, "155c0f8a0aca2bfa5f2e85a32be41803"); + strcpy(msg.szGroupMd5, "62bc68396162fda049d1ba7c7d04eb54"); + break; + case 5: + default: + break; + }; +} + +void init_sys_shell_log_msg(SysLog_T& log, int id = 1) +{ + switch(id) + { + case 1: + log.uiType = 5; + strcpy(log.szIp, "10.10.10.241"); + strcpy(log.szLogFile, "history"); + strcpy(log.szMsg[0], "ls"); + strcpy(log.szMsg[1], "rm -rf *"); + strcpy(log.szMsg[2], "shutdown -h now"); + strcpy(log.szMsg[3], "reboot"); + strcpy(log.szMsg[4], "free"); + break; + case 2: + case 3: + case 4: + case 5: + default: + break; + }; + cout << "send " << " ip: " << log.szIp << ", logfile: " << log.szLogFile; + for(int i=1;i<6;i++) + cout << ", shell" << i << ": " << log.szMsg[i]; + cout << endl; + +} + +void init_sys_login_log_msg(SysLog_T& log, int id = 1) +{ + switch(id) + { + case 1: + log.uiType = 5; + strcpy(log.szIp, "10.10.10.241"); + strcpy(log.szLogFile, "wtmp"); + strcpy(log.szMsg[0], "mswitch pts/0 192.168.6.129 Tue Jul 28 01:54 - 02:27 (00:33)"); + strcpy(log.szMsg[1], "fengchao pts/2 10.10.11.177 Tue Jul 28 23:15 - 23:44 (00:28)"); + strcpy(log.szMsg[2], "liuzhao pts/1 10.10.11.173 Tue Jul 28 22:49 - 03:58 (05:09)"); + strcpy(log.szMsg[3], "songtian pts/4 10.10.11.170 Wed Jul 29 04:41 - 08:05 (03:24)"); + strcpy(log.szMsg[4], "hongqian pts/4 10.10.11.156 Thu Jul 30 08:24 - 10:38 (02:14)"); + break; + case 2: + case 3: + case 4: + case 5: + default: + break; + }; + cout << "send " << " ip: " << log.szIp << ", logfile: " << log.szLogFile; + for(int i=1;i<6;i++) + cout << ", shell" << i << ": " << log.szMsg[i]; + cout << endl; + +} +void send_msg(CZMQReqRep* client, const void *pvData, uint uiDataLen) +{ + char buffer[1024]; + + memset(buffer, 0X00, sizeof(buffer)); + int send_num = client->SendData(pvData, uiDataLen); + int recv_num = client->RecvData(buffer, sizeof(buffer)); + + cout << "send code: " << send_num << endl; + cout << "recv code: " << recv_num << " ,msg: " << buffer << endl; + //sleep(1); +} + +// 1、消息解析测试 + +void test_msg_analysis() +{ + SysState_T mSysState; + ProcessState_T mProcessState; + FileState_T mFileState; + FileNum_T mFileNum; + SysLog_T mSysLog; + + init_sys_state_msg(mSysState); + init_process_state_msg(mProcessState); + init_file_state_msg(mFileState); + init_file_num_msg(mFileNum); + init_sys_shell_log_msg(mSysLog); + + cout << "开始测试消息解析,1-5号消息各一条,检查裁决消息解析。" << endl; + + send_msg(client, &mSysState, sizeof(mSysState) ); + send_msg(client, &mProcessState, sizeof(mProcessState)); + send_msg(client, &mFileState, sizeof(mFileState) ); + send_msg(client, &mFileNum, sizeof(mFileNum) ); + send_msg(client, &mSysLog, sizeof(mSysLog) ); +} + +// 2、系统运行状态裁决,正常时向上反馈运行正常,异常时反馈错误代码(包括超时) +void test_sys_state() +{ + + SysState_T mSysState; + + cout << "开始测试系统运行状态裁决,所有项正常,裁决应报告nos1,2,3运行正常。" << endl; + for(int i=1;i<5;i++) + { + init_sys_state_msg(mSysState, i); + send_msg(client, &mSysState, sizeof(mSysState)); + } + + sleep(1); + + cout << "开始测试系统运行状态裁决,模拟仅Nos1正常,,裁决应报告nos1运行正常,其他离线。" << endl; + for(int i=1;i<5;i++) + { + init_sys_state_msg(mSysState, 1); + send_msg(client, &mSysState, sizeof(mSysState)); + sleep(1); + } + +} + +// 3、进程状态裁决,进程挂掉时裁决失败,向SHD反馈错误代码 +void test_process_state() +{ + cout << "开始测试进程状态裁决,应报告nos1进程运行异常。" << endl; + ProcessState_T mProcessState; + init_process_state_msg(mProcessState,2); + send_msg(client, &mProcessState, sizeof(mProcessState)); +} + +// 4、文件状态裁决,文件被修改时裁决失败,向SHD反馈错误代码 +void test_file_state() +{ + cout << "开始测试文件状态裁决,应报告nos1文件异常。" << endl; + FileState_T mFileState; + init_file_state_msg(mFileState); + send_msg(client, &mFileState, sizeof(mFileState)); +} + +// 5、目录状态裁决,当文件个数过多时裁决失败,向SHD反馈错误代码 +void test_file_num() +{ + cout << "开始测试目录状态裁决,应报告nos1目录异常。" << endl; + FileNum_T mFileNum; + init_file_num_msg(mFileNum); + send_msg(client, &mFileNum, sizeof(mFileNum)); +} + +// 6、系统日志裁决,出现登录或是shell被运行时裁决失败,向SHD反馈错误代码 +void test_sys_log() +{ + cout << "开始系统日志裁决,应报告nos1目录异常。" << endl; + SysLog_T mSysLog; + + init_sys_login_log_msg(mSysLog); + send_msg(client, &mSysLog, sizeof(mSysLog)); + + sleep(1); + + init_sys_shell_log_msg(mSysLog); + //send_msg(client, &mSysLog, sizeof(mSysLog)); +} + +int main() +{ + /*MysqlPool::GetInstance().setParameter("localhost","root","123456","test",0,NULL,0,2); + std::map > m = MysqlPool::GetInstance().executeSql("INSERT INTO test(id, title, author, date)VALUES(7, \"学习\", \"日志\", NOW());"); + + Config::GetInstance().Init("./judge.ini"); + std::cout << Config::GetInstance().judge_ip << " " << Config::GetInstance().judge_port << std::endl;*/ + + //CMain::GetInstance().Init(); + //CMain::GetInstance().MainProcess(); + + + //SysState_T mSysState; + //ProcessState_T mProcessState; + //FileState_T mFileState; + //FileNum_T mFileNum; + //SysLog_T mSysLog; + + SysLog_T m_sys_login_log; + SysLog_T m_sys_shell_log; + + client = new CZMQReqRep(ZMQ_REQ, "tcp://127.0.0.1:7002", JUDGE_PRIVATE_KEY, JUDGE_PUBLIC_KEY); + + + while(true) + { + test_msg_analysis(); + test_sys_state(); + test_process_state(); + test_file_state(); + test_file_num(); + test_sys_log(); + sleep(1); + } + + + //for(int i=0;i<1000;i++) + { + //init_sys_state_log_msg(m_sys_state_log,0); + //send_msg(client, &m_sys_state_log, sizeof(m_sys_state_log)); + + //init_process_state_msg(m_process_state,0); + //send_msg(client, &m_process_state, sizeof(m_process_state)); + + //init_sys_shell_log_msg(m_sys_shell_log,0); + //send_msg(client, &m_sys_shell_log, sizeof(m_sys_shell_log)); + + //init_sys_login_log_msg(m_sys_login_log,0); + //send_msg(client, &m_sys_login_log, sizeof(m_sys_login_log)); + //if(i%5==0) + //sleep(3); + } + return 0; +} diff --git a/study_clang/Mimic/test_messagequeue/core.19948 b/study_clang/Mimic/test_messagequeue/core.19948 new file mode 100644 index 0000000..e77fc2a Binary files /dev/null and b/study_clang/Mimic/test_messagequeue/core.19948 differ diff --git a/study_clang/Mimic/test_messagequeue/include/CConfig.h b/study_clang/Mimic/test_messagequeue/include/CConfig.h new file mode 100644 index 0000000..164e1c2 --- /dev/null +++ b/study_clang/Mimic/test_messagequeue/include/CConfig.h @@ -0,0 +1,97 @@ +/************************************************************************* + > File Name : CConfig.h + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Fri 17 Jul 2020 09:31:50 AM CST + ************************************************************************/ + +#include +#include +#include +#include +#include "CJudgeUtils.h" +#include "CTypedef.h" + +class Config : public CSingleton +{ +public: + Config() {} + virtual ~Config() {} + + void Init(const std::string& file_name) + { + INIReader reader; + reader.Parse(file_name); + + std::string strNosIdx; + for(int i = 0; i < NOS_MAX_NUM; i++) + { + strNosIdx.clear(); + strNosIdx = "nos" + std::to_string((i + 1)) + "_ip"; + nos_ip[i] = reader.Get("judge", strNosIdx, strNosIdx); + } + + #define _GET_JUDGE_CFG(value) value = reader.GetInt32("judge", #value, value) + _GET_JUDGE_CFG(schedule_port); + _GET_JUDGE_CFG(pluginsctrl_port); + _GET_JUDGE_CFG(sub_nos_state_port); + _GET_JUDGE_CFG(nos_num); + _GET_JUDGE_CFG(running_num); + + #undef _GET_JUDGE_CFG + + #define _GET_JUDGE_CFG(value) value = reader.Get("judge", #value, value) + _GET_JUDGE_CFG(config_manager_ip); + _GET_JUDGE_CFG(schedule_ip); + _GET_JUDGE_CFG(pluginsctrl_ip); + + #undef _GET_JUDGE_CFG + + // Judge_sys_info + #define _GET_JUDGE_SYS_INFO_CFG(value) value = reader.GetInt32("judge_sys_info", #value, value) + _GET_JUDGE_SYS_INFO_CFG(nos_monitor_port); + _GET_JUDGE_SYS_INFO_CFG(cpu_occupy_max); + _GET_JUDGE_SYS_INFO_CFG(mem_occupy_max); + _GET_JUDGE_SYS_INFO_CFG(tcp_socket_max); + _GET_JUDGE_SYS_INFO_CFG(progress_max); + _GET_JUDGE_SYS_INFO_CFG(cron_max); + _GET_JUDGE_SYS_INFO_CFG(path_file_max); + _GET_JUDGE_SYS_INFO_CFG(home_file_max); + + #undef _GET_JUDGE_SYS_INFO_CFG + + #define _GET_JUDGE_SYS_INFO_CFG(value) value = reader.Get("judge_sys_info", #value, value) + _GET_JUDGE_SYS_INFO_CFG(user_md5); + _GET_JUDGE_SYS_INFO_CFG(group_md5); + _GET_JUDGE_SYS_INFO_CFG(config_manager_md5); + _GET_JUDGE_SYS_INFO_CFG(auto_start_md5); + + #undef _GET_JUDGE_SYS_INFO_CFG + } + + std::string nos_ip[NOS_MAX_NUM]; + std::string config_manager_ip; + std::string schedule_ip; + std::string pluginsctrl_ip; + + int sub_nos_state_port; + int schedule_port; + int pluginsctrl_port; + int nos_num; + int running_num; + + // Judge_sys_info + std::string user_md5; + std::string group_md5; + std::string config_manager_md5; + std::string auto_start_md5; + + int nos_monitor_port; + int cpu_occupy_max; + int mem_occupy_max; + int tcp_socket_max; + int progress_max; + int cron_max; + int path_file_max; + int home_file_max; +}; diff --git a/study_clang/Mimic/test_messagequeue/include/CJudgeConf.h b/study_clang/Mimic/test_messagequeue/include/CJudgeConf.h new file mode 100644 index 0000000..597ef64 --- /dev/null +++ b/study_clang/Mimic/test_messagequeue/include/CJudgeConf.h @@ -0,0 +1,48 @@ +/************************************************************************* + > File Name : ../include/CJudge.h + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Thu 16 Jul 2020 11:33:38 AM CST + ************************************************************************/ + +#ifndef CJUDGE_H +#define CJUDGE_H + +#include +#include "CTypedef.h" +#include "CJudgeUtils.h" + +typedef std::map > CACHE_MAP; +typedef std::vector MSG_VEC; + +struct MsgGroup +{ + CACHE_MAP cache_map; // 一组执行体消息的对比缓存 + MSG_VEC msg_vec; // 一组执行体消息源 + time_t start_ms; // 一组新消息进入起始时间 + unsigned int uiPort; // 一组消息的端口 +}; + +class JudgeConf : public CSingleton +{ +public: + JudgeConf() { } + ~JudgeConf() { } + + void Init(int _nos_num, int _running_num); + void Judge(); + +private: + std::map group_map; // 按iCmd划分消息组,nos端口相同 + + int nos_num; + int running_num; + + int nos_status; // 各个nos是否running TODO + +private: + int GetCacheNosNum(CACHE_MAP& map); + +}; + +#endif diff --git a/study_clang/Mimic/test_messagequeue/include/CJudgeSysInfo.h b/study_clang/Mimic/test_messagequeue/include/CJudgeSysInfo.h new file mode 100644 index 0000000..76224b3 --- /dev/null +++ b/study_clang/Mimic/test_messagequeue/include/CJudgeSysInfo.h @@ -0,0 +1,103 @@ +/************************************************************************* + > File Name : CJudgeSysInfo.h + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Fri 17 Jul 2020 09:47:20 AM CST + ************************************************************************/ + +#ifndef CJUDGE_SYS_INFO_H +#define CJUDGE_SYS_INFO_H + + +#include "CTypedef.h" +#include "CJudgeUtils.h" + +#define MAX_MSG_BUFFER 1024 // 通信消息缓存区 +#define TIME_OUT_JUDGE 30 // 超时裁决时间 + + + +class CJudgeSysInfo : public CSingleton +{ +public: + CJudgeSysInfo(); + ~CJudgeSysInfo(); + void Init(); + void RcvNosStateMessage(); +private: + int StartMultiThreadJudge(); + void JudgeSysState(); // 裁决系统运行状态 + void JudgeProcessState(); // 裁决系统进程状态 + void JudgeFileState(); // 裁决关键文件状态 + void JudgeFileNum(); // 裁决关键文件数量 + void JudgeSysLog(); // 裁决系统关键日志 + + static void AlarmJudgeSysState(int sig); // 系统状态超时裁决 + + void StartJudgeSysState(); // 开始裁决系统运行状态 + void StartJudgeProcessState(); // 开始裁决系统进程状态 + void StartJudgeFileState(); // 开始裁决关键文件状态 + void StartJudgeFileNum(); // 开始裁决关键文件数量 + void StartJudgeSysLog(); // 开始裁决系统关键日志 + + void JudgeCpuOccupy(uint current_cpu_occupy, uint nos_id); + void JudgeMemOccupy(); + void JudgeTcpSocket(); + void JudgeProcessNum(); + void JudgeLoginLog(); + void JudgeCmdLog(); + void JudgeUserInfo(); + void JudgeGroupInfo(); + void JudgeCronNum(); + void JudgePathFileNum(); + void JudgeHomeFileNum(); + void JudgeAppMd5(); + void JudgeAutoStartMd5(); + void JudgeManagerProgress(); + void JudgeProtocolProgress(); + void JudgeLocalConfigManager(); + void JudgeFirewell(); + + + // 消息解析函数 + SystemState_T SplitMsgToSysState(char *buffer, int len_Buffer); + ProcessState_T SplitMsgToProcessState(char *buffer, int len_Buffer); + FileState_T SplitMsgToFileState(char *buffer, int len_Buffer); + FileNum_T SplitMsgToFileNum(char *buffer, int len_Buffer); + SysLog_T SplitMsgToSysLog(char *buffer, int len_Buffer); + + uint GetNosId(char ip[32]); + +private: + int nos_num; + uint running_num; + + SystemState_T m_SysState; // 系统运行状态消息 + ProcessState_T m_ProcessState; // 关键进程状态消息 + FileState_T m_FileState; // 关键文件状态消息 + FileNum_T m_FileNum; // 关键文件数量消息 + SysLog_T m_SysLog; // 关键日志增量消息 + std::list ml_SysState; // 系统运行状态消息组 + std::list ml_ProcessState; // 关键进程状态消息组 + std::list ml_FileState; // 关键文件状态消息组 + std::list ml_FileNum; // 关键文件数量消息组 + std::list ml_SysLog; // 关键日志增量消息组 + + // Judge_sys_info + std::string user_md5; + std::string group_md5; + std::string config_manager_md5; + std::string auto_start_md5; + + uint nos_monitor_port; + uint cpu_occupy_max; + uint mem_occupy_max; + uint tcp_socket_max; + uint progress_max; + uint cron_max; + uint path_file_max; + uint home_file_max; +}; + + +#endif diff --git a/study_clang/Mimic/test_messagequeue/include/CJudgeUtils.h b/study_clang/Mimic/test_messagequeue/include/CJudgeUtils.h new file mode 100644 index 0000000..4aceb84 --- /dev/null +++ b/study_clang/Mimic/test_messagequeue/include/CJudgeUtils.h @@ -0,0 +1,152 @@ +/************************************************************************* + > File Name : CJudgeUtils.h + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Fri 17 Jul 2020 09:34:47 AM CST + ************************************************************************/ + +#ifndef _JUDGE_COMMON_H_ +#define _JUDGE_COMMON_H_ + +#include +#include +#include +#include +#include +#include +#include + +class CNonCopyable +{ +protected: + CNonCopyable() {} + ~CNonCopyable() {} +private: + CNonCopyable(const CNonCopyable &); + const CNonCopyable& operator=(const CNonCopyable &); +}; + +class CMutexLockGuard:CNonCopyable +{ + public: + explicit CMutexLockGuard(pthread_mutex_t& mutex) + : m_mutex(mutex) + { + pthread_mutex_lock(&m_mutex); + } + + ~CMutexLockGuard() + { + pthread_mutex_unlock(&m_mutex); + } + +private: + pthread_mutex_t& m_mutex; +}; + +template +class CSingleton +{ +public: + static T* GetInstance() + { + if( _instance == NULL ) + { + _instance = new T; + } + return _instance; + } + + static T* Instance() + { + if( _instance == NULL ) + { + _instance = new T; + } + return _instance; + } + + static void Release() + { + if( _instance!= NULL ) + { + delete _instance; + } + + _instance = NULL; + } + +protected: + CSingleton(){} + virtual ~CSingleton(){} +protected: + static T* _instance; +}; + +template T* CSingleton::_instance=NULL; + +class INIReader +{ +public: + explicit INIReader() {} + ~INIReader() {} + + /// @brief 解析文件 + /// @return 0 成功 + /// @return <0 失败 + /// @note 每次调用会清除上一次的解析结果 + int32_t Parse(const std::string& filename); + + void Clear(); + + /// @brief 获取string类型字段的值,字段未配置时使用默认值 + std::string Get(const std::string& section, const std::string& name, + const std::string& default_value); + + // Get an integer (long) value from INI file, returning default_value + // if not found or not a valid integer (decimal "1234", "-1234", + // or hex "0x4d2"). + int32_t GetInt32(const std::string& section, const std::string& name, + int32_t default_value); + + uint32_t GetUInt32(const std::string& section, const std::string& name, + uint32_t default_value); + + int64_t GetInt64(const std::string& section, const std::string& name, + int64_t default_value); + + uint64_t GetUInt64(const std::string& section, const std::string& name, + uint64_t default_value); + + // Get a real (floating point double) value from INI file, returning + // default_value if not found or not a valid floating point value + // according to strtod(). + double GetReal(const std::string& section, const std::string& name, double default_value); + + // Get a boolean value from INI file, returning default_value + // if not found or if not a valid true/false value. Valid true + // values are "true", "yes", "on", "1", and valid false values are + // "false", "no", "off", "0" (not case sensitive). + bool GetBoolean(const std::string& section, const std::string& name, bool default_value); + + // Returns all the section names from the INI file, in alphabetical order, + // but in the original casing + const std::set& GetSections() const; + + // Returns all the field names from a section in the INI file, in + // alphabetical order, but in the original casing. Returns an + // empty set if the field name is unknown + std::set GetFields(const std::string& section); + + /// @brief 返回最后错误字符串描述 + /// @return 最后一次错误的信息 + const char* GetLastError() const { return m_last_error; } +private: + int32_t ParseFile(FILE* file); +private: + char m_last_error[256]; + std::set m_sections; + std::map > m_fields; +}; + +#endif diff --git a/study_clang/Mimic/test_messagequeue/include/CLog.h b/study_clang/Mimic/test_messagequeue/include/CLog.h new file mode 100644 index 0000000..e2ad546 --- /dev/null +++ b/study_clang/Mimic/test_messagequeue/include/CLog.h @@ -0,0 +1,93 @@ +/************************************************************************* + > File Name : CLog.h + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Fri 17 Jul 2020 09:33:22 AM CST + ************************************************************************/ + #ifndef CLOG_H + #define CLOG_H + +#include +#include +#include +#include +#include +#include +#include +#include + + +//颜色宏定义 +#define NONE "\033[m" +#define RED "\033[0;32;31m" +#define LIGHT_RED "\033[1;31m" +#define GREEN "\033[0;32;32m" +#define LIGHT_GREEN "\033[1;32m" +#define BLUE "\033[0;32;34m" +#define LIGHT_BLUE "\033[1;34m" +#define DARY_GRAY "\033[1;30m" +#define CYAN "\033[0;36m" +#define LIGHT_CYAN "\033[1;36m" +#define PURPLE "\033[0;35m" +#define LIGHT_PURPLE "\033[1;35m" +#define BROWN "\033[0;33m" +#define YELLOW "\033[1;33m" +#define LIGHT_GRAY "\033[0;37m" +#define WHITE "\033[1;37m" + +#define PRO_NAME "JUDGE" +#define _FUN_ __FUNCTION__ + +typedef enum tagLogLevel +{ + FATAL = 0, + ALERT, + ERROR, + WARN, + NOTICE, + INFO, + DEBUG +} CYBERER_LOG_LEVEL_E; + + +/* + * priorities/facilities are encoded into a single 32-bit quantity, where the + * bottom 3 bits are the priority (0-7) and the top 28 bits are the facility + * (0-big number). Both the priorities and the facilities map roughly + * one-to-one to strings in the syslogd(8) source code. This mapping is + * included in this file. + * + * priorities (these are ordered) + * + * #define LOG_EMERG 0 // system is unusable / + * #define LOG_ALERT 1 // action must be taken immediately / + * #define LOG_CRIT 2 // critical conditions / + * #define LOG_ERR 3 // error conditions / + * #define LOG_WARNING 4 // warning conditions / + * #define LOG_NOTICE 5 // normal but significant condition / + * #define LOG_INFO 6 // informational / + * #define LOG_DEBUG 7 // debug-level messages / +*/ +#define SLOG_EMERG 0 /* system is unusable */ +#define SLOG_ALERT 1 /* action must be taken immediately */ +#define SLOG_CRIT 2 /* critical conditions */ +#define SLOG_ERR 3 /* error conditions */ +#define SLOG_WARNING 4 /* warning conditions */ +#define SLOG_NOTICE 5 /* normal but significant condition */ +#define SLOG_INFO 6 /* informational */ +#define SLOG_DEBUG 7 /* debug-level messages */ +#define SysLog(_level, fmt, ...) \ + do{openlog("[JUDGE]", LOG_NDELAY | LOG_CONS | LOG_PID | LOG_PERROR , LOG_LOCAL5); \ + syslog(_level, "[%s:%d] " fmt "", __FILE__, __LINE__, ##__VA_ARGS__); \ + closelog();}while(0) + +extern void LogPrint(const int level,const char *proName,const char *func,const int line,const char *format, ...); +extern void BufPrint(const char *func,const int line, const char *pData, int iDataLen); + +#define cPrint(fmt, ...) do{fprintf(stderr, PRO_NAME "[%s:%d] " fmt "\r\n", __FILE__, __LINE__, ##__VA_ARGS__);}while(0) +#define dPrint(fmt, ...) do{fprintf(stderr, YELLOW PRO_NAME "[%s:%d] " fmt "\r\n" NONE, __FILE__, __LINE__, ##__VA_ARGS__);}while(0) +#define lPrint(DLevel, format, ...) LogPrint(DLevel, PRO_NAME, __FILE__, __LINE__,format, ##__VA_ARGS__) +#define bufPrint(pData, iDataLen) BufPrint(__FILE__, __LINE__, (const char *)pData, (int)iDataLen) + +#endif + diff --git a/study_clang/Mimic/test_messagequeue/include/CMain.h b/study_clang/Mimic/test_messagequeue/include/CMain.h new file mode 100644 index 0000000..97754ee --- /dev/null +++ b/study_clang/Mimic/test_messagequeue/include/CMain.h @@ -0,0 +1,37 @@ +/************************************************************************* + > File Name : ../include/CMain.h + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Thu 16 Jul 2020 11:32:23 AM CST + ************************************************************************/ + +#ifndef CMAIN_H +#define CMAIN_H + + #include "CJudgeUtils.h" + +class CMain : public CSingleton +{ +public: + CMain(); + ~CMain(); + + void Init(); + int MainProcess(); + int ReleaseSource(); + +private: + int StartThreadTasks(); + + static void *NosHostConfMsgRcvThread(void *args); + static void *NosKernelConfMsgRcvThread(void *args); + static void *NosStateRcvThread(void *args); + static void *NosSysInfoRcvThread(void *args); + static void *SendPluginsCtrlThread(void *args); + +}; + + +#endif + + diff --git a/study_clang/Mimic/test_messagequeue/include/CMessageQueue.h b/study_clang/Mimic/test_messagequeue/include/CMessageQueue.h new file mode 100644 index 0000000..05b0b70 --- /dev/null +++ b/study_clang/Mimic/test_messagequeue/include/CMessageQueue.h @@ -0,0 +1,244 @@ +/************************************************************************* + > File Name : ../include/CMessageQueue.h + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Thu 16 Jul 2020 11:35:11 AM CST + ************************************************************************/ + +#ifndef CMESSAGEQUEUE_H +#define CMESSAGEQUEUE_H +#include "CTypedef.h" +#include "CJudgeUtils.h" + +template +class CMessageQueue : public CSingleton > +{ +public: + CMessageQueue(); + ~CMessageQueue(); + + void push(T stData,Message_QueueType_E MessageType); + void pop(Message_QueueType_E MessageType); + T& front(Message_QueueType_E MessageType); + T& back(Message_QueueType_E MessageType); + int empty(Message_QueueType_E MessageType); + int size(Message_QueueType_E MessageType); + void remove(T stData, Message_QueueType_E MessageType); + +private: + + +private: + static const Message_QueueType_E m_MessageTypeE = MQT_CONFIG_E; + + pthread_mutex_t m_QueueMutex; + std::list m_queue; + + pthread_mutex_t ss_QueueMutex; + std::list q_SysState; + + pthread_mutex_t ps_QueueMutex; + std::list q_ProcessState; + + pthread_mutex_t fs_QueueMutex; + std::list q_FileState; + + pthread_mutex_t fn_QueueMutex; + std::list q_FileNum; + + pthread_mutex_t sl_QueueMutex; + std::list q_SysLog; +}; + + +template +CMessageQueue::CMessageQueue() +{ + pthread_mutex_init(&m_QueueMutex, NULL); + + pthread_mutex_init(&ss_QueueMutex, NULL); + pthread_mutex_init(&ps_QueueMutex, NULL); + pthread_mutex_init(&fs_QueueMutex, NULL); + pthread_mutex_init(&fn_QueueMutex, NULL); + pthread_mutex_init(&sl_QueueMutex, NULL); +} + +template +CMessageQueue::~CMessageQueue() +{ + pthread_mutex_destroy(&m_QueueMutex); + + pthread_mutex_destroy(&ss_QueueMutex); + pthread_mutex_destroy(&ps_QueueMutex); + pthread_mutex_destroy(&fs_QueueMutex); + pthread_mutex_destroy(&fn_QueueMutex); + pthread_mutex_destroy(&sl_QueueMutex); +} + +template +void CMessageQueue::push(T stData,Message_QueueType_E MessageType = m_MessageTypeE) +{ + switch(MessageType) + { +#define _MQT_PUSH(type, q, lock) \ + case MQT_##type##_E: \ + { \ + CMutexLockGuard MutexLock(lock##_QueueMutex); \ + q.push_back(stData); \ + break;\ + } + _MQT_PUSH(CONFIG, m_queue, m); + _MQT_PUSH(SYSTEM_STATE, q_SysState, ss); + _MQT_PUSH(PROCESS_STATE, q_ProcessState, ps); + _MQT_PUSH(FILE_STATE, q_FileState, fs); + _MQT_PUSH(FILE_NUM, q_FileNum, fn); + _MQT_PUSH(SYSTEM_LOG, q_SysLog, sl); +#undef _MQT_PUSH + default: + break; + } +} + +template +void CMessageQueue::pop(Message_QueueType_E MessageType = m_MessageTypeE) +{ + switch(MessageType) + { +#define _MQT_POP(type, q, lock ) \ + case MQT_##type##_E: \ + { \ + CMutexLockGuard MutexLock(lock##_QueueMutex); \ + q.pop_front(); \ + break; \ + } + _MQT_POP(CONFIG, m_queue, m); + _MQT_POP(SYSTEM_STATE, q_SysState, ss); + _MQT_POP(PROCESS_STATE, q_ProcessState, ps); + _MQT_POP(FILE_STATE, q_FileState, fs); + _MQT_POP(FILE_NUM, q_FileNum, fn); + _MQT_POP(SYSTEM_LOG, q_SysLog, sl); +#undef _MQT_POP + default: + break; + } + +} + +template +T& CMessageQueue::front(Message_QueueType_E MessageType = m_MessageTypeE) +{ + switch(MessageType) + { +#define _MQT_FRONT(type, q, lock) \ + case MQT_##type##_E: \ + { \ + CMutexLockGuard MutexLock(lock##_QueueMutex); \ + return q.front(); \ + } + _MQT_FRONT(CONFIG, m_queue, m); + _MQT_FRONT(SYSTEM_STATE, q_SysState, ss); + _MQT_FRONT(PROCESS_STATE, q_ProcessState, ps); + _MQT_FRONT(FILE_STATE, q_FileState, fs); + _MQT_FRONT(FILE_NUM, q_FileNum, fn); + _MQT_FRONT(SYSTEM_LOG, q_SysLog, sl); +#undef _MQT_FRONT + default: + return m_queue.front(); + } + +} + +template +T& CMessageQueue::back(Message_QueueType_E MessageType = m_MessageTypeE) +{ + switch(MessageType) + { +#define _MQT_BACK(type, q, lock) \ + case MQT_##type##_E: \ + { \ + CMutexLockGuard MutexLock(lock##_QueueMutex); \ + return q.back(); \ + } + _MQT_BACK(CONFIG, m_queue, m); + _MQT_BACK(SYSTEM_STATE, q_SysState, ss); + _MQT_BACK(PROCESS_STATE, q_ProcessState, ps); + _MQT_BACK(FILE_STATE, q_FileState, fs); + _MQT_BACK(FILE_NUM, q_FileNum, fn); + _MQT_BACK(SYSTEM_LOG, q_SysLog, sl); +#undef _MQT_BACK + default: + return m_queue.back(); + } +} + +template +int CMessageQueue::empty(Message_QueueType_E MessageType = m_MessageTypeE) +{ + switch(MessageType) + { +#define _MQT_EMPTY(type, q, lock) \ + case MQT_##type##_E: \ + { \ + CMutexLockGuard MutexLock(lock##_QueueMutex); \ + return q.empty(); \ + } + _MQT_EMPTY(CONFIG, m_queue, m); + _MQT_EMPTY(SYSTEM_STATE, q_SysState, ss); + _MQT_EMPTY(PROCESS_STATE, q_ProcessState, ps); + _MQT_EMPTY(FILE_STATE, q_FileState, fs); + _MQT_EMPTY(FILE_NUM, q_FileNum, fn); + _MQT_EMPTY(SYSTEM_LOG, q_SysLog, sl); +#undef _MQT_EMPTY + default: + return 0; + } + return 0; +} + +template +int CMessageQueue::size(Message_QueueType_E MessageType = m_MessageTypeE) +{ + switch(MessageType) + { +#define _MQT_SIZE(type, q, lock) \ + case MQT_##type##_E: \ + { \ + CMutexLockGuard MutexLock(lock##_QueueMutex); \ + return q.size(); \ + } + _MQT_SIZE(CONFIG, m_queue, m); + _MQT_SIZE(SYSTEM_STATE, q_SysState, ss); + _MQT_SIZE(PROCESS_STATE, q_ProcessState, ps); + _MQT_SIZE(FILE_STATE, q_FileState, fs); + _MQT_SIZE(FILE_NUM, q_FileNum, fn); + _MQT_SIZE(SYSTEM_LOG, q_SysLog, sl); +#undef _MQT_SIZE + default: + return 0; + } +} + +template +void CMessageQueue::remove(T stData, Message_QueueType_E MessageType = m_MessageTypeE) +{ + switch(MessageType) + { +#define _MQT_REMOVE(type, q, lock) \ + case MQT_##type##_E: \ + { \ + CMutexLockGuard MutexLock(lock##_QueueMutex); \ + return q.remove(stData); \ + } + _MQT_REMOVE(CONFIG, m_queue, m); + _MQT_REMOVE(SYSTEM_STATE, q_SysState, ss); + _MQT_REMOVE(PROCESS_STATE, q_ProcessState, ps); + _MQT_REMOVE(FILE_STATE, q_FileState, fs); + _MQT_REMOVE(FILE_NUM, q_FileNum, fn); + _MQT_REMOVE(SYSTEM_LOG, q_SysLog, sl); +#undef _MQT_REMOVE + default: + break; + } +} +#endif + diff --git a/study_clang/Mimic/test_messagequeue/include/CMysqlPool.h b/study_clang/Mimic/test_messagequeue/include/CMysqlPool.h new file mode 100644 index 0000000..472801f --- /dev/null +++ b/study_clang/Mimic/test_messagequeue/include/CMysqlPool.h @@ -0,0 +1,62 @@ +/************************************************************************* + > File Name : CMysqlPool.h + > Author : liuzhao + > EMail : liuzhao@comleader.com.cn + > Created Time : Fri 17 Jul 2020 09:40:09 AM CST + ************************************************************************/ + +#ifndef MYSQLPOOL_H +#define MYSQLPOOL_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "CJudgeUtils.h" + + +class MysqlPool : public CSingleton +{ + public: + MysqlPool(); + ~MysqlPool(); + std::map > executeSql(const char* sql);//sql语句的执行函数 + void setParameter( const char* _mysqlhost, + const char* _mysqluser, + const char* _mysqlpwd, + const char* _databasename, + unsigned int _port = 0, + const char* _socket = NULL, + unsigned long _client_flag = 0, + unsigned int MAX_CONNECT = 50 ); //设置数据库参数 + private: + MYSQL* createOneConnect(); //创建一个新的连接对象 + MYSQL* getOneConnect(); //获取一个连接对象 + void close(MYSQL* conn); //关闭连接对象 + bool isEmpty(); //连接池队列池是否为空 + MYSQL* poolFront(); //连接池队列的队头 + unsigned int poolSize(); //获取连接池的大小 + void poolPop(); //弹出连接池队列的队头 + private: + std::queue mysqlpool; //连接池队列 + const char* _mysqlhost; //mysql主机地址 + const char* _mysqluser; //mysql用户名 + const char* _mysqlpwd; //mysql密码 + const char* _databasename; //要使用的mysql数据库名字 + unsigned int _port; //mysql端口 + const char* _socket; //可以设置成Socket or Pipeline,通常设置为NULL + unsigned long _client_flag; //设置为0 + unsigned int MAX_CONNECT; //同时允许最大连接对象数量 + unsigned int connect_count; //目前连接池的连接对象数量 + static std::mutex objectlock; //对象锁 + static std::mutex poollock; //连接池锁 + static MysqlPool* mysqlpool_object; //类的对象 +}; + +#endif diff --git a/study_clang/Mimic/test_messagequeue/include/CNetManager.h b/study_clang/Mimic/test_messagequeue/include/CNetManager.h new file mode 100644 index 0000000..7dd57e2 --- /dev/null +++ b/study_clang/Mimic/test_messagequeue/include/CNetManager.h @@ -0,0 +1,98 @@ +/************************************************************************* + > File Name : CNetManager.h + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Fri 17 Jul 2020 09:31:31 AM CST + ************************************************************************/ + +#ifndef CNETMANAGER_H +#define CNETMANAGER_H + +#include +#include "CTypedef.h" +#include "CUdpServer.h" +#include "CUdpClient.h" +#include "CZeroMQ.h" +#include "CJudgeUtils.h" + +#define PORT_BIND_SET_HOST 10014 +#define PORT_BIND_GET_HOST 10013 +#define PORT_BIND_SET_KERNEL 10012 +#define PORT_BIND_GET_KERNEL 10011 + +#define PORT_SET_HOST 10004 +#define PORT_GET_HOST 10003 +#define PORT_SET_KERNEL 10002 +#define PORT_GET_KERNEL 10001 + +class CNetManager : public CSingleton +{ +public: + CNetManager(); + ~CNetManager(); + int RecvDataToConfManagerHost(void *pvBuff, unsigned int uiBuffLen); + int SendDataToConfManagerHost(const void *pvData, unsigned int uiDataLen); + + int RecvDataToConfManagerKernel(void *pvBuff, unsigned int uiBuffLen); + int SendDataToConfManagerKernel(const void *pvData, unsigned int uiDataLen); + + int SendHostDataToAllNos(const void *pvData, unsigned int uiDataLen); + int SendHostDataToNos(int iNosIdx, const void *pvData, unsigned int uiDataLen); + + int SendKernelDataToAllNos(const void *pvData, unsigned int uiDataLen); + int SendKernelDataToNos(int iNosIdx, const void *pvData, unsigned int uiDataLen); + + int SendDataToShd(const void *pvData, unsigned int uiDataLen); + int RecvDataFromShd(void *pvBuff, unsigned int uiBuffLen); + + int SendDataToPCtl(const void *pvData, unsigned int uiDataLen); + int RecvDataFromPCtl(void *pvBuff, unsigned int uiBuffLen); + + void RecvNosDataHost(); + void RecvNosDataKernel(); + + void RecvNosStateFromShd(); + int GetNosStateById(int iIdx); + + int SetNosNetInfoHost(unsigned int uiIdx, const SOCKADDR_IN_T *pstInfo); + int GetNosNetInfoHost(unsigned int uiIdx, SOCKADDR_IN_T *pstInfo); + + int SetNosNetInfoKernel(unsigned int uiIdx, const SOCKADDR_IN_T *pstInfo); + int GetNosNetInfoKernel(unsigned int uiIdx, SOCKADDR_IN_T *pstInfo); + + void TransNosHostData(); + void TransNosKernelData(); + + void SendPluginsCtrl(); + +private: + int GetNosIdxBySock(SOCKADDR_IN_T *pstSockAddrIn); + +private: + pthread_mutex_t m_NosNetInfoHostMutex; + pthread_mutex_t m_NosNetInfoKernelMutex; + + SOCKADDR_IN_T m_stNosNetInfoHost[NOS_MAX_NUM]; + SOCKADDR_IN_T m_stNosNetInfoKernel[NOS_MAX_NUM]; + + CUdpClient m_ConfigManagerHost; + CUdpClient m_ConfigManagerKernel; + + CUdpServer m_NosDataHost; + CUdpServer m_NosDataKernel; + + CZMQReqRep *m_pShdClient; + CZMQReqRep *m_pPCtlClient; + CZMQSubscriber *m_pNosStateSub; + + NosState_T m_stNosState[NOS_MAX_NUM]; + + CUdpServer m_NosHostTrans; + CUdpServer m_NosKernelTrans; + +}; + + +#endif /*CNETMANAGER_H*/ + + diff --git a/study_clang/Mimic/test_messagequeue/include/CSwitchCommon.h b/study_clang/Mimic/test_messagequeue/include/CSwitchCommon.h new file mode 100644 index 0000000..4247ac3 --- /dev/null +++ b/study_clang/Mimic/test_messagequeue/include/CSwitchCommon.h @@ -0,0 +1,97 @@ +/************************************************************************* + > File Name : CSwitchCommon.h + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Thu 23 Jul 2020 09:13:37 AM CST + ************************************************************************/ + +#ifndef CSWITCHCOMMON_H +#define CSWITCHCOMMON_H + +#define MAX_NOS_NUM 8 + +typedef enum Judge_Error_Code_E +{ + JUDGE_ALL_SUCCESS=0, /*接收到所有执行体消息,全部一致*/ + JUDGE_SUCC_WITH_TWO_STAGE, /*接收到所有执行体消息,有多数一致,但少数也一致*/ + JUDGE_SUCC_WITH_MANY_STAGE, /*接收到所有执行体消息,有多数一致,但有多个少数群体*/ + JUDGE_SUCC_WITH_TIMEOUT, /*未收到所有执行体消息,全部一致*/ + JUDGE_SUCC_WITH_TIMEOUT_TWO_STAGE, /*未收到所有执行体消息,有多数一致,但少数也一致*/ + JUDGE_SUCC_WITH_TIMEOUT_MANY_STAGE, /*未收到所有执行体消息,有多数一致,但有多个少数群体*/ + + JUDGE_ALL_FAIL_WITH_DIFF, /*收到所有执行体消息,全部不一致*/ + JUDGE_FAIL_WITH_TWO_STAGE, /*收到所有执行体消息,分为数目相同的两个群体*/ + JUDGE_FAIL_WITH_MANY_STAGE, /*收到所有执行体信息,分为多个少数群体*/ + JUDGE_FAIL_WITH_TIMEOUT, /*未收到所有执行体消息,达不到裁决条件*/ + JUDGE_FAIL_WITH_TIMEOUT_TWO_STAGE, /*未收到所有执行体消息,分为两个少数群体*/ + JUDGE_FAIL_WITH_TIMEOUT_MANY_STAGE, /*未收到所有执行体消息,分为多个少数群体*/ + + ERROR_CODE_MAX +}Judge_Error_Code_T; + +typedef struct Judge_Error_Msg_S +{ + Judge_Error_Code_T uiErrorCode; //错误代码 +#define NOS1_FLAG 1<<0 +#define NOS2_FLAG 1<<1 +#define NOS3_FLAG 1<<2 +#define NOS4_FLAG 1<<3 +#define NOS5_FLAG 1<<4 +#define NOS6_FLAG 1<<5 +#define NOS7_FLAG 1<<6 +#define NOS8_FLAG 1<<7 +#define NOS9_FLAG 1<<8 +#define NOS10_FLAG 1<<9 + uint uiNosIdx; + char szReserve[32]; +}Judge_Error_Msg_T; + +typedef enum Judge_Sys_Info_Error_Code_E +{ + JUDGE_EXCESSIVE_CPU_OCCUPY, /*CPU占用率偏高*/ + JUDGE_EXCESSIVE_MEM_OCCUPY, /*内存占用率偏高*/ + JUDGE_EXCESSIVE_TCP_SOCKET, /*TCP SOCKET连接数过多*/ + JUDGE_EXCESSIVE_PROGRESS, /*进程总数过多*/ + JUDGE_SOMEONE_BROKEN_INTO, /*执行体被登入*/ + JUDGE_EXCEPTION_SHELL, /*执行体运行了异常的shell命令*/ + JUDGE_EXCEPTION_USER, /*执行体系统用户账户信息发生变化*/ + JUDGE_EXCEPTION_GROUP, /*执行体系统用户组信息发生变化*/ + JUDGE_CHANGE_CRON, /*计划任务个数产生变动*/ + JUDGE_CHANGE_FILE_IN_PATH, /*PATH目录下文件个数产生变动*/ + JUDGE_CHANGE_FILE_IN_HOME, /*用户目录下文件个数产生变动*/ + JUDGE_EXCEPTION_APP, /*关键可执行文件被篡改*/ + JUDGE_EXCEPTION_AUTOSTART, /*开机自启文件被篡改*/ + JUDGE_EXCEPTION_MANAGER, /*管理进程被异常停止*/ + JUDGE_EXCEPTION_PROTOCOL, /*协议进程被异常停止*/ + JUDGE_EXCEPTION_LOCAL_CONFIG_MANAGER, /*本地配置管理器被异常停止*/ + JUDGE_EXCEPTION_FIREWALL, /*防火墙被异常关闭*/ + JUDGE_TIME_OUT /*某执行体状态信息上报超时*/ +}Judge_Sys_Info_Error_Code_T; + +typedef struct Judge_Sys_Info_Error_Msg_S +{ + Judge_Sys_Info_Error_Code_T uiErrorCode; //错误代码 +#define NOS1_FLAG 1<<0 +#define NOS2_FLAG 1<<1 +#define NOS3_FLAG 1<<2 +#define NOS4_FLAG 1<<3 +#define NOS5_FLAG 1<<4 +#define NOS6_FLAG 1<<5 +#define NOS7_FLAG 1<<6 +#define NOS8_FLAG 1<<7 +#define NOS9_FLAG 1<<8 +#define NOS10_FLAG 1<<9 + uint uiNosIdx; + char szReserve[32]; +}Judge_Sys_Info_Error_Msg_T; + +typedef enum { + HB_JUDGE_E = 1, + HB_SHD_E, + HB_MYSQL_E, + HB_WEB_E, + HB_CFG_MANAGER_E, + HB_MAX_E +}HEARBEAT_E; + +#endif /*CSWITCHCOMMON_H*/ diff --git a/study_clang/Mimic/test_messagequeue/include/CTypedef.h b/study_clang/Mimic/test_messagequeue/include/CTypedef.h new file mode 100644 index 0000000..41fb6e6 --- /dev/null +++ b/study_clang/Mimic/test_messagequeue/include/CTypedef.h @@ -0,0 +1,115 @@ +/************************************************************************* + > File Name : CTypedef.h + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Fri 17 Jul 2020 09:32:54 AM CST + ************************************************************************/ +#ifndef CTYPEDEF_H +#define CTYPEDEF_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include "CLog.h" +#include "CSwitchCommon.h" + +#ifndef MAX_NOS_NUM +#define NOS_MAX_NUM 8 +#else +#define NOS_MAX_NUM MAX_NOS_NUM +#endif + +#define CONF_FILE_PATH "./judge_conf.ini" + +typedef socklen_t SOCKLEN_T; +typedef struct timeval TIMEVAL_T; +typedef struct sockaddr SOCKADDR_T; +typedef struct sockaddr_in SOCKADDR_IN_T; + +typedef unsigned int uint; + +typedef struct +{ + unsigned int uiNosIdx; + TIMEVAL_T stRcvTime; + unsigned int uiDataLen; + unsigned int uiPort; + int iCmd; + unsigned char ucData[1024]; +}NosConfMsg_ST; + +typedef struct +{ + int iCmd; + unsigned char ucData[1024]; +}ConfJudgeMsg_ST; + +typedef struct +{ + unsigned int uiNosIdx; + unsigned char ucHost[16]; + int iState; // 2 start +}NosState_T; + +typedef struct +{ + uint uiType; // 1 + char szIp[32]; + uint uiCpuRate; + uint uiMemRate; + uint uiTcpEstablishNum; + uint uiRunningProcessNum; + uint uiCronNum; + char szPasswdMd5[16]; +}SystemState_T; + +typedef struct +{ + uint uiType; // 2 + char szIp[32]; + uint uiProcessId; + uint uiProcessState; +}ProcessState_T; + +typedef struct +{ + uint uiType; // 3 + char szIp[32]; + char szFileName[32]; // 被改动的文件名称 + char eventType[16]; // 监视被改动的文件 + char szFileMd5[32]; // 文件的md5值 +}FileState_T; + +typedef struct +{ + uint uiType; // 4 + char szIp[32]; + char szPath[32]; // 监控的的文件路径 + char szFileName[32]; // 增加或删除的文件夹名称 + uint uiFileNum; // 当前文件夹下文件数量 +}FileNum_T; + +typedef struct +{ + uint uiType; //5 + char szIp[32]; + char szLogFile[32]; + char szMsg[128]; +}SysLog_T; + +typedef enum MESSAGE_QUQUQ_TYPE_E{ + MQT_CONFIG_E = 1, + MQT_SYSTEM_STATE_E, + MQT_PROCESS_STATE_E, + MQT_FILE_NUM_E, + MQT_FILE_STATE_E, + MQT_SYSTEM_LOG_E +}Message_QueueType_E; + + +#endif diff --git a/study_clang/Mimic/test_messagequeue/include/CUdpClient.h b/study_clang/Mimic/test_messagequeue/include/CUdpClient.h new file mode 100644 index 0000000..b79c80d --- /dev/null +++ b/study_clang/Mimic/test_messagequeue/include/CUdpClient.h @@ -0,0 +1,44 @@ +/************************************************************************* + > File Name : CUdpClient.h + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Fri 17 Jul 2020 09:29:08 AM CST + ************************************************************************/ + +#ifndef CUDPCLIENT_H +#define CUDPCLIENT_H +#include "CTypedef.h" + + +class CUdpClient +{ +public: + CUdpClient(); + CUdpClient(const char *pcHost, unsigned int uiPort); + ~CUdpClient(); + + int CUdpRecvData(void *pcBuff, unsigned int uiBuffLen); + int CUdpSendData(const void *pcData, unsigned int uiDataLen); + int CUdpRecvData(void *pcBuff, unsigned int uiBuffLen, const char *pcHost, unsigned int uiPort); + int CUdpSendData(const void *pcData, unsigned int uiDataLen, const char *pcHost, unsigned int uiPort); + + int CUdpSetSendTimeout(unsigned int uiSeconds = 3); + int CUdpSetRecvTimeout(unsigned int uiSeconds = 3); + +private: + int CUdpSocket(); + int CUdpGetSockaddr(const char * pcHost, unsigned int uiPort, SOCKADDR_IN_T *pstSockaddr); + +private: + int m_iClientSock; + unsigned int m_uiPort; + unsigned char m_ucHost[16]; + SOCKADDR_IN_T m_stServerInfo; +}; + + + + + +#endif /*CUDPCLIENT_H*/ + diff --git a/study_clang/Mimic/test_messagequeue/include/CUdpServer.h b/study_clang/Mimic/test_messagequeue/include/CUdpServer.h new file mode 100644 index 0000000..4e2ddfe --- /dev/null +++ b/study_clang/Mimic/test_messagequeue/include/CUdpServer.h @@ -0,0 +1,32 @@ +/************************************************************************* + > File Name : CUdpServer.h + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Fri 17 Jul 2020 09:29:21 AM CST + ************************************************************************/ +#ifndef CUDPSERVER_H +#define CUDPSERVER_H + +#include "CTypedef.h" + + +class CUdpServer +{ +public: + CUdpServer(); + CUdpServer(unsigned int uiPort); + ~CUdpServer(); + + int CUdpSocket(); + int CUdpSocket(unsigned int uiPort); + int CUdpRecvData(void *pvBuff, unsigned int uiBuffLen, SOCKADDR_IN_T *pstClientInfo); + int CUdpSendData(const void *pvData, unsigned int uiDataLen, SOCKADDR_IN_T stClientInfo); + + +private: + int m_iSerSock; + unsigned int m_uiPort; +}; + +#endif /*CUDPSERVER_H*/ + diff --git a/study_clang/Mimic/test_messagequeue/include/CZeroMQ.h b/study_clang/Mimic/test_messagequeue/include/CZeroMQ.h new file mode 100644 index 0000000..b8ac2f5 --- /dev/null +++ b/study_clang/Mimic/test_messagequeue/include/CZeroMQ.h @@ -0,0 +1,53 @@ +/************************************************************************* + > File Name : CZeroMQ.h + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Fri 17 Jul 2020 09:30:51 AM CST + ************************************************************************/ + +#ifndef CZEROMQ_H +#define CZEROMQ_H +#include + +class CZMQSubscriber +{ +public: + explicit CZMQSubscriber(const char *pcAddrPort); + ~CZMQSubscriber(); + + int SetRecvTimeout(unsigned int uiSeconds = 3); + int RecvData(void *pvBuff, unsigned int uiBuffLen); + +private: + int SocketInit(); + +private: + void *m_pvSubCtx; + void *m_pvSubSock; + std::string m_strAddrPort; +}; + + +class CZMQReqRep +{ +public: + explicit CZMQReqRep(int iType, const char *pcAddrPort); + ~CZMQReqRep(); + + int RecvData(void *pvBuff, unsigned int uiBuffLen); + int SendData(const void *pvData, unsigned int uiDataLen); + int SetRecvTimeout(unsigned int uiSeconds = 3); + int SetSendTimeout(unsigned int uiSeconds = 3); + +private: + int SocketInit(); + +private: + int m_iType; + void *m_pvCtx; + void *m_pvSock; + std::string m_strAddrPort; +}; + +#endif /*CZEROMQ_H*/ + diff --git a/study_clang/Mimic/test_messagequeue/test b/study_clang/Mimic/test_messagequeue/test new file mode 100755 index 0000000..12d5885 Binary files /dev/null and b/study_clang/Mimic/test_messagequeue/test differ diff --git a/study_clang/Mimic/test_messagequeue/test.cpp b/study_clang/Mimic/test_messagequeue/test.cpp new file mode 100644 index 0000000..96d55e5 --- /dev/null +++ b/study_clang/Mimic/test_messagequeue/test.cpp @@ -0,0 +1,169 @@ +/************************************************************************* + > File Name : test.cpp + > Author : TL Song + > EMail : songtianlun@frytea.com + > Created Time : Thu 30 Jul 2020 01:34:32 PM CST + ************************************************************************/ + +#include +#include + + +#include "include/CMessageQueue.h" +#include "include/CTypedef.h" +#include "include/CLog.h" +#include "include/CMessageQueue.h" + +using std::cout; +using std::endl; + +void check() +{ + cout << "------------------ Check Message Queue--------------------" << endl; + cout << "---- M_MessageQueue :"; + cout << "队列空: " << CMessageQueue::Instance()->empty() << " ," + << "长度: " << CMessageQueue::Instance()->size() << " ," + << "队头: " << CMessageQueue::Instance()->front() << " ," + << "队尾: " << CMessageQueue::Instance()->back() << endl; + cout << "---- MQT_SYSTEM_STATE_E :"; + cout << "队列空: " << CMessageQueue::Instance()->empty(MQT_SYSTEM_STATE_E) << " ," + << "长度: " << CMessageQueue::Instance()->size(MQT_SYSTEM_STATE_E) << " ," + << "队头: " << CMessageQueue::Instance()->front(MQT_SYSTEM_STATE_E) << " ," + << "队尾: " << CMessageQueue::Instance()->back(MQT_SYSTEM_STATE_E) << endl; + cout << "---- MQT_PROCESS_STATE_E :"; + cout << "队列空: " << CMessageQueue::Instance()->empty(MQT_PROCESS_STATE_E) << " ," + << "长度: " << CMessageQueue::Instance()->size(MQT_PROCESS_STATE_E) << " ," + << "队头: " << CMessageQueue::Instance()->front(MQT_PROCESS_STATE_E) << " ," + << "队尾: " << CMessageQueue::Instance()->back(MQT_PROCESS_STATE_E) << endl; + cout << "---- MQT_FILE_STATE_E :"; + cout << "队列空: " << CMessageQueue::Instance()->empty(MQT_FILE_STATE_E) << " ," + << "长度: " << CMessageQueue::Instance()->size(MQT_FILE_STATE_E) << " ," + << "队头: " << CMessageQueue::Instance()->front(MQT_FILE_STATE_E) << " ," + << "队尾: " << CMessageQueue::Instance()->back(MQT_FILE_STATE_E) << endl; + cout << "---- MQT_FILE_NUM_E :"; + cout << "队列空: " << CMessageQueue::Instance()->empty(MQT_FILE_NUM_E) << " ," + << "长度: " << CMessageQueue::Instance()->size(MQT_FILE_NUM_E) << " ," + << "队头: " << CMessageQueue::Instance()->front(MQT_FILE_NUM_E) << " ," + << "队尾: " << CMessageQueue::Instance()->back(MQT_FILE_NUM_E) << endl; + cout << "---- MQT_SYSTEM_LOG_E :"; + cout << "队列空: " << CMessageQueue::Instance()->empty(MQT_SYSTEM_LOG_E) << " ," + << "长度: " << CMessageQueue::Instance()->size(MQT_SYSTEM_LOG_E) << " ," + << "队头: " << CMessageQueue::Instance()->front(MQT_SYSTEM_LOG_E) << " ," + << "队尾: " << CMessageQueue::Instance()->back(MQT_SYSTEM_LOG_E) << endl; + cout << "------------------------- FINISH -------------------------" << endl; +} + +void* testPush(void *args) +{ + int i=0; + while(true) + { + cout << "PushTid1=" << std::this_thread::get_id(); + + CMessageQueue::Instance()->push(i,MQT_FILE_NUM_E); + cout << " -> Push: " << i << ", Size After Push : " << CMessageQueue::Instance()->size(MQT_FILE_NUM_E) << endl; + sleep(1); + i++; + } + return NULL; +} + +void* testPop(void *args) +{ + while(!CMessageQueue::Instance()->empty(MQT_FILE_NUM_E)) + { + cout << "PopTid2" << std::this_thread::get_id(); + // cout << " -> Before Pop : " << CMessageQueue::Instance()->front() << endl; + CMessageQueue::Instance()->pop(MQT_FILE_NUM_E); + // cout << " -> After Pop : " << CMessageQueue::Instance()->front() << endl; + cout << " -> Queue Front: " << CMessageQueue::Instance()->front(MQT_FILE_NUM_E) <<", Size After Pop: " << CMessageQueue::Instance()->size(MQT_FILE_NUM_E) << endl; + sleep(1); + } + cout << "Message queue empty, return!" << endl; + return NULL; +} + +void clean() +{ + while(!CMessageQueue::Instance()->empty(MQT_FILE_NUM_E)) + { + CMessageQueue::Instance()->pop(MQT_FILE_NUM_E); + } +} + +int main() +{ + cout << "step1: 默认队列入队3元素: 1 2 3" << endl; + for(int i=1;i<4;i++) + { + CMessageQueue::Instance()->push(i); + } + check(); + sleep(1); + + cout << "step2: MQT_SYSTEM_STATE_E 队列入队3元素: 4 5 6" << endl; + for(int i=4;i<7;i++) + { + CMessageQueue::Instance()->push(i,MQT_SYSTEM_STATE_E); + } + check(); + // sleep(1); + + cout << "step3: MQT_PROCESS_STATE_E 队列入队3元素: 7 8 9" << endl; + for(int i=7;i<10;i++) + { + CMessageQueue::Instance()->push(i, MQT_PROCESS_STATE_E); + } + check(); + // sleep(1); + + cout << "step4: MQT_FILE_STATE_E 队列入队3元素: 10 11 12" << endl; + for(int i=10;i<13;i++) + { + CMessageQueue::Instance()->push(i, MQT_FILE_STATE_E); + } + check(); + // sleep(1); + + cout << "step5: MQT_FILE_NUM_E 队列入队3元素: 13 14 15" << endl; + for(int i=13;i<16;i++) + { + CMessageQueue::Instance()->push(i, MQT_FILE_NUM_E); + } + check(); + // sleep(1); + + cout << "step6: MQT_SYSTEM_LOG_E 队列入队3元素: 16 17 18" << endl; + for(int i=16;i<19;i++) + { + CMessageQueue::Instance()->push(i, MQT_SYSTEM_LOG_E); + } + check(); + // sleep(1); + + clean(); + + cout << "队列已清空!" << endl; + + cout << "step7: 多线程同时出、入" << endl; + + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); //设置线程可分离 + + cout << "Start while() test Push---------------------" << endl; + pthread_t ttestPush; + pthread_create(&ttestPush, NULL, testPush, NULL); + + sleep(10); + cout << "Start while() test Pop---------------------" << endl; + pthread_t ttestPop; + pthread_create(&ttestPop, NULL, testPop, NULL); + + pthread_join(ttestPush,NULL); // 等待线程结束 + pthread_join(ttestPop,NULL); // 等待线程结束 + + + return 0; +} + diff --git a/study_clang/Mimic/test_messagequeue/test.i b/study_clang/Mimic/test_messagequeue/test.i new file mode 100644 index 0000000..a85a9ed --- /dev/null +++ b/study_clang/Mimic/test_messagequeue/test.i @@ -0,0 +1,33194 @@ +# 1 "test.cpp" +# 1 "" +# 1 "" +# 1 "/usr/include/stdc-predef.h" 1 3 4 +# 1 "" 2 +# 1 "test.cpp" + + + + + + + +# 1 "/usr/include/c++/4.8.2/iostream" 1 3 +# 36 "/usr/include/c++/4.8.2/iostream" 3 + +# 37 "/usr/include/c++/4.8.2/iostream" 3 + +# 1 "/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/c++config.h" 1 3 + + +# 1 "/usr/include/bits/wordsize.h" 1 3 4 +# 4 "/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/c++config.h" 2 3 +# 1855 "/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/c++config.h" 3 +namespace std +{ + typedef long unsigned int size_t; + typedef long int ptrdiff_t; + + + + +} +# 2097 "/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/c++config.h" 3 +# 1 "/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/os_defines.h" 1 3 +# 39 "/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/os_defines.h" 3 +# 1 "/usr/include/features.h" 1 3 4 +# 375 "/usr/include/features.h" 3 4 +# 1 "/usr/include/sys/cdefs.h" 1 3 4 +# 392 "/usr/include/sys/cdefs.h" 3 4 +# 1 "/usr/include/bits/wordsize.h" 1 3 4 +# 393 "/usr/include/sys/cdefs.h" 2 3 4 +# 376 "/usr/include/features.h" 2 3 4 +# 399 "/usr/include/features.h" 3 4 +# 1 "/usr/include/gnu/stubs.h" 1 3 4 +# 10 "/usr/include/gnu/stubs.h" 3 4 +# 1 "/usr/include/gnu/stubs-64.h" 1 3 4 +# 11 "/usr/include/gnu/stubs.h" 2 3 4 +# 400 "/usr/include/features.h" 2 3 4 +# 40 "/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/os_defines.h" 2 3 +# 2098 "/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/c++config.h" 2 3 + + +# 1 "/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/cpu_defines.h" 1 3 +# 2101 "/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/c++config.h" 2 3 +# 39 "/usr/include/c++/4.8.2/iostream" 2 3 +# 1 "/usr/include/c++/4.8.2/ostream" 1 3 +# 36 "/usr/include/c++/4.8.2/ostream" 3 + +# 37 "/usr/include/c++/4.8.2/ostream" 3 + +# 1 "/usr/include/c++/4.8.2/ios" 1 3 +# 36 "/usr/include/c++/4.8.2/ios" 3 + +# 37 "/usr/include/c++/4.8.2/ios" 3 + +# 1 "/usr/include/c++/4.8.2/iosfwd" 1 3 +# 36 "/usr/include/c++/4.8.2/iosfwd" 3 + +# 37 "/usr/include/c++/4.8.2/iosfwd" 3 + + +# 1 "/usr/include/c++/4.8.2/bits/stringfwd.h" 1 3 +# 37 "/usr/include/c++/4.8.2/bits/stringfwd.h" 3 + +# 38 "/usr/include/c++/4.8.2/bits/stringfwd.h" 3 + + +# 1 "/usr/include/c++/4.8.2/bits/memoryfwd.h" 1 3 +# 46 "/usr/include/c++/4.8.2/bits/memoryfwd.h" 3 + +# 47 "/usr/include/c++/4.8.2/bits/memoryfwd.h" 3 + + + +namespace std __attribute__ ((__visibility__ ("default"))) +{ + +# 63 "/usr/include/c++/4.8.2/bits/memoryfwd.h" 3 + template + class allocator; + + template<> + class allocator; + + + template + struct uses_allocator; + + + + +} +# 41 "/usr/include/c++/4.8.2/bits/stringfwd.h" 2 3 + +namespace std __attribute__ ((__visibility__ ("default"))) +{ + + + + + + + + + template + struct char_traits; + + template, + typename _Alloc = allocator<_CharT> > + class basic_string; + + template<> struct char_traits; + + + typedef basic_string string; + + + template<> struct char_traits; + + + typedef basic_string wstring; +# 86 "/usr/include/c++/4.8.2/bits/stringfwd.h" 3 + +} +# 40 "/usr/include/c++/4.8.2/iosfwd" 2 3 +# 1 "/usr/include/c++/4.8.2/bits/postypes.h" 1 3 +# 38 "/usr/include/c++/4.8.2/bits/postypes.h" 3 + +# 39 "/usr/include/c++/4.8.2/bits/postypes.h" 3 + +# 1 "/usr/include/c++/4.8.2/cwchar" 1 3 +# 39 "/usr/include/c++/4.8.2/cwchar" 3 + +# 40 "/usr/include/c++/4.8.2/cwchar" 3 + + + + +# 1 "/usr/include/wchar.h" 1 3 4 +# 36 "/usr/include/wchar.h" 3 4 +# 1 "/usr/include/stdio.h" 1 3 4 +# 44 "/usr/include/stdio.h" 3 4 +struct _IO_FILE; + + + +typedef struct _IO_FILE FILE; + + + + + +# 64 "/usr/include/stdio.h" 3 4 +typedef struct _IO_FILE __FILE; +# 37 "/usr/include/wchar.h" 2 3 4 + + +# 1 "/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stdarg.h" 1 3 4 +# 40 "/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stdarg.h" 3 4 +typedef __builtin_va_list __gnuc_va_list; +# 40 "/usr/include/wchar.h" 2 3 4 + +# 1 "/usr/include/bits/wchar.h" 1 3 4 +# 22 "/usr/include/bits/wchar.h" 3 4 +# 1 "/usr/include/bits/wordsize.h" 1 3 4 +# 23 "/usr/include/bits/wchar.h" 2 3 4 +# 42 "/usr/include/wchar.h" 2 3 4 +# 51 "/usr/include/wchar.h" 3 4 +# 1 "/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stddef.h" 1 3 4 +# 212 "/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stddef.h" 3 4 +typedef long unsigned int size_t; +# 353 "/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stddef.h" 3 4 +typedef unsigned int wint_t; +# 52 "/usr/include/wchar.h" 2 3 4 +# 82 "/usr/include/wchar.h" 3 4 +typedef struct +{ + int __count; + union + { + + unsigned int __wch; + + + + char __wchb[4]; + } __value; +} __mbstate_t; +# 104 "/usr/include/wchar.h" 3 4 + + +typedef __mbstate_t mbstate_t; + + + + + + +# 132 "/usr/include/wchar.h" 3 4 +extern "C" { + + + + +struct tm; + + + + + + + + + +extern wchar_t *wcscpy (wchar_t *__restrict __dest, + const wchar_t *__restrict __src) throw (); + +extern wchar_t *wcsncpy (wchar_t *__restrict __dest, + const wchar_t *__restrict __src, size_t __n) + throw (); + + +extern wchar_t *wcscat (wchar_t *__restrict __dest, + const wchar_t *__restrict __src) throw (); + +extern wchar_t *wcsncat (wchar_t *__restrict __dest, + const wchar_t *__restrict __src, size_t __n) + throw (); + + +extern int wcscmp (const wchar_t *__s1, const wchar_t *__s2) + throw () __attribute__ ((__pure__)); + +extern int wcsncmp (const wchar_t *__s1, const wchar_t *__s2, size_t __n) + throw () __attribute__ ((__pure__)); + + + + +extern int wcscasecmp (const wchar_t *__s1, const wchar_t *__s2) throw (); + + +extern int wcsncasecmp (const wchar_t *__s1, const wchar_t *__s2, + size_t __n) throw (); + + + +# 1 "/usr/include/xlocale.h" 1 3 4 +# 27 "/usr/include/xlocale.h" 3 4 +typedef struct __locale_struct +{ + + struct __locale_data *__locales[13]; + + + const unsigned short int *__ctype_b; + const int *__ctype_tolower; + const int *__ctype_toupper; + + + const char *__names[13]; +} *__locale_t; + + +typedef __locale_t locale_t; +# 181 "/usr/include/wchar.h" 2 3 4 + +extern int wcscasecmp_l (const wchar_t *__s1, const wchar_t *__s2, + __locale_t __loc) throw (); + +extern int wcsncasecmp_l (const wchar_t *__s1, const wchar_t *__s2, + size_t __n, __locale_t __loc) throw (); + + + + + +extern int wcscoll (const wchar_t *__s1, const wchar_t *__s2) throw (); + + + +extern size_t wcsxfrm (wchar_t *__restrict __s1, + const wchar_t *__restrict __s2, size_t __n) throw (); + + + + + + + + +extern int wcscoll_l (const wchar_t *__s1, const wchar_t *__s2, + __locale_t __loc) throw (); + + + + +extern size_t wcsxfrm_l (wchar_t *__s1, const wchar_t *__s2, + size_t __n, __locale_t __loc) throw (); + + +extern wchar_t *wcsdup (const wchar_t *__s) throw () __attribute__ ((__malloc__)); + + + + + +extern "C++" wchar_t *wcschr (wchar_t *__wcs, wchar_t __wc) + throw () __asm ("wcschr") __attribute__ ((__pure__)); +extern "C++" const wchar_t *wcschr (const wchar_t *__wcs, wchar_t __wc) + throw () __asm ("wcschr") __attribute__ ((__pure__)); + + + + + + +extern "C++" wchar_t *wcsrchr (wchar_t *__wcs, wchar_t __wc) + throw () __asm ("wcsrchr") __attribute__ ((__pure__)); +extern "C++" const wchar_t *wcsrchr (const wchar_t *__wcs, wchar_t __wc) + throw () __asm ("wcsrchr") __attribute__ ((__pure__)); + + + + + + + + + +extern wchar_t *wcschrnul (const wchar_t *__s, wchar_t __wc) + throw () __attribute__ ((__pure__)); + + + + + +extern size_t wcscspn (const wchar_t *__wcs, const wchar_t *__reject) + throw () __attribute__ ((__pure__)); + + +extern size_t wcsspn (const wchar_t *__wcs, const wchar_t *__accept) + throw () __attribute__ ((__pure__)); + + +extern "C++" wchar_t *wcspbrk (wchar_t *__wcs, const wchar_t *__accept) + throw () __asm ("wcspbrk") __attribute__ ((__pure__)); +extern "C++" const wchar_t *wcspbrk (const wchar_t *__wcs, + const wchar_t *__accept) + throw () __asm ("wcspbrk") __attribute__ ((__pure__)); + + + + + + +extern "C++" wchar_t *wcsstr (wchar_t *__haystack, const wchar_t *__needle) + throw () __asm ("wcsstr") __attribute__ ((__pure__)); +extern "C++" const wchar_t *wcsstr (const wchar_t *__haystack, + const wchar_t *__needle) + throw () __asm ("wcsstr") __attribute__ ((__pure__)); + + + + + + +extern wchar_t *wcstok (wchar_t *__restrict __s, + const wchar_t *__restrict __delim, + wchar_t **__restrict __ptr) throw (); + + +extern size_t wcslen (const wchar_t *__s) throw () __attribute__ ((__pure__)); + + + + + +extern "C++" wchar_t *wcswcs (wchar_t *__haystack, const wchar_t *__needle) + throw () __asm ("wcswcs") __attribute__ ((__pure__)); +extern "C++" const wchar_t *wcswcs (const wchar_t *__haystack, + const wchar_t *__needle) + throw () __asm ("wcswcs") __attribute__ ((__pure__)); +# 306 "/usr/include/wchar.h" 3 4 +extern size_t wcsnlen (const wchar_t *__s, size_t __maxlen) + throw () __attribute__ ((__pure__)); + + + + + + +extern "C++" wchar_t *wmemchr (wchar_t *__s, wchar_t __c, size_t __n) + throw () __asm ("wmemchr") __attribute__ ((__pure__)); +extern "C++" const wchar_t *wmemchr (const wchar_t *__s, wchar_t __c, + size_t __n) + throw () __asm ("wmemchr") __attribute__ ((__pure__)); + + + + + + +extern int wmemcmp (const wchar_t *__s1, const wchar_t *__s2, size_t __n) + throw () __attribute__ ((__pure__)); + + +extern wchar_t *wmemcpy (wchar_t *__restrict __s1, + const wchar_t *__restrict __s2, size_t __n) throw (); + + + +extern wchar_t *wmemmove (wchar_t *__s1, const wchar_t *__s2, size_t __n) + throw (); + + +extern wchar_t *wmemset (wchar_t *__s, wchar_t __c, size_t __n) throw (); + + + + + +extern wchar_t *wmempcpy (wchar_t *__restrict __s1, + const wchar_t *__restrict __s2, size_t __n) + throw (); + + + + + + +extern wint_t btowc (int __c) throw (); + + + +extern int wctob (wint_t __c) throw (); + + + +extern int mbsinit (const mbstate_t *__ps) throw () __attribute__ ((__pure__)); + + + +extern size_t mbrtowc (wchar_t *__restrict __pwc, + const char *__restrict __s, size_t __n, + mbstate_t *__restrict __p) throw (); + + +extern size_t wcrtomb (char *__restrict __s, wchar_t __wc, + mbstate_t *__restrict __ps) throw (); + + +extern size_t __mbrlen (const char *__restrict __s, size_t __n, + mbstate_t *__restrict __ps) throw (); +extern size_t mbrlen (const char *__restrict __s, size_t __n, + mbstate_t *__restrict __ps) throw (); + +# 405 "/usr/include/wchar.h" 3 4 + + + +extern size_t mbsrtowcs (wchar_t *__restrict __dst, + const char **__restrict __src, size_t __len, + mbstate_t *__restrict __ps) throw (); + + + +extern size_t wcsrtombs (char *__restrict __dst, + const wchar_t **__restrict __src, size_t __len, + mbstate_t *__restrict __ps) throw (); + + + + + + +extern size_t mbsnrtowcs (wchar_t *__restrict __dst, + const char **__restrict __src, size_t __nmc, + size_t __len, mbstate_t *__restrict __ps) throw (); + + + +extern size_t wcsnrtombs (char *__restrict __dst, + const wchar_t **__restrict __src, + size_t __nwc, size_t __len, + mbstate_t *__restrict __ps) throw (); + + + + + + +extern int wcwidth (wchar_t __c) throw (); + + + +extern int wcswidth (const wchar_t *__s, size_t __n) throw (); + + + + + + +extern double wcstod (const wchar_t *__restrict __nptr, + wchar_t **__restrict __endptr) throw (); + + + + + +extern float wcstof (const wchar_t *__restrict __nptr, + wchar_t **__restrict __endptr) throw (); +extern long double wcstold (const wchar_t *__restrict __nptr, + wchar_t **__restrict __endptr) throw (); + + + + + + + +extern long int wcstol (const wchar_t *__restrict __nptr, + wchar_t **__restrict __endptr, int __base) throw (); + + + +extern unsigned long int wcstoul (const wchar_t *__restrict __nptr, + wchar_t **__restrict __endptr, int __base) + throw (); + + + + + + +__extension__ +extern long long int wcstoll (const wchar_t *__restrict __nptr, + wchar_t **__restrict __endptr, int __base) + throw (); + + + +__extension__ +extern unsigned long long int wcstoull (const wchar_t *__restrict __nptr, + wchar_t **__restrict __endptr, + int __base) throw (); + + + + + + +__extension__ +extern long long int wcstoq (const wchar_t *__restrict __nptr, + wchar_t **__restrict __endptr, int __base) + throw (); + + + +__extension__ +extern unsigned long long int wcstouq (const wchar_t *__restrict __nptr, + wchar_t **__restrict __endptr, + int __base) throw (); +# 530 "/usr/include/wchar.h" 3 4 +extern long int wcstol_l (const wchar_t *__restrict __nptr, + wchar_t **__restrict __endptr, int __base, + __locale_t __loc) throw (); + +extern unsigned long int wcstoul_l (const wchar_t *__restrict __nptr, + wchar_t **__restrict __endptr, + int __base, __locale_t __loc) throw (); + +__extension__ +extern long long int wcstoll_l (const wchar_t *__restrict __nptr, + wchar_t **__restrict __endptr, + int __base, __locale_t __loc) throw (); + +__extension__ +extern unsigned long long int wcstoull_l (const wchar_t *__restrict __nptr, + wchar_t **__restrict __endptr, + int __base, __locale_t __loc) + throw (); + +extern double wcstod_l (const wchar_t *__restrict __nptr, + wchar_t **__restrict __endptr, __locale_t __loc) + throw (); + +extern float wcstof_l (const wchar_t *__restrict __nptr, + wchar_t **__restrict __endptr, __locale_t __loc) + throw (); + +extern long double wcstold_l (const wchar_t *__restrict __nptr, + wchar_t **__restrict __endptr, + __locale_t __loc) throw (); + + + + + + +extern wchar_t *wcpcpy (wchar_t *__restrict __dest, + const wchar_t *__restrict __src) throw (); + + + +extern wchar_t *wcpncpy (wchar_t *__restrict __dest, + const wchar_t *__restrict __src, size_t __n) + throw (); + + + + + + +extern __FILE *open_wmemstream (wchar_t **__bufloc, size_t *__sizeloc) throw (); + + + + + + +extern int fwide (__FILE *__fp, int __mode) throw (); + + + + + + +extern int fwprintf (__FILE *__restrict __stream, + const wchar_t *__restrict __format, ...) + ; + + + + +extern int wprintf (const wchar_t *__restrict __format, ...) + ; + +extern int swprintf (wchar_t *__restrict __s, size_t __n, + const wchar_t *__restrict __format, ...) + throw () ; + + + + + +extern int vfwprintf (__FILE *__restrict __s, + const wchar_t *__restrict __format, + __gnuc_va_list __arg) + ; + + + + +extern int vwprintf (const wchar_t *__restrict __format, + __gnuc_va_list __arg) + ; + + +extern int vswprintf (wchar_t *__restrict __s, size_t __n, + const wchar_t *__restrict __format, + __gnuc_va_list __arg) + throw () ; + + + + + + +extern int fwscanf (__FILE *__restrict __stream, + const wchar_t *__restrict __format, ...) + ; + + + + +extern int wscanf (const wchar_t *__restrict __format, ...) + ; + +extern int swscanf (const wchar_t *__restrict __s, + const wchar_t *__restrict __format, ...) + throw () ; +# 680 "/usr/include/wchar.h" 3 4 + + + + + + + + + +extern int vfwscanf (__FILE *__restrict __s, + const wchar_t *__restrict __format, + __gnuc_va_list __arg) + ; + + + + +extern int vwscanf (const wchar_t *__restrict __format, + __gnuc_va_list __arg) + ; + +extern int vswscanf (const wchar_t *__restrict __s, + const wchar_t *__restrict __format, + __gnuc_va_list __arg) + throw () ; +# 736 "/usr/include/wchar.h" 3 4 + + + + + + + + + +extern wint_t fgetwc (__FILE *__stream); +extern wint_t getwc (__FILE *__stream); + + + + + +extern wint_t getwchar (void); + + + + + + +extern wint_t fputwc (wchar_t __wc, __FILE *__stream); +extern wint_t putwc (wchar_t __wc, __FILE *__stream); + + + + + +extern wint_t putwchar (wchar_t __wc); + + + + + + + +extern wchar_t *fgetws (wchar_t *__restrict __ws, int __n, + __FILE *__restrict __stream); + + + + + +extern int fputws (const wchar_t *__restrict __ws, + __FILE *__restrict __stream); + + + + + + +extern wint_t ungetwc (wint_t __wc, __FILE *__stream); + +# 801 "/usr/include/wchar.h" 3 4 +extern wint_t getwc_unlocked (__FILE *__stream); +extern wint_t getwchar_unlocked (void); + + + + + + + +extern wint_t fgetwc_unlocked (__FILE *__stream); + + + + + + + +extern wint_t fputwc_unlocked (wchar_t __wc, __FILE *__stream); +# 827 "/usr/include/wchar.h" 3 4 +extern wint_t putwc_unlocked (wchar_t __wc, __FILE *__stream); +extern wint_t putwchar_unlocked (wchar_t __wc); +# 837 "/usr/include/wchar.h" 3 4 +extern wchar_t *fgetws_unlocked (wchar_t *__restrict __ws, int __n, + __FILE *__restrict __stream); + + + + + + + +extern int fputws_unlocked (const wchar_t *__restrict __ws, + __FILE *__restrict __stream); + + + + + + + +extern size_t wcsftime (wchar_t *__restrict __s, size_t __maxsize, + const wchar_t *__restrict __format, + const struct tm *__restrict __tp) throw (); + + + + + + + +extern size_t wcsftime_l (wchar_t *__restrict __s, size_t __maxsize, + const wchar_t *__restrict __format, + const struct tm *__restrict __tp, + __locale_t __loc) throw (); +# 891 "/usr/include/wchar.h" 3 4 +} +# 45 "/usr/include/c++/4.8.2/cwchar" 2 3 +# 62 "/usr/include/c++/4.8.2/cwchar" 3 +namespace std +{ + using ::mbstate_t; +} +# 135 "/usr/include/c++/4.8.2/cwchar" 3 +namespace std __attribute__ ((__visibility__ ("default"))) +{ + + + using ::wint_t; + + using ::btowc; + using ::fgetwc; + using ::fgetws; + using ::fputwc; + using ::fputws; + using ::fwide; + using ::fwprintf; + using ::fwscanf; + using ::getwc; + using ::getwchar; + using ::mbrlen; + using ::mbrtowc; + using ::mbsinit; + using ::mbsrtowcs; + using ::putwc; + using ::putwchar; + + using ::swprintf; + + using ::swscanf; + using ::ungetwc; + using ::vfwprintf; + + using ::vfwscanf; + + + using ::vswprintf; + + + using ::vswscanf; + + using ::vwprintf; + + using ::vwscanf; + + using ::wcrtomb; + using ::wcscat; + using ::wcscmp; + using ::wcscoll; + using ::wcscpy; + using ::wcscspn; + using ::wcsftime; + using ::wcslen; + using ::wcsncat; + using ::wcsncmp; + using ::wcsncpy; + using ::wcsrtombs; + using ::wcsspn; + using ::wcstod; + + using ::wcstof; + + using ::wcstok; + using ::wcstol; + using ::wcstoul; + using ::wcsxfrm; + using ::wctob; + using ::wmemcmp; + using ::wmemcpy; + using ::wmemmove; + using ::wmemset; + using ::wprintf; + using ::wscanf; + using ::wcschr; + using ::wcspbrk; + using ::wcsrchr; + using ::wcsstr; + using ::wmemchr; +# 232 "/usr/include/c++/4.8.2/cwchar" 3 + +} + + + + + + + +namespace __gnu_cxx +{ + + + + + + using ::wcstold; +# 257 "/usr/include/c++/4.8.2/cwchar" 3 + using ::wcstoll; + using ::wcstoull; + +} + +namespace std +{ + using ::__gnu_cxx::wcstold; + using ::__gnu_cxx::wcstoll; + using ::__gnu_cxx::wcstoull; +} +# 41 "/usr/include/c++/4.8.2/bits/postypes.h" 2 3 +# 68 "/usr/include/c++/4.8.2/bits/postypes.h" 3 +namespace std __attribute__ ((__visibility__ ("default"))) +{ + +# 88 "/usr/include/c++/4.8.2/bits/postypes.h" 3 + typedef long streamoff; +# 98 "/usr/include/c++/4.8.2/bits/postypes.h" 3 + typedef ptrdiff_t streamsize; +# 111 "/usr/include/c++/4.8.2/bits/postypes.h" 3 + template + class fpos + { + private: + streamoff _M_off; + _StateT _M_state; + + public: + + + + + fpos() + : _M_off(0), _M_state() { } +# 133 "/usr/include/c++/4.8.2/bits/postypes.h" 3 + fpos(streamoff __off) + : _M_off(__off), _M_state() { } + + + operator streamoff() const { return _M_off; } + + + void + state(_StateT __st) + { _M_state = __st; } + + + _StateT + state() const + { return _M_state; } + + + + + + fpos& + operator+=(streamoff __off) + { + _M_off += __off; + return *this; + } + + + + + + fpos& + operator-=(streamoff __off) + { + _M_off -= __off; + return *this; + } + + + + + + + + fpos + operator+(streamoff __off) const + { + fpos __pos(*this); + __pos += __off; + return __pos; + } + + + + + + + + fpos + operator-(streamoff __off) const + { + fpos __pos(*this); + __pos -= __off; + return __pos; + } + + + + + + + streamoff + operator-(const fpos& __other) const + { return _M_off - __other._M_off; } + }; + + + + + + + template + inline bool + operator==(const fpos<_StateT>& __lhs, const fpos<_StateT>& __rhs) + { return streamoff(__lhs) == streamoff(__rhs); } + + template + inline bool + operator!=(const fpos<_StateT>& __lhs, const fpos<_StateT>& __rhs) + { return streamoff(__lhs) != streamoff(__rhs); } + + + + + + typedef fpos streampos; + + typedef fpos wstreampos; +# 239 "/usr/include/c++/4.8.2/bits/postypes.h" 3 + +} +# 41 "/usr/include/c++/4.8.2/iosfwd" 2 3 + +namespace std __attribute__ ((__visibility__ ("default"))) +{ + +# 74 "/usr/include/c++/4.8.2/iosfwd" 3 + class ios_base; + + template > + class basic_ios; + + template > + class basic_streambuf; + + template > + class basic_istream; + + template > + class basic_ostream; + + template > + class basic_iostream; + + template, + typename _Alloc = allocator<_CharT> > + class basic_stringbuf; + + template, + typename _Alloc = allocator<_CharT> > + class basic_istringstream; + + template, + typename _Alloc = allocator<_CharT> > + class basic_ostringstream; + + template, + typename _Alloc = allocator<_CharT> > + class basic_stringstream; + + template > + class basic_filebuf; + + template > + class basic_ifstream; + + template > + class basic_ofstream; + + template > + class basic_fstream; + + template > + class istreambuf_iterator; + + template > + class ostreambuf_iterator; + + + + typedef basic_ios ios; + + + typedef basic_streambuf streambuf; + + + typedef basic_istream istream; + + + typedef basic_ostream ostream; + + + typedef basic_iostream iostream; + + + typedef basic_stringbuf stringbuf; + + + typedef basic_istringstream istringstream; + + + typedef basic_ostringstream ostringstream; + + + typedef basic_stringstream stringstream; + + + typedef basic_filebuf filebuf; + + + typedef basic_ifstream ifstream; + + + typedef basic_ofstream ofstream; + + + typedef basic_fstream fstream; + + + + typedef basic_ios wios; + + + typedef basic_streambuf wstreambuf; + + + typedef basic_istream wistream; + + + typedef basic_ostream wostream; + + + typedef basic_iostream wiostream; + + + typedef basic_stringbuf wstringbuf; + + + typedef basic_istringstream wistringstream; + + + typedef basic_ostringstream wostringstream; + + + typedef basic_stringstream wstringstream; + + + typedef basic_filebuf wfilebuf; + + + typedef basic_ifstream wifstream; + + + typedef basic_ofstream wofstream; + + + typedef basic_fstream wfstream; + + + + +} +# 39 "/usr/include/c++/4.8.2/ios" 2 3 +# 1 "/usr/include/c++/4.8.2/exception" 1 3 +# 33 "/usr/include/c++/4.8.2/exception" 3 + +# 34 "/usr/include/c++/4.8.2/exception" 3 + +#pragma GCC visibility push(default) + + +# 1 "/usr/include/c++/4.8.2/bits/atomic_lockfree_defines.h" 1 3 +# 33 "/usr/include/c++/4.8.2/bits/atomic_lockfree_defines.h" 3 + +# 34 "/usr/include/c++/4.8.2/bits/atomic_lockfree_defines.h" 3 +# 39 "/usr/include/c++/4.8.2/exception" 2 3 + +extern "C++" { + +namespace std +{ +# 60 "/usr/include/c++/4.8.2/exception" 3 + class exception + { + public: + exception() throw() { } + virtual ~exception() throw(); + + + + virtual const char* what() const throw(); + }; + + + + class bad_exception : public exception + { + public: + bad_exception() throw() { } + + + + virtual ~bad_exception() throw(); + + + virtual const char* what() const throw(); + }; + + + typedef void (*terminate_handler) (); + + + typedef void (*unexpected_handler) (); + + + terminate_handler set_terminate(terminate_handler) throw(); + + + + void terminate() throw() __attribute__ ((__noreturn__)); + + + unexpected_handler set_unexpected(unexpected_handler) throw(); + + + + void unexpected() __attribute__ ((__noreturn__)); +# 117 "/usr/include/c++/4.8.2/exception" 3 + bool uncaught_exception() throw() __attribute__ ((__pure__)); + + +} + +namespace __gnu_cxx +{ + +# 142 "/usr/include/c++/4.8.2/exception" 3 + void __verbose_terminate_handler(); + + +} + +} + +#pragma GCC visibility pop +# 40 "/usr/include/c++/4.8.2/ios" 2 3 +# 1 "/usr/include/c++/4.8.2/bits/char_traits.h" 1 3 +# 37 "/usr/include/c++/4.8.2/bits/char_traits.h" 3 + +# 38 "/usr/include/c++/4.8.2/bits/char_traits.h" 3 + +# 1 "/usr/include/c++/4.8.2/bits/stl_algobase.h" 1 3 +# 60 "/usr/include/c++/4.8.2/bits/stl_algobase.h" 3 +# 1 "/usr/include/c++/4.8.2/bits/functexcept.h" 1 3 +# 40 "/usr/include/c++/4.8.2/bits/functexcept.h" 3 +# 1 "/usr/include/c++/4.8.2/bits/exception_defines.h" 1 3 +# 41 "/usr/include/c++/4.8.2/bits/functexcept.h" 2 3 + +namespace std __attribute__ ((__visibility__ ("default"))) +{ + + + + void + __throw_bad_exception(void) __attribute__((__noreturn__)); + + + void + __throw_bad_alloc(void) __attribute__((__noreturn__)); + + + void + __throw_bad_cast(void) __attribute__((__noreturn__)); + + void + __throw_bad_typeid(void) __attribute__((__noreturn__)); + + + void + __throw_logic_error(const char*) __attribute__((__noreturn__)); + + void + __throw_domain_error(const char*) __attribute__((__noreturn__)); + + void + __throw_invalid_argument(const char*) __attribute__((__noreturn__)); + + void + __throw_length_error(const char*) __attribute__((__noreturn__)); + + void + __throw_out_of_range(const char*) __attribute__((__noreturn__)); + + void + __throw_runtime_error(const char*) __attribute__((__noreturn__)); + + void + __throw_range_error(const char*) __attribute__((__noreturn__)); + + void + __throw_overflow_error(const char*) __attribute__((__noreturn__)); + + void + __throw_underflow_error(const char*) __attribute__((__noreturn__)); + + + void + __throw_ios_failure(const char*) __attribute__((__noreturn__)); + + void + __throw_system_error(int) __attribute__((__noreturn__)); + + void + __throw_future_error(int) __attribute__((__noreturn__)); + + + void + __throw_bad_function_call() __attribute__((__noreturn__)); + + +} +# 61 "/usr/include/c++/4.8.2/bits/stl_algobase.h" 2 3 +# 1 "/usr/include/c++/4.8.2/bits/cpp_type_traits.h" 1 3 +# 35 "/usr/include/c++/4.8.2/bits/cpp_type_traits.h" 3 + +# 36 "/usr/include/c++/4.8.2/bits/cpp_type_traits.h" 3 +# 68 "/usr/include/c++/4.8.2/bits/cpp_type_traits.h" 3 +namespace __gnu_cxx __attribute__ ((__visibility__ ("default"))) +{ + + + template + class __normal_iterator; + + +} + +namespace std __attribute__ ((__visibility__ ("default"))) +{ + + + struct __true_type { }; + struct __false_type { }; + + template + struct __truth_type + { typedef __false_type __type; }; + + template<> + struct __truth_type + { typedef __true_type __type; }; + + + + template + struct __traitor + { + enum { __value = bool(_Sp::__value) || bool(_Tp::__value) }; + typedef typename __truth_type<__value>::__type __type; + }; + + + template + struct __are_same + { + enum { __value = 0 }; + typedef __false_type __type; + }; + + template + struct __are_same<_Tp, _Tp> + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + + template + struct __is_void + { + enum { __value = 0 }; + typedef __false_type __type; + }; + + template<> + struct __is_void + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + + + + template + struct __is_integer + { + enum { __value = 0 }; + typedef __false_type __type; + }; + + + + + template<> + struct __is_integer + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + template<> + struct __is_integer + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + template<> + struct __is_integer + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + template<> + struct __is_integer + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + + template<> + struct __is_integer + { + enum { __value = 1 }; + typedef __true_type __type; + }; +# 198 "/usr/include/c++/4.8.2/bits/cpp_type_traits.h" 3 + template<> + struct __is_integer + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + template<> + struct __is_integer + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + template<> + struct __is_integer + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + template<> + struct __is_integer + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + template<> + struct __is_integer + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + template<> + struct __is_integer + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + template<> + struct __is_integer + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + template<> + struct __is_integer + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + + + + template + struct __is_floating + { + enum { __value = 0 }; + typedef __false_type __type; + }; + + + template<> + struct __is_floating + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + template<> + struct __is_floating + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + template<> + struct __is_floating + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + + + + template + struct __is_pointer + { + enum { __value = 0 }; + typedef __false_type __type; + }; + + template + struct __is_pointer<_Tp*> + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + + + + template + struct __is_normal_iterator + { + enum { __value = 0 }; + typedef __false_type __type; + }; + + template + struct __is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator, + _Container> > + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + + + + template + struct __is_arithmetic + : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> > + { }; + + + + + template + struct __is_fundamental + : public __traitor<__is_void<_Tp>, __is_arithmetic<_Tp> > + { }; + + + + + template + struct __is_scalar + : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> > + { }; + + + + + template + struct __is_char + { + enum { __value = 0 }; + typedef __false_type __type; + }; + + template<> + struct __is_char + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + + template<> + struct __is_char + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + + template + struct __is_byte + { + enum { __value = 0 }; + typedef __false_type __type; + }; + + template<> + struct __is_byte + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + template<> + struct __is_byte + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + template<> + struct __is_byte + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + + + + template + struct __is_move_iterator + { + enum { __value = 0 }; + typedef __false_type __type; + }; +# 421 "/usr/include/c++/4.8.2/bits/cpp_type_traits.h" 3 + +} +# 62 "/usr/include/c++/4.8.2/bits/stl_algobase.h" 2 3 +# 1 "/usr/include/c++/4.8.2/ext/type_traits.h" 1 3 +# 32 "/usr/include/c++/4.8.2/ext/type_traits.h" 3 + +# 33 "/usr/include/c++/4.8.2/ext/type_traits.h" 3 + + + + +namespace __gnu_cxx __attribute__ ((__visibility__ ("default"))) +{ + + + + template + struct __enable_if + { }; + + template + struct __enable_if + { typedef _Tp __type; }; + + + + template + struct __conditional_type + { typedef _Iftrue __type; }; + + template + struct __conditional_type + { typedef _Iffalse __type; }; + + + + template + struct __add_unsigned + { + private: + typedef __enable_if::__value, _Tp> __if_type; + + public: + typedef typename __if_type::__type __type; + }; + + template<> + struct __add_unsigned + { typedef unsigned char __type; }; + + template<> + struct __add_unsigned + { typedef unsigned char __type; }; + + template<> + struct __add_unsigned + { typedef unsigned short __type; }; + + template<> + struct __add_unsigned + { typedef unsigned int __type; }; + + template<> + struct __add_unsigned + { typedef unsigned long __type; }; + + template<> + struct __add_unsigned + { typedef unsigned long long __type; }; + + + template<> + struct __add_unsigned; + + template<> + struct __add_unsigned; + + + + template + struct __remove_unsigned + { + private: + typedef __enable_if::__value, _Tp> __if_type; + + public: + typedef typename __if_type::__type __type; + }; + + template<> + struct __remove_unsigned + { typedef signed char __type; }; + + template<> + struct __remove_unsigned + { typedef signed char __type; }; + + template<> + struct __remove_unsigned + { typedef short __type; }; + + template<> + struct __remove_unsigned + { typedef int __type; }; + + template<> + struct __remove_unsigned + { typedef long __type; }; + + template<> + struct __remove_unsigned + { typedef long long __type; }; + + + template<> + struct __remove_unsigned; + + template<> + struct __remove_unsigned; + + + + template + inline bool + __is_null_pointer(_Type* __ptr) + { return __ptr == 0; } + + template + inline bool + __is_null_pointer(_Type) + { return false; } + + + + template::__value> + struct __promote + { typedef double __type; }; + + + + + template + struct __promote<_Tp, false> + { }; + + template<> + struct __promote + { typedef long double __type; }; + + template<> + struct __promote + { typedef double __type; }; + + template<> + struct __promote + { typedef float __type; }; + + template::__type, + typename _Up2 = typename __promote<_Up>::__type> + struct __promote_2 + { + typedef __typeof__(_Tp2() + _Up2()) __type; + }; + + template::__type, + typename _Up2 = typename __promote<_Up>::__type, + typename _Vp2 = typename __promote<_Vp>::__type> + struct __promote_3 + { + typedef __typeof__(_Tp2() + _Up2() + _Vp2()) __type; + }; + + template::__type, + typename _Up2 = typename __promote<_Up>::__type, + typename _Vp2 = typename __promote<_Vp>::__type, + typename _Wp2 = typename __promote<_Wp>::__type> + struct __promote_4 + { + typedef __typeof__(_Tp2() + _Up2() + _Vp2() + _Wp2()) __type; + }; + + +} +# 63 "/usr/include/c++/4.8.2/bits/stl_algobase.h" 2 3 +# 1 "/usr/include/c++/4.8.2/ext/numeric_traits.h" 1 3 +# 32 "/usr/include/c++/4.8.2/ext/numeric_traits.h" 3 + +# 33 "/usr/include/c++/4.8.2/ext/numeric_traits.h" 3 + + + + +namespace __gnu_cxx __attribute__ ((__visibility__ ("default"))) +{ + +# 54 "/usr/include/c++/4.8.2/ext/numeric_traits.h" 3 + template + struct __numeric_traits_integer + { + + static const _Value __min = (((_Value)(-1) < 0) ? (_Value)1 << (sizeof(_Value) * 8 - ((_Value)(-1) < 0)) : (_Value)0); + static const _Value __max = (((_Value)(-1) < 0) ? (((((_Value)1 << ((sizeof(_Value) * 8 - ((_Value)(-1) < 0)) - 1)) - 1) << 1) + 1) : ~(_Value)0); + + + + static const bool __is_signed = ((_Value)(-1) < 0); + static const int __digits = (sizeof(_Value) * 8 - ((_Value)(-1) < 0)); + }; + + template + const _Value __numeric_traits_integer<_Value>::__min; + + template + const _Value __numeric_traits_integer<_Value>::__max; + + template + const bool __numeric_traits_integer<_Value>::__is_signed; + + template + const int __numeric_traits_integer<_Value>::__digits; +# 99 "/usr/include/c++/4.8.2/ext/numeric_traits.h" 3 + template + struct __numeric_traits_floating + { + + static const int __max_digits10 = (2 + (std::__are_same<_Value, float>::__value ? 24 : std::__are_same<_Value, double>::__value ? 53 : 64) * 643L / 2136); + + + static const bool __is_signed = true; + static const int __digits10 = (std::__are_same<_Value, float>::__value ? 6 : std::__are_same<_Value, double>::__value ? 15 : 18); + static const int __max_exponent10 = (std::__are_same<_Value, float>::__value ? 38 : std::__are_same<_Value, double>::__value ? 308 : 4932); + }; + + template + const int __numeric_traits_floating<_Value>::__max_digits10; + + template + const bool __numeric_traits_floating<_Value>::__is_signed; + + template + const int __numeric_traits_floating<_Value>::__digits10; + + template + const int __numeric_traits_floating<_Value>::__max_exponent10; + + template + struct __numeric_traits + : public __conditional_type::__value, + __numeric_traits_integer<_Value>, + __numeric_traits_floating<_Value> >::__type + { }; + + +} +# 64 "/usr/include/c++/4.8.2/bits/stl_algobase.h" 2 3 +# 1 "/usr/include/c++/4.8.2/bits/stl_pair.h" 1 3 +# 59 "/usr/include/c++/4.8.2/bits/stl_pair.h" 3 +# 1 "/usr/include/c++/4.8.2/bits/move.h" 1 3 +# 34 "/usr/include/c++/4.8.2/bits/move.h" 3 +# 1 "/usr/include/c++/4.8.2/bits/concept_check.h" 1 3 +# 33 "/usr/include/c++/4.8.2/bits/concept_check.h" 3 + +# 34 "/usr/include/c++/4.8.2/bits/concept_check.h" 3 +# 35 "/usr/include/c++/4.8.2/bits/move.h" 2 3 + +namespace std __attribute__ ((__visibility__ ("default"))) +{ + + + + + + + + template + inline _Tp* + __addressof(_Tp& __r) + { + return reinterpret_cast<_Tp*> + (&const_cast(reinterpret_cast(__r))); + } + + +} +# 149 "/usr/include/c++/4.8.2/bits/move.h" 3 +namespace std __attribute__ ((__visibility__ ("default"))) +{ + +# 164 "/usr/include/c++/4.8.2/bits/move.h" 3 + template + inline void + swap(_Tp& __a, _Tp& __b) + + + + + { + + + + _Tp __tmp = (__a); + __a = (__b); + __b = (__tmp); + } + + + + + template + inline void + swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm]) + + + + { + for (size_t __n = 0; __n < _Nm; ++__n) + swap(__a[__n], __b[__n]); + } + + + +} +# 60 "/usr/include/c++/4.8.2/bits/stl_pair.h" 2 3 + + + + + +namespace std __attribute__ ((__visibility__ ("default"))) +{ + +# 95 "/usr/include/c++/4.8.2/bits/stl_pair.h" 3 + template + struct pair + { + typedef _T1 first_type; + typedef _T2 second_type; + + _T1 first; + _T2 second; + + + + + + pair() + : first(), second() { } + + + pair(const _T1& __a, const _T2& __b) + : first(__a), second(__b) { } + + + + template + pair(const pair<_U1, _U2>& __p) + : first(__p.first), second(__p.second) { } +# 209 "/usr/include/c++/4.8.2/bits/stl_pair.h" 3 + }; + + + template + inline bool + operator==(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) + { return __x.first == __y.first && __x.second == __y.second; } + + + template + inline bool + operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) + { return __x.first < __y.first + || (!(__y.first < __x.first) && __x.second < __y.second); } + + + template + inline bool + operator!=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) + { return !(__x == __y); } + + + template + inline bool + operator>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) + { return __y < __x; } + + + template + inline bool + operator<=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) + { return !(__y < __x); } + + + template + inline bool + operator>=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) + { return !(__x < __y); } +# 284 "/usr/include/c++/4.8.2/bits/stl_pair.h" 3 + template + inline pair<_T1, _T2> + make_pair(_T1 __x, _T2 __y) + { return pair<_T1, _T2>(__x, __y); } + + + + + +} +# 65 "/usr/include/c++/4.8.2/bits/stl_algobase.h" 2 3 +# 1 "/usr/include/c++/4.8.2/bits/stl_iterator_base_types.h" 1 3 +# 62 "/usr/include/c++/4.8.2/bits/stl_iterator_base_types.h" 3 + +# 63 "/usr/include/c++/4.8.2/bits/stl_iterator_base_types.h" 3 + + + + + + + +namespace std __attribute__ ((__visibility__ ("default"))) +{ + +# 89 "/usr/include/c++/4.8.2/bits/stl_iterator_base_types.h" 3 + struct input_iterator_tag { }; + + + struct output_iterator_tag { }; + + + struct forward_iterator_tag : public input_iterator_tag { }; + + + + struct bidirectional_iterator_tag : public forward_iterator_tag { }; + + + + struct random_access_iterator_tag : public bidirectional_iterator_tag { }; +# 116 "/usr/include/c++/4.8.2/bits/stl_iterator_base_types.h" 3 + template + struct iterator + { + + typedef _Category iterator_category; + + typedef _Tp value_type; + + typedef _Distance difference_type; + + typedef _Pointer pointer; + + typedef _Reference reference; + }; +# 162 "/usr/include/c++/4.8.2/bits/stl_iterator_base_types.h" 3 + template + struct iterator_traits + { + typedef typename _Iterator::iterator_category iterator_category; + typedef typename _Iterator::value_type value_type; + typedef typename _Iterator::difference_type difference_type; + typedef typename _Iterator::pointer pointer; + typedef typename _Iterator::reference reference; + }; + + + + template + struct iterator_traits<_Tp*> + { + typedef random_access_iterator_tag iterator_category; + typedef _Tp value_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; + }; + + + template + struct iterator_traits + { + typedef random_access_iterator_tag iterator_category; + typedef _Tp value_type; + typedef ptrdiff_t difference_type; + typedef const _Tp* pointer; + typedef const _Tp& reference; + }; + + + + + + template + inline typename iterator_traits<_Iter>::iterator_category + __iterator_category(const _Iter&) + { return typename iterator_traits<_Iter>::iterator_category(); } + + + + + + template + struct _Iter_base + { + typedef _Iterator iterator_type; + static iterator_type _S_base(_Iterator __it) + { return __it; } + }; + + template + struct _Iter_base<_Iterator, true> + { + typedef typename _Iterator::iterator_type iterator_type; + static iterator_type _S_base(_Iterator __it) + { return __it.base(); } + }; +# 232 "/usr/include/c++/4.8.2/bits/stl_iterator_base_types.h" 3 + +} +# 66 "/usr/include/c++/4.8.2/bits/stl_algobase.h" 2 3 +# 1 "/usr/include/c++/4.8.2/bits/stl_iterator_base_funcs.h" 1 3 +# 62 "/usr/include/c++/4.8.2/bits/stl_iterator_base_funcs.h" 3 + +# 63 "/usr/include/c++/4.8.2/bits/stl_iterator_base_funcs.h" 3 + + +# 1 "/usr/include/c++/4.8.2/debug/debug.h" 1 3 +# 46 "/usr/include/c++/4.8.2/debug/debug.h" 3 +namespace std +{ + namespace __debug { } +} + + + + +namespace __gnu_debug +{ + using namespace std::__debug; +} +# 66 "/usr/include/c++/4.8.2/bits/stl_iterator_base_funcs.h" 2 3 + +namespace std __attribute__ ((__visibility__ ("default"))) +{ + + + template + inline typename iterator_traits<_InputIterator>::difference_type + __distance(_InputIterator __first, _InputIterator __last, + input_iterator_tag) + { + + + + typename iterator_traits<_InputIterator>::difference_type __n = 0; + while (__first != __last) + { + ++__first; + ++__n; + } + return __n; + } + + template + inline typename iterator_traits<_RandomAccessIterator>::difference_type + __distance(_RandomAccessIterator __first, _RandomAccessIterator __last, + random_access_iterator_tag) + { + + + + return __last - __first; + } +# 112 "/usr/include/c++/4.8.2/bits/stl_iterator_base_funcs.h" 3 + template + inline typename iterator_traits<_InputIterator>::difference_type + distance(_InputIterator __first, _InputIterator __last) + { + + return std::__distance(__first, __last, + std::__iterator_category(__first)); + } + + template + inline void + __advance(_InputIterator& __i, _Distance __n, input_iterator_tag) + { + + + ; + while (__n--) + ++__i; + } + + template + inline void + __advance(_BidirectionalIterator& __i, _Distance __n, + bidirectional_iterator_tag) + { + + + + if (__n > 0) + while (__n--) + ++__i; + else + while (__n++) + --__i; + } + + template + inline void + __advance(_RandomAccessIterator& __i, _Distance __n, + random_access_iterator_tag) + { + + + + __i += __n; + } +# 171 "/usr/include/c++/4.8.2/bits/stl_iterator_base_funcs.h" 3 + template + inline void + advance(_InputIterator& __i, _Distance __n) + { + + typename iterator_traits<_InputIterator>::difference_type __d = __n; + std::__advance(__i, __d, std::__iterator_category(__i)); + } +# 202 "/usr/include/c++/4.8.2/bits/stl_iterator_base_funcs.h" 3 + +} +# 67 "/usr/include/c++/4.8.2/bits/stl_algobase.h" 2 3 +# 1 "/usr/include/c++/4.8.2/bits/stl_iterator.h" 1 3 +# 67 "/usr/include/c++/4.8.2/bits/stl_iterator.h" 3 +namespace std __attribute__ ((__visibility__ ("default"))) +{ + +# 95 "/usr/include/c++/4.8.2/bits/stl_iterator.h" 3 + template + class reverse_iterator + : public iterator::iterator_category, + typename iterator_traits<_Iterator>::value_type, + typename iterator_traits<_Iterator>::difference_type, + typename iterator_traits<_Iterator>::pointer, + typename iterator_traits<_Iterator>::reference> + { + protected: + _Iterator current; + + typedef iterator_traits<_Iterator> __traits_type; + + public: + typedef _Iterator iterator_type; + typedef typename __traits_type::difference_type difference_type; + typedef typename __traits_type::pointer pointer; + typedef typename __traits_type::reference reference; + + + + + + + + reverse_iterator() : current() { } + + + + + explicit + reverse_iterator(iterator_type __x) : current(__x) { } + + + + + reverse_iterator(const reverse_iterator& __x) + : current(__x.current) { } + + + + + + template + reverse_iterator(const reverse_iterator<_Iter>& __x) + : current(__x.base()) { } + + + + + iterator_type + base() const + { return current; } +# 159 "/usr/include/c++/4.8.2/bits/stl_iterator.h" 3 + reference + operator*() const + { + _Iterator __tmp = current; + return *--__tmp; + } + + + + + + + pointer + operator->() const + { return &(operator*()); } + + + + + + + reverse_iterator& + operator++() + { + --current; + return *this; + } + + + + + + + reverse_iterator + operator++(int) + { + reverse_iterator __tmp = *this; + --current; + return __tmp; + } + + + + + + + reverse_iterator& + operator--() + { + ++current; + return *this; + } + + + + + + + reverse_iterator + operator--(int) + { + reverse_iterator __tmp = *this; + ++current; + return __tmp; + } + + + + + + + reverse_iterator + operator+(difference_type __n) const + { return reverse_iterator(current - __n); } + + + + + + + + reverse_iterator& + operator+=(difference_type __n) + { + current -= __n; + return *this; + } + + + + + + + reverse_iterator + operator-(difference_type __n) const + { return reverse_iterator(current + __n); } + + + + + + + + reverse_iterator& + operator-=(difference_type __n) + { + current += __n; + return *this; + } + + + + + + + reference + operator[](difference_type __n) const + { return *(*this + __n); } + }; +# 289 "/usr/include/c++/4.8.2/bits/stl_iterator.h" 3 + template + inline bool + operator==(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) + { return __x.base() == __y.base(); } + + template + inline bool + operator<(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) + { return __y.base() < __x.base(); } + + template + inline bool + operator!=(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) + { return !(__x == __y); } + + template + inline bool + operator>(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) + { return __y < __x; } + + template + inline bool + operator<=(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) + { return !(__y < __x); } + + template + inline bool + operator>=(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) + { return !(__x < __y); } + + template + inline typename reverse_iterator<_Iterator>::difference_type + operator-(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) + { return __y.base() - __x.base(); } + + template + inline reverse_iterator<_Iterator> + operator+(typename reverse_iterator<_Iterator>::difference_type __n, + const reverse_iterator<_Iterator>& __x) + { return reverse_iterator<_Iterator>(__x.base() - __n); } + + + + template + inline bool + operator==(const reverse_iterator<_IteratorL>& __x, + const reverse_iterator<_IteratorR>& __y) + { return __x.base() == __y.base(); } + + template + inline bool + operator<(const reverse_iterator<_IteratorL>& __x, + const reverse_iterator<_IteratorR>& __y) + { return __y.base() < __x.base(); } + + template + inline bool + operator!=(const reverse_iterator<_IteratorL>& __x, + const reverse_iterator<_IteratorR>& __y) + { return !(__x == __y); } + + template + inline bool + operator>(const reverse_iterator<_IteratorL>& __x, + const reverse_iterator<_IteratorR>& __y) + { return __y < __x; } + + template + inline bool + operator<=(const reverse_iterator<_IteratorL>& __x, + const reverse_iterator<_IteratorR>& __y) + { return !(__y < __x); } + + template + inline bool + operator>=(const reverse_iterator<_IteratorL>& __x, + const reverse_iterator<_IteratorR>& __y) + { return !(__x < __y); } + + template + + + + + + + + inline typename reverse_iterator<_IteratorL>::difference_type + operator-(const reverse_iterator<_IteratorL>& __x, + const reverse_iterator<_IteratorR>& __y) + + { return __y.base() - __x.base(); } +# 401 "/usr/include/c++/4.8.2/bits/stl_iterator.h" 3 + template + class back_insert_iterator + : public iterator + { + protected: + _Container* container; + + public: + + typedef _Container container_type; + + + explicit + back_insert_iterator(_Container& __x) : container(&__x) { } +# 428 "/usr/include/c++/4.8.2/bits/stl_iterator.h" 3 + back_insert_iterator& + operator=(typename _Container::const_reference __value) + { + container->push_back(__value); + return *this; + } +# 451 "/usr/include/c++/4.8.2/bits/stl_iterator.h" 3 + back_insert_iterator& + operator*() + { return *this; } + + + back_insert_iterator& + operator++() + { return *this; } + + + back_insert_iterator + operator++(int) + { return *this; } + }; +# 477 "/usr/include/c++/4.8.2/bits/stl_iterator.h" 3 + template + inline back_insert_iterator<_Container> + back_inserter(_Container& __x) + { return back_insert_iterator<_Container>(__x); } +# 492 "/usr/include/c++/4.8.2/bits/stl_iterator.h" 3 + template + class front_insert_iterator + : public iterator + { + protected: + _Container* container; + + public: + + typedef _Container container_type; + + + explicit front_insert_iterator(_Container& __x) : container(&__x) { } +# 518 "/usr/include/c++/4.8.2/bits/stl_iterator.h" 3 + front_insert_iterator& + operator=(typename _Container::const_reference __value) + { + container->push_front(__value); + return *this; + } +# 541 "/usr/include/c++/4.8.2/bits/stl_iterator.h" 3 + front_insert_iterator& + operator*() + { return *this; } + + + front_insert_iterator& + operator++() + { return *this; } + + + front_insert_iterator + operator++(int) + { return *this; } + }; +# 567 "/usr/include/c++/4.8.2/bits/stl_iterator.h" 3 + template + inline front_insert_iterator<_Container> + front_inserter(_Container& __x) + { return front_insert_iterator<_Container>(__x); } +# 586 "/usr/include/c++/4.8.2/bits/stl_iterator.h" 3 + template + class insert_iterator + : public iterator + { + protected: + _Container* container; + typename _Container::iterator iter; + + public: + + typedef _Container container_type; + + + + + + insert_iterator(_Container& __x, typename _Container::iterator __i) + : container(&__x), iter(__i) {} +# 629 "/usr/include/c++/4.8.2/bits/stl_iterator.h" 3 + insert_iterator& + operator=(typename _Container::const_reference __value) + { + iter = container->insert(iter, __value); + ++iter; + return *this; + } +# 655 "/usr/include/c++/4.8.2/bits/stl_iterator.h" 3 + insert_iterator& + operator*() + { return *this; } + + + insert_iterator& + operator++() + { return *this; } + + + insert_iterator& + operator++(int) + { return *this; } + }; +# 681 "/usr/include/c++/4.8.2/bits/stl_iterator.h" 3 + template + inline insert_iterator<_Container> + inserter(_Container& __x, _Iterator __i) + { + return insert_iterator<_Container>(__x, + typename _Container::iterator(__i)); + } + + + + +} + +namespace __gnu_cxx __attribute__ ((__visibility__ ("default"))) +{ + +# 705 "/usr/include/c++/4.8.2/bits/stl_iterator.h" 3 + using std::iterator_traits; + using std::iterator; + template + class __normal_iterator + { + protected: + _Iterator _M_current; + + typedef iterator_traits<_Iterator> __traits_type; + + public: + typedef _Iterator iterator_type; + typedef typename __traits_type::iterator_category iterator_category; + typedef typename __traits_type::value_type value_type; + typedef typename __traits_type::difference_type difference_type; + typedef typename __traits_type::reference reference; + typedef typename __traits_type::pointer pointer; + + __normal_iterator() : _M_current(_Iterator()) { } + + explicit + __normal_iterator(const _Iterator& __i) : _M_current(__i) { } + + + template + __normal_iterator(const __normal_iterator<_Iter, + typename __enable_if< + (std::__are_same<_Iter, typename _Container::pointer>::__value), + _Container>::__type>& __i) + : _M_current(__i.base()) { } + + + reference + operator*() const + { return *_M_current; } + + pointer + operator->() const + { return _M_current; } + + __normal_iterator& + operator++() + { + ++_M_current; + return *this; + } + + __normal_iterator + operator++(int) + { return __normal_iterator(_M_current++); } + + + __normal_iterator& + operator--() + { + --_M_current; + return *this; + } + + __normal_iterator + operator--(int) + { return __normal_iterator(_M_current--); } + + + reference + operator[](const difference_type& __n) const + { return _M_current[__n]; } + + __normal_iterator& + operator+=(const difference_type& __n) + { _M_current += __n; return *this; } + + __normal_iterator + operator+(const difference_type& __n) const + { return __normal_iterator(_M_current + __n); } + + __normal_iterator& + operator-=(const difference_type& __n) + { _M_current -= __n; return *this; } + + __normal_iterator + operator-(const difference_type& __n) const + { return __normal_iterator(_M_current - __n); } + + const _Iterator& + base() const + { return _M_current; } + }; +# 803 "/usr/include/c++/4.8.2/bits/stl_iterator.h" 3 + template + inline bool + operator==(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() == __rhs.base(); } + + template + inline bool + operator==(const __normal_iterator<_Iterator, _Container>& __lhs, + const __normal_iterator<_Iterator, _Container>& __rhs) + { return __lhs.base() == __rhs.base(); } + + template + inline bool + operator!=(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() != __rhs.base(); } + + template + inline bool + operator!=(const __normal_iterator<_Iterator, _Container>& __lhs, + const __normal_iterator<_Iterator, _Container>& __rhs) + { return __lhs.base() != __rhs.base(); } + + + template + inline bool + operator<(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() < __rhs.base(); } + + template + inline bool + operator<(const __normal_iterator<_Iterator, _Container>& __lhs, + const __normal_iterator<_Iterator, _Container>& __rhs) + { return __lhs.base() < __rhs.base(); } + + template + inline bool + operator>(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() > __rhs.base(); } + + template + inline bool + operator>(const __normal_iterator<_Iterator, _Container>& __lhs, + const __normal_iterator<_Iterator, _Container>& __rhs) + { return __lhs.base() > __rhs.base(); } + + template + inline bool + operator<=(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() <= __rhs.base(); } + + template + inline bool + operator<=(const __normal_iterator<_Iterator, _Container>& __lhs, + const __normal_iterator<_Iterator, _Container>& __rhs) + { return __lhs.base() <= __rhs.base(); } + + template + inline bool + operator>=(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() >= __rhs.base(); } + + template + inline bool + operator>=(const __normal_iterator<_Iterator, _Container>& __lhs, + const __normal_iterator<_Iterator, _Container>& __rhs) + { return __lhs.base() >= __rhs.base(); } + + + + + + template + + + + + + + + inline typename __normal_iterator<_IteratorL, _Container>::difference_type + operator-(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + + { return __lhs.base() - __rhs.base(); } + + template + inline typename __normal_iterator<_Iterator, _Container>::difference_type + operator-(const __normal_iterator<_Iterator, _Container>& __lhs, + const __normal_iterator<_Iterator, _Container>& __rhs) + { return __lhs.base() - __rhs.base(); } + + template + inline __normal_iterator<_Iterator, _Container> + operator+(typename __normal_iterator<_Iterator, _Container>::difference_type + __n, const __normal_iterator<_Iterator, _Container>& __i) + { return __normal_iterator<_Iterator, _Container>(__i.base() + __n); } + + +} +# 68 "/usr/include/c++/4.8.2/bits/stl_algobase.h" 2 3 + + + + +namespace std __attribute__ ((__visibility__ ("default"))) +{ + + + + + + + template + struct __iter_swap + { + template + static void + iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b) + { + typedef typename iterator_traits<_ForwardIterator1>::value_type + _ValueType1; + _ValueType1 __tmp = (*__a); + *__a = (*__b); + *__b = (__tmp); + } + }; + + template<> + struct __iter_swap + { + template + static void + iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b) + { + swap(*__a, *__b); + } + }; +# 117 "/usr/include/c++/4.8.2/bits/stl_algobase.h" 3 + template + inline void + iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b) + { + + + + + + + + typedef typename iterator_traits<_ForwardIterator1>::value_type + _ValueType1; + typedef typename iterator_traits<_ForwardIterator2>::value_type + _ValueType2; + + + + + + + typedef typename iterator_traits<_ForwardIterator1>::reference + _ReferenceType1; + typedef typename iterator_traits<_ForwardIterator2>::reference + _ReferenceType2; + std::__iter_swap<__are_same<_ValueType1, _ValueType2>::__value + && __are_same<_ValueType1&, _ReferenceType1>::__value + && __are_same<_ValueType2&, _ReferenceType2>::__value>:: + iter_swap(__a, __b); + + + + } +# 163 "/usr/include/c++/4.8.2/bits/stl_algobase.h" 3 + template + _ForwardIterator2 + swap_ranges(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2) + { + + + + + + ; + + for (; __first1 != __last1; ++__first1, ++__first2) + std::iter_swap(__first1, __first2); + return __first2; + } +# 191 "/usr/include/c++/4.8.2/bits/stl_algobase.h" 3 + template + inline const _Tp& + min(const _Tp& __a, const _Tp& __b) + { + + + + if (__b < __a) + return __b; + return __a; + } +# 214 "/usr/include/c++/4.8.2/bits/stl_algobase.h" 3 + template + inline const _Tp& + max(const _Tp& __a, const _Tp& __b) + { + + + + if (__a < __b) + return __b; + return __a; + } +# 237 "/usr/include/c++/4.8.2/bits/stl_algobase.h" 3 + template + inline const _Tp& + min(const _Tp& __a, const _Tp& __b, _Compare __comp) + { + + if (__comp(__b, __a)) + return __b; + return __a; + } +# 258 "/usr/include/c++/4.8.2/bits/stl_algobase.h" 3 + template + inline const _Tp& + max(const _Tp& __a, const _Tp& __b, _Compare __comp) + { + + if (__comp(__a, __b)) + return __b; + return __a; + } + + + + template + struct _Niter_base + : _Iter_base<_Iterator, __is_normal_iterator<_Iterator>::__value> + { }; + + template + inline typename _Niter_base<_Iterator>::iterator_type + __niter_base(_Iterator __it) + { return std::_Niter_base<_Iterator>::_S_base(__it); } + + + template + struct _Miter_base + : _Iter_base<_Iterator, __is_move_iterator<_Iterator>::__value> + { }; + + template + inline typename _Miter_base<_Iterator>::iterator_type + __miter_base(_Iterator __it) + { return std::_Miter_base<_Iterator>::_S_base(__it); } + + + + + + + + template + struct __copy_move + { + template + static _OI + __copy_m(_II __first, _II __last, _OI __result) + { + for (; __first != __last; ++__result, ++__first) + *__result = *__first; + return __result; + } + }; +# 325 "/usr/include/c++/4.8.2/bits/stl_algobase.h" 3 + template<> + struct __copy_move + { + template + static _OI + __copy_m(_II __first, _II __last, _OI __result) + { + typedef typename iterator_traits<_II>::difference_type _Distance; + for(_Distance __n = __last - __first; __n > 0; --__n) + { + *__result = *__first; + ++__first; + ++__result; + } + return __result; + } + }; +# 363 "/usr/include/c++/4.8.2/bits/stl_algobase.h" 3 + template + struct __copy_move<_IsMove, true, random_access_iterator_tag> + { + template + static _Tp* + __copy_m(const _Tp* __first, const _Tp* __last, _Tp* __result) + { + const ptrdiff_t _Num = __last - __first; + if (_Num) + __builtin_memmove(__result, __first, sizeof(_Tp) * _Num); + return __result + _Num; + } + }; + + template + inline _OI + __copy_move_a(_II __first, _II __last, _OI __result) + { + typedef typename iterator_traits<_II>::value_type _ValueTypeI; + typedef typename iterator_traits<_OI>::value_type _ValueTypeO; + typedef typename iterator_traits<_II>::iterator_category _Category; + const bool __simple = (__is_trivial(_ValueTypeI) + && __is_pointer<_II>::__value + && __is_pointer<_OI>::__value + && __are_same<_ValueTypeI, _ValueTypeO>::__value); + + return std::__copy_move<_IsMove, __simple, + _Category>::__copy_m(__first, __last, __result); + } + + + + template + struct char_traits; + + template + class istreambuf_iterator; + + template + class ostreambuf_iterator; + + template + typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, + ostreambuf_iterator<_CharT, char_traits<_CharT> > >::__type + __copy_move_a2(_CharT*, _CharT*, + ostreambuf_iterator<_CharT, char_traits<_CharT> >); + + template + typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, + ostreambuf_iterator<_CharT, char_traits<_CharT> > >::__type + __copy_move_a2(const _CharT*, const _CharT*, + ostreambuf_iterator<_CharT, char_traits<_CharT> >); + + template + typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, + _CharT*>::__type + __copy_move_a2(istreambuf_iterator<_CharT, char_traits<_CharT> >, + istreambuf_iterator<_CharT, char_traits<_CharT> >, _CharT*); + + template + inline _OI + __copy_move_a2(_II __first, _II __last, _OI __result) + { + return _OI(std::__copy_move_a<_IsMove>(std::__niter_base(__first), + std::__niter_base(__last), + std::__niter_base(__result))); + } +# 448 "/usr/include/c++/4.8.2/bits/stl_algobase.h" 3 + template + inline _OI + copy(_II __first, _II __last, _OI __result) + { + + + + + ; + + return (std::__copy_move_a2<__is_move_iterator<_II>::__value> + (std::__miter_base(__first), std::__miter_base(__last), + __result)); + } +# 500 "/usr/include/c++/4.8.2/bits/stl_algobase.h" 3 + template + struct __copy_move_backward + { + template + static _BI2 + __copy_move_b(_BI1 __first, _BI1 __last, _BI2 __result) + { + while (__first != __last) + *--__result = *--__last; + return __result; + } + }; +# 528 "/usr/include/c++/4.8.2/bits/stl_algobase.h" 3 + template<> + struct __copy_move_backward + { + template + static _BI2 + __copy_move_b(_BI1 __first, _BI1 __last, _BI2 __result) + { + typename iterator_traits<_BI1>::difference_type __n; + for (__n = __last - __first; __n > 0; --__n) + *--__result = *--__last; + return __result; + } + }; +# 558 "/usr/include/c++/4.8.2/bits/stl_algobase.h" 3 + template + struct __copy_move_backward<_IsMove, true, random_access_iterator_tag> + { + template + static _Tp* + __copy_move_b(const _Tp* __first, const _Tp* __last, _Tp* __result) + { + const ptrdiff_t _Num = __last - __first; + if (_Num) + __builtin_memmove(__result - _Num, __first, sizeof(_Tp) * _Num); + return __result - _Num; + } + }; + + template + inline _BI2 + __copy_move_backward_a(_BI1 __first, _BI1 __last, _BI2 __result) + { + typedef typename iterator_traits<_BI1>::value_type _ValueType1; + typedef typename iterator_traits<_BI2>::value_type _ValueType2; + typedef typename iterator_traits<_BI1>::iterator_category _Category; + const bool __simple = (__is_trivial(_ValueType1) + && __is_pointer<_BI1>::__value + && __is_pointer<_BI2>::__value + && __are_same<_ValueType1, _ValueType2>::__value); + + return std::__copy_move_backward<_IsMove, __simple, + _Category>::__copy_move_b(__first, + __last, + __result); + } + + template + inline _BI2 + __copy_move_backward_a2(_BI1 __first, _BI1 __last, _BI2 __result) + { + return _BI2(std::__copy_move_backward_a<_IsMove> + (std::__niter_base(__first), std::__niter_base(__last), + std::__niter_base(__result))); + } +# 617 "/usr/include/c++/4.8.2/bits/stl_algobase.h" 3 + template + inline _BI2 + copy_backward(_BI1 __first, _BI1 __last, _BI2 __result) + { + + + + + + + ; + + return (std::__copy_move_backward_a2<__is_move_iterator<_BI1>::__value> + (std::__miter_base(__first), std::__miter_base(__last), + __result)); + } +# 675 "/usr/include/c++/4.8.2/bits/stl_algobase.h" 3 + template + inline typename + __gnu_cxx::__enable_if::__value, void>::__type + __fill_a(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __value) + { + for (; __first != __last; ++__first) + *__first = __value; + } + + template + inline typename + __gnu_cxx::__enable_if<__is_scalar<_Tp>::__value, void>::__type + __fill_a(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __value) + { + const _Tp __tmp = __value; + for (; __first != __last; ++__first) + *__first = __tmp; + } + + + template + inline typename + __gnu_cxx::__enable_if<__is_byte<_Tp>::__value, void>::__type + __fill_a(_Tp* __first, _Tp* __last, const _Tp& __c) + { + const _Tp __tmp = __c; + __builtin_memset(__first, static_cast(__tmp), + __last - __first); + } +# 719 "/usr/include/c++/4.8.2/bits/stl_algobase.h" 3 + template + inline void + fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) + { + + + + ; + + std::__fill_a(std::__niter_base(__first), std::__niter_base(__last), + __value); + } + + template + inline typename + __gnu_cxx::__enable_if::__value, _OutputIterator>::__type + __fill_n_a(_OutputIterator __first, _Size __n, const _Tp& __value) + { + for (__decltype(__n + 0) __niter = __n; + __niter > 0; --__niter, ++__first) + *__first = __value; + return __first; + } + + template + inline typename + __gnu_cxx::__enable_if<__is_scalar<_Tp>::__value, _OutputIterator>::__type + __fill_n_a(_OutputIterator __first, _Size __n, const _Tp& __value) + { + const _Tp __tmp = __value; + for (__decltype(__n + 0) __niter = __n; + __niter > 0; --__niter, ++__first) + *__first = __tmp; + return __first; + } + + template + inline typename + __gnu_cxx::__enable_if<__is_byte<_Tp>::__value, _Tp*>::__type + __fill_n_a(_Tp* __first, _Size __n, const _Tp& __c) + { + std::__fill_a(__first, __first + __n, __c); + return __first + __n; + } +# 779 "/usr/include/c++/4.8.2/bits/stl_algobase.h" 3 + template + inline _OI + fill_n(_OI __first, _Size __n, const _Tp& __value) + { + + + + return _OI(std::__fill_n_a(std::__niter_base(__first), __n, __value)); + } + + template + struct __equal + { + template + static bool + equal(_II1 __first1, _II1 __last1, _II2 __first2) + { + for (; __first1 != __last1; ++__first1, ++__first2) + if (!(*__first1 == *__first2)) + return false; + return true; + } + }; + + template<> + struct __equal + { + template + static bool + equal(const _Tp* __first1, const _Tp* __last1, const _Tp* __first2) + { + return !__builtin_memcmp(__first1, __first2, sizeof(_Tp) + * (__last1 - __first1)); + } + }; + + template + inline bool + __equal_aux(_II1 __first1, _II1 __last1, _II2 __first2) + { + typedef typename iterator_traits<_II1>::value_type _ValueType1; + typedef typename iterator_traits<_II2>::value_type _ValueType2; + const bool __simple = ((__is_integer<_ValueType1>::__value + || __is_pointer<_ValueType1>::__value) + && __is_pointer<_II1>::__value + && __is_pointer<_II2>::__value + && __are_same<_ValueType1, _ValueType2>::__value); + + return std::__equal<__simple>::equal(__first1, __last1, __first2); + } + + + template + struct __lc_rai + { + template + static _II1 + __newlast1(_II1, _II1 __last1, _II2, _II2) + { return __last1; } + + template + static bool + __cnd2(_II __first, _II __last) + { return __first != __last; } + }; + + template<> + struct __lc_rai + { + template + static _RAI1 + __newlast1(_RAI1 __first1, _RAI1 __last1, + _RAI2 __first2, _RAI2 __last2) + { + const typename iterator_traits<_RAI1>::difference_type + __diff1 = __last1 - __first1; + const typename iterator_traits<_RAI2>::difference_type + __diff2 = __last2 - __first2; + return __diff2 < __diff1 ? __first1 + __diff2 : __last1; + } + + template + static bool + __cnd2(_RAI, _RAI) + { return true; } + }; + + template + struct __lexicographical_compare + { + template + static bool __lc(_II1, _II1, _II2, _II2); + }; + + template + template + bool + __lexicographical_compare<_BoolType>:: + __lc(_II1 __first1, _II1 __last1, _II2 __first2, _II2 __last2) + { + typedef typename iterator_traits<_II1>::iterator_category _Category1; + typedef typename iterator_traits<_II2>::iterator_category _Category2; + typedef std::__lc_rai<_Category1, _Category2> __rai_type; + + __last1 = __rai_type::__newlast1(__first1, __last1, + __first2, __last2); + for (; __first1 != __last1 && __rai_type::__cnd2(__first2, __last2); + ++__first1, ++__first2) + { + if (*__first1 < *__first2) + return true; + if (*__first2 < *__first1) + return false; + } + return __first1 == __last1 && __first2 != __last2; + } + + template<> + struct __lexicographical_compare + { + template + static bool + __lc(const _Tp* __first1, const _Tp* __last1, + const _Up* __first2, const _Up* __last2) + { + const size_t __len1 = __last1 - __first1; + const size_t __len2 = __last2 - __first2; + const int __result = __builtin_memcmp(__first1, __first2, + std::min(__len1, __len2)); + return __result != 0 ? __result < 0 : __len1 < __len2; + } + }; + + template + inline bool + __lexicographical_compare_aux(_II1 __first1, _II1 __last1, + _II2 __first2, _II2 __last2) + { + typedef typename iterator_traits<_II1>::value_type _ValueType1; + typedef typename iterator_traits<_II2>::value_type _ValueType2; + const bool __simple = + (__is_byte<_ValueType1>::__value && __is_byte<_ValueType2>::__value + && !__gnu_cxx::__numeric_traits<_ValueType1>::__is_signed + && !__gnu_cxx::__numeric_traits<_ValueType2>::__is_signed + && __is_pointer<_II1>::__value + && __is_pointer<_II2>::__value); + + return std::__lexicographical_compare<__simple>::__lc(__first1, __last1, + __first2, __last2); + } +# 941 "/usr/include/c++/4.8.2/bits/stl_algobase.h" 3 + template + _ForwardIterator + lower_bound(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val) + { + + + + + typedef typename iterator_traits<_ForwardIterator>::difference_type + _DistanceType; + + + + + ; + + _DistanceType __len = std::distance(__first, __last); + + while (__len > 0) + { + _DistanceType __half = __len >> 1; + _ForwardIterator __middle = __first; + std::advance(__middle, __half); + if (*__middle < __val) + { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + else + __len = __half; + } + return __first; + } + + + + inline int + __lg(int __n) + { return sizeof(int) * 8 - 1 - __builtin_clz(__n); } + + inline unsigned + __lg(unsigned __n) + { return sizeof(int) * 8 - 1 - __builtin_clz(__n); } + + inline long + __lg(long __n) + { return sizeof(long) * 8 - 1 - __builtin_clzl(__n); } + + inline unsigned long + __lg(unsigned long __n) + { return sizeof(long) * 8 - 1 - __builtin_clzl(__n); } + + inline long long + __lg(long long __n) + { return sizeof(long long) * 8 - 1 - __builtin_clzll(__n); } + + inline unsigned long long + __lg(unsigned long long __n) + { return sizeof(long long) * 8 - 1 - __builtin_clzll(__n); } + + + + +# 1019 "/usr/include/c++/4.8.2/bits/stl_algobase.h" 3 + template + inline bool + equal(_II1 __first1, _II1 __last1, _II2 __first2) + { + + + + + + + ; + + return std::__equal_aux(std::__niter_base(__first1), + std::__niter_base(__last1), + std::__niter_base(__first2)); + } +# 1051 "/usr/include/c++/4.8.2/bits/stl_algobase.h" 3 + template + inline bool + equal(_IIter1 __first1, _IIter1 __last1, + _IIter2 __first2, _BinaryPredicate __binary_pred) + { + + + + ; + + for (; __first1 != __last1; ++__first1, ++__first2) + if (!bool(__binary_pred(*__first1, *__first2))) + return false; + return true; + } +# 1082 "/usr/include/c++/4.8.2/bits/stl_algobase.h" 3 + template + inline bool + lexicographical_compare(_II1 __first1, _II1 __last1, + _II2 __first2, _II2 __last2) + { + + + + + + + + + + ; + ; + + return std::__lexicographical_compare_aux(std::__niter_base(__first1), + std::__niter_base(__last1), + std::__niter_base(__first2), + std::__niter_base(__last2)); + } +# 1118 "/usr/include/c++/4.8.2/bits/stl_algobase.h" 3 + template + bool + lexicographical_compare(_II1 __first1, _II1 __last1, + _II2 __first2, _II2 __last2, _Compare __comp) + { + typedef typename iterator_traits<_II1>::iterator_category _Category1; + typedef typename iterator_traits<_II2>::iterator_category _Category2; + typedef std::__lc_rai<_Category1, _Category2> __rai_type; + + + + + ; + ; + + __last1 = __rai_type::__newlast1(__first1, __last1, __first2, __last2); + for (; __first1 != __last1 && __rai_type::__cnd2(__first2, __last2); + ++__first1, ++__first2) + { + if (__comp(*__first1, *__first2)) + return true; + if (__comp(*__first2, *__first1)) + return false; + } + return __first1 == __last1 && __first2 != __last2; + } +# 1158 "/usr/include/c++/4.8.2/bits/stl_algobase.h" 3 + template + pair<_InputIterator1, _InputIterator2> + mismatch(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2) + { + + + + + + + ; + + while (__first1 != __last1 && *__first1 == *__first2) + { + ++__first1; + ++__first2; + } + return pair<_InputIterator1, _InputIterator2>(__first1, __first2); + } +# 1195 "/usr/include/c++/4.8.2/bits/stl_algobase.h" 3 + template + pair<_InputIterator1, _InputIterator2> + mismatch(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _BinaryPredicate __binary_pred) + { + + + + ; + + while (__first1 != __last1 && bool(__binary_pred(*__first1, *__first2))) + { + ++__first1; + ++__first2; + } + return pair<_InputIterator1, _InputIterator2>(__first1, __first2); + } + + +} +# 40 "/usr/include/c++/4.8.2/bits/char_traits.h" 2 3 + +# 1 "/usr/include/c++/4.8.2/cwchar" 1 3 +# 39 "/usr/include/c++/4.8.2/cwchar" 3 + +# 40 "/usr/include/c++/4.8.2/cwchar" 3 + + + + +# 1 "/usr/include/wchar.h" 1 3 4 +# 45 "/usr/include/c++/4.8.2/cwchar" 2 3 +# 42 "/usr/include/c++/4.8.2/bits/char_traits.h" 2 3 + +namespace __gnu_cxx __attribute__ ((__visibility__ ("default"))) +{ + +# 57 "/usr/include/c++/4.8.2/bits/char_traits.h" 3 + template + struct _Char_types + { + typedef unsigned long int_type; + typedef std::streampos pos_type; + typedef std::streamoff off_type; + typedef std::mbstate_t state_type; + }; +# 82 "/usr/include/c++/4.8.2/bits/char_traits.h" 3 + template + struct char_traits + { + typedef _CharT char_type; + typedef typename _Char_types<_CharT>::int_type int_type; + typedef typename _Char_types<_CharT>::pos_type pos_type; + typedef typename _Char_types<_CharT>::off_type off_type; + typedef typename _Char_types<_CharT>::state_type state_type; + + static void + assign(char_type& __c1, const char_type& __c2) + { __c1 = __c2; } + + static bool + eq(const char_type& __c1, const char_type& __c2) + { return __c1 == __c2; } + + static bool + lt(const char_type& __c1, const char_type& __c2) + { return __c1 < __c2; } + + static int + compare(const char_type* __s1, const char_type* __s2, std::size_t __n); + + static std::size_t + length(const char_type* __s); + + static const char_type* + find(const char_type* __s, std::size_t __n, const char_type& __a); + + static char_type* + move(char_type* __s1, const char_type* __s2, std::size_t __n); + + static char_type* + copy(char_type* __s1, const char_type* __s2, std::size_t __n); + + static char_type* + assign(char_type* __s, std::size_t __n, char_type __a); + + static char_type + to_char_type(const int_type& __c) + { return static_cast(__c); } + + static int_type + to_int_type(const char_type& __c) + { return static_cast(__c); } + + static bool + eq_int_type(const int_type& __c1, const int_type& __c2) + { return __c1 == __c2; } + + static int_type + eof() + { return static_cast(-1); } + + static int_type + not_eof(const int_type& __c) + { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); } + }; + + template + int + char_traits<_CharT>:: + compare(const char_type* __s1, const char_type* __s2, std::size_t __n) + { + for (std::size_t __i = 0; __i < __n; ++__i) + if (lt(__s1[__i], __s2[__i])) + return -1; + else if (lt(__s2[__i], __s1[__i])) + return 1; + return 0; + } + + template + std::size_t + char_traits<_CharT>:: + length(const char_type* __p) + { + std::size_t __i = 0; + while (!eq(__p[__i], char_type())) + ++__i; + return __i; + } + + template + const typename char_traits<_CharT>::char_type* + char_traits<_CharT>:: + find(const char_type* __s, std::size_t __n, const char_type& __a) + { + for (std::size_t __i = 0; __i < __n; ++__i) + if (eq(__s[__i], __a)) + return __s + __i; + return 0; + } + + template + typename char_traits<_CharT>::char_type* + char_traits<_CharT>:: + move(char_type* __s1, const char_type* __s2, std::size_t __n) + { + return static_cast<_CharT*>(__builtin_memmove(__s1, __s2, + __n * sizeof(char_type))); + } + + template + typename char_traits<_CharT>::char_type* + char_traits<_CharT>:: + copy(char_type* __s1, const char_type* __s2, std::size_t __n) + { + + std::copy(__s2, __s2 + __n, __s1); + return __s1; + } + + template + typename char_traits<_CharT>::char_type* + char_traits<_CharT>:: + assign(char_type* __s, std::size_t __n, char_type __a) + { + + std::fill_n(__s, __n, __a); + return __s; + } + + +} + +namespace std __attribute__ ((__visibility__ ("default"))) +{ + +# 226 "/usr/include/c++/4.8.2/bits/char_traits.h" 3 + template + struct char_traits : public __gnu_cxx::char_traits<_CharT> + { }; + + + + template<> + struct char_traits + { + typedef char char_type; + typedef int int_type; + typedef streampos pos_type; + typedef streamoff off_type; + typedef mbstate_t state_type; + + static void + assign(char_type& __c1, const char_type& __c2) + { __c1 = __c2; } + + static bool + eq(const char_type& __c1, const char_type& __c2) + { return __c1 == __c2; } + + static bool + lt(const char_type& __c1, const char_type& __c2) + { return __c1 < __c2; } + + static int + compare(const char_type* __s1, const char_type* __s2, size_t __n) + { return __builtin_memcmp(__s1, __s2, __n); } + + static size_t + length(const char_type* __s) + { return __builtin_strlen(__s); } + + static const char_type* + find(const char_type* __s, size_t __n, const char_type& __a) + { return static_cast(__builtin_memchr(__s, __a, __n)); } + + static char_type* + move(char_type* __s1, const char_type* __s2, size_t __n) + { return static_cast(__builtin_memmove(__s1, __s2, __n)); } + + static char_type* + copy(char_type* __s1, const char_type* __s2, size_t __n) + { return static_cast(__builtin_memcpy(__s1, __s2, __n)); } + + static char_type* + assign(char_type* __s, size_t __n, char_type __a) + { return static_cast(__builtin_memset(__s, __a, __n)); } + + static char_type + to_char_type(const int_type& __c) + { return static_cast(__c); } + + + + static int_type + to_int_type(const char_type& __c) + { return static_cast(static_cast(__c)); } + + static bool + eq_int_type(const int_type& __c1, const int_type& __c2) + { return __c1 == __c2; } + + static int_type + eof() + { return static_cast(-1); } + + static int_type + not_eof(const int_type& __c) + { return (__c == eof()) ? 0 : __c; } + }; + + + + + template<> + struct char_traits + { + typedef wchar_t char_type; + typedef wint_t int_type; + typedef streamoff off_type; + typedef wstreampos pos_type; + typedef mbstate_t state_type; + + static void + assign(char_type& __c1, const char_type& __c2) + { __c1 = __c2; } + + static bool + eq(const char_type& __c1, const char_type& __c2) + { return __c1 == __c2; } + + static bool + lt(const char_type& __c1, const char_type& __c2) + { return __c1 < __c2; } + + static int + compare(const char_type* __s1, const char_type* __s2, size_t __n) + { return wmemcmp(__s1, __s2, __n); } + + static size_t + length(const char_type* __s) + { return wcslen(__s); } + + static const char_type* + find(const char_type* __s, size_t __n, const char_type& __a) + { return wmemchr(__s, __a, __n); } + + static char_type* + move(char_type* __s1, const char_type* __s2, size_t __n) + { return wmemmove(__s1, __s2, __n); } + + static char_type* + copy(char_type* __s1, const char_type* __s2, size_t __n) + { return wmemcpy(__s1, __s2, __n); } + + static char_type* + assign(char_type* __s, size_t __n, char_type __a) + { return wmemset(__s, __a, __n); } + + static char_type + to_char_type(const int_type& __c) + { return char_type(__c); } + + static int_type + to_int_type(const char_type& __c) + { return int_type(__c); } + + static bool + eq_int_type(const int_type& __c1, const int_type& __c2) + { return __c1 == __c2; } + + static int_type + eof() + { return static_cast((0xffffffffu)); } + + static int_type + not_eof(const int_type& __c) + { return eq_int_type(__c, eof()) ? 0 : __c; } + }; + + + +} +# 41 "/usr/include/c++/4.8.2/ios" 2 3 +# 1 "/usr/include/c++/4.8.2/bits/localefwd.h" 1 3 +# 37 "/usr/include/c++/4.8.2/bits/localefwd.h" 3 + +# 38 "/usr/include/c++/4.8.2/bits/localefwd.h" 3 + + +# 1 "/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/c++locale.h" 1 3 +# 39 "/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/c++locale.h" 3 + +# 40 "/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/c++locale.h" 3 + +# 1 "/usr/include/c++/4.8.2/clocale" 1 3 +# 39 "/usr/include/c++/4.8.2/clocale" 3 + +# 40 "/usr/include/c++/4.8.2/clocale" 3 + + +# 1 "/usr/include/locale.h" 1 3 4 +# 29 "/usr/include/locale.h" 3 4 +# 1 "/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stddef.h" 1 3 4 +# 30 "/usr/include/locale.h" 2 3 4 +# 1 "/usr/include/bits/locale.h" 1 3 4 +# 31 "/usr/include/locale.h" 2 3 4 + +extern "C" { +# 51 "/usr/include/locale.h" 3 4 + + + +struct lconv +{ + + + char *decimal_point; + char *thousands_sep; + + + + + + char *grouping; + + + + + + char *int_curr_symbol; + char *currency_symbol; + char *mon_decimal_point; + char *mon_thousands_sep; + char *mon_grouping; + char *positive_sign; + char *negative_sign; + char int_frac_digits; + char frac_digits; + + char p_cs_precedes; + + char p_sep_by_space; + + char n_cs_precedes; + + char n_sep_by_space; + + + + + + + char p_sign_posn; + char n_sign_posn; + + + char int_p_cs_precedes; + + char int_p_sep_by_space; + + char int_n_cs_precedes; + + char int_n_sep_by_space; + + + + + + + char int_p_sign_posn; + char int_n_sign_posn; +# 121 "/usr/include/locale.h" 3 4 +}; + + + +extern char *setlocale (int __category, const char *__locale) throw (); + + +extern struct lconv *localeconv (void) throw (); + + +# 152 "/usr/include/locale.h" 3 4 +extern __locale_t newlocale (int __category_mask, const char *__locale, + __locale_t __base) throw (); +# 187 "/usr/include/locale.h" 3 4 +extern __locale_t duplocale (__locale_t __dataset) throw (); + + + +extern void freelocale (__locale_t __dataset) throw (); + + + + + + +extern __locale_t uselocale (__locale_t __dataset) throw (); + + + + + + + +} +# 43 "/usr/include/c++/4.8.2/clocale" 2 3 +# 51 "/usr/include/c++/4.8.2/clocale" 3 +namespace std +{ + using ::lconv; + using ::setlocale; + using ::localeconv; +} +# 42 "/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/c++locale.h" 2 3 + + + + + + +namespace __gnu_cxx __attribute__ ((__visibility__ ("default"))) +{ + + + extern "C" __typeof(uselocale) __uselocale; + + +} + + +namespace std __attribute__ ((__visibility__ ("default"))) +{ + + + typedef __locale_t __c_locale; + + + + + + inline int + __convert_from_v(const __c_locale& __cloc __attribute__ ((__unused__)), + char* __out, + const int __size __attribute__ ((__unused__)), + const char* __fmt, ...) + { + + __c_locale __old = __gnu_cxx::__uselocale(__cloc); +# 88 "/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/c++locale.h" 3 + __builtin_va_list __args; + __builtin_va_start(__args, __fmt); + + + const int __ret = __builtin_vsnprintf(__out, __size, __fmt, __args); + + + + + __builtin_va_end(__args); + + + __gnu_cxx::__uselocale(__old); + + + + + + + + return __ret; + } + + +} +# 41 "/usr/include/c++/4.8.2/bits/localefwd.h" 2 3 + +# 1 "/usr/include/c++/4.8.2/cctype" 1 3 +# 39 "/usr/include/c++/4.8.2/cctype" 3 + +# 40 "/usr/include/c++/4.8.2/cctype" 3 + + +# 1 "/usr/include/ctype.h" 1 3 4 +# 27 "/usr/include/ctype.h" 3 4 +# 1 "/usr/include/bits/types.h" 1 3 4 +# 27 "/usr/include/bits/types.h" 3 4 +# 1 "/usr/include/bits/wordsize.h" 1 3 4 +# 28 "/usr/include/bits/types.h" 2 3 4 + + +typedef unsigned char __u_char; +typedef unsigned short int __u_short; +typedef unsigned int __u_int; +typedef unsigned long int __u_long; + + +typedef signed char __int8_t; +typedef unsigned char __uint8_t; +typedef signed short int __int16_t; +typedef unsigned short int __uint16_t; +typedef signed int __int32_t; +typedef unsigned int __uint32_t; + +typedef signed long int __int64_t; +typedef unsigned long int __uint64_t; + + + + + + + +typedef long int __quad_t; +typedef unsigned long int __u_quad_t; +# 130 "/usr/include/bits/types.h" 3 4 +# 1 "/usr/include/bits/typesizes.h" 1 3 4 +# 131 "/usr/include/bits/types.h" 2 3 4 + + +typedef unsigned long int __dev_t; +typedef unsigned int __uid_t; +typedef unsigned int __gid_t; +typedef unsigned long int __ino_t; +typedef unsigned long int __ino64_t; +typedef unsigned int __mode_t; +typedef unsigned long int __nlink_t; +typedef long int __off_t; +typedef long int __off64_t; +typedef int __pid_t; +typedef struct { int __val[2]; } __fsid_t; +typedef long int __clock_t; +typedef unsigned long int __rlim_t; +typedef unsigned long int __rlim64_t; +typedef unsigned int __id_t; +typedef long int __time_t; +typedef unsigned int __useconds_t; +typedef long int __suseconds_t; + +typedef int __daddr_t; +typedef int __key_t; + + +typedef int __clockid_t; + + +typedef void * __timer_t; + + +typedef long int __blksize_t; + + + + +typedef long int __blkcnt_t; +typedef long int __blkcnt64_t; + + +typedef unsigned long int __fsblkcnt_t; +typedef unsigned long int __fsblkcnt64_t; + + +typedef unsigned long int __fsfilcnt_t; +typedef unsigned long int __fsfilcnt64_t; + + +typedef long int __fsword_t; + +typedef long int __ssize_t; + + +typedef long int __syscall_slong_t; + +typedef unsigned long int __syscall_ulong_t; + + + +typedef __off64_t __loff_t; +typedef __quad_t *__qaddr_t; +typedef char *__caddr_t; + + +typedef long int __intptr_t; + + +typedef unsigned int __socklen_t; +# 28 "/usr/include/ctype.h" 2 3 4 + +extern "C" { +# 40 "/usr/include/ctype.h" 3 4 +# 1 "/usr/include/endian.h" 1 3 4 +# 36 "/usr/include/endian.h" 3 4 +# 1 "/usr/include/bits/endian.h" 1 3 4 +# 37 "/usr/include/endian.h" 2 3 4 +# 60 "/usr/include/endian.h" 3 4 +# 1 "/usr/include/bits/byteswap.h" 1 3 4 +# 28 "/usr/include/bits/byteswap.h" 3 4 +# 1 "/usr/include/bits/wordsize.h" 1 3 4 +# 29 "/usr/include/bits/byteswap.h" 2 3 4 + + + + + + +# 1 "/usr/include/bits/byteswap-16.h" 1 3 4 +# 36 "/usr/include/bits/byteswap.h" 2 3 4 +# 44 "/usr/include/bits/byteswap.h" 3 4 +static __inline unsigned int +__bswap_32 (unsigned int __bsx) +{ + return __builtin_bswap32 (__bsx); +} +# 108 "/usr/include/bits/byteswap.h" 3 4 +static __inline __uint64_t +__bswap_64 (__uint64_t __bsx) +{ + return __builtin_bswap64 (__bsx); +} +# 61 "/usr/include/endian.h" 2 3 4 +# 41 "/usr/include/ctype.h" 2 3 4 + + + + + + +enum +{ + _ISupper = ((0) < 8 ? ((1 << (0)) << 8) : ((1 << (0)) >> 8)), + _ISlower = ((1) < 8 ? ((1 << (1)) << 8) : ((1 << (1)) >> 8)), + _ISalpha = ((2) < 8 ? ((1 << (2)) << 8) : ((1 << (2)) >> 8)), + _ISdigit = ((3) < 8 ? ((1 << (3)) << 8) : ((1 << (3)) >> 8)), + _ISxdigit = ((4) < 8 ? ((1 << (4)) << 8) : ((1 << (4)) >> 8)), + _ISspace = ((5) < 8 ? ((1 << (5)) << 8) : ((1 << (5)) >> 8)), + _ISprint = ((6) < 8 ? ((1 << (6)) << 8) : ((1 << (6)) >> 8)), + _ISgraph = ((7) < 8 ? ((1 << (7)) << 8) : ((1 << (7)) >> 8)), + _ISblank = ((8) < 8 ? ((1 << (8)) << 8) : ((1 << (8)) >> 8)), + _IScntrl = ((9) < 8 ? ((1 << (9)) << 8) : ((1 << (9)) >> 8)), + _ISpunct = ((10) < 8 ? ((1 << (10)) << 8) : ((1 << (10)) >> 8)), + _ISalnum = ((11) < 8 ? ((1 << (11)) << 8) : ((1 << (11)) >> 8)) +}; +# 80 "/usr/include/ctype.h" 3 4 +extern const unsigned short int **__ctype_b_loc (void) + throw () __attribute__ ((__const__)); +extern const __int32_t **__ctype_tolower_loc (void) + throw () __attribute__ ((__const__)); +extern const __int32_t **__ctype_toupper_loc (void) + throw () __attribute__ ((__const__)); +# 105 "/usr/include/ctype.h" 3 4 + + + + + + +extern int isalnum (int) throw (); +extern int isalpha (int) throw (); +extern int iscntrl (int) throw (); +extern int isdigit (int) throw (); +extern int islower (int) throw (); +extern int isgraph (int) throw (); +extern int isprint (int) throw (); +extern int ispunct (int) throw (); +extern int isspace (int) throw (); +extern int isupper (int) throw (); +extern int isxdigit (int) throw (); + + + +extern int tolower (int __c) throw (); + + +extern int toupper (int __c) throw (); + + + + + + + + +extern int isblank (int) throw (); + + + + + + +extern int isctype (int __c, int __mask) throw (); + + + + + + +extern int isascii (int __c) throw (); + + + +extern int toascii (int __c) throw (); + + + +extern int _toupper (int) throw (); +extern int _tolower (int) throw (); +# 272 "/usr/include/ctype.h" 3 4 +extern int isalnum_l (int, __locale_t) throw (); +extern int isalpha_l (int, __locale_t) throw (); +extern int iscntrl_l (int, __locale_t) throw (); +extern int isdigit_l (int, __locale_t) throw (); +extern int islower_l (int, __locale_t) throw (); +extern int isgraph_l (int, __locale_t) throw (); +extern int isprint_l (int, __locale_t) throw (); +extern int ispunct_l (int, __locale_t) throw (); +extern int isspace_l (int, __locale_t) throw (); +extern int isupper_l (int, __locale_t) throw (); +extern int isxdigit_l (int, __locale_t) throw (); + +extern int isblank_l (int, __locale_t) throw (); + + + +extern int __tolower_l (int __c, __locale_t __l) throw (); +extern int tolower_l (int __c, __locale_t __l) throw (); + + +extern int __toupper_l (int __c, __locale_t __l) throw (); +extern int toupper_l (int __c, __locale_t __l) throw (); +# 348 "/usr/include/ctype.h" 3 4 +} +# 43 "/usr/include/c++/4.8.2/cctype" 2 3 +# 62 "/usr/include/c++/4.8.2/cctype" 3 +namespace std +{ + using ::isalnum; + using ::isalpha; + using ::iscntrl; + using ::isdigit; + using ::isgraph; + using ::islower; + using ::isprint; + using ::ispunct; + using ::isspace; + using ::isupper; + using ::isxdigit; + using ::tolower; + using ::toupper; +} +# 43 "/usr/include/c++/4.8.2/bits/localefwd.h" 2 3 + +namespace std __attribute__ ((__visibility__ ("default"))) +{ + +# 55 "/usr/include/c++/4.8.2/bits/localefwd.h" 3 + class locale; + + template + bool + has_facet(const locale&) throw(); + + template + const _Facet& + use_facet(const locale&); + + + template + bool + isspace(_CharT, const locale&); + + template + bool + isprint(_CharT, const locale&); + + template + bool + iscntrl(_CharT, const locale&); + + template + bool + isupper(_CharT, const locale&); + + template + bool + islower(_CharT, const locale&); + + template + bool + isalpha(_CharT, const locale&); + + template + bool + isdigit(_CharT, const locale&); + + template + bool + ispunct(_CharT, const locale&); + + template + bool + isxdigit(_CharT, const locale&); + + template + bool + isalnum(_CharT, const locale&); + + template + bool + isgraph(_CharT, const locale&); + + template + _CharT + toupper(_CharT, const locale&); + + template + _CharT + tolower(_CharT, const locale&); + + + class ctype_base; + template + class ctype; + template<> class ctype; + + template<> class ctype; + + template + class ctype_byname; + + + class codecvt_base; + template + class codecvt; + template<> class codecvt; + + template<> class codecvt; + + template + class codecvt_byname; + + + + template > + class num_get; + template > + class num_put; + + template class numpunct; + template class numpunct_byname; + + + template + class collate; + template class + collate_byname; + + + class time_base; + template > + class time_get; + template > + class time_get_byname; + template > + class time_put; + template > + class time_put_byname; + + + class money_base; + + template > + class money_get; + template > + class money_put; + + template + class moneypunct; + template + class moneypunct_byname; + + + class messages_base; + template + class messages; + template + class messages_byname; + + +} +# 42 "/usr/include/c++/4.8.2/ios" 2 3 +# 1 "/usr/include/c++/4.8.2/bits/ios_base.h" 1 3 +# 37 "/usr/include/c++/4.8.2/bits/ios_base.h" 3 + +# 38 "/usr/include/c++/4.8.2/bits/ios_base.h" 3 + +# 1 "/usr/include/c++/4.8.2/ext/atomicity.h" 1 3 +# 32 "/usr/include/c++/4.8.2/ext/atomicity.h" 3 + +# 33 "/usr/include/c++/4.8.2/ext/atomicity.h" 3 + + +# 1 "/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/gthr.h" 1 3 +# 30 "/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/gthr.h" 3 +#pragma GCC visibility push(default) +# 148 "/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/gthr.h" 3 +# 1 "/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/gthr-default.h" 1 3 +# 35 "/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/gthr-default.h" 3 +# 1 "/usr/include/pthread.h" 1 3 4 +# 23 "/usr/include/pthread.h" 3 4 +# 1 "/usr/include/sched.h" 1 3 4 +# 29 "/usr/include/sched.h" 3 4 +# 1 "/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stddef.h" 1 3 4 +# 30 "/usr/include/sched.h" 2 3 4 + + + +# 1 "/usr/include/time.h" 1 3 4 +# 73 "/usr/include/time.h" 3 4 + + +typedef __time_t time_t; + + + +# 120 "/usr/include/time.h" 3 4 +struct timespec + { + __time_t tv_sec; + __syscall_slong_t tv_nsec; + }; +# 34 "/usr/include/sched.h" 2 3 4 + + +typedef __pid_t pid_t; + + + + + +# 1 "/usr/include/bits/sched.h" 1 3 4 +# 73 "/usr/include/bits/sched.h" 3 4 +struct sched_param + { + int __sched_priority; + }; + +extern "C" { + + + +extern int clone (int (*__fn) (void *__arg), void *__child_stack, + int __flags, void *__arg, ...) throw (); + + +extern int unshare (int __flags) throw (); + + +extern int sched_getcpu (void) throw (); + + +extern int setns (int __fd, int __nstype) throw (); + + + +} + + + + + + + +struct __sched_param + { + int __sched_priority; + }; +# 119 "/usr/include/bits/sched.h" 3 4 +typedef unsigned long int __cpu_mask; + + + + + + +typedef struct +{ + __cpu_mask __bits[1024 / (8 * sizeof (__cpu_mask))]; +} cpu_set_t; +# 202 "/usr/include/bits/sched.h" 3 4 +extern "C" { + +extern int __sched_cpucount (size_t __setsize, const cpu_set_t *__setp) + throw (); +extern cpu_set_t *__sched_cpualloc (size_t __count) throw () ; +extern void __sched_cpufree (cpu_set_t *__set) throw (); + +} +# 43 "/usr/include/sched.h" 2 3 4 + + + + +extern "C" { + + +extern int sched_setparam (__pid_t __pid, const struct sched_param *__param) + throw (); + + +extern int sched_getparam (__pid_t __pid, struct sched_param *__param) throw (); + + +extern int sched_setscheduler (__pid_t __pid, int __policy, + const struct sched_param *__param) throw (); + + +extern int sched_getscheduler (__pid_t __pid) throw (); + + +extern int sched_yield (void) throw (); + + +extern int sched_get_priority_max (int __algorithm) throw (); + + +extern int sched_get_priority_min (int __algorithm) throw (); + + +extern int sched_rr_get_interval (__pid_t __pid, struct timespec *__t) throw (); +# 117 "/usr/include/sched.h" 3 4 +extern int sched_setaffinity (__pid_t __pid, size_t __cpusetsize, + const cpu_set_t *__cpuset) throw (); + + +extern int sched_getaffinity (__pid_t __pid, size_t __cpusetsize, + cpu_set_t *__cpuset) throw (); + + +} +# 24 "/usr/include/pthread.h" 2 3 4 +# 1 "/usr/include/time.h" 1 3 4 +# 29 "/usr/include/time.h" 3 4 +extern "C" { + + + + + + + +# 1 "/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stddef.h" 1 3 4 +# 38 "/usr/include/time.h" 2 3 4 + + + +# 1 "/usr/include/bits/time.h" 1 3 4 +# 30 "/usr/include/bits/time.h" 3 4 +struct timeval + { + __time_t tv_sec; + __suseconds_t tv_usec; + }; +# 88 "/usr/include/bits/time.h" 3 4 +# 1 "/usr/include/bits/timex.h" 1 3 4 +# 25 "/usr/include/bits/timex.h" 3 4 +struct timex +{ + unsigned int modes; + __syscall_slong_t offset; + __syscall_slong_t freq; + __syscall_slong_t maxerror; + __syscall_slong_t esterror; + int status; + __syscall_slong_t constant; + __syscall_slong_t precision; + __syscall_slong_t tolerance; + struct timeval time; + __syscall_slong_t tick; + __syscall_slong_t ppsfreq; + __syscall_slong_t jitter; + int shift; + __syscall_slong_t stabil; + __syscall_slong_t jitcnt; + __syscall_slong_t calcnt; + __syscall_slong_t errcnt; + __syscall_slong_t stbcnt; + + int tai; + + + int :32; int :32; int :32; int :32; + int :32; int :32; int :32; int :32; + int :32; int :32; int :32; +}; +# 89 "/usr/include/bits/time.h" 2 3 4 + +extern "C" { + + +extern int clock_adjtime (__clockid_t __clock_id, struct timex *__utx) throw (); + +} +# 42 "/usr/include/time.h" 2 3 4 +# 57 "/usr/include/time.h" 3 4 + + +typedef __clock_t clock_t; + + + +# 91 "/usr/include/time.h" 3 4 +typedef __clockid_t clockid_t; +# 103 "/usr/include/time.h" 3 4 +typedef __timer_t timer_t; +# 131 "/usr/include/time.h" 3 4 + + +struct tm +{ + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; + + + long int tm_gmtoff; + const char *tm_zone; + + + + +}; + + + + + + + + +struct itimerspec + { + struct timespec it_interval; + struct timespec it_value; + }; + + +struct sigevent; +# 186 "/usr/include/time.h" 3 4 + + + +extern clock_t clock (void) throw (); + + +extern time_t time (time_t *__timer) throw (); + + +extern double difftime (time_t __time1, time_t __time0) + throw () __attribute__ ((__const__)); + + +extern time_t mktime (struct tm *__tp) throw (); + + + + + +extern size_t strftime (char *__restrict __s, size_t __maxsize, + const char *__restrict __format, + const struct tm *__restrict __tp) throw (); + + + + + +extern char *strptime (const char *__restrict __s, + const char *__restrict __fmt, struct tm *__tp) + throw (); + + + + + + + +extern size_t strftime_l (char *__restrict __s, size_t __maxsize, + const char *__restrict __format, + const struct tm *__restrict __tp, + __locale_t __loc) throw (); + + + +extern char *strptime_l (const char *__restrict __s, + const char *__restrict __fmt, struct tm *__tp, + __locale_t __loc) throw (); + + + + + + +extern struct tm *gmtime (const time_t *__timer) throw (); + + + +extern struct tm *localtime (const time_t *__timer) throw (); + + + + + +extern struct tm *gmtime_r (const time_t *__restrict __timer, + struct tm *__restrict __tp) throw (); + + + +extern struct tm *localtime_r (const time_t *__restrict __timer, + struct tm *__restrict __tp) throw (); + + + + + +extern char *asctime (const struct tm *__tp) throw (); + + +extern char *ctime (const time_t *__timer) throw (); + + + + + + + +extern char *asctime_r (const struct tm *__restrict __tp, + char *__restrict __buf) throw (); + + +extern char *ctime_r (const time_t *__restrict __timer, + char *__restrict __buf) throw (); + + + + +extern char *__tzname[2]; +extern int __daylight; +extern long int __timezone; + + + + +extern char *tzname[2]; + + + +extern void tzset (void) throw (); + + + +extern int daylight; +extern long int timezone; + + + + + +extern int stime (const time_t *__when) throw (); +# 319 "/usr/include/time.h" 3 4 +extern time_t timegm (struct tm *__tp) throw (); + + +extern time_t timelocal (struct tm *__tp) throw (); + + +extern int dysize (int __year) throw () __attribute__ ((__const__)); +# 334 "/usr/include/time.h" 3 4 +extern int nanosleep (const struct timespec *__requested_time, + struct timespec *__remaining); + + + +extern int clock_getres (clockid_t __clock_id, struct timespec *__res) throw (); + + +extern int clock_gettime (clockid_t __clock_id, struct timespec *__tp) throw (); + + +extern int clock_settime (clockid_t __clock_id, const struct timespec *__tp) + throw (); + + + + + + +extern int clock_nanosleep (clockid_t __clock_id, int __flags, + const struct timespec *__req, + struct timespec *__rem); + + +extern int clock_getcpuclockid (pid_t __pid, clockid_t *__clock_id) throw (); + + + + +extern int timer_create (clockid_t __clock_id, + struct sigevent *__restrict __evp, + timer_t *__restrict __timerid) throw (); + + +extern int timer_delete (timer_t __timerid) throw (); + + +extern int timer_settime (timer_t __timerid, int __flags, + const struct itimerspec *__restrict __value, + struct itimerspec *__restrict __ovalue) throw (); + + +extern int timer_gettime (timer_t __timerid, struct itimerspec *__value) + throw (); + + +extern int timer_getoverrun (timer_t __timerid) throw (); + + + + + +extern int timespec_get (struct timespec *__ts, int __base) + throw () __attribute__ ((__nonnull__ (1))); +# 403 "/usr/include/time.h" 3 4 +extern int getdate_err; +# 412 "/usr/include/time.h" 3 4 +extern struct tm *getdate (const char *__string); +# 426 "/usr/include/time.h" 3 4 +extern int getdate_r (const char *__restrict __string, + struct tm *__restrict __resbufp); + + +} +# 25 "/usr/include/pthread.h" 2 3 4 + +# 1 "/usr/include/bits/pthreadtypes.h" 1 3 4 +# 21 "/usr/include/bits/pthreadtypes.h" 3 4 +# 1 "/usr/include/bits/wordsize.h" 1 3 4 +# 22 "/usr/include/bits/pthreadtypes.h" 2 3 4 +# 60 "/usr/include/bits/pthreadtypes.h" 3 4 +typedef unsigned long int pthread_t; + + +union pthread_attr_t +{ + char __size[56]; + long int __align; +}; + +typedef union pthread_attr_t pthread_attr_t; + + + + + +typedef struct __pthread_internal_list +{ + struct __pthread_internal_list *__prev; + struct __pthread_internal_list *__next; +} __pthread_list_t; +# 90 "/usr/include/bits/pthreadtypes.h" 3 4 +typedef union +{ + struct __pthread_mutex_s + { + int __lock; + unsigned int __count; + int __owner; + + unsigned int __nusers; + + + + int __kind; + + short __spins; + short __elision; + __pthread_list_t __list; +# 125 "/usr/include/bits/pthreadtypes.h" 3 4 + } __data; + char __size[40]; + long int __align; +} pthread_mutex_t; + +typedef union +{ + char __size[4]; + int __align; +} pthread_mutexattr_t; + + + + +typedef union +{ + struct + { + int __lock; + unsigned int __futex; + __extension__ unsigned long long int __total_seq; + __extension__ unsigned long long int __wakeup_seq; + __extension__ unsigned long long int __woken_seq; + void *__mutex; + unsigned int __nwaiters; + unsigned int __broadcast_seq; + } __data; + char __size[48]; + __extension__ long long int __align; +} pthread_cond_t; + +typedef union +{ + char __size[4]; + int __align; +} pthread_condattr_t; + + + +typedef unsigned int pthread_key_t; + + + +typedef int pthread_once_t; + + + + + +typedef union +{ + + struct + { + int __lock; + unsigned int __nr_readers; + unsigned int __readers_wakeup; + unsigned int __writer_wakeup; + unsigned int __nr_readers_queued; + unsigned int __nr_writers_queued; + int __writer; + int __shared; + unsigned long int __pad1; + unsigned long int __pad2; + + + unsigned int __flags; + + } __data; +# 212 "/usr/include/bits/pthreadtypes.h" 3 4 + char __size[56]; + long int __align; +} pthread_rwlock_t; + +typedef union +{ + char __size[8]; + long int __align; +} pthread_rwlockattr_t; + + + + + +typedef volatile int pthread_spinlock_t; + + + + +typedef union +{ + char __size[32]; + long int __align; +} pthread_barrier_t; + +typedef union +{ + char __size[4]; + int __align; +} pthread_barrierattr_t; +# 27 "/usr/include/pthread.h" 2 3 4 +# 1 "/usr/include/bits/setjmp.h" 1 3 4 +# 26 "/usr/include/bits/setjmp.h" 3 4 +# 1 "/usr/include/bits/wordsize.h" 1 3 4 +# 27 "/usr/include/bits/setjmp.h" 2 3 4 + + + + +typedef long int __jmp_buf[8]; +# 28 "/usr/include/pthread.h" 2 3 4 +# 1 "/usr/include/bits/wordsize.h" 1 3 4 +# 29 "/usr/include/pthread.h" 2 3 4 + + + +enum +{ + PTHREAD_CREATE_JOINABLE, + + PTHREAD_CREATE_DETACHED + +}; + + + +enum +{ + PTHREAD_MUTEX_TIMED_NP, + PTHREAD_MUTEX_RECURSIVE_NP, + PTHREAD_MUTEX_ERRORCHECK_NP, + PTHREAD_MUTEX_ADAPTIVE_NP + + , + PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_TIMED_NP, + PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP, + PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP, + PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL + + + + , PTHREAD_MUTEX_FAST_NP = PTHREAD_MUTEX_TIMED_NP + +}; + + + + +enum +{ + PTHREAD_MUTEX_STALLED, + PTHREAD_MUTEX_STALLED_NP = PTHREAD_MUTEX_STALLED, + PTHREAD_MUTEX_ROBUST, + PTHREAD_MUTEX_ROBUST_NP = PTHREAD_MUTEX_ROBUST +}; + + + + + +enum +{ + PTHREAD_PRIO_NONE, + PTHREAD_PRIO_INHERIT, + PTHREAD_PRIO_PROTECT +}; +# 116 "/usr/include/pthread.h" 3 4 +enum +{ + PTHREAD_RWLOCK_PREFER_READER_NP, + PTHREAD_RWLOCK_PREFER_WRITER_NP, + PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP, + PTHREAD_RWLOCK_DEFAULT_NP = PTHREAD_RWLOCK_PREFER_READER_NP +}; +# 157 "/usr/include/pthread.h" 3 4 +enum +{ + PTHREAD_INHERIT_SCHED, + + PTHREAD_EXPLICIT_SCHED + +}; + + + +enum +{ + PTHREAD_SCOPE_SYSTEM, + + PTHREAD_SCOPE_PROCESS + +}; + + + +enum +{ + PTHREAD_PROCESS_PRIVATE, + + PTHREAD_PROCESS_SHARED + +}; +# 192 "/usr/include/pthread.h" 3 4 +struct _pthread_cleanup_buffer +{ + void (*__routine) (void *); + void *__arg; + int __canceltype; + struct _pthread_cleanup_buffer *__prev; +}; + + +enum +{ + PTHREAD_CANCEL_ENABLE, + + PTHREAD_CANCEL_DISABLE + +}; +enum +{ + PTHREAD_CANCEL_DEFERRED, + + PTHREAD_CANCEL_ASYNCHRONOUS + +}; +# 230 "/usr/include/pthread.h" 3 4 +extern "C" { + + + + +extern int pthread_create (pthread_t *__restrict __newthread, + const pthread_attr_t *__restrict __attr, + void *(*__start_routine) (void *), + void *__restrict __arg) throw () __attribute__ ((__nonnull__ (1, 3))); + + + + + +extern void pthread_exit (void *__retval) __attribute__ ((__noreturn__)); + + + + + + + +extern int pthread_join (pthread_t __th, void **__thread_return); + + + + +extern int pthread_tryjoin_np (pthread_t __th, void **__thread_return) throw (); + + + + + + + +extern int pthread_timedjoin_np (pthread_t __th, void **__thread_return, + const struct timespec *__abstime); + + + + + + +extern int pthread_detach (pthread_t __th) throw (); + + + +extern pthread_t pthread_self (void) throw () __attribute__ ((__const__)); + + +extern int pthread_equal (pthread_t __thread1, pthread_t __thread2) + throw () __attribute__ ((__const__)); + + + + + + + +extern int pthread_attr_init (pthread_attr_t *__attr) throw () __attribute__ ((__nonnull__ (1))); + + +extern int pthread_attr_destroy (pthread_attr_t *__attr) + throw () __attribute__ ((__nonnull__ (1))); + + +extern int pthread_attr_getdetachstate (const pthread_attr_t *__attr, + int *__detachstate) + throw () __attribute__ ((__nonnull__ (1, 2))); + + +extern int pthread_attr_setdetachstate (pthread_attr_t *__attr, + int __detachstate) + throw () __attribute__ ((__nonnull__ (1))); + + + +extern int pthread_attr_getguardsize (const pthread_attr_t *__attr, + size_t *__guardsize) + throw () __attribute__ ((__nonnull__ (1, 2))); + + +extern int pthread_attr_setguardsize (pthread_attr_t *__attr, + size_t __guardsize) + throw () __attribute__ ((__nonnull__ (1))); + + + +extern int pthread_attr_getschedparam (const pthread_attr_t *__restrict __attr, + struct sched_param *__restrict __param) + throw () __attribute__ ((__nonnull__ (1, 2))); + + +extern int pthread_attr_setschedparam (pthread_attr_t *__restrict __attr, + const struct sched_param *__restrict + __param) throw () __attribute__ ((__nonnull__ (1, 2))); + + +extern int pthread_attr_getschedpolicy (const pthread_attr_t *__restrict + __attr, int *__restrict __policy) + throw () __attribute__ ((__nonnull__ (1, 2))); + + +extern int pthread_attr_setschedpolicy (pthread_attr_t *__attr, int __policy) + throw () __attribute__ ((__nonnull__ (1))); + + +extern int pthread_attr_getinheritsched (const pthread_attr_t *__restrict + __attr, int *__restrict __inherit) + throw () __attribute__ ((__nonnull__ (1, 2))); + + +extern int pthread_attr_setinheritsched (pthread_attr_t *__attr, + int __inherit) + throw () __attribute__ ((__nonnull__ (1))); + + + +extern int pthread_attr_getscope (const pthread_attr_t *__restrict __attr, + int *__restrict __scope) + throw () __attribute__ ((__nonnull__ (1, 2))); + + +extern int pthread_attr_setscope (pthread_attr_t *__attr, int __scope) + throw () __attribute__ ((__nonnull__ (1))); + + +extern int pthread_attr_getstackaddr (const pthread_attr_t *__restrict + __attr, void **__restrict __stackaddr) + throw () __attribute__ ((__nonnull__ (1, 2))) __attribute__ ((__deprecated__)); + + + + + +extern int pthread_attr_setstackaddr (pthread_attr_t *__attr, + void *__stackaddr) + throw () __attribute__ ((__nonnull__ (1))) __attribute__ ((__deprecated__)); + + +extern int pthread_attr_getstacksize (const pthread_attr_t *__restrict + __attr, size_t *__restrict __stacksize) + throw () __attribute__ ((__nonnull__ (1, 2))); + + + + +extern int pthread_attr_setstacksize (pthread_attr_t *__attr, + size_t __stacksize) + throw () __attribute__ ((__nonnull__ (1))); + + + +extern int pthread_attr_getstack (const pthread_attr_t *__restrict __attr, + void **__restrict __stackaddr, + size_t *__restrict __stacksize) + throw () __attribute__ ((__nonnull__ (1, 2, 3))); + + + + +extern int pthread_attr_setstack (pthread_attr_t *__attr, void *__stackaddr, + size_t __stacksize) throw () __attribute__ ((__nonnull__ (1))); + + + + + +extern int pthread_attr_setaffinity_np (pthread_attr_t *__attr, + size_t __cpusetsize, + const cpu_set_t *__cpuset) + throw () __attribute__ ((__nonnull__ (1, 3))); + + + +extern int pthread_attr_getaffinity_np (const pthread_attr_t *__attr, + size_t __cpusetsize, + cpu_set_t *__cpuset) + throw () __attribute__ ((__nonnull__ (1, 3))); + + + + + +extern int pthread_getattr_np (pthread_t __th, pthread_attr_t *__attr) + throw () __attribute__ ((__nonnull__ (2))); + + + + + + + +extern int pthread_setschedparam (pthread_t __target_thread, int __policy, + const struct sched_param *__param) + throw () __attribute__ ((__nonnull__ (3))); + + +extern int pthread_getschedparam (pthread_t __target_thread, + int *__restrict __policy, + struct sched_param *__restrict __param) + throw () __attribute__ ((__nonnull__ (2, 3))); + + +extern int pthread_setschedprio (pthread_t __target_thread, int __prio) + throw (); + + + + +extern int pthread_getname_np (pthread_t __target_thread, char *__buf, + size_t __buflen) + throw () __attribute__ ((__nonnull__ (2))); + + +extern int pthread_setname_np (pthread_t __target_thread, const char *__name) + throw () __attribute__ ((__nonnull__ (2))); + + + + + +extern int pthread_getconcurrency (void) throw (); + + +extern int pthread_setconcurrency (int __level) throw (); + + + + + + + +extern int pthread_yield (void) throw (); + + + + +extern int pthread_setaffinity_np (pthread_t __th, size_t __cpusetsize, + const cpu_set_t *__cpuset) + throw () __attribute__ ((__nonnull__ (3))); + + +extern int pthread_getaffinity_np (pthread_t __th, size_t __cpusetsize, + cpu_set_t *__cpuset) + throw () __attribute__ ((__nonnull__ (3))); +# 488 "/usr/include/pthread.h" 3 4 +extern int pthread_once (pthread_once_t *__once_control, + void (*__init_routine) (void)) __attribute__ ((__nonnull__ (1, 2))); +# 500 "/usr/include/pthread.h" 3 4 +extern int pthread_setcancelstate (int __state, int *__oldstate); + + + +extern int pthread_setcanceltype (int __type, int *__oldtype); + + +extern int pthread_cancel (pthread_t __th); + + + + +extern void pthread_testcancel (void); + + + + +typedef struct +{ + struct + { + __jmp_buf __cancel_jmp_buf; + int __mask_was_saved; + } __cancel_jmp_buf[1]; + void *__pad[4]; +} __pthread_unwind_buf_t __attribute__ ((__aligned__)); +# 534 "/usr/include/pthread.h" 3 4 +struct __pthread_cleanup_frame +{ + void (*__cancel_routine) (void *); + void *__cancel_arg; + int __do_it; + int __cancel_type; +}; + + + + +class __pthread_cleanup_class +{ + void (*__cancel_routine) (void *); + void *__cancel_arg; + int __do_it; + int __cancel_type; + + public: + __pthread_cleanup_class (void (*__fct) (void *), void *__arg) + : __cancel_routine (__fct), __cancel_arg (__arg), __do_it (1) { } + ~__pthread_cleanup_class () { if (__do_it) __cancel_routine (__cancel_arg); } + void __setdoit (int __newval) { __do_it = __newval; } + void __defer () { pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, + &__cancel_type); } + void __restore () const { pthread_setcanceltype (__cancel_type, 0); } +}; +# 736 "/usr/include/pthread.h" 3 4 +struct __jmp_buf_tag; +extern int __sigsetjmp (struct __jmp_buf_tag *__env, int __savemask) throw (); + + + + + +extern int pthread_mutex_init (pthread_mutex_t *__mutex, + const pthread_mutexattr_t *__mutexattr) + throw () __attribute__ ((__nonnull__ (1))); + + +extern int pthread_mutex_destroy (pthread_mutex_t *__mutex) + throw () __attribute__ ((__nonnull__ (1))); + + +extern int pthread_mutex_trylock (pthread_mutex_t *__mutex) + throw () __attribute__ ((__nonnull__ (1))); + + +extern int pthread_mutex_lock (pthread_mutex_t *__mutex) + throw () __attribute__ ((__nonnull__ (1))); + + + +extern int pthread_mutex_timedlock (pthread_mutex_t *__restrict __mutex, + const struct timespec *__restrict + __abstime) throw () __attribute__ ((__nonnull__ (1, 2))); + + + +extern int pthread_mutex_unlock (pthread_mutex_t *__mutex) + throw () __attribute__ ((__nonnull__ (1))); + + + +extern int pthread_mutex_getprioceiling (const pthread_mutex_t * + __restrict __mutex, + int *__restrict __prioceiling) + throw () __attribute__ ((__nonnull__ (1, 2))); + + + +extern int pthread_mutex_setprioceiling (pthread_mutex_t *__restrict __mutex, + int __prioceiling, + int *__restrict __old_ceiling) + throw () __attribute__ ((__nonnull__ (1, 3))); + + + + +extern int pthread_mutex_consistent (pthread_mutex_t *__mutex) + throw () __attribute__ ((__nonnull__ (1))); + +extern int pthread_mutex_consistent_np (pthread_mutex_t *__mutex) + throw () __attribute__ ((__nonnull__ (1))); +# 800 "/usr/include/pthread.h" 3 4 +extern int pthread_mutexattr_init (pthread_mutexattr_t *__attr) + throw () __attribute__ ((__nonnull__ (1))); + + +extern int pthread_mutexattr_destroy (pthread_mutexattr_t *__attr) + throw () __attribute__ ((__nonnull__ (1))); + + +extern int pthread_mutexattr_getpshared (const pthread_mutexattr_t * + __restrict __attr, + int *__restrict __pshared) + throw () __attribute__ ((__nonnull__ (1, 2))); + + +extern int pthread_mutexattr_setpshared (pthread_mutexattr_t *__attr, + int __pshared) + throw () __attribute__ ((__nonnull__ (1))); + + + +extern int pthread_mutexattr_gettype (const pthread_mutexattr_t *__restrict + __attr, int *__restrict __kind) + throw () __attribute__ ((__nonnull__ (1, 2))); + + + + +extern int pthread_mutexattr_settype (pthread_mutexattr_t *__attr, int __kind) + throw () __attribute__ ((__nonnull__ (1))); + + + +extern int pthread_mutexattr_getprotocol (const pthread_mutexattr_t * + __restrict __attr, + int *__restrict __protocol) + throw () __attribute__ ((__nonnull__ (1, 2))); + + + +extern int pthread_mutexattr_setprotocol (pthread_mutexattr_t *__attr, + int __protocol) + throw () __attribute__ ((__nonnull__ (1))); + + +extern int pthread_mutexattr_getprioceiling (const pthread_mutexattr_t * + __restrict __attr, + int *__restrict __prioceiling) + throw () __attribute__ ((__nonnull__ (1, 2))); + + +extern int pthread_mutexattr_setprioceiling (pthread_mutexattr_t *__attr, + int __prioceiling) + throw () __attribute__ ((__nonnull__ (1))); + + + +extern int pthread_mutexattr_getrobust (const pthread_mutexattr_t *__attr, + int *__robustness) + throw () __attribute__ ((__nonnull__ (1, 2))); + +extern int pthread_mutexattr_getrobust_np (const pthread_mutexattr_t *__attr, + int *__robustness) + throw () __attribute__ ((__nonnull__ (1, 2))); + + + +extern int pthread_mutexattr_setrobust (pthread_mutexattr_t *__attr, + int __robustness) + throw () __attribute__ ((__nonnull__ (1))); + +extern int pthread_mutexattr_setrobust_np (pthread_mutexattr_t *__attr, + int __robustness) + throw () __attribute__ ((__nonnull__ (1))); +# 882 "/usr/include/pthread.h" 3 4 +extern int pthread_rwlock_init (pthread_rwlock_t *__restrict __rwlock, + const pthread_rwlockattr_t *__restrict + __attr) throw () __attribute__ ((__nonnull__ (1))); + + +extern int pthread_rwlock_destroy (pthread_rwlock_t *__rwlock) + throw () __attribute__ ((__nonnull__ (1))); + + +extern int pthread_rwlock_rdlock (pthread_rwlock_t *__rwlock) + throw () __attribute__ ((__nonnull__ (1))); + + +extern int pthread_rwlock_tryrdlock (pthread_rwlock_t *__rwlock) + throw () __attribute__ ((__nonnull__ (1))); + + + +extern int pthread_rwlock_timedrdlock (pthread_rwlock_t *__restrict __rwlock, + const struct timespec *__restrict + __abstime) throw () __attribute__ ((__nonnull__ (1, 2))); + + + +extern int pthread_rwlock_wrlock (pthread_rwlock_t *__rwlock) + throw () __attribute__ ((__nonnull__ (1))); + + +extern int pthread_rwlock_trywrlock (pthread_rwlock_t *__rwlock) + throw () __attribute__ ((__nonnull__ (1))); + + + +extern int pthread_rwlock_timedwrlock (pthread_rwlock_t *__restrict __rwlock, + const struct timespec *__restrict + __abstime) throw () __attribute__ ((__nonnull__ (1, 2))); + + + +extern int pthread_rwlock_unlock (pthread_rwlock_t *__rwlock) + throw () __attribute__ ((__nonnull__ (1))); + + + + + +extern int pthread_rwlockattr_init (pthread_rwlockattr_t *__attr) + throw () __attribute__ ((__nonnull__ (1))); + + +extern int pthread_rwlockattr_destroy (pthread_rwlockattr_t *__attr) + throw () __attribute__ ((__nonnull__ (1))); + + +extern int pthread_rwlockattr_getpshared (const pthread_rwlockattr_t * + __restrict __attr, + int *__restrict __pshared) + throw () __attribute__ ((__nonnull__ (1, 2))); + + +extern int pthread_rwlockattr_setpshared (pthread_rwlockattr_t *__attr, + int __pshared) + throw () __attribute__ ((__nonnull__ (1))); + + +extern int pthread_rwlockattr_getkind_np (const pthread_rwlockattr_t * + __restrict __attr, + int *__restrict __pref) + throw () __attribute__ ((__nonnull__ (1, 2))); + + +extern int pthread_rwlockattr_setkind_np (pthread_rwlockattr_t *__attr, + int __pref) throw () __attribute__ ((__nonnull__ (1))); + + + + + + + +extern int pthread_cond_init (pthread_cond_t *__restrict __cond, + const pthread_condattr_t *__restrict __cond_attr) + throw () __attribute__ ((__nonnull__ (1))); + + +extern int pthread_cond_destroy (pthread_cond_t *__cond) + throw () __attribute__ ((__nonnull__ (1))); + + +extern int pthread_cond_signal (pthread_cond_t *__cond) + throw () __attribute__ ((__nonnull__ (1))); + + +extern int pthread_cond_broadcast (pthread_cond_t *__cond) + throw () __attribute__ ((__nonnull__ (1))); + + + + + + +extern int pthread_cond_wait (pthread_cond_t *__restrict __cond, + pthread_mutex_t *__restrict __mutex) + __attribute__ ((__nonnull__ (1, 2))); +# 994 "/usr/include/pthread.h" 3 4 +extern int pthread_cond_timedwait (pthread_cond_t *__restrict __cond, + pthread_mutex_t *__restrict __mutex, + const struct timespec *__restrict __abstime) + __attribute__ ((__nonnull__ (1, 2, 3))); + + + + +extern int pthread_condattr_init (pthread_condattr_t *__attr) + throw () __attribute__ ((__nonnull__ (1))); + + +extern int pthread_condattr_destroy (pthread_condattr_t *__attr) + throw () __attribute__ ((__nonnull__ (1))); + + +extern int pthread_condattr_getpshared (const pthread_condattr_t * + __restrict __attr, + int *__restrict __pshared) + throw () __attribute__ ((__nonnull__ (1, 2))); + + +extern int pthread_condattr_setpshared (pthread_condattr_t *__attr, + int __pshared) throw () __attribute__ ((__nonnull__ (1))); + + + +extern int pthread_condattr_getclock (const pthread_condattr_t * + __restrict __attr, + __clockid_t *__restrict __clock_id) + throw () __attribute__ ((__nonnull__ (1, 2))); + + +extern int pthread_condattr_setclock (pthread_condattr_t *__attr, + __clockid_t __clock_id) + throw () __attribute__ ((__nonnull__ (1))); +# 1038 "/usr/include/pthread.h" 3 4 +extern int pthread_spin_init (pthread_spinlock_t *__lock, int __pshared) + throw () __attribute__ ((__nonnull__ (1))); + + +extern int pthread_spin_destroy (pthread_spinlock_t *__lock) + throw () __attribute__ ((__nonnull__ (1))); + + +extern int pthread_spin_lock (pthread_spinlock_t *__lock) + throw () __attribute__ ((__nonnull__ (1))); + + +extern int pthread_spin_trylock (pthread_spinlock_t *__lock) + throw () __attribute__ ((__nonnull__ (1))); + + +extern int pthread_spin_unlock (pthread_spinlock_t *__lock) + throw () __attribute__ ((__nonnull__ (1))); + + + + + + +extern int pthread_barrier_init (pthread_barrier_t *__restrict __barrier, + const pthread_barrierattr_t *__restrict + __attr, unsigned int __count) + throw () __attribute__ ((__nonnull__ (1))); + + +extern int pthread_barrier_destroy (pthread_barrier_t *__barrier) + throw () __attribute__ ((__nonnull__ (1))); + + +extern int pthread_barrier_wait (pthread_barrier_t *__barrier) + throw () __attribute__ ((__nonnull__ (1))); + + + +extern int pthread_barrierattr_init (pthread_barrierattr_t *__attr) + throw () __attribute__ ((__nonnull__ (1))); + + +extern int pthread_barrierattr_destroy (pthread_barrierattr_t *__attr) + throw () __attribute__ ((__nonnull__ (1))); + + +extern int pthread_barrierattr_getpshared (const pthread_barrierattr_t * + __restrict __attr, + int *__restrict __pshared) + throw () __attribute__ ((__nonnull__ (1, 2))); + + +extern int pthread_barrierattr_setpshared (pthread_barrierattr_t *__attr, + int __pshared) + throw () __attribute__ ((__nonnull__ (1))); +# 1105 "/usr/include/pthread.h" 3 4 +extern int pthread_key_create (pthread_key_t *__key, + void (*__destr_function) (void *)) + throw () __attribute__ ((__nonnull__ (1))); + + +extern int pthread_key_delete (pthread_key_t __key) throw (); + + +extern void *pthread_getspecific (pthread_key_t __key) throw (); + + +extern int pthread_setspecific (pthread_key_t __key, + const void *__pointer) throw () ; + + + + +extern int pthread_getcpuclockid (pthread_t __thread_id, + __clockid_t *__clock_id) + throw () __attribute__ ((__nonnull__ (2))); +# 1139 "/usr/include/pthread.h" 3 4 +extern int pthread_atfork (void (*__prepare) (void), + void (*__parent) (void), + void (*__child) (void)) throw (); +# 1153 "/usr/include/pthread.h" 3 4 +} +# 36 "/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/gthr-default.h" 2 3 +# 47 "/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/gthr-default.h" 3 +typedef pthread_t __gthread_t; +typedef pthread_key_t __gthread_key_t; +typedef pthread_once_t __gthread_once_t; +typedef pthread_mutex_t __gthread_mutex_t; +typedef pthread_mutex_t __gthread_recursive_mutex_t; +typedef pthread_cond_t __gthread_cond_t; +typedef struct timespec __gthread_time_t; +# 101 "/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/gthr-default.h" 3 +static __typeof(pthread_once) __gthrw_pthread_once __attribute__ ((__weakref__("pthread_once"))); +static __typeof(pthread_getspecific) __gthrw_pthread_getspecific __attribute__ ((__weakref__("pthread_getspecific"))); +static __typeof(pthread_setspecific) __gthrw_pthread_setspecific __attribute__ ((__weakref__("pthread_setspecific"))); + +static __typeof(pthread_create) __gthrw_pthread_create __attribute__ ((__weakref__("pthread_create"))); +static __typeof(pthread_join) __gthrw_pthread_join __attribute__ ((__weakref__("pthread_join"))); +static __typeof(pthread_equal) __gthrw_pthread_equal __attribute__ ((__weakref__("pthread_equal"))); +static __typeof(pthread_self) __gthrw_pthread_self __attribute__ ((__weakref__("pthread_self"))); +static __typeof(pthread_detach) __gthrw_pthread_detach __attribute__ ((__weakref__("pthread_detach"))); + +static __typeof(pthread_cancel) __gthrw_pthread_cancel __attribute__ ((__weakref__("pthread_cancel"))); + +static __typeof(sched_yield) __gthrw_sched_yield __attribute__ ((__weakref__("sched_yield"))); + +static __typeof(pthread_mutex_lock) __gthrw_pthread_mutex_lock __attribute__ ((__weakref__("pthread_mutex_lock"))); +static __typeof(pthread_mutex_trylock) __gthrw_pthread_mutex_trylock __attribute__ ((__weakref__("pthread_mutex_trylock"))); + +static __typeof(pthread_mutex_timedlock) __gthrw_pthread_mutex_timedlock __attribute__ ((__weakref__("pthread_mutex_timedlock"))); + +static __typeof(pthread_mutex_unlock) __gthrw_pthread_mutex_unlock __attribute__ ((__weakref__("pthread_mutex_unlock"))); +static __typeof(pthread_mutex_init) __gthrw_pthread_mutex_init __attribute__ ((__weakref__("pthread_mutex_init"))); +static __typeof(pthread_mutex_destroy) __gthrw_pthread_mutex_destroy __attribute__ ((__weakref__("pthread_mutex_destroy"))); + +static __typeof(pthread_cond_init) __gthrw_pthread_cond_init __attribute__ ((__weakref__("pthread_cond_init"))); +static __typeof(pthread_cond_broadcast) __gthrw_pthread_cond_broadcast __attribute__ ((__weakref__("pthread_cond_broadcast"))); +static __typeof(pthread_cond_signal) __gthrw_pthread_cond_signal __attribute__ ((__weakref__("pthread_cond_signal"))); +static __typeof(pthread_cond_wait) __gthrw_pthread_cond_wait __attribute__ ((__weakref__("pthread_cond_wait"))); +static __typeof(pthread_cond_timedwait) __gthrw_pthread_cond_timedwait __attribute__ ((__weakref__("pthread_cond_timedwait"))); +static __typeof(pthread_cond_destroy) __gthrw_pthread_cond_destroy __attribute__ ((__weakref__("pthread_cond_destroy"))); + +static __typeof(pthread_key_create) __gthrw_pthread_key_create __attribute__ ((__weakref__("pthread_key_create"))); +static __typeof(pthread_key_delete) __gthrw_pthread_key_delete __attribute__ ((__weakref__("pthread_key_delete"))); +static __typeof(pthread_mutexattr_init) __gthrw_pthread_mutexattr_init __attribute__ ((__weakref__("pthread_mutexattr_init"))); +static __typeof(pthread_mutexattr_settype) __gthrw_pthread_mutexattr_settype __attribute__ ((__weakref__("pthread_mutexattr_settype"))); +static __typeof(pthread_mutexattr_destroy) __gthrw_pthread_mutexattr_destroy __attribute__ ((__weakref__("pthread_mutexattr_destroy"))); +# 236 "/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/gthr-default.h" 3 +static __typeof(pthread_key_create) __gthrw___pthread_key_create __attribute__ ((__weakref__("__pthread_key_create"))); +# 246 "/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/gthr-default.h" 3 +static inline int +__gthread_active_p (void) +{ + static void *const __gthread_active_ptr + = __extension__ (void *) &__gthrw___pthread_key_create; + return __gthread_active_ptr != 0; +} +# 658 "/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/gthr-default.h" 3 +static inline int +__gthread_create (__gthread_t *__threadid, void *(*__func) (void*), + void *__args) +{ + return __gthrw_pthread_create (__threadid, __null, __func, __args); +} + +static inline int +__gthread_join (__gthread_t __threadid, void **__value_ptr) +{ + return __gthrw_pthread_join (__threadid, __value_ptr); +} + +static inline int +__gthread_detach (__gthread_t __threadid) +{ + return __gthrw_pthread_detach (__threadid); +} + +static inline int +__gthread_equal (__gthread_t __t1, __gthread_t __t2) +{ + return __gthrw_pthread_equal (__t1, __t2); +} + +static inline __gthread_t +__gthread_self (void) +{ + return __gthrw_pthread_self (); +} + +static inline int +__gthread_yield (void) +{ + return __gthrw_sched_yield (); +} + +static inline int +__gthread_once (__gthread_once_t *__once, void (*__func) (void)) +{ + if (__gthread_active_p ()) + return __gthrw_pthread_once (__once, __func); + else + return -1; +} + +static inline int +__gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *)) +{ + return __gthrw_pthread_key_create (__key, __dtor); +} + +static inline int +__gthread_key_delete (__gthread_key_t __key) +{ + return __gthrw_pthread_key_delete (__key); +} + +static inline void * +__gthread_getspecific (__gthread_key_t __key) +{ + return __gthrw_pthread_getspecific (__key); +} + +static inline int +__gthread_setspecific (__gthread_key_t __key, const void *__ptr) +{ + return __gthrw_pthread_setspecific (__key, __ptr); +} + +static inline void +__gthread_mutex_init_function (__gthread_mutex_t *__mutex) +{ + if (__gthread_active_p ()) + __gthrw_pthread_mutex_init (__mutex, __null); +} + +static inline int +__gthread_mutex_destroy (__gthread_mutex_t *__mutex) +{ + if (__gthread_active_p ()) + return __gthrw_pthread_mutex_destroy (__mutex); + else + return 0; +} + +static inline int +__gthread_mutex_lock (__gthread_mutex_t *__mutex) +{ + if (__gthread_active_p ()) + return __gthrw_pthread_mutex_lock (__mutex); + else + return 0; +} + +static inline int +__gthread_mutex_trylock (__gthread_mutex_t *__mutex) +{ + if (__gthread_active_p ()) + return __gthrw_pthread_mutex_trylock (__mutex); + else + return 0; +} + + +static inline int +__gthread_mutex_timedlock (__gthread_mutex_t *__mutex, + const __gthread_time_t *__abs_timeout) +{ + if (__gthread_active_p ()) + return __gthrw_pthread_mutex_timedlock (__mutex, __abs_timeout); + else + return 0; +} + + +static inline int +__gthread_mutex_unlock (__gthread_mutex_t *__mutex) +{ + if (__gthread_active_p ()) + return __gthrw_pthread_mutex_unlock (__mutex); + else + return 0; +} +# 807 "/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/gthr-default.h" 3 +static inline int +__gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex) +{ + return __gthread_mutex_lock (__mutex); +} + +static inline int +__gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex) +{ + return __gthread_mutex_trylock (__mutex); +} + + +static inline int +__gthread_recursive_mutex_timedlock (__gthread_recursive_mutex_t *__mutex, + const __gthread_time_t *__abs_timeout) +{ + return __gthread_mutex_timedlock (__mutex, __abs_timeout); +} + + +static inline int +__gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex) +{ + return __gthread_mutex_unlock (__mutex); +} + +static inline int +__gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t *__mutex) +{ + return __gthread_mutex_destroy (__mutex); +} +# 849 "/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/gthr-default.h" 3 +static inline int +__gthread_cond_broadcast (__gthread_cond_t *__cond) +{ + return __gthrw_pthread_cond_broadcast (__cond); +} + +static inline int +__gthread_cond_signal (__gthread_cond_t *__cond) +{ + return __gthrw_pthread_cond_signal (__cond); +} + +static inline int +__gthread_cond_wait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex) +{ + return __gthrw_pthread_cond_wait (__cond, __mutex); +} + +static inline int +__gthread_cond_timedwait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex, + const __gthread_time_t *__abs_timeout) +{ + return __gthrw_pthread_cond_timedwait (__cond, __mutex, __abs_timeout); +} + +static inline int +__gthread_cond_wait_recursive (__gthread_cond_t *__cond, + __gthread_recursive_mutex_t *__mutex) +{ + return __gthread_cond_wait (__cond, __mutex); +} + +static inline int +__gthread_cond_destroy (__gthread_cond_t* __cond) +{ + return __gthrw_pthread_cond_destroy (__cond); +} +# 149 "/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/gthr.h" 2 3 + + +#pragma GCC visibility pop +# 36 "/usr/include/c++/4.8.2/ext/atomicity.h" 2 3 +# 1 "/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/atomic_word.h" 1 3 +# 32 "/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/atomic_word.h" 3 +typedef int _Atomic_word; +# 37 "/usr/include/c++/4.8.2/ext/atomicity.h" 2 3 + +namespace __gnu_cxx __attribute__ ((__visibility__ ("default"))) +{ + + + + + + + + static inline _Atomic_word + __exchange_and_add(volatile _Atomic_word* __mem, int __val) + { return __atomic_fetch_add(__mem, __val, 4); } + + static inline void + __atomic_add(volatile _Atomic_word* __mem, int __val) + { __atomic_fetch_add(__mem, __val, 4); } +# 64 "/usr/include/c++/4.8.2/ext/atomicity.h" 3 + static inline _Atomic_word + __exchange_and_add_single(_Atomic_word* __mem, int __val) + { + _Atomic_word __result = *__mem; + *__mem += __val; + return __result; + } + + static inline void + __atomic_add_single(_Atomic_word* __mem, int __val) + { *__mem += __val; } + + static inline _Atomic_word + __attribute__ ((__unused__)) + __exchange_and_add_dispatch(_Atomic_word* __mem, int __val) + { + + if (__gthread_active_p()) + return __exchange_and_add(__mem, __val); + else + return __exchange_and_add_single(__mem, __val); + + + + } + + static inline void + __attribute__ ((__unused__)) + __atomic_add_dispatch(_Atomic_word* __mem, int __val) + { + + if (__gthread_active_p()) + __atomic_add(__mem, __val); + else + __atomic_add_single(__mem, __val); + + + + } + + +} +# 40 "/usr/include/c++/4.8.2/bits/ios_base.h" 2 3 + +# 1 "/usr/include/c++/4.8.2/bits/locale_classes.h" 1 3 +# 37 "/usr/include/c++/4.8.2/bits/locale_classes.h" 3 + +# 38 "/usr/include/c++/4.8.2/bits/locale_classes.h" 3 + + +# 1 "/usr/include/c++/4.8.2/string" 1 3 +# 36 "/usr/include/c++/4.8.2/string" 3 + +# 37 "/usr/include/c++/4.8.2/string" 3 + + + + +# 1 "/usr/include/c++/4.8.2/bits/allocator.h" 1 3 +# 46 "/usr/include/c++/4.8.2/bits/allocator.h" 3 +# 1 "/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/c++allocator.h" 1 3 +# 33 "/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/c++allocator.h" 3 +# 1 "/usr/include/c++/4.8.2/ext/new_allocator.h" 1 3 +# 33 "/usr/include/c++/4.8.2/ext/new_allocator.h" 3 +# 1 "/usr/include/c++/4.8.2/new" 1 3 +# 37 "/usr/include/c++/4.8.2/new" 3 + +# 38 "/usr/include/c++/4.8.2/new" 3 + + + + +#pragma GCC visibility push(default) + +extern "C++" { + +namespace std +{ + + + + + + + class bad_alloc : public exception + { + public: + bad_alloc() throw() { } + + + + virtual ~bad_alloc() throw(); + + + virtual const char* what() const throw(); + }; + + struct nothrow_t { }; + + extern const nothrow_t nothrow; + + + + typedef void (*new_handler)(); + + + + new_handler set_new_handler(new_handler) throw(); +} +# 91 "/usr/include/c++/4.8.2/new" 3 +void* operator new(std::size_t) throw(std::bad_alloc) + __attribute__((__externally_visible__)); +void* operator new[](std::size_t) throw(std::bad_alloc) + __attribute__((__externally_visible__)); +void operator delete(void*) throw() + __attribute__((__externally_visible__)); +void operator delete[](void*) throw() + __attribute__((__externally_visible__)); +void* operator new(std::size_t, const std::nothrow_t&) throw() + __attribute__((__externally_visible__)); +void* operator new[](std::size_t, const std::nothrow_t&) throw() + __attribute__((__externally_visible__)); +void operator delete(void*, const std::nothrow_t&) throw() + __attribute__((__externally_visible__)); +void operator delete[](void*, const std::nothrow_t&) throw() + __attribute__((__externally_visible__)); + + +inline void* operator new(std::size_t, void* __p) throw() +{ return __p; } +inline void* operator new[](std::size_t, void* __p) throw() +{ return __p; } + + +inline void operator delete (void*, void*) throw() { } +inline void operator delete[](void*, void*) throw() { } + +} + +#pragma GCC visibility pop +# 34 "/usr/include/c++/4.8.2/ext/new_allocator.h" 2 3 + + + + + + +namespace __gnu_cxx __attribute__ ((__visibility__ ("default"))) +{ + + + using std::size_t; + using std::ptrdiff_t; +# 57 "/usr/include/c++/4.8.2/ext/new_allocator.h" 3 + template + class new_allocator + { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef _Tp value_type; + + template + struct rebind + { typedef new_allocator<_Tp1> other; }; + + + + + + + + new_allocator() throw() { } + + new_allocator(const new_allocator&) throw() { } + + template + new_allocator(const new_allocator<_Tp1>&) throw() { } + + ~new_allocator() throw() { } + + pointer + address(reference __x) const + { return std::__addressof(__x); } + + const_pointer + address(const_reference __x) const + { return std::__addressof(__x); } + + + + pointer + allocate(size_type __n, const void* = 0) + { + if (__n > this->max_size()) + std::__throw_bad_alloc(); + + return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp))); + } + + + void + deallocate(pointer __p, size_type) + { ::operator delete(__p); } + + size_type + max_size() const throw() + { return size_t(-1) / sizeof(_Tp); } +# 128 "/usr/include/c++/4.8.2/ext/new_allocator.h" 3 + void + construct(pointer __p, const _Tp& __val) + { ::new((void *)__p) _Tp(__val); } + + void + destroy(pointer __p) { __p->~_Tp(); } + + }; + + template + inline bool + operator==(const new_allocator<_Tp>&, const new_allocator<_Tp>&) + { return true; } + + template + inline bool + operator!=(const new_allocator<_Tp>&, const new_allocator<_Tp>&) + { return false; } + + +} +# 34 "/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/c++allocator.h" 2 3 +# 47 "/usr/include/c++/4.8.2/bits/allocator.h" 2 3 + + + + + +namespace std __attribute__ ((__visibility__ ("default"))) +{ + + + + + + + + + template<> + class allocator + { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef void* pointer; + typedef const void* const_pointer; + typedef void value_type; + + template + struct rebind + { typedef allocator<_Tp1> other; }; + + + + + + + }; +# 91 "/usr/include/c++/4.8.2/bits/allocator.h" 3 + template + class allocator: public __gnu_cxx::new_allocator<_Tp> + { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef _Tp value_type; + + template + struct rebind + { typedef allocator<_Tp1> other; }; + + + + + + + + allocator() throw() { } + + allocator(const allocator& __a) throw() + : __gnu_cxx::new_allocator<_Tp>(__a) { } + + template + allocator(const allocator<_Tp1>&) throw() { } + + ~allocator() throw() { } + + + }; + + template + inline bool + operator==(const allocator<_T1>&, const allocator<_T2>&) + { return true; } + + template + inline bool + operator==(const allocator<_Tp>&, const allocator<_Tp>&) + { return true; } + + template + inline bool + operator!=(const allocator<_T1>&, const allocator<_T2>&) + { return false; } + + template + inline bool + operator!=(const allocator<_Tp>&, const allocator<_Tp>&) + { return false; } + + + + + + + extern template class allocator; + extern template class allocator; + + + + + + + template + struct __alloc_swap + { static void _S_do_it(_Alloc&, _Alloc&) { } }; + + template + struct __alloc_swap<_Alloc, false> + { + static void + _S_do_it(_Alloc& __one, _Alloc& __two) + { + + if (__one != __two) + swap(__one, __two); + } + }; + + + template + struct __alloc_neq + { + static bool + _S_do_it(const _Alloc&, const _Alloc&) + { return false; } + }; + + template + struct __alloc_neq<_Alloc, false> + { + static bool + _S_do_it(const _Alloc& __one, const _Alloc& __two) + { return __one != __two; } + }; +# 218 "/usr/include/c++/4.8.2/bits/allocator.h" 3 + +} +# 42 "/usr/include/c++/4.8.2/string" 2 3 + + +# 1 "/usr/include/c++/4.8.2/bits/ostream_insert.h" 1 3 +# 33 "/usr/include/c++/4.8.2/bits/ostream_insert.h" 3 + +# 34 "/usr/include/c++/4.8.2/bits/ostream_insert.h" 3 + + +# 1 "/usr/include/c++/4.8.2/bits/cxxabi_forced.h" 1 3 +# 34 "/usr/include/c++/4.8.2/bits/cxxabi_forced.h" 3 + +# 35 "/usr/include/c++/4.8.2/bits/cxxabi_forced.h" 3 + +#pragma GCC visibility push(default) + + +namespace __cxxabiv1 +{ + + + + + + + + class __forced_unwind + { + virtual ~__forced_unwind() throw(); + + + virtual void __pure_dummy() = 0; + }; +} + + +#pragma GCC visibility pop +# 37 "/usr/include/c++/4.8.2/bits/ostream_insert.h" 2 3 + +namespace std __attribute__ ((__visibility__ ("default"))) +{ + + + template + inline void + __ostream_write(basic_ostream<_CharT, _Traits>& __out, + const _CharT* __s, streamsize __n) + { + typedef basic_ostream<_CharT, _Traits> __ostream_type; + typedef typename __ostream_type::ios_base __ios_base; + + const streamsize __put = __out.rdbuf()->sputn(__s, __n); + if (__put != __n) + __out.setstate(__ios_base::badbit); + } + + template + inline void + __ostream_fill(basic_ostream<_CharT, _Traits>& __out, streamsize __n) + { + typedef basic_ostream<_CharT, _Traits> __ostream_type; + typedef typename __ostream_type::ios_base __ios_base; + + const _CharT __c = __out.fill(); + for (; __n > 0; --__n) + { + const typename _Traits::int_type __put = __out.rdbuf()->sputc(__c); + if (_Traits::eq_int_type(__put, _Traits::eof())) + { + __out.setstate(__ios_base::badbit); + break; + } + } + } + + template + basic_ostream<_CharT, _Traits>& + __ostream_insert(basic_ostream<_CharT, _Traits>& __out, + const _CharT* __s, streamsize __n) + { + typedef basic_ostream<_CharT, _Traits> __ostream_type; + typedef typename __ostream_type::ios_base __ios_base; + + typename __ostream_type::sentry __cerb(__out); + if (__cerb) + { + try + { + const streamsize __w = __out.width(); + if (__w > __n) + { + const bool __left = ((__out.flags() + & __ios_base::adjustfield) + == __ios_base::left); + if (!__left) + __ostream_fill(__out, __w - __n); + if (__out.good()) + __ostream_write(__out, __s, __n); + if (__left && __out.good()) + __ostream_fill(__out, __w - __n); + } + else + __ostream_write(__out, __s, __n); + __out.width(0); + } + catch(__cxxabiv1::__forced_unwind&) + { + __out._M_setstate(__ios_base::badbit); + throw; + } + catch(...) + { __out._M_setstate(__ios_base::badbit); } + } + return __out; + } + + + + + extern template ostream& __ostream_insert(ostream&, const char*, streamsize); + + + extern template wostream& __ostream_insert(wostream&, const wchar_t*, + streamsize); + + + + +} +# 45 "/usr/include/c++/4.8.2/string" 2 3 + + + +# 1 "/usr/include/c++/4.8.2/bits/stl_function.h" 1 3 +# 59 "/usr/include/c++/4.8.2/bits/stl_function.h" 3 +namespace std __attribute__ ((__visibility__ ("default"))) +{ + +# 100 "/usr/include/c++/4.8.2/bits/stl_function.h" 3 + template + struct unary_function + { + + typedef _Arg argument_type; + + + typedef _Result result_type; + }; + + + + + template + struct binary_function + { + + typedef _Arg1 first_argument_type; + + + typedef _Arg2 second_argument_type; + + + typedef _Result result_type; + }; +# 139 "/usr/include/c++/4.8.2/bits/stl_function.h" 3 + template + struct plus : public binary_function<_Tp, _Tp, _Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x + __y; } + }; + + + template + struct minus : public binary_function<_Tp, _Tp, _Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x - __y; } + }; + + + template + struct multiplies : public binary_function<_Tp, _Tp, _Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x * __y; } + }; + + + template + struct divides : public binary_function<_Tp, _Tp, _Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x / __y; } + }; + + + template + struct modulus : public binary_function<_Tp, _Tp, _Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x % __y; } + }; + + + template + struct negate : public unary_function<_Tp, _Tp> + { + _Tp + operator()(const _Tp& __x) const + { return -__x; } + }; +# 203 "/usr/include/c++/4.8.2/bits/stl_function.h" 3 + template + struct equal_to : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x == __y; } + }; + + + template + struct not_equal_to : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x != __y; } + }; + + + template + struct greater : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x > __y; } + }; + + + template + struct less : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x < __y; } + }; + + + template + struct greater_equal : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x >= __y; } + }; + + + template + struct less_equal : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x <= __y; } + }; +# 267 "/usr/include/c++/4.8.2/bits/stl_function.h" 3 + template + struct logical_and : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x && __y; } + }; + + + template + struct logical_or : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x || __y; } + }; + + + template + struct logical_not : public unary_function<_Tp, bool> + { + bool + operator()(const _Tp& __x) const + { return !__x; } + }; + + + + + template + struct bit_and : public binary_function<_Tp, _Tp, _Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x & __y; } + }; + + template + struct bit_or : public binary_function<_Tp, _Tp, _Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x | __y; } + }; + + template + struct bit_xor : public binary_function<_Tp, _Tp, _Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x ^ __y; } + }; +# 350 "/usr/include/c++/4.8.2/bits/stl_function.h" 3 + template + class unary_negate + : public unary_function + { + protected: + _Predicate _M_pred; + + public: + explicit + unary_negate(const _Predicate& __x) : _M_pred(__x) { } + + bool + operator()(const typename _Predicate::argument_type& __x) const + { return !_M_pred(__x); } + }; + + + template + inline unary_negate<_Predicate> + not1(const _Predicate& __pred) + { return unary_negate<_Predicate>(__pred); } + + + template + class binary_negate + : public binary_function + { + protected: + _Predicate _M_pred; + + public: + explicit + binary_negate(const _Predicate& __x) : _M_pred(__x) { } + + bool + operator()(const typename _Predicate::first_argument_type& __x, + const typename _Predicate::second_argument_type& __y) const + { return !_M_pred(__x, __y); } + }; + + + template + inline binary_negate<_Predicate> + not2(const _Predicate& __pred) + { return binary_negate<_Predicate>(__pred); } +# 421 "/usr/include/c++/4.8.2/bits/stl_function.h" 3 + template + class pointer_to_unary_function : public unary_function<_Arg, _Result> + { + protected: + _Result (*_M_ptr)(_Arg); + + public: + pointer_to_unary_function() { } + + explicit + pointer_to_unary_function(_Result (*__x)(_Arg)) + : _M_ptr(__x) { } + + _Result + operator()(_Arg __x) const + { return _M_ptr(__x); } + }; + + + template + inline pointer_to_unary_function<_Arg, _Result> + ptr_fun(_Result (*__x)(_Arg)) + { return pointer_to_unary_function<_Arg, _Result>(__x); } + + + template + class pointer_to_binary_function + : public binary_function<_Arg1, _Arg2, _Result> + { + protected: + _Result (*_M_ptr)(_Arg1, _Arg2); + + public: + pointer_to_binary_function() { } + + explicit + pointer_to_binary_function(_Result (*__x)(_Arg1, _Arg2)) + : _M_ptr(__x) { } + + _Result + operator()(_Arg1 __x, _Arg2 __y) const + { return _M_ptr(__x, __y); } + }; + + + template + inline pointer_to_binary_function<_Arg1, _Arg2, _Result> + ptr_fun(_Result (*__x)(_Arg1, _Arg2)) + { return pointer_to_binary_function<_Arg1, _Arg2, _Result>(__x); } + + + template + struct _Identity + : public unary_function<_Tp,_Tp> + { + _Tp& + operator()(_Tp& __x) const + { return __x; } + + const _Tp& + operator()(const _Tp& __x) const + { return __x; } + }; + + template + struct _Select1st + : public unary_function<_Pair, typename _Pair::first_type> + { + typename _Pair::first_type& + operator()(_Pair& __x) const + { return __x.first; } + + const typename _Pair::first_type& + operator()(const _Pair& __x) const + { return __x.first; } +# 508 "/usr/include/c++/4.8.2/bits/stl_function.h" 3 + }; + + template + struct _Select2nd + : public unary_function<_Pair, typename _Pair::second_type> + { + typename _Pair::second_type& + operator()(_Pair& __x) const + { return __x.second; } + + const typename _Pair::second_type& + operator()(const _Pair& __x) const + { return __x.second; } + }; +# 541 "/usr/include/c++/4.8.2/bits/stl_function.h" 3 + template + class mem_fun_t : public unary_function<_Tp*, _Ret> + { + public: + explicit + mem_fun_t(_Ret (_Tp::*__pf)()) + : _M_f(__pf) { } + + _Ret + operator()(_Tp* __p) const + { return (__p->*_M_f)(); } + + private: + _Ret (_Tp::*_M_f)(); + }; + + + + template + class const_mem_fun_t : public unary_function + { + public: + explicit + const_mem_fun_t(_Ret (_Tp::*__pf)() const) + : _M_f(__pf) { } + + _Ret + operator()(const _Tp* __p) const + { return (__p->*_M_f)(); } + + private: + _Ret (_Tp::*_M_f)() const; + }; + + + + template + class mem_fun_ref_t : public unary_function<_Tp, _Ret> + { + public: + explicit + mem_fun_ref_t(_Ret (_Tp::*__pf)()) + : _M_f(__pf) { } + + _Ret + operator()(_Tp& __r) const + { return (__r.*_M_f)(); } + + private: + _Ret (_Tp::*_M_f)(); + }; + + + + template + class const_mem_fun_ref_t : public unary_function<_Tp, _Ret> + { + public: + explicit + const_mem_fun_ref_t(_Ret (_Tp::*__pf)() const) + : _M_f(__pf) { } + + _Ret + operator()(const _Tp& __r) const + { return (__r.*_M_f)(); } + + private: + _Ret (_Tp::*_M_f)() const; + }; + + + + template + class mem_fun1_t : public binary_function<_Tp*, _Arg, _Ret> + { + public: + explicit + mem_fun1_t(_Ret (_Tp::*__pf)(_Arg)) + : _M_f(__pf) { } + + _Ret + operator()(_Tp* __p, _Arg __x) const + { return (__p->*_M_f)(__x); } + + private: + _Ret (_Tp::*_M_f)(_Arg); + }; + + + + template + class const_mem_fun1_t : public binary_function + { + public: + explicit + const_mem_fun1_t(_Ret (_Tp::*__pf)(_Arg) const) + : _M_f(__pf) { } + + _Ret + operator()(const _Tp* __p, _Arg __x) const + { return (__p->*_M_f)(__x); } + + private: + _Ret (_Tp::*_M_f)(_Arg) const; + }; + + + + template + class mem_fun1_ref_t : public binary_function<_Tp, _Arg, _Ret> + { + public: + explicit + mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg)) + : _M_f(__pf) { } + + _Ret + operator()(_Tp& __r, _Arg __x) const + { return (__r.*_M_f)(__x); } + + private: + _Ret (_Tp::*_M_f)(_Arg); + }; + + + + template + class const_mem_fun1_ref_t : public binary_function<_Tp, _Arg, _Ret> + { + public: + explicit + const_mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg) const) + : _M_f(__pf) { } + + _Ret + operator()(const _Tp& __r, _Arg __x) const + { return (__r.*_M_f)(__x); } + + private: + _Ret (_Tp::*_M_f)(_Arg) const; + }; + + + + template + inline mem_fun_t<_Ret, _Tp> + mem_fun(_Ret (_Tp::*__f)()) + { return mem_fun_t<_Ret, _Tp>(__f); } + + template + inline const_mem_fun_t<_Ret, _Tp> + mem_fun(_Ret (_Tp::*__f)() const) + { return const_mem_fun_t<_Ret, _Tp>(__f); } + + template + inline mem_fun_ref_t<_Ret, _Tp> + mem_fun_ref(_Ret (_Tp::*__f)()) + { return mem_fun_ref_t<_Ret, _Tp>(__f); } + + template + inline const_mem_fun_ref_t<_Ret, _Tp> + mem_fun_ref(_Ret (_Tp::*__f)() const) + { return const_mem_fun_ref_t<_Ret, _Tp>(__f); } + + template + inline mem_fun1_t<_Ret, _Tp, _Arg> + mem_fun(_Ret (_Tp::*__f)(_Arg)) + { return mem_fun1_t<_Ret, _Tp, _Arg>(__f); } + + template + inline const_mem_fun1_t<_Ret, _Tp, _Arg> + mem_fun(_Ret (_Tp::*__f)(_Arg) const) + { return const_mem_fun1_t<_Ret, _Tp, _Arg>(__f); } + + template + inline mem_fun1_ref_t<_Ret, _Tp, _Arg> + mem_fun_ref(_Ret (_Tp::*__f)(_Arg)) + { return mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); } + + template + inline const_mem_fun1_ref_t<_Ret, _Tp, _Arg> + mem_fun_ref(_Ret (_Tp::*__f)(_Arg) const) + { return const_mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); } + + + + +} + + +# 1 "/usr/include/c++/4.8.2/backward/binders.h" 1 3 +# 59 "/usr/include/c++/4.8.2/backward/binders.h" 3 +namespace std __attribute__ ((__visibility__ ("default"))) +{ + +# 103 "/usr/include/c++/4.8.2/backward/binders.h" 3 + template + class binder1st + : public unary_function + { + protected: + _Operation op; + typename _Operation::first_argument_type value; + + public: + binder1st(const _Operation& __x, + const typename _Operation::first_argument_type& __y) + : op(__x), value(__y) { } + + typename _Operation::result_type + operator()(const typename _Operation::second_argument_type& __x) const + { return op(value, __x); } + + + + typename _Operation::result_type + operator()(typename _Operation::second_argument_type& __x) const + { return op(value, __x); } + } ; + + + template + inline binder1st<_Operation> + bind1st(const _Operation& __fn, const _Tp& __x) + { + typedef typename _Operation::first_argument_type _Arg1_type; + return binder1st<_Operation>(__fn, _Arg1_type(__x)); + } + + + template + class binder2nd + : public unary_function + { + protected: + _Operation op; + typename _Operation::second_argument_type value; + + public: + binder2nd(const _Operation& __x, + const typename _Operation::second_argument_type& __y) + : op(__x), value(__y) { } + + typename _Operation::result_type + operator()(const typename _Operation::first_argument_type& __x) const + { return op(__x, value); } + + + + typename _Operation::result_type + operator()(typename _Operation::first_argument_type& __x) const + { return op(__x, value); } + } ; + + + template + inline binder2nd<_Operation> + bind2nd(const _Operation& __fn, const _Tp& __x) + { + typedef typename _Operation::second_argument_type _Arg2_type; + return binder2nd<_Operation>(__fn, _Arg2_type(__x)); + } + + + +} +# 732 "/usr/include/c++/4.8.2/bits/stl_function.h" 2 3 +# 49 "/usr/include/c++/4.8.2/string" 2 3 + + +# 1 "/usr/include/c++/4.8.2/bits/range_access.h" 1 3 +# 33 "/usr/include/c++/4.8.2/bits/range_access.h" 3 + +# 34 "/usr/include/c++/4.8.2/bits/range_access.h" 3 +# 52 "/usr/include/c++/4.8.2/string" 2 3 +# 1 "/usr/include/c++/4.8.2/bits/basic_string.h" 1 3 +# 37 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + +# 38 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + + + + + + + +namespace std __attribute__ ((__visibility__ ("default"))) +{ + +# 111 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + template + class basic_string + { + typedef typename _Alloc::template rebind<_CharT>::other _CharT_alloc_type; + + + public: + typedef _Traits traits_type; + typedef typename _Traits::char_type value_type; + typedef _Alloc allocator_type; + typedef typename _CharT_alloc_type::size_type size_type; + typedef typename _CharT_alloc_type::difference_type difference_type; + typedef typename _CharT_alloc_type::reference reference; + typedef typename _CharT_alloc_type::const_reference const_reference; + typedef typename _CharT_alloc_type::pointer pointer; + typedef typename _CharT_alloc_type::const_pointer const_pointer; + typedef __gnu_cxx::__normal_iterator iterator; + typedef __gnu_cxx::__normal_iterator + const_iterator; + typedef std::reverse_iterator const_reverse_iterator; + typedef std::reverse_iterator reverse_iterator; + + private: +# 148 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + struct _Rep_base + { + size_type _M_length; + size_type _M_capacity; + _Atomic_word _M_refcount; + }; + + struct _Rep : _Rep_base + { + + typedef typename _Alloc::template rebind::other _Raw_bytes_alloc; +# 173 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + static const size_type _S_max_size; + static const _CharT _S_terminal; + + + + static size_type _S_empty_rep_storage[]; + + static _Rep& + _S_empty_rep() + { + + + + void* __p = reinterpret_cast(&_S_empty_rep_storage); + return *reinterpret_cast<_Rep*>(__p); + } + + bool + _M_is_leaked() const + { return this->_M_refcount < 0; } + + bool + _M_is_shared() const + { return this->_M_refcount > 0; } + + void + _M_set_leaked() + { this->_M_refcount = -1; } + + void + _M_set_sharable() + { this->_M_refcount = 0; } + + void + _M_set_length_and_sharable(size_type __n) + { + + if (__builtin_expect(this != &_S_empty_rep(), false)) + + { + this->_M_set_sharable(); + this->_M_length = __n; + traits_type::assign(this->_M_refdata()[__n], _S_terminal); + + + } + } + + _CharT* + _M_refdata() throw() + { return reinterpret_cast<_CharT*>(this + 1); } + + _CharT* + _M_grab(const _Alloc& __alloc1, const _Alloc& __alloc2) + { + return (!_M_is_leaked() && __alloc1 == __alloc2) + ? _M_refcopy() : _M_clone(__alloc1); + } + + + static _Rep* + _S_create(size_type, size_type, const _Alloc&); + + void + _M_dispose(const _Alloc& __a) + { + + if (__builtin_expect(this != &_S_empty_rep(), false)) + + { + + ; + if (__gnu_cxx::__exchange_and_add_dispatch(&this->_M_refcount, + -1) <= 0) + { + ; + _M_destroy(__a); + } + } + } + + void + _M_destroy(const _Alloc&) throw(); + + _CharT* + _M_refcopy() throw() + { + + if (__builtin_expect(this != &_S_empty_rep(), false)) + + __gnu_cxx::__atomic_add_dispatch(&this->_M_refcount, 1); + return _M_refdata(); + } + + _CharT* + _M_clone(const _Alloc&, size_type __res = 0); + }; + + + struct _Alloc_hider : _Alloc + { + _Alloc_hider(_CharT* __dat, const _Alloc& __a) + : _Alloc(__a), _M_p(__dat) { } + + _CharT* _M_p; + }; + + public: + + + + + static const size_type npos = static_cast(-1); + + private: + + mutable _Alloc_hider _M_dataplus; + + _CharT* + _M_data() const + { return _M_dataplus._M_p; } + + _CharT* + _M_data(_CharT* __p) + { return (_M_dataplus._M_p = __p); } + + _Rep* + _M_rep() const + { return &((reinterpret_cast<_Rep*> (_M_data()))[-1]); } + + + + iterator + _M_ibegin() const + { return iterator(_M_data()); } + + iterator + _M_iend() const + { return iterator(_M_data() + this->size()); } + + void + _M_leak() + { + if (!_M_rep()->_M_is_leaked()) + _M_leak_hard(); + } + + size_type + _M_check(size_type __pos, const char* __s) const + { + if (__pos > this->size()) + __throw_out_of_range((__s)); + return __pos; + } + + void + _M_check_length(size_type __n1, size_type __n2, const char* __s) const + { + if (this->max_size() - (this->size() - __n1) < __n2) + __throw_length_error((__s)); + } + + + size_type + _M_limit(size_type __pos, size_type __off) const + { + const bool __testoff = __off < this->size() - __pos; + return __testoff ? __off : this->size() - __pos; + } + + + bool + _M_disjunct(const _CharT* __s) const + { + return (less()(__s, _M_data()) + || less()(_M_data() + this->size(), __s)); + } + + + + static void + _M_copy(_CharT* __d, const _CharT* __s, size_type __n) + { + if (__n == 1) + traits_type::assign(*__d, *__s); + else + traits_type::copy(__d, __s, __n); + } + + static void + _M_move(_CharT* __d, const _CharT* __s, size_type __n) + { + if (__n == 1) + traits_type::assign(*__d, *__s); + else + traits_type::move(__d, __s, __n); + } + + static void + _M_assign(_CharT* __d, size_type __n, _CharT __c) + { + if (__n == 1) + traits_type::assign(*__d, __c); + else + traits_type::assign(__d, __n, __c); + } + + + + template + static void + _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2) + { + for (; __k1 != __k2; ++__k1, ++__p) + traits_type::assign(*__p, *__k1); + } + + static void + _S_copy_chars(_CharT* __p, iterator __k1, iterator __k2) + { _S_copy_chars(__p, __k1.base(), __k2.base()); } + + static void + _S_copy_chars(_CharT* __p, const_iterator __k1, const_iterator __k2) + { _S_copy_chars(__p, __k1.base(), __k2.base()); } + + static void + _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2) + { _M_copy(__p, __k1, __k2 - __k1); } + + static void + _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2) + { _M_copy(__p, __k1, __k2 - __k1); } + + static int + _S_compare(size_type __n1, size_type __n2) + { + const difference_type __d = difference_type(__n1 - __n2); + + if (__d > __gnu_cxx::__numeric_traits::__max) + return __gnu_cxx::__numeric_traits::__max; + else if (__d < __gnu_cxx::__numeric_traits::__min) + return __gnu_cxx::__numeric_traits::__min; + else + return int(__d); + } + + void + _M_mutate(size_type __pos, size_type __len1, size_type __len2); + + void + _M_leak_hard(); + + static _Rep& + _S_empty_rep() + { return _Rep::_S_empty_rep(); } + + public: + + + + + + + + basic_string() + + : _M_dataplus(_S_empty_rep()._M_refdata(), _Alloc()) { } + + + + + + + + explicit + basic_string(const _Alloc& __a); + + + + + + + basic_string(const basic_string& __str); + + + + + + + basic_string(const basic_string& __str, size_type __pos, + size_type __n = npos); + + + + + + + + basic_string(const basic_string& __str, size_type __pos, + size_type __n, const _Alloc& __a); +# 483 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + basic_string(const _CharT* __s, size_type __n, + const _Alloc& __a = _Alloc()); + + + + + + basic_string(const _CharT* __s, const _Alloc& __a = _Alloc()); + + + + + + + basic_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc()); +# 531 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + template + basic_string(_InputIterator __beg, _InputIterator __end, + const _Alloc& __a = _Alloc()); + + + + + ~basic_string() + { _M_rep()->_M_dispose(this->get_allocator()); } + + + + + + basic_string& + operator=(const basic_string& __str) + { return this->assign(__str); } + + + + + + basic_string& + operator=(const _CharT* __s) + { return this->assign(__s); } +# 564 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + basic_string& + operator=(_CharT __c) + { + this->assign(1, __c); + return *this; + } +# 604 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + iterator + begin() + { + _M_leak(); + return iterator(_M_data()); + } + + + + + + const_iterator + begin() const + { return const_iterator(_M_data()); } + + + + + + iterator + end() + { + _M_leak(); + return iterator(_M_data() + this->size()); + } + + + + + + const_iterator + end() const + { return const_iterator(_M_data() + this->size()); } + + + + + + + reverse_iterator + rbegin() + { return reverse_iterator(this->end()); } + + + + + + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(this->end()); } + + + + + + + reverse_iterator + rend() + { return reverse_iterator(this->begin()); } + + + + + + + const_reverse_iterator + rend() const + { return const_reverse_iterator(this->begin()); } +# 710 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + public: + + + + size_type + size() const + { return _M_rep()->_M_length; } + + + + size_type + length() const + { return _M_rep()->_M_length; } + + + size_type + max_size() const + { return _Rep::_S_max_size; } +# 739 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + void + resize(size_type __n, _CharT __c); +# 752 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + void + resize(size_type __n) + { this->resize(__n, _CharT()); } +# 775 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + size_type + capacity() const + { return _M_rep()->_M_capacity; } +# 796 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + void + reserve(size_type __res_arg = 0); + + + + + void + clear() + { _M_mutate(0, this->size(), 0); } + + + + + + bool + empty() const + { return this->size() == 0; } +# 825 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + const_reference + operator[] (size_type __pos) const + { + ; + return _M_data()[__pos]; + } +# 842 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + reference + operator[](size_type __pos) + { + + ; + + ; + _M_leak(); + return _M_data()[__pos]; + } +# 863 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + const_reference + at(size_type __n) const + { + if (__n >= this->size()) + __throw_out_of_range(("basic_string::at")); + return _M_data()[__n]; + } +# 882 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + reference + at(size_type __n) + { + if (__n >= size()) + __throw_out_of_range(("basic_string::at")); + _M_leak(); + return _M_data()[__n]; + } +# 931 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + basic_string& + operator+=(const basic_string& __str) + { return this->append(__str); } + + + + + + + basic_string& + operator+=(const _CharT* __s) + { return this->append(__s); } + + + + + + + basic_string& + operator+=(_CharT __c) + { + this->push_back(__c); + return *this; + } +# 972 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + basic_string& + append(const basic_string& __str); +# 988 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + basic_string& + append(const basic_string& __str, size_type __pos, size_type __n); + + + + + + + + basic_string& + append(const _CharT* __s, size_type __n); + + + + + + + basic_string& + append(const _CharT* __s) + { + ; + return this->append(__s, traits_type::length(__s)); + } +# 1020 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + basic_string& + append(size_type __n, _CharT __c); +# 1042 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + template + basic_string& + append(_InputIterator __first, _InputIterator __last) + { return this->replace(_M_iend(), _M_iend(), __first, __last); } + + + + + + void + push_back(_CharT __c) + { + const size_type __len = 1 + this->size(); + if (__len > this->capacity() || _M_rep()->_M_is_shared()) + this->reserve(__len); + traits_type::assign(_M_data()[this->size()], __c); + _M_rep()->_M_set_length_and_sharable(__len); + } + + + + + + + basic_string& + assign(const basic_string& __str); +# 1099 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + basic_string& + assign(const basic_string& __str, size_type __pos, size_type __n) + { return this->assign(__str._M_data() + + __str._M_check(__pos, "basic_string::assign"), + __str._M_limit(__pos, __n)); } +# 1115 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + basic_string& + assign(const _CharT* __s, size_type __n); +# 1127 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + basic_string& + assign(const _CharT* __s) + { + ; + return this->assign(__s, traits_type::length(__s)); + } +# 1143 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + basic_string& + assign(size_type __n, _CharT __c) + { return _M_replace_aux(size_type(0), this->size(), __n, __c); } +# 1155 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + template + basic_string& + assign(_InputIterator __first, _InputIterator __last) + { return this->replace(_M_ibegin(), _M_iend(), __first, __last); } +# 1184 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + void + insert(iterator __p, size_type __n, _CharT __c) + { this->replace(__p, __p, __n, __c); } +# 1200 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + template + void + insert(iterator __p, _InputIterator __beg, _InputIterator __end) + { this->replace(__p, __p, __beg, __end); } +# 1232 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + basic_string& + insert(size_type __pos1, const basic_string& __str) + { return this->insert(__pos1, __str, size_type(0), __str.size()); } +# 1254 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + basic_string& + insert(size_type __pos1, const basic_string& __str, + size_type __pos2, size_type __n) + { return this->insert(__pos1, __str._M_data() + + __str._M_check(__pos2, "basic_string::insert"), + __str._M_limit(__pos2, __n)); } +# 1277 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + basic_string& + insert(size_type __pos, const _CharT* __s, size_type __n); +# 1295 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + basic_string& + insert(size_type __pos, const _CharT* __s) + { + ; + return this->insert(__pos, __s, traits_type::length(__s)); + } +# 1318 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + basic_string& + insert(size_type __pos, size_type __n, _CharT __c) + { return _M_replace_aux(_M_check(__pos, "basic_string::insert"), + size_type(0), __n, __c); } +# 1336 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + iterator + insert(iterator __p, _CharT __c) + { + ; + const size_type __pos = __p - _M_ibegin(); + _M_replace_aux(__pos, size_type(0), size_type(1), __c); + _M_rep()->_M_set_leaked(); + return iterator(_M_data() + __pos); + } +# 1361 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + basic_string& + erase(size_type __pos = 0, size_type __n = npos) + { + _M_mutate(_M_check(__pos, "basic_string::erase"), + _M_limit(__pos, __n), size_type(0)); + return *this; + } +# 1377 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + iterator + erase(iterator __position) + { + + ; + const size_type __pos = __position - _M_ibegin(); + _M_mutate(__pos, size_type(1), size_type(0)); + _M_rep()->_M_set_leaked(); + return iterator(_M_data() + __pos); + } +# 1397 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + iterator + erase(iterator __first, iterator __last); +# 1428 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + basic_string& + replace(size_type __pos, size_type __n, const basic_string& __str) + { return this->replace(__pos, __n, __str._M_data(), __str.size()); } +# 1450 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + basic_string& + replace(size_type __pos1, size_type __n1, const basic_string& __str, + size_type __pos2, size_type __n2) + { return this->replace(__pos1, __n1, __str._M_data() + + __str._M_check(__pos2, "basic_string::replace"), + __str._M_limit(__pos2, __n2)); } +# 1475 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + basic_string& + replace(size_type __pos, size_type __n1, const _CharT* __s, + size_type __n2); +# 1495 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + basic_string& + replace(size_type __pos, size_type __n1, const _CharT* __s) + { + ; + return this->replace(__pos, __n1, __s, traits_type::length(__s)); + } +# 1519 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + basic_string& + replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c) + { return _M_replace_aux(_M_check(__pos, "basic_string::replace"), + _M_limit(__pos, __n1), __n2, __c); } +# 1537 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + basic_string& + replace(iterator __i1, iterator __i2, const basic_string& __str) + { return this->replace(__i1, __i2, __str._M_data(), __str.size()); } +# 1556 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + basic_string& + replace(iterator __i1, iterator __i2, const _CharT* __s, size_type __n) + { + + ; + return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __s, __n); + } +# 1577 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + basic_string& + replace(iterator __i1, iterator __i2, const _CharT* __s) + { + ; + return this->replace(__i1, __i2, __s, traits_type::length(__s)); + } +# 1598 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + basic_string& + replace(iterator __i1, iterator __i2, size_type __n, _CharT __c) + { + + ; + return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1, __n, __c); + } +# 1621 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + template + basic_string& + replace(iterator __i1, iterator __i2, + _InputIterator __k1, _InputIterator __k2) + { + + ; + ; + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + return _M_replace_dispatch(__i1, __i2, __k1, __k2, _Integral()); + } + + + + basic_string& + replace(iterator __i1, iterator __i2, _CharT* __k1, _CharT* __k2) + { + + ; + ; + return this->replace(__i1 - _M_ibegin(), __i2 - __i1, + __k1, __k2 - __k1); + } + + basic_string& + replace(iterator __i1, iterator __i2, + const _CharT* __k1, const _CharT* __k2) + { + + ; + ; + return this->replace(__i1 - _M_ibegin(), __i2 - __i1, + __k1, __k2 - __k1); + } + + basic_string& + replace(iterator __i1, iterator __i2, iterator __k1, iterator __k2) + { + + ; + ; + return this->replace(__i1 - _M_ibegin(), __i2 - __i1, + __k1.base(), __k2 - __k1); + } + + basic_string& + replace(iterator __i1, iterator __i2, + const_iterator __k1, const_iterator __k2) + { + + ; + ; + return this->replace(__i1 - _M_ibegin(), __i2 - __i1, + __k1.base(), __k2 - __k1); + } +# 1697 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + private: + template + basic_string& + _M_replace_dispatch(iterator __i1, iterator __i2, _Integer __n, + _Integer __val, __true_type) + { return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1, __n, __val); } + + template + basic_string& + _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1, + _InputIterator __k2, __false_type); + + basic_string& + _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2, + _CharT __c); + + basic_string& + _M_replace_safe(size_type __pos1, size_type __n1, const _CharT* __s, + size_type __n2); + + + + template + static _CharT* + _S_construct_aux(_InIterator __beg, _InIterator __end, + const _Alloc& __a, __false_type) + { + typedef typename iterator_traits<_InIterator>::iterator_category _Tag; + return _S_construct(__beg, __end, __a, _Tag()); + } + + + + template + static _CharT* + _S_construct_aux(_Integer __beg, _Integer __end, + const _Alloc& __a, __true_type) + { return _S_construct_aux_2(static_cast(__beg), + __end, __a); } + + static _CharT* + _S_construct_aux_2(size_type __req, _CharT __c, const _Alloc& __a) + { return _S_construct(__req, __c, __a); } + + template + static _CharT* + _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a) + { + typedef typename std::__is_integer<_InIterator>::__type _Integral; + return _S_construct_aux(__beg, __end, __a, _Integral()); + } + + + template + static _CharT* + _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, + input_iterator_tag); + + + + template + static _CharT* + _S_construct(_FwdIterator __beg, _FwdIterator __end, const _Alloc& __a, + forward_iterator_tag); + + static _CharT* + _S_construct(size_type __req, _CharT __c, const _Alloc& __a); + + public: +# 1779 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + size_type + copy(_CharT* __s, size_type __n, size_type __pos = 0) const; +# 1789 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + void + swap(basic_string& __s); +# 1799 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + const _CharT* + c_str() const + { return _M_data(); } + + + + + + + + const _CharT* + data() const + { return _M_data(); } + + + + + allocator_type + get_allocator() const + { return _M_dataplus; } +# 1832 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + size_type + find(const _CharT* __s, size_type __pos, size_type __n) const; +# 1845 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + size_type + find(const basic_string& __str, size_type __pos = 0) const + + { return this->find(__str.data(), __pos, __str.size()); } +# 1860 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + size_type + find(const _CharT* __s, size_type __pos = 0) const + { + ; + return this->find(__s, __pos, traits_type::length(__s)); + } +# 1877 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + size_type + find(_CharT __c, size_type __pos = 0) const ; +# 1890 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + size_type + rfind(const basic_string& __str, size_type __pos = npos) const + + { return this->rfind(__str.data(), __pos, __str.size()); } +# 1907 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + size_type + rfind(const _CharT* __s, size_type __pos, size_type __n) const; +# 1920 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + size_type + rfind(const _CharT* __s, size_type __pos = npos) const + { + ; + return this->rfind(__s, __pos, traits_type::length(__s)); + } +# 1937 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + size_type + rfind(_CharT __c, size_type __pos = npos) const ; +# 1951 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + size_type + find_first_of(const basic_string& __str, size_type __pos = 0) const + + { return this->find_first_of(__str.data(), __pos, __str.size()); } +# 1968 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + size_type + find_first_of(const _CharT* __s, size_type __pos, size_type __n) const; +# 1981 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + size_type + find_first_of(const _CharT* __s, size_type __pos = 0) const + { + ; + return this->find_first_of(__s, __pos, traits_type::length(__s)); + } +# 2000 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + size_type + find_first_of(_CharT __c, size_type __pos = 0) const + { return this->find(__c, __pos); } +# 2015 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + size_type + find_last_of(const basic_string& __str, size_type __pos = npos) const + + { return this->find_last_of(__str.data(), __pos, __str.size()); } +# 2032 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + size_type + find_last_of(const _CharT* __s, size_type __pos, size_type __n) const; +# 2045 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + size_type + find_last_of(const _CharT* __s, size_type __pos = npos) const + { + ; + return this->find_last_of(__s, __pos, traits_type::length(__s)); + } +# 2064 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + size_type + find_last_of(_CharT __c, size_type __pos = npos) const + { return this->rfind(__c, __pos); } +# 2078 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + size_type + find_first_not_of(const basic_string& __str, size_type __pos = 0) const + + { return this->find_first_not_of(__str.data(), __pos, __str.size()); } +# 2095 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + size_type + find_first_not_of(const _CharT* __s, size_type __pos, + size_type __n) const; +# 2109 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + size_type + find_first_not_of(const _CharT* __s, size_type __pos = 0) const + { + ; + return this->find_first_not_of(__s, __pos, traits_type::length(__s)); + } +# 2126 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + size_type + find_first_not_of(_CharT __c, size_type __pos = 0) const + ; +# 2141 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + size_type + find_last_not_of(const basic_string& __str, size_type __pos = npos) const + + { return this->find_last_not_of(__str.data(), __pos, __str.size()); } +# 2158 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + size_type + find_last_not_of(const _CharT* __s, size_type __pos, + size_type __n) const; +# 2172 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + size_type + find_last_not_of(const _CharT* __s, size_type __pos = npos) const + { + ; + return this->find_last_not_of(__s, __pos, traits_type::length(__s)); + } +# 2189 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + size_type + find_last_not_of(_CharT __c, size_type __pos = npos) const + ; +# 2205 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + basic_string + substr(size_type __pos = 0, size_type __n = npos) const + { return basic_string(*this, + _M_check(__pos, "basic_string::substr"), __n); } +# 2224 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + int + compare(const basic_string& __str) const + { + const size_type __size = this->size(); + const size_type __osize = __str.size(); + const size_type __len = std::min(__size, __osize); + + int __r = traits_type::compare(_M_data(), __str.data(), __len); + if (!__r) + __r = _S_compare(__size, __osize); + return __r; + } +# 2256 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + int + compare(size_type __pos, size_type __n, const basic_string& __str) const; +# 2282 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + int + compare(size_type __pos1, size_type __n1, const basic_string& __str, + size_type __pos2, size_type __n2) const; +# 2300 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + int + compare(const _CharT* __s) const; +# 2324 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + int + compare(size_type __pos, size_type __n1, const _CharT* __s) const; +# 2351 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + int + compare(size_type __pos, size_type __n1, const _CharT* __s, + size_type __n2) const; + }; +# 2363 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + template + basic_string<_CharT, _Traits, _Alloc> + operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { + basic_string<_CharT, _Traits, _Alloc> __str(__lhs); + __str.append(__rhs); + return __str; + } + + + + + + + + template + basic_string<_CharT,_Traits,_Alloc> + operator+(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Alloc>& __rhs); + + + + + + + + template + basic_string<_CharT,_Traits,_Alloc> + operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Alloc>& __rhs); + + + + + + + + template + inline basic_string<_CharT, _Traits, _Alloc> + operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const _CharT* __rhs) + { + basic_string<_CharT, _Traits, _Alloc> __str(__lhs); + __str.append(__rhs); + return __str; + } + + + + + + + + template + inline basic_string<_CharT, _Traits, _Alloc> + operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, _CharT __rhs) + { + typedef basic_string<_CharT, _Traits, _Alloc> __string_type; + typedef typename __string_type::size_type __size_type; + __string_type __str(__lhs); + __str.append(__size_type(1), __rhs); + return __str; + } +# 2484 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + template + inline bool + operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __lhs.compare(__rhs) == 0; } + + template + inline + typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, bool>::__type + operator==(const basic_string<_CharT>& __lhs, + const basic_string<_CharT>& __rhs) + { return (__lhs.size() == __rhs.size() + && !std::char_traits<_CharT>::compare(__lhs.data(), __rhs.data(), + __lhs.size())); } + + + + + + + + template + inline bool + operator==(const _CharT* __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __rhs.compare(__lhs) == 0; } + + + + + + + + template + inline bool + operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) == 0; } +# 2530 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + template + inline bool + operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return !(__lhs == __rhs); } + + + + + + + + template + inline bool + operator!=(const _CharT* __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return !(__lhs == __rhs); } + + + + + + + + template + inline bool + operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const _CharT* __rhs) + { return !(__lhs == __rhs); } +# 2567 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + template + inline bool + operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __lhs.compare(__rhs) < 0; } + + + + + + + + template + inline bool + operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) < 0; } + + + + + + + + template + inline bool + operator<(const _CharT* __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __rhs.compare(__lhs) > 0; } +# 2604 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + template + inline bool + operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __lhs.compare(__rhs) > 0; } + + + + + + + + template + inline bool + operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) > 0; } + + + + + + + + template + inline bool + operator>(const _CharT* __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __rhs.compare(__lhs) < 0; } +# 2641 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + template + inline bool + operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __lhs.compare(__rhs) <= 0; } + + + + + + + + template + inline bool + operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) <= 0; } + + + + + + + + template + inline bool + operator<=(const _CharT* __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __rhs.compare(__lhs) >= 0; } +# 2678 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + template + inline bool + operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __lhs.compare(__rhs) >= 0; } + + + + + + + + template + inline bool + operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) >= 0; } + + + + + + + + template + inline bool + operator>=(const _CharT* __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __rhs.compare(__lhs) <= 0; } +# 2715 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + template + inline void + swap(basic_string<_CharT, _Traits, _Alloc>& __lhs, + basic_string<_CharT, _Traits, _Alloc>& __rhs) + { __lhs.swap(__rhs); } +# 2733 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + template + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, + basic_string<_CharT, _Traits, _Alloc>& __str); + + template<> + basic_istream& + operator>>(basic_istream& __is, basic_string& __str); +# 2751 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + template + inline basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, + const basic_string<_CharT, _Traits, _Alloc>& __str) + { + + + return __ostream_insert(__os, __str.data(), __str.size()); + } +# 2774 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + template + basic_istream<_CharT, _Traits>& + getline(basic_istream<_CharT, _Traits>& __is, + basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim); +# 2791 "/usr/include/c++/4.8.2/bits/basic_string.h" 3 + template + inline basic_istream<_CharT, _Traits>& + getline(basic_istream<_CharT, _Traits>& __is, + basic_string<_CharT, _Traits, _Alloc>& __str) + { return getline(__is, __str, __is.widen('\n')); } + + template<> + basic_istream& + getline(basic_istream& __in, basic_string& __str, + char __delim); + + + template<> + basic_istream& + getline(basic_istream& __in, basic_string& __str, + wchar_t __delim); + + + +} +# 53 "/usr/include/c++/4.8.2/string" 2 3 +# 1 "/usr/include/c++/4.8.2/bits/basic_string.tcc" 1 3 +# 40 "/usr/include/c++/4.8.2/bits/basic_string.tcc" 3 + +# 41 "/usr/include/c++/4.8.2/bits/basic_string.tcc" 3 + + + +namespace std __attribute__ ((__visibility__ ("default"))) +{ + + + template + const typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + _Rep::_S_max_size = (((npos - sizeof(_Rep_base))/sizeof(_CharT)) - 1) / 4; + + template + const _CharT + basic_string<_CharT, _Traits, _Alloc>:: + _Rep::_S_terminal = _CharT(); + + template + const typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>::npos; + + + + template + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_empty_rep_storage[ + (sizeof(_Rep_base) + sizeof(_CharT) + sizeof(size_type) - 1) / + sizeof(size_type)]; + + + + + + template + template + _CharT* + basic_string<_CharT, _Traits, _Alloc>:: + _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, + input_iterator_tag) + { + + if (__beg == __end && __a == _Alloc()) + return _S_empty_rep()._M_refdata(); + + + _CharT __buf[128]; + size_type __len = 0; + while (__beg != __end && __len < sizeof(__buf) / sizeof(_CharT)) + { + __buf[__len++] = *__beg; + ++__beg; + } + _Rep* __r = _Rep::_S_create(__len, size_type(0), __a); + _M_copy(__r->_M_refdata(), __buf, __len); + try + { + while (__beg != __end) + { + if (__len == __r->_M_capacity) + { + + _Rep* __another = _Rep::_S_create(__len + 1, __len, __a); + _M_copy(__another->_M_refdata(), __r->_M_refdata(), __len); + __r->_M_destroy(__a); + __r = __another; + } + __r->_M_refdata()[__len++] = *__beg; + ++__beg; + } + } + catch(...) + { + __r->_M_destroy(__a); + throw; + } + __r->_M_set_length_and_sharable(__len); + return __r->_M_refdata(); + } + + template + template + _CharT* + basic_string<_CharT, _Traits, _Alloc>:: + _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, + forward_iterator_tag) + { + + if (__beg == __end && __a == _Alloc()) + return _S_empty_rep()._M_refdata(); + + + if (__gnu_cxx::__is_null_pointer(__beg) && __beg != __end) + __throw_logic_error(("basic_string::_S_construct null not valid")); + + const size_type __dnew = static_cast(std::distance(__beg, + __end)); + + _Rep* __r = _Rep::_S_create(__dnew, size_type(0), __a); + try + { _S_copy_chars(__r->_M_refdata(), __beg, __end); } + catch(...) + { + __r->_M_destroy(__a); + throw; + } + __r->_M_set_length_and_sharable(__dnew); + return __r->_M_refdata(); + } + + template + _CharT* + basic_string<_CharT, _Traits, _Alloc>:: + _S_construct(size_type __n, _CharT __c, const _Alloc& __a) + { + + if (__n == 0 && __a == _Alloc()) + return _S_empty_rep()._M_refdata(); + + + _Rep* __r = _Rep::_S_create(__n, size_type(0), __a); + if (__n) + _M_assign(__r->_M_refdata(), __n, __c); + + __r->_M_set_length_and_sharable(__n); + return __r->_M_refdata(); + } + + template + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(const basic_string& __str) + : _M_dataplus(__str._M_rep()->_M_grab(_Alloc(__str.get_allocator()), + __str.get_allocator()), + __str.get_allocator()) + { } + + template + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(const _Alloc& __a) + : _M_dataplus(_S_construct(size_type(), _CharT(), __a), __a) + { } + + template + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(const basic_string& __str, size_type __pos, size_type __n) + : _M_dataplus(_S_construct(__str._M_data() + + __str._M_check(__pos, + "basic_string::basic_string"), + __str._M_data() + __str._M_limit(__pos, __n) + + __pos, _Alloc()), _Alloc()) + { } + + template + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(const basic_string& __str, size_type __pos, + size_type __n, const _Alloc& __a) + : _M_dataplus(_S_construct(__str._M_data() + + __str._M_check(__pos, + "basic_string::basic_string"), + __str._M_data() + __str._M_limit(__pos, __n) + + __pos, __a), __a) + { } + + + template + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(const _CharT* __s, size_type __n, const _Alloc& __a) + : _M_dataplus(_S_construct(__s, __s + __n, __a), __a) + { } + + + template + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(const _CharT* __s, const _Alloc& __a) + : _M_dataplus(_S_construct(__s, __s ? __s + traits_type::length(__s) : + __s + npos, __a), __a) + { } + + template + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(size_type __n, _CharT __c, const _Alloc& __a) + : _M_dataplus(_S_construct(__n, __c, __a), __a) + { } + + + template + template + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(_InputIterator __beg, _InputIterator __end, const _Alloc& __a) + : _M_dataplus(_S_construct(__beg, __end, __a), __a) + { } +# 240 "/usr/include/c++/4.8.2/bits/basic_string.tcc" 3 + template + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + assign(const basic_string& __str) + { + if (_M_rep() != __str._M_rep()) + { + + const allocator_type __a = this->get_allocator(); + _CharT* __tmp = __str._M_rep()->_M_grab(__a, __str.get_allocator()); + _M_rep()->_M_dispose(__a); + _M_data(__tmp); + } + return *this; + } + + template + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + assign(const _CharT* __s, size_type __n) + { + ; + _M_check_length(this->size(), __n, "basic_string::assign"); + if (_M_disjunct(__s) || _M_rep()->_M_is_shared()) + return _M_replace_safe(size_type(0), this->size(), __s, __n); + else + { + + const size_type __pos = __s - _M_data(); + if (__pos >= __n) + _M_copy(_M_data(), __s, __n); + else if (__pos) + _M_move(_M_data(), __s, __n); + _M_rep()->_M_set_length_and_sharable(__n); + return *this; + } + } + + template + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + append(size_type __n, _CharT __c) + { + if (__n) + { + _M_check_length(size_type(0), __n, "basic_string::append"); + const size_type __len = __n + this->size(); + if (__len > this->capacity() || _M_rep()->_M_is_shared()) + this->reserve(__len); + _M_assign(_M_data() + this->size(), __n, __c); + _M_rep()->_M_set_length_and_sharable(__len); + } + return *this; + } + + template + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + append(const _CharT* __s, size_type __n) + { + ; + if (__n) + { + _M_check_length(size_type(0), __n, "basic_string::append"); + const size_type __len = __n + this->size(); + if (__len > this->capacity() || _M_rep()->_M_is_shared()) + { + if (_M_disjunct(__s)) + this->reserve(__len); + else + { + const size_type __off = __s - _M_data(); + this->reserve(__len); + __s = _M_data() + __off; + } + } + _M_copy(_M_data() + this->size(), __s, __n); + _M_rep()->_M_set_length_and_sharable(__len); + } + return *this; + } + + template + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + append(const basic_string& __str) + { + const size_type __size = __str.size(); + if (__size) + { + const size_type __len = __size + this->size(); + if (__len > this->capacity() || _M_rep()->_M_is_shared()) + this->reserve(__len); + _M_copy(_M_data() + this->size(), __str._M_data(), __size); + _M_rep()->_M_set_length_and_sharable(__len); + } + return *this; + } + + template + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + append(const basic_string& __str, size_type __pos, size_type __n) + { + __str._M_check(__pos, "basic_string::append"); + __n = __str._M_limit(__pos, __n); + if (__n) + { + const size_type __len = __n + this->size(); + if (__len > this->capacity() || _M_rep()->_M_is_shared()) + this->reserve(__len); + _M_copy(_M_data() + this->size(), __str._M_data() + __pos, __n); + _M_rep()->_M_set_length_and_sharable(__len); + } + return *this; + } + + template + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + insert(size_type __pos, const _CharT* __s, size_type __n) + { + ; + _M_check(__pos, "basic_string::insert"); + _M_check_length(size_type(0), __n, "basic_string::insert"); + if (_M_disjunct(__s) || _M_rep()->_M_is_shared()) + return _M_replace_safe(__pos, size_type(0), __s, __n); + else + { + + const size_type __off = __s - _M_data(); + _M_mutate(__pos, 0, __n); + __s = _M_data() + __off; + _CharT* __p = _M_data() + __pos; + if (__s + __n <= __p) + _M_copy(__p, __s, __n); + else if (__s >= __p) + _M_copy(__p, __s + __n, __n); + else + { + const size_type __nleft = __p - __s; + _M_copy(__p, __s, __nleft); + _M_copy(__p + __nleft, __p + __n, __n - __nleft); + } + return *this; + } + } + + template + typename basic_string<_CharT, _Traits, _Alloc>::iterator + basic_string<_CharT, _Traits, _Alloc>:: + erase(iterator __first, iterator __last) + { + + ; + + + + + const size_type __size = __last - __first; + if (__size) + { + const size_type __pos = __first - _M_ibegin(); + _M_mutate(__pos, __size, size_type(0)); + _M_rep()->_M_set_leaked(); + return iterator(_M_data() + __pos); + } + else + return __first; + } + + template + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + replace(size_type __pos, size_type __n1, const _CharT* __s, + size_type __n2) + { + ; + _M_check(__pos, "basic_string::replace"); + __n1 = _M_limit(__pos, __n1); + _M_check_length(__n1, __n2, "basic_string::replace"); + bool __left; + if (_M_disjunct(__s) || _M_rep()->_M_is_shared()) + return _M_replace_safe(__pos, __n1, __s, __n2); + else if ((__left = __s + __n2 <= _M_data() + __pos) + || _M_data() + __pos + __n1 <= __s) + { + + size_type __off = __s - _M_data(); + __left ? __off : (__off += __n2 - __n1); + _M_mutate(__pos, __n1, __n2); + _M_copy(_M_data() + __pos, _M_data() + __off, __n2); + return *this; + } + else + { + + const basic_string __tmp(__s, __n2); + return _M_replace_safe(__pos, __n1, __tmp._M_data(), __n2); + } + } + + template + void + basic_string<_CharT, _Traits, _Alloc>::_Rep:: + _M_destroy(const _Alloc& __a) throw () + { + const size_type __size = sizeof(_Rep_base) + + (this->_M_capacity + 1) * sizeof(_CharT); + _Raw_bytes_alloc(__a).deallocate(reinterpret_cast(this), __size); + } + + template + void + basic_string<_CharT, _Traits, _Alloc>:: + _M_leak_hard() + { + + if (_M_rep() == &_S_empty_rep()) + return; + + if (_M_rep()->_M_is_shared()) + _M_mutate(0, 0, 0); + _M_rep()->_M_set_leaked(); + } + + template + void + basic_string<_CharT, _Traits, _Alloc>:: + _M_mutate(size_type __pos, size_type __len1, size_type __len2) + { + const size_type __old_size = this->size(); + const size_type __new_size = __old_size + __len2 - __len1; + const size_type __how_much = __old_size - __pos - __len1; + + if (__new_size > this->capacity() || _M_rep()->_M_is_shared()) + { + + const allocator_type __a = get_allocator(); + _Rep* __r = _Rep::_S_create(__new_size, this->capacity(), __a); + + if (__pos) + _M_copy(__r->_M_refdata(), _M_data(), __pos); + if (__how_much) + _M_copy(__r->_M_refdata() + __pos + __len2, + _M_data() + __pos + __len1, __how_much); + + _M_rep()->_M_dispose(__a); + _M_data(__r->_M_refdata()); + } + else if (__how_much && __len1 != __len2) + { + + _M_move(_M_data() + __pos + __len2, + _M_data() + __pos + __len1, __how_much); + } + _M_rep()->_M_set_length_and_sharable(__new_size); + } + + template + void + basic_string<_CharT, _Traits, _Alloc>:: + reserve(size_type __res) + { + if (__res != this->capacity() || _M_rep()->_M_is_shared()) + { + + if (__res < this->size()) + __res = this->size(); + const allocator_type __a = get_allocator(); + _CharT* __tmp = _M_rep()->_M_clone(__a, __res - this->size()); + _M_rep()->_M_dispose(__a); + _M_data(__tmp); + } + } + + template + void + basic_string<_CharT, _Traits, _Alloc>:: + swap(basic_string& __s) + { + if (_M_rep()->_M_is_leaked()) + _M_rep()->_M_set_sharable(); + if (__s._M_rep()->_M_is_leaked()) + __s._M_rep()->_M_set_sharable(); + if (this->get_allocator() == __s.get_allocator()) + { + _CharT* __tmp = _M_data(); + _M_data(__s._M_data()); + __s._M_data(__tmp); + } + + else + { + const basic_string __tmp1(_M_ibegin(), _M_iend(), + __s.get_allocator()); + const basic_string __tmp2(__s._M_ibegin(), __s._M_iend(), + this->get_allocator()); + *this = __tmp2; + __s = __tmp1; + } + } + + template + typename basic_string<_CharT, _Traits, _Alloc>::_Rep* + basic_string<_CharT, _Traits, _Alloc>::_Rep:: + _S_create(size_type __capacity, size_type __old_capacity, + const _Alloc& __alloc) + { + + + if (__capacity > _S_max_size) + __throw_length_error(("basic_string::_S_create")); +# 577 "/usr/include/c++/4.8.2/bits/basic_string.tcc" 3 + const size_type __pagesize = 4096; + const size_type __malloc_header_size = 4 * sizeof(void*); + + + + + + + + if (__capacity > __old_capacity && __capacity < 2 * __old_capacity) + __capacity = 2 * __old_capacity; + + + + + size_type __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep); + + const size_type __adj_size = __size + __malloc_header_size; + if (__adj_size > __pagesize && __capacity > __old_capacity) + { + const size_type __extra = __pagesize - __adj_size % __pagesize; + __capacity += __extra / sizeof(_CharT); + + if (__capacity > _S_max_size) + __capacity = _S_max_size; + __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep); + } + + + + void* __place = _Raw_bytes_alloc(__alloc).allocate(__size); + _Rep *__p = new (__place) _Rep; + __p->_M_capacity = __capacity; + + + + + + + + __p->_M_set_sharable(); + return __p; + } + + template + _CharT* + basic_string<_CharT, _Traits, _Alloc>::_Rep:: + _M_clone(const _Alloc& __alloc, size_type __res) + { + + const size_type __requested_cap = this->_M_length + __res; + _Rep* __r = _Rep::_S_create(__requested_cap, this->_M_capacity, + __alloc); + if (this->_M_length) + _M_copy(__r->_M_refdata(), _M_refdata(), this->_M_length); + + __r->_M_set_length_and_sharable(this->_M_length); + return __r->_M_refdata(); + } + + template + void + basic_string<_CharT, _Traits, _Alloc>:: + resize(size_type __n, _CharT __c) + { + const size_type __size = this->size(); + _M_check_length(__size, __n, "basic_string::resize"); + if (__size < __n) + this->append(__n - __size, __c); + else if (__n < __size) + this->erase(__n); + + } + + template + template + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1, + _InputIterator __k2, __false_type) + { + const basic_string __s(__k1, __k2); + const size_type __n1 = __i2 - __i1; + _M_check_length(__n1, __s.size(), "basic_string::_M_replace_dispatch"); + return _M_replace_safe(__i1 - _M_ibegin(), __n1, __s._M_data(), + __s.size()); + } + + template + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2, + _CharT __c) + { + _M_check_length(__n1, __n2, "basic_string::_M_replace_aux"); + _M_mutate(__pos1, __n1, __n2); + if (__n2) + _M_assign(_M_data() + __pos1, __n2, __c); + return *this; + } + + template + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + _M_replace_safe(size_type __pos1, size_type __n1, const _CharT* __s, + size_type __n2) + { + _M_mutate(__pos1, __n1, __n2); + if (__n2) + _M_copy(_M_data() + __pos1, __s, __n2); + return *this; + } + + template + basic_string<_CharT, _Traits, _Alloc> + operator+(const _CharT* __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { + ; + typedef basic_string<_CharT, _Traits, _Alloc> __string_type; + typedef typename __string_type::size_type __size_type; + const __size_type __len = _Traits::length(__lhs); + __string_type __str; + __str.reserve(__len + __rhs.size()); + __str.append(__lhs, __len); + __str.append(__rhs); + return __str; + } + + template + basic_string<_CharT, _Traits, _Alloc> + operator+(_CharT __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { + typedef basic_string<_CharT, _Traits, _Alloc> __string_type; + typedef typename __string_type::size_type __size_type; + __string_type __str; + const __size_type __len = __rhs.size(); + __str.reserve(__len + 1); + __str.append(__size_type(1), __lhs); + __str.append(__rhs); + return __str; + } + + template + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + copy(_CharT* __s, size_type __n, size_type __pos) const + { + _M_check(__pos, "basic_string::copy"); + __n = _M_limit(__pos, __n); + ; + if (__n) + _M_copy(__s, _M_data() + __pos, __n); + + return __n; + } + + template + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + find(const _CharT* __s, size_type __pos, size_type __n) const + { + ; + const size_type __size = this->size(); + const _CharT* __data = _M_data(); + + if (__n == 0) + return __pos <= __size ? __pos : npos; + + if (__n <= __size) + { + for (; __pos <= __size - __n; ++__pos) + if (traits_type::eq(__data[__pos], __s[0]) + && traits_type::compare(__data + __pos + 1, + __s + 1, __n - 1) == 0) + return __pos; + } + return npos; + } + + template + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + find(_CharT __c, size_type __pos) const + { + size_type __ret = npos; + const size_type __size = this->size(); + if (__pos < __size) + { + const _CharT* __data = _M_data(); + const size_type __n = __size - __pos; + const _CharT* __p = traits_type::find(__data + __pos, __n, __c); + if (__p) + __ret = __p - __data; + } + return __ret; + } + + template + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + rfind(const _CharT* __s, size_type __pos, size_type __n) const + { + ; + const size_type __size = this->size(); + if (__n <= __size) + { + __pos = std::min(size_type(__size - __n), __pos); + const _CharT* __data = _M_data(); + do + { + if (traits_type::compare(__data + __pos, __s, __n) == 0) + return __pos; + } + while (__pos-- > 0); + } + return npos; + } + + template + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + rfind(_CharT __c, size_type __pos) const + { + size_type __size = this->size(); + if (__size) + { + if (--__size > __pos) + __size = __pos; + for (++__size; __size-- > 0; ) + if (traits_type::eq(_M_data()[__size], __c)) + return __size; + } + return npos; + } + + template + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + find_first_of(const _CharT* __s, size_type __pos, size_type __n) const + { + ; + for (; __n && __pos < this->size(); ++__pos) + { + const _CharT* __p = traits_type::find(__s, __n, _M_data()[__pos]); + if (__p) + return __pos; + } + return npos; + } + + template + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + find_last_of(const _CharT* __s, size_type __pos, size_type __n) const + { + ; + size_type __size = this->size(); + if (__size && __n) + { + if (--__size > __pos) + __size = __pos; + do + { + if (traits_type::find(__s, __n, _M_data()[__size])) + return __size; + } + while (__size-- != 0); + } + return npos; + } + + template + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const + { + ; + for (; __pos < this->size(); ++__pos) + if (!traits_type::find(__s, __n, _M_data()[__pos])) + return __pos; + return npos; + } + + template + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + find_first_not_of(_CharT __c, size_type __pos) const + { + for (; __pos < this->size(); ++__pos) + if (!traits_type::eq(_M_data()[__pos], __c)) + return __pos; + return npos; + } + + template + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const + { + ; + size_type __size = this->size(); + if (__size) + { + if (--__size > __pos) + __size = __pos; + do + { + if (!traits_type::find(__s, __n, _M_data()[__size])) + return __size; + } + while (__size--); + } + return npos; + } + + template + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + find_last_not_of(_CharT __c, size_type __pos) const + { + size_type __size = this->size(); + if (__size) + { + if (--__size > __pos) + __size = __pos; + do + { + if (!traits_type::eq(_M_data()[__size], __c)) + return __size; + } + while (__size--); + } + return npos; + } + + template + int + basic_string<_CharT, _Traits, _Alloc>:: + compare(size_type __pos, size_type __n, const basic_string& __str) const + { + _M_check(__pos, "basic_string::compare"); + __n = _M_limit(__pos, __n); + const size_type __osize = __str.size(); + const size_type __len = std::min(__n, __osize); + int __r = traits_type::compare(_M_data() + __pos, __str.data(), __len); + if (!__r) + __r = _S_compare(__n, __osize); + return __r; + } + + template + int + basic_string<_CharT, _Traits, _Alloc>:: + compare(size_type __pos1, size_type __n1, const basic_string& __str, + size_type __pos2, size_type __n2) const + { + _M_check(__pos1, "basic_string::compare"); + __str._M_check(__pos2, "basic_string::compare"); + __n1 = _M_limit(__pos1, __n1); + __n2 = __str._M_limit(__pos2, __n2); + const size_type __len = std::min(__n1, __n2); + int __r = traits_type::compare(_M_data() + __pos1, + __str.data() + __pos2, __len); + if (!__r) + __r = _S_compare(__n1, __n2); + return __r; + } + + template + int + basic_string<_CharT, _Traits, _Alloc>:: + compare(const _CharT* __s) const + { + ; + const size_type __size = this->size(); + const size_type __osize = traits_type::length(__s); + const size_type __len = std::min(__size, __osize); + int __r = traits_type::compare(_M_data(), __s, __len); + if (!__r) + __r = _S_compare(__size, __osize); + return __r; + } + + template + int + basic_string <_CharT, _Traits, _Alloc>:: + compare(size_type __pos, size_type __n1, const _CharT* __s) const + { + ; + _M_check(__pos, "basic_string::compare"); + __n1 = _M_limit(__pos, __n1); + const size_type __osize = traits_type::length(__s); + const size_type __len = std::min(__n1, __osize); + int __r = traits_type::compare(_M_data() + __pos, __s, __len); + if (!__r) + __r = _S_compare(__n1, __osize); + return __r; + } + + template + int + basic_string <_CharT, _Traits, _Alloc>:: + compare(size_type __pos, size_type __n1, const _CharT* __s, + size_type __n2) const + { + ; + _M_check(__pos, "basic_string::compare"); + __n1 = _M_limit(__pos, __n1); + const size_type __len = std::min(__n1, __n2); + int __r = traits_type::compare(_M_data() + __pos, __s, __len); + if (!__r) + __r = _S_compare(__n1, __n2); + return __r; + } + + + template + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __in, + basic_string<_CharT, _Traits, _Alloc>& __str) + { + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef basic_string<_CharT, _Traits, _Alloc> __string_type; + typedef typename __istream_type::ios_base __ios_base; + typedef typename __istream_type::int_type __int_type; + typedef typename __string_type::size_type __size_type; + typedef ctype<_CharT> __ctype_type; + typedef typename __ctype_type::ctype_base __ctype_base; + + __size_type __extracted = 0; + typename __ios_base::iostate __err = __ios_base::goodbit; + typename __istream_type::sentry __cerb(__in, false); + if (__cerb) + { + try + { + + __str.erase(); + _CharT __buf[128]; + __size_type __len = 0; + const streamsize __w = __in.width(); + const __size_type __n = __w > 0 ? static_cast<__size_type>(__w) + : __str.max_size(); + const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); + const __int_type __eof = _Traits::eof(); + __int_type __c = __in.rdbuf()->sgetc(); + + while (__extracted < __n + && !_Traits::eq_int_type(__c, __eof) + && !__ct.is(__ctype_base::space, + _Traits::to_char_type(__c))) + { + if (__len == sizeof(__buf) / sizeof(_CharT)) + { + __str.append(__buf, sizeof(__buf) / sizeof(_CharT)); + __len = 0; + } + __buf[__len++] = _Traits::to_char_type(__c); + ++__extracted; + __c = __in.rdbuf()->snextc(); + } + __str.append(__buf, __len); + + if (_Traits::eq_int_type(__c, __eof)) + __err |= __ios_base::eofbit; + __in.width(0); + } + catch(__cxxabiv1::__forced_unwind&) + { + __in._M_setstate(__ios_base::badbit); + throw; + } + catch(...) + { + + + + __in._M_setstate(__ios_base::badbit); + } + } + + if (!__extracted) + __err |= __ios_base::failbit; + if (__err) + __in.setstate(__err); + return __in; + } + + template + basic_istream<_CharT, _Traits>& + getline(basic_istream<_CharT, _Traits>& __in, + basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim) + { + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef basic_string<_CharT, _Traits, _Alloc> __string_type; + typedef typename __istream_type::ios_base __ios_base; + typedef typename __istream_type::int_type __int_type; + typedef typename __string_type::size_type __size_type; + + __size_type __extracted = 0; + const __size_type __n = __str.max_size(); + typename __ios_base::iostate __err = __ios_base::goodbit; + typename __istream_type::sentry __cerb(__in, true); + if (__cerb) + { + try + { + __str.erase(); + const __int_type __idelim = _Traits::to_int_type(__delim); + const __int_type __eof = _Traits::eof(); + __int_type __c = __in.rdbuf()->sgetc(); + + while (__extracted < __n + && !_Traits::eq_int_type(__c, __eof) + && !_Traits::eq_int_type(__c, __idelim)) + { + __str += _Traits::to_char_type(__c); + ++__extracted; + __c = __in.rdbuf()->snextc(); + } + + if (_Traits::eq_int_type(__c, __eof)) + __err |= __ios_base::eofbit; + else if (_Traits::eq_int_type(__c, __idelim)) + { + ++__extracted; + __in.rdbuf()->sbumpc(); + } + else + __err |= __ios_base::failbit; + } + catch(__cxxabiv1::__forced_unwind&) + { + __in._M_setstate(__ios_base::badbit); + throw; + } + catch(...) + { + + + + __in._M_setstate(__ios_base::badbit); + } + } + if (!__extracted) + __err |= __ios_base::failbit; + if (__err) + __in.setstate(__err); + return __in; + } + + + + + extern template class basic_string; + extern template + basic_istream& + operator>>(basic_istream&, string&); + extern template + basic_ostream& + operator<<(basic_ostream&, const string&); + extern template + basic_istream& + getline(basic_istream&, string&, char); + extern template + basic_istream& + getline(basic_istream&, string&); + + + extern template class basic_string; + extern template + basic_istream& + operator>>(basic_istream&, wstring&); + extern template + basic_ostream& + operator<<(basic_ostream&, const wstring&); + extern template + basic_istream& + getline(basic_istream&, wstring&, wchar_t); + extern template + basic_istream& + getline(basic_istream&, wstring&); + + + + +} +# 54 "/usr/include/c++/4.8.2/string" 2 3 +# 41 "/usr/include/c++/4.8.2/bits/locale_classes.h" 2 3 + + +namespace std __attribute__ ((__visibility__ ("default"))) +{ + +# 62 "/usr/include/c++/4.8.2/bits/locale_classes.h" 3 + class locale + { + public: + + + typedef int category; + + + class facet; + class id; + class _Impl; + + friend class facet; + friend class _Impl; + + template + friend bool + has_facet(const locale&) throw(); + + template + friend const _Facet& + use_facet(const locale&); + + template + friend struct __use_cache; +# 98 "/usr/include/c++/4.8.2/bits/locale_classes.h" 3 + static const category none = 0; + static const category ctype = 1L << 0; + static const category numeric = 1L << 1; + static const category collate = 1L << 2; + static const category time = 1L << 3; + static const category monetary = 1L << 4; + static const category messages = 1L << 5; + static const category all = (ctype | numeric | collate | + time | monetary | messages); +# 117 "/usr/include/c++/4.8.2/bits/locale_classes.h" 3 + locale() throw(); +# 126 "/usr/include/c++/4.8.2/bits/locale_classes.h" 3 + locale(const locale& __other) throw(); +# 136 "/usr/include/c++/4.8.2/bits/locale_classes.h" 3 + explicit + locale(const char* __s); +# 151 "/usr/include/c++/4.8.2/bits/locale_classes.h" 3 + locale(const locale& __base, const char* __s, category __cat); +# 164 "/usr/include/c++/4.8.2/bits/locale_classes.h" 3 + locale(const locale& __base, const locale& __add, category __cat); +# 177 "/usr/include/c++/4.8.2/bits/locale_classes.h" 3 + template + locale(const locale& __other, _Facet* __f); + + + ~locale() throw(); +# 191 "/usr/include/c++/4.8.2/bits/locale_classes.h" 3 + const locale& + operator=(const locale& __other) throw(); +# 206 "/usr/include/c++/4.8.2/bits/locale_classes.h" 3 + template + locale + combine(const locale& __other) const; + + + + + + + string + name() const; +# 225 "/usr/include/c++/4.8.2/bits/locale_classes.h" 3 + bool + operator==(const locale& __other) const throw(); + + + + + + + + bool + operator!=(const locale& __other) const throw() + { return !(this->operator==(__other)); } +# 253 "/usr/include/c++/4.8.2/bits/locale_classes.h" 3 + template + bool + operator()(const basic_string<_Char, _Traits, _Alloc>& __s1, + const basic_string<_Char, _Traits, _Alloc>& __s2) const; +# 269 "/usr/include/c++/4.8.2/bits/locale_classes.h" 3 + static locale + global(const locale& __loc); + + + + + static const locale& + classic(); + + private: + + _Impl* _M_impl; + + + static _Impl* _S_classic; + + + static _Impl* _S_global; + + + + + + static const char* const* const _S_categories; +# 304 "/usr/include/c++/4.8.2/bits/locale_classes.h" 3 + enum { _S_categories_size = 6 + 6 }; + + + static __gthread_once_t _S_once; + + + explicit + locale(_Impl*) throw(); + + static void + _S_initialize(); + + static void + _S_initialize_once() throw(); + + static category + _S_normalize_category(category); + + void + _M_coalesce(const locale& __base, const locale& __add, category __cat); + }; +# 338 "/usr/include/c++/4.8.2/bits/locale_classes.h" 3 + class locale::facet + { + private: + friend class locale; + friend class locale::_Impl; + + mutable _Atomic_word _M_refcount; + + + static __c_locale _S_c_locale; + + + static const char _S_c_name[2]; + + + static __gthread_once_t _S_once; + + + static void + _S_initialize_once(); + + protected: +# 369 "/usr/include/c++/4.8.2/bits/locale_classes.h" 3 + explicit + facet(size_t __refs = 0) throw() : _M_refcount(__refs ? 1 : 0) + { } + + + virtual + ~facet(); + + static void + _S_create_c_locale(__c_locale& __cloc, const char* __s, + __c_locale __old = 0); + + static __c_locale + _S_clone_c_locale(__c_locale& __cloc) throw(); + + static void + _S_destroy_c_locale(__c_locale& __cloc); + + static __c_locale + _S_lc_ctype_c_locale(__c_locale __cloc, const char* __s); + + + + static __c_locale + _S_get_c_locale(); + + __attribute__ ((__const__)) static const char* + _S_get_c_name() throw(); + + private: + void + _M_add_reference() const throw() + { __gnu_cxx::__atomic_add_dispatch(&_M_refcount, 1); } + + void + _M_remove_reference() const throw() + { + + ; + if (__gnu_cxx::__exchange_and_add_dispatch(&_M_refcount, -1) == 1) + { + ; + try + { delete this; } + catch(...) + { } + } + } + + facet(const facet&); + + facet& + operator=(const facet&); + }; +# 436 "/usr/include/c++/4.8.2/bits/locale_classes.h" 3 + class locale::id + { + private: + friend class locale; + friend class locale::_Impl; + + template + friend const _Facet& + use_facet(const locale&); + + template + friend bool + has_facet(const locale&) throw(); + + + + + mutable size_t _M_index; + + + static _Atomic_word _S_refcount; + + void + operator=(const id&); + + id(const id&); + + public: + + + + id() { } + + size_t + _M_id() const throw(); + }; + + + + class locale::_Impl + { + public: + + friend class locale; + friend class locale::facet; + + template + friend bool + has_facet(const locale&) throw(); + + template + friend const _Facet& + use_facet(const locale&); + + template + friend struct __use_cache; + + private: + + _Atomic_word _M_refcount; + const facet** _M_facets; + size_t _M_facets_size; + const facet** _M_caches; + char** _M_names; + static const locale::id* const _S_id_ctype[]; + static const locale::id* const _S_id_numeric[]; + static const locale::id* const _S_id_collate[]; + static const locale::id* const _S_id_time[]; + static const locale::id* const _S_id_monetary[]; + static const locale::id* const _S_id_messages[]; + static const locale::id* const* const _S_facet_categories[]; + + void + _M_add_reference() throw() + { __gnu_cxx::__atomic_add_dispatch(&_M_refcount, 1); } + + void + _M_remove_reference() throw() + { + + ; + if (__gnu_cxx::__exchange_and_add_dispatch(&_M_refcount, -1) == 1) + { + ; + try + { delete this; } + catch(...) + { } + } + } + + _Impl(const _Impl&, size_t); + _Impl(const char*, size_t); + _Impl(size_t) throw(); + + ~_Impl() throw(); + + _Impl(const _Impl&); + + void + operator=(const _Impl&); + + bool + _M_check_same_name() + { + bool __ret = true; + if (_M_names[1]) + + for (size_t __i = 0; __ret && __i < _S_categories_size - 1; ++__i) + __ret = __builtin_strcmp(_M_names[__i], _M_names[__i + 1]) == 0; + return __ret; + } + + void + _M_replace_categories(const _Impl*, category); + + void + _M_replace_category(const _Impl*, const locale::id* const*); + + void + _M_replace_facet(const _Impl*, const locale::id*); + + void + _M_install_facet(const locale::id*, const facet*); + + template + void + _M_init_facet(_Facet* __facet) + { _M_install_facet(&_Facet::id, __facet); } + + void + _M_install_cache(const facet*, size_t); + }; +# 583 "/usr/include/c++/4.8.2/bits/locale_classes.h" 3 + template + class collate : public locale::facet + { + public: + + + + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + + + protected: + + + __c_locale _M_c_locale_collate; + + public: + + static locale::id id; +# 610 "/usr/include/c++/4.8.2/bits/locale_classes.h" 3 + explicit + collate(size_t __refs = 0) + : facet(__refs), _M_c_locale_collate(_S_get_c_locale()) + { } +# 624 "/usr/include/c++/4.8.2/bits/locale_classes.h" 3 + explicit + collate(__c_locale __cloc, size_t __refs = 0) + : facet(__refs), _M_c_locale_collate(_S_clone_c_locale(__cloc)) + { } +# 641 "/usr/include/c++/4.8.2/bits/locale_classes.h" 3 + int + compare(const _CharT* __lo1, const _CharT* __hi1, + const _CharT* __lo2, const _CharT* __hi2) const + { return this->do_compare(__lo1, __hi1, __lo2, __hi2); } +# 660 "/usr/include/c++/4.8.2/bits/locale_classes.h" 3 + string_type + transform(const _CharT* __lo, const _CharT* __hi) const + { return this->do_transform(__lo, __hi); } +# 674 "/usr/include/c++/4.8.2/bits/locale_classes.h" 3 + long + hash(const _CharT* __lo, const _CharT* __hi) const + { return this->do_hash(__lo, __hi); } + + + int + _M_compare(const _CharT*, const _CharT*) const throw(); + + size_t + _M_transform(_CharT*, const _CharT*, size_t) const throw(); + + protected: + + virtual + ~collate() + { _S_destroy_c_locale(_M_c_locale_collate); } +# 703 "/usr/include/c++/4.8.2/bits/locale_classes.h" 3 + virtual int + do_compare(const _CharT* __lo1, const _CharT* __hi1, + const _CharT* __lo2, const _CharT* __hi2) const; +# 717 "/usr/include/c++/4.8.2/bits/locale_classes.h" 3 + virtual string_type + do_transform(const _CharT* __lo, const _CharT* __hi) const; +# 730 "/usr/include/c++/4.8.2/bits/locale_classes.h" 3 + virtual long + do_hash(const _CharT* __lo, const _CharT* __hi) const; + }; + + template + locale::id collate<_CharT>::id; + + + template<> + int + collate::_M_compare(const char*, const char*) const throw(); + + template<> + size_t + collate::_M_transform(char*, const char*, size_t) const throw(); + + + template<> + int + collate::_M_compare(const wchar_t*, const wchar_t*) const throw(); + + template<> + size_t + collate::_M_transform(wchar_t*, const wchar_t*, size_t) const throw(); + + + + template + class collate_byname : public collate<_CharT> + { + public: + + + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + + + explicit + collate_byname(const char* __s, size_t __refs = 0) + : collate<_CharT>(__refs) + { + if (__builtin_strcmp(__s, "C") != 0 + && __builtin_strcmp(__s, "POSIX") != 0) + { + this->_S_destroy_c_locale(this->_M_c_locale_collate); + this->_S_create_c_locale(this->_M_c_locale_collate, __s); + } + } + + protected: + virtual + ~collate_byname() { } + }; + + +} + +# 1 "/usr/include/c++/4.8.2/bits/locale_classes.tcc" 1 3 +# 37 "/usr/include/c++/4.8.2/bits/locale_classes.tcc" 3 + +# 38 "/usr/include/c++/4.8.2/bits/locale_classes.tcc" 3 + +namespace std __attribute__ ((__visibility__ ("default"))) +{ + + + template + locale:: + locale(const locale& __other, _Facet* __f) + { + _M_impl = new _Impl(*__other._M_impl, 1); + + try + { _M_impl->_M_install_facet(&_Facet::id, __f); } + catch(...) + { + _M_impl->_M_remove_reference(); + throw; + } + delete [] _M_impl->_M_names[0]; + _M_impl->_M_names[0] = 0; + } + + template + locale + locale:: + combine(const locale& __other) const + { + _Impl* __tmp = new _Impl(*_M_impl, 1); + try + { + __tmp->_M_replace_facet(__other._M_impl, &_Facet::id); + } + catch(...) + { + __tmp->_M_remove_reference(); + throw; + } + return locale(__tmp); + } + + template + bool + locale:: + operator()(const basic_string<_CharT, _Traits, _Alloc>& __s1, + const basic_string<_CharT, _Traits, _Alloc>& __s2) const + { + typedef std::collate<_CharT> __collate_type; + const __collate_type& __collate = use_facet<__collate_type>(*this); + return (__collate.compare(__s1.data(), __s1.data() + __s1.length(), + __s2.data(), __s2.data() + __s2.length()) < 0); + } +# 102 "/usr/include/c++/4.8.2/bits/locale_classes.tcc" 3 + template + bool + has_facet(const locale& __loc) throw() + { + const size_t __i = _Facet::id._M_id(); + const locale::facet** __facets = __loc._M_impl->_M_facets; + return (__i < __loc._M_impl->_M_facets_size + + && dynamic_cast(__facets[__i])); + + + + } +# 130 "/usr/include/c++/4.8.2/bits/locale_classes.tcc" 3 + template + const _Facet& + use_facet(const locale& __loc) + { + const size_t __i = _Facet::id._M_id(); + const locale::facet** __facets = __loc._M_impl->_M_facets; + if (__i >= __loc._M_impl->_M_facets_size || !__facets[__i]) + __throw_bad_cast(); + + return dynamic_cast(*__facets[__i]); + + + + } + + + + template + int + collate<_CharT>::_M_compare(const _CharT*, const _CharT*) const throw () + { return 0; } + + + template + size_t + collate<_CharT>::_M_transform(_CharT*, const _CharT*, size_t) const throw () + { return 0; } + + template + int + collate<_CharT>:: + do_compare(const _CharT* __lo1, const _CharT* __hi1, + const _CharT* __lo2, const _CharT* __hi2) const + { + + + const string_type __one(__lo1, __hi1); + const string_type __two(__lo2, __hi2); + + const _CharT* __p = __one.c_str(); + const _CharT* __pend = __one.data() + __one.length(); + const _CharT* __q = __two.c_str(); + const _CharT* __qend = __two.data() + __two.length(); + + + + + for (;;) + { + const int __res = _M_compare(__p, __q); + if (__res) + return __res; + + __p += char_traits<_CharT>::length(__p); + __q += char_traits<_CharT>::length(__q); + if (__p == __pend && __q == __qend) + return 0; + else if (__p == __pend) + return -1; + else if (__q == __qend) + return 1; + + __p++; + __q++; + } + } + + template + typename collate<_CharT>::string_type + collate<_CharT>:: + do_transform(const _CharT* __lo, const _CharT* __hi) const + { + string_type __ret; + + + const string_type __str(__lo, __hi); + + const _CharT* __p = __str.c_str(); + const _CharT* __pend = __str.data() + __str.length(); + + size_t __len = (__hi - __lo) * 2; + + _CharT* __c = new _CharT[__len]; + + try + { + + + + for (;;) + { + + size_t __res = _M_transform(__c, __p, __len); + + + if (__res >= __len) + { + __len = __res + 1; + delete [] __c, __c = 0; + __c = new _CharT[__len]; + __res = _M_transform(__c, __p, __len); + } + + __ret.append(__c, __res); + __p += char_traits<_CharT>::length(__p); + if (__p == __pend) + break; + + __p++; + __ret.push_back(_CharT()); + } + } + catch(...) + { + delete [] __c; + throw; + } + + delete [] __c; + + return __ret; + } + + template + long + collate<_CharT>:: + do_hash(const _CharT* __lo, const _CharT* __hi) const + { + unsigned long __val = 0; + for (; __lo < __hi; ++__lo) + __val = + *__lo + ((__val << 7) + | (__val >> (__gnu_cxx::__numeric_traits:: + __digits - 7))); + return static_cast(__val); + } + + + + + extern template class collate; + extern template class collate_byname; + + extern template + const collate& + use_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + + extern template class collate; + extern template class collate_byname; + + extern template + const collate& + use_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + + + +} +# 788 "/usr/include/c++/4.8.2/bits/locale_classes.h" 2 3 +# 42 "/usr/include/c++/4.8.2/bits/ios_base.h" 2 3 + +namespace std __attribute__ ((__visibility__ ("default"))) +{ + + + + + + + enum _Ios_Fmtflags + { + _S_boolalpha = 1L << 0, + _S_dec = 1L << 1, + _S_fixed = 1L << 2, + _S_hex = 1L << 3, + _S_internal = 1L << 4, + _S_left = 1L << 5, + _S_oct = 1L << 6, + _S_right = 1L << 7, + _S_scientific = 1L << 8, + _S_showbase = 1L << 9, + _S_showpoint = 1L << 10, + _S_showpos = 1L << 11, + _S_skipws = 1L << 12, + _S_unitbuf = 1L << 13, + _S_uppercase = 1L << 14, + _S_adjustfield = _S_left | _S_right | _S_internal, + _S_basefield = _S_dec | _S_oct | _S_hex, + _S_floatfield = _S_scientific | _S_fixed, + _S_ios_fmtflags_end = 1L << 16 + }; + + inline _Ios_Fmtflags + operator&(_Ios_Fmtflags __a, _Ios_Fmtflags __b) + { return _Ios_Fmtflags(static_cast(__a) & static_cast(__b)); } + + inline _Ios_Fmtflags + operator|(_Ios_Fmtflags __a, _Ios_Fmtflags __b) + { return _Ios_Fmtflags(static_cast(__a) | static_cast(__b)); } + + inline _Ios_Fmtflags + operator^(_Ios_Fmtflags __a, _Ios_Fmtflags __b) + { return _Ios_Fmtflags(static_cast(__a) ^ static_cast(__b)); } + + inline _Ios_Fmtflags + operator~(_Ios_Fmtflags __a) + { return _Ios_Fmtflags(~static_cast(__a)); } + + inline const _Ios_Fmtflags& + operator|=(_Ios_Fmtflags& __a, _Ios_Fmtflags __b) + { return __a = __a | __b; } + + inline const _Ios_Fmtflags& + operator&=(_Ios_Fmtflags& __a, _Ios_Fmtflags __b) + { return __a = __a & __b; } + + inline const _Ios_Fmtflags& + operator^=(_Ios_Fmtflags& __a, _Ios_Fmtflags __b) + { return __a = __a ^ __b; } + + + enum _Ios_Openmode + { + _S_app = 1L << 0, + _S_ate = 1L << 1, + _S_bin = 1L << 2, + _S_in = 1L << 3, + _S_out = 1L << 4, + _S_trunc = 1L << 5, + _S_ios_openmode_end = 1L << 16 + }; + + inline _Ios_Openmode + operator&(_Ios_Openmode __a, _Ios_Openmode __b) + { return _Ios_Openmode(static_cast(__a) & static_cast(__b)); } + + inline _Ios_Openmode + operator|(_Ios_Openmode __a, _Ios_Openmode __b) + { return _Ios_Openmode(static_cast(__a) | static_cast(__b)); } + + inline _Ios_Openmode + operator^(_Ios_Openmode __a, _Ios_Openmode __b) + { return _Ios_Openmode(static_cast(__a) ^ static_cast(__b)); } + + inline _Ios_Openmode + operator~(_Ios_Openmode __a) + { return _Ios_Openmode(~static_cast(__a)); } + + inline const _Ios_Openmode& + operator|=(_Ios_Openmode& __a, _Ios_Openmode __b) + { return __a = __a | __b; } + + inline const _Ios_Openmode& + operator&=(_Ios_Openmode& __a, _Ios_Openmode __b) + { return __a = __a & __b; } + + inline const _Ios_Openmode& + operator^=(_Ios_Openmode& __a, _Ios_Openmode __b) + { return __a = __a ^ __b; } + + + enum _Ios_Iostate + { + _S_goodbit = 0, + _S_badbit = 1L << 0, + _S_eofbit = 1L << 1, + _S_failbit = 1L << 2, + _S_ios_iostate_end = 1L << 16 + }; + + inline _Ios_Iostate + operator&(_Ios_Iostate __a, _Ios_Iostate __b) + { return _Ios_Iostate(static_cast(__a) & static_cast(__b)); } + + inline _Ios_Iostate + operator|(_Ios_Iostate __a, _Ios_Iostate __b) + { return _Ios_Iostate(static_cast(__a) | static_cast(__b)); } + + inline _Ios_Iostate + operator^(_Ios_Iostate __a, _Ios_Iostate __b) + { return _Ios_Iostate(static_cast(__a) ^ static_cast(__b)); } + + inline _Ios_Iostate + operator~(_Ios_Iostate __a) + { return _Ios_Iostate(~static_cast(__a)); } + + inline const _Ios_Iostate& + operator|=(_Ios_Iostate& __a, _Ios_Iostate __b) + { return __a = __a | __b; } + + inline const _Ios_Iostate& + operator&=(_Ios_Iostate& __a, _Ios_Iostate __b) + { return __a = __a & __b; } + + inline const _Ios_Iostate& + operator^=(_Ios_Iostate& __a, _Ios_Iostate __b) + { return __a = __a ^ __b; } + + + enum _Ios_Seekdir + { + _S_beg = 0, + _S_cur = 1, + _S_end = 2, + _S_ios_seekdir_end = 1L << 16 + }; +# 199 "/usr/include/c++/4.8.2/bits/ios_base.h" 3 + class ios_base + { + public: + + + + + + + + class failure : public exception + { + public: + + + explicit + failure(const string& __str) throw(); + + + + virtual + ~failure() throw(); + + virtual const char* + what() const throw(); + + private: + string _M_msg; + }; +# 255 "/usr/include/c++/4.8.2/bits/ios_base.h" 3 + typedef _Ios_Fmtflags fmtflags; + + + static const fmtflags boolalpha = _S_boolalpha; + + + static const fmtflags dec = _S_dec; + + + static const fmtflags fixed = _S_fixed; + + + static const fmtflags hex = _S_hex; + + + + + static const fmtflags internal = _S_internal; + + + + static const fmtflags left = _S_left; + + + static const fmtflags oct = _S_oct; + + + + static const fmtflags right = _S_right; + + + static const fmtflags scientific = _S_scientific; + + + + static const fmtflags showbase = _S_showbase; + + + + static const fmtflags showpoint = _S_showpoint; + + + static const fmtflags showpos = _S_showpos; + + + static const fmtflags skipws = _S_skipws; + + + static const fmtflags unitbuf = _S_unitbuf; + + + + static const fmtflags uppercase = _S_uppercase; + + + static const fmtflags adjustfield = _S_adjustfield; + + + static const fmtflags basefield = _S_basefield; + + + static const fmtflags floatfield = _S_floatfield; +# 330 "/usr/include/c++/4.8.2/bits/ios_base.h" 3 + typedef _Ios_Iostate iostate; + + + + static const iostate badbit = _S_badbit; + + + static const iostate eofbit = _S_eofbit; + + + + + static const iostate failbit = _S_failbit; + + + static const iostate goodbit = _S_goodbit; +# 361 "/usr/include/c++/4.8.2/bits/ios_base.h" 3 + typedef _Ios_Openmode openmode; + + + static const openmode app = _S_app; + + + static const openmode ate = _S_ate; + + + + + static const openmode binary = _S_bin; + + + static const openmode in = _S_in; + + + static const openmode out = _S_out; + + + static const openmode trunc = _S_trunc; +# 393 "/usr/include/c++/4.8.2/bits/ios_base.h" 3 + typedef _Ios_Seekdir seekdir; + + + static const seekdir beg = _S_beg; + + + static const seekdir cur = _S_cur; + + + static const seekdir end = _S_end; + + + typedef int io_state; + typedef int open_mode; + typedef int seek_dir; + + typedef std::streampos streampos; + typedef std::streamoff streamoff; +# 419 "/usr/include/c++/4.8.2/bits/ios_base.h" 3 + enum event + { + erase_event, + imbue_event, + copyfmt_event + }; +# 436 "/usr/include/c++/4.8.2/bits/ios_base.h" 3 + typedef void (*event_callback) (event __e, ios_base& __b, int __i); +# 448 "/usr/include/c++/4.8.2/bits/ios_base.h" 3 + void + register_callback(event_callback __fn, int __index); + + protected: + streamsize _M_precision; + streamsize _M_width; + fmtflags _M_flags; + iostate _M_exception; + iostate _M_streambuf_state; + + + + struct _Callback_list + { + + _Callback_list* _M_next; + ios_base::event_callback _M_fn; + int _M_index; + _Atomic_word _M_refcount; + + _Callback_list(ios_base::event_callback __fn, int __index, + _Callback_list* __cb) + : _M_next(__cb), _M_fn(__fn), _M_index(__index), _M_refcount(0) { } + + void + _M_add_reference() { __gnu_cxx::__atomic_add_dispatch(&_M_refcount, 1); } + + + int + _M_remove_reference() + { + + ; + int __res = __gnu_cxx::__exchange_and_add_dispatch(&_M_refcount, -1); + if (__res == 0) + { + ; + } + return __res; + } + }; + + _Callback_list* _M_callbacks; + + void + _M_call_callbacks(event __ev) throw(); + + void + _M_dispose_callbacks(void) throw(); + + + struct _Words + { + void* _M_pword; + long _M_iword; + _Words() : _M_pword(0), _M_iword(0) { } + }; + + + _Words _M_word_zero; + + + + enum { _S_local_word_size = 8 }; + _Words _M_local_word[_S_local_word_size]; + + + int _M_word_size; + _Words* _M_word; + + _Words& + _M_grow_words(int __index, bool __iword); + + + locale _M_ios_locale; + + void + _M_init() throw(); + + public: + + + + + + class Init + { + friend class ios_base; + public: + Init(); + ~Init(); + + private: + static _Atomic_word _S_refcount; + static bool _S_synced_with_stdio; + }; + + + + + + + fmtflags + flags() const + { return _M_flags; } +# 561 "/usr/include/c++/4.8.2/bits/ios_base.h" 3 + fmtflags + flags(fmtflags __fmtfl) + { + fmtflags __old = _M_flags; + _M_flags = __fmtfl; + return __old; + } +# 577 "/usr/include/c++/4.8.2/bits/ios_base.h" 3 + fmtflags + setf(fmtflags __fmtfl) + { + fmtflags __old = _M_flags; + _M_flags |= __fmtfl; + return __old; + } +# 594 "/usr/include/c++/4.8.2/bits/ios_base.h" 3 + fmtflags + setf(fmtflags __fmtfl, fmtflags __mask) + { + fmtflags __old = _M_flags; + _M_flags &= ~__mask; + _M_flags |= (__fmtfl & __mask); + return __old; + } + + + + + + + + void + unsetf(fmtflags __mask) + { _M_flags &= ~__mask; } +# 620 "/usr/include/c++/4.8.2/bits/ios_base.h" 3 + streamsize + precision() const + { return _M_precision; } + + + + + + + streamsize + precision(streamsize __prec) + { + streamsize __old = _M_precision; + _M_precision = __prec; + return __old; + } + + + + + + + + streamsize + width() const + { return _M_width; } + + + + + + + streamsize + width(streamsize __wide) + { + streamsize __old = _M_width; + _M_width = __wide; + return __old; + } +# 671 "/usr/include/c++/4.8.2/bits/ios_base.h" 3 + static bool + sync_with_stdio(bool __sync = true); +# 683 "/usr/include/c++/4.8.2/bits/ios_base.h" 3 + locale + imbue(const locale& __loc) throw(); +# 694 "/usr/include/c++/4.8.2/bits/ios_base.h" 3 + locale + getloc() const + { return _M_ios_locale; } +# 705 "/usr/include/c++/4.8.2/bits/ios_base.h" 3 + const locale& + _M_getloc() const + { return _M_ios_locale; } +# 724 "/usr/include/c++/4.8.2/bits/ios_base.h" 3 + static int + xalloc() throw(); +# 740 "/usr/include/c++/4.8.2/bits/ios_base.h" 3 + long& + iword(int __ix) + { + _Words& __word = (__ix < _M_word_size) + ? _M_word[__ix] : _M_grow_words(__ix, true); + return __word._M_iword; + } +# 761 "/usr/include/c++/4.8.2/bits/ios_base.h" 3 + void*& + pword(int __ix) + { + _Words& __word = (__ix < _M_word_size) + ? _M_word[__ix] : _M_grow_words(__ix, false); + return __word._M_pword; + } +# 778 "/usr/include/c++/4.8.2/bits/ios_base.h" 3 + virtual ~ios_base(); + + protected: + ios_base() throw (); + + + + private: + ios_base(const ios_base&); + + ios_base& + operator=(const ios_base&); + }; + + + + inline ios_base& + boolalpha(ios_base& __base) + { + __base.setf(ios_base::boolalpha); + return __base; + } + + + inline ios_base& + noboolalpha(ios_base& __base) + { + __base.unsetf(ios_base::boolalpha); + return __base; + } + + + inline ios_base& + showbase(ios_base& __base) + { + __base.setf(ios_base::showbase); + return __base; + } + + + inline ios_base& + noshowbase(ios_base& __base) + { + __base.unsetf(ios_base::showbase); + return __base; + } + + + inline ios_base& + showpoint(ios_base& __base) + { + __base.setf(ios_base::showpoint); + return __base; + } + + + inline ios_base& + noshowpoint(ios_base& __base) + { + __base.unsetf(ios_base::showpoint); + return __base; + } + + + inline ios_base& + showpos(ios_base& __base) + { + __base.setf(ios_base::showpos); + return __base; + } + + + inline ios_base& + noshowpos(ios_base& __base) + { + __base.unsetf(ios_base::showpos); + return __base; + } + + + inline ios_base& + skipws(ios_base& __base) + { + __base.setf(ios_base::skipws); + return __base; + } + + + inline ios_base& + noskipws(ios_base& __base) + { + __base.unsetf(ios_base::skipws); + return __base; + } + + + inline ios_base& + uppercase(ios_base& __base) + { + __base.setf(ios_base::uppercase); + return __base; + } + + + inline ios_base& + nouppercase(ios_base& __base) + { + __base.unsetf(ios_base::uppercase); + return __base; + } + + + inline ios_base& + unitbuf(ios_base& __base) + { + __base.setf(ios_base::unitbuf); + return __base; + } + + + inline ios_base& + nounitbuf(ios_base& __base) + { + __base.unsetf(ios_base::unitbuf); + return __base; + } + + + + inline ios_base& + internal(ios_base& __base) + { + __base.setf(ios_base::internal, ios_base::adjustfield); + return __base; + } + + + inline ios_base& + left(ios_base& __base) + { + __base.setf(ios_base::left, ios_base::adjustfield); + return __base; + } + + + inline ios_base& + right(ios_base& __base) + { + __base.setf(ios_base::right, ios_base::adjustfield); + return __base; + } + + + + inline ios_base& + dec(ios_base& __base) + { + __base.setf(ios_base::dec, ios_base::basefield); + return __base; + } + + + inline ios_base& + hex(ios_base& __base) + { + __base.setf(ios_base::hex, ios_base::basefield); + return __base; + } + + + inline ios_base& + oct(ios_base& __base) + { + __base.setf(ios_base::oct, ios_base::basefield); + return __base; + } + + + + inline ios_base& + fixed(ios_base& __base) + { + __base.setf(ios_base::fixed, ios_base::floatfield); + return __base; + } + + + inline ios_base& + scientific(ios_base& __base) + { + __base.setf(ios_base::scientific, ios_base::floatfield); + return __base; + } + + +} +# 43 "/usr/include/c++/4.8.2/ios" 2 3 +# 1 "/usr/include/c++/4.8.2/streambuf" 1 3 +# 36 "/usr/include/c++/4.8.2/streambuf" 3 + +# 37 "/usr/include/c++/4.8.2/streambuf" 3 +# 45 "/usr/include/c++/4.8.2/streambuf" 3 +namespace std __attribute__ ((__visibility__ ("default"))) +{ + + + template + streamsize + __copy_streambufs_eof(basic_streambuf<_CharT, _Traits>*, + basic_streambuf<_CharT, _Traits>*, bool&); +# 119 "/usr/include/c++/4.8.2/streambuf" 3 + template + class basic_streambuf + { + public: + + + + + + + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + + + + typedef basic_streambuf __streambuf_type; + + + friend class basic_ios; + friend class basic_istream; + friend class basic_ostream; + friend class istreambuf_iterator; + friend class ostreambuf_iterator; + + friend streamsize + __copy_streambufs_eof<>(basic_streambuf*, basic_streambuf*, bool&); + + template + friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, + _CharT2*>::__type + __copy_move_a2(istreambuf_iterator<_CharT2>, + istreambuf_iterator<_CharT2>, _CharT2*); + + template + friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, + istreambuf_iterator<_CharT2> >::__type + find(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>, + const _CharT2&); + + template + friend basic_istream<_CharT2, _Traits2>& + operator>>(basic_istream<_CharT2, _Traits2>&, _CharT2*); + + template + friend basic_istream<_CharT2, _Traits2>& + operator>>(basic_istream<_CharT2, _Traits2>&, + basic_string<_CharT2, _Traits2, _Alloc>&); + + template + friend basic_istream<_CharT2, _Traits2>& + getline(basic_istream<_CharT2, _Traits2>&, + basic_string<_CharT2, _Traits2, _Alloc>&, _CharT2); + + protected: + + + + + + + + char_type* _M_in_beg; + char_type* _M_in_cur; + char_type* _M_in_end; + char_type* _M_out_beg; + char_type* _M_out_cur; + char_type* _M_out_end; + + + locale _M_buf_locale; + + public: + + virtual + ~basic_streambuf() + { } +# 208 "/usr/include/c++/4.8.2/streambuf" 3 + locale + pubimbue(const locale& __loc) + { + locale __tmp(this->getloc()); + this->imbue(__loc); + _M_buf_locale = __loc; + return __tmp; + } +# 225 "/usr/include/c++/4.8.2/streambuf" 3 + locale + getloc() const + { return _M_buf_locale; } +# 238 "/usr/include/c++/4.8.2/streambuf" 3 + basic_streambuf* + pubsetbuf(char_type* __s, streamsize __n) + { return this->setbuf(__s, __n); } +# 250 "/usr/include/c++/4.8.2/streambuf" 3 + pos_type + pubseekoff(off_type __off, ios_base::seekdir __way, + ios_base::openmode __mode = ios_base::in | ios_base::out) + { return this->seekoff(__off, __way, __mode); } +# 262 "/usr/include/c++/4.8.2/streambuf" 3 + pos_type + pubseekpos(pos_type __sp, + ios_base::openmode __mode = ios_base::in | ios_base::out) + { return this->seekpos(__sp, __mode); } + + + + + int + pubsync() { return this->sync(); } +# 283 "/usr/include/c++/4.8.2/streambuf" 3 + streamsize + in_avail() + { + const streamsize __ret = this->egptr() - this->gptr(); + return __ret ? __ret : this->showmanyc(); + } +# 297 "/usr/include/c++/4.8.2/streambuf" 3 + int_type + snextc() + { + int_type __ret = traits_type::eof(); + if (__builtin_expect(!traits_type::eq_int_type(this->sbumpc(), + __ret), true)) + __ret = this->sgetc(); + return __ret; + } +# 315 "/usr/include/c++/4.8.2/streambuf" 3 + int_type + sbumpc() + { + int_type __ret; + if (__builtin_expect(this->gptr() < this->egptr(), true)) + { + __ret = traits_type::to_int_type(*this->gptr()); + this->gbump(1); + } + else + __ret = this->uflow(); + return __ret; + } +# 337 "/usr/include/c++/4.8.2/streambuf" 3 + int_type + sgetc() + { + int_type __ret; + if (__builtin_expect(this->gptr() < this->egptr(), true)) + __ret = traits_type::to_int_type(*this->gptr()); + else + __ret = this->underflow(); + return __ret; + } +# 356 "/usr/include/c++/4.8.2/streambuf" 3 + streamsize + sgetn(char_type* __s, streamsize __n) + { return this->xsgetn(__s, __n); } +# 371 "/usr/include/c++/4.8.2/streambuf" 3 + int_type + sputbackc(char_type __c) + { + int_type __ret; + const bool __testpos = this->eback() < this->gptr(); + if (__builtin_expect(!__testpos || + !traits_type::eq(__c, this->gptr()[-1]), false)) + __ret = this->pbackfail(traits_type::to_int_type(__c)); + else + { + this->gbump(-1); + __ret = traits_type::to_int_type(*this->gptr()); + } + return __ret; + } +# 396 "/usr/include/c++/4.8.2/streambuf" 3 + int_type + sungetc() + { + int_type __ret; + if (__builtin_expect(this->eback() < this->gptr(), true)) + { + this->gbump(-1); + __ret = traits_type::to_int_type(*this->gptr()); + } + else + __ret = this->pbackfail(); + return __ret; + } +# 423 "/usr/include/c++/4.8.2/streambuf" 3 + int_type + sputc(char_type __c) + { + int_type __ret; + if (__builtin_expect(this->pptr() < this->epptr(), true)) + { + *this->pptr() = __c; + this->pbump(1); + __ret = traits_type::to_int_type(__c); + } + else + __ret = this->overflow(traits_type::to_int_type(__c)); + return __ret; + } +# 449 "/usr/include/c++/4.8.2/streambuf" 3 + streamsize + sputn(const char_type* __s, streamsize __n) + { return this->xsputn(__s, __n); } + + protected: +# 463 "/usr/include/c++/4.8.2/streambuf" 3 + basic_streambuf() + : _M_in_beg(0), _M_in_cur(0), _M_in_end(0), + _M_out_beg(0), _M_out_cur(0), _M_out_end(0), + _M_buf_locale(locale()) + { } +# 481 "/usr/include/c++/4.8.2/streambuf" 3 + char_type* + eback() const { return _M_in_beg; } + + char_type* + gptr() const { return _M_in_cur; } + + char_type* + egptr() const { return _M_in_end; } +# 497 "/usr/include/c++/4.8.2/streambuf" 3 + void + gbump(int __n) { _M_in_cur += __n; } +# 508 "/usr/include/c++/4.8.2/streambuf" 3 + void + setg(char_type* __gbeg, char_type* __gnext, char_type* __gend) + { + _M_in_beg = __gbeg; + _M_in_cur = __gnext; + _M_in_end = __gend; + } +# 528 "/usr/include/c++/4.8.2/streambuf" 3 + char_type* + pbase() const { return _M_out_beg; } + + char_type* + pptr() const { return _M_out_cur; } + + char_type* + epptr() const { return _M_out_end; } +# 544 "/usr/include/c++/4.8.2/streambuf" 3 + void + pbump(int __n) { _M_out_cur += __n; } +# 554 "/usr/include/c++/4.8.2/streambuf" 3 + void + setp(char_type* __pbeg, char_type* __pend) + { + _M_out_beg = _M_out_cur = __pbeg; + _M_out_end = __pend; + } +# 575 "/usr/include/c++/4.8.2/streambuf" 3 + virtual void + imbue(const locale& __loc) + { } +# 590 "/usr/include/c++/4.8.2/streambuf" 3 + virtual basic_streambuf* + setbuf(char_type*, streamsize) + { return this; } +# 601 "/usr/include/c++/4.8.2/streambuf" 3 + virtual pos_type + seekoff(off_type, ios_base::seekdir, + ios_base::openmode = ios_base::in | ios_base::out) + { return pos_type(off_type(-1)); } +# 613 "/usr/include/c++/4.8.2/streambuf" 3 + virtual pos_type + seekpos(pos_type, + ios_base::openmode = ios_base::in | ios_base::out) + { return pos_type(off_type(-1)); } +# 626 "/usr/include/c++/4.8.2/streambuf" 3 + virtual int + sync() { return 0; } +# 648 "/usr/include/c++/4.8.2/streambuf" 3 + virtual streamsize + showmanyc() { return 0; } +# 664 "/usr/include/c++/4.8.2/streambuf" 3 + virtual streamsize + xsgetn(char_type* __s, streamsize __n); +# 686 "/usr/include/c++/4.8.2/streambuf" 3 + virtual int_type + underflow() + { return traits_type::eof(); } +# 699 "/usr/include/c++/4.8.2/streambuf" 3 + virtual int_type + uflow() + { + int_type __ret = traits_type::eof(); + const bool __testeof = traits_type::eq_int_type(this->underflow(), + __ret); + if (!__testeof) + { + __ret = traits_type::to_int_type(*this->gptr()); + this->gbump(1); + } + return __ret; + } +# 723 "/usr/include/c++/4.8.2/streambuf" 3 + virtual int_type + pbackfail(int_type __c = traits_type::eof()) + { return traits_type::eof(); } +# 741 "/usr/include/c++/4.8.2/streambuf" 3 + virtual streamsize + xsputn(const char_type* __s, streamsize __n); +# 767 "/usr/include/c++/4.8.2/streambuf" 3 + virtual int_type + overflow(int_type __c = traits_type::eof()) + { return traits_type::eof(); } + + + + public: +# 782 "/usr/include/c++/4.8.2/streambuf" 3 + void + stossc() + { + if (this->gptr() < this->egptr()) + this->gbump(1); + else + this->uflow(); + } + + + + void + __safe_gbump(streamsize __n) { _M_in_cur += __n; } + + void + __safe_pbump(streamsize __n) { _M_out_cur += __n; } + + private: + + + basic_streambuf(const basic_streambuf& __sb) + : _M_in_beg(__sb._M_in_beg), _M_in_cur(__sb._M_in_cur), + _M_in_end(__sb._M_in_end), _M_out_beg(__sb._M_out_beg), + _M_out_cur(__sb._M_out_cur), _M_out_end(__sb._M_out_end), + _M_buf_locale(__sb._M_buf_locale) + { } + + basic_streambuf& + operator=(const basic_streambuf& __sb) + { + _M_in_beg = __sb._M_in_beg; + _M_in_cur = __sb._M_in_cur; + _M_in_end = __sb._M_in_end; + _M_out_beg = __sb._M_out_beg; + _M_out_cur = __sb._M_out_cur; + _M_out_end = __sb._M_out_end; + _M_buf_locale = __sb._M_buf_locale; + return *this; + }; + }; + + + template<> + streamsize + __copy_streambufs_eof(basic_streambuf* __sbin, + basic_streambuf* __sbout, bool& __ineof); + + template<> + streamsize + __copy_streambufs_eof(basic_streambuf* __sbin, + basic_streambuf* __sbout, bool& __ineof); + + + +} + +# 1 "/usr/include/c++/4.8.2/bits/streambuf.tcc" 1 3 +# 37 "/usr/include/c++/4.8.2/bits/streambuf.tcc" 3 + +# 38 "/usr/include/c++/4.8.2/bits/streambuf.tcc" 3 + +namespace std __attribute__ ((__visibility__ ("default"))) +{ + + + template + streamsize + basic_streambuf<_CharT, _Traits>:: + xsgetn(char_type* __s, streamsize __n) + { + streamsize __ret = 0; + while (__ret < __n) + { + const streamsize __buf_len = this->egptr() - this->gptr(); + if (__buf_len) + { + const streamsize __remaining = __n - __ret; + const streamsize __len = std::min(__buf_len, __remaining); + traits_type::copy(__s, this->gptr(), __len); + __ret += __len; + __s += __len; + this->__safe_gbump(__len); + } + + if (__ret < __n) + { + const int_type __c = this->uflow(); + if (!traits_type::eq_int_type(__c, traits_type::eof())) + { + traits_type::assign(*__s++, traits_type::to_char_type(__c)); + ++__ret; + } + else + break; + } + } + return __ret; + } + + template + streamsize + basic_streambuf<_CharT, _Traits>:: + xsputn(const char_type* __s, streamsize __n) + { + streamsize __ret = 0; + while (__ret < __n) + { + const streamsize __buf_len = this->epptr() - this->pptr(); + if (__buf_len) + { + const streamsize __remaining = __n - __ret; + const streamsize __len = std::min(__buf_len, __remaining); + traits_type::copy(this->pptr(), __s, __len); + __ret += __len; + __s += __len; + this->__safe_pbump(__len); + } + + if (__ret < __n) + { + int_type __c = this->overflow(traits_type::to_int_type(*__s)); + if (!traits_type::eq_int_type(__c, traits_type::eof())) + { + ++__ret; + ++__s; + } + else + break; + } + } + return __ret; + } + + + + + template + streamsize + __copy_streambufs_eof(basic_streambuf<_CharT, _Traits>* __sbin, + basic_streambuf<_CharT, _Traits>* __sbout, + bool& __ineof) + { + streamsize __ret = 0; + __ineof = true; + typename _Traits::int_type __c = __sbin->sgetc(); + while (!_Traits::eq_int_type(__c, _Traits::eof())) + { + __c = __sbout->sputc(_Traits::to_char_type(__c)); + if (_Traits::eq_int_type(__c, _Traits::eof())) + { + __ineof = false; + break; + } + ++__ret; + __c = __sbin->snextc(); + } + return __ret; + } + + template + inline streamsize + __copy_streambufs(basic_streambuf<_CharT, _Traits>* __sbin, + basic_streambuf<_CharT, _Traits>* __sbout) + { + bool __ineof; + return __copy_streambufs_eof(__sbin, __sbout, __ineof); + } + + + + + extern template class basic_streambuf; + extern template + streamsize + __copy_streambufs(basic_streambuf*, + basic_streambuf*); + extern template + streamsize + __copy_streambufs_eof(basic_streambuf*, + basic_streambuf*, bool&); + + + extern template class basic_streambuf; + extern template + streamsize + __copy_streambufs(basic_streambuf*, + basic_streambuf*); + extern template + streamsize + __copy_streambufs_eof(basic_streambuf*, + basic_streambuf*, bool&); + + + + +} +# 839 "/usr/include/c++/4.8.2/streambuf" 2 3 +# 44 "/usr/include/c++/4.8.2/ios" 2 3 +# 1 "/usr/include/c++/4.8.2/bits/basic_ios.h" 1 3 +# 33 "/usr/include/c++/4.8.2/bits/basic_ios.h" 3 + +# 34 "/usr/include/c++/4.8.2/bits/basic_ios.h" 3 + + + +# 1 "/usr/include/c++/4.8.2/bits/locale_facets.h" 1 3 +# 37 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + +# 38 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + +# 1 "/usr/include/c++/4.8.2/cwctype" 1 3 +# 39 "/usr/include/c++/4.8.2/cwctype" 3 + +# 40 "/usr/include/c++/4.8.2/cwctype" 3 +# 50 "/usr/include/c++/4.8.2/cwctype" 3 +# 1 "/usr/include/wctype.h" 1 3 4 +# 33 "/usr/include/wctype.h" 3 4 +# 1 "/usr/include/wchar.h" 1 3 4 +# 34 "/usr/include/wctype.h" 2 3 4 +# 49 "/usr/include/wctype.h" 3 4 + + + +typedef unsigned long int wctype_t; + +# 71 "/usr/include/wctype.h" 3 4 +enum +{ + __ISwupper = 0, + __ISwlower = 1, + __ISwalpha = 2, + __ISwdigit = 3, + __ISwxdigit = 4, + __ISwspace = 5, + __ISwprint = 6, + __ISwgraph = 7, + __ISwblank = 8, + __ISwcntrl = 9, + __ISwpunct = 10, + __ISwalnum = 11, + + _ISwupper = ((__ISwupper) < 8 ? (int) ((1UL << (__ISwupper)) << 24) : ((__ISwupper) < 16 ? (int) ((1UL << (__ISwupper)) << 8) : ((__ISwupper) < 24 ? (int) ((1UL << (__ISwupper)) >> 8) : (int) ((1UL << (__ISwupper)) >> 24)))), + _ISwlower = ((__ISwlower) < 8 ? (int) ((1UL << (__ISwlower)) << 24) : ((__ISwlower) < 16 ? (int) ((1UL << (__ISwlower)) << 8) : ((__ISwlower) < 24 ? (int) ((1UL << (__ISwlower)) >> 8) : (int) ((1UL << (__ISwlower)) >> 24)))), + _ISwalpha = ((__ISwalpha) < 8 ? (int) ((1UL << (__ISwalpha)) << 24) : ((__ISwalpha) < 16 ? (int) ((1UL << (__ISwalpha)) << 8) : ((__ISwalpha) < 24 ? (int) ((1UL << (__ISwalpha)) >> 8) : (int) ((1UL << (__ISwalpha)) >> 24)))), + _ISwdigit = ((__ISwdigit) < 8 ? (int) ((1UL << (__ISwdigit)) << 24) : ((__ISwdigit) < 16 ? (int) ((1UL << (__ISwdigit)) << 8) : ((__ISwdigit) < 24 ? (int) ((1UL << (__ISwdigit)) >> 8) : (int) ((1UL << (__ISwdigit)) >> 24)))), + _ISwxdigit = ((__ISwxdigit) < 8 ? (int) ((1UL << (__ISwxdigit)) << 24) : ((__ISwxdigit) < 16 ? (int) ((1UL << (__ISwxdigit)) << 8) : ((__ISwxdigit) < 24 ? (int) ((1UL << (__ISwxdigit)) >> 8) : (int) ((1UL << (__ISwxdigit)) >> 24)))), + _ISwspace = ((__ISwspace) < 8 ? (int) ((1UL << (__ISwspace)) << 24) : ((__ISwspace) < 16 ? (int) ((1UL << (__ISwspace)) << 8) : ((__ISwspace) < 24 ? (int) ((1UL << (__ISwspace)) >> 8) : (int) ((1UL << (__ISwspace)) >> 24)))), + _ISwprint = ((__ISwprint) < 8 ? (int) ((1UL << (__ISwprint)) << 24) : ((__ISwprint) < 16 ? (int) ((1UL << (__ISwprint)) << 8) : ((__ISwprint) < 24 ? (int) ((1UL << (__ISwprint)) >> 8) : (int) ((1UL << (__ISwprint)) >> 24)))), + _ISwgraph = ((__ISwgraph) < 8 ? (int) ((1UL << (__ISwgraph)) << 24) : ((__ISwgraph) < 16 ? (int) ((1UL << (__ISwgraph)) << 8) : ((__ISwgraph) < 24 ? (int) ((1UL << (__ISwgraph)) >> 8) : (int) ((1UL << (__ISwgraph)) >> 24)))), + _ISwblank = ((__ISwblank) < 8 ? (int) ((1UL << (__ISwblank)) << 24) : ((__ISwblank) < 16 ? (int) ((1UL << (__ISwblank)) << 8) : ((__ISwblank) < 24 ? (int) ((1UL << (__ISwblank)) >> 8) : (int) ((1UL << (__ISwblank)) >> 24)))), + _ISwcntrl = ((__ISwcntrl) < 8 ? (int) ((1UL << (__ISwcntrl)) << 24) : ((__ISwcntrl) < 16 ? (int) ((1UL << (__ISwcntrl)) << 8) : ((__ISwcntrl) < 24 ? (int) ((1UL << (__ISwcntrl)) >> 8) : (int) ((1UL << (__ISwcntrl)) >> 24)))), + _ISwpunct = ((__ISwpunct) < 8 ? (int) ((1UL << (__ISwpunct)) << 24) : ((__ISwpunct) < 16 ? (int) ((1UL << (__ISwpunct)) << 8) : ((__ISwpunct) < 24 ? (int) ((1UL << (__ISwpunct)) >> 8) : (int) ((1UL << (__ISwpunct)) >> 24)))), + _ISwalnum = ((__ISwalnum) < 8 ? (int) ((1UL << (__ISwalnum)) << 24) : ((__ISwalnum) < 16 ? (int) ((1UL << (__ISwalnum)) << 8) : ((__ISwalnum) < 24 ? (int) ((1UL << (__ISwalnum)) >> 8) : (int) ((1UL << (__ISwalnum)) >> 24)))) +}; + + + +extern "C" { + + + + + + + + +extern int iswalnum (wint_t __wc) throw (); + + + + + +extern int iswalpha (wint_t __wc) throw (); + + +extern int iswcntrl (wint_t __wc) throw (); + + + +extern int iswdigit (wint_t __wc) throw (); + + + +extern int iswgraph (wint_t __wc) throw (); + + + + +extern int iswlower (wint_t __wc) throw (); + + +extern int iswprint (wint_t __wc) throw (); + + + + +extern int iswpunct (wint_t __wc) throw (); + + + + +extern int iswspace (wint_t __wc) throw (); + + + + +extern int iswupper (wint_t __wc) throw (); + + + + +extern int iswxdigit (wint_t __wc) throw (); + + + + + +extern int iswblank (wint_t __wc) throw (); +# 171 "/usr/include/wctype.h" 3 4 +extern wctype_t wctype (const char *__property) throw (); + + + +extern int iswctype (wint_t __wc, wctype_t __desc) throw (); + + + + + + + + + + +typedef const __int32_t *wctrans_t; + + + + + + + +extern wint_t towlower (wint_t __wc) throw (); + + +extern wint_t towupper (wint_t __wc) throw (); + + +} +# 213 "/usr/include/wctype.h" 3 4 +extern "C" { + + + + +extern wctrans_t wctrans (const char *__property) throw (); + + +extern wint_t towctrans (wint_t __wc, wctrans_t __desc) throw (); + + + + + + + + +extern int iswalnum_l (wint_t __wc, __locale_t __locale) throw (); + + + + + +extern int iswalpha_l (wint_t __wc, __locale_t __locale) throw (); + + +extern int iswcntrl_l (wint_t __wc, __locale_t __locale) throw (); + + + +extern int iswdigit_l (wint_t __wc, __locale_t __locale) throw (); + + + +extern int iswgraph_l (wint_t __wc, __locale_t __locale) throw (); + + + + +extern int iswlower_l (wint_t __wc, __locale_t __locale) throw (); + + +extern int iswprint_l (wint_t __wc, __locale_t __locale) throw (); + + + + +extern int iswpunct_l (wint_t __wc, __locale_t __locale) throw (); + + + + +extern int iswspace_l (wint_t __wc, __locale_t __locale) throw (); + + + + +extern int iswupper_l (wint_t __wc, __locale_t __locale) throw (); + + + + +extern int iswxdigit_l (wint_t __wc, __locale_t __locale) throw (); + + + + +extern int iswblank_l (wint_t __wc, __locale_t __locale) throw (); + + + +extern wctype_t wctype_l (const char *__property, __locale_t __locale) + throw (); + + + +extern int iswctype_l (wint_t __wc, wctype_t __desc, __locale_t __locale) + throw (); + + + + + + + +extern wint_t towlower_l (wint_t __wc, __locale_t __locale) throw (); + + +extern wint_t towupper_l (wint_t __wc, __locale_t __locale) throw (); + + + +extern wctrans_t wctrans_l (const char *__property, __locale_t __locale) + throw (); + + +extern wint_t towctrans_l (wint_t __wc, wctrans_t __desc, + __locale_t __locale) throw (); + + + +} +# 51 "/usr/include/c++/4.8.2/cwctype" 2 3 +# 80 "/usr/include/c++/4.8.2/cwctype" 3 +namespace std +{ + using ::wctrans_t; + using ::wctype_t; + using ::wint_t; + + using ::iswalnum; + using ::iswalpha; + + using ::iswblank; + + using ::iswcntrl; + using ::iswctype; + using ::iswdigit; + using ::iswgraph; + using ::iswlower; + using ::iswprint; + using ::iswpunct; + using ::iswspace; + using ::iswupper; + using ::iswxdigit; + using ::towctrans; + using ::towlower; + using ::towupper; + using ::wctrans; + using ::wctype; +} +# 40 "/usr/include/c++/4.8.2/bits/locale_facets.h" 2 3 +# 1 "/usr/include/c++/4.8.2/cctype" 1 3 +# 39 "/usr/include/c++/4.8.2/cctype" 3 + +# 40 "/usr/include/c++/4.8.2/cctype" 3 +# 41 "/usr/include/c++/4.8.2/bits/locale_facets.h" 2 3 +# 1 "/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/ctype_base.h" 1 3 +# 36 "/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/ctype_base.h" 3 +namespace std __attribute__ ((__visibility__ ("default"))) +{ + + + + struct ctype_base + { + + typedef const int* __to_type; + + + + typedef unsigned short mask; + static const mask upper = _ISupper; + static const mask lower = _ISlower; + static const mask alpha = _ISalpha; + static const mask digit = _ISdigit; + static const mask xdigit = _ISxdigit; + static const mask space = _ISspace; + static const mask print = _ISprint; + static const mask graph = _ISalpha | _ISdigit | _ISpunct; + static const mask cntrl = _IScntrl; + static const mask punct = _ISpunct; + static const mask alnum = _ISalpha | _ISdigit; + }; + + +} +# 42 "/usr/include/c++/4.8.2/bits/locale_facets.h" 2 3 + + + + + + +# 1 "/usr/include/c++/4.8.2/bits/streambuf_iterator.h" 1 3 +# 33 "/usr/include/c++/4.8.2/bits/streambuf_iterator.h" 3 + +# 34 "/usr/include/c++/4.8.2/bits/streambuf_iterator.h" 3 + + + + +namespace std __attribute__ ((__visibility__ ("default"))) +{ + +# 49 "/usr/include/c++/4.8.2/bits/streambuf_iterator.h" 3 + template + class istreambuf_iterator + : public iterator + + { + public: + + + + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename _Traits::int_type int_type; + typedef basic_streambuf<_CharT, _Traits> streambuf_type; + typedef basic_istream<_CharT, _Traits> istream_type; + + + template + friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, + ostreambuf_iterator<_CharT2> >::__type + copy(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>, + ostreambuf_iterator<_CharT2>); + + template + friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, + _CharT2*>::__type + __copy_move_a2(istreambuf_iterator<_CharT2>, + istreambuf_iterator<_CharT2>, _CharT2*); + + template + friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, + istreambuf_iterator<_CharT2> >::__type + find(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>, + const _CharT2&); + + private: + + + + + + + + mutable streambuf_type* _M_sbuf; + mutable int_type _M_c; + + public: + + istreambuf_iterator() throw() + : _M_sbuf(0), _M_c(traits_type::eof()) { } +# 112 "/usr/include/c++/4.8.2/bits/streambuf_iterator.h" 3 + istreambuf_iterator(istream_type& __s) throw() + : _M_sbuf(__s.rdbuf()), _M_c(traits_type::eof()) { } + + + istreambuf_iterator(streambuf_type* __s) throw() + : _M_sbuf(__s), _M_c(traits_type::eof()) { } + + + + + char_type + operator*() const + { + + + + + + + + return traits_type::to_char_type(_M_get()); + } + + + istreambuf_iterator& + operator++() + { + + + ; + if (_M_sbuf) + { + _M_sbuf->sbumpc(); + _M_c = traits_type::eof(); + } + return *this; + } + + + istreambuf_iterator + operator++(int) + { + + + ; + + istreambuf_iterator __old = *this; + if (_M_sbuf) + { + __old._M_c = _M_sbuf->sbumpc(); + _M_c = traits_type::eof(); + } + return __old; + } + + + + + + bool + equal(const istreambuf_iterator& __b) const + { return _M_at_eof() == __b._M_at_eof(); } + + private: + int_type + _M_get() const + { + const int_type __eof = traits_type::eof(); + int_type __ret = __eof; + if (_M_sbuf) + { + if (!traits_type::eq_int_type(_M_c, __eof)) + __ret = _M_c; + else if (!traits_type::eq_int_type((__ret = _M_sbuf->sgetc()), + __eof)) + _M_c = __ret; + else + _M_sbuf = 0; + } + return __ret; + } + + bool + _M_at_eof() const + { + const int_type __eof = traits_type::eof(); + return traits_type::eq_int_type(_M_get(), __eof); + } + }; + + template + inline bool + operator==(const istreambuf_iterator<_CharT, _Traits>& __a, + const istreambuf_iterator<_CharT, _Traits>& __b) + { return __a.equal(__b); } + + template + inline bool + operator!=(const istreambuf_iterator<_CharT, _Traits>& __a, + const istreambuf_iterator<_CharT, _Traits>& __b) + { return !__a.equal(__b); } + + + template + class ostreambuf_iterator + : public iterator + { + public: + + + + typedef _CharT char_type; + typedef _Traits traits_type; + typedef basic_streambuf<_CharT, _Traits> streambuf_type; + typedef basic_ostream<_CharT, _Traits> ostream_type; + + + template + friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, + ostreambuf_iterator<_CharT2> >::__type + copy(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>, + ostreambuf_iterator<_CharT2>); + + private: + streambuf_type* _M_sbuf; + bool _M_failed; + + public: + + ostreambuf_iterator(ostream_type& __s) throw() + : _M_sbuf(__s.rdbuf()), _M_failed(!_M_sbuf) { } + + + ostreambuf_iterator(streambuf_type* __s) throw() + : _M_sbuf(__s), _M_failed(!_M_sbuf) { } + + + ostreambuf_iterator& + operator=(_CharT __c) + { + if (!_M_failed && + _Traits::eq_int_type(_M_sbuf->sputc(__c), _Traits::eof())) + _M_failed = true; + return *this; + } + + + ostreambuf_iterator& + operator*() + { return *this; } + + + ostreambuf_iterator& + operator++(int) + { return *this; } + + + ostreambuf_iterator& + operator++() + { return *this; } + + + bool + failed() const throw() + { return _M_failed; } + + ostreambuf_iterator& + _M_put(const _CharT* __ws, streamsize __len) + { + if (__builtin_expect(!_M_failed, true) + && __builtin_expect(this->_M_sbuf->sputn(__ws, __len) != __len, + false)) + _M_failed = true; + return *this; + } + }; + + + template + typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, + ostreambuf_iterator<_CharT> >::__type + copy(istreambuf_iterator<_CharT> __first, + istreambuf_iterator<_CharT> __last, + ostreambuf_iterator<_CharT> __result) + { + if (__first._M_sbuf && !__last._M_sbuf && !__result._M_failed) + { + bool __ineof; + __copy_streambufs_eof(__first._M_sbuf, __result._M_sbuf, __ineof); + if (!__ineof) + __result._M_failed = true; + } + return __result; + } + + template + typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, + ostreambuf_iterator<_CharT> >::__type + __copy_move_a2(_CharT* __first, _CharT* __last, + ostreambuf_iterator<_CharT> __result) + { + const streamsize __num = __last - __first; + if (__num > 0) + __result._M_put(__first, __num); + return __result; + } + + template + typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, + ostreambuf_iterator<_CharT> >::__type + __copy_move_a2(const _CharT* __first, const _CharT* __last, + ostreambuf_iterator<_CharT> __result) + { + const streamsize __num = __last - __first; + if (__num > 0) + __result._M_put(__first, __num); + return __result; + } + + template + typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, + _CharT*>::__type + __copy_move_a2(istreambuf_iterator<_CharT> __first, + istreambuf_iterator<_CharT> __last, _CharT* __result) + { + typedef istreambuf_iterator<_CharT> __is_iterator_type; + typedef typename __is_iterator_type::traits_type traits_type; + typedef typename __is_iterator_type::streambuf_type streambuf_type; + typedef typename traits_type::int_type int_type; + + if (__first._M_sbuf && !__last._M_sbuf) + { + streambuf_type* __sb = __first._M_sbuf; + int_type __c = __sb->sgetc(); + while (!traits_type::eq_int_type(__c, traits_type::eof())) + { + const streamsize __n = __sb->egptr() - __sb->gptr(); + if (__n > 1) + { + traits_type::copy(__result, __sb->gptr(), __n); + __sb->__safe_gbump(__n); + __result += __n; + __c = __sb->underflow(); + } + else + { + *__result++ = traits_type::to_char_type(__c); + __c = __sb->snextc(); + } + } + } + return __result; + } + + template + typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, + istreambuf_iterator<_CharT> >::__type + find(istreambuf_iterator<_CharT> __first, + istreambuf_iterator<_CharT> __last, const _CharT& __val) + { + typedef istreambuf_iterator<_CharT> __is_iterator_type; + typedef typename __is_iterator_type::traits_type traits_type; + typedef typename __is_iterator_type::streambuf_type streambuf_type; + typedef typename traits_type::int_type int_type; + + if (__first._M_sbuf && !__last._M_sbuf) + { + const int_type __ival = traits_type::to_int_type(__val); + streambuf_type* __sb = __first._M_sbuf; + int_type __c = __sb->sgetc(); + while (!traits_type::eq_int_type(__c, traits_type::eof()) + && !traits_type::eq_int_type(__c, __ival)) + { + streamsize __n = __sb->egptr() - __sb->gptr(); + if (__n > 1) + { + const _CharT* __p = traits_type::find(__sb->gptr(), + __n, __val); + if (__p) + __n = __p - __sb->gptr(); + __sb->__safe_gbump(__n); + __c = __sb->sgetc(); + } + else + __c = __sb->snextc(); + } + + if (!traits_type::eq_int_type(__c, traits_type::eof())) + __first._M_c = __c; + else + __first._M_sbuf = 0; + } + return __first; + } + + + + +} +# 49 "/usr/include/c++/4.8.2/bits/locale_facets.h" 2 3 + +namespace std __attribute__ ((__visibility__ ("default"))) +{ + +# 64 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + template + void + __convert_to_v(const char*, _Tp&, ios_base::iostate&, + const __c_locale&) throw(); + + + template<> + void + __convert_to_v(const char*, float&, ios_base::iostate&, + const __c_locale&) throw(); + + template<> + void + __convert_to_v(const char*, double&, ios_base::iostate&, + const __c_locale&) throw(); + + template<> + void + __convert_to_v(const char*, long double&, ios_base::iostate&, + const __c_locale&) throw(); + + + + template + struct __pad + { + static void + _S_pad(ios_base& __io, _CharT __fill, _CharT* __news, + const _CharT* __olds, streamsize __newlen, streamsize __oldlen); + }; + + + + + + + template + _CharT* + __add_grouping(_CharT* __s, _CharT __sep, + const char* __gbeg, size_t __gsize, + const _CharT* __first, const _CharT* __last); + + + + + template + inline + ostreambuf_iterator<_CharT> + __write(ostreambuf_iterator<_CharT> __s, const _CharT* __ws, int __len) + { + __s._M_put(__ws, __len); + return __s; + } + + + template + inline + _OutIter + __write(_OutIter __s, const _CharT* __ws, int __len) + { + for (int __j = 0; __j < __len; __j++, ++__s) + *__s = __ws[__j]; + return __s; + } +# 142 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + template + class __ctype_abstract_base : public locale::facet, public ctype_base + { + public: + + + typedef _CharT char_type; +# 161 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + bool + is(mask __m, char_type __c) const + { return this->do_is(__m, __c); } +# 178 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + const char_type* + is(const char_type *__lo, const char_type *__hi, mask *__vec) const + { return this->do_is(__lo, __hi, __vec); } +# 194 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + const char_type* + scan_is(mask __m, const char_type* __lo, const char_type* __hi) const + { return this->do_scan_is(__m, __lo, __hi); } +# 210 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + const char_type* + scan_not(mask __m, const char_type* __lo, const char_type* __hi) const + { return this->do_scan_not(__m, __lo, __hi); } +# 224 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + char_type + toupper(char_type __c) const + { return this->do_toupper(__c); } +# 239 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + const char_type* + toupper(char_type *__lo, const char_type* __hi) const + { return this->do_toupper(__lo, __hi); } +# 253 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + char_type + tolower(char_type __c) const + { return this->do_tolower(__c); } +# 268 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + const char_type* + tolower(char_type* __lo, const char_type* __hi) const + { return this->do_tolower(__lo, __hi); } +# 285 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + char_type + widen(char __c) const + { return this->do_widen(__c); } +# 304 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + const char* + widen(const char* __lo, const char* __hi, char_type* __to) const + { return this->do_widen(__lo, __hi, __to); } +# 323 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + char + narrow(char_type __c, char __dfault) const + { return this->do_narrow(__c, __dfault); } +# 345 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + const char_type* + narrow(const char_type* __lo, const char_type* __hi, + char __dfault, char* __to) const + { return this->do_narrow(__lo, __hi, __dfault, __to); } + + protected: + explicit + __ctype_abstract_base(size_t __refs = 0): facet(__refs) { } + + virtual + ~__ctype_abstract_base() { } +# 370 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + virtual bool + do_is(mask __m, char_type __c) const = 0; +# 389 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + virtual const char_type* + do_is(const char_type* __lo, const char_type* __hi, + mask* __vec) const = 0; +# 408 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + virtual const char_type* + do_scan_is(mask __m, const char_type* __lo, + const char_type* __hi) const = 0; +# 427 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + virtual const char_type* + do_scan_not(mask __m, const char_type* __lo, + const char_type* __hi) const = 0; +# 445 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + virtual char_type + do_toupper(char_type __c) const = 0; +# 462 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + virtual const char_type* + do_toupper(char_type* __lo, const char_type* __hi) const = 0; +# 478 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + virtual char_type + do_tolower(char_type __c) const = 0; +# 495 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + virtual const char_type* + do_tolower(char_type* __lo, const char_type* __hi) const = 0; +# 514 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + virtual char_type + do_widen(char __c) const = 0; +# 535 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + virtual const char* + do_widen(const char* __lo, const char* __hi, char_type* __to) const = 0; +# 556 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + virtual char + do_narrow(char_type __c, char __dfault) const = 0; +# 581 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + virtual const char_type* + do_narrow(const char_type* __lo, const char_type* __hi, + char __dfault, char* __to) const = 0; + }; +# 604 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + template + class ctype : public __ctype_abstract_base<_CharT> + { + public: + + typedef _CharT char_type; + typedef typename __ctype_abstract_base<_CharT>::mask mask; + + + static locale::id id; + + explicit + ctype(size_t __refs = 0) : __ctype_abstract_base<_CharT>(__refs) { } + + protected: + virtual + ~ctype(); + + virtual bool + do_is(mask __m, char_type __c) const; + + virtual const char_type* + do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const; + + virtual const char_type* + do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const; + + virtual const char_type* + do_scan_not(mask __m, const char_type* __lo, + const char_type* __hi) const; + + virtual char_type + do_toupper(char_type __c) const; + + virtual const char_type* + do_toupper(char_type* __lo, const char_type* __hi) const; + + virtual char_type + do_tolower(char_type __c) const; + + virtual const char_type* + do_tolower(char_type* __lo, const char_type* __hi) const; + + virtual char_type + do_widen(char __c) const; + + virtual const char* + do_widen(const char* __lo, const char* __hi, char_type* __dest) const; + + virtual char + do_narrow(char_type, char __dfault) const; + + virtual const char_type* + do_narrow(const char_type* __lo, const char_type* __hi, + char __dfault, char* __to) const; + }; + + template + locale::id ctype<_CharT>::id; +# 673 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + template<> + class ctype : public locale::facet, public ctype_base + { + public: + + + typedef char char_type; + + protected: + + __c_locale _M_c_locale_ctype; + bool _M_del; + __to_type _M_toupper; + __to_type _M_tolower; + const mask* _M_table; + mutable char _M_widen_ok; + mutable char _M_widen[1 + static_cast(-1)]; + mutable char _M_narrow[1 + static_cast(-1)]; + mutable char _M_narrow_ok; + + + public: + + static locale::id id; + + static const size_t table_size = 1 + static_cast(-1); +# 710 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + explicit + ctype(const mask* __table = 0, bool __del = false, size_t __refs = 0); +# 723 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + explicit + ctype(__c_locale __cloc, const mask* __table = 0, bool __del = false, + size_t __refs = 0); +# 736 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + inline bool + is(mask __m, char __c) const; +# 751 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + inline const char* + is(const char* __lo, const char* __hi, mask* __vec) const; +# 765 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + inline const char* + scan_is(mask __m, const char* __lo, const char* __hi) const; +# 779 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + inline const char* + scan_not(mask __m, const char* __lo, const char* __hi) const; +# 794 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + char_type + toupper(char_type __c) const + { return this->do_toupper(__c); } +# 811 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + const char_type* + toupper(char_type *__lo, const char_type* __hi) const + { return this->do_toupper(__lo, __hi); } +# 827 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + char_type + tolower(char_type __c) const + { return this->do_tolower(__c); } +# 844 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + const char_type* + tolower(char_type* __lo, const char_type* __hi) const + { return this->do_tolower(__lo, __hi); } +# 864 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + char_type + widen(char __c) const + { + if (_M_widen_ok) + return _M_widen[static_cast(__c)]; + this->_M_widen_init(); + return this->do_widen(__c); + } +# 891 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + const char* + widen(const char* __lo, const char* __hi, char_type* __to) const + { + if (_M_widen_ok == 1) + { + __builtin_memcpy(__to, __lo, __hi - __lo); + return __hi; + } + if (!_M_widen_ok) + _M_widen_init(); + return this->do_widen(__lo, __hi, __to); + } +# 922 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + char + narrow(char_type __c, char __dfault) const + { + if (_M_narrow[static_cast(__c)]) + return _M_narrow[static_cast(__c)]; + const char __t = do_narrow(__c, __dfault); + if (__t != __dfault) + _M_narrow[static_cast(__c)] = __t; + return __t; + } +# 955 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + const char_type* + narrow(const char_type* __lo, const char_type* __hi, + char __dfault, char* __to) const + { + if (__builtin_expect(_M_narrow_ok == 1, true)) + { + __builtin_memcpy(__to, __lo, __hi - __lo); + return __hi; + } + if (!_M_narrow_ok) + _M_narrow_init(); + return this->do_narrow(__lo, __hi, __dfault, __to); + } + + + + + + const mask* + table() const throw() + { return _M_table; } + + + static const mask* + classic_table() throw(); + protected: + + + + + + + + virtual + ~ctype(); +# 1004 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + virtual char_type + do_toupper(char_type __c) const; +# 1021 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + virtual const char_type* + do_toupper(char_type* __lo, const char_type* __hi) const; +# 1037 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + virtual char_type + do_tolower(char_type __c) const; +# 1054 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + virtual const char_type* + do_tolower(char_type* __lo, const char_type* __hi) const; +# 1074 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + virtual char_type + do_widen(char __c) const + { return __c; } +# 1097 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + virtual const char* + do_widen(const char* __lo, const char* __hi, char_type* __to) const + { + __builtin_memcpy(__to, __lo, __hi - __lo); + return __hi; + } +# 1123 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + virtual char + do_narrow(char_type __c, char __dfault) const + { return __c; } +# 1149 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + virtual const char_type* + do_narrow(const char_type* __lo, const char_type* __hi, + char __dfault, char* __to) const + { + __builtin_memcpy(__to, __lo, __hi - __lo); + return __hi; + } + + private: + void _M_narrow_init() const; + void _M_widen_init() const; + }; +# 1174 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + template<> + class ctype : public __ctype_abstract_base + { + public: + + + typedef wchar_t char_type; + typedef wctype_t __wmask_type; + + protected: + __c_locale _M_c_locale_ctype; + + + bool _M_narrow_ok; + char _M_narrow[128]; + wint_t _M_widen[1 + static_cast(-1)]; + + + mask _M_bit[16]; + __wmask_type _M_wmask[16]; + + public: + + + static locale::id id; +# 1207 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + explicit + ctype(size_t __refs = 0); +# 1218 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + explicit + ctype(__c_locale __cloc, size_t __refs = 0); + + protected: + __wmask_type + _M_convert_to_wmask(const mask __m) const throw(); + + + virtual + ~ctype(); +# 1242 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + virtual bool + do_is(mask __m, char_type __c) const; +# 1261 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + virtual const char_type* + do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const; +# 1279 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + virtual const char_type* + do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const; +# 1297 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + virtual const char_type* + do_scan_not(mask __m, const char_type* __lo, + const char_type* __hi) const; +# 1314 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + virtual char_type + do_toupper(char_type __c) const; +# 1331 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + virtual const char_type* + do_toupper(char_type* __lo, const char_type* __hi) const; +# 1347 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + virtual char_type + do_tolower(char_type __c) const; +# 1364 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + virtual const char_type* + do_tolower(char_type* __lo, const char_type* __hi) const; +# 1384 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + virtual char_type + do_widen(char __c) const; +# 1406 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + virtual const char* + do_widen(const char* __lo, const char* __hi, char_type* __to) const; +# 1429 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + virtual char + do_narrow(char_type __c, char __dfault) const; +# 1455 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + virtual const char_type* + do_narrow(const char_type* __lo, const char_type* __hi, + char __dfault, char* __to) const; + + + void + _M_initialize_ctype() throw(); + }; + + + + template + class ctype_byname : public ctype<_CharT> + { + public: + typedef typename ctype<_CharT>::mask mask; + + explicit + ctype_byname(const char* __s, size_t __refs = 0); + + protected: + virtual + ~ctype_byname() { }; + }; + + + template<> + class ctype_byname : public ctype + { + public: + explicit + ctype_byname(const char* __s, size_t __refs = 0); + + protected: + virtual + ~ctype_byname(); + }; + + + template<> + class ctype_byname : public ctype + { + public: + explicit + ctype_byname(const char* __s, size_t __refs = 0); + + protected: + virtual + ~ctype_byname(); + }; + + + +} + + +# 1 "/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/ctype_inline.h" 1 3 +# 37 "/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/ctype_inline.h" 3 +namespace std __attribute__ ((__visibility__ ("default"))) +{ + + + bool + ctype:: + is(mask __m, char __c) const + { return _M_table[static_cast(__c)] & __m; } + + const char* + ctype:: + is(const char* __low, const char* __high, mask* __vec) const + { + while (__low < __high) + *__vec++ = _M_table[static_cast(*__low++)]; + return __high; + } + + const char* + ctype:: + scan_is(mask __m, const char* __low, const char* __high) const + { + while (__low < __high + && !(_M_table[static_cast(*__low)] & __m)) + ++__low; + return __low; + } + + const char* + ctype:: + scan_not(mask __m, const char* __low, const char* __high) const + { + while (__low < __high + && (_M_table[static_cast(*__low)] & __m) != 0) + ++__low; + return __low; + } + + +} +# 1512 "/usr/include/c++/4.8.2/bits/locale_facets.h" 2 3 + +namespace std __attribute__ ((__visibility__ ("default"))) +{ + + + + class __num_base + { + public: + + + enum + { + _S_ominus, + _S_oplus, + _S_ox, + _S_oX, + _S_odigits, + _S_odigits_end = _S_odigits + 16, + _S_oudigits = _S_odigits_end, + _S_oudigits_end = _S_oudigits + 16, + _S_oe = _S_odigits + 14, + _S_oE = _S_oudigits + 14, + _S_oend = _S_oudigits_end + }; + + + + + + + static const char* _S_atoms_out; + + + + static const char* _S_atoms_in; + + enum + { + _S_iminus, + _S_iplus, + _S_ix, + _S_iX, + _S_izero, + _S_ie = _S_izero + 14, + _S_iE = _S_izero + 20, + _S_iend = 26 + }; + + + + static void + _S_format_float(const ios_base& __io, char* __fptr, char __mod) throw(); + }; + + template + struct __numpunct_cache : public locale::facet + { + const char* _M_grouping; + size_t _M_grouping_size; + bool _M_use_grouping; + const _CharT* _M_truename; + size_t _M_truename_size; + const _CharT* _M_falsename; + size_t _M_falsename_size; + _CharT _M_decimal_point; + _CharT _M_thousands_sep; + + + + + + _CharT _M_atoms_out[__num_base::_S_oend]; + + + + + + _CharT _M_atoms_in[__num_base::_S_iend]; + + bool _M_allocated; + + __numpunct_cache(size_t __refs = 0) + : facet(__refs), _M_grouping(0), _M_grouping_size(0), + _M_use_grouping(false), + _M_truename(0), _M_truename_size(0), _M_falsename(0), + _M_falsename_size(0), _M_decimal_point(_CharT()), + _M_thousands_sep(_CharT()), _M_allocated(false) + { } + + ~__numpunct_cache(); + + void + _M_cache(const locale& __loc); + + private: + __numpunct_cache& + operator=(const __numpunct_cache&); + + explicit + __numpunct_cache(const __numpunct_cache&); + }; + + template + __numpunct_cache<_CharT>::~__numpunct_cache() + { + if (_M_allocated) + { + delete [] _M_grouping; + delete [] _M_truename; + delete [] _M_falsename; + } + } +# 1640 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + template + class numpunct : public locale::facet + { + public: + + + + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + + typedef __numpunct_cache<_CharT> __cache_type; + + protected: + __cache_type* _M_data; + + public: + + static locale::id id; + + + + + + + explicit + numpunct(size_t __refs = 0) + : facet(__refs), _M_data(0) + { _M_initialize_numpunct(); } +# 1678 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + explicit + numpunct(__cache_type* __cache, size_t __refs = 0) + : facet(__refs), _M_data(__cache) + { _M_initialize_numpunct(); } +# 1692 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + explicit + numpunct(__c_locale __cloc, size_t __refs = 0) + : facet(__refs), _M_data(0) + { _M_initialize_numpunct(__cloc); } +# 1706 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + char_type + decimal_point() const + { return this->do_decimal_point(); } +# 1719 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + char_type + thousands_sep() const + { return this->do_thousands_sep(); } +# 1750 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + string + grouping() const + { return this->do_grouping(); } +# 1763 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + string_type + truename() const + { return this->do_truename(); } +# 1776 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + string_type + falsename() const + { return this->do_falsename(); } + + protected: + + virtual + ~numpunct(); +# 1793 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + virtual char_type + do_decimal_point() const + { return _M_data->_M_decimal_point; } +# 1805 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + virtual char_type + do_thousands_sep() const + { return _M_data->_M_thousands_sep; } +# 1818 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + virtual string + do_grouping() const + { return _M_data->_M_grouping; } +# 1831 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + virtual string_type + do_truename() const + { return _M_data->_M_truename; } +# 1844 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + virtual string_type + do_falsename() const + { return _M_data->_M_falsename; } + + + void + _M_initialize_numpunct(__c_locale __cloc = 0); + }; + + template + locale::id numpunct<_CharT>::id; + + template<> + numpunct::~numpunct(); + + template<> + void + numpunct::_M_initialize_numpunct(__c_locale __cloc); + + + template<> + numpunct::~numpunct(); + + template<> + void + numpunct::_M_initialize_numpunct(__c_locale __cloc); + + + + template + class numpunct_byname : public numpunct<_CharT> + { + public: + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + + explicit + numpunct_byname(const char* __s, size_t __refs = 0) + : numpunct<_CharT>(__refs) + { + if (__builtin_strcmp(__s, "C") != 0 + && __builtin_strcmp(__s, "POSIX") != 0) + { + __c_locale __tmp; + this->_S_create_c_locale(__tmp, __s); + this->_M_initialize_numpunct(__tmp); + this->_S_destroy_c_locale(__tmp); + } + } + + protected: + virtual + ~numpunct_byname() { } + }; + + +# 1914 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + template + class num_get : public locale::facet + { + public: + + + + typedef _CharT char_type; + typedef _InIter iter_type; + + + + static locale::id id; +# 1935 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + explicit + num_get(size_t __refs = 0) : facet(__refs) { } +# 1961 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, bool& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } +# 1998 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, long& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } + + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned short& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } + + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned int& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } + + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned long& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } + + + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, long long& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } + + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned long long& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } +# 2058 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, float& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } + + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, double& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } + + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, long double& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } +# 2101 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, void*& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } + + protected: + + virtual ~num_get() { } + + iter_type + _M_extract_float(iter_type, iter_type, ios_base&, ios_base::iostate&, + string&) const; + + template + iter_type + _M_extract_int(iter_type, iter_type, ios_base&, ios_base::iostate&, + _ValueT&) const; + + template + typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, int>::__type + _M_find(const _CharT2*, size_t __len, _CharT2 __c) const + { + int __ret = -1; + if (__len <= 10) + { + if (__c >= _CharT2('0') && __c < _CharT2(_CharT2('0') + __len)) + __ret = __c - _CharT2('0'); + } + else + { + if (__c >= _CharT2('0') && __c <= _CharT2('9')) + __ret = __c - _CharT2('0'); + else if (__c >= _CharT2('a') && __c <= _CharT2('f')) + __ret = 10 + (__c - _CharT2('a')); + else if (__c >= _CharT2('A') && __c <= _CharT2('F')) + __ret = 10 + (__c - _CharT2('A')); + } + return __ret; + } + + template + typename __gnu_cxx::__enable_if::__value, + int>::__type + _M_find(const _CharT2* __zero, size_t __len, _CharT2 __c) const + { + int __ret = -1; + const char_type* __q = char_traits<_CharT2>::find(__zero, __len, __c); + if (__q) + { + __ret = __q - __zero; + if (__ret > 15) + __ret -= 6; + } + return __ret; + } +# 2172 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const; + + virtual iter_type + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, long& __v) const + { return _M_extract_int(__beg, __end, __io, __err, __v); } + + virtual iter_type + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned short& __v) const + { return _M_extract_int(__beg, __end, __io, __err, __v); } + + virtual iter_type + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned int& __v) const + { return _M_extract_int(__beg, __end, __io, __err, __v); } + + virtual iter_type + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned long& __v) const + { return _M_extract_int(__beg, __end, __io, __err, __v); } + + + virtual iter_type + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, long long& __v) const + { return _M_extract_int(__beg, __end, __io, __err, __v); } + + virtual iter_type + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned long long& __v) const + { return _M_extract_int(__beg, __end, __io, __err, __v); } + + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, float&) const; + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, + double&) const; + + + + + + + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, + long double&) const; + + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, void*&) const; +# 2235 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + }; + + template + locale::id num_get<_CharT, _InIter>::id; +# 2253 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + template + class num_put : public locale::facet + { + public: + + + + typedef _CharT char_type; + typedef _OutIter iter_type; + + + + static locale::id id; +# 2274 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + explicit + num_put(size_t __refs = 0) : facet(__refs) { } +# 2292 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + iter_type + put(iter_type __s, ios_base& __io, char_type __fill, bool __v) const + { return this->do_put(__s, __io, __fill, __v); } +# 2334 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + iter_type + put(iter_type __s, ios_base& __io, char_type __fill, long __v) const + { return this->do_put(__s, __io, __fill, __v); } + + iter_type + put(iter_type __s, ios_base& __io, char_type __fill, + unsigned long __v) const + { return this->do_put(__s, __io, __fill, __v); } + + + iter_type + put(iter_type __s, ios_base& __io, char_type __fill, long long __v) const + { return this->do_put(__s, __io, __fill, __v); } + + iter_type + put(iter_type __s, ios_base& __io, char_type __fill, + unsigned long long __v) const + { return this->do_put(__s, __io, __fill, __v); } +# 2397 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + iter_type + put(iter_type __s, ios_base& __io, char_type __fill, double __v) const + { return this->do_put(__s, __io, __fill, __v); } + + iter_type + put(iter_type __s, ios_base& __io, char_type __fill, + long double __v) const + { return this->do_put(__s, __io, __fill, __v); } +# 2422 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + iter_type + put(iter_type __s, ios_base& __io, char_type __fill, + const void* __v) const + { return this->do_put(__s, __io, __fill, __v); } + + protected: + template + iter_type + _M_insert_float(iter_type, ios_base& __io, char_type __fill, + char __mod, _ValueT __v) const; + + void + _M_group_float(const char* __grouping, size_t __grouping_size, + char_type __sep, const char_type* __p, char_type* __new, + char_type* __cs, int& __len) const; + + template + iter_type + _M_insert_int(iter_type, ios_base& __io, char_type __fill, + _ValueT __v) const; + + void + _M_group_int(const char* __grouping, size_t __grouping_size, + char_type __sep, ios_base& __io, char_type* __new, + char_type* __cs, int& __len) const; + + void + _M_pad(char_type __fill, streamsize __w, ios_base& __io, + char_type* __new, const char_type* __cs, int& __len) const; + + + virtual + ~num_put() { }; +# 2470 "/usr/include/c++/4.8.2/bits/locale_facets.h" 3 + virtual iter_type + do_put(iter_type __s, ios_base& __io, char_type __fill, bool __v) const; + + virtual iter_type + do_put(iter_type __s, ios_base& __io, char_type __fill, long __v) const + { return _M_insert_int(__s, __io, __fill, __v); } + + virtual iter_type + do_put(iter_type __s, ios_base& __io, char_type __fill, + unsigned long __v) const + { return _M_insert_int(__s, __io, __fill, __v); } + + + virtual iter_type + do_put(iter_type __s, ios_base& __io, char_type __fill, + long long __v) const + { return _M_insert_int(__s, __io, __fill, __v); } + + virtual iter_type + do_put(iter_type __s, ios_base& __io, char_type __fill, + unsigned long long __v) const + { return _M_insert_int(__s, __io, __fill, __v); } + + + virtual iter_type + do_put(iter_type, ios_base&, char_type, double) const; + + + + + + + virtual iter_type + do_put(iter_type, ios_base&, char_type, long double) const; + + + virtual iter_type + do_put(iter_type, ios_base&, char_type, const void*) const; + + + + + + + + }; + + template + locale::id num_put<_CharT, _OutIter>::id; + + + + + + + + + + template + inline bool + isspace(_CharT __c, const locale& __loc) + { return use_facet >(__loc).is(ctype_base::space, __c); } + + + template + inline bool + isprint(_CharT __c, const locale& __loc) + { return use_facet >(__loc).is(ctype_base::print, __c); } + + + template + inline bool + iscntrl(_CharT __c, const locale& __loc) + { return use_facet >(__loc).is(ctype_base::cntrl, __c); } + + + template + inline bool + isupper(_CharT __c, const locale& __loc) + { return use_facet >(__loc).is(ctype_base::upper, __c); } + + + template + inline bool + islower(_CharT __c, const locale& __loc) + { return use_facet >(__loc).is(ctype_base::lower, __c); } + + + template + inline bool + isalpha(_CharT __c, const locale& __loc) + { return use_facet >(__loc).is(ctype_base::alpha, __c); } + + + template + inline bool + isdigit(_CharT __c, const locale& __loc) + { return use_facet >(__loc).is(ctype_base::digit, __c); } + + + template + inline bool + ispunct(_CharT __c, const locale& __loc) + { return use_facet >(__loc).is(ctype_base::punct, __c); } + + + template + inline bool + isxdigit(_CharT __c, const locale& __loc) + { return use_facet >(__loc).is(ctype_base::xdigit, __c); } + + + template + inline bool + isalnum(_CharT __c, const locale& __loc) + { return use_facet >(__loc).is(ctype_base::alnum, __c); } + + + template + inline bool + isgraph(_CharT __c, const locale& __loc) + { return use_facet >(__loc).is(ctype_base::graph, __c); } + + + template + inline _CharT + toupper(_CharT __c, const locale& __loc) + { return use_facet >(__loc).toupper(__c); } + + + template + inline _CharT + tolower(_CharT __c, const locale& __loc) + { return use_facet >(__loc).tolower(__c); } + + +} + +# 1 "/usr/include/c++/4.8.2/bits/locale_facets.tcc" 1 3 +# 33 "/usr/include/c++/4.8.2/bits/locale_facets.tcc" 3 + +# 34 "/usr/include/c++/4.8.2/bits/locale_facets.tcc" 3 + +namespace std __attribute__ ((__visibility__ ("default"))) +{ + + + + + template + struct __use_cache + { + const _Facet* + operator() (const locale& __loc) const; + }; + + + template + struct __use_cache<__numpunct_cache<_CharT> > + { + const __numpunct_cache<_CharT>* + operator() (const locale& __loc) const + { + const size_t __i = numpunct<_CharT>::id._M_id(); + const locale::facet** __caches = __loc._M_impl->_M_caches; + if (!__caches[__i]) + { + __numpunct_cache<_CharT>* __tmp = 0; + try + { + __tmp = new __numpunct_cache<_CharT>; + __tmp->_M_cache(__loc); + } + catch(...) + { + delete __tmp; + throw; + } + __loc._M_impl->_M_install_cache(__tmp, __i); + } + return static_cast*>(__caches[__i]); + } + }; + + template + void + __numpunct_cache<_CharT>::_M_cache(const locale& __loc) + { + _M_allocated = true; + + const numpunct<_CharT>& __np = use_facet >(__loc); + + char* __grouping = 0; + _CharT* __truename = 0; + _CharT* __falsename = 0; + try + { + _M_grouping_size = __np.grouping().size(); + __grouping = new char[_M_grouping_size]; + __np.grouping().copy(__grouping, _M_grouping_size); + _M_grouping = __grouping; + _M_use_grouping = (_M_grouping_size + && static_cast(_M_grouping[0]) > 0 + && (_M_grouping[0] + != __gnu_cxx::__numeric_traits::__max)); + + _M_truename_size = __np.truename().size(); + __truename = new _CharT[_M_truename_size]; + __np.truename().copy(__truename, _M_truename_size); + _M_truename = __truename; + + _M_falsename_size = __np.falsename().size(); + __falsename = new _CharT[_M_falsename_size]; + __np.falsename().copy(__falsename, _M_falsename_size); + _M_falsename = __falsename; + + _M_decimal_point = __np.decimal_point(); + _M_thousands_sep = __np.thousands_sep(); + + const ctype<_CharT>& __ct = use_facet >(__loc); + __ct.widen(__num_base::_S_atoms_out, + __num_base::_S_atoms_out + + __num_base::_S_oend, _M_atoms_out); + __ct.widen(__num_base::_S_atoms_in, + __num_base::_S_atoms_in + + __num_base::_S_iend, _M_atoms_in); + } + catch(...) + { + delete [] __grouping; + delete [] __truename; + delete [] __falsename; + throw; + } + } +# 136 "/usr/include/c++/4.8.2/bits/locale_facets.tcc" 3 + __attribute__ ((__pure__)) bool + __verify_grouping(const char* __grouping, size_t __grouping_size, + const string& __grouping_tmp) throw (); + + + + template + _InIter + num_get<_CharT, _InIter>:: + _M_extract_float(_InIter __beg, _InIter __end, ios_base& __io, + ios_base::iostate& __err, string& __xtrc) const + { + typedef char_traits<_CharT> __traits_type; + typedef __numpunct_cache<_CharT> __cache_type; + __use_cache<__cache_type> __uc; + const locale& __loc = __io._M_getloc(); + const __cache_type* __lc = __uc(__loc); + const _CharT* __lit = __lc->_M_atoms_in; + char_type __c = char_type(); + + + bool __testeof = __beg == __end; + + + if (!__testeof) + { + __c = *__beg; + const bool __plus = __c == __lit[__num_base::_S_iplus]; + if ((__plus || __c == __lit[__num_base::_S_iminus]) + && !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) + && !(__c == __lc->_M_decimal_point)) + { + __xtrc += __plus ? '+' : '-'; + if (++__beg != __end) + __c = *__beg; + else + __testeof = true; + } + } + + + bool __found_mantissa = false; + int __sep_pos = 0; + while (!__testeof) + { + if ((__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) + || __c == __lc->_M_decimal_point) + break; + else if (__c == __lit[__num_base::_S_izero]) + { + if (!__found_mantissa) + { + __xtrc += '0'; + __found_mantissa = true; + } + ++__sep_pos; + + if (++__beg != __end) + __c = *__beg; + else + __testeof = true; + } + else + break; + } + + + bool __found_dec = false; + bool __found_sci = false; + string __found_grouping; + if (__lc->_M_use_grouping) + __found_grouping.reserve(32); + const char_type* __lit_zero = __lit + __num_base::_S_izero; + + if (!__lc->_M_allocated) + + while (!__testeof) + { + const int __digit = _M_find(__lit_zero, 10, __c); + if (__digit != -1) + { + __xtrc += '0' + __digit; + __found_mantissa = true; + } + else if (__c == __lc->_M_decimal_point + && !__found_dec && !__found_sci) + { + __xtrc += '.'; + __found_dec = true; + } + else if ((__c == __lit[__num_base::_S_ie] + || __c == __lit[__num_base::_S_iE]) + && !__found_sci && __found_mantissa) + { + + __xtrc += 'e'; + __found_sci = true; + + + if (++__beg != __end) + { + __c = *__beg; + const bool __plus = __c == __lit[__num_base::_S_iplus]; + if (__plus || __c == __lit[__num_base::_S_iminus]) + __xtrc += __plus ? '+' : '-'; + else + continue; + } + else + { + __testeof = true; + break; + } + } + else + break; + + if (++__beg != __end) + __c = *__beg; + else + __testeof = true; + } + else + while (!__testeof) + { + + + if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) + { + if (!__found_dec && !__found_sci) + { + + + if (__sep_pos) + { + __found_grouping += static_cast(__sep_pos); + __sep_pos = 0; + } + else + { + + + __xtrc.clear(); + break; + } + } + else + break; + } + else if (__c == __lc->_M_decimal_point) + { + if (!__found_dec && !__found_sci) + { + + + + if (__found_grouping.size()) + __found_grouping += static_cast(__sep_pos); + __xtrc += '.'; + __found_dec = true; + } + else + break; + } + else + { + const char_type* __q = + __traits_type::find(__lit_zero, 10, __c); + if (__q) + { + __xtrc += '0' + (__q - __lit_zero); + __found_mantissa = true; + ++__sep_pos; + } + else if ((__c == __lit[__num_base::_S_ie] + || __c == __lit[__num_base::_S_iE]) + && !__found_sci && __found_mantissa) + { + + if (__found_grouping.size() && !__found_dec) + __found_grouping += static_cast(__sep_pos); + __xtrc += 'e'; + __found_sci = true; + + + if (++__beg != __end) + { + __c = *__beg; + const bool __plus = __c == __lit[__num_base::_S_iplus]; + if ((__plus || __c == __lit[__num_base::_S_iminus]) + && !(__lc->_M_use_grouping + && __c == __lc->_M_thousands_sep) + && !(__c == __lc->_M_decimal_point)) + __xtrc += __plus ? '+' : '-'; + else + continue; + } + else + { + __testeof = true; + break; + } + } + else + break; + } + + if (++__beg != __end) + __c = *__beg; + else + __testeof = true; + } + + + + if (__found_grouping.size()) + { + + if (!__found_dec && !__found_sci) + __found_grouping += static_cast(__sep_pos); + + if (!std::__verify_grouping(__lc->_M_grouping, + __lc->_M_grouping_size, + __found_grouping)) + __err = ios_base::failbit; + } + + return __beg; + } + + template + template + _InIter + num_get<_CharT, _InIter>:: + _M_extract_int(_InIter __beg, _InIter __end, ios_base& __io, + ios_base::iostate& __err, _ValueT& __v) const + { + typedef char_traits<_CharT> __traits_type; + using __gnu_cxx::__add_unsigned; + typedef typename __add_unsigned<_ValueT>::__type __unsigned_type; + typedef __numpunct_cache<_CharT> __cache_type; + __use_cache<__cache_type> __uc; + const locale& __loc = __io._M_getloc(); + const __cache_type* __lc = __uc(__loc); + const _CharT* __lit = __lc->_M_atoms_in; + char_type __c = char_type(); + + + const ios_base::fmtflags __basefield = __io.flags() + & ios_base::basefield; + const bool __oct = __basefield == ios_base::oct; + int __base = __oct ? 8 : (__basefield == ios_base::hex ? 16 : 10); + + + bool __testeof = __beg == __end; + + + bool __negative = false; + if (!__testeof) + { + __c = *__beg; + __negative = __c == __lit[__num_base::_S_iminus]; + if ((__negative || __c == __lit[__num_base::_S_iplus]) + && !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) + && !(__c == __lc->_M_decimal_point)) + { + if (++__beg != __end) + __c = *__beg; + else + __testeof = true; + } + } + + + + bool __found_zero = false; + int __sep_pos = 0; + while (!__testeof) + { + if ((__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) + || __c == __lc->_M_decimal_point) + break; + else if (__c == __lit[__num_base::_S_izero] + && (!__found_zero || __base == 10)) + { + __found_zero = true; + ++__sep_pos; + if (__basefield == 0) + __base = 8; + if (__base == 8) + __sep_pos = 0; + } + else if (__found_zero + && (__c == __lit[__num_base::_S_ix] + || __c == __lit[__num_base::_S_iX])) + { + if (__basefield == 0) + __base = 16; + if (__base == 16) + { + __found_zero = false; + __sep_pos = 0; + } + else + break; + } + else + break; + + if (++__beg != __end) + { + __c = *__beg; + if (!__found_zero) + break; + } + else + __testeof = true; + } + + + + const size_t __len = (__base == 16 ? __num_base::_S_iend + - __num_base::_S_izero : __base); + + + string __found_grouping; + if (__lc->_M_use_grouping) + __found_grouping.reserve(32); + bool __testfail = false; + bool __testoverflow = false; + const __unsigned_type __max = + (__negative && __gnu_cxx::__numeric_traits<_ValueT>::__is_signed) + ? -__gnu_cxx::__numeric_traits<_ValueT>::__min + : __gnu_cxx::__numeric_traits<_ValueT>::__max; + const __unsigned_type __smax = __max / __base; + __unsigned_type __result = 0; + int __digit = 0; + const char_type* __lit_zero = __lit + __num_base::_S_izero; + + if (!__lc->_M_allocated) + + while (!__testeof) + { + __digit = _M_find(__lit_zero, __len, __c); + if (__digit == -1) + break; + + if (__result > __smax) + __testoverflow = true; + else + { + __result *= __base; + __testoverflow |= __result > __max - __digit; + __result += __digit; + ++__sep_pos; + } + + if (++__beg != __end) + __c = *__beg; + else + __testeof = true; + } + else + while (!__testeof) + { + + + if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) + { + + + if (__sep_pos) + { + __found_grouping += static_cast(__sep_pos); + __sep_pos = 0; + } + else + { + __testfail = true; + break; + } + } + else if (__c == __lc->_M_decimal_point) + break; + else + { + const char_type* __q = + __traits_type::find(__lit_zero, __len, __c); + if (!__q) + break; + + __digit = __q - __lit_zero; + if (__digit > 15) + __digit -= 6; + if (__result > __smax) + __testoverflow = true; + else + { + __result *= __base; + __testoverflow |= __result > __max - __digit; + __result += __digit; + ++__sep_pos; + } + } + + if (++__beg != __end) + __c = *__beg; + else + __testeof = true; + } + + + + if (__found_grouping.size()) + { + + __found_grouping += static_cast(__sep_pos); + + if (!std::__verify_grouping(__lc->_M_grouping, + __lc->_M_grouping_size, + __found_grouping)) + __err = ios_base::failbit; + } + + + + if ((!__sep_pos && !__found_zero && !__found_grouping.size()) + || __testfail) + { + __v = 0; + __err = ios_base::failbit; + } + else if (__testoverflow) + { + if (__negative + && __gnu_cxx::__numeric_traits<_ValueT>::__is_signed) + __v = __gnu_cxx::__numeric_traits<_ValueT>::__min; + else + __v = __gnu_cxx::__numeric_traits<_ValueT>::__max; + __err = ios_base::failbit; + } + else + __v = __negative ? -__result : __result; + + if (__testeof) + __err |= ios_base::eofbit; + return __beg; + } + + + + template + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, bool& __v) const + { + if (!(__io.flags() & ios_base::boolalpha)) + { + + + + long __l = -1; + __beg = _M_extract_int(__beg, __end, __io, __err, __l); + if (__l == 0 || __l == 1) + __v = bool(__l); + else + { + + + __v = true; + __err = ios_base::failbit; + if (__beg == __end) + __err |= ios_base::eofbit; + } + } + else + { + + typedef __numpunct_cache<_CharT> __cache_type; + __use_cache<__cache_type> __uc; + const locale& __loc = __io._M_getloc(); + const __cache_type* __lc = __uc(__loc); + + bool __testf = true; + bool __testt = true; + bool __donef = __lc->_M_falsename_size == 0; + bool __donet = __lc->_M_truename_size == 0; + bool __testeof = false; + size_t __n = 0; + while (!__donef || !__donet) + { + if (__beg == __end) + { + __testeof = true; + break; + } + + const char_type __c = *__beg; + + if (!__donef) + __testf = __c == __lc->_M_falsename[__n]; + + if (!__testf && __donet) + break; + + if (!__donet) + __testt = __c == __lc->_M_truename[__n]; + + if (!__testt && __donef) + break; + + if (!__testt && !__testf) + break; + + ++__n; + ++__beg; + + __donef = !__testf || __n >= __lc->_M_falsename_size; + __donet = !__testt || __n >= __lc->_M_truename_size; + } + if (__testf && __n == __lc->_M_falsename_size && __n) + { + __v = false; + if (__testt && __n == __lc->_M_truename_size) + __err = ios_base::failbit; + else + __err = __testeof ? ios_base::eofbit : ios_base::goodbit; + } + else if (__testt && __n == __lc->_M_truename_size && __n) + { + __v = true; + __err = __testeof ? ios_base::eofbit : ios_base::goodbit; + } + else + { + + + __v = false; + __err = ios_base::failbit; + if (__testeof) + __err |= ios_base::eofbit; + } + } + return __beg; + } + + template + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, float& __v) const + { + string __xtrc; + __xtrc.reserve(32); + __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc); + std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale()); + if (__beg == __end) + __err |= ios_base::eofbit; + return __beg; + } + + template + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, double& __v) const + { + string __xtrc; + __xtrc.reserve(32); + __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc); + std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale()); + if (__beg == __end) + __err |= ios_base::eofbit; + return __beg; + } +# 730 "/usr/include/c++/4.8.2/bits/locale_facets.tcc" 3 + template + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, long double& __v) const + { + string __xtrc; + __xtrc.reserve(32); + __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc); + std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale()); + if (__beg == __end) + __err |= ios_base::eofbit; + return __beg; + } + + template + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, void*& __v) const + { + + typedef ios_base::fmtflags fmtflags; + const fmtflags __fmt = __io.flags(); + __io.flags((__fmt & ~ios_base::basefield) | ios_base::hex); + + typedef __gnu_cxx::__conditional_type<(sizeof(void*) + <= sizeof(unsigned long)), + unsigned long, unsigned long long>::__type _UIntPtrType; + + _UIntPtrType __ul; + __beg = _M_extract_int(__beg, __end, __io, __err, __ul); + + + __io.flags(__fmt); + + __v = reinterpret_cast(__ul); + return __beg; + } + + + + template + void + num_put<_CharT, _OutIter>:: + _M_pad(_CharT __fill, streamsize __w, ios_base& __io, + _CharT* __new, const _CharT* __cs, int& __len) const + { + + + __pad<_CharT, char_traits<_CharT> >::_S_pad(__io, __fill, __new, + __cs, __w, __len); + __len = static_cast(__w); + } + + + + template + int + __int_to_char(_CharT* __bufend, _ValueT __v, const _CharT* __lit, + ios_base::fmtflags __flags, bool __dec) + { + _CharT* __buf = __bufend; + if (__builtin_expect(__dec, true)) + { + + do + { + *--__buf = __lit[(__v % 10) + __num_base::_S_odigits]; + __v /= 10; + } + while (__v != 0); + } + else if ((__flags & ios_base::basefield) == ios_base::oct) + { + + do + { + *--__buf = __lit[(__v & 0x7) + __num_base::_S_odigits]; + __v >>= 3; + } + while (__v != 0); + } + else + { + + const bool __uppercase = __flags & ios_base::uppercase; + const int __case_offset = __uppercase ? __num_base::_S_oudigits + : __num_base::_S_odigits; + do + { + *--__buf = __lit[(__v & 0xf) + __case_offset]; + __v >>= 4; + } + while (__v != 0); + } + return __bufend - __buf; + } + + + + template + void + num_put<_CharT, _OutIter>:: + _M_group_int(const char* __grouping, size_t __grouping_size, _CharT __sep, + ios_base&, _CharT* __new, _CharT* __cs, int& __len) const + { + _CharT* __p = std::__add_grouping(__new, __sep, __grouping, + __grouping_size, __cs, __cs + __len); + __len = __p - __new; + } + + template + template + _OutIter + num_put<_CharT, _OutIter>:: + _M_insert_int(_OutIter __s, ios_base& __io, _CharT __fill, + _ValueT __v) const + { + using __gnu_cxx::__add_unsigned; + typedef typename __add_unsigned<_ValueT>::__type __unsigned_type; + typedef __numpunct_cache<_CharT> __cache_type; + __use_cache<__cache_type> __uc; + const locale& __loc = __io._M_getloc(); + const __cache_type* __lc = __uc(__loc); + const _CharT* __lit = __lc->_M_atoms_out; + const ios_base::fmtflags __flags = __io.flags(); + + + const int __ilen = 5 * sizeof(_ValueT); + _CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __ilen)); + + + + const ios_base::fmtflags __basefield = __flags & ios_base::basefield; + const bool __dec = (__basefield != ios_base::oct + && __basefield != ios_base::hex); + const __unsigned_type __u = ((__v > 0 || !__dec) + ? __unsigned_type(__v) + : -__unsigned_type(__v)); + int __len = __int_to_char(__cs + __ilen, __u, __lit, __flags, __dec); + __cs += __ilen - __len; + + + if (__lc->_M_use_grouping) + { + + + _CharT* __cs2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * (__len + 1) + * 2)); + _M_group_int(__lc->_M_grouping, __lc->_M_grouping_size, + __lc->_M_thousands_sep, __io, __cs2 + 2, __cs, __len); + __cs = __cs2 + 2; + } + + + if (__builtin_expect(__dec, true)) + { + + if (__v >= 0) + { + if (bool(__flags & ios_base::showpos) + && __gnu_cxx::__numeric_traits<_ValueT>::__is_signed) + *--__cs = __lit[__num_base::_S_oplus], ++__len; + } + else + *--__cs = __lit[__num_base::_S_ominus], ++__len; + } + else if (bool(__flags & ios_base::showbase) && __v) + { + if (__basefield == ios_base::oct) + *--__cs = __lit[__num_base::_S_odigits], ++__len; + else + { + + const bool __uppercase = __flags & ios_base::uppercase; + *--__cs = __lit[__num_base::_S_ox + __uppercase]; + + *--__cs = __lit[__num_base::_S_odigits]; + __len += 2; + } + } + + + const streamsize __w = __io.width(); + if (__w > static_cast(__len)) + { + _CharT* __cs3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __w)); + _M_pad(__fill, __w, __io, __cs3, __cs, __len); + __cs = __cs3; + } + __io.width(0); + + + + return std::__write(__s, __cs, __len); + } + + template + void + num_put<_CharT, _OutIter>:: + _M_group_float(const char* __grouping, size_t __grouping_size, + _CharT __sep, const _CharT* __p, _CharT* __new, + _CharT* __cs, int& __len) const + { + + + + const int __declen = __p ? __p - __cs : __len; + _CharT* __p2 = std::__add_grouping(__new, __sep, __grouping, + __grouping_size, + __cs, __cs + __declen); + + + int __newlen = __p2 - __new; + if (__p) + { + char_traits<_CharT>::copy(__p2, __p, __len - __declen); + __newlen += __len - __declen; + } + __len = __newlen; + } +# 966 "/usr/include/c++/4.8.2/bits/locale_facets.tcc" 3 + template + template + _OutIter + num_put<_CharT, _OutIter>:: + _M_insert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod, + _ValueT __v) const + { + typedef __numpunct_cache<_CharT> __cache_type; + __use_cache<__cache_type> __uc; + const locale& __loc = __io._M_getloc(); + const __cache_type* __lc = __uc(__loc); + + + const streamsize __prec = __io.precision() < 0 ? 6 : __io.precision(); + + const int __max_digits = + __gnu_cxx::__numeric_traits<_ValueT>::__digits10; + + + int __len; + + char __fbuf[16]; + __num_base::_S_format_float(__io, __fbuf, __mod); + + + + + int __cs_size = __max_digits * 3; + char* __cs = static_cast(__builtin_alloca(__cs_size)); + __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, + __fbuf, __prec, __v); + + + if (__len >= __cs_size) + { + __cs_size = __len + 1; + __cs = static_cast(__builtin_alloca(__cs_size)); + __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, + __fbuf, __prec, __v); + } +# 1027 "/usr/include/c++/4.8.2/bits/locale_facets.tcc" 3 + const ctype<_CharT>& __ctype = use_facet >(__loc); + + _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __len)); + __ctype.widen(__cs, __cs + __len, __ws); + + + _CharT* __wp = 0; + const char* __p = char_traits::find(__cs, __len, '.'); + if (__p) + { + __wp = __ws + (__p - __cs); + *__wp = __lc->_M_decimal_point; + } + + + + + if (__lc->_M_use_grouping + && (__wp || __len < 3 || (__cs[1] <= '9' && __cs[2] <= '9' + && __cs[1] >= '0' && __cs[2] >= '0'))) + { + + + _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __len * 2)); + + streamsize __off = 0; + if (__cs[0] == '-' || __cs[0] == '+') + { + __off = 1; + __ws2[0] = __ws[0]; + __len -= 1; + } + + _M_group_float(__lc->_M_grouping, __lc->_M_grouping_size, + __lc->_M_thousands_sep, __wp, __ws2 + __off, + __ws + __off, __len); + __len += __off; + + __ws = __ws2; + } + + + const streamsize __w = __io.width(); + if (__w > static_cast(__len)) + { + _CharT* __ws3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __w)); + _M_pad(__fill, __w, __io, __ws3, __ws, __len); + __ws = __ws3; + } + __io.width(0); + + + + return std::__write(__s, __ws, __len); + } + + template + _OutIter + num_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __io, char_type __fill, bool __v) const + { + const ios_base::fmtflags __flags = __io.flags(); + if ((__flags & ios_base::boolalpha) == 0) + { + const long __l = __v; + __s = _M_insert_int(__s, __io, __fill, __l); + } + else + { + typedef __numpunct_cache<_CharT> __cache_type; + __use_cache<__cache_type> __uc; + const locale& __loc = __io._M_getloc(); + const __cache_type* __lc = __uc(__loc); + + const _CharT* __name = __v ? __lc->_M_truename + : __lc->_M_falsename; + int __len = __v ? __lc->_M_truename_size + : __lc->_M_falsename_size; + + const streamsize __w = __io.width(); + if (__w > static_cast(__len)) + { + const streamsize __plen = __w - __len; + _CharT* __ps + = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __plen)); + + char_traits<_CharT>::assign(__ps, __plen, __fill); + __io.width(0); + + if ((__flags & ios_base::adjustfield) == ios_base::left) + { + __s = std::__write(__s, __name, __len); + __s = std::__write(__s, __ps, __plen); + } + else + { + __s = std::__write(__s, __ps, __plen); + __s = std::__write(__s, __name, __len); + } + return __s; + } + __io.width(0); + __s = std::__write(__s, __name, __len); + } + return __s; + } + + template + _OutIter + num_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const + { return _M_insert_float(__s, __io, __fill, char(), __v); } +# 1152 "/usr/include/c++/4.8.2/bits/locale_facets.tcc" 3 + template + _OutIter + num_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __io, char_type __fill, + long double __v) const + { return _M_insert_float(__s, __io, __fill, 'L', __v); } + + template + _OutIter + num_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __io, char_type __fill, + const void* __v) const + { + const ios_base::fmtflags __flags = __io.flags(); + const ios_base::fmtflags __fmt = ~(ios_base::basefield + | ios_base::uppercase); + __io.flags((__flags & __fmt) | (ios_base::hex | ios_base::showbase)); + + typedef __gnu_cxx::__conditional_type<(sizeof(const void*) + <= sizeof(unsigned long)), + unsigned long, unsigned long long>::__type _UIntPtrType; + + __s = _M_insert_int(__s, __io, __fill, + reinterpret_cast<_UIntPtrType>(__v)); + __io.flags(__flags); + return __s; + } + + +# 1189 "/usr/include/c++/4.8.2/bits/locale_facets.tcc" 3 + template + void + __pad<_CharT, _Traits>::_S_pad(ios_base& __io, _CharT __fill, + _CharT* __news, const _CharT* __olds, + streamsize __newlen, streamsize __oldlen) + { + const size_t __plen = static_cast(__newlen - __oldlen); + const ios_base::fmtflags __adjust = __io.flags() & ios_base::adjustfield; + + + if (__adjust == ios_base::left) + { + _Traits::copy(__news, __olds, __oldlen); + _Traits::assign(__news + __oldlen, __plen, __fill); + return; + } + + size_t __mod = 0; + if (__adjust == ios_base::internal) + { + + + + const locale& __loc = __io._M_getloc(); + const ctype<_CharT>& __ctype = use_facet >(__loc); + + if (__ctype.widen('-') == __olds[0] + || __ctype.widen('+') == __olds[0]) + { + __news[0] = __olds[0]; + __mod = 1; + ++__news; + } + else if (__ctype.widen('0') == __olds[0] + && __oldlen > 1 + && (__ctype.widen('x') == __olds[1] + || __ctype.widen('X') == __olds[1])) + { + __news[0] = __olds[0]; + __news[1] = __olds[1]; + __mod = 2; + __news += 2; + } + + } + _Traits::assign(__news, __plen, __fill); + _Traits::copy(__news + __plen, __olds + __mod, __oldlen - __mod); + } + + template + _CharT* + __add_grouping(_CharT* __s, _CharT __sep, + const char* __gbeg, size_t __gsize, + const _CharT* __first, const _CharT* __last) + { + size_t __idx = 0; + size_t __ctr = 0; + + while (__last - __first > __gbeg[__idx] + && static_cast(__gbeg[__idx]) > 0 + && __gbeg[__idx] != __gnu_cxx::__numeric_traits::__max) + { + __last -= __gbeg[__idx]; + __idx < __gsize - 1 ? ++__idx : ++__ctr; + } + + while (__first != __last) + *__s++ = *__first++; + + while (__ctr--) + { + *__s++ = __sep; + for (char __i = __gbeg[__idx]; __i > 0; --__i) + *__s++ = *__first++; + } + + while (__idx--) + { + *__s++ = __sep; + for (char __i = __gbeg[__idx]; __i > 0; --__i) + *__s++ = *__first++; + } + + return __s; + } + + + + + extern template class numpunct; + extern template class numpunct_byname; + extern template class num_get; + extern template class num_put; + extern template class ctype_byname; + + extern template + const ctype& + use_facet >(const locale&); + + extern template + const numpunct& + use_facet >(const locale&); + + extern template + const num_put& + use_facet >(const locale&); + + extern template + const num_get& + use_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + + extern template class numpunct; + extern template class numpunct_byname; + extern template class num_get; + extern template class num_put; + extern template class ctype_byname; + + extern template + const ctype& + use_facet >(const locale&); + + extern template + const numpunct& + use_facet >(const locale&); + + extern template + const num_put& + use_facet >(const locale&); + + extern template + const num_get& + use_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + + + +} +# 2609 "/usr/include/c++/4.8.2/bits/locale_facets.h" 2 3 +# 38 "/usr/include/c++/4.8.2/bits/basic_ios.h" 2 3 + + +namespace std __attribute__ ((__visibility__ ("default"))) +{ + + + template + inline const _Facet& + __check_facet(const _Facet* __f) + { + if (!__f) + __throw_bad_cast(); + return *__f; + } +# 65 "/usr/include/c++/4.8.2/bits/basic_ios.h" 3 + template + class basic_ios : public ios_base + { + public: + + + + + + + typedef _CharT char_type; + typedef typename _Traits::int_type int_type; + typedef typename _Traits::pos_type pos_type; + typedef typename _Traits::off_type off_type; + typedef _Traits traits_type; + + + + + + + typedef ctype<_CharT> __ctype_type; + typedef num_put<_CharT, ostreambuf_iterator<_CharT, _Traits> > + __num_put_type; + typedef num_get<_CharT, istreambuf_iterator<_CharT, _Traits> > + __num_get_type; + + + + protected: + basic_ostream<_CharT, _Traits>* _M_tie; + mutable char_type _M_fill; + mutable bool _M_fill_init; + basic_streambuf<_CharT, _Traits>* _M_streambuf; + + + const __ctype_type* _M_ctype; + + const __num_put_type* _M_num_put; + + const __num_get_type* _M_num_get; + + public: + + + + + + + + operator void*() const + { return this->fail() ? 0 : const_cast(this); } + + bool + operator!() const + { return this->fail(); } +# 130 "/usr/include/c++/4.8.2/bits/basic_ios.h" 3 + iostate + rdstate() const + { return _M_streambuf_state; } +# 141 "/usr/include/c++/4.8.2/bits/basic_ios.h" 3 + void + clear(iostate __state = goodbit); + + + + + + + + void + setstate(iostate __state) + { this->clear(this->rdstate() | __state); } + + + + + void + _M_setstate(iostate __state) + { + + + _M_streambuf_state |= __state; + if (this->exceptions() & __state) + throw; + } + + + + + + + + bool + good() const + { return this->rdstate() == 0; } + + + + + + + + bool + eof() const + { return (this->rdstate() & eofbit) != 0; } +# 194 "/usr/include/c++/4.8.2/bits/basic_ios.h" 3 + bool + fail() const + { return (this->rdstate() & (badbit | failbit)) != 0; } + + + + + + + + bool + bad() const + { return (this->rdstate() & badbit) != 0; } +# 215 "/usr/include/c++/4.8.2/bits/basic_ios.h" 3 + iostate + exceptions() const + { return _M_exception; } +# 250 "/usr/include/c++/4.8.2/bits/basic_ios.h" 3 + void + exceptions(iostate __except) + { + _M_exception = __except; + this->clear(_M_streambuf_state); + } + + + + + + + + explicit + basic_ios(basic_streambuf<_CharT, _Traits>* __sb) + : ios_base(), _M_tie(0), _M_fill(), _M_fill_init(false), _M_streambuf(0), + _M_ctype(0), _M_num_put(0), _M_num_get(0) + { this->init(__sb); } + + + + + + + + virtual + ~basic_ios() { } +# 288 "/usr/include/c++/4.8.2/bits/basic_ios.h" 3 + basic_ostream<_CharT, _Traits>* + tie() const + { return _M_tie; } +# 300 "/usr/include/c++/4.8.2/bits/basic_ios.h" 3 + basic_ostream<_CharT, _Traits>* + tie(basic_ostream<_CharT, _Traits>* __tiestr) + { + basic_ostream<_CharT, _Traits>* __old = _M_tie; + _M_tie = __tiestr; + return __old; + } + + + + + + + + basic_streambuf<_CharT, _Traits>* + rdbuf() const + { return _M_streambuf; } +# 340 "/usr/include/c++/4.8.2/bits/basic_ios.h" 3 + basic_streambuf<_CharT, _Traits>* + rdbuf(basic_streambuf<_CharT, _Traits>* __sb); +# 354 "/usr/include/c++/4.8.2/bits/basic_ios.h" 3 + basic_ios& + copyfmt(const basic_ios& __rhs); + + + + + + + + char_type + fill() const + { + if (!_M_fill_init) + { + _M_fill = this->widen(' '); + _M_fill_init = true; + } + return _M_fill; + } +# 383 "/usr/include/c++/4.8.2/bits/basic_ios.h" 3 + char_type + fill(char_type __ch) + { + char_type __old = this->fill(); + _M_fill = __ch; + return __old; + } +# 403 "/usr/include/c++/4.8.2/bits/basic_ios.h" 3 + locale + imbue(const locale& __loc); +# 423 "/usr/include/c++/4.8.2/bits/basic_ios.h" 3 + char + narrow(char_type __c, char __dfault) const + { return __check_facet(_M_ctype).narrow(__c, __dfault); } +# 442 "/usr/include/c++/4.8.2/bits/basic_ios.h" 3 + char_type + widen(char __c) const + { return __check_facet(_M_ctype).widen(__c); } + + protected: + + + + + + + + basic_ios() + : ios_base(), _M_tie(0), _M_fill(char_type()), _M_fill_init(false), + _M_streambuf(0), _M_ctype(0), _M_num_put(0), _M_num_get(0) + { } + + + + + + + + void + init(basic_streambuf<_CharT, _Traits>* __sb); + + void + _M_cache_locale(const locale& __loc); + }; + + +} + +# 1 "/usr/include/c++/4.8.2/bits/basic_ios.tcc" 1 3 +# 33 "/usr/include/c++/4.8.2/bits/basic_ios.tcc" 3 + +# 34 "/usr/include/c++/4.8.2/bits/basic_ios.tcc" 3 + +namespace std __attribute__ ((__visibility__ ("default"))) +{ + + + template + void + basic_ios<_CharT, _Traits>::clear(iostate __state) + { + if (this->rdbuf()) + _M_streambuf_state = __state; + else + _M_streambuf_state = __state | badbit; + if (this->exceptions() & this->rdstate()) + __throw_ios_failure(("basic_ios::clear")); + } + + template + basic_streambuf<_CharT, _Traits>* + basic_ios<_CharT, _Traits>::rdbuf(basic_streambuf<_CharT, _Traits>* __sb) + { + basic_streambuf<_CharT, _Traits>* __old = _M_streambuf; + _M_streambuf = __sb; + this->clear(); + return __old; + } + + template + basic_ios<_CharT, _Traits>& + basic_ios<_CharT, _Traits>::copyfmt(const basic_ios& __rhs) + { + + + if (this != &__rhs) + { + + + + + _Words* __words = (__rhs._M_word_size <= _S_local_word_size) ? + _M_local_word : new _Words[__rhs._M_word_size]; + + + _Callback_list* __cb = __rhs._M_callbacks; + if (__cb) + __cb->_M_add_reference(); + _M_call_callbacks(erase_event); + if (_M_word != _M_local_word) + { + delete [] _M_word; + _M_word = 0; + } + _M_dispose_callbacks(); + + + _M_callbacks = __cb; + for (int __i = 0; __i < __rhs._M_word_size; ++__i) + __words[__i] = __rhs._M_word[__i]; + _M_word = __words; + _M_word_size = __rhs._M_word_size; + + this->flags(__rhs.flags()); + this->width(__rhs.width()); + this->precision(__rhs.precision()); + this->tie(__rhs.tie()); + this->fill(__rhs.fill()); + _M_ios_locale = __rhs.getloc(); + _M_cache_locale(_M_ios_locale); + + _M_call_callbacks(copyfmt_event); + + + this->exceptions(__rhs.exceptions()); + } + return *this; + } + + + template + locale + basic_ios<_CharT, _Traits>::imbue(const locale& __loc) + { + locale __old(this->getloc()); + ios_base::imbue(__loc); + _M_cache_locale(__loc); + if (this->rdbuf() != 0) + this->rdbuf()->pubimbue(__loc); + return __old; + } + + template + void + basic_ios<_CharT, _Traits>::init(basic_streambuf<_CharT, _Traits>* __sb) + { + + ios_base::_M_init(); + + + _M_cache_locale(_M_ios_locale); +# 146 "/usr/include/c++/4.8.2/bits/basic_ios.tcc" 3 + _M_fill = _CharT(); + _M_fill_init = false; + + _M_tie = 0; + _M_exception = goodbit; + _M_streambuf = __sb; + _M_streambuf_state = __sb ? goodbit : badbit; + } + + template + void + basic_ios<_CharT, _Traits>::_M_cache_locale(const locale& __loc) + { + if (__builtin_expect(has_facet<__ctype_type>(__loc), true)) + _M_ctype = &use_facet<__ctype_type>(__loc); + else + _M_ctype = 0; + + if (__builtin_expect(has_facet<__num_put_type>(__loc), true)) + _M_num_put = &use_facet<__num_put_type>(__loc); + else + _M_num_put = 0; + + if (__builtin_expect(has_facet<__num_get_type>(__loc), true)) + _M_num_get = &use_facet<__num_get_type>(__loc); + else + _M_num_get = 0; + } + + + + + extern template class basic_ios; + + + extern template class basic_ios; + + + + +} +# 476 "/usr/include/c++/4.8.2/bits/basic_ios.h" 2 3 +# 45 "/usr/include/c++/4.8.2/ios" 2 3 +# 39 "/usr/include/c++/4.8.2/ostream" 2 3 + + +namespace std __attribute__ ((__visibility__ ("default"))) +{ + +# 57 "/usr/include/c++/4.8.2/ostream" 3 + template + class basic_ostream : virtual public basic_ios<_CharT, _Traits> + { + public: + + typedef _CharT char_type; + typedef typename _Traits::int_type int_type; + typedef typename _Traits::pos_type pos_type; + typedef typename _Traits::off_type off_type; + typedef _Traits traits_type; + + + typedef basic_streambuf<_CharT, _Traits> __streambuf_type; + typedef basic_ios<_CharT, _Traits> __ios_type; + typedef basic_ostream<_CharT, _Traits> __ostream_type; + typedef num_put<_CharT, ostreambuf_iterator<_CharT, _Traits> > + __num_put_type; + typedef ctype<_CharT> __ctype_type; +# 83 "/usr/include/c++/4.8.2/ostream" 3 + explicit + basic_ostream(__streambuf_type* __sb) + { this->init(__sb); } + + + + + + + virtual + ~basic_ostream() { } + + + class sentry; + friend class sentry; +# 107 "/usr/include/c++/4.8.2/ostream" 3 + __ostream_type& + operator<<(__ostream_type& (*__pf)(__ostream_type&)) + { + + + + return __pf(*this); + } + + __ostream_type& + operator<<(__ios_type& (*__pf)(__ios_type&)) + { + + + + __pf(*this); + return *this; + } + + __ostream_type& + operator<<(ios_base& (*__pf) (ios_base&)) + { + + + + __pf(*this); + return *this; + } +# 165 "/usr/include/c++/4.8.2/ostream" 3 + __ostream_type& + operator<<(long __n) + { return _M_insert(__n); } + + __ostream_type& + operator<<(unsigned long __n) + { return _M_insert(__n); } + + __ostream_type& + operator<<(bool __n) + { return _M_insert(__n); } + + __ostream_type& + operator<<(short __n); + + __ostream_type& + operator<<(unsigned short __n) + { + + + return _M_insert(static_cast(__n)); + } + + __ostream_type& + operator<<(int __n); + + __ostream_type& + operator<<(unsigned int __n) + { + + + return _M_insert(static_cast(__n)); + } + + + __ostream_type& + operator<<(long long __n) + { return _M_insert(__n); } + + __ostream_type& + operator<<(unsigned long long __n) + { return _M_insert(__n); } +# 219 "/usr/include/c++/4.8.2/ostream" 3 + __ostream_type& + operator<<(double __f) + { return _M_insert(__f); } + + __ostream_type& + operator<<(float __f) + { + + + return _M_insert(static_cast(__f)); + } + + __ostream_type& + operator<<(long double __f) + { return _M_insert(__f); } +# 244 "/usr/include/c++/4.8.2/ostream" 3 + __ostream_type& + operator<<(const void* __p) + { return _M_insert(__p); } +# 269 "/usr/include/c++/4.8.2/ostream" 3 + __ostream_type& + operator<<(__streambuf_type* __sb); +# 302 "/usr/include/c++/4.8.2/ostream" 3 + __ostream_type& + put(char_type __c); + + + + + + + void + _M_write(const char_type* __s, streamsize __n) + { + const streamsize __put = this->rdbuf()->sputn(__s, __n); + if (__put != __n) + this->setstate(ios_base::badbit); + } +# 334 "/usr/include/c++/4.8.2/ostream" 3 + __ostream_type& + write(const char_type* __s, streamsize __n); +# 347 "/usr/include/c++/4.8.2/ostream" 3 + __ostream_type& + flush(); +# 357 "/usr/include/c++/4.8.2/ostream" 3 + pos_type + tellp(); +# 368 "/usr/include/c++/4.8.2/ostream" 3 + __ostream_type& + seekp(pos_type); +# 380 "/usr/include/c++/4.8.2/ostream" 3 + __ostream_type& + seekp(off_type, ios_base::seekdir); + + protected: + basic_ostream() + { this->init(0); } + + template + __ostream_type& + _M_insert(_ValueT __v); + }; +# 399 "/usr/include/c++/4.8.2/ostream" 3 + template + class basic_ostream<_CharT, _Traits>::sentry + { + + bool _M_ok; + basic_ostream<_CharT, _Traits>& _M_os; + + public: +# 418 "/usr/include/c++/4.8.2/ostream" 3 + explicit + sentry(basic_ostream<_CharT, _Traits>& __os); +# 428 "/usr/include/c++/4.8.2/ostream" 3 + ~sentry() + { + + if (bool(_M_os.flags() & ios_base::unitbuf) && !uncaught_exception()) + { + + if (_M_os.rdbuf() && _M_os.rdbuf()->pubsync() == -1) + _M_os.setstate(ios_base::badbit); + } + } +# 449 "/usr/include/c++/4.8.2/ostream" 3 + operator bool() const + { return _M_ok; } + }; +# 469 "/usr/include/c++/4.8.2/ostream" 3 + template + inline basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c) + { return __ostream_insert(__out, &__c, 1); } + + template + inline basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __out, char __c) + { return (__out << __out.widen(__c)); } + + + template + inline basic_ostream& + operator<<(basic_ostream& __out, char __c) + { return __ostream_insert(__out, &__c, 1); } + + + template + inline basic_ostream& + operator<<(basic_ostream& __out, signed char __c) + { return (__out << static_cast(__c)); } + + template + inline basic_ostream& + operator<<(basic_ostream& __out, unsigned char __c) + { return (__out << static_cast(__c)); } +# 511 "/usr/include/c++/4.8.2/ostream" 3 + template + inline basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s) + { + if (!__s) + __out.setstate(ios_base::badbit); + else + __ostream_insert(__out, __s, + static_cast(_Traits::length(__s))); + return __out; + } + + template + basic_ostream<_CharT, _Traits> & + operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s); + + + template + inline basic_ostream& + operator<<(basic_ostream& __out, const char* __s) + { + if (!__s) + __out.setstate(ios_base::badbit); + else + __ostream_insert(__out, __s, + static_cast(_Traits::length(__s))); + return __out; + } + + + template + inline basic_ostream& + operator<<(basic_ostream& __out, const signed char* __s) + { return (__out << reinterpret_cast(__s)); } + + template + inline basic_ostream & + operator<<(basic_ostream& __out, const unsigned char* __s) + { return (__out << reinterpret_cast(__s)); } +# 562 "/usr/include/c++/4.8.2/ostream" 3 + template + inline basic_ostream<_CharT, _Traits>& + endl(basic_ostream<_CharT, _Traits>& __os) + { return flush(__os.put(__os.widen('\n'))); } +# 574 "/usr/include/c++/4.8.2/ostream" 3 + template + inline basic_ostream<_CharT, _Traits>& + ends(basic_ostream<_CharT, _Traits>& __os) + { return __os.put(_CharT()); } + + + + + + + template + inline basic_ostream<_CharT, _Traits>& + flush(basic_ostream<_CharT, _Traits>& __os) + { return __os.flush(); } +# 609 "/usr/include/c++/4.8.2/ostream" 3 + +} + +# 1 "/usr/include/c++/4.8.2/bits/ostream.tcc" 1 3 +# 37 "/usr/include/c++/4.8.2/bits/ostream.tcc" 3 + +# 38 "/usr/include/c++/4.8.2/bits/ostream.tcc" 3 + + + +namespace std __attribute__ ((__visibility__ ("default"))) +{ + + + template + basic_ostream<_CharT, _Traits>::sentry:: + sentry(basic_ostream<_CharT, _Traits>& __os) + : _M_ok(false), _M_os(__os) + { + + if (__os.tie() && __os.good()) + __os.tie()->flush(); + + if (__os.good()) + _M_ok = true; + else + __os.setstate(ios_base::failbit); + } + + template + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + _M_insert(_ValueT __v) + { + sentry __cerb(*this); + if (__cerb) + { + ios_base::iostate __err = ios_base::goodbit; + try + { + const __num_put_type& __np = __check_facet(this->_M_num_put); + if (__np.put(*this, *this, this->fill(), __v).failed()) + __err |= ios_base::badbit; + } + catch(__cxxabiv1::__forced_unwind&) + { + this->_M_setstate(ios_base::badbit); + throw; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(short __n) + { + + + const ios_base::fmtflags __fmt = this->flags() & ios_base::basefield; + if (__fmt == ios_base::oct || __fmt == ios_base::hex) + return _M_insert(static_cast(static_cast(__n))); + else + return _M_insert(static_cast(__n)); + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(int __n) + { + + + const ios_base::fmtflags __fmt = this->flags() & ios_base::basefield; + if (__fmt == ios_base::oct || __fmt == ios_base::hex) + return _M_insert(static_cast(static_cast(__n))); + else + return _M_insert(static_cast(__n)); + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(__streambuf_type* __sbin) + { + ios_base::iostate __err = ios_base::goodbit; + sentry __cerb(*this); + if (__cerb && __sbin) + { + try + { + if (!__copy_streambufs(__sbin, this->rdbuf())) + __err |= ios_base::failbit; + } + catch(__cxxabiv1::__forced_unwind&) + { + this->_M_setstate(ios_base::badbit); + throw; + } + catch(...) + { this->_M_setstate(ios_base::failbit); } + } + else if (!__sbin) + __err |= ios_base::badbit; + if (__err) + this->setstate(__err); + return *this; + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + put(char_type __c) + { + + + + + + + sentry __cerb(*this); + if (__cerb) + { + ios_base::iostate __err = ios_base::goodbit; + try + { + const int_type __put = this->rdbuf()->sputc(__c); + if (traits_type::eq_int_type(__put, traits_type::eof())) + __err |= ios_base::badbit; + } + catch(__cxxabiv1::__forced_unwind&) + { + this->_M_setstate(ios_base::badbit); + throw; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + write(const _CharT* __s, streamsize __n) + { + + + + + + + + sentry __cerb(*this); + if (__cerb) + { + try + { _M_write(__s, __n); } + catch(__cxxabiv1::__forced_unwind&) + { + this->_M_setstate(ios_base::badbit); + throw; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + } + return *this; + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + flush() + { + + + + ios_base::iostate __err = ios_base::goodbit; + try + { + if (this->rdbuf() && this->rdbuf()->pubsync() == -1) + __err |= ios_base::badbit; + } + catch(__cxxabiv1::__forced_unwind&) + { + this->_M_setstate(ios_base::badbit); + throw; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + return *this; + } + + template + typename basic_ostream<_CharT, _Traits>::pos_type + basic_ostream<_CharT, _Traits>:: + tellp() + { + pos_type __ret = pos_type(-1); + try + { + if (!this->fail()) + __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out); + } + catch(__cxxabiv1::__forced_unwind&) + { + this->_M_setstate(ios_base::badbit); + throw; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + return __ret; + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + seekp(pos_type __pos) + { + ios_base::iostate __err = ios_base::goodbit; + try + { + if (!this->fail()) + { + + + const pos_type __p = this->rdbuf()->pubseekpos(__pos, + ios_base::out); + + + if (__p == pos_type(off_type(-1))) + __err |= ios_base::failbit; + } + } + catch(__cxxabiv1::__forced_unwind&) + { + this->_M_setstate(ios_base::badbit); + throw; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + return *this; + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + seekp(off_type __off, ios_base::seekdir __dir) + { + ios_base::iostate __err = ios_base::goodbit; + try + { + if (!this->fail()) + { + + + const pos_type __p = this->rdbuf()->pubseekoff(__off, __dir, + ios_base::out); + + + if (__p == pos_type(off_type(-1))) + __err |= ios_base::failbit; + } + } + catch(__cxxabiv1::__forced_unwind&) + { + this->_M_setstate(ios_base::badbit); + throw; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + return *this; + } + + template + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s) + { + if (!__s) + __out.setstate(ios_base::badbit); + else + { + + + const size_t __clen = char_traits::length(__s); + try + { + struct __ptr_guard + { + _CharT *__p; + __ptr_guard (_CharT *__ip): __p(__ip) { } + ~__ptr_guard() { delete[] __p; } + _CharT* __get() { return __p; } + } __pg (new _CharT[__clen]); + + _CharT *__ws = __pg.__get(); + for (size_t __i = 0; __i < __clen; ++__i) + __ws[__i] = __out.widen(__s[__i]); + __ostream_insert(__out, __ws, __clen); + } + catch(__cxxabiv1::__forced_unwind&) + { + __out._M_setstate(ios_base::badbit); + throw; + } + catch(...) + { __out._M_setstate(ios_base::badbit); } + } + return __out; + } + + + + + extern template class basic_ostream; + extern template ostream& endl(ostream&); + extern template ostream& ends(ostream&); + extern template ostream& flush(ostream&); + extern template ostream& operator<<(ostream&, char); + extern template ostream& operator<<(ostream&, unsigned char); + extern template ostream& operator<<(ostream&, signed char); + extern template ostream& operator<<(ostream&, const char*); + extern template ostream& operator<<(ostream&, const unsigned char*); + extern template ostream& operator<<(ostream&, const signed char*); + + extern template ostream& ostream::_M_insert(long); + extern template ostream& ostream::_M_insert(unsigned long); + extern template ostream& ostream::_M_insert(bool); + + extern template ostream& ostream::_M_insert(long long); + extern template ostream& ostream::_M_insert(unsigned long long); + + extern template ostream& ostream::_M_insert(double); + extern template ostream& ostream::_M_insert(long double); + extern template ostream& ostream::_M_insert(const void*); + + + extern template class basic_ostream; + extern template wostream& endl(wostream&); + extern template wostream& ends(wostream&); + extern template wostream& flush(wostream&); + extern template wostream& operator<<(wostream&, wchar_t); + extern template wostream& operator<<(wostream&, char); + extern template wostream& operator<<(wostream&, const wchar_t*); + extern template wostream& operator<<(wostream&, const char*); + + extern template wostream& wostream::_M_insert(long); + extern template wostream& wostream::_M_insert(unsigned long); + extern template wostream& wostream::_M_insert(bool); + + extern template wostream& wostream::_M_insert(long long); + extern template wostream& wostream::_M_insert(unsigned long long); + + extern template wostream& wostream::_M_insert(double); + extern template wostream& wostream::_M_insert(long double); + extern template wostream& wostream::_M_insert(const void*); + + + + +} +# 613 "/usr/include/c++/4.8.2/ostream" 2 3 +# 40 "/usr/include/c++/4.8.2/iostream" 2 3 +# 1 "/usr/include/c++/4.8.2/istream" 1 3 +# 36 "/usr/include/c++/4.8.2/istream" 3 + +# 37 "/usr/include/c++/4.8.2/istream" 3 + + + + +namespace std __attribute__ ((__visibility__ ("default"))) +{ + +# 57 "/usr/include/c++/4.8.2/istream" 3 + template + class basic_istream : virtual public basic_ios<_CharT, _Traits> + { + public: + + typedef _CharT char_type; + typedef typename _Traits::int_type int_type; + typedef typename _Traits::pos_type pos_type; + typedef typename _Traits::off_type off_type; + typedef _Traits traits_type; + + + typedef basic_streambuf<_CharT, _Traits> __streambuf_type; + typedef basic_ios<_CharT, _Traits> __ios_type; + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef num_get<_CharT, istreambuf_iterator<_CharT, _Traits> > + __num_get_type; + typedef ctype<_CharT> __ctype_type; + + protected: + + + + + + streamsize _M_gcount; + + public: + + + + + + + + explicit + basic_istream(__streambuf_type* __sb) + : _M_gcount(streamsize(0)) + { this->init(__sb); } + + + + + + + virtual + ~basic_istream() + { _M_gcount = streamsize(0); } + + + class sentry; + friend class sentry; +# 119 "/usr/include/c++/4.8.2/istream" 3 + __istream_type& + operator>>(__istream_type& (*__pf)(__istream_type&)) + { return __pf(*this); } + + __istream_type& + operator>>(__ios_type& (*__pf)(__ios_type&)) + { + __pf(*this); + return *this; + } + + __istream_type& + operator>>(ios_base& (*__pf)(ios_base&)) + { + __pf(*this); + return *this; + } +# 167 "/usr/include/c++/4.8.2/istream" 3 + __istream_type& + operator>>(bool& __n) + { return _M_extract(__n); } + + __istream_type& + operator>>(short& __n); + + __istream_type& + operator>>(unsigned short& __n) + { return _M_extract(__n); } + + __istream_type& + operator>>(int& __n); + + __istream_type& + operator>>(unsigned int& __n) + { return _M_extract(__n); } + + __istream_type& + operator>>(long& __n) + { return _M_extract(__n); } + + __istream_type& + operator>>(unsigned long& __n) + { return _M_extract(__n); } + + + __istream_type& + operator>>(long long& __n) + { return _M_extract(__n); } + + __istream_type& + operator>>(unsigned long long& __n) + { return _M_extract(__n); } +# 213 "/usr/include/c++/4.8.2/istream" 3 + __istream_type& + operator>>(float& __f) + { return _M_extract(__f); } + + __istream_type& + operator>>(double& __f) + { return _M_extract(__f); } + + __istream_type& + operator>>(long double& __f) + { return _M_extract(__f); } +# 234 "/usr/include/c++/4.8.2/istream" 3 + __istream_type& + operator>>(void*& __p) + { return _M_extract(__p); } +# 258 "/usr/include/c++/4.8.2/istream" 3 + __istream_type& + operator>>(__streambuf_type* __sb); +# 268 "/usr/include/c++/4.8.2/istream" 3 + streamsize + gcount() const + { return _M_gcount; } +# 301 "/usr/include/c++/4.8.2/istream" 3 + int_type + get(); +# 315 "/usr/include/c++/4.8.2/istream" 3 + __istream_type& + get(char_type& __c); +# 342 "/usr/include/c++/4.8.2/istream" 3 + __istream_type& + get(char_type* __s, streamsize __n, char_type __delim); +# 353 "/usr/include/c++/4.8.2/istream" 3 + __istream_type& + get(char_type* __s, streamsize __n) + { return this->get(__s, __n, this->widen('\n')); } +# 376 "/usr/include/c++/4.8.2/istream" 3 + __istream_type& + get(__streambuf_type& __sb, char_type __delim); +# 386 "/usr/include/c++/4.8.2/istream" 3 + __istream_type& + get(__streambuf_type& __sb) + { return this->get(__sb, this->widen('\n')); } +# 415 "/usr/include/c++/4.8.2/istream" 3 + __istream_type& + getline(char_type* __s, streamsize __n, char_type __delim); +# 426 "/usr/include/c++/4.8.2/istream" 3 + __istream_type& + getline(char_type* __s, streamsize __n) + { return this->getline(__s, __n, this->widen('\n')); } +# 450 "/usr/include/c++/4.8.2/istream" 3 + __istream_type& + ignore(streamsize __n, int_type __delim); + + __istream_type& + ignore(streamsize __n); + + __istream_type& + ignore(); +# 467 "/usr/include/c++/4.8.2/istream" 3 + int_type + peek(); +# 485 "/usr/include/c++/4.8.2/istream" 3 + __istream_type& + read(char_type* __s, streamsize __n); +# 504 "/usr/include/c++/4.8.2/istream" 3 + streamsize + readsome(char_type* __s, streamsize __n); +# 521 "/usr/include/c++/4.8.2/istream" 3 + __istream_type& + putback(char_type __c); +# 537 "/usr/include/c++/4.8.2/istream" 3 + __istream_type& + unget(); +# 555 "/usr/include/c++/4.8.2/istream" 3 + int + sync(); +# 570 "/usr/include/c++/4.8.2/istream" 3 + pos_type + tellg(); +# 585 "/usr/include/c++/4.8.2/istream" 3 + __istream_type& + seekg(pos_type); +# 601 "/usr/include/c++/4.8.2/istream" 3 + __istream_type& + seekg(off_type, ios_base::seekdir); + + + protected: + basic_istream() + : _M_gcount(streamsize(0)) + { this->init(0); } + + template + __istream_type& + _M_extract(_ValueT& __v); + }; + + + template<> + basic_istream& + basic_istream:: + getline(char_type* __s, streamsize __n, char_type __delim); + + template<> + basic_istream& + basic_istream:: + ignore(streamsize __n); + + template<> + basic_istream& + basic_istream:: + ignore(streamsize __n, int_type __delim); + + + template<> + basic_istream& + basic_istream:: + getline(char_type* __s, streamsize __n, char_type __delim); + + template<> + basic_istream& + basic_istream:: + ignore(streamsize __n); + + template<> + basic_istream& + basic_istream:: + ignore(streamsize __n, int_type __delim); +# 656 "/usr/include/c++/4.8.2/istream" 3 + template + class basic_istream<_CharT, _Traits>::sentry + { + + bool _M_ok; + + public: + + typedef _Traits traits_type; + typedef basic_streambuf<_CharT, _Traits> __streambuf_type; + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::__ctype_type __ctype_type; + typedef typename _Traits::int_type __int_type; +# 692 "/usr/include/c++/4.8.2/istream" 3 + explicit + sentry(basic_istream<_CharT, _Traits>& __is, bool __noskipws = false); +# 705 "/usr/include/c++/4.8.2/istream" 3 + operator bool() const + { return _M_ok; } + }; +# 721 "/usr/include/c++/4.8.2/istream" 3 + template + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __in, _CharT& __c); + + template + inline basic_istream& + operator>>(basic_istream& __in, unsigned char& __c) + { return (__in >> reinterpret_cast(__c)); } + + template + inline basic_istream& + operator>>(basic_istream& __in, signed char& __c) + { return (__in >> reinterpret_cast(__c)); } +# 763 "/usr/include/c++/4.8.2/istream" 3 + template + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __in, _CharT* __s); + + + template<> + basic_istream& + operator>>(basic_istream& __in, char* __s); + + template + inline basic_istream& + operator>>(basic_istream& __in, unsigned char* __s) + { return (__in >> reinterpret_cast(__s)); } + + template + inline basic_istream& + operator>>(basic_istream& __in, signed char* __s) + { return (__in >> reinterpret_cast(__s)); } +# 794 "/usr/include/c++/4.8.2/istream" 3 + template + class basic_iostream + : public basic_istream<_CharT, _Traits>, + public basic_ostream<_CharT, _Traits> + { + public: + + + + typedef _CharT char_type; + typedef typename _Traits::int_type int_type; + typedef typename _Traits::pos_type pos_type; + typedef typename _Traits::off_type off_type; + typedef _Traits traits_type; + + + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef basic_ostream<_CharT, _Traits> __ostream_type; + + + + + + + + explicit + basic_iostream(basic_streambuf<_CharT, _Traits>* __sb) + : __istream_type(__sb), __ostream_type(__sb) { } + + + + + virtual + ~basic_iostream() { } + + protected: + basic_iostream() + : __istream_type(), __ostream_type() { } + }; +# 854 "/usr/include/c++/4.8.2/istream" 3 + template + basic_istream<_CharT, _Traits>& + ws(basic_istream<_CharT, _Traits>& __is); +# 879 "/usr/include/c++/4.8.2/istream" 3 + +} + +# 1 "/usr/include/c++/4.8.2/bits/istream.tcc" 1 3 +# 37 "/usr/include/c++/4.8.2/bits/istream.tcc" 3 + +# 38 "/usr/include/c++/4.8.2/bits/istream.tcc" 3 + + + +namespace std __attribute__ ((__visibility__ ("default"))) +{ + + + template + basic_istream<_CharT, _Traits>::sentry:: + sentry(basic_istream<_CharT, _Traits>& __in, bool __noskip) : _M_ok(false) + { + ios_base::iostate __err = ios_base::goodbit; + if (__in.good()) + try + { + if (__in.tie()) + __in.tie()->flush(); + if (!__noskip && bool(__in.flags() & ios_base::skipws)) + { + const __int_type __eof = traits_type::eof(); + __streambuf_type* __sb = __in.rdbuf(); + __int_type __c = __sb->sgetc(); + + const __ctype_type& __ct = __check_facet(__in._M_ctype); + while (!traits_type::eq_int_type(__c, __eof) + && __ct.is(ctype_base::space, + traits_type::to_char_type(__c))) + __c = __sb->snextc(); + + + + + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + } + } + catch(__cxxabiv1::__forced_unwind&) + { + __in._M_setstate(ios_base::badbit); + throw; + } + catch(...) + { __in._M_setstate(ios_base::badbit); } + + if (__in.good() && __err == ios_base::goodbit) + _M_ok = true; + else + { + __err |= ios_base::failbit; + __in.setstate(__err); + } + } + + template + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + _M_extract(_ValueT& __v) + { + sentry __cerb(*this, false); + if (__cerb) + { + ios_base::iostate __err = ios_base::goodbit; + try + { + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __v); + } + catch(__cxxabiv1::__forced_unwind&) + { + this->_M_setstate(ios_base::badbit); + throw; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(short& __n) + { + + + sentry __cerb(*this, false); + if (__cerb) + { + ios_base::iostate __err = ios_base::goodbit; + try + { + long __l; + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __l); + + + + if (__l < __gnu_cxx::__numeric_traits::__min) + { + __err |= ios_base::failbit; + __n = __gnu_cxx::__numeric_traits::__min; + } + else if (__l > __gnu_cxx::__numeric_traits::__max) + { + __err |= ios_base::failbit; + __n = __gnu_cxx::__numeric_traits::__max; + } + else + __n = short(__l); + } + catch(__cxxabiv1::__forced_unwind&) + { + this->_M_setstate(ios_base::badbit); + throw; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(int& __n) + { + + + sentry __cerb(*this, false); + if (__cerb) + { + ios_base::iostate __err = ios_base::goodbit; + try + { + long __l; + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __l); + + + + if (__l < __gnu_cxx::__numeric_traits::__min) + { + __err |= ios_base::failbit; + __n = __gnu_cxx::__numeric_traits::__min; + } + else if (__l > __gnu_cxx::__numeric_traits::__max) + { + __err |= ios_base::failbit; + __n = __gnu_cxx::__numeric_traits::__max; + } + else + __n = int(__l); + } + catch(__cxxabiv1::__forced_unwind&) + { + this->_M_setstate(ios_base::badbit); + throw; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(__streambuf_type* __sbout) + { + ios_base::iostate __err = ios_base::goodbit; + sentry __cerb(*this, false); + if (__cerb && __sbout) + { + try + { + bool __ineof; + if (!__copy_streambufs_eof(this->rdbuf(), __sbout, __ineof)) + __err |= ios_base::failbit; + if (__ineof) + __err |= ios_base::eofbit; + } + catch(__cxxabiv1::__forced_unwind&) + { + this->_M_setstate(ios_base::failbit); + throw; + } + catch(...) + { this->_M_setstate(ios_base::failbit); } + } + else if (!__sbout) + __err |= ios_base::failbit; + if (__err) + this->setstate(__err); + return *this; + } + + template + typename basic_istream<_CharT, _Traits>::int_type + basic_istream<_CharT, _Traits>:: + get(void) + { + const int_type __eof = traits_type::eof(); + int_type __c = __eof; + _M_gcount = 0; + ios_base::iostate __err = ios_base::goodbit; + sentry __cerb(*this, true); + if (__cerb) + { + try + { + __c = this->rdbuf()->sbumpc(); + + if (!traits_type::eq_int_type(__c, __eof)) + _M_gcount = 1; + else + __err |= ios_base::eofbit; + } + catch(__cxxabiv1::__forced_unwind&) + { + this->_M_setstate(ios_base::badbit); + throw; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + } + if (!_M_gcount) + __err |= ios_base::failbit; + if (__err) + this->setstate(__err); + return __c; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + get(char_type& __c) + { + _M_gcount = 0; + ios_base::iostate __err = ios_base::goodbit; + sentry __cerb(*this, true); + if (__cerb) + { + try + { + const int_type __cb = this->rdbuf()->sbumpc(); + + if (!traits_type::eq_int_type(__cb, traits_type::eof())) + { + _M_gcount = 1; + __c = traits_type::to_char_type(__cb); + } + else + __err |= ios_base::eofbit; + } + catch(__cxxabiv1::__forced_unwind&) + { + this->_M_setstate(ios_base::badbit); + throw; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + } + if (!_M_gcount) + __err |= ios_base::failbit; + if (__err) + this->setstate(__err); + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + get(char_type* __s, streamsize __n, char_type __delim) + { + _M_gcount = 0; + ios_base::iostate __err = ios_base::goodbit; + sentry __cerb(*this, true); + if (__cerb) + { + try + { + const int_type __idelim = traits_type::to_int_type(__delim); + const int_type __eof = traits_type::eof(); + __streambuf_type* __sb = this->rdbuf(); + int_type __c = __sb->sgetc(); + + while (_M_gcount + 1 < __n + && !traits_type::eq_int_type(__c, __eof) + && !traits_type::eq_int_type(__c, __idelim)) + { + *__s++ = traits_type::to_char_type(__c); + ++_M_gcount; + __c = __sb->snextc(); + } + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + } + catch(__cxxabiv1::__forced_unwind&) + { + this->_M_setstate(ios_base::badbit); + throw; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + } + + + if (__n > 0) + *__s = char_type(); + if (!_M_gcount) + __err |= ios_base::failbit; + if (__err) + this->setstate(__err); + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + get(__streambuf_type& __sb, char_type __delim) + { + _M_gcount = 0; + ios_base::iostate __err = ios_base::goodbit; + sentry __cerb(*this, true); + if (__cerb) + { + try + { + const int_type __idelim = traits_type::to_int_type(__delim); + const int_type __eof = traits_type::eof(); + __streambuf_type* __this_sb = this->rdbuf(); + int_type __c = __this_sb->sgetc(); + char_type __c2 = traits_type::to_char_type(__c); + + while (!traits_type::eq_int_type(__c, __eof) + && !traits_type::eq_int_type(__c, __idelim) + && !traits_type::eq_int_type(__sb.sputc(__c2), __eof)) + { + ++_M_gcount; + __c = __this_sb->snextc(); + __c2 = traits_type::to_char_type(__c); + } + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + } + catch(__cxxabiv1::__forced_unwind&) + { + this->_M_setstate(ios_base::badbit); + throw; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + } + if (!_M_gcount) + __err |= ios_base::failbit; + if (__err) + this->setstate(__err); + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + getline(char_type* __s, streamsize __n, char_type __delim) + { + _M_gcount = 0; + ios_base::iostate __err = ios_base::goodbit; + sentry __cerb(*this, true); + if (__cerb) + { + try + { + const int_type __idelim = traits_type::to_int_type(__delim); + const int_type __eof = traits_type::eof(); + __streambuf_type* __sb = this->rdbuf(); + int_type __c = __sb->sgetc(); + + while (_M_gcount + 1 < __n + && !traits_type::eq_int_type(__c, __eof) + && !traits_type::eq_int_type(__c, __idelim)) + { + *__s++ = traits_type::to_char_type(__c); + __c = __sb->snextc(); + ++_M_gcount; + } + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + else + { + if (traits_type::eq_int_type(__c, __idelim)) + { + __sb->sbumpc(); + ++_M_gcount; + } + else + __err |= ios_base::failbit; + } + } + catch(__cxxabiv1::__forced_unwind&) + { + this->_M_setstate(ios_base::badbit); + throw; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + } + + + if (__n > 0) + *__s = char_type(); + if (!_M_gcount) + __err |= ios_base::failbit; + if (__err) + this->setstate(__err); + return *this; + } + + + + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + ignore(void) + { + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb) + { + ios_base::iostate __err = ios_base::goodbit; + try + { + const int_type __eof = traits_type::eof(); + __streambuf_type* __sb = this->rdbuf(); + + if (traits_type::eq_int_type(__sb->sbumpc(), __eof)) + __err |= ios_base::eofbit; + else + _M_gcount = 1; + } + catch(__cxxabiv1::__forced_unwind&) + { + this->_M_setstate(ios_base::badbit); + throw; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + ignore(streamsize __n) + { + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb && __n > 0) + { + ios_base::iostate __err = ios_base::goodbit; + try + { + const int_type __eof = traits_type::eof(); + __streambuf_type* __sb = this->rdbuf(); + int_type __c = __sb->sgetc(); +# 521 "/usr/include/c++/4.8.2/bits/istream.tcc" 3 + bool __large_ignore = false; + while (true) + { + while (_M_gcount < __n + && !traits_type::eq_int_type(__c, __eof)) + { + ++_M_gcount; + __c = __sb->snextc(); + } + if (__n == __gnu_cxx::__numeric_traits::__max + && !traits_type::eq_int_type(__c, __eof)) + { + _M_gcount = + __gnu_cxx::__numeric_traits::__min; + __large_ignore = true; + } + else + break; + } + + if (__large_ignore) + _M_gcount = __gnu_cxx::__numeric_traits::__max; + + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + } + catch(__cxxabiv1::__forced_unwind&) + { + this->_M_setstate(ios_base::badbit); + throw; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + ignore(streamsize __n, int_type __delim) + { + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb && __n > 0) + { + ios_base::iostate __err = ios_base::goodbit; + try + { + const int_type __eof = traits_type::eof(); + __streambuf_type* __sb = this->rdbuf(); + int_type __c = __sb->sgetc(); + + + bool __large_ignore = false; + while (true) + { + while (_M_gcount < __n + && !traits_type::eq_int_type(__c, __eof) + && !traits_type::eq_int_type(__c, __delim)) + { + ++_M_gcount; + __c = __sb->snextc(); + } + if (__n == __gnu_cxx::__numeric_traits::__max + && !traits_type::eq_int_type(__c, __eof) + && !traits_type::eq_int_type(__c, __delim)) + { + _M_gcount = + __gnu_cxx::__numeric_traits::__min; + __large_ignore = true; + } + else + break; + } + + if (__large_ignore) + _M_gcount = __gnu_cxx::__numeric_traits::__max; + + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + else if (traits_type::eq_int_type(__c, __delim)) + { + if (_M_gcount + < __gnu_cxx::__numeric_traits::__max) + ++_M_gcount; + __sb->sbumpc(); + } + } + catch(__cxxabiv1::__forced_unwind&) + { + this->_M_setstate(ios_base::badbit); + throw; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + typename basic_istream<_CharT, _Traits>::int_type + basic_istream<_CharT, _Traits>:: + peek(void) + { + int_type __c = traits_type::eof(); + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb) + { + ios_base::iostate __err = ios_base::goodbit; + try + { + __c = this->rdbuf()->sgetc(); + if (traits_type::eq_int_type(__c, traits_type::eof())) + __err |= ios_base::eofbit; + } + catch(__cxxabiv1::__forced_unwind&) + { + this->_M_setstate(ios_base::badbit); + throw; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return __c; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + read(char_type* __s, streamsize __n) + { + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb) + { + ios_base::iostate __err = ios_base::goodbit; + try + { + _M_gcount = this->rdbuf()->sgetn(__s, __n); + if (_M_gcount != __n) + __err |= (ios_base::eofbit | ios_base::failbit); + } + catch(__cxxabiv1::__forced_unwind&) + { + this->_M_setstate(ios_base::badbit); + throw; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + streamsize + basic_istream<_CharT, _Traits>:: + readsome(char_type* __s, streamsize __n) + { + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb) + { + ios_base::iostate __err = ios_base::goodbit; + try + { + + const streamsize __num = this->rdbuf()->in_avail(); + if (__num > 0) + _M_gcount = this->rdbuf()->sgetn(__s, std::min(__num, __n)); + else if (__num == -1) + __err |= ios_base::eofbit; + } + catch(__cxxabiv1::__forced_unwind&) + { + this->_M_setstate(ios_base::badbit); + throw; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return _M_gcount; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + putback(char_type __c) + { + + + _M_gcount = 0; + + this->clear(this->rdstate() & ~ios_base::eofbit); + sentry __cerb(*this, true); + if (__cerb) + { + ios_base::iostate __err = ios_base::goodbit; + try + { + const int_type __eof = traits_type::eof(); + __streambuf_type* __sb = this->rdbuf(); + if (!__sb + || traits_type::eq_int_type(__sb->sputbackc(__c), __eof)) + __err |= ios_base::badbit; + } + catch(__cxxabiv1::__forced_unwind&) + { + this->_M_setstate(ios_base::badbit); + throw; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + unget(void) + { + + + _M_gcount = 0; + + this->clear(this->rdstate() & ~ios_base::eofbit); + sentry __cerb(*this, true); + if (__cerb) + { + ios_base::iostate __err = ios_base::goodbit; + try + { + const int_type __eof = traits_type::eof(); + __streambuf_type* __sb = this->rdbuf(); + if (!__sb + || traits_type::eq_int_type(__sb->sungetc(), __eof)) + __err |= ios_base::badbit; + } + catch(__cxxabiv1::__forced_unwind&) + { + this->_M_setstate(ios_base::badbit); + throw; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + int + basic_istream<_CharT, _Traits>:: + sync(void) + { + + + int __ret = -1; + sentry __cerb(*this, true); + if (__cerb) + { + ios_base::iostate __err = ios_base::goodbit; + try + { + __streambuf_type* __sb = this->rdbuf(); + if (__sb) + { + if (__sb->pubsync() == -1) + __err |= ios_base::badbit; + else + __ret = 0; + } + } + catch(__cxxabiv1::__forced_unwind&) + { + this->_M_setstate(ios_base::badbit); + throw; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return __ret; + } + + template + typename basic_istream<_CharT, _Traits>::pos_type + basic_istream<_CharT, _Traits>:: + tellg(void) + { + + + pos_type __ret = pos_type(-1); + sentry __cerb(*this, true); + if (__cerb) + { + try + { + if (!this->fail()) + __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, + ios_base::in); + } + catch(__cxxabiv1::__forced_unwind&) + { + this->_M_setstate(ios_base::badbit); + throw; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + } + return __ret; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + seekg(pos_type __pos) + { + + + + this->clear(this->rdstate() & ~ios_base::eofbit); + sentry __cerb(*this, true); + if (__cerb) + { + ios_base::iostate __err = ios_base::goodbit; + try + { + if (!this->fail()) + { + + const pos_type __p = this->rdbuf()->pubseekpos(__pos, + ios_base::in); + + + if (__p == pos_type(off_type(-1))) + __err |= ios_base::failbit; + } + } + catch(__cxxabiv1::__forced_unwind&) + { + this->_M_setstate(ios_base::badbit); + throw; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + seekg(off_type __off, ios_base::seekdir __dir) + { + + + + this->clear(this->rdstate() & ~ios_base::eofbit); + sentry __cerb(*this, true); + if (__cerb) + { + ios_base::iostate __err = ios_base::goodbit; + try + { + if (!this->fail()) + { + + const pos_type __p = this->rdbuf()->pubseekoff(__off, __dir, + ios_base::in); + + + if (__p == pos_type(off_type(-1))) + __err |= ios_base::failbit; + } + } + catch(__cxxabiv1::__forced_unwind&) + { + this->_M_setstate(ios_base::badbit); + throw; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + + template + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __in, _CharT& __c) + { + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::int_type __int_type; + + typename __istream_type::sentry __cerb(__in, false); + if (__cerb) + { + ios_base::iostate __err = ios_base::goodbit; + try + { + const __int_type __cb = __in.rdbuf()->sbumpc(); + if (!_Traits::eq_int_type(__cb, _Traits::eof())) + __c = _Traits::to_char_type(__cb); + else + __err |= (ios_base::eofbit | ios_base::failbit); + } + catch(__cxxabiv1::__forced_unwind&) + { + __in._M_setstate(ios_base::badbit); + throw; + } + catch(...) + { __in._M_setstate(ios_base::badbit); } + if (__err) + __in.setstate(__err); + } + return __in; + } + + template + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __in, _CharT* __s) + { + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef basic_streambuf<_CharT, _Traits> __streambuf_type; + typedef typename _Traits::int_type int_type; + typedef _CharT char_type; + typedef ctype<_CharT> __ctype_type; + + streamsize __extracted = 0; + ios_base::iostate __err = ios_base::goodbit; + typename __istream_type::sentry __cerb(__in, false); + if (__cerb) + { + try + { + + streamsize __num = __in.width(); + if (__num <= 0) + __num = __gnu_cxx::__numeric_traits::__max; + + const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); + + const int_type __eof = _Traits::eof(); + __streambuf_type* __sb = __in.rdbuf(); + int_type __c = __sb->sgetc(); + + while (__extracted < __num - 1 + && !_Traits::eq_int_type(__c, __eof) + && !__ct.is(ctype_base::space, + _Traits::to_char_type(__c))) + { + *__s++ = _Traits::to_char_type(__c); + ++__extracted; + __c = __sb->snextc(); + } + if (_Traits::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + + + + *__s = char_type(); + __in.width(0); + } + catch(__cxxabiv1::__forced_unwind&) + { + __in._M_setstate(ios_base::badbit); + throw; + } + catch(...) + { __in._M_setstate(ios_base::badbit); } + } + if (!__extracted) + __err |= ios_base::failbit; + if (__err) + __in.setstate(__err); + return __in; + } + + + template + basic_istream<_CharT, _Traits>& + ws(basic_istream<_CharT, _Traits>& __in) + { + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef basic_streambuf<_CharT, _Traits> __streambuf_type; + typedef typename __istream_type::int_type __int_type; + typedef ctype<_CharT> __ctype_type; + + const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); + const __int_type __eof = _Traits::eof(); + __streambuf_type* __sb = __in.rdbuf(); + __int_type __c = __sb->sgetc(); + + while (!_Traits::eq_int_type(__c, __eof) + && __ct.is(ctype_base::space, _Traits::to_char_type(__c))) + __c = __sb->snextc(); + + if (_Traits::eq_int_type(__c, __eof)) + __in.setstate(ios_base::eofbit); + return __in; + } + + + + + extern template class basic_istream; + extern template istream& ws(istream&); + extern template istream& operator>>(istream&, char&); + extern template istream& operator>>(istream&, char*); + extern template istream& operator>>(istream&, unsigned char&); + extern template istream& operator>>(istream&, signed char&); + extern template istream& operator>>(istream&, unsigned char*); + extern template istream& operator>>(istream&, signed char*); + + extern template istream& istream::_M_extract(unsigned short&); + extern template istream& istream::_M_extract(unsigned int&); + extern template istream& istream::_M_extract(long&); + extern template istream& istream::_M_extract(unsigned long&); + extern template istream& istream::_M_extract(bool&); + + extern template istream& istream::_M_extract(long long&); + extern template istream& istream::_M_extract(unsigned long long&); + + extern template istream& istream::_M_extract(float&); + extern template istream& istream::_M_extract(double&); + extern template istream& istream::_M_extract(long double&); + extern template istream& istream::_M_extract(void*&); + + extern template class basic_iostream; + + + extern template class basic_istream; + extern template wistream& ws(wistream&); + extern template wistream& operator>>(wistream&, wchar_t&); + extern template wistream& operator>>(wistream&, wchar_t*); + + extern template wistream& wistream::_M_extract(unsigned short&); + extern template wistream& wistream::_M_extract(unsigned int&); + extern template wistream& wistream::_M_extract(long&); + extern template wistream& wistream::_M_extract(unsigned long&); + extern template wistream& wistream::_M_extract(bool&); + + extern template wistream& wistream::_M_extract(long long&); + extern template wistream& wistream::_M_extract(unsigned long long&); + + extern template wistream& wistream::_M_extract(float&); + extern template wistream& wistream::_M_extract(double&); + extern template wistream& wistream::_M_extract(long double&); + extern template wistream& wistream::_M_extract(void*&); + + extern template class basic_iostream; + + + + +} +# 883 "/usr/include/c++/4.8.2/istream" 2 3 +# 41 "/usr/include/c++/4.8.2/iostream" 2 3 + +namespace std __attribute__ ((__visibility__ ("default"))) +{ + +# 60 "/usr/include/c++/4.8.2/iostream" 3 + extern istream cin; + extern ostream cout; + extern ostream cerr; + extern ostream clog; + + + extern wistream wcin; + extern wostream wcout; + extern wostream wcerr; + extern wostream wclog; + + + + + static ios_base::Init __ioinit; + + +} +# 9 "test.cpp" 2 +# 1 "include/CMessageQueue.h" 1 +# 10 "include/CMessageQueue.h" +# 1 "include/CTypedef.h" 1 +# 10 "include/CTypedef.h" +# 1 "/usr/include/c++/4.8.2/map" 1 3 +# 58 "/usr/include/c++/4.8.2/map" 3 + +# 59 "/usr/include/c++/4.8.2/map" 3 + +# 1 "/usr/include/c++/4.8.2/bits/stl_tree.h" 1 3 +# 69 "/usr/include/c++/4.8.2/bits/stl_tree.h" 3 +namespace std __attribute__ ((__visibility__ ("default"))) +{ + +# 89 "/usr/include/c++/4.8.2/bits/stl_tree.h" 3 + enum _Rb_tree_color { _S_red = false, _S_black = true }; + + struct _Rb_tree_node_base + { + typedef _Rb_tree_node_base* _Base_ptr; + typedef const _Rb_tree_node_base* _Const_Base_ptr; + + _Rb_tree_color _M_color; + _Base_ptr _M_parent; + _Base_ptr _M_left; + _Base_ptr _M_right; + + static _Base_ptr + _S_minimum(_Base_ptr __x) + { + while (__x->_M_left != 0) __x = __x->_M_left; + return __x; + } + + static _Const_Base_ptr + _S_minimum(_Const_Base_ptr __x) + { + while (__x->_M_left != 0) __x = __x->_M_left; + return __x; + } + + static _Base_ptr + _S_maximum(_Base_ptr __x) + { + while (__x->_M_right != 0) __x = __x->_M_right; + return __x; + } + + static _Const_Base_ptr + _S_maximum(_Const_Base_ptr __x) + { + while (__x->_M_right != 0) __x = __x->_M_right; + return __x; + } + }; + + template + struct _Rb_tree_node : public _Rb_tree_node_base + { + typedef _Rb_tree_node<_Val>* _Link_type; + _Val _M_value_field; + + + + + + + + }; + + __attribute__ ((__pure__)) _Rb_tree_node_base* + _Rb_tree_increment(_Rb_tree_node_base* __x) throw (); + + __attribute__ ((__pure__)) const _Rb_tree_node_base* + _Rb_tree_increment(const _Rb_tree_node_base* __x) throw (); + + __attribute__ ((__pure__)) _Rb_tree_node_base* + _Rb_tree_decrement(_Rb_tree_node_base* __x) throw (); + + __attribute__ ((__pure__)) const _Rb_tree_node_base* + _Rb_tree_decrement(const _Rb_tree_node_base* __x) throw (); + + template + struct _Rb_tree_iterator + { + typedef _Tp value_type; + typedef _Tp& reference; + typedef _Tp* pointer; + + typedef bidirectional_iterator_tag iterator_category; + typedef ptrdiff_t difference_type; + + typedef _Rb_tree_iterator<_Tp> _Self; + typedef _Rb_tree_node_base::_Base_ptr _Base_ptr; + typedef _Rb_tree_node<_Tp>* _Link_type; + + _Rb_tree_iterator() + : _M_node() { } + + explicit + _Rb_tree_iterator(_Link_type __x) + : _M_node(__x) { } + + reference + operator*() const + { return static_cast<_Link_type>(_M_node)->_M_value_field; } + + pointer + operator->() const + { return std::__addressof(static_cast<_Link_type> + (_M_node)->_M_value_field); } + + _Self& + operator++() + { + _M_node = _Rb_tree_increment(_M_node); + return *this; + } + + _Self + operator++(int) + { + _Self __tmp = *this; + _M_node = _Rb_tree_increment(_M_node); + return __tmp; + } + + _Self& + operator--() + { + _M_node = _Rb_tree_decrement(_M_node); + return *this; + } + + _Self + operator--(int) + { + _Self __tmp = *this; + _M_node = _Rb_tree_decrement(_M_node); + return __tmp; + } + + bool + operator==(const _Self& __x) const + { return _M_node == __x._M_node; } + + bool + operator!=(const _Self& __x) const + { return _M_node != __x._M_node; } + + _Base_ptr _M_node; + }; + + template + struct _Rb_tree_const_iterator + { + typedef _Tp value_type; + typedef const _Tp& reference; + typedef const _Tp* pointer; + + typedef _Rb_tree_iterator<_Tp> iterator; + + typedef bidirectional_iterator_tag iterator_category; + typedef ptrdiff_t difference_type; + + typedef _Rb_tree_const_iterator<_Tp> _Self; + typedef _Rb_tree_node_base::_Const_Base_ptr _Base_ptr; + typedef const _Rb_tree_node<_Tp>* _Link_type; + + _Rb_tree_const_iterator() + : _M_node() { } + + explicit + _Rb_tree_const_iterator(_Link_type __x) + : _M_node(__x) { } + + _Rb_tree_const_iterator(const iterator& __it) + : _M_node(__it._M_node) { } + + iterator + _M_const_cast() const + { return iterator(static_cast + (const_cast(_M_node))); } + + reference + operator*() const + { return static_cast<_Link_type>(_M_node)->_M_value_field; } + + pointer + operator->() const + { return std::__addressof(static_cast<_Link_type> + (_M_node)->_M_value_field); } + + _Self& + operator++() + { + _M_node = _Rb_tree_increment(_M_node); + return *this; + } + + _Self + operator++(int) + { + _Self __tmp = *this; + _M_node = _Rb_tree_increment(_M_node); + return __tmp; + } + + _Self& + operator--() + { + _M_node = _Rb_tree_decrement(_M_node); + return *this; + } + + _Self + operator--(int) + { + _Self __tmp = *this; + _M_node = _Rb_tree_decrement(_M_node); + return __tmp; + } + + bool + operator==(const _Self& __x) const + { return _M_node == __x._M_node; } + + bool + operator!=(const _Self& __x) const + { return _M_node != __x._M_node; } + + _Base_ptr _M_node; + }; + + template + inline bool + operator==(const _Rb_tree_iterator<_Val>& __x, + const _Rb_tree_const_iterator<_Val>& __y) + { return __x._M_node == __y._M_node; } + + template + inline bool + operator!=(const _Rb_tree_iterator<_Val>& __x, + const _Rb_tree_const_iterator<_Val>& __y) + { return __x._M_node != __y._M_node; } + + void + _Rb_tree_insert_and_rebalance(const bool __insert_left, + _Rb_tree_node_base* __x, + _Rb_tree_node_base* __p, + _Rb_tree_node_base& __header) throw (); + + _Rb_tree_node_base* + _Rb_tree_rebalance_for_erase(_Rb_tree_node_base* const __z, + _Rb_tree_node_base& __header) throw (); + + + template > + class _Rb_tree + { + typedef typename _Alloc::template rebind<_Rb_tree_node<_Val> >::other + _Node_allocator; + + protected: + typedef _Rb_tree_node_base* _Base_ptr; + typedef const _Rb_tree_node_base* _Const_Base_ptr; + + public: + typedef _Key key_type; + typedef _Val value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef _Rb_tree_node<_Val>* _Link_type; + typedef const _Rb_tree_node<_Val>* _Const_Link_type; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Alloc allocator_type; + + _Node_allocator& + _M_get_Node_allocator() + { return *static_cast<_Node_allocator*>(&this->_M_impl); } + + const _Node_allocator& + _M_get_Node_allocator() const + { return *static_cast(&this->_M_impl); } + + allocator_type + get_allocator() const + { return allocator_type(_M_get_Node_allocator()); } + + protected: + _Link_type + _M_get_node() + { return _M_impl._Node_allocator::allocate(1); } + + void + _M_put_node(_Link_type __p) + { _M_impl._Node_allocator::deallocate(__p, 1); } + + + _Link_type + _M_create_node(const value_type& __x) + { + _Link_type __tmp = _M_get_node(); + try + { get_allocator().construct + (std::__addressof(__tmp->_M_value_field), __x); } + catch(...) + { + _M_put_node(__tmp); + throw; + } + return __tmp; + } + + void + _M_destroy_node(_Link_type __p) + { + get_allocator().destroy(std::__addressof(__p->_M_value_field)); + _M_put_node(__p); + } +# 426 "/usr/include/c++/4.8.2/bits/stl_tree.h" 3 + _Link_type + _M_clone_node(_Const_Link_type __x) + { + _Link_type __tmp = _M_create_node(__x->_M_value_field); + __tmp->_M_color = __x->_M_color; + __tmp->_M_left = 0; + __tmp->_M_right = 0; + return __tmp; + } + + protected: + template + struct _Rb_tree_impl : public _Node_allocator + { + _Key_compare _M_key_compare; + _Rb_tree_node_base _M_header; + size_type _M_node_count; + + _Rb_tree_impl() + : _Node_allocator(), _M_key_compare(), _M_header(), + _M_node_count(0) + { _M_initialize(); } + + _Rb_tree_impl(const _Key_compare& __comp, const _Node_allocator& __a) + : _Node_allocator(__a), _M_key_compare(__comp), _M_header(), + _M_node_count(0) + { _M_initialize(); } +# 462 "/usr/include/c++/4.8.2/bits/stl_tree.h" 3 + private: + void + _M_initialize() + { + this->_M_header._M_color = _S_red; + this->_M_header._M_parent = 0; + this->_M_header._M_left = &this->_M_header; + this->_M_header._M_right = &this->_M_header; + } + }; + + _Rb_tree_impl<_Compare> _M_impl; + + protected: + _Base_ptr& + _M_root() + { return this->_M_impl._M_header._M_parent; } + + _Const_Base_ptr + _M_root() const + { return this->_M_impl._M_header._M_parent; } + + _Base_ptr& + _M_leftmost() + { return this->_M_impl._M_header._M_left; } + + _Const_Base_ptr + _M_leftmost() const + { return this->_M_impl._M_header._M_left; } + + _Base_ptr& + _M_rightmost() + { return this->_M_impl._M_header._M_right; } + + _Const_Base_ptr + _M_rightmost() const + { return this->_M_impl._M_header._M_right; } + + _Link_type + _M_begin() + { return static_cast<_Link_type>(this->_M_impl._M_header._M_parent); } + + _Const_Link_type + _M_begin() const + { + return static_cast<_Const_Link_type> + (this->_M_impl._M_header._M_parent); + } + + _Link_type + _M_end() + { return reinterpret_cast<_Link_type>(&this->_M_impl._M_header); } + + _Const_Link_type + _M_end() const + { return reinterpret_cast<_Const_Link_type>(&this->_M_impl._M_header); } + + static const_reference + _S_value(_Const_Link_type __x) + { return __x->_M_value_field; } + + static const _Key& + _S_key(_Const_Link_type __x) + { return _KeyOfValue()(_S_value(__x)); } + + static _Link_type + _S_left(_Base_ptr __x) + { return static_cast<_Link_type>(__x->_M_left); } + + static _Const_Link_type + _S_left(_Const_Base_ptr __x) + { return static_cast<_Const_Link_type>(__x->_M_left); } + + static _Link_type + _S_right(_Base_ptr __x) + { return static_cast<_Link_type>(__x->_M_right); } + + static _Const_Link_type + _S_right(_Const_Base_ptr __x) + { return static_cast<_Const_Link_type>(__x->_M_right); } + + static const_reference + _S_value(_Const_Base_ptr __x) + { return static_cast<_Const_Link_type>(__x)->_M_value_field; } + + static const _Key& + _S_key(_Const_Base_ptr __x) + { return _KeyOfValue()(_S_value(__x)); } + + static _Base_ptr + _S_minimum(_Base_ptr __x) + { return _Rb_tree_node_base::_S_minimum(__x); } + + static _Const_Base_ptr + _S_minimum(_Const_Base_ptr __x) + { return _Rb_tree_node_base::_S_minimum(__x); } + + static _Base_ptr + _S_maximum(_Base_ptr __x) + { return _Rb_tree_node_base::_S_maximum(__x); } + + static _Const_Base_ptr + _S_maximum(_Const_Base_ptr __x) + { return _Rb_tree_node_base::_S_maximum(__x); } + + public: + typedef _Rb_tree_iterator iterator; + typedef _Rb_tree_const_iterator const_iterator; + + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + private: + pair<_Base_ptr, _Base_ptr> + _M_get_insert_unique_pos(const key_type& __k); + + pair<_Base_ptr, _Base_ptr> + _M_get_insert_equal_pos(const key_type& __k); + + pair<_Base_ptr, _Base_ptr> + _M_get_insert_hint_unique_pos(const_iterator __pos, + const key_type& __k); + + pair<_Base_ptr, _Base_ptr> + _M_get_insert_hint_equal_pos(const_iterator __pos, + const key_type& __k); +# 611 "/usr/include/c++/4.8.2/bits/stl_tree.h" 3 + iterator + _M_insert_(_Base_ptr __x, _Base_ptr __y, + const value_type& __v); + + + + iterator + _M_insert_lower(_Base_ptr __y, const value_type& __v); + + iterator + _M_insert_equal_lower(const value_type& __x); + + + _Link_type + _M_copy(_Const_Link_type __x, _Link_type __p); + + void + _M_erase(_Link_type __x); + + iterator + _M_lower_bound(_Link_type __x, _Link_type __y, + const _Key& __k); + + const_iterator + _M_lower_bound(_Const_Link_type __x, _Const_Link_type __y, + const _Key& __k) const; + + iterator + _M_upper_bound(_Link_type __x, _Link_type __y, + const _Key& __k); + + const_iterator + _M_upper_bound(_Const_Link_type __x, _Const_Link_type __y, + const _Key& __k) const; + + public: + + _Rb_tree() { } + + _Rb_tree(const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_impl(__comp, _Node_allocator(__a)) { } + + _Rb_tree(const _Rb_tree& __x) + : _M_impl(__x._M_impl._M_key_compare, __x._M_get_Node_allocator()) + { + if (__x._M_root() != 0) + { + _M_root() = _M_copy(__x._M_begin(), _M_end()); + _M_leftmost() = _S_minimum(_M_root()); + _M_rightmost() = _S_maximum(_M_root()); + _M_impl._M_node_count = __x._M_impl._M_node_count; + } + } + + + + + + ~_Rb_tree() + { _M_erase(_M_begin()); } + + _Rb_tree& + operator=(const _Rb_tree& __x); + + + _Compare + key_comp() const + { return _M_impl._M_key_compare; } + + iterator + begin() + { + return iterator(static_cast<_Link_type> + (this->_M_impl._M_header._M_left)); + } + + const_iterator + begin() const + { + return const_iterator(static_cast<_Const_Link_type> + (this->_M_impl._M_header._M_left)); + } + + iterator + end() + { return iterator(static_cast<_Link_type>(&this->_M_impl._M_header)); } + + const_iterator + end() const + { + return const_iterator(static_cast<_Const_Link_type> + (&this->_M_impl._M_header)); + } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + bool + empty() const + { return _M_impl._M_node_count == 0; } + + size_type + size() const + { return _M_impl._M_node_count; } + + size_type + max_size() const + { return _M_get_Node_allocator().max_size(); } + + void + swap(_Rb_tree& __t); +# 771 "/usr/include/c++/4.8.2/bits/stl_tree.h" 3 + pair + _M_insert_unique(const value_type& __x); + + iterator + _M_insert_equal(const value_type& __x); + + iterator + _M_insert_unique_(const_iterator __position, const value_type& __x); + + iterator + _M_insert_equal_(const_iterator __position, const value_type& __x); + + + template + void + _M_insert_unique(_InputIterator __first, _InputIterator __last); + + template + void + _M_insert_equal(_InputIterator __first, _InputIterator __last); + + private: + void + _M_erase_aux(const_iterator __position); + + void + _M_erase_aux(const_iterator __first, const_iterator __last); + + public: +# 824 "/usr/include/c++/4.8.2/bits/stl_tree.h" 3 + void + erase(iterator __position) + { _M_erase_aux(__position); } + + void + erase(const_iterator __position) + { _M_erase_aux(__position); } + + size_type + erase(const key_type& __x); +# 846 "/usr/include/c++/4.8.2/bits/stl_tree.h" 3 + void + erase(iterator __first, iterator __last) + { _M_erase_aux(__first, __last); } + + void + erase(const_iterator __first, const_iterator __last) + { _M_erase_aux(__first, __last); } + + void + erase(const key_type* __first, const key_type* __last); + + void + clear() + { + _M_erase(_M_begin()); + _M_leftmost() = _M_end(); + _M_root() = 0; + _M_rightmost() = _M_end(); + _M_impl._M_node_count = 0; + } + + + iterator + find(const key_type& __k); + + const_iterator + find(const key_type& __k) const; + + size_type + count(const key_type& __k) const; + + iterator + lower_bound(const key_type& __k) + { return _M_lower_bound(_M_begin(), _M_end(), __k); } + + const_iterator + lower_bound(const key_type& __k) const + { return _M_lower_bound(_M_begin(), _M_end(), __k); } + + iterator + upper_bound(const key_type& __k) + { return _M_upper_bound(_M_begin(), _M_end(), __k); } + + const_iterator + upper_bound(const key_type& __k) const + { return _M_upper_bound(_M_begin(), _M_end(), __k); } + + pair + equal_range(const key_type& __k); + + pair + equal_range(const key_type& __k) const; + + + bool + __rb_verify() const; + }; + + template + inline bool + operator==(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x, + const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y) + { + return __x.size() == __y.size() + && std::equal(__x.begin(), __x.end(), __y.begin()); + } + + template + inline bool + operator<(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x, + const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y) + { + return std::lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); + } + + template + inline bool + operator!=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x, + const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y) + { return !(__x == __y); } + + template + inline bool + operator>(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x, + const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y) + { return __y < __x; } + + template + inline bool + operator<=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x, + const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y) + { return !(__y < __x); } + + template + inline bool + operator>=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x, + const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y) + { return !(__x < __y); } + + template + inline void + swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x, + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y) + { __x.swap(__y); } +# 984 "/usr/include/c++/4.8.2/bits/stl_tree.h" 3 + template + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + operator=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x) + { + if (this != &__x) + { + + clear(); + _M_impl._M_key_compare = __x._M_impl._M_key_compare; + if (__x._M_root() != 0) + { + _M_root() = _M_copy(__x._M_begin(), _M_end()); + _M_leftmost() = _S_minimum(_M_root()); + _M_rightmost() = _S_maximum(_M_root()); + _M_impl._M_node_count = __x._M_impl._M_node_count; + } + } + return *this; + } + + template + + + + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + + + + _M_insert_(_Base_ptr __x, _Base_ptr __p, const _Val& __v) + + { + bool __insert_left = (__x != 0 || __p == _M_end() + || _M_impl._M_key_compare(_KeyOfValue()(__v), + _S_key(__p))); + + _Link_type __z = _M_create_node((__v)); + + _Rb_tree_insert_and_rebalance(__insert_left, __z, __p, + this->_M_impl._M_header); + ++_M_impl._M_node_count; + return iterator(__z); + } + + template + + + + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + + + + _M_insert_lower(_Base_ptr __p, const _Val& __v) + + { + bool __insert_left = (__p == _M_end() + || !_M_impl._M_key_compare(_S_key(__p), + _KeyOfValue()(__v))); + + _Link_type __z = _M_create_node((__v)); + + _Rb_tree_insert_and_rebalance(__insert_left, __z, __p, + this->_M_impl._M_header); + ++_M_impl._M_node_count; + return iterator(__z); + } + + template + + + + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + + + + _M_insert_equal_lower(const _Val& __v) + + { + _Link_type __x = _M_begin(); + _Link_type __y = _M_end(); + while (__x != 0) + { + __y = __x; + __x = !_M_impl._M_key_compare(_S_key(__x), _KeyOfValue()(__v)) ? + _S_left(__x) : _S_right(__x); + } + return _M_insert_lower(__y, (__v)); + } + + template + typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::_Link_type + _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>:: + _M_copy(_Const_Link_type __x, _Link_type __p) + { + + _Link_type __top = _M_clone_node(__x); + __top->_M_parent = __p; + + try + { + if (__x->_M_right) + __top->_M_right = _M_copy(_S_right(__x), __top); + __p = __top; + __x = _S_left(__x); + + while (__x != 0) + { + _Link_type __y = _M_clone_node(__x); + __p->_M_left = __y; + __y->_M_parent = __p; + if (__x->_M_right) + __y->_M_right = _M_copy(_S_right(__x), __y); + __p = __y; + __x = _S_left(__x); + } + } + catch(...) + { + _M_erase(__top); + throw; + } + return __top; + } + + template + void + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + _M_erase(_Link_type __x) + { + + while (__x != 0) + { + _M_erase(_S_right(__x)); + _Link_type __y = _S_left(__x); + _M_destroy_node(__x); + __x = __y; + } + } + + template + typename _Rb_tree<_Key, _Val, _KeyOfValue, + _Compare, _Alloc>::iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + _M_lower_bound(_Link_type __x, _Link_type __y, + const _Key& __k) + { + while (__x != 0) + if (!_M_impl._M_key_compare(_S_key(__x), __k)) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + return iterator(__y); + } + + template + typename _Rb_tree<_Key, _Val, _KeyOfValue, + _Compare, _Alloc>::const_iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + _M_lower_bound(_Const_Link_type __x, _Const_Link_type __y, + const _Key& __k) const + { + while (__x != 0) + if (!_M_impl._M_key_compare(_S_key(__x), __k)) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + return const_iterator(__y); + } + + template + typename _Rb_tree<_Key, _Val, _KeyOfValue, + _Compare, _Alloc>::iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + _M_upper_bound(_Link_type __x, _Link_type __y, + const _Key& __k) + { + while (__x != 0) + if (_M_impl._M_key_compare(__k, _S_key(__x))) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + return iterator(__y); + } + + template + typename _Rb_tree<_Key, _Val, _KeyOfValue, + _Compare, _Alloc>::const_iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + _M_upper_bound(_Const_Link_type __x, _Const_Link_type __y, + const _Key& __k) const + { + while (__x != 0) + if (_M_impl._M_key_compare(__k, _S_key(__x))) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + return const_iterator(__y); + } + + template + pair::iterator, + typename _Rb_tree<_Key, _Val, _KeyOfValue, + _Compare, _Alloc>::iterator> + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + equal_range(const _Key& __k) + { + _Link_type __x = _M_begin(); + _Link_type __y = _M_end(); + while (__x != 0) + { + if (_M_impl._M_key_compare(_S_key(__x), __k)) + __x = _S_right(__x); + else if (_M_impl._M_key_compare(__k, _S_key(__x))) + __y = __x, __x = _S_left(__x); + else + { + _Link_type __xu(__x), __yu(__y); + __y = __x, __x = _S_left(__x); + __xu = _S_right(__xu); + return pair(_M_lower_bound(__x, __y, __k), + _M_upper_bound(__xu, __yu, __k)); + } + } + return pair(iterator(__y), + iterator(__y)); + } + + template + pair::const_iterator, + typename _Rb_tree<_Key, _Val, _KeyOfValue, + _Compare, _Alloc>::const_iterator> + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + equal_range(const _Key& __k) const + { + _Const_Link_type __x = _M_begin(); + _Const_Link_type __y = _M_end(); + while (__x != 0) + { + if (_M_impl._M_key_compare(_S_key(__x), __k)) + __x = _S_right(__x); + else if (_M_impl._M_key_compare(__k, _S_key(__x))) + __y = __x, __x = _S_left(__x); + else + { + _Const_Link_type __xu(__x), __yu(__y); + __y = __x, __x = _S_left(__x); + __xu = _S_right(__xu); + return pair(_M_lower_bound(__x, __y, __k), + _M_upper_bound(__xu, __yu, __k)); + } + } + return pair(const_iterator(__y), + const_iterator(__y)); + } + + template + void + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __t) + { + if (_M_root() == 0) + { + if (__t._M_root() != 0) + { + _M_root() = __t._M_root(); + _M_leftmost() = __t._M_leftmost(); + _M_rightmost() = __t._M_rightmost(); + _M_root()->_M_parent = _M_end(); + + __t._M_root() = 0; + __t._M_leftmost() = __t._M_end(); + __t._M_rightmost() = __t._M_end(); + } + } + else if (__t._M_root() == 0) + { + __t._M_root() = _M_root(); + __t._M_leftmost() = _M_leftmost(); + __t._M_rightmost() = _M_rightmost(); + __t._M_root()->_M_parent = __t._M_end(); + + _M_root() = 0; + _M_leftmost() = _M_end(); + _M_rightmost() = _M_end(); + } + else + { + std::swap(_M_root(),__t._M_root()); + std::swap(_M_leftmost(),__t._M_leftmost()); + std::swap(_M_rightmost(),__t._M_rightmost()); + + _M_root()->_M_parent = _M_end(); + __t._M_root()->_M_parent = __t._M_end(); + } + + std::swap(this->_M_impl._M_node_count, __t._M_impl._M_node_count); + std::swap(this->_M_impl._M_key_compare, __t._M_impl._M_key_compare); + + + + std::__alloc_swap<_Node_allocator>:: + _S_do_it(_M_get_Node_allocator(), __t._M_get_Node_allocator()); + } + + template + pair::_Base_ptr, + typename _Rb_tree<_Key, _Val, _KeyOfValue, + _Compare, _Alloc>::_Base_ptr> + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + _M_get_insert_unique_pos(const key_type& __k) + { + typedef pair<_Base_ptr, _Base_ptr> _Res; + _Link_type __x = _M_begin(); + _Link_type __y = _M_end(); + bool __comp = true; + while (__x != 0) + { + __y = __x; + __comp = _M_impl._M_key_compare(__k, _S_key(__x)); + __x = __comp ? _S_left(__x) : _S_right(__x); + } + iterator __j = iterator(__y); + if (__comp) + { + if (__j == begin()) + return _Res(__x, __y); + else + --__j; + } + if (_M_impl._M_key_compare(_S_key(__j._M_node), __k)) + return _Res(__x, __y); + return _Res(__j._M_node, 0); + } + + template + pair::_Base_ptr, + typename _Rb_tree<_Key, _Val, _KeyOfValue, + _Compare, _Alloc>::_Base_ptr> + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + _M_get_insert_equal_pos(const key_type& __k) + { + typedef pair<_Base_ptr, _Base_ptr> _Res; + _Link_type __x = _M_begin(); + _Link_type __y = _M_end(); + while (__x != 0) + { + __y = __x; + __x = _M_impl._M_key_compare(__k, _S_key(__x)) ? + _S_left(__x) : _S_right(__x); + } + return _Res(__x, __y); + } + + template + + + + pair::iterator, bool> + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + + + + _M_insert_unique(const _Val& __v) + + { + typedef pair _Res; + pair<_Base_ptr, _Base_ptr> __res + = _M_get_insert_unique_pos(_KeyOfValue()(__v)); + + if (__res.second) + return _Res(_M_insert_(__res.first, __res.second, + (__v)), + true); + + return _Res(iterator(static_cast<_Link_type>(__res.first)), false); + } + + template + + + + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + + + + _M_insert_equal(const _Val& __v) + + { + pair<_Base_ptr, _Base_ptr> __res + = _M_get_insert_equal_pos(_KeyOfValue()(__v)); + return _M_insert_(__res.first, __res.second, (__v)); + } + + template + pair::_Base_ptr, + typename _Rb_tree<_Key, _Val, _KeyOfValue, + _Compare, _Alloc>::_Base_ptr> + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + _M_get_insert_hint_unique_pos(const_iterator __position, + const key_type& __k) + { + iterator __pos = __position._M_const_cast(); + typedef pair<_Base_ptr, _Base_ptr> _Res; + + + if (__pos._M_node == _M_end()) + { + if (size() > 0 + && _M_impl._M_key_compare(_S_key(_M_rightmost()), __k)) + return _Res(0, _M_rightmost()); + else + return _M_get_insert_unique_pos(__k); + } + else if (_M_impl._M_key_compare(__k, _S_key(__pos._M_node))) + { + + iterator __before = __pos; + if (__pos._M_node == _M_leftmost()) + return _Res(_M_leftmost(), _M_leftmost()); + else if (_M_impl._M_key_compare(_S_key((--__before)._M_node), __k)) + { + if (_S_right(__before._M_node) == 0) + return _Res(0, __before._M_node); + else + return _Res(__pos._M_node, __pos._M_node); + } + else + return _M_get_insert_unique_pos(__k); + } + else if (_M_impl._M_key_compare(_S_key(__pos._M_node), __k)) + { + + iterator __after = __pos; + if (__pos._M_node == _M_rightmost()) + return _Res(0, _M_rightmost()); + else if (_M_impl._M_key_compare(__k, _S_key((++__after)._M_node))) + { + if (_S_right(__pos._M_node) == 0) + return _Res(0, __pos._M_node); + else + return _Res(__after._M_node, __after._M_node); + } + else + return _M_get_insert_unique_pos(__k); + } + else + + return _Res(__pos._M_node, 0); + } + + template + + + + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + + + + _M_insert_unique_(const_iterator __position, const _Val& __v) + + { + pair<_Base_ptr, _Base_ptr> __res + = _M_get_insert_hint_unique_pos(__position, _KeyOfValue()(__v)); + + if (__res.second) + return _M_insert_(__res.first, __res.second, + (__v)); + return iterator(static_cast<_Link_type>(__res.first)); + } + + template + pair::_Base_ptr, + typename _Rb_tree<_Key, _Val, _KeyOfValue, + _Compare, _Alloc>::_Base_ptr> + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + _M_get_insert_hint_equal_pos(const_iterator __position, const key_type& __k) + { + iterator __pos = __position._M_const_cast(); + typedef pair<_Base_ptr, _Base_ptr> _Res; + + + if (__pos._M_node == _M_end()) + { + if (size() > 0 + && !_M_impl._M_key_compare(__k, _S_key(_M_rightmost()))) + return _Res(0, _M_rightmost()); + else + return _M_get_insert_equal_pos(__k); + } + else if (!_M_impl._M_key_compare(_S_key(__pos._M_node), __k)) + { + + iterator __before = __pos; + if (__pos._M_node == _M_leftmost()) + return _Res(_M_leftmost(), _M_leftmost()); + else if (!_M_impl._M_key_compare(__k, _S_key((--__before)._M_node))) + { + if (_S_right(__before._M_node) == 0) + return _Res(0, __before._M_node); + else + return _Res(__pos._M_node, __pos._M_node); + } + else + return _M_get_insert_equal_pos(__k); + } + else + { + + iterator __after = __pos; + if (__pos._M_node == _M_rightmost()) + return _Res(0, _M_rightmost()); + else if (!_M_impl._M_key_compare(_S_key((++__after)._M_node), __k)) + { + if (_S_right(__pos._M_node) == 0) + return _Res(0, __pos._M_node); + else + return _Res(__after._M_node, __after._M_node); + } + else + return _Res(0, 0); + } + } + + template + + + + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + + + + _M_insert_equal_(const_iterator __position, const _Val& __v) + + { + pair<_Base_ptr, _Base_ptr> __res + = _M_get_insert_hint_equal_pos(__position, _KeyOfValue()(__v)); + + if (__res.second) + return _M_insert_(__res.first, __res.second, + (__v)); + + return _M_insert_equal_lower((__v)); + } +# 1714 "/usr/include/c++/4.8.2/bits/stl_tree.h" 3 + template + template + void + _Rb_tree<_Key, _Val, _KoV, _Cmp, _Alloc>:: + _M_insert_unique(_II __first, _II __last) + { + for (; __first != __last; ++__first) + _M_insert_unique_(end(), *__first); + } + + template + template + void + _Rb_tree<_Key, _Val, _KoV, _Cmp, _Alloc>:: + _M_insert_equal(_II __first, _II __last) + { + for (; __first != __last; ++__first) + _M_insert_equal_(end(), *__first); + } + + template + void + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + _M_erase_aux(const_iterator __position) + { + _Link_type __y = + static_cast<_Link_type>(_Rb_tree_rebalance_for_erase + (const_cast<_Base_ptr>(__position._M_node), + this->_M_impl._M_header)); + _M_destroy_node(__y); + --_M_impl._M_node_count; + } + + template + void + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + _M_erase_aux(const_iterator __first, const_iterator __last) + { + if (__first == begin() && __last == end()) + clear(); + else + while (__first != __last) + erase(__first++); + } + + template + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + erase(const _Key& __x) + { + pair __p = equal_range(__x); + const size_type __old_size = size(); + erase(__p.first, __p.second); + return __old_size - size(); + } + + template + void + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + erase(const _Key* __first, const _Key* __last) + { + while (__first != __last) + erase(*__first++); + } + + template + typename _Rb_tree<_Key, _Val, _KeyOfValue, + _Compare, _Alloc>::iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + find(const _Key& __k) + { + iterator __j = _M_lower_bound(_M_begin(), _M_end(), __k); + return (__j == end() + || _M_impl._M_key_compare(__k, + _S_key(__j._M_node))) ? end() : __j; + } + + template + typename _Rb_tree<_Key, _Val, _KeyOfValue, + _Compare, _Alloc>::const_iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + find(const _Key& __k) const + { + const_iterator __j = _M_lower_bound(_M_begin(), _M_end(), __k); + return (__j == end() + || _M_impl._M_key_compare(__k, + _S_key(__j._M_node))) ? end() : __j; + } + + template + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + count(const _Key& __k) const + { + pair __p = equal_range(__k); + const size_type __n = std::distance(__p.first, __p.second); + return __n; + } + + __attribute__ ((__pure__)) unsigned int + _Rb_tree_black_count(const _Rb_tree_node_base* __node, + const _Rb_tree_node_base* __root) throw (); + + template + bool + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::__rb_verify() const + { + if (_M_impl._M_node_count == 0 || begin() == end()) + return _M_impl._M_node_count == 0 && begin() == end() + && this->_M_impl._M_header._M_left == _M_end() + && this->_M_impl._M_header._M_right == _M_end(); + + unsigned int __len = _Rb_tree_black_count(_M_leftmost(), _M_root()); + for (const_iterator __it = begin(); __it != end(); ++__it) + { + _Const_Link_type __x = static_cast<_Const_Link_type>(__it._M_node); + _Const_Link_type __L = _S_left(__x); + _Const_Link_type __R = _S_right(__x); + + if (__x->_M_color == _S_red) + if ((__L && __L->_M_color == _S_red) + || (__R && __R->_M_color == _S_red)) + return false; + + if (__L && _M_impl._M_key_compare(_S_key(__x), _S_key(__L))) + return false; + if (__R && _M_impl._M_key_compare(_S_key(__R), _S_key(__x))) + return false; + + if (!__L && !__R && _Rb_tree_black_count(__x, _M_root()) != __len) + return false; + } + + if (_M_leftmost() != _Rb_tree_node_base::_S_minimum(_M_root())) + return false; + if (_M_rightmost() != _Rb_tree_node_base::_S_maximum(_M_root())) + return false; + return true; + } + + +} +# 61 "/usr/include/c++/4.8.2/map" 2 3 +# 1 "/usr/include/c++/4.8.2/bits/stl_map.h" 1 3 +# 66 "/usr/include/c++/4.8.2/bits/stl_map.h" 3 +namespace std __attribute__ ((__visibility__ ("default"))) +{ + +# 94 "/usr/include/c++/4.8.2/bits/stl_map.h" 3 + template , + typename _Alloc = std::allocator > > + class map + { + public: + typedef _Key key_type; + typedef _Tp mapped_type; + typedef std::pair value_type; + typedef _Compare key_compare; + typedef _Alloc allocator_type; + + private: + + typedef typename _Alloc::value_type _Alloc_value_type; + + + + + + public: + class value_compare + : public std::binary_function + { + friend class map<_Key, _Tp, _Compare, _Alloc>; + protected: + _Compare comp; + + value_compare(_Compare __c) + : comp(__c) { } + + public: + bool operator()(const value_type& __x, const value_type& __y) const + { return comp(__x.first, __y.first); } + }; + + private: + + typedef typename _Alloc::template rebind::other + _Pair_alloc_type; + + typedef _Rb_tree, + key_compare, _Pair_alloc_type> _Rep_type; + + + _Rep_type _M_t; + + public: + + + typedef typename _Pair_alloc_type::pointer pointer; + typedef typename _Pair_alloc_type::const_pointer const_pointer; + typedef typename _Pair_alloc_type::reference reference; + typedef typename _Pair_alloc_type::const_reference const_reference; + typedef typename _Rep_type::iterator iterator; + typedef typename _Rep_type::const_iterator const_iterator; + typedef typename _Rep_type::size_type size_type; + typedef typename _Rep_type::difference_type difference_type; + typedef typename _Rep_type::reverse_iterator reverse_iterator; + typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; + + + + + + + + map() + : _M_t() { } + + + + + + + explicit + map(const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, _Pair_alloc_type(__a)) { } +# 180 "/usr/include/c++/4.8.2/bits/stl_map.h" 3 + map(const map& __x) + : _M_t(__x._M_t) { } +# 223 "/usr/include/c++/4.8.2/bits/stl_map.h" 3 + template + map(_InputIterator __first, _InputIterator __last) + : _M_t() + { _M_t._M_insert_unique(__first, __last); } +# 240 "/usr/include/c++/4.8.2/bits/stl_map.h" 3 + template + map(_InputIterator __first, _InputIterator __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, _Pair_alloc_type(__a)) + { _M_t._M_insert_unique(__first, __last); } +# 263 "/usr/include/c++/4.8.2/bits/stl_map.h" 3 + map& + operator=(const map& __x) + { + _M_t = __x._M_t; + return *this; + } +# 309 "/usr/include/c++/4.8.2/bits/stl_map.h" 3 + allocator_type + get_allocator() const + { return allocator_type(_M_t.get_allocator()); } + + + + + + + + iterator + begin() + { return _M_t.begin(); } + + + + + + + const_iterator + begin() const + { return _M_t.begin(); } + + + + + + + iterator + end() + { return _M_t.end(); } + + + + + + + const_iterator + end() const + { return _M_t.end(); } + + + + + + + reverse_iterator + rbegin() + { return _M_t.rbegin(); } + + + + + + + const_reverse_iterator + rbegin() const + { return _M_t.rbegin(); } + + + + + + + reverse_iterator + rend() + { return _M_t.rend(); } + + + + + + + const_reverse_iterator + rend() const + { return _M_t.rend(); } +# 428 "/usr/include/c++/4.8.2/bits/stl_map.h" 3 + bool + empty() const + { return _M_t.empty(); } + + + size_type + size() const + { return _M_t.size(); } + + + size_type + max_size() const + { return _M_t.max_size(); } +# 455 "/usr/include/c++/4.8.2/bits/stl_map.h" 3 + mapped_type& + operator[](const key_type& __k) + { + + + + iterator __i = lower_bound(__k); + + if (__i == end() || key_comp()(__k, (*__i).first)) + + + + + + __i = insert(__i, value_type(__k, mapped_type())); + + return (*__i).second; + } +# 500 "/usr/include/c++/4.8.2/bits/stl_map.h" 3 + mapped_type& + at(const key_type& __k) + { + iterator __i = lower_bound(__k); + if (__i == end() || key_comp()(__k, (*__i).first)) + __throw_out_of_range(("map::at")); + return (*__i).second; + } + + const mapped_type& + at(const key_type& __k) const + { + const_iterator __i = lower_bound(__k); + if (__i == end() || key_comp()(__k, (*__i).first)) + __throw_out_of_range(("map::at")); + return (*__i).second; + } +# 593 "/usr/include/c++/4.8.2/bits/stl_map.h" 3 + std::pair + insert(const value_type& __x) + { return _M_t._M_insert_unique(__x); } +# 642 "/usr/include/c++/4.8.2/bits/stl_map.h" 3 + iterator + + + + insert(iterator __position, const value_type& __x) + + { return _M_t._M_insert_unique_(__position, __x); } +# 668 "/usr/include/c++/4.8.2/bits/stl_map.h" 3 + template + void + insert(_InputIterator __first, _InputIterator __last) + { _M_t._M_insert_unique(__first, __last); } +# 709 "/usr/include/c++/4.8.2/bits/stl_map.h" 3 + void + erase(iterator __position) + { _M_t.erase(__position); } +# 725 "/usr/include/c++/4.8.2/bits/stl_map.h" 3 + size_type + erase(const key_type& __x) + { return _M_t.erase(__x); } +# 761 "/usr/include/c++/4.8.2/bits/stl_map.h" 3 + void + erase(iterator __first, iterator __last) + { _M_t.erase(__first, __last); } +# 777 "/usr/include/c++/4.8.2/bits/stl_map.h" 3 + void + swap(map& __x) + { _M_t.swap(__x._M_t); } + + + + + + + + void + clear() + { _M_t.clear(); } + + + + + + + key_compare + key_comp() const + { return _M_t.key_comp(); } + + + + + + value_compare + value_comp() const + { return value_compare(_M_t.key_comp()); } +# 820 "/usr/include/c++/4.8.2/bits/stl_map.h" 3 + iterator + find(const key_type& __x) + { return _M_t.find(__x); } +# 835 "/usr/include/c++/4.8.2/bits/stl_map.h" 3 + const_iterator + find(const key_type& __x) const + { return _M_t.find(__x); } +# 847 "/usr/include/c++/4.8.2/bits/stl_map.h" 3 + size_type + count(const key_type& __x) const + { return _M_t.find(__x) == _M_t.end() ? 0 : 1; } +# 862 "/usr/include/c++/4.8.2/bits/stl_map.h" 3 + iterator + lower_bound(const key_type& __x) + { return _M_t.lower_bound(__x); } +# 877 "/usr/include/c++/4.8.2/bits/stl_map.h" 3 + const_iterator + lower_bound(const key_type& __x) const + { return _M_t.lower_bound(__x); } + + + + + + + + iterator + upper_bound(const key_type& __x) + { return _M_t.upper_bound(__x); } + + + + + + + + const_iterator + upper_bound(const key_type& __x) const + { return _M_t.upper_bound(__x); } +# 916 "/usr/include/c++/4.8.2/bits/stl_map.h" 3 + std::pair + equal_range(const key_type& __x) + { return _M_t.equal_range(__x); } +# 935 "/usr/include/c++/4.8.2/bits/stl_map.h" 3 + std::pair + equal_range(const key_type& __x) const + { return _M_t.equal_range(__x); } + + template + friend bool + operator==(const map<_K1, _T1, _C1, _A1>&, + const map<_K1, _T1, _C1, _A1>&); + + template + friend bool + operator<(const map<_K1, _T1, _C1, _A1>&, + const map<_K1, _T1, _C1, _A1>&); + }; +# 960 "/usr/include/c++/4.8.2/bits/stl_map.h" 3 + template + inline bool + operator==(const map<_Key, _Tp, _Compare, _Alloc>& __x, + const map<_Key, _Tp, _Compare, _Alloc>& __y) + { return __x._M_t == __y._M_t; } +# 977 "/usr/include/c++/4.8.2/bits/stl_map.h" 3 + template + inline bool + operator<(const map<_Key, _Tp, _Compare, _Alloc>& __x, + const map<_Key, _Tp, _Compare, _Alloc>& __y) + { return __x._M_t < __y._M_t; } + + + template + inline bool + operator!=(const map<_Key, _Tp, _Compare, _Alloc>& __x, + const map<_Key, _Tp, _Compare, _Alloc>& __y) + { return !(__x == __y); } + + + template + inline bool + operator>(const map<_Key, _Tp, _Compare, _Alloc>& __x, + const map<_Key, _Tp, _Compare, _Alloc>& __y) + { return __y < __x; } + + + template + inline bool + operator<=(const map<_Key, _Tp, _Compare, _Alloc>& __x, + const map<_Key, _Tp, _Compare, _Alloc>& __y) + { return !(__y < __x); } + + + template + inline bool + operator>=(const map<_Key, _Tp, _Compare, _Alloc>& __x, + const map<_Key, _Tp, _Compare, _Alloc>& __y) + { return !(__x < __y); } + + + template + inline void + swap(map<_Key, _Tp, _Compare, _Alloc>& __x, + map<_Key, _Tp, _Compare, _Alloc>& __y) + { __x.swap(__y); } + + +} +# 62 "/usr/include/c++/4.8.2/map" 2 3 +# 1 "/usr/include/c++/4.8.2/bits/stl_multimap.h" 1 3 +# 64 "/usr/include/c++/4.8.2/bits/stl_multimap.h" 3 +namespace std __attribute__ ((__visibility__ ("default"))) +{ + +# 92 "/usr/include/c++/4.8.2/bits/stl_multimap.h" 3 + template , + typename _Alloc = std::allocator > > + class multimap + { + public: + typedef _Key key_type; + typedef _Tp mapped_type; + typedef std::pair value_type; + typedef _Compare key_compare; + typedef _Alloc allocator_type; + + private: + + typedef typename _Alloc::value_type _Alloc_value_type; + + + + + + public: + class value_compare + : public std::binary_function + { + friend class multimap<_Key, _Tp, _Compare, _Alloc>; + protected: + _Compare comp; + + value_compare(_Compare __c) + : comp(__c) { } + + public: + bool operator()(const value_type& __x, const value_type& __y) const + { return comp(__x.first, __y.first); } + }; + + private: + + typedef typename _Alloc::template rebind::other + _Pair_alloc_type; + + typedef _Rb_tree, + key_compare, _Pair_alloc_type> _Rep_type; + + _Rep_type _M_t; + + public: + + + typedef typename _Pair_alloc_type::pointer pointer; + typedef typename _Pair_alloc_type::const_pointer const_pointer; + typedef typename _Pair_alloc_type::reference reference; + typedef typename _Pair_alloc_type::const_reference const_reference; + typedef typename _Rep_type::iterator iterator; + typedef typename _Rep_type::const_iterator const_iterator; + typedef typename _Rep_type::size_type size_type; + typedef typename _Rep_type::difference_type difference_type; + typedef typename _Rep_type::reverse_iterator reverse_iterator; + typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; + + + + + + + multimap() + : _M_t() { } + + + + + + + explicit + multimap(const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, _Pair_alloc_type(__a)) { } +# 177 "/usr/include/c++/4.8.2/bits/stl_multimap.h" 3 + multimap(const multimap& __x) + : _M_t(__x._M_t) { } +# 218 "/usr/include/c++/4.8.2/bits/stl_multimap.h" 3 + template + multimap(_InputIterator __first, _InputIterator __last) + : _M_t() + { _M_t._M_insert_equal(__first, __last); } +# 234 "/usr/include/c++/4.8.2/bits/stl_multimap.h" 3 + template + multimap(_InputIterator __first, _InputIterator __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, _Pair_alloc_type(__a)) + { _M_t._M_insert_equal(__first, __last); } +# 257 "/usr/include/c++/4.8.2/bits/stl_multimap.h" 3 + multimap& + operator=(const multimap& __x) + { + _M_t = __x._M_t; + return *this; + } +# 303 "/usr/include/c++/4.8.2/bits/stl_multimap.h" 3 + allocator_type + get_allocator() const + { return allocator_type(_M_t.get_allocator()); } + + + + + + + + iterator + begin() + { return _M_t.begin(); } + + + + + + + const_iterator + begin() const + { return _M_t.begin(); } + + + + + + + iterator + end() + { return _M_t.end(); } + + + + + + + const_iterator + end() const + { return _M_t.end(); } + + + + + + + reverse_iterator + rbegin() + { return _M_t.rbegin(); } + + + + + + + const_reverse_iterator + rbegin() const + { return _M_t.rbegin(); } + + + + + + + reverse_iterator + rend() + { return _M_t.rend(); } + + + + + + + const_reverse_iterator + rend() const + { return _M_t.rend(); } +# 420 "/usr/include/c++/4.8.2/bits/stl_multimap.h" 3 + bool + empty() const + { return _M_t.empty(); } + + + size_type + size() const + { return _M_t.size(); } + + + size_type + max_size() const + { return _M_t.max_size(); } +# 500 "/usr/include/c++/4.8.2/bits/stl_multimap.h" 3 + iterator + insert(const value_type& __x) + { return _M_t._M_insert_equal(__x); } +# 533 "/usr/include/c++/4.8.2/bits/stl_multimap.h" 3 + iterator + + + + insert(iterator __position, const value_type& __x) + + { return _M_t._M_insert_equal_(__position, __x); } +# 560 "/usr/include/c++/4.8.2/bits/stl_multimap.h" 3 + template + void + insert(_InputIterator __first, _InputIterator __last) + { _M_t._M_insert_equal(__first, __last); } +# 614 "/usr/include/c++/4.8.2/bits/stl_multimap.h" 3 + void + erase(iterator __position) + { _M_t.erase(__position); } +# 630 "/usr/include/c++/4.8.2/bits/stl_multimap.h" 3 + size_type + erase(const key_type& __x) + { return _M_t.erase(__x); } +# 670 "/usr/include/c++/4.8.2/bits/stl_multimap.h" 3 + void + erase(iterator __first, iterator __last) + { _M_t.erase(__first, __last); } +# 686 "/usr/include/c++/4.8.2/bits/stl_multimap.h" 3 + void + swap(multimap& __x) + { _M_t.swap(__x._M_t); } + + + + + + + + void + clear() + { _M_t.clear(); } + + + + + + + key_compare + key_comp() const + { return _M_t.key_comp(); } + + + + + + value_compare + value_comp() const + { return value_compare(_M_t.key_comp()); } +# 729 "/usr/include/c++/4.8.2/bits/stl_multimap.h" 3 + iterator + find(const key_type& __x) + { return _M_t.find(__x); } +# 744 "/usr/include/c++/4.8.2/bits/stl_multimap.h" 3 + const_iterator + find(const key_type& __x) const + { return _M_t.find(__x); } + + + + + + + size_type + count(const key_type& __x) const + { return _M_t.count(__x); } +# 768 "/usr/include/c++/4.8.2/bits/stl_multimap.h" 3 + iterator + lower_bound(const key_type& __x) + { return _M_t.lower_bound(__x); } +# 783 "/usr/include/c++/4.8.2/bits/stl_multimap.h" 3 + const_iterator + lower_bound(const key_type& __x) const + { return _M_t.lower_bound(__x); } + + + + + + + + iterator + upper_bound(const key_type& __x) + { return _M_t.upper_bound(__x); } + + + + + + + + const_iterator + upper_bound(const key_type& __x) const + { return _M_t.upper_bound(__x); } +# 820 "/usr/include/c++/4.8.2/bits/stl_multimap.h" 3 + std::pair + equal_range(const key_type& __x) + { return _M_t.equal_range(__x); } +# 837 "/usr/include/c++/4.8.2/bits/stl_multimap.h" 3 + std::pair + equal_range(const key_type& __x) const + { return _M_t.equal_range(__x); } + + template + friend bool + operator==(const multimap<_K1, _T1, _C1, _A1>&, + const multimap<_K1, _T1, _C1, _A1>&); + + template + friend bool + operator<(const multimap<_K1, _T1, _C1, _A1>&, + const multimap<_K1, _T1, _C1, _A1>&); + }; +# 862 "/usr/include/c++/4.8.2/bits/stl_multimap.h" 3 + template + inline bool + operator==(const multimap<_Key, _Tp, _Compare, _Alloc>& __x, + const multimap<_Key, _Tp, _Compare, _Alloc>& __y) + { return __x._M_t == __y._M_t; } +# 879 "/usr/include/c++/4.8.2/bits/stl_multimap.h" 3 + template + inline bool + operator<(const multimap<_Key, _Tp, _Compare, _Alloc>& __x, + const multimap<_Key, _Tp, _Compare, _Alloc>& __y) + { return __x._M_t < __y._M_t; } + + + template + inline bool + operator!=(const multimap<_Key, _Tp, _Compare, _Alloc>& __x, + const multimap<_Key, _Tp, _Compare, _Alloc>& __y) + { return !(__x == __y); } + + + template + inline bool + operator>(const multimap<_Key, _Tp, _Compare, _Alloc>& __x, + const multimap<_Key, _Tp, _Compare, _Alloc>& __y) + { return __y < __x; } + + + template + inline bool + operator<=(const multimap<_Key, _Tp, _Compare, _Alloc>& __x, + const multimap<_Key, _Tp, _Compare, _Alloc>& __y) + { return !(__y < __x); } + + + template + inline bool + operator>=(const multimap<_Key, _Tp, _Compare, _Alloc>& __x, + const multimap<_Key, _Tp, _Compare, _Alloc>& __y) + { return !(__x < __y); } + + + template + inline void + swap(multimap<_Key, _Tp, _Compare, _Alloc>& __x, + multimap<_Key, _Tp, _Compare, _Alloc>& __y) + { __x.swap(__y); } + + +} +# 63 "/usr/include/c++/4.8.2/map" 2 3 +# 11 "include/CTypedef.h" 2 +# 1 "/usr/include/c++/4.8.2/vector" 1 3 +# 58 "/usr/include/c++/4.8.2/vector" 3 + +# 59 "/usr/include/c++/4.8.2/vector" 3 + + + +# 1 "/usr/include/c++/4.8.2/bits/stl_construct.h" 1 3 +# 61 "/usr/include/c++/4.8.2/bits/stl_construct.h" 3 +# 1 "/usr/include/c++/4.8.2/ext/alloc_traits.h" 1 3 +# 32 "/usr/include/c++/4.8.2/ext/alloc_traits.h" 3 + +# 33 "/usr/include/c++/4.8.2/ext/alloc_traits.h" 3 +# 41 "/usr/include/c++/4.8.2/ext/alloc_traits.h" 3 +namespace __gnu_cxx __attribute__ ((__visibility__ ("default"))) +{ + +# 120 "/usr/include/c++/4.8.2/ext/alloc_traits.h" 3 +template + struct __alloc_traits + + + + { + typedef _Alloc allocator_type; +# 199 "/usr/include/c++/4.8.2/ext/alloc_traits.h" 3 + typedef typename _Alloc::pointer pointer; + typedef typename _Alloc::const_pointer const_pointer; + typedef typename _Alloc::value_type value_type; + typedef typename _Alloc::reference reference; + typedef typename _Alloc::const_reference const_reference; + typedef typename _Alloc::size_type size_type; + typedef typename _Alloc::difference_type difference_type; + + static pointer + allocate(_Alloc& __a, size_type __n) + { return __a.allocate(__n); } + + static void deallocate(_Alloc& __a, pointer __p, size_type __n) + { __a.deallocate(__p, __n); } + + template + static void construct(_Alloc& __a, pointer __p, const _Tp& __arg) + { __a.construct(__p, __arg); } + + static void destroy(_Alloc& __a, pointer __p) + { __a.destroy(__p); } + + static size_type max_size(const _Alloc& __a) + { return __a.max_size(); } + + static const _Alloc& _S_select_on_copy(const _Alloc& __a) { return __a; } + + static void _S_on_swap(_Alloc& __a, _Alloc& __b) + { + + + std::__alloc_swap<_Alloc>::_S_do_it(__a, __b); + } + + template + struct rebind + { typedef typename _Alloc::template rebind<_Tp>::other other; }; + + }; + + +} +# 62 "/usr/include/c++/4.8.2/bits/stl_construct.h" 2 3 + +namespace std __attribute__ ((__visibility__ ("default"))) +{ + +# 77 "/usr/include/c++/4.8.2/bits/stl_construct.h" 3 + template + inline void + _Construct(_T1* __p, const _T2& __value) + { + + + ::new(static_cast(__p)) _T1(__value); + } + + + + + + template + inline void + _Destroy(_Tp* __pointer) + { __pointer->~_Tp(); } + + template + struct _Destroy_aux + { + template + static void + __destroy(_ForwardIterator __first, _ForwardIterator __last) + { + for (; __first != __last; ++__first) + std::_Destroy(std::__addressof(*__first)); + } + }; + + template<> + struct _Destroy_aux + { + template + static void + __destroy(_ForwardIterator, _ForwardIterator) { } + }; + + + + + + + template + inline void + _Destroy(_ForwardIterator __first, _ForwardIterator __last) + { + typedef typename iterator_traits<_ForwardIterator>::value_type + _Value_type; + std::_Destroy_aux<__has_trivial_destructor(_Value_type)>:: + __destroy(__first, __last); + } + + + + + + + + template + void + _Destroy(_ForwardIterator __first, _ForwardIterator __last, + _Allocator& __alloc) + { + typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; + for (; __first != __last; ++__first) + __traits::destroy(__alloc, std::__addressof(*__first)); + } + + template + inline void + _Destroy(_ForwardIterator __first, _ForwardIterator __last, + allocator<_Tp>&) + { + _Destroy(__first, __last); + } + + +} +# 63 "/usr/include/c++/4.8.2/vector" 2 3 +# 1 "/usr/include/c++/4.8.2/bits/stl_uninitialized.h" 1 3 +# 59 "/usr/include/c++/4.8.2/bits/stl_uninitialized.h" 3 +namespace std __attribute__ ((__visibility__ ("default"))) +{ + + + template + struct __uninitialized_copy + { + template + static _ForwardIterator + __uninit_copy(_InputIterator __first, _InputIterator __last, + _ForwardIterator __result) + { + _ForwardIterator __cur = __result; + try + { + for (; __first != __last; ++__first, ++__cur) + std::_Construct(std::__addressof(*__cur), *__first); + return __cur; + } + catch(...) + { + std::_Destroy(__result, __cur); + throw; + } + } + }; + + template<> + struct __uninitialized_copy + { + template + static _ForwardIterator + __uninit_copy(_InputIterator __first, _InputIterator __last, + _ForwardIterator __result) + { return std::copy(__first, __last, __result); } + }; +# 105 "/usr/include/c++/4.8.2/bits/stl_uninitialized.h" 3 + template + inline _ForwardIterator + uninitialized_copy(_InputIterator __first, _InputIterator __last, + _ForwardIterator __result) + { + typedef typename iterator_traits<_InputIterator>::value_type + _ValueType1; + typedef typename iterator_traits<_ForwardIterator>::value_type + _ValueType2; + + return std::__uninitialized_copy<(__is_trivial(_ValueType1) + && __is_trivial(_ValueType2))>:: + __uninit_copy(__first, __last, __result); + } + + + template + struct __uninitialized_fill + { + template + static void + __uninit_fill(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __x) + { + _ForwardIterator __cur = __first; + try + { + for (; __cur != __last; ++__cur) + std::_Construct(std::__addressof(*__cur), __x); + } + catch(...) + { + std::_Destroy(__first, __cur); + throw; + } + } + }; + + template<> + struct __uninitialized_fill + { + template + static void + __uninit_fill(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __x) + { std::fill(__first, __last, __x); } + }; +# 162 "/usr/include/c++/4.8.2/bits/stl_uninitialized.h" 3 + template + inline void + uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __x) + { + typedef typename iterator_traits<_ForwardIterator>::value_type + _ValueType; + + std::__uninitialized_fill<__is_trivial(_ValueType)>:: + __uninit_fill(__first, __last, __x); + } + + + template + struct __uninitialized_fill_n + { + template + static void + __uninit_fill_n(_ForwardIterator __first, _Size __n, + const _Tp& __x) + { + _ForwardIterator __cur = __first; + try + { + for (; __n > 0; --__n, ++__cur) + std::_Construct(std::__addressof(*__cur), __x); + } + catch(...) + { + std::_Destroy(__first, __cur); + throw; + } + } + }; + + template<> + struct __uninitialized_fill_n + { + template + static void + __uninit_fill_n(_ForwardIterator __first, _Size __n, + const _Tp& __x) + { std::fill_n(__first, __n, __x); } + }; +# 216 "/usr/include/c++/4.8.2/bits/stl_uninitialized.h" 3 + template + inline void + uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x) + { + typedef typename iterator_traits<_ForwardIterator>::value_type + _ValueType; + + std::__uninitialized_fill_n<__is_trivial(_ValueType)>:: + __uninit_fill_n(__first, __n, __x); + } + + + + + + + + template + _ForwardIterator + __uninitialized_copy_a(_InputIterator __first, _InputIterator __last, + _ForwardIterator __result, _Allocator& __alloc) + { + _ForwardIterator __cur = __result; + try + { + typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; + for (; __first != __last; ++__first, ++__cur) + __traits::construct(__alloc, std::__addressof(*__cur), *__first); + return __cur; + } + catch(...) + { + std::_Destroy(__result, __cur, __alloc); + throw; + } + } + + template + inline _ForwardIterator + __uninitialized_copy_a(_InputIterator __first, _InputIterator __last, + _ForwardIterator __result, allocator<_Tp>&) + { return std::uninitialized_copy(__first, __last, __result); } + + template + inline _ForwardIterator + __uninitialized_move_a(_InputIterator __first, _InputIterator __last, + _ForwardIterator __result, _Allocator& __alloc) + { + return std::__uninitialized_copy_a((__first), + (__last), + __result, __alloc); + } + + template + inline _ForwardIterator + __uninitialized_move_if_noexcept_a(_InputIterator __first, + _InputIterator __last, + _ForwardIterator __result, + _Allocator& __alloc) + { + return std::__uninitialized_copy_a + ((__first), + (__last), __result, __alloc); + } + + template + void + __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __x, _Allocator& __alloc) + { + _ForwardIterator __cur = __first; + try + { + typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; + for (; __cur != __last; ++__cur) + __traits::construct(__alloc, std::__addressof(*__cur), __x); + } + catch(...) + { + std::_Destroy(__first, __cur, __alloc); + throw; + } + } + + template + inline void + __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __x, allocator<_Tp2>&) + { std::uninitialized_fill(__first, __last, __x); } + + template + void + __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, + const _Tp& __x, _Allocator& __alloc) + { + _ForwardIterator __cur = __first; + try + { + typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; + for (; __n > 0; --__n, ++__cur) + __traits::construct(__alloc, std::__addressof(*__cur), __x); + } + catch(...) + { + std::_Destroy(__first, __cur, __alloc); + throw; + } + } + + template + inline void + __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, + const _Tp& __x, allocator<_Tp2>&) + { std::uninitialized_fill_n(__first, __n, __x); } +# 346 "/usr/include/c++/4.8.2/bits/stl_uninitialized.h" 3 + template + inline _ForwardIterator + __uninitialized_copy_move(_InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _ForwardIterator __result, + _Allocator& __alloc) + { + _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1, + __result, + __alloc); + try + { + return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc); + } + catch(...) + { + std::_Destroy(__result, __mid, __alloc); + throw; + } + } + + + + + + template + inline _ForwardIterator + __uninitialized_move_copy(_InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _ForwardIterator __result, + _Allocator& __alloc) + { + _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1, + __result, + __alloc); + try + { + return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc); + } + catch(...) + { + std::_Destroy(__result, __mid, __alloc); + throw; + } + } + + + + + template + inline _ForwardIterator + __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid, + const _Tp& __x, _InputIterator __first, + _InputIterator __last, _Allocator& __alloc) + { + std::__uninitialized_fill_a(__result, __mid, __x, __alloc); + try + { + return std::__uninitialized_move_a(__first, __last, __mid, __alloc); + } + catch(...) + { + std::_Destroy(__result, __mid, __alloc); + throw; + } + } + + + + + template + inline void + __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1, + _ForwardIterator __first2, + _ForwardIterator __last2, const _Tp& __x, + _Allocator& __alloc) + { + _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1, + __first2, + __alloc); + try + { + std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc); + } + catch(...) + { + std::_Destroy(__first2, __mid2, __alloc); + throw; + } + } +# 653 "/usr/include/c++/4.8.2/bits/stl_uninitialized.h" 3 + +} +# 64 "/usr/include/c++/4.8.2/vector" 2 3 +# 1 "/usr/include/c++/4.8.2/bits/stl_vector.h" 1 3 +# 66 "/usr/include/c++/4.8.2/bits/stl_vector.h" 3 +namespace std __attribute__ ((__visibility__ ("default"))) +{ + + + + template + struct _Vector_base + { + typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template + rebind<_Tp>::other _Tp_alloc_type; + typedef typename __gnu_cxx::__alloc_traits<_Tp_alloc_type>::pointer + pointer; + + struct _Vector_impl + : public _Tp_alloc_type + { + pointer _M_start; + pointer _M_finish; + pointer _M_end_of_storage; + + _Vector_impl() + : _Tp_alloc_type(), _M_start(0), _M_finish(0), _M_end_of_storage(0) + { } + + _Vector_impl(_Tp_alloc_type const& __a) + : _Tp_alloc_type(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0) + { } +# 101 "/usr/include/c++/4.8.2/bits/stl_vector.h" 3 + void _M_swap_data(_Vector_impl& __x) + { + std::swap(_M_start, __x._M_start); + std::swap(_M_finish, __x._M_finish); + std::swap(_M_end_of_storage, __x._M_end_of_storage); + } + }; + + public: + typedef _Alloc allocator_type; + + _Tp_alloc_type& + _M_get_Tp_allocator() + { return *static_cast<_Tp_alloc_type*>(&this->_M_impl); } + + const _Tp_alloc_type& + _M_get_Tp_allocator() const + { return *static_cast(&this->_M_impl); } + + allocator_type + get_allocator() const + { return allocator_type(_M_get_Tp_allocator()); } + + _Vector_base() + : _M_impl() { } + + _Vector_base(const allocator_type& __a) + : _M_impl(__a) { } + + _Vector_base(size_t __n) + : _M_impl() + { _M_create_storage(__n); } + + _Vector_base(size_t __n, const allocator_type& __a) + : _M_impl(__a) + { _M_create_storage(__n); } +# 159 "/usr/include/c++/4.8.2/bits/stl_vector.h" 3 + ~_Vector_base() + { _M_deallocate(this->_M_impl._M_start, this->_M_impl._M_end_of_storage + - this->_M_impl._M_start); } + + public: + _Vector_impl _M_impl; + + pointer + _M_allocate(size_t __n) + { return __n != 0 ? _M_impl.allocate(__n) : 0; } + + void + _M_deallocate(pointer __p, size_t __n) + { + if (__p) + _M_impl.deallocate(__p, __n); + } + + private: + void + _M_create_storage(size_t __n) + { + this->_M_impl._M_start = this->_M_allocate(__n); + this->_M_impl._M_finish = this->_M_impl._M_start; + this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; + } + }; +# 209 "/usr/include/c++/4.8.2/bits/stl_vector.h" 3 + template > + class vector : protected _Vector_base<_Tp, _Alloc> + { + + typedef typename _Alloc::value_type _Alloc_value_type; + + + + typedef _Vector_base<_Tp, _Alloc> _Base; + typedef typename _Base::_Tp_alloc_type _Tp_alloc_type; + typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Alloc_traits; + + public: + typedef _Tp value_type; + typedef typename _Base::pointer pointer; + typedef typename _Alloc_traits::const_pointer const_pointer; + typedef typename _Alloc_traits::reference reference; + typedef typename _Alloc_traits::const_reference const_reference; + typedef __gnu_cxx::__normal_iterator iterator; + typedef __gnu_cxx::__normal_iterator + const_iterator; + typedef std::reverse_iterator const_reverse_iterator; + typedef std::reverse_iterator reverse_iterator; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Alloc allocator_type; + + protected: + using _Base::_M_allocate; + using _Base::_M_deallocate; + using _Base::_M_impl; + using _Base::_M_get_Tp_allocator; + + public: + + + + + + vector() + : _Base() { } + + + + + + explicit + vector(const allocator_type& __a) + : _Base(__a) { } +# 294 "/usr/include/c++/4.8.2/bits/stl_vector.h" 3 + explicit + vector(size_type __n, const value_type& __value = value_type(), + const allocator_type& __a = allocator_type()) + : _Base(__n, __a) + { _M_fill_initialize(__n, __value); } +# 310 "/usr/include/c++/4.8.2/bits/stl_vector.h" 3 + vector(const vector& __x) + : _Base(__x.size(), + _Alloc_traits::_S_select_on_copy(__x._M_get_Tp_allocator())) + { this->_M_impl._M_finish = + std::__uninitialized_copy_a(__x.begin(), __x.end(), + this->_M_impl._M_start, + _M_get_Tp_allocator()); + } +# 397 "/usr/include/c++/4.8.2/bits/stl_vector.h" 3 + template + vector(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { + + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + _M_initialize_dispatch(__first, __last, _Integral()); + } +# 414 "/usr/include/c++/4.8.2/bits/stl_vector.h" 3 + ~vector() + { std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, + _M_get_Tp_allocator()); } +# 426 "/usr/include/c++/4.8.2/bits/stl_vector.h" 3 + vector& + operator=(const vector& __x); +# 478 "/usr/include/c++/4.8.2/bits/stl_vector.h" 3 + void + assign(size_type __n, const value_type& __val) + { _M_fill_assign(__n, __val); } +# 501 "/usr/include/c++/4.8.2/bits/stl_vector.h" 3 + template + void + assign(_InputIterator __first, _InputIterator __last) + { + + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } +# 529 "/usr/include/c++/4.8.2/bits/stl_vector.h" 3 + using _Base::get_allocator; + + + + + + + + iterator + begin() + { return iterator(this->_M_impl._M_start); } + + + + + + + const_iterator + begin() const + { return const_iterator(this->_M_impl._M_start); } + + + + + + + iterator + end() + { return iterator(this->_M_impl._M_finish); } + + + + + + + const_iterator + end() const + { return const_iterator(this->_M_impl._M_finish); } + + + + + + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + + + + + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + + + + + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + + + + + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } +# 644 "/usr/include/c++/4.8.2/bits/stl_vector.h" 3 + size_type + size() const + { return size_type(this->_M_impl._M_finish - this->_M_impl._M_start); } + + + size_type + max_size() const + { return _Alloc_traits::max_size(_M_get_Tp_allocator()); } +# 703 "/usr/include/c++/4.8.2/bits/stl_vector.h" 3 + void + resize(size_type __new_size, value_type __x = value_type()) + { + if (__new_size > size()) + insert(end(), __new_size - size(), __x); + else if (__new_size < size()) + _M_erase_at_end(this->_M_impl._M_start + __new_size); + } +# 724 "/usr/include/c++/4.8.2/bits/stl_vector.h" 3 + size_type + capacity() const + { return size_type(this->_M_impl._M_end_of_storage + - this->_M_impl._M_start); } + + + + + + bool + empty() const + { return begin() == end(); } +# 754 "/usr/include/c++/4.8.2/bits/stl_vector.h" 3 + void + reserve(size_type __n); +# 769 "/usr/include/c++/4.8.2/bits/stl_vector.h" 3 + reference + operator[](size_type __n) + { return *(this->_M_impl._M_start + __n); } +# 784 "/usr/include/c++/4.8.2/bits/stl_vector.h" 3 + const_reference + operator[](size_type __n) const + { return *(this->_M_impl._M_start + __n); } + + protected: + + void + _M_range_check(size_type __n) const + { + if (__n >= this->size()) + __throw_out_of_range(("vector::_M_range_check")); + } + + public: +# 809 "/usr/include/c++/4.8.2/bits/stl_vector.h" 3 + reference + at(size_type __n) + { + _M_range_check(__n); + return (*this)[__n]; + } +# 827 "/usr/include/c++/4.8.2/bits/stl_vector.h" 3 + const_reference + at(size_type __n) const + { + _M_range_check(__n); + return (*this)[__n]; + } + + + + + + reference + front() + { return *begin(); } + + + + + + const_reference + front() const + { return *begin(); } + + + + + + reference + back() + { return *(end() - 1); } + + + + + + const_reference + back() const + { return *(end() - 1); } +# 876 "/usr/include/c++/4.8.2/bits/stl_vector.h" 3 + pointer + + data() + { return std::__addressof(front()); } + + + + + const_pointer + + data() const + { return std::__addressof(front()); } +# 900 "/usr/include/c++/4.8.2/bits/stl_vector.h" 3 + void + push_back(const value_type& __x) + { + if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) + { + _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish, + __x); + ++this->_M_impl._M_finish; + } + else + + + + _M_insert_aux(end(), __x); + + } +# 936 "/usr/include/c++/4.8.2/bits/stl_vector.h" 3 + void + pop_back() + { + --this->_M_impl._M_finish; + _Alloc_traits::destroy(this->_M_impl, this->_M_impl._M_finish); + } +# 972 "/usr/include/c++/4.8.2/bits/stl_vector.h" 3 + iterator + insert(iterator __position, const value_type& __x); +# 1022 "/usr/include/c++/4.8.2/bits/stl_vector.h" 3 + void + insert(iterator __position, size_type __n, const value_type& __x) + { _M_fill_insert(__position, __n, __x); } +# 1048 "/usr/include/c++/4.8.2/bits/stl_vector.h" 3 + template + void + insert(iterator __position, _InputIterator __first, + _InputIterator __last) + { + + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + _M_insert_dispatch(__position, __first, __last, _Integral()); + } +# 1074 "/usr/include/c++/4.8.2/bits/stl_vector.h" 3 + iterator + erase(iterator __position); +# 1095 "/usr/include/c++/4.8.2/bits/stl_vector.h" 3 + iterator + erase(iterator __first, iterator __last); +# 1107 "/usr/include/c++/4.8.2/bits/stl_vector.h" 3 + void + swap(vector& __x) + + + + { + this->_M_impl._M_swap_data(__x._M_impl); + _Alloc_traits::_S_on_swap(_M_get_Tp_allocator(), + __x._M_get_Tp_allocator()); + } + + + + + + + + void + clear() + { _M_erase_at_end(this->_M_impl._M_start); } + + protected: + + + + + template + pointer + _M_allocate_and_copy(size_type __n, + _ForwardIterator __first, _ForwardIterator __last) + { + pointer __result = this->_M_allocate(__n); + try + { + std::__uninitialized_copy_a(__first, __last, __result, + _M_get_Tp_allocator()); + return __result; + } + catch(...) + { + _M_deallocate(__result, __n); + throw; + } + } +# 1159 "/usr/include/c++/4.8.2/bits/stl_vector.h" 3 + template + void + _M_initialize_dispatch(_Integer __n, _Integer __value, __true_type) + { + this->_M_impl._M_start = _M_allocate(static_cast(__n)); + this->_M_impl._M_end_of_storage = + this->_M_impl._M_start + static_cast(__n); + _M_fill_initialize(static_cast(__n), __value); + } + + + template + void + _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) + { + typedef typename std::iterator_traits<_InputIterator>:: + iterator_category _IterCategory; + _M_range_initialize(__first, __last, _IterCategory()); + } + + + template + void + _M_range_initialize(_InputIterator __first, + _InputIterator __last, std::input_iterator_tag) + { + for (; __first != __last; ++__first) + + + + push_back(*__first); + + } + + + template + void + _M_range_initialize(_ForwardIterator __first, + _ForwardIterator __last, std::forward_iterator_tag) + { + const size_type __n = std::distance(__first, __last); + this->_M_impl._M_start = this->_M_allocate(__n); + this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; + this->_M_impl._M_finish = + std::__uninitialized_copy_a(__first, __last, + this->_M_impl._M_start, + _M_get_Tp_allocator()); + } + + + + void + _M_fill_initialize(size_type __n, const value_type& __value) + { + std::__uninitialized_fill_n_a(this->_M_impl._M_start, __n, __value, + _M_get_Tp_allocator()); + this->_M_impl._M_finish = this->_M_impl._M_end_of_storage; + } +# 1237 "/usr/include/c++/4.8.2/bits/stl_vector.h" 3 + template + void + _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { _M_fill_assign(__n, __val); } + + + template + void + _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) + { + typedef typename std::iterator_traits<_InputIterator>:: + iterator_category _IterCategory; + _M_assign_aux(__first, __last, _IterCategory()); + } + + + template + void + _M_assign_aux(_InputIterator __first, _InputIterator __last, + std::input_iterator_tag); + + + template + void + _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, + std::forward_iterator_tag); + + + + void + _M_fill_assign(size_type __n, const value_type& __val); +# 1277 "/usr/include/c++/4.8.2/bits/stl_vector.h" 3 + template + void + _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val, + __true_type) + { _M_fill_insert(__pos, __n, __val); } + + + template + void + _M_insert_dispatch(iterator __pos, _InputIterator __first, + _InputIterator __last, __false_type) + { + typedef typename std::iterator_traits<_InputIterator>:: + iterator_category _IterCategory; + _M_range_insert(__pos, __first, __last, _IterCategory()); + } + + + template + void + _M_range_insert(iterator __pos, _InputIterator __first, + _InputIterator __last, std::input_iterator_tag); + + + template + void + _M_range_insert(iterator __pos, _ForwardIterator __first, + _ForwardIterator __last, std::forward_iterator_tag); + + + + void + _M_fill_insert(iterator __pos, size_type __n, const value_type& __x); +# 1322 "/usr/include/c++/4.8.2/bits/stl_vector.h" 3 + void + _M_insert_aux(iterator __position, const value_type& __x); +# 1335 "/usr/include/c++/4.8.2/bits/stl_vector.h" 3 + size_type + _M_check_len(size_type __n, const char* __s) const + { + if (max_size() - size() < __n) + __throw_length_error((__s)); + + const size_type __len = size() + std::max(size(), __n); + return (__len < size() || __len > max_size()) ? max_size() : __len; + } + + + + + + void + _M_erase_at_end(pointer __pos) + { + std::_Destroy(__pos, this->_M_impl._M_finish, _M_get_Tp_allocator()); + this->_M_impl._M_finish = __pos; + } +# 1389 "/usr/include/c++/4.8.2/bits/stl_vector.h" 3 + }; +# 1402 "/usr/include/c++/4.8.2/bits/stl_vector.h" 3 + template + inline bool + operator==(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) + { return (__x.size() == __y.size() + && std::equal(__x.begin(), __x.end(), __y.begin())); } +# 1419 "/usr/include/c++/4.8.2/bits/stl_vector.h" 3 + template + inline bool + operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) + { return std::lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); } + + + template + inline bool + operator!=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) + { return !(__x == __y); } + + + template + inline bool + operator>(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) + { return __y < __x; } + + + template + inline bool + operator<=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) + { return !(__y < __x); } + + + template + inline bool + operator>=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) + { return !(__x < __y); } + + + template + inline void + swap(vector<_Tp, _Alloc>& __x, vector<_Tp, _Alloc>& __y) + { __x.swap(__y); } + + +} +# 65 "/usr/include/c++/4.8.2/vector" 2 3 +# 1 "/usr/include/c++/4.8.2/bits/stl_bvector.h" 1 3 +# 63 "/usr/include/c++/4.8.2/bits/stl_bvector.h" 3 +namespace std __attribute__ ((__visibility__ ("default"))) +{ + + + typedef unsigned long _Bit_type; + enum { _S_word_bit = int(8 * sizeof(_Bit_type)) }; + + struct _Bit_reference + { + _Bit_type * _M_p; + _Bit_type _M_mask; + + _Bit_reference(_Bit_type * __x, _Bit_type __y) + : _M_p(__x), _M_mask(__y) { } + + _Bit_reference() : _M_p(0), _M_mask(0) { } + + operator bool() const + { return !!(*_M_p & _M_mask); } + + _Bit_reference& + operator=(bool __x) + { + if (__x) + *_M_p |= _M_mask; + else + *_M_p &= ~_M_mask; + return *this; + } + + _Bit_reference& + operator=(const _Bit_reference& __x) + { return *this = bool(__x); } + + bool + operator==(const _Bit_reference& __x) const + { return bool(*this) == bool(__x); } + + bool + operator<(const _Bit_reference& __x) const + { return !bool(*this) && bool(__x); } + + void + flip() + { *_M_p ^= _M_mask; } + }; +# 136 "/usr/include/c++/4.8.2/bits/stl_bvector.h" 3 + struct _Bit_iterator_base + : public std::iterator + { + _Bit_type * _M_p; + unsigned int _M_offset; + + _Bit_iterator_base(_Bit_type * __x, unsigned int __y) + : _M_p(__x), _M_offset(__y) { } + + void + _M_bump_up() + { + if (_M_offset++ == int(_S_word_bit) - 1) + { + _M_offset = 0; + ++_M_p; + } + } + + void + _M_bump_down() + { + if (_M_offset-- == 0) + { + _M_offset = int(_S_word_bit) - 1; + --_M_p; + } + } + + void + _M_incr(ptrdiff_t __i) + { + difference_type __n = __i + _M_offset; + _M_p += __n / int(_S_word_bit); + __n = __n % int(_S_word_bit); + if (__n < 0) + { + __n += int(_S_word_bit); + --_M_p; + } + _M_offset = static_cast(__n); + } + + bool + operator==(const _Bit_iterator_base& __i) const + { return _M_p == __i._M_p && _M_offset == __i._M_offset; } + + bool + operator<(const _Bit_iterator_base& __i) const + { + return _M_p < __i._M_p + || (_M_p == __i._M_p && _M_offset < __i._M_offset); + } + + bool + operator!=(const _Bit_iterator_base& __i) const + { return !(*this == __i); } + + bool + operator>(const _Bit_iterator_base& __i) const + { return __i < *this; } + + bool + operator<=(const _Bit_iterator_base& __i) const + { return !(__i < *this); } + + bool + operator>=(const _Bit_iterator_base& __i) const + { return !(*this < __i); } + }; + + inline ptrdiff_t + operator-(const _Bit_iterator_base& __x, const _Bit_iterator_base& __y) + { + return (int(_S_word_bit) * (__x._M_p - __y._M_p) + + __x._M_offset - __y._M_offset); + } + + struct _Bit_iterator : public _Bit_iterator_base + { + typedef _Bit_reference reference; + typedef _Bit_reference* pointer; + typedef _Bit_iterator iterator; + + _Bit_iterator() : _Bit_iterator_base(0, 0) { } + + _Bit_iterator(_Bit_type * __x, unsigned int __y) + : _Bit_iterator_base(__x, __y) { } + + reference + operator*() const + { return reference(_M_p, 1UL << _M_offset); } + + iterator& + operator++() + { + _M_bump_up(); + return *this; + } + + iterator + operator++(int) + { + iterator __tmp = *this; + _M_bump_up(); + return __tmp; + } + + iterator& + operator--() + { + _M_bump_down(); + return *this; + } + + iterator + operator--(int) + { + iterator __tmp = *this; + _M_bump_down(); + return __tmp; + } + + iterator& + operator+=(difference_type __i) + { + _M_incr(__i); + return *this; + } + + iterator& + operator-=(difference_type __i) + { + *this += -__i; + return *this; + } + + iterator + operator+(difference_type __i) const + { + iterator __tmp = *this; + return __tmp += __i; + } + + iterator + operator-(difference_type __i) const + { + iterator __tmp = *this; + return __tmp -= __i; + } + + reference + operator[](difference_type __i) const + { return *(*this + __i); } + }; + + inline _Bit_iterator + operator+(ptrdiff_t __n, const _Bit_iterator& __x) + { return __x + __n; } + + struct _Bit_const_iterator : public _Bit_iterator_base + { + typedef bool reference; + typedef bool const_reference; + typedef const bool* pointer; + typedef _Bit_const_iterator const_iterator; + + _Bit_const_iterator() : _Bit_iterator_base(0, 0) { } + + _Bit_const_iterator(_Bit_type * __x, unsigned int __y) + : _Bit_iterator_base(__x, __y) { } + + _Bit_const_iterator(const _Bit_iterator& __x) + : _Bit_iterator_base(__x._M_p, __x._M_offset) { } + + const_reference + operator*() const + { return _Bit_reference(_M_p, 1UL << _M_offset); } + + const_iterator& + operator++() + { + _M_bump_up(); + return *this; + } + + const_iterator + operator++(int) + { + const_iterator __tmp = *this; + _M_bump_up(); + return __tmp; + } + + const_iterator& + operator--() + { + _M_bump_down(); + return *this; + } + + const_iterator + operator--(int) + { + const_iterator __tmp = *this; + _M_bump_down(); + return __tmp; + } + + const_iterator& + operator+=(difference_type __i) + { + _M_incr(__i); + return *this; + } + + const_iterator& + operator-=(difference_type __i) + { + *this += -__i; + return *this; + } + + const_iterator + operator+(difference_type __i) const + { + const_iterator __tmp = *this; + return __tmp += __i; + } + + const_iterator + operator-(difference_type __i) const + { + const_iterator __tmp = *this; + return __tmp -= __i; + } + + const_reference + operator[](difference_type __i) const + { return *(*this + __i); } + }; + + inline _Bit_const_iterator + operator+(ptrdiff_t __n, const _Bit_const_iterator& __x) + { return __x + __n; } + + inline void + __fill_bvector(_Bit_iterator __first, _Bit_iterator __last, bool __x) + { + for (; __first != __last; ++__first) + *__first = __x; + } + + inline void + fill(_Bit_iterator __first, _Bit_iterator __last, const bool& __x) + { + if (__first._M_p != __last._M_p) + { + std::fill(__first._M_p + 1, __last._M_p, __x ? ~0 : 0); + __fill_bvector(__first, _Bit_iterator(__first._M_p + 1, 0), __x); + __fill_bvector(_Bit_iterator(__last._M_p, 0), __last, __x); + } + else + __fill_bvector(__first, __last, __x); + } + + template + struct _Bvector_base + { + typedef typename _Alloc::template rebind<_Bit_type>::other + _Bit_alloc_type; + + struct _Bvector_impl + : public _Bit_alloc_type + { + _Bit_iterator _M_start; + _Bit_iterator _M_finish; + _Bit_type* _M_end_of_storage; + + _Bvector_impl() + : _Bit_alloc_type(), _M_start(), _M_finish(), _M_end_of_storage(0) + { } + + _Bvector_impl(const _Bit_alloc_type& __a) + : _Bit_alloc_type(__a), _M_start(), _M_finish(), _M_end_of_storage(0) + { } + + + + + + + + }; + + public: + typedef _Alloc allocator_type; + + _Bit_alloc_type& + _M_get_Bit_allocator() + { return *static_cast<_Bit_alloc_type*>(&this->_M_impl); } + + const _Bit_alloc_type& + _M_get_Bit_allocator() const + { return *static_cast(&this->_M_impl); } + + allocator_type + get_allocator() const + { return allocator_type(_M_get_Bit_allocator()); } + + _Bvector_base() + : _M_impl() { } + + _Bvector_base(const allocator_type& __a) + : _M_impl(__a) { } +# 465 "/usr/include/c++/4.8.2/bits/stl_bvector.h" 3 + ~_Bvector_base() + { this->_M_deallocate(); } + + protected: + _Bvector_impl _M_impl; + + _Bit_type* + _M_allocate(size_t __n) + { return _M_impl.allocate(_S_nword(__n)); } + + void + _M_deallocate() + { + if (_M_impl._M_start._M_p) + _M_impl.deallocate(_M_impl._M_start._M_p, + _M_impl._M_end_of_storage - _M_impl._M_start._M_p); + } + + static size_t + _S_nword(size_t __n) + { return (__n + int(_S_word_bit) - 1) / int(_S_word_bit); } + }; + + +} + + + + +namespace std __attribute__ ((__visibility__ ("default"))) +{ + +# 517 "/usr/include/c++/4.8.2/bits/stl_bvector.h" 3 +template + class vector : protected _Bvector_base<_Alloc> + { + typedef _Bvector_base<_Alloc> _Base; + + + + + + public: + typedef bool value_type; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Bit_reference reference; + typedef bool const_reference; + typedef _Bit_reference* pointer; + typedef const bool* const_pointer; + typedef _Bit_iterator iterator; + typedef _Bit_const_iterator const_iterator; + typedef std::reverse_iterator const_reverse_iterator; + typedef std::reverse_iterator reverse_iterator; + typedef _Alloc allocator_type; + + allocator_type get_allocator() const + { return _Base::get_allocator(); } + + protected: + using _Base::_M_allocate; + using _Base::_M_deallocate; + using _Base::_S_nword; + using _Base::_M_get_Bit_allocator; + + public: + vector() + : _Base() { } + + explicit + vector(const allocator_type& __a) + : _Base(__a) { } +# 572 "/usr/include/c++/4.8.2/bits/stl_bvector.h" 3 + explicit + vector(size_type __n, const bool& __value = bool(), + const allocator_type& __a = allocator_type()) + : _Base(__a) + { + _M_initialize(__n); + std::fill(this->_M_impl._M_start._M_p, this->_M_impl._M_end_of_storage, + __value ? ~0 : 0); + } + + + vector(const vector& __x) + : _Base(__x._M_get_Bit_allocator()) + { + _M_initialize(__x.size()); + _M_copy_aligned(__x.begin(), __x.end(), this->_M_impl._M_start); + } +# 611 "/usr/include/c++/4.8.2/bits/stl_bvector.h" 3 + template + vector(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + _M_initialize_dispatch(__first, __last, _Integral()); + } + + + ~vector() { } + + vector& + operator=(const vector& __x) + { + if (&__x == this) + return *this; + if (__x.size() > capacity()) + { + this->_M_deallocate(); + _M_initialize(__x.size()); + } + this->_M_impl._M_finish = _M_copy_aligned(__x.begin(), __x.end(), + begin()); + return *this; + } +# 661 "/usr/include/c++/4.8.2/bits/stl_bvector.h" 3 + void + assign(size_type __n, const bool& __x) + { _M_fill_assign(__n, __x); } +# 672 "/usr/include/c++/4.8.2/bits/stl_bvector.h" 3 + template + void + assign(_InputIterator __first, _InputIterator __last) + { + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } +# 687 "/usr/include/c++/4.8.2/bits/stl_bvector.h" 3 + iterator + begin() + { return this->_M_impl._M_start; } + + const_iterator + begin() const + { return this->_M_impl._M_start; } + + iterator + end() + { return this->_M_impl._M_finish; } + + const_iterator + end() const + { return this->_M_impl._M_finish; } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } +# 737 "/usr/include/c++/4.8.2/bits/stl_bvector.h" 3 + size_type + size() const + { return size_type(end() - begin()); } + + size_type + max_size() const + { + const size_type __isize = + __gnu_cxx::__numeric_traits::__max + - int(_S_word_bit) + 1; + const size_type __asize = _M_get_Bit_allocator().max_size(); + return (__asize <= __isize / int(_S_word_bit) + ? __asize * int(_S_word_bit) : __isize); + } + + size_type + capacity() const + { return size_type(const_iterator(this->_M_impl._M_end_of_storage, 0) + - begin()); } + + bool + empty() const + { return begin() == end(); } + + reference + operator[](size_type __n) + { + return *iterator(this->_M_impl._M_start._M_p + + __n / int(_S_word_bit), __n % int(_S_word_bit)); + } + + const_reference + operator[](size_type __n) const + { + return *const_iterator(this->_M_impl._M_start._M_p + + __n / int(_S_word_bit), __n % int(_S_word_bit)); + } + + protected: + void + _M_range_check(size_type __n) const + { + if (__n >= this->size()) + __throw_out_of_range(("vector::_M_range_check")); + } + + public: + reference + at(size_type __n) + { _M_range_check(__n); return (*this)[__n]; } + + const_reference + at(size_type __n) const + { _M_range_check(__n); return (*this)[__n]; } + + void + reserve(size_type __n) + { + if (__n > max_size()) + __throw_length_error(("vector::reserve")); + if (capacity() < __n) + _M_reallocate(__n); + } + + reference + front() + { return *begin(); } + + const_reference + front() const + { return *begin(); } + + reference + back() + { return *(end() - 1); } + + const_reference + back() const + { return *(end() - 1); } + + + + + + + void + data() { } + + void + push_back(bool __x) + { + if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage) + *this->_M_impl._M_finish++ = __x; + else + _M_insert_aux(end(), __x); + } + + void + swap(vector& __x) + { + std::swap(this->_M_impl._M_start, __x._M_impl._M_start); + std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish); + std::swap(this->_M_impl._M_end_of_storage, + __x._M_impl._M_end_of_storage); + + + + std::__alloc_swap:: + _S_do_it(_M_get_Bit_allocator(), __x._M_get_Bit_allocator()); + } + + + static void + swap(reference __x, reference __y) + { + bool __tmp = __x; + __x = __y; + __y = __tmp; + } + + iterator + insert(iterator __position, const bool& __x = bool()) + { + const difference_type __n = __position - begin(); + if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage + && __position == end()) + *this->_M_impl._M_finish++ = __x; + else + _M_insert_aux(__position, __x); + return begin() + __n; + } +# 877 "/usr/include/c++/4.8.2/bits/stl_bvector.h" 3 + template + void + insert(iterator __position, + _InputIterator __first, _InputIterator __last) + { + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + _M_insert_dispatch(__position, __first, __last, _Integral()); + } + + + void + insert(iterator __position, size_type __n, const bool& __x) + { _M_fill_insert(__position, __n, __x); } + + + + + + + void + pop_back() + { --this->_M_impl._M_finish; } + + iterator + erase(iterator __position) + { + if (__position + 1 != end()) + std::copy(__position + 1, end(), __position); + --this->_M_impl._M_finish; + return __position; + } + + iterator + erase(iterator __first, iterator __last) + { + if (__first != __last) + _M_erase_at_end(std::copy(__last, end(), __first)); + return __first; + } + + void + resize(size_type __new_size, bool __x = bool()) + { + if (__new_size < size()) + _M_erase_at_end(begin() + difference_type(__new_size)); + else + insert(end(), __new_size - size(), __x); + } + + + + + + + + void + flip() + { + for (_Bit_type * __p = this->_M_impl._M_start._M_p; + __p != this->_M_impl._M_end_of_storage; ++__p) + *__p = ~*__p; + } + + void + clear() + { _M_erase_at_end(begin()); } + + + protected: + + iterator + _M_copy_aligned(const_iterator __first, const_iterator __last, + iterator __result) + { + _Bit_type* __q = std::copy(__first._M_p, __last._M_p, __result._M_p); + return std::copy(const_iterator(__last._M_p, 0), __last, + iterator(__q, 0)); + } + + void + _M_initialize(size_type __n) + { + _Bit_type* __q = this->_M_allocate(__n); + this->_M_impl._M_end_of_storage = __q + _S_nword(__n); + this->_M_impl._M_start = iterator(__q, 0); + this->_M_impl._M_finish = this->_M_impl._M_start + difference_type(__n); + } + + void + _M_reallocate(size_type __n); +# 977 "/usr/include/c++/4.8.2/bits/stl_bvector.h" 3 + template + void + _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) + { + _M_initialize(static_cast(__n)); + std::fill(this->_M_impl._M_start._M_p, + this->_M_impl._M_end_of_storage, __x ? ~0 : 0); + } + + template + void + _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) + { _M_initialize_range(__first, __last, + std::__iterator_category(__first)); } + + template + void + _M_initialize_range(_InputIterator __first, _InputIterator __last, + std::input_iterator_tag) + { + for (; __first != __last; ++__first) + push_back(*__first); + } + + template + void + _M_initialize_range(_ForwardIterator __first, _ForwardIterator __last, + std::forward_iterator_tag) + { + const size_type __n = std::distance(__first, __last); + _M_initialize(__n); + std::copy(__first, __last, this->_M_impl._M_start); + } + + + + template + void + _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { _M_fill_assign(__n, __val); } + + template + void + _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) + { _M_assign_aux(__first, __last, std::__iterator_category(__first)); } + + void + _M_fill_assign(size_t __n, bool __x) + { + if (__n > size()) + { + std::fill(this->_M_impl._M_start._M_p, + this->_M_impl._M_end_of_storage, __x ? ~0 : 0); + insert(end(), __n - size(), __x); + } + else + { + _M_erase_at_end(begin() + __n); + std::fill(this->_M_impl._M_start._M_p, + this->_M_impl._M_end_of_storage, __x ? ~0 : 0); + } + } + + template + void + _M_assign_aux(_InputIterator __first, _InputIterator __last, + std::input_iterator_tag) + { + iterator __cur = begin(); + for (; __first != __last && __cur != end(); ++__cur, ++__first) + *__cur = *__first; + if (__first == __last) + _M_erase_at_end(__cur); + else + insert(end(), __first, __last); + } + + template + void + _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, + std::forward_iterator_tag) + { + const size_type __len = std::distance(__first, __last); + if (__len < size()) + _M_erase_at_end(std::copy(__first, __last, begin())); + else + { + _ForwardIterator __mid = __first; + std::advance(__mid, size()); + std::copy(__first, __mid, begin()); + insert(end(), __mid, __last); + } + } + + + + + + template + void + _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, + __true_type) + { _M_fill_insert(__pos, __n, __x); } + + template + void + _M_insert_dispatch(iterator __pos, + _InputIterator __first, _InputIterator __last, + __false_type) + { _M_insert_range(__pos, __first, __last, + std::__iterator_category(__first)); } + + void + _M_fill_insert(iterator __position, size_type __n, bool __x); + + template + void + _M_insert_range(iterator __pos, _InputIterator __first, + _InputIterator __last, std::input_iterator_tag) + { + for (; __first != __last; ++__first) + { + __pos = insert(__pos, *__first); + ++__pos; + } + } + + template + void + _M_insert_range(iterator __position, _ForwardIterator __first, + _ForwardIterator __last, std::forward_iterator_tag); + + void + _M_insert_aux(iterator __position, bool __x); + + size_type + _M_check_len(size_type __n, const char* __s) const + { + if (max_size() - size() < __n) + __throw_length_error((__s)); + + const size_type __len = size() + std::max(size(), __n); + return (__len < size() || __len > max_size()) ? max_size() : __len; + } + + void + _M_erase_at_end(iterator __pos) + { this->_M_impl._M_finish = __pos; } + }; + + +} +# 66 "/usr/include/c++/4.8.2/vector" 2 3 + + + +# 1 "/usr/include/c++/4.8.2/bits/vector.tcc" 1 3 +# 59 "/usr/include/c++/4.8.2/bits/vector.tcc" 3 +namespace std __attribute__ ((__visibility__ ("default"))) +{ + + + template + void + vector<_Tp, _Alloc>:: + reserve(size_type __n) + { + if (__n > this->max_size()) + __throw_length_error(("vector::reserve")); + if (this->capacity() < __n) + { + const size_type __old_size = size(); + pointer __tmp = _M_allocate_and_copy(__n, + (this->_M_impl._M_start), + (this->_M_impl._M_finish)); + std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, + _M_get_Tp_allocator()); + _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage + - this->_M_impl._M_start); + this->_M_impl._M_start = __tmp; + this->_M_impl._M_finish = __tmp + __old_size; + this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; + } + } +# 105 "/usr/include/c++/4.8.2/bits/vector.tcc" 3 + template + typename vector<_Tp, _Alloc>::iterator + vector<_Tp, _Alloc>:: + insert(iterator __position, const value_type& __x) + { + const size_type __n = __position - begin(); + if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage + && __position == end()) + { + _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish, __x); + ++this->_M_impl._M_finish; + } + else + { +# 127 "/usr/include/c++/4.8.2/bits/vector.tcc" 3 + _M_insert_aux(__position, __x); + } + return iterator(this->_M_impl._M_start + __n); + } + + template + typename vector<_Tp, _Alloc>::iterator + vector<_Tp, _Alloc>:: + erase(iterator __position) + { + if (__position + 1 != end()) + std::copy(__position + 1, end(), __position); + --this->_M_impl._M_finish; + _Alloc_traits::destroy(this->_M_impl, this->_M_impl._M_finish); + return __position; + } + + template + typename vector<_Tp, _Alloc>::iterator + vector<_Tp, _Alloc>:: + erase(iterator __first, iterator __last) + { + if (__first != __last) + { + if (__last != end()) + std::copy(__last, end(), __first); + _M_erase_at_end(__first.base() + (end() - __last)); + } + return __first; + } + + template + vector<_Tp, _Alloc>& + vector<_Tp, _Alloc>:: + operator=(const vector<_Tp, _Alloc>& __x) + { + if (&__x != this) + { +# 184 "/usr/include/c++/4.8.2/bits/vector.tcc" 3 + const size_type __xlen = __x.size(); + if (__xlen > capacity()) + { + pointer __tmp = _M_allocate_and_copy(__xlen, __x.begin(), + __x.end()); + std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, + _M_get_Tp_allocator()); + _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage + - this->_M_impl._M_start); + this->_M_impl._M_start = __tmp; + this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __xlen; + } + else if (size() >= __xlen) + { + std::_Destroy(std::copy(__x.begin(), __x.end(), begin()), + end(), _M_get_Tp_allocator()); + } + else + { + std::copy(__x._M_impl._M_start, __x._M_impl._M_start + size(), + this->_M_impl._M_start); + std::__uninitialized_copy_a(__x._M_impl._M_start + size(), + __x._M_impl._M_finish, + this->_M_impl._M_finish, + _M_get_Tp_allocator()); + } + this->_M_impl._M_finish = this->_M_impl._M_start + __xlen; + } + return *this; + } + + template + void + vector<_Tp, _Alloc>:: + _M_fill_assign(size_t __n, const value_type& __val) + { + if (__n > capacity()) + { + vector __tmp(__n, __val, _M_get_Tp_allocator()); + __tmp.swap(*this); + } + else if (__n > size()) + { + std::fill(begin(), end(), __val); + std::__uninitialized_fill_n_a(this->_M_impl._M_finish, + __n - size(), __val, + _M_get_Tp_allocator()); + this->_M_impl._M_finish += __n - size(); + } + else + _M_erase_at_end(std::fill_n(this->_M_impl._M_start, __n, __val)); + } + + template + template + void + vector<_Tp, _Alloc>:: + _M_assign_aux(_InputIterator __first, _InputIterator __last, + std::input_iterator_tag) + { + pointer __cur(this->_M_impl._M_start); + for (; __first != __last && __cur != this->_M_impl._M_finish; + ++__cur, ++__first) + *__cur = *__first; + if (__first == __last) + _M_erase_at_end(__cur); + else + insert(end(), __first, __last); + } + + template + template + void + vector<_Tp, _Alloc>:: + _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, + std::forward_iterator_tag) + { + const size_type __len = std::distance(__first, __last); + + if (__len > capacity()) + { + pointer __tmp(_M_allocate_and_copy(__len, __first, __last)); + std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, + _M_get_Tp_allocator()); + _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage + - this->_M_impl._M_start); + this->_M_impl._M_start = __tmp; + this->_M_impl._M_finish = this->_M_impl._M_start + __len; + this->_M_impl._M_end_of_storage = this->_M_impl._M_finish; + } + else if (size() >= __len) + _M_erase_at_end(std::copy(__first, __last, this->_M_impl._M_start)); + else + { + _ForwardIterator __mid = __first; + std::advance(__mid, size()); + std::copy(__first, __mid, this->_M_impl._M_start); + this->_M_impl._M_finish = + std::__uninitialized_copy_a(__mid, __last, + this->_M_impl._M_finish, + _M_get_Tp_allocator()); + } + } +# 316 "/usr/include/c++/4.8.2/bits/vector.tcc" 3 + template + void + vector<_Tp, _Alloc>:: + _M_insert_aux(iterator __position, const _Tp& __x) + + { + if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) + { + _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish, + (*(this->_M_impl._M_finish - 1)) + ); + ++this->_M_impl._M_finish; + + _Tp __x_copy = __x; + + std::copy_backward(__position.base(), this->_M_impl._M_finish - 2, this->_M_impl._M_finish - 1) + + ; + + *__position = __x_copy; + + + + } + else + { + const size_type __len = + _M_check_len(size_type(1), "vector::_M_insert_aux"); + const size_type __elems_before = __position - begin(); + pointer __new_start(this->_M_allocate(__len)); + pointer __new_finish(__new_start); + try + { + + + + + _Alloc_traits::construct(this->_M_impl, + __new_start + __elems_before, + + + + __x); + + __new_finish = 0; + + __new_finish + = std::__uninitialized_move_if_noexcept_a + (this->_M_impl._M_start, __position.base(), + __new_start, _M_get_Tp_allocator()); + + ++__new_finish; + + __new_finish + = std::__uninitialized_move_if_noexcept_a + (__position.base(), this->_M_impl._M_finish, + __new_finish, _M_get_Tp_allocator()); + } + catch(...) + { + if (!__new_finish) + _Alloc_traits::destroy(this->_M_impl, + __new_start + __elems_before); + else + std::_Destroy(__new_start, __new_finish, _M_get_Tp_allocator()); + _M_deallocate(__new_start, __len); + throw; + } + std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, + _M_get_Tp_allocator()); + _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage + - this->_M_impl._M_start); + this->_M_impl._M_start = __new_start; + this->_M_impl._M_finish = __new_finish; + this->_M_impl._M_end_of_storage = __new_start + __len; + } + } +# 439 "/usr/include/c++/4.8.2/bits/vector.tcc" 3 + template + void + vector<_Tp, _Alloc>:: + _M_fill_insert(iterator __position, size_type __n, const value_type& __x) + { + if (__n != 0) + { + if (size_type(this->_M_impl._M_end_of_storage + - this->_M_impl._M_finish) >= __n) + { + value_type __x_copy = __x; + const size_type __elems_after = end() - __position; + pointer __old_finish(this->_M_impl._M_finish); + if (__elems_after > __n) + { + std::__uninitialized_move_a(this->_M_impl._M_finish - __n, + this->_M_impl._M_finish, + this->_M_impl._M_finish, + _M_get_Tp_allocator()); + this->_M_impl._M_finish += __n; + std::copy_backward(__position.base(), __old_finish - __n, __old_finish) + ; + std::fill(__position.base(), __position.base() + __n, + __x_copy); + } + else + { + std::__uninitialized_fill_n_a(this->_M_impl._M_finish, + __n - __elems_after, + __x_copy, + _M_get_Tp_allocator()); + this->_M_impl._M_finish += __n - __elems_after; + std::__uninitialized_move_a(__position.base(), __old_finish, + this->_M_impl._M_finish, + _M_get_Tp_allocator()); + this->_M_impl._M_finish += __elems_after; + std::fill(__position.base(), __old_finish, __x_copy); + } + } + else + { + const size_type __len = + _M_check_len(__n, "vector::_M_fill_insert"); + const size_type __elems_before = __position - begin(); + pointer __new_start(this->_M_allocate(__len)); + pointer __new_finish(__new_start); + try + { + + std::__uninitialized_fill_n_a(__new_start + __elems_before, + __n, __x, + _M_get_Tp_allocator()); + __new_finish = 0; + + __new_finish + = std::__uninitialized_move_if_noexcept_a + (this->_M_impl._M_start, __position.base(), + __new_start, _M_get_Tp_allocator()); + + __new_finish += __n; + + __new_finish + = std::__uninitialized_move_if_noexcept_a + (__position.base(), this->_M_impl._M_finish, + __new_finish, _M_get_Tp_allocator()); + } + catch(...) + { + if (!__new_finish) + std::_Destroy(__new_start + __elems_before, + __new_start + __elems_before + __n, + _M_get_Tp_allocator()); + else + std::_Destroy(__new_start, __new_finish, + _M_get_Tp_allocator()); + _M_deallocate(__new_start, __len); + throw; + } + std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, + _M_get_Tp_allocator()); + _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage + - this->_M_impl._M_start); + this->_M_impl._M_start = __new_start; + this->_M_impl._M_finish = __new_finish; + this->_M_impl._M_end_of_storage = __new_start + __len; + } + } + } +# 591 "/usr/include/c++/4.8.2/bits/vector.tcc" 3 + template + template + void + vector<_Tp, _Alloc>:: + _M_range_insert(iterator __pos, _InputIterator __first, + _InputIterator __last, std::input_iterator_tag) + { + for (; __first != __last; ++__first) + { + __pos = insert(__pos, *__first); + ++__pos; + } + } + + template + template + void + vector<_Tp, _Alloc>:: + _M_range_insert(iterator __position, _ForwardIterator __first, + _ForwardIterator __last, std::forward_iterator_tag) + { + if (__first != __last) + { + const size_type __n = std::distance(__first, __last); + if (size_type(this->_M_impl._M_end_of_storage + - this->_M_impl._M_finish) >= __n) + { + const size_type __elems_after = end() - __position; + pointer __old_finish(this->_M_impl._M_finish); + if (__elems_after > __n) + { + std::__uninitialized_move_a(this->_M_impl._M_finish - __n, + this->_M_impl._M_finish, + this->_M_impl._M_finish, + _M_get_Tp_allocator()); + this->_M_impl._M_finish += __n; + std::copy_backward(__position.base(), __old_finish - __n, __old_finish) + ; + std::copy(__first, __last, __position); + } + else + { + _ForwardIterator __mid = __first; + std::advance(__mid, __elems_after); + std::__uninitialized_copy_a(__mid, __last, + this->_M_impl._M_finish, + _M_get_Tp_allocator()); + this->_M_impl._M_finish += __n - __elems_after; + std::__uninitialized_move_a(__position.base(), + __old_finish, + this->_M_impl._M_finish, + _M_get_Tp_allocator()); + this->_M_impl._M_finish += __elems_after; + std::copy(__first, __mid, __position); + } + } + else + { + const size_type __len = + _M_check_len(__n, "vector::_M_range_insert"); + pointer __new_start(this->_M_allocate(__len)); + pointer __new_finish(__new_start); + try + { + __new_finish + = std::__uninitialized_move_if_noexcept_a + (this->_M_impl._M_start, __position.base(), + __new_start, _M_get_Tp_allocator()); + __new_finish + = std::__uninitialized_copy_a(__first, __last, + __new_finish, + _M_get_Tp_allocator()); + __new_finish + = std::__uninitialized_move_if_noexcept_a + (__position.base(), this->_M_impl._M_finish, + __new_finish, _M_get_Tp_allocator()); + } + catch(...) + { + std::_Destroy(__new_start, __new_finish, + _M_get_Tp_allocator()); + _M_deallocate(__new_start, __len); + throw; + } + std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, + _M_get_Tp_allocator()); + _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage + - this->_M_impl._M_start); + this->_M_impl._M_start = __new_start; + this->_M_impl._M_finish = __new_finish; + this->_M_impl._M_end_of_storage = __new_start + __len; + } + } + } + + + + template + void + vector:: + _M_reallocate(size_type __n) + { + _Bit_type* __q = this->_M_allocate(__n); + this->_M_impl._M_finish = _M_copy_aligned(begin(), end(), + iterator(__q, 0)); + this->_M_deallocate(); + this->_M_impl._M_start = iterator(__q, 0); + this->_M_impl._M_end_of_storage = __q + _S_nword(__n); + } + + template + void + vector:: + _M_fill_insert(iterator __position, size_type __n, bool __x) + { + if (__n == 0) + return; + if (capacity() - size() >= __n) + { + std::copy_backward(__position, end(), + this->_M_impl._M_finish + difference_type(__n)); + std::fill(__position, __position + difference_type(__n), __x); + this->_M_impl._M_finish += difference_type(__n); + } + else + { + const size_type __len = + _M_check_len(__n, "vector::_M_fill_insert"); + _Bit_type * __q = this->_M_allocate(__len); + iterator __i = _M_copy_aligned(begin(), __position, + iterator(__q, 0)); + std::fill(__i, __i + difference_type(__n), __x); + this->_M_impl._M_finish = std::copy(__position, end(), + __i + difference_type(__n)); + this->_M_deallocate(); + this->_M_impl._M_end_of_storage = __q + _S_nword(__len); + this->_M_impl._M_start = iterator(__q, 0); + } + } + + template + template + void + vector:: + _M_insert_range(iterator __position, _ForwardIterator __first, + _ForwardIterator __last, std::forward_iterator_tag) + { + if (__first != __last) + { + size_type __n = std::distance(__first, __last); + if (capacity() - size() >= __n) + { + std::copy_backward(__position, end(), + this->_M_impl._M_finish + + difference_type(__n)); + std::copy(__first, __last, __position); + this->_M_impl._M_finish += difference_type(__n); + } + else + { + const size_type __len = + _M_check_len(__n, "vector::_M_insert_range"); + _Bit_type * __q = this->_M_allocate(__len); + iterator __i = _M_copy_aligned(begin(), __position, + iterator(__q, 0)); + __i = std::copy(__first, __last, __i); + this->_M_impl._M_finish = std::copy(__position, end(), __i); + this->_M_deallocate(); + this->_M_impl._M_end_of_storage = __q + _S_nword(__len); + this->_M_impl._M_start = iterator(__q, 0); + } + } + } + + template + void + vector:: + _M_insert_aux(iterator __position, bool __x) + { + if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage) + { + std::copy_backward(__position, this->_M_impl._M_finish, + this->_M_impl._M_finish + 1); + *__position = __x; + ++this->_M_impl._M_finish; + } + else + { + const size_type __len = + _M_check_len(size_type(1), "vector::_M_insert_aux"); + _Bit_type * __q = this->_M_allocate(__len); + iterator __i = _M_copy_aligned(begin(), __position, + iterator(__q, 0)); + *__i++ = __x; + this->_M_impl._M_finish = std::copy(__position, end(), __i); + this->_M_deallocate(); + this->_M_impl._M_end_of_storage = __q + _S_nword(__len); + this->_M_impl._M_start = iterator(__q, 0); + } + } +# 811 "/usr/include/c++/4.8.2/bits/vector.tcc" 3 + +} +# 70 "/usr/include/c++/4.8.2/vector" 2 3 +# 12 "include/CTypedef.h" 2 +# 1 "/usr/include/c++/4.8.2/queue" 1 3 +# 58 "/usr/include/c++/4.8.2/queue" 3 + +# 59 "/usr/include/c++/4.8.2/queue" 3 + +# 1 "/usr/include/c++/4.8.2/deque" 1 3 +# 58 "/usr/include/c++/4.8.2/deque" 3 + +# 59 "/usr/include/c++/4.8.2/deque" 3 + + + + + +# 1 "/usr/include/c++/4.8.2/bits/stl_deque.h" 1 3 +# 66 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 +namespace std __attribute__ ((__visibility__ ("default"))) +{ + +# 88 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 + inline size_t + __deque_buf_size(size_t __size) + { return (__size < 512 + ? size_t(512 / __size) : size_t(1)); } +# 105 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 + template + struct _Deque_iterator + { + typedef _Deque_iterator<_Tp, _Tp&, _Tp*> iterator; + typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator; + + static size_t _S_buffer_size() + { return __deque_buf_size(sizeof(_Tp)); } + + typedef std::random_access_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Ptr pointer; + typedef _Ref reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp** _Map_pointer; + typedef _Deque_iterator _Self; + + _Tp* _M_cur; + _Tp* _M_first; + _Tp* _M_last; + _Map_pointer _M_node; + + _Deque_iterator(_Tp* __x, _Map_pointer __y) + : _M_cur(__x), _M_first(*__y), + _M_last(*__y + _S_buffer_size()), _M_node(__y) { } + + _Deque_iterator() + : _M_cur(0), _M_first(0), _M_last(0), _M_node(0) { } + + _Deque_iterator(const iterator& __x) + : _M_cur(__x._M_cur), _M_first(__x._M_first), + _M_last(__x._M_last), _M_node(__x._M_node) { } + + reference + operator*() const + { return *_M_cur; } + + pointer + operator->() const + { return _M_cur; } + + _Self& + operator++() + { + ++_M_cur; + if (_M_cur == _M_last) + { + _M_set_node(_M_node + 1); + _M_cur = _M_first; + } + return *this; + } + + _Self + operator++(int) + { + _Self __tmp = *this; + ++*this; + return __tmp; + } + + _Self& + operator--() + { + if (_M_cur == _M_first) + { + _M_set_node(_M_node - 1); + _M_cur = _M_last; + } + --_M_cur; + return *this; + } + + _Self + operator--(int) + { + _Self __tmp = *this; + --*this; + return __tmp; + } + + _Self& + operator+=(difference_type __n) + { + const difference_type __offset = __n + (_M_cur - _M_first); + if (__offset >= 0 && __offset < difference_type(_S_buffer_size())) + _M_cur += __n; + else + { + const difference_type __node_offset = + __offset > 0 ? __offset / difference_type(_S_buffer_size()) + : -difference_type((-__offset - 1) + / _S_buffer_size()) - 1; + _M_set_node(_M_node + __node_offset); + _M_cur = _M_first + (__offset - __node_offset + * difference_type(_S_buffer_size())); + } + return *this; + } + + _Self + operator+(difference_type __n) const + { + _Self __tmp = *this; + return __tmp += __n; + } + + _Self& + operator-=(difference_type __n) + { return *this += -__n; } + + _Self + operator-(difference_type __n) const + { + _Self __tmp = *this; + return __tmp -= __n; + } + + reference + operator[](difference_type __n) const + { return *(*this + __n); } + + + + + + + void + _M_set_node(_Map_pointer __new_node) + { + _M_node = __new_node; + _M_first = *__new_node; + _M_last = _M_first + difference_type(_S_buffer_size()); + } + }; + + + + + template + inline bool + operator==(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + { return __x._M_cur == __y._M_cur; } + + template + inline bool + operator==(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { return __x._M_cur == __y._M_cur; } + + template + inline bool + operator!=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + { return !(__x == __y); } + + template + inline bool + operator!=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { return !(__x == __y); } + + template + inline bool + operator<(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + { return (__x._M_node == __y._M_node) ? (__x._M_cur < __y._M_cur) + : (__x._M_node < __y._M_node); } + + template + inline bool + operator<(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { return (__x._M_node == __y._M_node) ? (__x._M_cur < __y._M_cur) + : (__x._M_node < __y._M_node); } + + template + inline bool + operator>(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + { return __y < __x; } + + template + inline bool + operator>(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { return __y < __x; } + + template + inline bool + operator<=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + { return !(__y < __x); } + + template + inline bool + operator<=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { return !(__y < __x); } + + template + inline bool + operator>=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + { return !(__x < __y); } + + template + inline bool + operator>=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { return !(__x < __y); } + + + + + + template + inline typename _Deque_iterator<_Tp, _Ref, _Ptr>::difference_type + operator-(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + { + return typename _Deque_iterator<_Tp, _Ref, _Ptr>::difference_type + (_Deque_iterator<_Tp, _Ref, _Ptr>::_S_buffer_size()) + * (__x._M_node - __y._M_node - 1) + (__x._M_cur - __x._M_first) + + (__y._M_last - __y._M_cur); + } + + template + inline typename _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type + operator-(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { + return typename _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type + (_Deque_iterator<_Tp, _RefL, _PtrL>::_S_buffer_size()) + * (__x._M_node - __y._M_node - 1) + (__x._M_cur - __x._M_first) + + (__y._M_last - __y._M_cur); + } + + template + inline _Deque_iterator<_Tp, _Ref, _Ptr> + operator+(ptrdiff_t __n, const _Deque_iterator<_Tp, _Ref, _Ptr>& __x) + { return __x + __n; } + + template + void + fill(const _Deque_iterator<_Tp, _Tp&, _Tp*>&, + const _Deque_iterator<_Tp, _Tp&, _Tp*>&, const _Tp&); + + template + _Deque_iterator<_Tp, _Tp&, _Tp*> + copy(_Deque_iterator<_Tp, const _Tp&, const _Tp*>, + _Deque_iterator<_Tp, const _Tp&, const _Tp*>, + _Deque_iterator<_Tp, _Tp&, _Tp*>); + + template + inline _Deque_iterator<_Tp, _Tp&, _Tp*> + copy(_Deque_iterator<_Tp, _Tp&, _Tp*> __first, + _Deque_iterator<_Tp, _Tp&, _Tp*> __last, + _Deque_iterator<_Tp, _Tp&, _Tp*> __result) + { return std::copy(_Deque_iterator<_Tp, const _Tp&, const _Tp*>(__first), + _Deque_iterator<_Tp, const _Tp&, const _Tp*>(__last), + __result); } + + template + _Deque_iterator<_Tp, _Tp&, _Tp*> + copy_backward(_Deque_iterator<_Tp, const _Tp&, const _Tp*>, + _Deque_iterator<_Tp, const _Tp&, const _Tp*>, + _Deque_iterator<_Tp, _Tp&, _Tp*>); + + template + inline _Deque_iterator<_Tp, _Tp&, _Tp*> + copy_backward(_Deque_iterator<_Tp, _Tp&, _Tp*> __first, + _Deque_iterator<_Tp, _Tp&, _Tp*> __last, + _Deque_iterator<_Tp, _Tp&, _Tp*> __result) + { return std::copy_backward(_Deque_iterator<_Tp, + const _Tp&, const _Tp*>(__first), + _Deque_iterator<_Tp, + const _Tp&, const _Tp*>(__last), + __result); } +# 438 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 + template + class _Deque_base + { + public: + typedef _Alloc allocator_type; + + allocator_type + get_allocator() const + { return allocator_type(_M_get_Tp_allocator()); } + + typedef _Deque_iterator<_Tp, _Tp&, _Tp*> iterator; + typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator; + + _Deque_base() + : _M_impl() + { _M_initialize_map(0); } + + _Deque_base(size_t __num_elements) + : _M_impl() + { _M_initialize_map(__num_elements); } + + _Deque_base(const allocator_type& __a, size_t __num_elements) + : _M_impl(__a) + { _M_initialize_map(__num_elements); } + + _Deque_base(const allocator_type& __a) + : _M_impl(__a) + { } +# 482 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 + ~_Deque_base(); + + protected: + + + + typedef typename _Alloc::template rebind<_Tp*>::other _Map_alloc_type; + + typedef typename _Alloc::template rebind<_Tp>::other _Tp_alloc_type; + + struct _Deque_impl + : public _Tp_alloc_type + { + _Tp** _M_map; + size_t _M_map_size; + iterator _M_start; + iterator _M_finish; + + _Deque_impl() + : _Tp_alloc_type(), _M_map(0), _M_map_size(0), + _M_start(), _M_finish() + { } + + _Deque_impl(const _Tp_alloc_type& __a) + : _Tp_alloc_type(__a), _M_map(0), _M_map_size(0), + _M_start(), _M_finish() + { } + + + + + + + + }; + + _Tp_alloc_type& + _M_get_Tp_allocator() + { return *static_cast<_Tp_alloc_type*>(&this->_M_impl); } + + const _Tp_alloc_type& + _M_get_Tp_allocator() const + { return *static_cast(&this->_M_impl); } + + _Map_alloc_type + _M_get_map_allocator() const + { return _Map_alloc_type(_M_get_Tp_allocator()); } + + _Tp* + _M_allocate_node() + { + return _M_impl._Tp_alloc_type::allocate(__deque_buf_size(sizeof(_Tp))); + } + + void + _M_deallocate_node(_Tp* __p) + { + _M_impl._Tp_alloc_type::deallocate(__p, __deque_buf_size(sizeof(_Tp))); + } + + _Tp** + _M_allocate_map(size_t __n) + { return _M_get_map_allocator().allocate(__n); } + + void + _M_deallocate_map(_Tp** __p, size_t __n) + { _M_get_map_allocator().deallocate(__p, __n); } + + protected: + void _M_initialize_map(size_t); + void _M_create_nodes(_Tp** __nstart, _Tp** __nfinish); + void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish); + enum { _S_initial_map_size = 8 }; + + _Deque_impl _M_impl; + }; + + template + _Deque_base<_Tp, _Alloc>:: + ~_Deque_base() + { + if (this->_M_impl._M_map) + { + _M_destroy_nodes(this->_M_impl._M_start._M_node, + this->_M_impl._M_finish._M_node + 1); + _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size); + } + } +# 579 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 + template + void + _Deque_base<_Tp, _Alloc>:: + _M_initialize_map(size_t __num_elements) + { + const size_t __num_nodes = (__num_elements/ __deque_buf_size(sizeof(_Tp)) + + 1); + + this->_M_impl._M_map_size = std::max((size_t) _S_initial_map_size, + size_t(__num_nodes + 2)); + this->_M_impl._M_map = _M_allocate_map(this->_M_impl._M_map_size); + + + + + + + _Tp** __nstart = (this->_M_impl._M_map + + (this->_M_impl._M_map_size - __num_nodes) / 2); + _Tp** __nfinish = __nstart + __num_nodes; + + try + { _M_create_nodes(__nstart, __nfinish); } + catch(...) + { + _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size); + this->_M_impl._M_map = 0; + this->_M_impl._M_map_size = 0; + throw; + } + + this->_M_impl._M_start._M_set_node(__nstart); + this->_M_impl._M_finish._M_set_node(__nfinish - 1); + this->_M_impl._M_start._M_cur = _M_impl._M_start._M_first; + this->_M_impl._M_finish._M_cur = (this->_M_impl._M_finish._M_first + + __num_elements + % __deque_buf_size(sizeof(_Tp))); + } + + template + void + _Deque_base<_Tp, _Alloc>:: + _M_create_nodes(_Tp** __nstart, _Tp** __nfinish) + { + _Tp** __cur; + try + { + for (__cur = __nstart; __cur < __nfinish; ++__cur) + *__cur = this->_M_allocate_node(); + } + catch(...) + { + _M_destroy_nodes(__nstart, __cur); + throw; + } + } + + template + void + _Deque_base<_Tp, _Alloc>:: + _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish) + { + for (_Tp** __n = __nstart; __n < __nfinish; ++__n) + _M_deallocate_node(*__n); + } +# 729 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 + template > + class deque : protected _Deque_base<_Tp, _Alloc> + { + + typedef typename _Alloc::value_type _Alloc_value_type; + + + + typedef _Deque_base<_Tp, _Alloc> _Base; + typedef typename _Base::_Tp_alloc_type _Tp_alloc_type; + + public: + typedef _Tp value_type; + typedef typename _Tp_alloc_type::pointer pointer; + typedef typename _Tp_alloc_type::const_pointer const_pointer; + typedef typename _Tp_alloc_type::reference reference; + typedef typename _Tp_alloc_type::const_reference const_reference; + typedef typename _Base::iterator iterator; + typedef typename _Base::const_iterator const_iterator; + typedef std::reverse_iterator const_reverse_iterator; + typedef std::reverse_iterator reverse_iterator; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Alloc allocator_type; + + protected: + typedef pointer* _Map_pointer; + + static size_t _S_buffer_size() + { return __deque_buf_size(sizeof(_Tp)); } + + + using _Base::_M_initialize_map; + using _Base::_M_create_nodes; + using _Base::_M_destroy_nodes; + using _Base::_M_allocate_node; + using _Base::_M_deallocate_node; + using _Base::_M_allocate_map; + using _Base::_M_deallocate_map; + using _Base::_M_get_Tp_allocator; + + + + + + using _Base::_M_impl; + + public: + + + + + + deque() + : _Base() { } + + + + + + explicit + deque(const allocator_type& __a) + : _Base(__a, 0) { } +# 827 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 + explicit + deque(size_type __n, const value_type& __value = value_type(), + const allocator_type& __a = allocator_type()) + : _Base(__a, __n) + { _M_fill_initialize(__value); } +# 841 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 + deque(const deque& __x) + : _Base(__x._M_get_Tp_allocator(), __x.size()) + { std::__uninitialized_copy_a(__x.begin(), __x.end(), + this->_M_impl._M_start, + _M_get_Tp_allocator()); } +# 901 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 + template + deque(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { + + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + _M_initialize_dispatch(__first, __last, _Integral()); + } + + + + + + + + ~deque() + { _M_destroy_data(begin(), end(), _M_get_Tp_allocator()); } +# 927 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 + deque& + operator=(const deque& __x); +# 977 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 + void + assign(size_type __n, const value_type& __val) + { _M_fill_assign(__n, __val); } +# 1000 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 + template + void + assign(_InputIterator __first, _InputIterator __last) + { + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } +# 1027 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 + allocator_type + get_allocator() const + { return _Base::get_allocator(); } + + + + + + + iterator + begin() + { return this->_M_impl._M_start; } + + + + + + const_iterator + begin() const + { return this->_M_impl._M_start; } + + + + + + + iterator + end() + { return this->_M_impl._M_finish; } + + + + + + + const_iterator + end() const + { return this->_M_impl._M_finish; } + + + + + + + reverse_iterator + rbegin() + { return reverse_iterator(this->_M_impl._M_finish); } + + + + + + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(this->_M_impl._M_finish); } + + + + + + + reverse_iterator + rend() + { return reverse_iterator(this->_M_impl._M_start); } + + + + + + + const_reverse_iterator + rend() const + { return const_reverse_iterator(this->_M_impl._M_start); } +# 1141 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 + size_type + size() const + { return this->_M_impl._M_finish - this->_M_impl._M_start; } + + + size_type + max_size() const + { return _M_get_Tp_allocator().max_size(); } +# 1204 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 + void + resize(size_type __new_size, value_type __x = value_type()) + { + const size_type __len = size(); + if (__new_size > __len) + insert(this->_M_impl._M_finish, __new_size - __len, __x); + else if (__new_size < __len) + _M_erase_at_end(this->_M_impl._M_start + + difference_type(__new_size)); + } +# 1227 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 + bool + empty() const + { return this->_M_impl._M_finish == this->_M_impl._M_start; } +# 1243 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 + reference + operator[](size_type __n) + { return this->_M_impl._M_start[difference_type(__n)]; } +# 1258 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 + const_reference + operator[](size_type __n) const + { return this->_M_impl._M_start[difference_type(__n)]; } + + protected: + + void + _M_range_check(size_type __n) const + { + if (__n >= this->size()) + __throw_out_of_range(("deque::_M_range_check")); + } + + public: +# 1283 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 + reference + at(size_type __n) + { + _M_range_check(__n); + return (*this)[__n]; + } +# 1301 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 + const_reference + at(size_type __n) const + { + _M_range_check(__n); + return (*this)[__n]; + } + + + + + + reference + front() + { return *begin(); } + + + + + + const_reference + front() const + { return *begin(); } + + + + + + reference + back() + { + iterator __tmp = end(); + --__tmp; + return *__tmp; + } + + + + + + const_reference + back() const + { + const_iterator __tmp = end(); + --__tmp; + return *__tmp; + } +# 1358 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 + void + push_front(const value_type& __x) + { + if (this->_M_impl._M_start._M_cur != this->_M_impl._M_start._M_first) + { + this->_M_impl.construct(this->_M_impl._M_start._M_cur - 1, __x); + --this->_M_impl._M_start._M_cur; + } + else + _M_push_front_aux(__x); + } +# 1389 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 + void + push_back(const value_type& __x) + { + if (this->_M_impl._M_finish._M_cur + != this->_M_impl._M_finish._M_last - 1) + { + this->_M_impl.construct(this->_M_impl._M_finish._M_cur, __x); + ++this->_M_impl._M_finish._M_cur; + } + else + _M_push_back_aux(__x); + } +# 1420 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 + void + pop_front() + { + if (this->_M_impl._M_start._M_cur + != this->_M_impl._M_start._M_last - 1) + { + this->_M_impl.destroy(this->_M_impl._M_start._M_cur); + ++this->_M_impl._M_start._M_cur; + } + else + _M_pop_front_aux(); + } +# 1441 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 + void + pop_back() + { + if (this->_M_impl._M_finish._M_cur + != this->_M_impl._M_finish._M_first) + { + --this->_M_impl._M_finish._M_cur; + this->_M_impl.destroy(this->_M_impl._M_finish._M_cur); + } + else + _M_pop_back_aux(); + } +# 1478 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 + iterator + insert(iterator __position, const value_type& __x); +# 1518 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 + void + insert(iterator __position, size_type __n, const value_type& __x) + { _M_fill_insert(__position, __n, __x); } +# 1540 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 + template + void + insert(iterator __position, _InputIterator __first, + _InputIterator __last) + { + + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + _M_insert_dispatch(__position, __first, __last, _Integral()); + } +# 1564 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 + iterator + erase(iterator __position); +# 1583 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 + iterator + erase(iterator __first, iterator __last); +# 1595 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 + void + swap(deque& __x) + { + std::swap(this->_M_impl._M_start, __x._M_impl._M_start); + std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish); + std::swap(this->_M_impl._M_map, __x._M_impl._M_map); + std::swap(this->_M_impl._M_map_size, __x._M_impl._M_map_size); + + + + std::__alloc_swap<_Tp_alloc_type>::_S_do_it(_M_get_Tp_allocator(), + __x._M_get_Tp_allocator()); + } + + + + + + + + void + clear() + { _M_erase_at_end(begin()); } + + protected: + + + + + + + template + void + _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) + { + _M_initialize_map(static_cast(__n)); + _M_fill_initialize(__x); + } + + + template + void + _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) + { + typedef typename std::iterator_traits<_InputIterator>:: + iterator_category _IterCategory; + _M_range_initialize(__first, __last, _IterCategory()); + } +# 1657 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 + template + void + _M_range_initialize(_InputIterator __first, _InputIterator __last, + std::input_iterator_tag); + + + template + void + _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last, + std::forward_iterator_tag); +# 1679 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 + void + _M_fill_initialize(const value_type& __value); +# 1695 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 + template + void + _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { _M_fill_assign(__n, __val); } + + + template + void + _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) + { + typedef typename std::iterator_traits<_InputIterator>:: + iterator_category _IterCategory; + _M_assign_aux(__first, __last, _IterCategory()); + } + + + template + void + _M_assign_aux(_InputIterator __first, _InputIterator __last, + std::input_iterator_tag); + + + template + void + _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, + std::forward_iterator_tag) + { + const size_type __len = std::distance(__first, __last); + if (__len > size()) + { + _ForwardIterator __mid = __first; + std::advance(__mid, size()); + std::copy(__first, __mid, begin()); + insert(end(), __mid, __last); + } + else + _M_erase_at_end(std::copy(__first, __last, begin())); + } + + + + void + _M_fill_assign(size_type __n, const value_type& __val) + { + if (__n > size()) + { + std::fill(begin(), end(), __val); + insert(end(), __n - size(), __val); + } + else + { + _M_erase_at_end(begin() + difference_type(__n)); + std::fill(begin(), end(), __val); + } + } + + + + + void _M_push_back_aux(const value_type&); + + void _M_push_front_aux(const value_type&); +# 1766 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 + void _M_pop_back_aux(); + + void _M_pop_front_aux(); +# 1778 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 + template + void + _M_insert_dispatch(iterator __pos, + _Integer __n, _Integer __x, __true_type) + { _M_fill_insert(__pos, __n, __x); } + + + template + void + _M_insert_dispatch(iterator __pos, + _InputIterator __first, _InputIterator __last, + __false_type) + { + typedef typename std::iterator_traits<_InputIterator>:: + iterator_category _IterCategory; + _M_range_insert_aux(__pos, __first, __last, _IterCategory()); + } + + + template + void + _M_range_insert_aux(iterator __pos, _InputIterator __first, + _InputIterator __last, std::input_iterator_tag); + + + template + void + _M_range_insert_aux(iterator __pos, _ForwardIterator __first, + _ForwardIterator __last, std::forward_iterator_tag); + + + + + void + _M_fill_insert(iterator __pos, size_type __n, const value_type& __x); + + + + iterator + _M_insert_aux(iterator __pos, const value_type& __x); + + + + + + + + void + _M_insert_aux(iterator __pos, size_type __n, const value_type& __x); + + + template + void + _M_insert_aux(iterator __pos, + _ForwardIterator __first, _ForwardIterator __last, + size_type __n); + + + + + void + _M_destroy_data_aux(iterator __first, iterator __last); + + + + template + void + _M_destroy_data(iterator __first, iterator __last, const _Alloc1&) + { _M_destroy_data_aux(__first, __last); } + + void + _M_destroy_data(iterator __first, iterator __last, + const std::allocator<_Tp>&) + { + if (!__has_trivial_destructor(value_type)) + _M_destroy_data_aux(__first, __last); + } + + + void + _M_erase_at_begin(iterator __pos) + { + _M_destroy_data(begin(), __pos, _M_get_Tp_allocator()); + _M_destroy_nodes(this->_M_impl._M_start._M_node, __pos._M_node); + this->_M_impl._M_start = __pos; + } + + + + void + _M_erase_at_end(iterator __pos) + { + _M_destroy_data(__pos, end(), _M_get_Tp_allocator()); + _M_destroy_nodes(__pos._M_node + 1, + this->_M_impl._M_finish._M_node + 1); + this->_M_impl._M_finish = __pos; + } +# 1887 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 + iterator + _M_reserve_elements_at_front(size_type __n) + { + const size_type __vacancies = this->_M_impl._M_start._M_cur + - this->_M_impl._M_start._M_first; + if (__n > __vacancies) + _M_new_elements_at_front(__n - __vacancies); + return this->_M_impl._M_start - difference_type(__n); + } + + iterator + _M_reserve_elements_at_back(size_type __n) + { + const size_type __vacancies = (this->_M_impl._M_finish._M_last + - this->_M_impl._M_finish._M_cur) - 1; + if (__n > __vacancies) + _M_new_elements_at_back(__n - __vacancies); + return this->_M_impl._M_finish + difference_type(__n); + } + + void + _M_new_elements_at_front(size_type __new_elements); + + void + _M_new_elements_at_back(size_type __new_elements); +# 1923 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 + void + _M_reserve_map_at_back(size_type __nodes_to_add = 1) + { + if (__nodes_to_add + 1 > this->_M_impl._M_map_size + - (this->_M_impl._M_finish._M_node - this->_M_impl._M_map)) + _M_reallocate_map(__nodes_to_add, false); + } + + void + _M_reserve_map_at_front(size_type __nodes_to_add = 1) + { + if (__nodes_to_add > size_type(this->_M_impl._M_start._M_node + - this->_M_impl._M_map)) + _M_reallocate_map(__nodes_to_add, true); + } + + void + _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front); + + }; +# 1955 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 + template + inline bool + operator==(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) + { return __x.size() == __y.size() + && std::equal(__x.begin(), __x.end(), __y.begin()); } +# 1973 "/usr/include/c++/4.8.2/bits/stl_deque.h" 3 + template + inline bool + operator<(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) + { return std::lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); } + + + template + inline bool + operator!=(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) + { return !(__x == __y); } + + + template + inline bool + operator>(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) + { return __y < __x; } + + + template + inline bool + operator<=(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) + { return !(__y < __x); } + + + template + inline bool + operator>=(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) + { return !(__x < __y); } + + + template + inline void + swap(deque<_Tp,_Alloc>& __x, deque<_Tp,_Alloc>& __y) + { __x.swap(__y); } + + + + +} +# 65 "/usr/include/c++/4.8.2/deque" 2 3 + +# 1 "/usr/include/c++/4.8.2/bits/deque.tcc" 1 3 +# 59 "/usr/include/c++/4.8.2/bits/deque.tcc" 3 +namespace std __attribute__ ((__visibility__ ("default"))) +{ + +# 90 "/usr/include/c++/4.8.2/bits/deque.tcc" 3 + template + deque<_Tp, _Alloc>& + deque<_Tp, _Alloc>:: + operator=(const deque& __x) + { + const size_type __len = size(); + if (&__x != this) + { + if (__len >= __x.size()) + _M_erase_at_end(std::copy(__x.begin(), __x.end(), + this->_M_impl._M_start)); + else + { + const_iterator __mid = __x.begin() + difference_type(__len); + std::copy(__x.begin(), __mid, this->_M_impl._M_start); + insert(this->_M_impl._M_finish, __mid, __x.end()); + } + } + return *this; + } +# 146 "/usr/include/c++/4.8.2/bits/deque.tcc" 3 + template + typename deque<_Tp, _Alloc>::iterator + deque<_Tp, _Alloc>:: + insert(iterator __position, const value_type& __x) + { + if (__position._M_cur == this->_M_impl._M_start._M_cur) + { + push_front(__x); + return this->_M_impl._M_start; + } + else if (__position._M_cur == this->_M_impl._M_finish._M_cur) + { + push_back(__x); + iterator __tmp = this->_M_impl._M_finish; + --__tmp; + return __tmp; + } + else + return _M_insert_aux(__position, __x); + } +# 191 "/usr/include/c++/4.8.2/bits/deque.tcc" 3 + template + typename deque<_Tp, _Alloc>::iterator + deque<_Tp, _Alloc>:: + erase(iterator __position) + { + iterator __next = __position; + ++__next; + const difference_type __index = __position - begin(); + if (static_cast(__index) < (size() >> 1)) + { + if (__position != begin()) + std::copy_backward(begin(), __position, __next); + pop_front(); + } + else + { + if (__next != end()) + std::copy(__next, end(), __position); + pop_back(); + } + return begin() + __index; + } + + template + typename deque<_Tp, _Alloc>::iterator + deque<_Tp, _Alloc>:: + erase(iterator __first, iterator __last) + { + if (__first == __last) + return __first; + else if (__first == begin() && __last == end()) + { + clear(); + return end(); + } + else + { + const difference_type __n = __last - __first; + const difference_type __elems_before = __first - begin(); + if (static_cast(__elems_before) <= (size() - __n) / 2) + { + if (__first != begin()) + std::copy_backward(begin(), __first, __last); + _M_erase_at_begin(begin() + __n); + } + else + { + if (__last != end()) + std::copy(__last, end(), __first); + _M_erase_at_end(end() - __n); + } + return begin() + __elems_before; + } + } + + template + template + void + deque<_Tp, _Alloc>:: + _M_assign_aux(_InputIterator __first, _InputIterator __last, + std::input_iterator_tag) + { + iterator __cur = begin(); + for (; __first != __last && __cur != end(); ++__cur, ++__first) + *__cur = *__first; + if (__first == __last) + _M_erase_at_end(__cur); + else + insert(end(), __first, __last); + } + + template + void + deque<_Tp, _Alloc>:: + _M_fill_insert(iterator __pos, size_type __n, const value_type& __x) + { + if (__pos._M_cur == this->_M_impl._M_start._M_cur) + { + iterator __new_start = _M_reserve_elements_at_front(__n); + try + { + std::__uninitialized_fill_a(__new_start, this->_M_impl._M_start, + __x, _M_get_Tp_allocator()); + this->_M_impl._M_start = __new_start; + } + catch(...) + { + _M_destroy_nodes(__new_start._M_node, + this->_M_impl._M_start._M_node); + throw; + } + } + else if (__pos._M_cur == this->_M_impl._M_finish._M_cur) + { + iterator __new_finish = _M_reserve_elements_at_back(__n); + try + { + std::__uninitialized_fill_a(this->_M_impl._M_finish, + __new_finish, __x, + _M_get_Tp_allocator()); + this->_M_impl._M_finish = __new_finish; + } + catch(...) + { + _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, + __new_finish._M_node + 1); + throw; + } + } + else + _M_insert_aux(__pos, __n, __x); + } +# 348 "/usr/include/c++/4.8.2/bits/deque.tcc" 3 + template + void + deque<_Tp, _Alloc>:: + _M_fill_initialize(const value_type& __value) + { + _Map_pointer __cur; + try + { + for (__cur = this->_M_impl._M_start._M_node; + __cur < this->_M_impl._M_finish._M_node; + ++__cur) + std::__uninitialized_fill_a(*__cur, *__cur + _S_buffer_size(), + __value, _M_get_Tp_allocator()); + std::__uninitialized_fill_a(this->_M_impl._M_finish._M_first, + this->_M_impl._M_finish._M_cur, + __value, _M_get_Tp_allocator()); + } + catch(...) + { + std::_Destroy(this->_M_impl._M_start, iterator(*__cur, __cur), + _M_get_Tp_allocator()); + throw; + } + } + + template + template + void + deque<_Tp, _Alloc>:: + _M_range_initialize(_InputIterator __first, _InputIterator __last, + std::input_iterator_tag) + { + this->_M_initialize_map(0); + try + { + for (; __first != __last; ++__first) + + + + push_back(*__first); + + } + catch(...) + { + clear(); + throw; + } + } + + template + template + void + deque<_Tp, _Alloc>:: + _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last, + std::forward_iterator_tag) + { + const size_type __n = std::distance(__first, __last); + this->_M_initialize_map(__n); + + _Map_pointer __cur_node; + try + { + for (__cur_node = this->_M_impl._M_start._M_node; + __cur_node < this->_M_impl._M_finish._M_node; + ++__cur_node) + { + _ForwardIterator __mid = __first; + std::advance(__mid, _S_buffer_size()); + std::__uninitialized_copy_a(__first, __mid, *__cur_node, + _M_get_Tp_allocator()); + __first = __mid; + } + std::__uninitialized_copy_a(__first, __last, + this->_M_impl._M_finish._M_first, + _M_get_Tp_allocator()); + } + catch(...) + { + std::_Destroy(this->_M_impl._M_start, + iterator(*__cur_node, __cur_node), + _M_get_Tp_allocator()); + throw; + } + } + + + template + + + + + + + void + deque<_Tp, _Alloc>:: + _M_push_back_aux(const value_type& __t) + + { + _M_reserve_map_at_back(); + *(this->_M_impl._M_finish._M_node + 1) = this->_M_allocate_node(); + try + { + + + + + this->_M_impl.construct(this->_M_impl._M_finish._M_cur, __t); + + this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node + + 1); + this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_first; + } + catch(...) + { + _M_deallocate_node(*(this->_M_impl._M_finish._M_node + 1)); + throw; + } + } + + + template + + + + + + + void + deque<_Tp, _Alloc>:: + _M_push_front_aux(const value_type& __t) + + { + _M_reserve_map_at_front(); + *(this->_M_impl._M_start._M_node - 1) = this->_M_allocate_node(); + try + { + this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node + - 1); + this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_last - 1; + + + + + this->_M_impl.construct(this->_M_impl._M_start._M_cur, __t); + + } + catch(...) + { + ++this->_M_impl._M_start; + _M_deallocate_node(*(this->_M_impl._M_start._M_node - 1)); + throw; + } + } + + + template + void deque<_Tp, _Alloc>:: + _M_pop_back_aux() + { + _M_deallocate_node(this->_M_impl._M_finish._M_first); + this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node - 1); + this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_last - 1; + this->_M_impl.destroy(this->_M_impl._M_finish._M_cur); + } + + + + + + + template + void deque<_Tp, _Alloc>:: + _M_pop_front_aux() + { + this->_M_impl.destroy(this->_M_impl._M_start._M_cur); + _M_deallocate_node(this->_M_impl._M_start._M_first); + this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node + 1); + this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_first; + } + + template + template + void + deque<_Tp, _Alloc>:: + _M_range_insert_aux(iterator __pos, + _InputIterator __first, _InputIterator __last, + std::input_iterator_tag) + { std::copy(__first, __last, std::inserter(*this, __pos)); } + + template + template + void + deque<_Tp, _Alloc>:: + _M_range_insert_aux(iterator __pos, + _ForwardIterator __first, _ForwardIterator __last, + std::forward_iterator_tag) + { + const size_type __n = std::distance(__first, __last); + if (__pos._M_cur == this->_M_impl._M_start._M_cur) + { + iterator __new_start = _M_reserve_elements_at_front(__n); + try + { + std::__uninitialized_copy_a(__first, __last, __new_start, + _M_get_Tp_allocator()); + this->_M_impl._M_start = __new_start; + } + catch(...) + { + _M_destroy_nodes(__new_start._M_node, + this->_M_impl._M_start._M_node); + throw; + } + } + else if (__pos._M_cur == this->_M_impl._M_finish._M_cur) + { + iterator __new_finish = _M_reserve_elements_at_back(__n); + try + { + std::__uninitialized_copy_a(__first, __last, + this->_M_impl._M_finish, + _M_get_Tp_allocator()); + this->_M_impl._M_finish = __new_finish; + } + catch(...) + { + _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, + __new_finish._M_node + 1); + throw; + } + } + else + _M_insert_aux(__pos, __first, __last, __n); + } + + template +# 592 "/usr/include/c++/4.8.2/bits/deque.tcc" 3 + typename deque<_Tp, _Alloc>::iterator + deque<_Tp, _Alloc>:: + _M_insert_aux(iterator __pos, const value_type& __x) + { + value_type __x_copy = __x; + + difference_type __index = __pos - this->_M_impl._M_start; + if (static_cast(__index) < size() / 2) + { + push_front((front())); + iterator __front1 = this->_M_impl._M_start; + ++__front1; + iterator __front2 = __front1; + ++__front2; + __pos = this->_M_impl._M_start + __index; + iterator __pos1 = __pos; + ++__pos1; + std::copy(__front2, __pos1, __front1); + } + else + { + push_back((back())); + iterator __back1 = this->_M_impl._M_finish; + --__back1; + iterator __back2 = __back1; + --__back2; + __pos = this->_M_impl._M_start + __index; + std::copy_backward(__pos, __back2, __back1); + } + *__pos = (__x_copy); + return __pos; + } + + template + void + deque<_Tp, _Alloc>:: + _M_insert_aux(iterator __pos, size_type __n, const value_type& __x) + { + const difference_type __elems_before = __pos - this->_M_impl._M_start; + const size_type __length = this->size(); + value_type __x_copy = __x; + if (__elems_before < difference_type(__length / 2)) + { + iterator __new_start = _M_reserve_elements_at_front(__n); + iterator __old_start = this->_M_impl._M_start; + __pos = this->_M_impl._M_start + __elems_before; + try + { + if (__elems_before >= difference_type(__n)) + { + iterator __start_n = (this->_M_impl._M_start + + difference_type(__n)); + std::__uninitialized_move_a(this->_M_impl._M_start, + __start_n, __new_start, + _M_get_Tp_allocator()); + this->_M_impl._M_start = __new_start; + std::copy(__start_n, __pos, __old_start); + std::fill(__pos - difference_type(__n), __pos, __x_copy); + } + else + { + std::__uninitialized_move_fill(this->_M_impl._M_start, + __pos, __new_start, + this->_M_impl._M_start, + __x_copy, + _M_get_Tp_allocator()); + this->_M_impl._M_start = __new_start; + std::fill(__old_start, __pos, __x_copy); + } + } + catch(...) + { + _M_destroy_nodes(__new_start._M_node, + this->_M_impl._M_start._M_node); + throw; + } + } + else + { + iterator __new_finish = _M_reserve_elements_at_back(__n); + iterator __old_finish = this->_M_impl._M_finish; + const difference_type __elems_after = + difference_type(__length) - __elems_before; + __pos = this->_M_impl._M_finish - __elems_after; + try + { + if (__elems_after > difference_type(__n)) + { + iterator __finish_n = (this->_M_impl._M_finish + - difference_type(__n)); + std::__uninitialized_move_a(__finish_n, + this->_M_impl._M_finish, + this->_M_impl._M_finish, + _M_get_Tp_allocator()); + this->_M_impl._M_finish = __new_finish; + std::copy_backward(__pos, __finish_n, __old_finish); + std::fill(__pos, __pos + difference_type(__n), __x_copy); + } + else + { + std::__uninitialized_fill_move(this->_M_impl._M_finish, + __pos + difference_type(__n), + __x_copy, __pos, + this->_M_impl._M_finish, + _M_get_Tp_allocator()); + this->_M_impl._M_finish = __new_finish; + std::fill(__pos, __old_finish, __x_copy); + } + } + catch(...) + { + _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, + __new_finish._M_node + 1); + throw; + } + } + } + + template + template + void + deque<_Tp, _Alloc>:: + _M_insert_aux(iterator __pos, + _ForwardIterator __first, _ForwardIterator __last, + size_type __n) + { + const difference_type __elemsbefore = __pos - this->_M_impl._M_start; + const size_type __length = size(); + if (static_cast(__elemsbefore) < __length / 2) + { + iterator __new_start = _M_reserve_elements_at_front(__n); + iterator __old_start = this->_M_impl._M_start; + __pos = this->_M_impl._M_start + __elemsbefore; + try + { + if (__elemsbefore >= difference_type(__n)) + { + iterator __start_n = (this->_M_impl._M_start + + difference_type(__n)); + std::__uninitialized_move_a(this->_M_impl._M_start, + __start_n, __new_start, + _M_get_Tp_allocator()); + this->_M_impl._M_start = __new_start; + std::copy(__start_n, __pos, __old_start); + std::copy(__first, __last, __pos - difference_type(__n)); + } + else + { + _ForwardIterator __mid = __first; + std::advance(__mid, difference_type(__n) - __elemsbefore); + std::__uninitialized_move_copy(this->_M_impl._M_start, + __pos, __first, __mid, + __new_start, + _M_get_Tp_allocator()); + this->_M_impl._M_start = __new_start; + std::copy(__mid, __last, __old_start); + } + } + catch(...) + { + _M_destroy_nodes(__new_start._M_node, + this->_M_impl._M_start._M_node); + throw; + } + } + else + { + iterator __new_finish = _M_reserve_elements_at_back(__n); + iterator __old_finish = this->_M_impl._M_finish; + const difference_type __elemsafter = + difference_type(__length) - __elemsbefore; + __pos = this->_M_impl._M_finish - __elemsafter; + try + { + if (__elemsafter > difference_type(__n)) + { + iterator __finish_n = (this->_M_impl._M_finish + - difference_type(__n)); + std::__uninitialized_move_a(__finish_n, + this->_M_impl._M_finish, + this->_M_impl._M_finish, + _M_get_Tp_allocator()); + this->_M_impl._M_finish = __new_finish; + std::copy_backward(__pos, __finish_n, __old_finish); + std::copy(__first, __last, __pos); + } + else + { + _ForwardIterator __mid = __first; + std::advance(__mid, __elemsafter); + std::__uninitialized_copy_move(__mid, __last, __pos, + this->_M_impl._M_finish, + this->_M_impl._M_finish, + _M_get_Tp_allocator()); + this->_M_impl._M_finish = __new_finish; + std::copy(__first, __mid, __pos); + } + } + catch(...) + { + _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, + __new_finish._M_node + 1); + throw; + } + } + } + + template + void + deque<_Tp, _Alloc>:: + _M_destroy_data_aux(iterator __first, iterator __last) + { + for (_Map_pointer __node = __first._M_node + 1; + __node < __last._M_node; ++__node) + std::_Destroy(*__node, *__node + _S_buffer_size(), + _M_get_Tp_allocator()); + + if (__first._M_node != __last._M_node) + { + std::_Destroy(__first._M_cur, __first._M_last, + _M_get_Tp_allocator()); + std::_Destroy(__last._M_first, __last._M_cur, + _M_get_Tp_allocator()); + } + else + std::_Destroy(__first._M_cur, __last._M_cur, + _M_get_Tp_allocator()); + } + + template + void + deque<_Tp, _Alloc>:: + _M_new_elements_at_front(size_type __new_elems) + { + if (this->max_size() - this->size() < __new_elems) + __throw_length_error(("deque::_M_new_elements_at_front")); + + const size_type __new_nodes = ((__new_elems + _S_buffer_size() - 1) + / _S_buffer_size()); + _M_reserve_map_at_front(__new_nodes); + size_type __i; + try + { + for (__i = 1; __i <= __new_nodes; ++__i) + *(this->_M_impl._M_start._M_node - __i) = this->_M_allocate_node(); + } + catch(...) + { + for (size_type __j = 1; __j < __i; ++__j) + _M_deallocate_node(*(this->_M_impl._M_start._M_node - __j)); + throw; + } + } + + template + void + deque<_Tp, _Alloc>:: + _M_new_elements_at_back(size_type __new_elems) + { + if (this->max_size() - this->size() < __new_elems) + __throw_length_error(("deque::_M_new_elements_at_back")); + + const size_type __new_nodes = ((__new_elems + _S_buffer_size() - 1) + / _S_buffer_size()); + _M_reserve_map_at_back(__new_nodes); + size_type __i; + try + { + for (__i = 1; __i <= __new_nodes; ++__i) + *(this->_M_impl._M_finish._M_node + __i) = this->_M_allocate_node(); + } + catch(...) + { + for (size_type __j = 1; __j < __i; ++__j) + _M_deallocate_node(*(this->_M_impl._M_finish._M_node + __j)); + throw; + } + } + + template + void + deque<_Tp, _Alloc>:: + _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front) + { + const size_type __old_num_nodes + = this->_M_impl._M_finish._M_node - this->_M_impl._M_start._M_node + 1; + const size_type __new_num_nodes = __old_num_nodes + __nodes_to_add; + + _Map_pointer __new_nstart; + if (this->_M_impl._M_map_size > 2 * __new_num_nodes) + { + __new_nstart = this->_M_impl._M_map + (this->_M_impl._M_map_size + - __new_num_nodes) / 2 + + (__add_at_front ? __nodes_to_add : 0); + if (__new_nstart < this->_M_impl._M_start._M_node) + std::copy(this->_M_impl._M_start._M_node, + this->_M_impl._M_finish._M_node + 1, + __new_nstart); + else + std::copy_backward(this->_M_impl._M_start._M_node, + this->_M_impl._M_finish._M_node + 1, + __new_nstart + __old_num_nodes); + } + else + { + size_type __new_map_size = this->_M_impl._M_map_size + + std::max(this->_M_impl._M_map_size, + __nodes_to_add) + 2; + + _Map_pointer __new_map = this->_M_allocate_map(__new_map_size); + __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2 + + (__add_at_front ? __nodes_to_add : 0); + std::copy(this->_M_impl._M_start._M_node, + this->_M_impl._M_finish._M_node + 1, + __new_nstart); + _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size); + + this->_M_impl._M_map = __new_map; + this->_M_impl._M_map_size = __new_map_size; + } + + this->_M_impl._M_start._M_set_node(__new_nstart); + this->_M_impl._M_finish._M_set_node(__new_nstart + __old_num_nodes - 1); + } + + + + template + void + fill(const _Deque_iterator<_Tp, _Tp&, _Tp*>& __first, + const _Deque_iterator<_Tp, _Tp&, _Tp*>& __last, const _Tp& __value) + { + typedef typename _Deque_iterator<_Tp, _Tp&, _Tp*>::_Self _Self; + + for (typename _Self::_Map_pointer __node = __first._M_node + 1; + __node < __last._M_node; ++__node) + std::fill(*__node, *__node + _Self::_S_buffer_size(), __value); + + if (__first._M_node != __last._M_node) + { + std::fill(__first._M_cur, __first._M_last, __value); + std::fill(__last._M_first, __last._M_cur, __value); + } + else + std::fill(__first._M_cur, __last._M_cur, __value); + } + + template + _Deque_iterator<_Tp, _Tp&, _Tp*> + copy(_Deque_iterator<_Tp, const _Tp&, const _Tp*> __first, + _Deque_iterator<_Tp, const _Tp&, const _Tp*> __last, + _Deque_iterator<_Tp, _Tp&, _Tp*> __result) + { + typedef typename _Deque_iterator<_Tp, _Tp&, _Tp*>::_Self _Self; + typedef typename _Self::difference_type difference_type; + + difference_type __len = __last - __first; + while (__len > 0) + { + const difference_type __clen + = std::min(__len, std::min(__first._M_last - __first._M_cur, + __result._M_last - __result._M_cur)); + std::copy(__first._M_cur, __first._M_cur + __clen, __result._M_cur); + __first += __clen; + __result += __clen; + __len -= __clen; + } + return __result; + } + + template + _Deque_iterator<_Tp, _Tp&, _Tp*> + copy_backward(_Deque_iterator<_Tp, const _Tp&, const _Tp*> __first, + _Deque_iterator<_Tp, const _Tp&, const _Tp*> __last, + _Deque_iterator<_Tp, _Tp&, _Tp*> __result) + { + typedef typename _Deque_iterator<_Tp, _Tp&, _Tp*>::_Self _Self; + typedef typename _Self::difference_type difference_type; + + difference_type __len = __last - __first; + while (__len > 0) + { + difference_type __llen = __last._M_cur - __last._M_first; + _Tp* __lend = __last._M_cur; + + difference_type __rlen = __result._M_cur - __result._M_first; + _Tp* __rend = __result._M_cur; + + if (!__llen) + { + __llen = _Self::_S_buffer_size(); + __lend = *(__last._M_node - 1) + __llen; + } + if (!__rlen) + { + __rlen = _Self::_S_buffer_size(); + __rend = *(__result._M_node - 1) + __rlen; + } + + const difference_type __clen = std::min(__len, + std::min(__llen, __rlen)); + std::copy_backward(__lend - __clen, __lend, __rend); + __last -= __clen; + __result -= __clen; + __len -= __clen; + } + return __result; + } +# 1065 "/usr/include/c++/4.8.2/bits/deque.tcc" 3 + +} +# 67 "/usr/include/c++/4.8.2/deque" 2 3 +# 61 "/usr/include/c++/4.8.2/queue" 2 3 + +# 1 "/usr/include/c++/4.8.2/bits/stl_heap.h" 1 3 +# 61 "/usr/include/c++/4.8.2/bits/stl_heap.h" 3 +namespace std __attribute__ ((__visibility__ ("default"))) +{ + + + + + + + + template + _Distance + __is_heap_until(_RandomAccessIterator __first, _Distance __n) + { + _Distance __parent = 0; + for (_Distance __child = 1; __child < __n; ++__child) + { + if (__first[__parent] < __first[__child]) + return __child; + if ((__child & 1) == 0) + ++__parent; + } + return __n; + } + + template + _Distance + __is_heap_until(_RandomAccessIterator __first, _Distance __n, + _Compare __comp) + { + _Distance __parent = 0; + for (_Distance __child = 1; __child < __n; ++__child) + { + if (__comp(__first[__parent], __first[__child])) + return __child; + if ((__child & 1) == 0) + ++__parent; + } + return __n; + } + + + + template + inline bool + __is_heap(_RandomAccessIterator __first, _Distance __n) + { return std::__is_heap_until(__first, __n) == __n; } + + template + inline bool + __is_heap(_RandomAccessIterator __first, _Compare __comp, _Distance __n) + { return std::__is_heap_until(__first, __n, __comp) == __n; } + + template + inline bool + __is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) + { return std::__is_heap(__first, std::distance(__first, __last)); } + + template + inline bool + __is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) + { return std::__is_heap(__first, __comp, std::distance(__first, __last)); } + + + + + template + void + __push_heap(_RandomAccessIterator __first, + _Distance __holeIndex, _Distance __topIndex, _Tp __value) + { + _Distance __parent = (__holeIndex - 1) / 2; + while (__holeIndex > __topIndex && *(__first + __parent) < __value) + { + *(__first + __holeIndex) = (*(__first + __parent)); + __holeIndex = __parent; + __parent = (__holeIndex - 1) / 2; + } + *(__first + __holeIndex) = (__value); + } +# 154 "/usr/include/c++/4.8.2/bits/stl_heap.h" 3 + template + inline void + push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _DistanceType; + + + + + + ; + ; + + _ValueType __value = (*(__last - 1)); + std::__push_heap(__first, _DistanceType((__last - __first) - 1), + _DistanceType(0), (__value)); + } + + template + void + __push_heap(_RandomAccessIterator __first, _Distance __holeIndex, + _Distance __topIndex, _Tp __value, _Compare __comp) + { + _Distance __parent = (__holeIndex - 1) / 2; + while (__holeIndex > __topIndex + && __comp(*(__first + __parent), __value)) + { + *(__first + __holeIndex) = (*(__first + __parent)); + __holeIndex = __parent; + __parent = (__holeIndex - 1) / 2; + } + *(__first + __holeIndex) = (__value); + } +# 204 "/usr/include/c++/4.8.2/bits/stl_heap.h" 3 + template + inline void + push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _DistanceType; + + + + + ; + ; + + _ValueType __value = (*(__last - 1)); + std::__push_heap(__first, _DistanceType((__last - __first) - 1), + _DistanceType(0), (__value), __comp); + } + + template + void + __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex, + _Distance __len, _Tp __value) + { + const _Distance __topIndex = __holeIndex; + _Distance __secondChild = __holeIndex; + while (__secondChild < (__len - 1) / 2) + { + __secondChild = 2 * (__secondChild + 1); + if (*(__first + __secondChild) < *(__first + (__secondChild - 1))) + __secondChild--; + *(__first + __holeIndex) = (*(__first + __secondChild)); + __holeIndex = __secondChild; + } + if ((__len & 1) == 0 && __secondChild == (__len - 2) / 2) + { + __secondChild = 2 * (__secondChild + 1); + *(__first + __holeIndex) = (*(__first + (__secondChild - 1))) + ; + __holeIndex = __secondChild - 1; + } + std::__push_heap(__first, __holeIndex, __topIndex, + (__value)); + } + + template + inline void + __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _RandomAccessIterator __result) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _DistanceType; + + _ValueType __value = (*__result); + *__result = (*__first); + std::__adjust_heap(__first, _DistanceType(0), + _DistanceType(__last - __first), + (__value)); + } +# 279 "/usr/include/c++/4.8.2/bits/stl_heap.h" 3 + template + inline void + pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + + + + + ; + ; + ; + + if (__last - __first > 1) + { + --__last; + std::__pop_heap(__first, __last, __last); + } + } + + template + void + __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex, + _Distance __len, _Tp __value, _Compare __comp) + { + const _Distance __topIndex = __holeIndex; + _Distance __secondChild = __holeIndex; + while (__secondChild < (__len - 1) / 2) + { + __secondChild = 2 * (__secondChild + 1); + if (__comp(*(__first + __secondChild), + *(__first + (__secondChild - 1)))) + __secondChild--; + *(__first + __holeIndex) = (*(__first + __secondChild)); + __holeIndex = __secondChild; + } + if ((__len & 1) == 0 && __secondChild == (__len - 2) / 2) + { + __secondChild = 2 * (__secondChild + 1); + *(__first + __holeIndex) = (*(__first + (__secondChild - 1))) + ; + __holeIndex = __secondChild - 1; + } + std::__push_heap(__first, __holeIndex, __topIndex, + (__value), __comp); + } + + template + inline void + __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _RandomAccessIterator __result, _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _DistanceType; + + _ValueType __value = (*__result); + *__result = (*__first); + std::__adjust_heap(__first, _DistanceType(0), + _DistanceType(__last - __first), + (__value), __comp); + } +# 357 "/usr/include/c++/4.8.2/bits/stl_heap.h" 3 + template + inline void + pop_heap(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) + { + + + + ; + ; + ; + + if (__last - __first > 1) + { + --__last; + std::__pop_heap(__first, __last, __last, __comp); + } + } +# 384 "/usr/include/c++/4.8.2/bits/stl_heap.h" 3 + template + void + make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _DistanceType; + + + + + + ; + + if (__last - __first < 2) + return; + + const _DistanceType __len = __last - __first; + _DistanceType __parent = (__len - 2) / 2; + while (true) + { + _ValueType __value = (*(__first + __parent)); + std::__adjust_heap(__first, __parent, __len, (__value)); + if (__parent == 0) + return; + __parent--; + } + } +# 424 "/usr/include/c++/4.8.2/bits/stl_heap.h" 3 + template + void + make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _DistanceType; + + + + + ; + + if (__last - __first < 2) + return; + + const _DistanceType __len = __last - __first; + _DistanceType __parent = (__len - 2) / 2; + while (true) + { + _ValueType __value = (*(__first + __parent)); + std::__adjust_heap(__first, __parent, __len, (__value), + __comp); + if (__parent == 0) + return; + __parent--; + } + } +# 463 "/usr/include/c++/4.8.2/bits/stl_heap.h" 3 + template + void + sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) + { + + + + + + ; + ; + + while (__last - __first > 1) + { + --__last; + std::__pop_heap(__first, __last, __last); + } + } +# 492 "/usr/include/c++/4.8.2/bits/stl_heap.h" 3 + template + void + sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) + { + + + + ; + ; + + while (__last - __first > 1) + { + --__last; + std::__pop_heap(__first, __last, __last, __comp); + } + } +# 589 "/usr/include/c++/4.8.2/bits/stl_heap.h" 3 + +} +# 63 "/usr/include/c++/4.8.2/queue" 2 3 + +# 1 "/usr/include/c++/4.8.2/bits/stl_queue.h" 1 3 +# 62 "/usr/include/c++/4.8.2/bits/stl_queue.h" 3 +namespace std __attribute__ ((__visibility__ ("default"))) +{ + +# 92 "/usr/include/c++/4.8.2/bits/stl_queue.h" 3 + template > + class queue + { + + typedef typename _Sequence::value_type _Sequence_value_type; + + + + + + template + friend bool + operator==(const queue<_Tp1, _Seq1>&, const queue<_Tp1, _Seq1>&); + + template + friend bool + operator<(const queue<_Tp1, _Seq1>&, const queue<_Tp1, _Seq1>&); + + public: + typedef typename _Sequence::value_type value_type; + typedef typename _Sequence::reference reference; + typedef typename _Sequence::const_reference const_reference; + typedef typename _Sequence::size_type size_type; + typedef _Sequence container_type; + + protected: +# 126 "/usr/include/c++/4.8.2/bits/stl_queue.h" 3 + _Sequence c; + + public: + + + + + explicit + queue(const _Sequence& __c = _Sequence()) + : c(__c) { } +# 149 "/usr/include/c++/4.8.2/bits/stl_queue.h" 3 + bool + empty() const + { return c.empty(); } + + + size_type + size() const + { return c.size(); } + + + + + + reference + front() + { + ; + return c.front(); + } + + + + + + const_reference + front() const + { + ; + return c.front(); + } + + + + + + reference + back() + { + ; + return c.back(); + } + + + + + + const_reference + back() const + { + ; + return c.back(); + } +# 211 "/usr/include/c++/4.8.2/bits/stl_queue.h" 3 + void + push(const value_type& __x) + { c.push_back(__x); } +# 237 "/usr/include/c++/4.8.2/bits/stl_queue.h" 3 + void + pop() + { + ; + c.pop_front(); + } +# 253 "/usr/include/c++/4.8.2/bits/stl_queue.h" 3 + }; +# 266 "/usr/include/c++/4.8.2/bits/stl_queue.h" 3 + template + inline bool + operator==(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y) + { return __x.c == __y.c; } +# 284 "/usr/include/c++/4.8.2/bits/stl_queue.h" 3 + template + inline bool + operator<(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y) + { return __x.c < __y.c; } + + + template + inline bool + operator!=(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y) + { return !(__x == __y); } + + + template + inline bool + operator>(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y) + { return __y < __x; } + + + template + inline bool + operator<=(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y) + { return !(__y < __x); } + + + template + inline bool + operator>=(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y) + { return !(__x < __y); } +# 365 "/usr/include/c++/4.8.2/bits/stl_queue.h" 3 + template, + typename _Compare = less > + class priority_queue + { + + typedef typename _Sequence::value_type _Sequence_value_type; + + + + + + + + public: + typedef typename _Sequence::value_type value_type; + typedef typename _Sequence::reference reference; + typedef typename _Sequence::const_reference const_reference; + typedef typename _Sequence::size_type size_type; + typedef _Sequence container_type; + + protected: + + _Sequence c; + _Compare comp; + + public: + + + + + explicit + priority_queue(const _Compare& __x = _Compare(), + const _Sequence& __s = _Sequence()) + : c(__s), comp(__x) + { std::make_heap(c.begin(), c.end(), comp); } +# 430 "/usr/include/c++/4.8.2/bits/stl_queue.h" 3 + template + priority_queue(_InputIterator __first, _InputIterator __last, + const _Compare& __x = _Compare(), + const _Sequence& __s = _Sequence()) + : c(__s), comp(__x) + { + ; + c.insert(c.end(), __first, __last); + std::make_heap(c.begin(), c.end(), comp); + } +# 467 "/usr/include/c++/4.8.2/bits/stl_queue.h" 3 + bool + empty() const + { return c.empty(); } + + + size_type + size() const + { return c.size(); } + + + + + + const_reference + top() const + { + ; + return c.front(); + } +# 495 "/usr/include/c++/4.8.2/bits/stl_queue.h" 3 + void + push(const value_type& __x) + { + c.push_back(__x); + std::push_heap(c.begin(), c.end(), comp); + } +# 530 "/usr/include/c++/4.8.2/bits/stl_queue.h" 3 + void + pop() + { + ; + std::pop_heap(c.begin(), c.end(), comp); + c.pop_back(); + } +# 548 "/usr/include/c++/4.8.2/bits/stl_queue.h" 3 + }; +# 566 "/usr/include/c++/4.8.2/bits/stl_queue.h" 3 + +} +# 65 "/usr/include/c++/4.8.2/queue" 2 3 +# 13 "include/CTypedef.h" 2 +# 1 "/usr/include/c++/4.8.2/list" 1 3 +# 58 "/usr/include/c++/4.8.2/list" 3 + +# 59 "/usr/include/c++/4.8.2/list" 3 + + + + +# 1 "/usr/include/c++/4.8.2/bits/stl_list.h" 1 3 +# 64 "/usr/include/c++/4.8.2/bits/stl_list.h" 3 +namespace std __attribute__ ((__visibility__ ("default"))) +{ + namespace __detail + { + +# 77 "/usr/include/c++/4.8.2/bits/stl_list.h" 3 + struct _List_node_base + { + _List_node_base* _M_next; + _List_node_base* _M_prev; + + static void + swap(_List_node_base& __x, _List_node_base& __y) throw(); + + void + _M_transfer(_List_node_base* const __first, + _List_node_base* const __last) throw(); + + void + _M_reverse() throw(); + + void + _M_hook(_List_node_base* const __position) throw(); + + void + _M_unhook() throw(); + }; + + + } + + + + + template + struct _List_node : public __detail::_List_node_base + { + + _Tp _M_data; + + + + + + + + }; + + + + + + + template + struct _List_iterator + { + typedef _List_iterator<_Tp> _Self; + typedef _List_node<_Tp> _Node; + + typedef ptrdiff_t difference_type; + typedef std::bidirectional_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Tp* pointer; + typedef _Tp& reference; + + _List_iterator() + : _M_node() { } + + explicit + _List_iterator(__detail::_List_node_base* __x) + : _M_node(__x) { } + + + reference + operator*() const + { return static_cast<_Node*>(_M_node)->_M_data; } + + pointer + operator->() const + { return std::__addressof(static_cast<_Node*>(_M_node)->_M_data); } + + _Self& + operator++() + { + _M_node = _M_node->_M_next; + return *this; + } + + _Self + operator++(int) + { + _Self __tmp = *this; + _M_node = _M_node->_M_next; + return __tmp; + } + + _Self& + operator--() + { + _M_node = _M_node->_M_prev; + return *this; + } + + _Self + operator--(int) + { + _Self __tmp = *this; + _M_node = _M_node->_M_prev; + return __tmp; + } + + bool + operator==(const _Self& __x) const + { return _M_node == __x._M_node; } + + bool + operator!=(const _Self& __x) const + { return _M_node != __x._M_node; } + + + __detail::_List_node_base* _M_node; + }; + + + + + + + template + struct _List_const_iterator + { + typedef _List_const_iterator<_Tp> _Self; + typedef const _List_node<_Tp> _Node; + typedef _List_iterator<_Tp> iterator; + + typedef ptrdiff_t difference_type; + typedef std::bidirectional_iterator_tag iterator_category; + typedef _Tp value_type; + typedef const _Tp* pointer; + typedef const _Tp& reference; + + _List_const_iterator() + : _M_node() { } + + explicit + _List_const_iterator(const __detail::_List_node_base* __x) + : _M_node(__x) { } + + _List_const_iterator(const iterator& __x) + : _M_node(__x._M_node) { } + + + + reference + operator*() const + { return static_cast<_Node*>(_M_node)->_M_data; } + + pointer + operator->() const + { return std::__addressof(static_cast<_Node*>(_M_node)->_M_data); } + + _Self& + operator++() + { + _M_node = _M_node->_M_next; + return *this; + } + + _Self + operator++(int) + { + _Self __tmp = *this; + _M_node = _M_node->_M_next; + return __tmp; + } + + _Self& + operator--() + { + _M_node = _M_node->_M_prev; + return *this; + } + + _Self + operator--(int) + { + _Self __tmp = *this; + _M_node = _M_node->_M_prev; + return __tmp; + } + + bool + operator==(const _Self& __x) const + { return _M_node == __x._M_node; } + + bool + operator!=(const _Self& __x) const + { return _M_node != __x._M_node; } + + + const __detail::_List_node_base* _M_node; + }; + + template + inline bool + operator==(const _List_iterator<_Val>& __x, + const _List_const_iterator<_Val>& __y) + { return __x._M_node == __y._M_node; } + + template + inline bool + operator!=(const _List_iterator<_Val>& __x, + const _List_const_iterator<_Val>& __y) + { return __x._M_node != __y._M_node; } + + + + template + class _List_base + { + protected: +# 305 "/usr/include/c++/4.8.2/bits/stl_list.h" 3 + typedef typename _Alloc::template rebind<_List_node<_Tp> >::other + _Node_alloc_type; + + typedef typename _Alloc::template rebind<_Tp>::other _Tp_alloc_type; + + struct _List_impl + : public _Node_alloc_type + { + __detail::_List_node_base _M_node; + + _List_impl() + : _Node_alloc_type(), _M_node() + { } + + _List_impl(const _Node_alloc_type& __a) + : _Node_alloc_type(__a), _M_node() + { } + + + + + + + }; + + _List_impl _M_impl; + + _List_node<_Tp>* + _M_get_node() + { return _M_impl._Node_alloc_type::allocate(1); } + + void + _M_put_node(_List_node<_Tp>* __p) + { _M_impl._Node_alloc_type::deallocate(__p, 1); } + + public: + typedef _Alloc allocator_type; + + _Node_alloc_type& + _M_get_Node_allocator() + { return *static_cast<_Node_alloc_type*>(&_M_impl); } + + const _Node_alloc_type& + _M_get_Node_allocator() const + { return *static_cast(&_M_impl); } + + _Tp_alloc_type + _M_get_Tp_allocator() const + { return _Tp_alloc_type(_M_get_Node_allocator()); } + + allocator_type + get_allocator() const + { return allocator_type(_M_get_Node_allocator()); } + + _List_base() + : _M_impl() + { _M_init(); } + + _List_base(const _Node_alloc_type& __a) + : _M_impl(__a) + { _M_init(); } +# 377 "/usr/include/c++/4.8.2/bits/stl_list.h" 3 + ~_List_base() + { _M_clear(); } + + void + _M_clear(); + + void + _M_init() + { + this->_M_impl._M_node._M_next = &this->_M_impl._M_node; + this->_M_impl._M_node._M_prev = &this->_M_impl._M_node; + } + }; +# 437 "/usr/include/c++/4.8.2/bits/stl_list.h" 3 + template > + class list : protected _List_base<_Tp, _Alloc> + { + + typedef typename _Alloc::value_type _Alloc_value_type; + + + + typedef _List_base<_Tp, _Alloc> _Base; + typedef typename _Base::_Tp_alloc_type _Tp_alloc_type; + typedef typename _Base::_Node_alloc_type _Node_alloc_type; + + public: + typedef _Tp value_type; + typedef typename _Tp_alloc_type::pointer pointer; + typedef typename _Tp_alloc_type::const_pointer const_pointer; + typedef typename _Tp_alloc_type::reference reference; + typedef typename _Tp_alloc_type::const_reference const_reference; + typedef _List_iterator<_Tp> iterator; + typedef _List_const_iterator<_Tp> const_iterator; + typedef std::reverse_iterator const_reverse_iterator; + typedef std::reverse_iterator reverse_iterator; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Alloc allocator_type; + + protected: + + + typedef _List_node<_Tp> _Node; + + using _Base::_M_impl; + using _Base::_M_put_node; + using _Base::_M_get_node; + using _Base::_M_get_Tp_allocator; + using _Base::_M_get_Node_allocator; +# 481 "/usr/include/c++/4.8.2/bits/stl_list.h" 3 + _Node* + _M_create_node(const value_type& __x) + { + _Node* __p = this->_M_get_node(); + try + { + _M_get_Tp_allocator().construct + (std::__addressof(__p->_M_data), __x); + } + catch(...) + { + _M_put_node(__p); + throw; + } + return __p; + } +# 517 "/usr/include/c++/4.8.2/bits/stl_list.h" 3 + public: + + + + + + list() + : _Base() { } + + + + + + explicit + list(const allocator_type& __a) + : _Base(_Node_alloc_type(__a)) { } +# 568 "/usr/include/c++/4.8.2/bits/stl_list.h" 3 + explicit + list(size_type __n, const value_type& __value = value_type(), + const allocator_type& __a = allocator_type()) + : _Base(_Node_alloc_type(__a)) + { _M_fill_initialize(__n, __value); } +# 582 "/usr/include/c++/4.8.2/bits/stl_list.h" 3 + list(const list& __x) + : _Base(__x._M_get_Node_allocator()) + { _M_initialize_dispatch(__x.begin(), __x.end(), __false_type()); } +# 629 "/usr/include/c++/4.8.2/bits/stl_list.h" 3 + template + list(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) + : _Base(_Node_alloc_type(__a)) + { + + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + _M_initialize_dispatch(__first, __last, _Integral()); + } +# 655 "/usr/include/c++/4.8.2/bits/stl_list.h" 3 + list& + operator=(const list& __x); +# 701 "/usr/include/c++/4.8.2/bits/stl_list.h" 3 + void + assign(size_type __n, const value_type& __val) + { _M_fill_assign(__n, __val); } +# 724 "/usr/include/c++/4.8.2/bits/stl_list.h" 3 + template + void + assign(_InputIterator __first, _InputIterator __last) + { + + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } +# 748 "/usr/include/c++/4.8.2/bits/stl_list.h" 3 + allocator_type + get_allocator() const + { return _Base::get_allocator(); } + + + + + + + iterator + begin() + { return iterator(this->_M_impl._M_node._M_next); } + + + + + + + const_iterator + begin() const + { return const_iterator(this->_M_impl._M_node._M_next); } + + + + + + + iterator + end() + { return iterator(&this->_M_impl._M_node); } + + + + + + + const_iterator + end() const + { return const_iterator(&this->_M_impl._M_node); } + + + + + + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + + + + + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + + + + + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + + + + + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } +# 867 "/usr/include/c++/4.8.2/bits/stl_list.h" 3 + bool + empty() const + { return this->_M_impl._M_node._M_next == &this->_M_impl._M_node; } + + + size_type + size() const + { return std::distance(begin(), end()); } + + + size_type + max_size() const + { return _M_get_Node_allocator().max_size(); } +# 917 "/usr/include/c++/4.8.2/bits/stl_list.h" 3 + void + resize(size_type __new_size, value_type __x = value_type()); + + + + + + + + reference + front() + { return *begin(); } + + + + + + const_reference + front() const + { return *begin(); } + + + + + + reference + back() + { + iterator __tmp = end(); + --__tmp; + return *__tmp; + } + + + + + + const_reference + back() const + { + const_iterator __tmp = end(); + --__tmp; + return *__tmp; + } +# 973 "/usr/include/c++/4.8.2/bits/stl_list.h" 3 + void + push_front(const value_type& __x) + { this->_M_insert(begin(), __x); } +# 1000 "/usr/include/c++/4.8.2/bits/stl_list.h" 3 + void + pop_front() + { this->_M_erase(begin()); } +# 1014 "/usr/include/c++/4.8.2/bits/stl_list.h" 3 + void + push_back(const value_type& __x) + { this->_M_insert(end(), __x); } +# 1040 "/usr/include/c++/4.8.2/bits/stl_list.h" 3 + void + pop_back() + { this->_M_erase(iterator(this->_M_impl._M_node._M_prev)); } +# 1073 "/usr/include/c++/4.8.2/bits/stl_list.h" 3 + iterator + insert(iterator __position, const value_type& __x); +# 1122 "/usr/include/c++/4.8.2/bits/stl_list.h" 3 + void + insert(iterator __position, size_type __n, const value_type& __x) + { + list __tmp(__n, __x, get_allocator()); + splice(__position, __tmp); + } +# 1146 "/usr/include/c++/4.8.2/bits/stl_list.h" 3 + template + + void + insert(iterator __position, _InputIterator __first, + _InputIterator __last) + { + list __tmp(__first, __last, get_allocator()); + splice(__position, __tmp); + } +# 1171 "/usr/include/c++/4.8.2/bits/stl_list.h" 3 + iterator + erase(iterator __position); +# 1192 "/usr/include/c++/4.8.2/bits/stl_list.h" 3 + iterator + erase(iterator __first, iterator __last) + { + while (__first != __last) + __first = erase(__first); + return __last; + } +# 1209 "/usr/include/c++/4.8.2/bits/stl_list.h" 3 + void + swap(list& __x) + { + __detail::_List_node_base::swap(this->_M_impl._M_node, + __x._M_impl._M_node); + + + + std::__alloc_swap:: + _S_do_it(_M_get_Node_allocator(), __x._M_get_Node_allocator()); + } + + + + + + + + void + clear() + { + _Base::_M_clear(); + _Base::_M_init(); + } +# 1246 "/usr/include/c++/4.8.2/bits/stl_list.h" 3 + void + + + + splice(iterator __position, list& __x) + + { + if (!__x.empty()) + { + _M_check_equal_allocators(__x); + + this->_M_transfer(__position, __x.begin(), __x.end()); + } + } +# 1276 "/usr/include/c++/4.8.2/bits/stl_list.h" 3 + void + + + + splice(iterator __position, list& __x, iterator __i) + + { + iterator __j = __i; + ++__j; + if (__position == __i || __position == __j) + return; + + if (this != &__x) + _M_check_equal_allocators(__x); + + this->_M_transfer(__position, __i, __j); + } +# 1312 "/usr/include/c++/4.8.2/bits/stl_list.h" 3 + void + + + + + splice(iterator __position, list& __x, iterator __first, + iterator __last) + + { + if (__first != __last) + { + if (this != &__x) + _M_check_equal_allocators(__x); + + this->_M_transfer(__position, __first, __last); + } + } +# 1347 "/usr/include/c++/4.8.2/bits/stl_list.h" 3 + void + remove(const _Tp& __value); +# 1361 "/usr/include/c++/4.8.2/bits/stl_list.h" 3 + template + void + remove_if(_Predicate); +# 1375 "/usr/include/c++/4.8.2/bits/stl_list.h" 3 + void + unique(); +# 1390 "/usr/include/c++/4.8.2/bits/stl_list.h" 3 + template + void + unique(_BinaryPredicate); +# 1411 "/usr/include/c++/4.8.2/bits/stl_list.h" 3 + void + merge(list& __x); +# 1438 "/usr/include/c++/4.8.2/bits/stl_list.h" 3 + template + void + merge(list& __x, _StrictWeakOrdering __comp); + + + + + + + + void + reverse() + { this->_M_impl._M_node._M_reverse(); } + + + + + + + + void + sort(); + + + + + + + + template + void + sort(_StrictWeakOrdering); + + protected: + + + + + + + template + void + _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) + { _M_fill_initialize(static_cast(__n), __x); } + + + template + void + _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) + { + for (; __first != __last; ++__first) + + + + push_back(*__first); + + } + + + + void + _M_fill_initialize(size_type __n, const value_type& __x) + { + for (; __n; --__n) + push_back(__x); + } +# 1526 "/usr/include/c++/4.8.2/bits/stl_list.h" 3 + template + void + _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { _M_fill_assign(__n, __val); } + + + template + void + _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type); + + + + void + _M_fill_assign(size_type __n, const value_type& __val); + + + + void + _M_transfer(iterator __position, iterator __first, iterator __last) + { __position._M_node->_M_transfer(__first._M_node, __last._M_node); } + + + + void + _M_insert(iterator __position, const value_type& __x) + { + _Node* __tmp = _M_create_node(__x); + __tmp->_M_hook(__position._M_node); + } +# 1567 "/usr/include/c++/4.8.2/bits/stl_list.h" 3 + void + _M_erase(iterator __position) + { + __position._M_node->_M_unhook(); + _Node* __n = static_cast<_Node*>(__position._M_node); + + + + _M_get_Tp_allocator().destroy(std::__addressof(__n->_M_data)); + + _M_put_node(__n); + } + + + void + _M_check_equal_allocators(list& __x) + { + if (std::__alloc_neq:: + _S_do_it(_M_get_Node_allocator(), __x._M_get_Node_allocator())) + __throw_runtime_error(("list::_M_check_equal_allocators")); + } + }; +# 1600 "/usr/include/c++/4.8.2/bits/stl_list.h" 3 + template + inline bool + operator==(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) + { + typedef typename list<_Tp, _Alloc>::const_iterator const_iterator; + const_iterator __end1 = __x.end(); + const_iterator __end2 = __y.end(); + + const_iterator __i1 = __x.begin(); + const_iterator __i2 = __y.begin(); + while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2) + { + ++__i1; + ++__i2; + } + return __i1 == __end1 && __i2 == __end2; + } +# 1629 "/usr/include/c++/4.8.2/bits/stl_list.h" 3 + template + inline bool + operator<(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) + { return std::lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); } + + + template + inline bool + operator!=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) + { return !(__x == __y); } + + + template + inline bool + operator>(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) + { return __y < __x; } + + + template + inline bool + operator<=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) + { return !(__y < __x); } + + + template + inline bool + operator>=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) + { return !(__x < __y); } + + + template + inline void + swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y) + { __x.swap(__y); } + + +} +# 64 "/usr/include/c++/4.8.2/list" 2 3 +# 1 "/usr/include/c++/4.8.2/bits/list.tcc" 1 3 +# 59 "/usr/include/c++/4.8.2/bits/list.tcc" 3 +namespace std __attribute__ ((__visibility__ ("default"))) +{ + + + template + void + _List_base<_Tp, _Alloc>:: + _M_clear() + { + typedef _List_node<_Tp> _Node; + _Node* __cur = static_cast<_Node*>(_M_impl._M_node._M_next); + while (__cur != &_M_impl._M_node) + { + _Node* __tmp = __cur; + __cur = static_cast<_Node*>(__cur->_M_next); + + + + _M_get_Tp_allocator().destroy(std::__addressof(__tmp->_M_data)); + + _M_put_node(__tmp); + } + } +# 96 "/usr/include/c++/4.8.2/bits/list.tcc" 3 + template + typename list<_Tp, _Alloc>::iterator + list<_Tp, _Alloc>:: + insert(iterator __position, const value_type& __x) + { + _Node* __tmp = _M_create_node(__x); + __tmp->_M_hook(__position._M_node); + return iterator(__tmp); + } + + template + typename list<_Tp, _Alloc>::iterator + list<_Tp, _Alloc>:: + erase(iterator __position) + { + iterator __ret = iterator(__position._M_node->_M_next); + _M_erase(__position); + return __ret; + } +# 166 "/usr/include/c++/4.8.2/bits/list.tcc" 3 + template + void + list<_Tp, _Alloc>:: + resize(size_type __new_size, value_type __x) + { + iterator __i = begin(); + size_type __len = 0; + for (; __i != end() && __len < __new_size; ++__i, ++__len) + ; + if (__len == __new_size) + erase(__i, end()); + else + insert(end(), __new_size - __len, __x); + } + + + template + list<_Tp, _Alloc>& + list<_Tp, _Alloc>:: + operator=(const list& __x) + { + if (this != &__x) + { + iterator __first1 = begin(); + iterator __last1 = end(); + const_iterator __first2 = __x.begin(); + const_iterator __last2 = __x.end(); + for (; __first1 != __last1 && __first2 != __last2; + ++__first1, ++__first2) + *__first1 = *__first2; + if (__first2 == __last2) + erase(__first1, __last1); + else + insert(__last1, __first2, __last2); + } + return *this; + } + + template + void + list<_Tp, _Alloc>:: + _M_fill_assign(size_type __n, const value_type& __val) + { + iterator __i = begin(); + for (; __i != end() && __n > 0; ++__i, --__n) + *__i = __val; + if (__n > 0) + insert(end(), __n, __val); + else + erase(__i, end()); + } + + template + template + void + list<_Tp, _Alloc>:: + _M_assign_dispatch(_InputIterator __first2, _InputIterator __last2, + __false_type) + { + iterator __first1 = begin(); + iterator __last1 = end(); + for (; __first1 != __last1 && __first2 != __last2; + ++__first1, ++__first2) + *__first1 = *__first2; + if (__first2 == __last2) + erase(__first1, __last1); + else + insert(__last1, __first2, __last2); + } + + template + void + list<_Tp, _Alloc>:: + remove(const value_type& __value) + { + iterator __first = begin(); + iterator __last = end(); + iterator __extra = __last; + while (__first != __last) + { + iterator __next = __first; + ++__next; + if (*__first == __value) + { + + + + if (std::__addressof(*__first) != std::__addressof(__value)) + _M_erase(__first); + else + __extra = __first; + } + __first = __next; + } + if (__extra != __last) + _M_erase(__extra); + } + + template + void + list<_Tp, _Alloc>:: + unique() + { + iterator __first = begin(); + iterator __last = end(); + if (__first == __last) + return; + iterator __next = __first; + while (++__next != __last) + { + if (*__first == *__next) + _M_erase(__next); + else + __first = __next; + __next = __first; + } + } + + template + void + list<_Tp, _Alloc>:: + + + + merge(list& __x) + + { + + + if (this != &__x) + { + _M_check_equal_allocators(__x); + + iterator __first1 = begin(); + iterator __last1 = end(); + iterator __first2 = __x.begin(); + iterator __last2 = __x.end(); + while (__first1 != __last1 && __first2 != __last2) + if (*__first2 < *__first1) + { + iterator __next = __first2; + _M_transfer(__first1, __first2, ++__next); + __first2 = __next; + } + else + ++__first1; + if (__first2 != __last2) + _M_transfer(__last1, __first2, __last2); + } + } + + template + template + void + list<_Tp, _Alloc>:: + + + + merge(list& __x, _StrictWeakOrdering __comp) + + { + + + if (this != &__x) + { + _M_check_equal_allocators(__x); + + iterator __first1 = begin(); + iterator __last1 = end(); + iterator __first2 = __x.begin(); + iterator __last2 = __x.end(); + while (__first1 != __last1 && __first2 != __last2) + if (__comp(*__first2, *__first1)) + { + iterator __next = __first2; + _M_transfer(__first1, __first2, ++__next); + __first2 = __next; + } + else + ++__first1; + if (__first2 != __last2) + _M_transfer(__last1, __first2, __last2); + } + } + + template + void + list<_Tp, _Alloc>:: + sort() + { + + if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node + && this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node) + { + list __carry; + list __tmp[64]; + list * __fill = &__tmp[0]; + list * __counter; + + do + { + __carry.splice(__carry.begin(), *this, begin()); + + for(__counter = &__tmp[0]; + __counter != __fill && !__counter->empty(); + ++__counter) + { + __counter->merge(__carry); + __carry.swap(*__counter); + } + __carry.swap(*__counter); + if (__counter == __fill) + ++__fill; + } + while ( !empty() ); + + for (__counter = &__tmp[1]; __counter != __fill; ++__counter) + __counter->merge(*(__counter - 1)); + swap( *(__fill - 1) ); + } + } + + template + template + void + list<_Tp, _Alloc>:: + remove_if(_Predicate __pred) + { + iterator __first = begin(); + iterator __last = end(); + while (__first != __last) + { + iterator __next = __first; + ++__next; + if (__pred(*__first)) + _M_erase(__first); + __first = __next; + } + } + + template + template + void + list<_Tp, _Alloc>:: + unique(_BinaryPredicate __binary_pred) + { + iterator __first = begin(); + iterator __last = end(); + if (__first == __last) + return; + iterator __next = __first; + while (++__next != __last) + { + if (__binary_pred(*__first, *__next)) + _M_erase(__next); + else + __first = __next; + __next = __first; + } + } + + template + template + void + list<_Tp, _Alloc>:: + sort(_StrictWeakOrdering __comp) + { + + if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node + && this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node) + { + list __carry; + list __tmp[64]; + list * __fill = &__tmp[0]; + list * __counter; + + do + { + __carry.splice(__carry.begin(), *this, begin()); + + for(__counter = &__tmp[0]; + __counter != __fill && !__counter->empty(); + ++__counter) + { + __counter->merge(__carry, __comp); + __carry.swap(*__counter); + } + __carry.swap(*__counter); + if (__counter == __fill) + ++__fill; + } + while ( !empty() ); + + for (__counter = &__tmp[1]; __counter != __fill; ++__counter) + __counter->merge(*(__counter - 1), __comp); + swap(*(__fill - 1)); + } + } + + +} +# 65 "/usr/include/c++/4.8.2/list" 2 3 +# 14 "include/CTypedef.h" 2 +# 1 "/usr/include/c++/4.8.2/set" 1 3 +# 58 "/usr/include/c++/4.8.2/set" 3 + +# 59 "/usr/include/c++/4.8.2/set" 3 + + +# 1 "/usr/include/c++/4.8.2/bits/stl_set.h" 1 3 +# 64 "/usr/include/c++/4.8.2/bits/stl_set.h" 3 +namespace std __attribute__ ((__visibility__ ("default"))) +{ + +# 88 "/usr/include/c++/4.8.2/bits/stl_set.h" 3 + template, + typename _Alloc = std::allocator<_Key> > + class set + { + + typedef typename _Alloc::value_type _Alloc_value_type; + + + + + + public: + + + + typedef _Key key_type; + typedef _Key value_type; + typedef _Compare key_compare; + typedef _Compare value_compare; + typedef _Alloc allocator_type; + + + private: + typedef typename _Alloc::template rebind<_Key>::other _Key_alloc_type; + + typedef _Rb_tree, + key_compare, _Key_alloc_type> _Rep_type; + _Rep_type _M_t; + + public: + + + typedef typename _Key_alloc_type::pointer pointer; + typedef typename _Key_alloc_type::const_pointer const_pointer; + typedef typename _Key_alloc_type::reference reference; + typedef typename _Key_alloc_type::const_reference const_reference; + + + + typedef typename _Rep_type::const_iterator iterator; + typedef typename _Rep_type::const_iterator const_iterator; + typedef typename _Rep_type::const_reverse_iterator reverse_iterator; + typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; + typedef typename _Rep_type::size_type size_type; + typedef typename _Rep_type::difference_type difference_type; + + + + + + + set() + : _M_t() { } + + + + + + + explicit + set(const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, _Key_alloc_type(__a)) { } +# 162 "/usr/include/c++/4.8.2/bits/stl_set.h" 3 + template + set(_InputIterator __first, _InputIterator __last) + : _M_t() + { _M_t._M_insert_unique(__first, __last); } +# 179 "/usr/include/c++/4.8.2/bits/stl_set.h" 3 + template + set(_InputIterator __first, _InputIterator __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, _Key_alloc_type(__a)) + { _M_t._M_insert_unique(__first, __last); } +# 193 "/usr/include/c++/4.8.2/bits/stl_set.h" 3 + set(const set& __x) + : _M_t(__x._M_t) { } +# 232 "/usr/include/c++/4.8.2/bits/stl_set.h" 3 + set& + operator=(const set& __x) + { + _M_t = __x._M_t; + return *this; + } +# 280 "/usr/include/c++/4.8.2/bits/stl_set.h" 3 + key_compare + key_comp() const + { return _M_t.key_comp(); } + + value_compare + value_comp() const + { return _M_t.key_comp(); } + + allocator_type + get_allocator() const + { return allocator_type(_M_t.get_allocator()); } + + + + + + + iterator + begin() const + { return _M_t.begin(); } + + + + + + + iterator + end() const + { return _M_t.end(); } + + + + + + + reverse_iterator + rbegin() const + { return _M_t.rbegin(); } + + + + + + + reverse_iterator + rend() const + { return _M_t.rend(); } +# 367 "/usr/include/c++/4.8.2/bits/stl_set.h" 3 + bool + empty() const + { return _M_t.empty(); } + + + size_type + size() const + { return _M_t.size(); } + + + size_type + max_size() const + { return _M_t.max_size(); } +# 392 "/usr/include/c++/4.8.2/bits/stl_set.h" 3 + void + swap(set& __x) + { _M_t.swap(__x._M_t); } +# 459 "/usr/include/c++/4.8.2/bits/stl_set.h" 3 + std::pair + insert(const value_type& __x) + { + std::pair __p = + _M_t._M_insert_unique(__x); + return std::pair(__p.first, __p.second); + } +# 496 "/usr/include/c++/4.8.2/bits/stl_set.h" 3 + iterator + insert(const_iterator __position, const value_type& __x) + { return _M_t._M_insert_unique_(__position, __x); } +# 515 "/usr/include/c++/4.8.2/bits/stl_set.h" 3 + template + void + insert(_InputIterator __first, _InputIterator __last) + { _M_t._M_insert_unique(__first, __last); } +# 564 "/usr/include/c++/4.8.2/bits/stl_set.h" 3 + void + erase(iterator __position) + { _M_t.erase(__position); } +# 580 "/usr/include/c++/4.8.2/bits/stl_set.h" 3 + size_type + erase(const key_type& __x) + { return _M_t.erase(__x); } +# 618 "/usr/include/c++/4.8.2/bits/stl_set.h" 3 + void + erase(iterator __first, iterator __last) + { _M_t.erase(__first, __last); } +# 629 "/usr/include/c++/4.8.2/bits/stl_set.h" 3 + void + clear() + { _M_t.clear(); } +# 643 "/usr/include/c++/4.8.2/bits/stl_set.h" 3 + size_type + count(const key_type& __x) const + { return _M_t.find(__x) == _M_t.end() ? 0 : 1; } +# 661 "/usr/include/c++/4.8.2/bits/stl_set.h" 3 + iterator + find(const key_type& __x) + { return _M_t.find(__x); } + + const_iterator + find(const key_type& __x) const + { return _M_t.find(__x); } +# 682 "/usr/include/c++/4.8.2/bits/stl_set.h" 3 + iterator + lower_bound(const key_type& __x) + { return _M_t.lower_bound(__x); } + + const_iterator + lower_bound(const key_type& __x) const + { return _M_t.lower_bound(__x); } +# 698 "/usr/include/c++/4.8.2/bits/stl_set.h" 3 + iterator + upper_bound(const key_type& __x) + { return _M_t.upper_bound(__x); } + + const_iterator + upper_bound(const key_type& __x) const + { return _M_t.upper_bound(__x); } +# 723 "/usr/include/c++/4.8.2/bits/stl_set.h" 3 + std::pair + equal_range(const key_type& __x) + { return _M_t.equal_range(__x); } + + std::pair + equal_range(const key_type& __x) const + { return _M_t.equal_range(__x); } + + + template + friend bool + operator==(const set<_K1, _C1, _A1>&, const set<_K1, _C1, _A1>&); + + template + friend bool + operator<(const set<_K1, _C1, _A1>&, const set<_K1, _C1, _A1>&); + }; +# 752 "/usr/include/c++/4.8.2/bits/stl_set.h" 3 + template + inline bool + operator==(const set<_Key, _Compare, _Alloc>& __x, + const set<_Key, _Compare, _Alloc>& __y) + { return __x._M_t == __y._M_t; } +# 769 "/usr/include/c++/4.8.2/bits/stl_set.h" 3 + template + inline bool + operator<(const set<_Key, _Compare, _Alloc>& __x, + const set<_Key, _Compare, _Alloc>& __y) + { return __x._M_t < __y._M_t; } + + + template + inline bool + operator!=(const set<_Key, _Compare, _Alloc>& __x, + const set<_Key, _Compare, _Alloc>& __y) + { return !(__x == __y); } + + + template + inline bool + operator>(const set<_Key, _Compare, _Alloc>& __x, + const set<_Key, _Compare, _Alloc>& __y) + { return __y < __x; } + + + template + inline bool + operator<=(const set<_Key, _Compare, _Alloc>& __x, + const set<_Key, _Compare, _Alloc>& __y) + { return !(__y < __x); } + + + template + inline bool + operator>=(const set<_Key, _Compare, _Alloc>& __x, + const set<_Key, _Compare, _Alloc>& __y) + { return !(__x < __y); } + + + template + inline void + swap(set<_Key, _Compare, _Alloc>& __x, set<_Key, _Compare, _Alloc>& __y) + { __x.swap(__y); } + + +} +# 62 "/usr/include/c++/4.8.2/set" 2 3 +# 1 "/usr/include/c++/4.8.2/bits/stl_multiset.h" 1 3 +# 64 "/usr/include/c++/4.8.2/bits/stl_multiset.h" 3 +namespace std __attribute__ ((__visibility__ ("default"))) +{ + +# 90 "/usr/include/c++/4.8.2/bits/stl_multiset.h" 3 + template , + typename _Alloc = std::allocator<_Key> > + class multiset + { + + typedef typename _Alloc::value_type _Alloc_value_type; + + + + + + public: + + typedef _Key key_type; + typedef _Key value_type; + typedef _Compare key_compare; + typedef _Compare value_compare; + typedef _Alloc allocator_type; + + private: + + typedef typename _Alloc::template rebind<_Key>::other _Key_alloc_type; + + typedef _Rb_tree, + key_compare, _Key_alloc_type> _Rep_type; + + _Rep_type _M_t; + + public: + typedef typename _Key_alloc_type::pointer pointer; + typedef typename _Key_alloc_type::const_pointer const_pointer; + typedef typename _Key_alloc_type::reference reference; + typedef typename _Key_alloc_type::const_reference const_reference; + + + + typedef typename _Rep_type::const_iterator iterator; + typedef typename _Rep_type::const_iterator const_iterator; + typedef typename _Rep_type::const_reverse_iterator reverse_iterator; + typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; + typedef typename _Rep_type::size_type size_type; + typedef typename _Rep_type::difference_type difference_type; + + + + + + multiset() + : _M_t() { } + + + + + + + explicit + multiset(const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, _Key_alloc_type(__a)) { } +# 159 "/usr/include/c++/4.8.2/bits/stl_multiset.h" 3 + template + multiset(_InputIterator __first, _InputIterator __last) + : _M_t() + { _M_t._M_insert_equal(__first, __last); } +# 175 "/usr/include/c++/4.8.2/bits/stl_multiset.h" 3 + template + multiset(_InputIterator __first, _InputIterator __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, _Key_alloc_type(__a)) + { _M_t._M_insert_equal(__first, __last); } +# 189 "/usr/include/c++/4.8.2/bits/stl_multiset.h" 3 + multiset(const multiset& __x) + : _M_t(__x._M_t) { } +# 228 "/usr/include/c++/4.8.2/bits/stl_multiset.h" 3 + multiset& + operator=(const multiset& __x) + { + _M_t = __x._M_t; + return *this; + } +# 277 "/usr/include/c++/4.8.2/bits/stl_multiset.h" 3 + key_compare + key_comp() const + { return _M_t.key_comp(); } + + value_compare + value_comp() const + { return _M_t.key_comp(); } + + allocator_type + get_allocator() const + { return allocator_type(_M_t.get_allocator()); } + + + + + + + iterator + begin() const + { return _M_t.begin(); } + + + + + + + iterator + end() const + { return _M_t.end(); } + + + + + + + reverse_iterator + rbegin() const + { return _M_t.rbegin(); } + + + + + + + reverse_iterator + rend() const + { return _M_t.rend(); } +# 364 "/usr/include/c++/4.8.2/bits/stl_multiset.h" 3 + bool + empty() const + { return _M_t.empty(); } + + + size_type + size() const + { return _M_t.size(); } + + + size_type + max_size() const + { return _M_t.max_size(); } +# 389 "/usr/include/c++/4.8.2/bits/stl_multiset.h" 3 + void + swap(multiset& __x) + { _M_t.swap(__x._M_t); } +# 453 "/usr/include/c++/4.8.2/bits/stl_multiset.h" 3 + iterator + insert(const value_type& __x) + { return _M_t._M_insert_equal(__x); } +# 483 "/usr/include/c++/4.8.2/bits/stl_multiset.h" 3 + iterator + insert(const_iterator __position, const value_type& __x) + { return _M_t._M_insert_equal_(__position, __x); } +# 501 "/usr/include/c++/4.8.2/bits/stl_multiset.h" 3 + template + void + insert(_InputIterator __first, _InputIterator __last) + { _M_t._M_insert_equal(__first, __last); } +# 550 "/usr/include/c++/4.8.2/bits/stl_multiset.h" 3 + void + erase(iterator __position) + { _M_t.erase(__position); } +# 566 "/usr/include/c++/4.8.2/bits/stl_multiset.h" 3 + size_type + erase(const key_type& __x) + { return _M_t.erase(__x); } +# 604 "/usr/include/c++/4.8.2/bits/stl_multiset.h" 3 + void + erase(iterator __first, iterator __last) + { _M_t.erase(__first, __last); } +# 615 "/usr/include/c++/4.8.2/bits/stl_multiset.h" 3 + void + clear() + { _M_t.clear(); } +# 626 "/usr/include/c++/4.8.2/bits/stl_multiset.h" 3 + size_type + count(const key_type& __x) const + { return _M_t.count(__x); } +# 644 "/usr/include/c++/4.8.2/bits/stl_multiset.h" 3 + iterator + find(const key_type& __x) + { return _M_t.find(__x); } + + const_iterator + find(const key_type& __x) const + { return _M_t.find(__x); } +# 665 "/usr/include/c++/4.8.2/bits/stl_multiset.h" 3 + iterator + lower_bound(const key_type& __x) + { return _M_t.lower_bound(__x); } + + const_iterator + lower_bound(const key_type& __x) const + { return _M_t.lower_bound(__x); } +# 681 "/usr/include/c++/4.8.2/bits/stl_multiset.h" 3 + iterator + upper_bound(const key_type& __x) + { return _M_t.upper_bound(__x); } + + const_iterator + upper_bound(const key_type& __x) const + { return _M_t.upper_bound(__x); } +# 706 "/usr/include/c++/4.8.2/bits/stl_multiset.h" 3 + std::pair + equal_range(const key_type& __x) + { return _M_t.equal_range(__x); } + + std::pair + equal_range(const key_type& __x) const + { return _M_t.equal_range(__x); } + + + template + friend bool + operator==(const multiset<_K1, _C1, _A1>&, + const multiset<_K1, _C1, _A1>&); + + template + friend bool + operator< (const multiset<_K1, _C1, _A1>&, + const multiset<_K1, _C1, _A1>&); + }; +# 737 "/usr/include/c++/4.8.2/bits/stl_multiset.h" 3 + template + inline bool + operator==(const multiset<_Key, _Compare, _Alloc>& __x, + const multiset<_Key, _Compare, _Alloc>& __y) + { return __x._M_t == __y._M_t; } +# 754 "/usr/include/c++/4.8.2/bits/stl_multiset.h" 3 + template + inline bool + operator<(const multiset<_Key, _Compare, _Alloc>& __x, + const multiset<_Key, _Compare, _Alloc>& __y) + { return __x._M_t < __y._M_t; } + + + template + inline bool + operator!=(const multiset<_Key, _Compare, _Alloc>& __x, + const multiset<_Key, _Compare, _Alloc>& __y) + { return !(__x == __y); } + + + template + inline bool + operator>(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y) + { return __y < __x; } + + + template + inline bool + operator<=(const multiset<_Key, _Compare, _Alloc>& __x, + const multiset<_Key, _Compare, _Alloc>& __y) + { return !(__y < __x); } + + + template + inline bool + operator>=(const multiset<_Key, _Compare, _Alloc>& __x, + const multiset<_Key, _Compare, _Alloc>& __y) + { return !(__x < __y); } + + + template + inline void + swap(multiset<_Key, _Compare, _Alloc>& __x, + multiset<_Key, _Compare, _Alloc>& __y) + { __x.swap(__y); } + + +} +# 63 "/usr/include/c++/4.8.2/set" 2 3 +# 15 "include/CTypedef.h" 2 +# 1 "/usr/include/unistd.h" 1 3 4 +# 27 "/usr/include/unistd.h" 3 4 +extern "C" { +# 202 "/usr/include/unistd.h" 3 4 +# 1 "/usr/include/bits/posix_opt.h" 1 3 4 +# 203 "/usr/include/unistd.h" 2 3 4 + + + +# 1 "/usr/include/bits/environments.h" 1 3 4 +# 22 "/usr/include/bits/environments.h" 3 4 +# 1 "/usr/include/bits/wordsize.h" 1 3 4 +# 23 "/usr/include/bits/environments.h" 2 3 4 +# 207 "/usr/include/unistd.h" 2 3 4 +# 220 "/usr/include/unistd.h" 3 4 +typedef __ssize_t ssize_t; + + + + + +# 1 "/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stddef.h" 1 3 4 +# 227 "/usr/include/unistd.h" 2 3 4 + + + + + +typedef __gid_t gid_t; + + + + +typedef __uid_t uid_t; + + + + + +typedef __off_t off_t; + + + + + + +typedef __off64_t off64_t; + + + + +typedef __useconds_t useconds_t; +# 267 "/usr/include/unistd.h" 3 4 +typedef __intptr_t intptr_t; + + + + + + +typedef __socklen_t socklen_t; +# 287 "/usr/include/unistd.h" 3 4 +extern int access (const char *__name, int __type) throw () __attribute__ ((__nonnull__ (1))); + + + + +extern int euidaccess (const char *__name, int __type) + throw () __attribute__ ((__nonnull__ (1))); + + +extern int eaccess (const char *__name, int __type) + throw () __attribute__ ((__nonnull__ (1))); + + + + + + +extern int faccessat (int __fd, const char *__file, int __type, int __flag) + throw () __attribute__ ((__nonnull__ (2))) ; +# 334 "/usr/include/unistd.h" 3 4 +extern __off_t lseek (int __fd, __off_t __offset, int __whence) throw (); +# 345 "/usr/include/unistd.h" 3 4 +extern __off64_t lseek64 (int __fd, __off64_t __offset, int __whence) + throw (); + + + + + + +extern int close (int __fd); + + + + + + +extern ssize_t read (int __fd, void *__buf, size_t __nbytes) ; + + + + + +extern ssize_t write (int __fd, const void *__buf, size_t __n) ; +# 376 "/usr/include/unistd.h" 3 4 +extern ssize_t pread (int __fd, void *__buf, size_t __nbytes, + __off_t __offset) ; + + + + + + +extern ssize_t pwrite (int __fd, const void *__buf, size_t __n, + __off_t __offset) ; +# 404 "/usr/include/unistd.h" 3 4 +extern ssize_t pread64 (int __fd, void *__buf, size_t __nbytes, + __off64_t __offset) ; + + +extern ssize_t pwrite64 (int __fd, const void *__buf, size_t __n, + __off64_t __offset) ; + + + + + + + +extern int pipe (int __pipedes[2]) throw () ; + + + + +extern int pipe2 (int __pipedes[2], int __flags) throw () ; +# 432 "/usr/include/unistd.h" 3 4 +extern unsigned int alarm (unsigned int __seconds) throw (); +# 444 "/usr/include/unistd.h" 3 4 +extern unsigned int sleep (unsigned int __seconds); + + + + + + + +extern __useconds_t ualarm (__useconds_t __value, __useconds_t __interval) + throw (); + + + + + + +extern int usleep (__useconds_t __useconds); +# 469 "/usr/include/unistd.h" 3 4 +extern int pause (void); + + + +extern int chown (const char *__file, __uid_t __owner, __gid_t __group) + throw () __attribute__ ((__nonnull__ (1))) ; + + + +extern int fchown (int __fd, __uid_t __owner, __gid_t __group) throw () ; + + + + +extern int lchown (const char *__file, __uid_t __owner, __gid_t __group) + throw () __attribute__ ((__nonnull__ (1))) ; + + + + + + +extern int fchownat (int __fd, const char *__file, __uid_t __owner, + __gid_t __group, int __flag) + throw () __attribute__ ((__nonnull__ (2))) ; + + + +extern int chdir (const char *__path) throw () __attribute__ ((__nonnull__ (1))) ; + + + +extern int fchdir (int __fd) throw () ; +# 511 "/usr/include/unistd.h" 3 4 +extern char *getcwd (char *__buf, size_t __size) throw () ; + + + + + +extern char *get_current_dir_name (void) throw (); + + + + + + + +extern char *getwd (char *__buf) + throw () __attribute__ ((__nonnull__ (1))) __attribute__ ((__deprecated__)) ; + + + + +extern int dup (int __fd) throw () ; + + +extern int dup2 (int __fd, int __fd2) throw (); + + + + +extern int dup3 (int __fd, int __fd2, int __flags) throw (); + + + +extern char **__environ; + +extern char **environ; + + + + + +extern int execve (const char *__path, char *const __argv[], + char *const __envp[]) throw () __attribute__ ((__nonnull__ (1, 2))); + + + + +extern int fexecve (int __fd, char *const __argv[], char *const __envp[]) + throw () __attribute__ ((__nonnull__ (2))); + + + + +extern int execv (const char *__path, char *const __argv[]) + throw () __attribute__ ((__nonnull__ (1, 2))); + + + +extern int execle (const char *__path, const char *__arg, ...) + throw () __attribute__ ((__nonnull__ (1, 2))); + + + +extern int execl (const char *__path, const char *__arg, ...) + throw () __attribute__ ((__nonnull__ (1, 2))); + + + +extern int execvp (const char *__file, char *const __argv[]) + throw () __attribute__ ((__nonnull__ (1, 2))); + + + + +extern int execlp (const char *__file, const char *__arg, ...) + throw () __attribute__ ((__nonnull__ (1, 2))); + + + + +extern int execvpe (const char *__file, char *const __argv[], + char *const __envp[]) + throw () __attribute__ ((__nonnull__ (1, 2))); + + + + + +extern int nice (int __inc) throw () ; + + + + +extern void _exit (int __status) __attribute__ ((__noreturn__)); + + + + + +# 1 "/usr/include/bits/confname.h" 1 3 4 +# 25 "/usr/include/bits/confname.h" 3 4 +enum + { + _PC_LINK_MAX, + + _PC_MAX_CANON, + + _PC_MAX_INPUT, + + _PC_NAME_MAX, + + _PC_PATH_MAX, + + _PC_PIPE_BUF, + + _PC_CHOWN_RESTRICTED, + + _PC_NO_TRUNC, + + _PC_VDISABLE, + + _PC_SYNC_IO, + + _PC_ASYNC_IO, + + _PC_PRIO_IO, + + _PC_SOCK_MAXBUF, + + _PC_FILESIZEBITS, + + _PC_REC_INCR_XFER_SIZE, + + _PC_REC_MAX_XFER_SIZE, + + _PC_REC_MIN_XFER_SIZE, + + _PC_REC_XFER_ALIGN, + + _PC_ALLOC_SIZE_MIN, + + _PC_SYMLINK_MAX, + + _PC_2_SYMLINKS + + }; + + +enum + { + _SC_ARG_MAX, + + _SC_CHILD_MAX, + + _SC_CLK_TCK, + + _SC_NGROUPS_MAX, + + _SC_OPEN_MAX, + + _SC_STREAM_MAX, + + _SC_TZNAME_MAX, + + _SC_JOB_CONTROL, + + _SC_SAVED_IDS, + + _SC_REALTIME_SIGNALS, + + _SC_PRIORITY_SCHEDULING, + + _SC_TIMERS, + + _SC_ASYNCHRONOUS_IO, + + _SC_PRIORITIZED_IO, + + _SC_SYNCHRONIZED_IO, + + _SC_FSYNC, + + _SC_MAPPED_FILES, + + _SC_MEMLOCK, + + _SC_MEMLOCK_RANGE, + + _SC_MEMORY_PROTECTION, + + _SC_MESSAGE_PASSING, + + _SC_SEMAPHORES, + + _SC_SHARED_MEMORY_OBJECTS, + + _SC_AIO_LISTIO_MAX, + + _SC_AIO_MAX, + + _SC_AIO_PRIO_DELTA_MAX, + + _SC_DELAYTIMER_MAX, + + _SC_MQ_OPEN_MAX, + + _SC_MQ_PRIO_MAX, + + _SC_VERSION, + + _SC_PAGESIZE, + + + _SC_RTSIG_MAX, + + _SC_SEM_NSEMS_MAX, + + _SC_SEM_VALUE_MAX, + + _SC_SIGQUEUE_MAX, + + _SC_TIMER_MAX, + + + + + _SC_BC_BASE_MAX, + + _SC_BC_DIM_MAX, + + _SC_BC_SCALE_MAX, + + _SC_BC_STRING_MAX, + + _SC_COLL_WEIGHTS_MAX, + + _SC_EQUIV_CLASS_MAX, + + _SC_EXPR_NEST_MAX, + + _SC_LINE_MAX, + + _SC_RE_DUP_MAX, + + _SC_CHARCLASS_NAME_MAX, + + + _SC_2_VERSION, + + _SC_2_C_BIND, + + _SC_2_C_DEV, + + _SC_2_FORT_DEV, + + _SC_2_FORT_RUN, + + _SC_2_SW_DEV, + + _SC_2_LOCALEDEF, + + + _SC_PII, + + _SC_PII_XTI, + + _SC_PII_SOCKET, + + _SC_PII_INTERNET, + + _SC_PII_OSI, + + _SC_POLL, + + _SC_SELECT, + + _SC_UIO_MAXIOV, + + _SC_IOV_MAX = _SC_UIO_MAXIOV, + + _SC_PII_INTERNET_STREAM, + + _SC_PII_INTERNET_DGRAM, + + _SC_PII_OSI_COTS, + + _SC_PII_OSI_CLTS, + + _SC_PII_OSI_M, + + _SC_T_IOV_MAX, + + + + _SC_THREADS, + + _SC_THREAD_SAFE_FUNCTIONS, + + _SC_GETGR_R_SIZE_MAX, + + _SC_GETPW_R_SIZE_MAX, + + _SC_LOGIN_NAME_MAX, + + _SC_TTY_NAME_MAX, + + _SC_THREAD_DESTRUCTOR_ITERATIONS, + + _SC_THREAD_KEYS_MAX, + + _SC_THREAD_STACK_MIN, + + _SC_THREAD_THREADS_MAX, + + _SC_THREAD_ATTR_STACKADDR, + + _SC_THREAD_ATTR_STACKSIZE, + + _SC_THREAD_PRIORITY_SCHEDULING, + + _SC_THREAD_PRIO_INHERIT, + + _SC_THREAD_PRIO_PROTECT, + + _SC_THREAD_PROCESS_SHARED, + + + _SC_NPROCESSORS_CONF, + + _SC_NPROCESSORS_ONLN, + + _SC_PHYS_PAGES, + + _SC_AVPHYS_PAGES, + + _SC_ATEXIT_MAX, + + _SC_PASS_MAX, + + + _SC_XOPEN_VERSION, + + _SC_XOPEN_XCU_VERSION, + + _SC_XOPEN_UNIX, + + _SC_XOPEN_CRYPT, + + _SC_XOPEN_ENH_I18N, + + _SC_XOPEN_SHM, + + + _SC_2_CHAR_TERM, + + _SC_2_C_VERSION, + + _SC_2_UPE, + + + _SC_XOPEN_XPG2, + + _SC_XOPEN_XPG3, + + _SC_XOPEN_XPG4, + + + _SC_CHAR_BIT, + + _SC_CHAR_MAX, + + _SC_CHAR_MIN, + + _SC_INT_MAX, + + _SC_INT_MIN, + + _SC_LONG_BIT, + + _SC_WORD_BIT, + + _SC_MB_LEN_MAX, + + _SC_NZERO, + + _SC_SSIZE_MAX, + + _SC_SCHAR_MAX, + + _SC_SCHAR_MIN, + + _SC_SHRT_MAX, + + _SC_SHRT_MIN, + + _SC_UCHAR_MAX, + + _SC_UINT_MAX, + + _SC_ULONG_MAX, + + _SC_USHRT_MAX, + + + _SC_NL_ARGMAX, + + _SC_NL_LANGMAX, + + _SC_NL_MSGMAX, + + _SC_NL_NMAX, + + _SC_NL_SETMAX, + + _SC_NL_TEXTMAX, + + + _SC_XBS5_ILP32_OFF32, + + _SC_XBS5_ILP32_OFFBIG, + + _SC_XBS5_LP64_OFF64, + + _SC_XBS5_LPBIG_OFFBIG, + + + _SC_XOPEN_LEGACY, + + _SC_XOPEN_REALTIME, + + _SC_XOPEN_REALTIME_THREADS, + + + _SC_ADVISORY_INFO, + + _SC_BARRIERS, + + _SC_BASE, + + _SC_C_LANG_SUPPORT, + + _SC_C_LANG_SUPPORT_R, + + _SC_CLOCK_SELECTION, + + _SC_CPUTIME, + + _SC_THREAD_CPUTIME, + + _SC_DEVICE_IO, + + _SC_DEVICE_SPECIFIC, + + _SC_DEVICE_SPECIFIC_R, + + _SC_FD_MGMT, + + _SC_FIFO, + + _SC_PIPE, + + _SC_FILE_ATTRIBUTES, + + _SC_FILE_LOCKING, + + _SC_FILE_SYSTEM, + + _SC_MONOTONIC_CLOCK, + + _SC_MULTI_PROCESS, + + _SC_SINGLE_PROCESS, + + _SC_NETWORKING, + + _SC_READER_WRITER_LOCKS, + + _SC_SPIN_LOCKS, + + _SC_REGEXP, + + _SC_REGEX_VERSION, + + _SC_SHELL, + + _SC_SIGNALS, + + _SC_SPAWN, + + _SC_SPORADIC_SERVER, + + _SC_THREAD_SPORADIC_SERVER, + + _SC_SYSTEM_DATABASE, + + _SC_SYSTEM_DATABASE_R, + + _SC_TIMEOUTS, + + _SC_TYPED_MEMORY_OBJECTS, + + _SC_USER_GROUPS, + + _SC_USER_GROUPS_R, + + _SC_2_PBS, + + _SC_2_PBS_ACCOUNTING, + + _SC_2_PBS_LOCATE, + + _SC_2_PBS_MESSAGE, + + _SC_2_PBS_TRACK, + + _SC_SYMLOOP_MAX, + + _SC_STREAMS, + + _SC_2_PBS_CHECKPOINT, + + + _SC_V6_ILP32_OFF32, + + _SC_V6_ILP32_OFFBIG, + + _SC_V6_LP64_OFF64, + + _SC_V6_LPBIG_OFFBIG, + + + _SC_HOST_NAME_MAX, + + _SC_TRACE, + + _SC_TRACE_EVENT_FILTER, + + _SC_TRACE_INHERIT, + + _SC_TRACE_LOG, + + + _SC_LEVEL1_ICACHE_SIZE, + + _SC_LEVEL1_ICACHE_ASSOC, + + _SC_LEVEL1_ICACHE_LINESIZE, + + _SC_LEVEL1_DCACHE_SIZE, + + _SC_LEVEL1_DCACHE_ASSOC, + + _SC_LEVEL1_DCACHE_LINESIZE, + + _SC_LEVEL2_CACHE_SIZE, + + _SC_LEVEL2_CACHE_ASSOC, + + _SC_LEVEL2_CACHE_LINESIZE, + + _SC_LEVEL3_CACHE_SIZE, + + _SC_LEVEL3_CACHE_ASSOC, + + _SC_LEVEL3_CACHE_LINESIZE, + + _SC_LEVEL4_CACHE_SIZE, + + _SC_LEVEL4_CACHE_ASSOC, + + _SC_LEVEL4_CACHE_LINESIZE, + + + + _SC_IPV6 = _SC_LEVEL1_ICACHE_SIZE + 50, + + _SC_RAW_SOCKETS, + + + _SC_V7_ILP32_OFF32, + + _SC_V7_ILP32_OFFBIG, + + _SC_V7_LP64_OFF64, + + _SC_V7_LPBIG_OFFBIG, + + + _SC_SS_REPL_MAX, + + + _SC_TRACE_EVENT_NAME_MAX, + + _SC_TRACE_NAME_MAX, + + _SC_TRACE_SYS_MAX, + + _SC_TRACE_USER_EVENT_MAX, + + + _SC_XOPEN_STREAMS, + + + _SC_THREAD_ROBUST_PRIO_INHERIT, + + _SC_THREAD_ROBUST_PRIO_PROTECT + + }; + + +enum + { + _CS_PATH, + + + _CS_V6_WIDTH_RESTRICTED_ENVS, + + + + _CS_GNU_LIBC_VERSION, + + _CS_GNU_LIBPTHREAD_VERSION, + + + _CS_V5_WIDTH_RESTRICTED_ENVS, + + + + _CS_V7_WIDTH_RESTRICTED_ENVS, + + + + _CS_LFS_CFLAGS = 1000, + + _CS_LFS_LDFLAGS, + + _CS_LFS_LIBS, + + _CS_LFS_LINTFLAGS, + + _CS_LFS64_CFLAGS, + + _CS_LFS64_LDFLAGS, + + _CS_LFS64_LIBS, + + _CS_LFS64_LINTFLAGS, + + + _CS_XBS5_ILP32_OFF32_CFLAGS = 1100, + + _CS_XBS5_ILP32_OFF32_LDFLAGS, + + _CS_XBS5_ILP32_OFF32_LIBS, + + _CS_XBS5_ILP32_OFF32_LINTFLAGS, + + _CS_XBS5_ILP32_OFFBIG_CFLAGS, + + _CS_XBS5_ILP32_OFFBIG_LDFLAGS, + + _CS_XBS5_ILP32_OFFBIG_LIBS, + + _CS_XBS5_ILP32_OFFBIG_LINTFLAGS, + + _CS_XBS5_LP64_OFF64_CFLAGS, + + _CS_XBS5_LP64_OFF64_LDFLAGS, + + _CS_XBS5_LP64_OFF64_LIBS, + + _CS_XBS5_LP64_OFF64_LINTFLAGS, + + _CS_XBS5_LPBIG_OFFBIG_CFLAGS, + + _CS_XBS5_LPBIG_OFFBIG_LDFLAGS, + + _CS_XBS5_LPBIG_OFFBIG_LIBS, + + _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS, + + + _CS_POSIX_V6_ILP32_OFF32_CFLAGS, + + _CS_POSIX_V6_ILP32_OFF32_LDFLAGS, + + _CS_POSIX_V6_ILP32_OFF32_LIBS, + + _CS_POSIX_V6_ILP32_OFF32_LINTFLAGS, + + _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS, + + _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS, + + _CS_POSIX_V6_ILP32_OFFBIG_LIBS, + + _CS_POSIX_V6_ILP32_OFFBIG_LINTFLAGS, + + _CS_POSIX_V6_LP64_OFF64_CFLAGS, + + _CS_POSIX_V6_LP64_OFF64_LDFLAGS, + + _CS_POSIX_V6_LP64_OFF64_LIBS, + + _CS_POSIX_V6_LP64_OFF64_LINTFLAGS, + + _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS, + + _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS, + + _CS_POSIX_V6_LPBIG_OFFBIG_LIBS, + + _CS_POSIX_V6_LPBIG_OFFBIG_LINTFLAGS, + + + _CS_POSIX_V7_ILP32_OFF32_CFLAGS, + + _CS_POSIX_V7_ILP32_OFF32_LDFLAGS, + + _CS_POSIX_V7_ILP32_OFF32_LIBS, + + _CS_POSIX_V7_ILP32_OFF32_LINTFLAGS, + + _CS_POSIX_V7_ILP32_OFFBIG_CFLAGS, + + _CS_POSIX_V7_ILP32_OFFBIG_LDFLAGS, + + _CS_POSIX_V7_ILP32_OFFBIG_LIBS, + + _CS_POSIX_V7_ILP32_OFFBIG_LINTFLAGS, + + _CS_POSIX_V7_LP64_OFF64_CFLAGS, + + _CS_POSIX_V7_LP64_OFF64_LDFLAGS, + + _CS_POSIX_V7_LP64_OFF64_LIBS, + + _CS_POSIX_V7_LP64_OFF64_LINTFLAGS, + + _CS_POSIX_V7_LPBIG_OFFBIG_CFLAGS, + + _CS_POSIX_V7_LPBIG_OFFBIG_LDFLAGS, + + _CS_POSIX_V7_LPBIG_OFFBIG_LIBS, + + _CS_POSIX_V7_LPBIG_OFFBIG_LINTFLAGS, + + + _CS_V6_ENV, + + _CS_V7_ENV + + }; +# 610 "/usr/include/unistd.h" 2 3 4 + + +extern long int pathconf (const char *__path, int __name) + throw () __attribute__ ((__nonnull__ (1))); + + +extern long int fpathconf (int __fd, int __name) throw (); + + +extern long int sysconf (int __name) throw (); + + + +extern size_t confstr (int __name, char *__buf, size_t __len) throw (); + + + + +extern __pid_t getpid (void) throw (); + + +extern __pid_t getppid (void) throw (); + + + + +extern __pid_t getpgrp (void) throw (); +# 646 "/usr/include/unistd.h" 3 4 +extern __pid_t __getpgid (__pid_t __pid) throw (); + +extern __pid_t getpgid (__pid_t __pid) throw (); + + + + + + +extern int setpgid (__pid_t __pid, __pid_t __pgid) throw (); +# 672 "/usr/include/unistd.h" 3 4 +extern int setpgrp (void) throw (); +# 689 "/usr/include/unistd.h" 3 4 +extern __pid_t setsid (void) throw (); + + + +extern __pid_t getsid (__pid_t __pid) throw (); + + + +extern __uid_t getuid (void) throw (); + + +extern __uid_t geteuid (void) throw (); + + +extern __gid_t getgid (void) throw (); + + +extern __gid_t getegid (void) throw (); + + + + +extern int getgroups (int __size, __gid_t __list[]) throw () ; + + + +extern int group_member (__gid_t __gid) throw (); + + + + + + +extern int setuid (__uid_t __uid) throw () ; + + + + +extern int setreuid (__uid_t __ruid, __uid_t __euid) throw () ; + + + + +extern int seteuid (__uid_t __uid) throw () ; + + + + + + +extern int setgid (__gid_t __gid) throw () ; + + + + +extern int setregid (__gid_t __rgid, __gid_t __egid) throw () ; + + + + +extern int setegid (__gid_t __gid) throw () ; + + + + + +extern int getresuid (__uid_t *__ruid, __uid_t *__euid, __uid_t *__suid) + throw (); + + + +extern int getresgid (__gid_t *__rgid, __gid_t *__egid, __gid_t *__sgid) + throw (); + + + +extern int setresuid (__uid_t __ruid, __uid_t __euid, __uid_t __suid) + throw () ; + + + +extern int setresgid (__gid_t __rgid, __gid_t __egid, __gid_t __sgid) + throw () ; + + + + + + +extern __pid_t fork (void) throw (); + + + + + + + +extern __pid_t vfork (void) throw (); + + + + + +extern char *ttyname (int __fd) throw (); + + + +extern int ttyname_r (int __fd, char *__buf, size_t __buflen) + throw () __attribute__ ((__nonnull__ (2))) ; + + + +extern int isatty (int __fd) throw (); + + + + + +extern int ttyslot (void) throw (); + + + + +extern int link (const char *__from, const char *__to) + throw () __attribute__ ((__nonnull__ (1, 2))) ; + + + + +extern int linkat (int __fromfd, const char *__from, int __tofd, + const char *__to, int __flags) + throw () __attribute__ ((__nonnull__ (2, 4))) ; + + + + +extern int symlink (const char *__from, const char *__to) + throw () __attribute__ ((__nonnull__ (1, 2))) ; + + + + +extern ssize_t readlink (const char *__restrict __path, + char *__restrict __buf, size_t __len) + throw () __attribute__ ((__nonnull__ (1, 2))) ; + + + + +extern int symlinkat (const char *__from, int __tofd, + const char *__to) throw () __attribute__ ((__nonnull__ (1, 3))) ; + + +extern ssize_t readlinkat (int __fd, const char *__restrict __path, + char *__restrict __buf, size_t __len) + throw () __attribute__ ((__nonnull__ (2, 3))) ; + + + +extern int unlink (const char *__name) throw () __attribute__ ((__nonnull__ (1))); + + + +extern int unlinkat (int __fd, const char *__name, int __flag) + throw () __attribute__ ((__nonnull__ (2))); + + + +extern int rmdir (const char *__path) throw () __attribute__ ((__nonnull__ (1))); + + + +extern __pid_t tcgetpgrp (int __fd) throw (); + + +extern int tcsetpgrp (int __fd, __pid_t __pgrp_id) throw (); + + + + + + +extern char *getlogin (void); + + + + + + + +extern int getlogin_r (char *__name, size_t __name_len) __attribute__ ((__nonnull__ (1))); + + + + +extern int setlogin (const char *__name) throw () __attribute__ ((__nonnull__ (1))); +# 893 "/usr/include/unistd.h" 3 4 +# 1 "/usr/include/getopt.h" 1 3 4 +# 49 "/usr/include/getopt.h" 3 4 +extern "C" { +# 58 "/usr/include/getopt.h" 3 4 +extern char *optarg; +# 72 "/usr/include/getopt.h" 3 4 +extern int optind; + + + + +extern int opterr; + + + +extern int optopt; +# 151 "/usr/include/getopt.h" 3 4 +extern int getopt (int ___argc, char *const *___argv, const char *__shortopts) + throw (); +# 186 "/usr/include/getopt.h" 3 4 +} +# 894 "/usr/include/unistd.h" 2 3 4 + + + + + + + +extern int gethostname (char *__name, size_t __len) throw () __attribute__ ((__nonnull__ (1))); + + + + + + +extern int sethostname (const char *__name, size_t __len) + throw () __attribute__ ((__nonnull__ (1))) ; + + + +extern int sethostid (long int __id) throw () ; + + + + + +extern int getdomainname (char *__name, size_t __len) + throw () __attribute__ ((__nonnull__ (1))) ; +extern int setdomainname (const char *__name, size_t __len) + throw () __attribute__ ((__nonnull__ (1))) ; + + + + + +extern int vhangup (void) throw (); + + +extern int revoke (const char *__file) throw () __attribute__ ((__nonnull__ (1))) ; + + + + + + + +extern int profil (unsigned short int *__sample_buffer, size_t __size, + size_t __offset, unsigned int __scale) + throw () __attribute__ ((__nonnull__ (1))); + + + + + +extern int acct (const char *__name) throw (); + + + +extern char *getusershell (void) throw (); +extern void endusershell (void) throw (); +extern void setusershell (void) throw (); + + + + + +extern int daemon (int __nochdir, int __noclose) throw () ; + + + + + + +extern int chroot (const char *__path) throw () __attribute__ ((__nonnull__ (1))) ; + + + +extern char *getpass (const char *__prompt) __attribute__ ((__nonnull__ (1))); + + + + + + + +extern int fsync (int __fd); + + + + + +extern int syncfs (int __fd) throw (); + + + + + + +extern long int gethostid (void); + + +extern void sync (void) throw (); + + + + + +extern int getpagesize (void) throw () __attribute__ ((__const__)); + + + + +extern int getdtablesize (void) throw (); +# 1015 "/usr/include/unistd.h" 3 4 +extern int truncate (const char *__file, __off_t __length) + throw () __attribute__ ((__nonnull__ (1))) ; +# 1027 "/usr/include/unistd.h" 3 4 +extern int truncate64 (const char *__file, __off64_t __length) + throw () __attribute__ ((__nonnull__ (1))) ; +# 1038 "/usr/include/unistd.h" 3 4 +extern int ftruncate (int __fd, __off_t __length) throw () ; +# 1048 "/usr/include/unistd.h" 3 4 +extern int ftruncate64 (int __fd, __off64_t __length) throw () ; +# 1059 "/usr/include/unistd.h" 3 4 +extern int brk (void *__addr) throw () ; + + + + + +extern void *sbrk (intptr_t __delta) throw (); +# 1080 "/usr/include/unistd.h" 3 4 +extern long int syscall (long int __sysno, ...) throw (); +# 1103 "/usr/include/unistd.h" 3 4 +extern int lockf (int __fd, int __cmd, __off_t __len) ; +# 1113 "/usr/include/unistd.h" 3 4 +extern int lockf64 (int __fd, int __cmd, __off64_t __len) ; +# 1134 "/usr/include/unistd.h" 3 4 +extern int fdatasync (int __fildes); + + + + + + + +extern char *crypt (const char *__key, const char *__salt) + throw () __attribute__ ((__nonnull__ (1, 2))); + + + +extern void encrypt (char *__block, int __edflag) throw () __attribute__ ((__nonnull__ (1))); + + + + + + +extern void swab (const void *__restrict __from, void *__restrict __to, + ssize_t __n) throw () __attribute__ ((__nonnull__ (1, 2))); +# 1172 "/usr/include/unistd.h" 3 4 +} +# 16 "include/CTypedef.h" 2 +# 1 "/usr/include/sys/time.h" 1 3 4 +# 28 "/usr/include/sys/time.h" 3 4 +# 1 "/usr/include/bits/time.h" 1 3 4 +# 29 "/usr/include/sys/time.h" 2 3 4 + +# 1 "/usr/include/sys/select.h" 1 3 4 +# 30 "/usr/include/sys/select.h" 3 4 +# 1 "/usr/include/bits/select.h" 1 3 4 +# 22 "/usr/include/bits/select.h" 3 4 +# 1 "/usr/include/bits/wordsize.h" 1 3 4 +# 23 "/usr/include/bits/select.h" 2 3 4 +# 31 "/usr/include/sys/select.h" 2 3 4 + + +# 1 "/usr/include/bits/sigset.h" 1 3 4 +# 23 "/usr/include/bits/sigset.h" 3 4 +typedef int __sig_atomic_t; + + + + +typedef struct + { + unsigned long int __val[(1024 / (8 * sizeof (unsigned long int)))]; + } __sigset_t; +# 34 "/usr/include/sys/select.h" 2 3 4 + + + +typedef __sigset_t sigset_t; + + + + + + + +# 1 "/usr/include/bits/time.h" 1 3 4 +# 46 "/usr/include/sys/select.h" 2 3 4 + + +typedef __suseconds_t suseconds_t; + + + + + +typedef long int __fd_mask; +# 64 "/usr/include/sys/select.h" 3 4 +typedef struct + { + + + + __fd_mask fds_bits[1024 / (8 * (int) sizeof (__fd_mask))]; + + + + + + } fd_set; + + + + + + +typedef __fd_mask fd_mask; +# 96 "/usr/include/sys/select.h" 3 4 +extern "C" { +# 106 "/usr/include/sys/select.h" 3 4 +extern int select (int __nfds, fd_set *__restrict __readfds, + fd_set *__restrict __writefds, + fd_set *__restrict __exceptfds, + struct timeval *__restrict __timeout); +# 118 "/usr/include/sys/select.h" 3 4 +extern int pselect (int __nfds, fd_set *__restrict __readfds, + fd_set *__restrict __writefds, + fd_set *__restrict __exceptfds, + const struct timespec *__restrict __timeout, + const __sigset_t *__restrict __sigmask); +# 131 "/usr/include/sys/select.h" 3 4 +} +# 31 "/usr/include/sys/time.h" 2 3 4 + + + + + + + +extern "C" { +# 56 "/usr/include/sys/time.h" 3 4 +struct timezone + { + int tz_minuteswest; + int tz_dsttime; + }; + +typedef struct timezone *__restrict __timezone_ptr_t; +# 72 "/usr/include/sys/time.h" 3 4 +extern int gettimeofday (struct timeval *__restrict __tv, + __timezone_ptr_t __tz) throw () __attribute__ ((__nonnull__ (1))); + + + + +extern int settimeofday (const struct timeval *__tv, + const struct timezone *__tz) + throw (); + + + + + +extern int adjtime (const struct timeval *__delta, + struct timeval *__olddelta) throw (); + + + + +enum __itimer_which + { + + ITIMER_REAL = 0, + + + ITIMER_VIRTUAL = 1, + + + + ITIMER_PROF = 2 + + }; + + + +struct itimerval + { + + struct timeval it_interval; + + struct timeval it_value; + }; + + + + + + +typedef int __itimer_which_t; + + + + +extern int getitimer (__itimer_which_t __which, + struct itimerval *__value) throw (); + + + + +extern int setitimer (__itimer_which_t __which, + const struct itimerval *__restrict __new, + struct itimerval *__restrict __old) throw (); + + + + +extern int utimes (const char *__file, const struct timeval __tvp[2]) + throw () __attribute__ ((__nonnull__ (1))); + + + +extern int lutimes (const char *__file, const struct timeval __tvp[2]) + throw () __attribute__ ((__nonnull__ (1))); + + +extern int futimes (int __fd, const struct timeval __tvp[2]) throw (); + + + + + + +extern int futimesat (int __fd, const char *__file, + const struct timeval __tvp[2]) throw (); +# 190 "/usr/include/sys/time.h" 3 4 +} +# 17 "include/CTypedef.h" 2 +# 1 "/usr/include/arpa/inet.h" 1 3 4 +# 22 "/usr/include/arpa/inet.h" 3 4 +# 1 "/usr/include/netinet/in.h" 1 3 4 +# 23 "/usr/include/netinet/in.h" 3 4 +# 1 "/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stdint.h" 1 3 4 +# 9 "/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stdint.h" 3 4 +# 1 "/usr/include/stdint.h" 1 3 4 +# 27 "/usr/include/stdint.h" 3 4 +# 1 "/usr/include/bits/wordsize.h" 1 3 4 +# 28 "/usr/include/stdint.h" 2 3 4 +# 36 "/usr/include/stdint.h" 3 4 +typedef signed char int8_t; +typedef short int int16_t; +typedef int int32_t; + +typedef long int int64_t; + + + + + + + +typedef unsigned char uint8_t; +typedef unsigned short int uint16_t; + +typedef unsigned int uint32_t; + + + +typedef unsigned long int uint64_t; +# 65 "/usr/include/stdint.h" 3 4 +typedef signed char int_least8_t; +typedef short int int_least16_t; +typedef int int_least32_t; + +typedef long int int_least64_t; + + + + + + +typedef unsigned char uint_least8_t; +typedef unsigned short int uint_least16_t; +typedef unsigned int uint_least32_t; + +typedef unsigned long int uint_least64_t; +# 90 "/usr/include/stdint.h" 3 4 +typedef signed char int_fast8_t; + +typedef long int int_fast16_t; +typedef long int int_fast32_t; +typedef long int int_fast64_t; +# 103 "/usr/include/stdint.h" 3 4 +typedef unsigned char uint_fast8_t; + +typedef unsigned long int uint_fast16_t; +typedef unsigned long int uint_fast32_t; +typedef unsigned long int uint_fast64_t; +# 122 "/usr/include/stdint.h" 3 4 +typedef unsigned long int uintptr_t; +# 134 "/usr/include/stdint.h" 3 4 +typedef long int intmax_t; +typedef unsigned long int uintmax_t; +# 10 "/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stdint.h" 2 3 4 +# 24 "/usr/include/netinet/in.h" 2 3 4 +# 1 "/usr/include/sys/socket.h" 1 3 4 +# 25 "/usr/include/sys/socket.h" 3 4 +extern "C" { + +# 1 "/usr/include/sys/uio.h" 1 3 4 +# 24 "/usr/include/sys/uio.h" 3 4 +# 1 "/usr/include/sys/types.h" 1 3 4 +# 27 "/usr/include/sys/types.h" 3 4 +extern "C" { + + + + + +typedef __u_char u_char; +typedef __u_short u_short; +typedef __u_int u_int; +typedef __u_long u_long; +typedef __quad_t quad_t; +typedef __u_quad_t u_quad_t; +typedef __fsid_t fsid_t; + + + + +typedef __loff_t loff_t; + + + +typedef __ino_t ino_t; + + + + + + +typedef __ino64_t ino64_t; + + + + +typedef __dev_t dev_t; +# 70 "/usr/include/sys/types.h" 3 4 +typedef __mode_t mode_t; + + + + +typedef __nlink_t nlink_t; +# 104 "/usr/include/sys/types.h" 3 4 +typedef __id_t id_t; +# 115 "/usr/include/sys/types.h" 3 4 +typedef __daddr_t daddr_t; +typedef __caddr_t caddr_t; + + + + + +typedef __key_t key_t; +# 146 "/usr/include/sys/types.h" 3 4 +# 1 "/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stddef.h" 1 3 4 +# 147 "/usr/include/sys/types.h" 2 3 4 + + + +typedef unsigned long int ulong; +typedef unsigned short int ushort; +typedef unsigned int uint; +# 200 "/usr/include/sys/types.h" 3 4 +typedef unsigned int u_int8_t __attribute__ ((__mode__ (__QI__))); +typedef unsigned int u_int16_t __attribute__ ((__mode__ (__HI__))); +typedef unsigned int u_int32_t __attribute__ ((__mode__ (__SI__))); +typedef unsigned int u_int64_t __attribute__ ((__mode__ (__DI__))); + +typedef int register_t __attribute__ ((__mode__ (__word__))); +# 222 "/usr/include/sys/types.h" 3 4 +# 1 "/usr/include/sys/sysmacros.h" 1 3 4 +# 29 "/usr/include/sys/sysmacros.h" 3 4 +extern "C" { + +__extension__ +extern unsigned int gnu_dev_major (unsigned long long int __dev) + throw () __attribute__ ((__const__)); +__extension__ +extern unsigned int gnu_dev_minor (unsigned long long int __dev) + throw () __attribute__ ((__const__)); +__extension__ +extern unsigned long long int gnu_dev_makedev (unsigned int __major, + unsigned int __minor) + throw () __attribute__ ((__const__)); +# 63 "/usr/include/sys/sysmacros.h" 3 4 +} +# 223 "/usr/include/sys/types.h" 2 3 4 + + + + + +typedef __blksize_t blksize_t; + + + + + + +typedef __blkcnt_t blkcnt_t; + + + +typedef __fsblkcnt_t fsblkcnt_t; + + + +typedef __fsfilcnt_t fsfilcnt_t; +# 262 "/usr/include/sys/types.h" 3 4 +typedef __blkcnt64_t blkcnt64_t; +typedef __fsblkcnt64_t fsblkcnt64_t; +typedef __fsfilcnt64_t fsfilcnt64_t; +# 273 "/usr/include/sys/types.h" 3 4 +} +# 25 "/usr/include/sys/uio.h" 2 3 4 + +extern "C" { + + +# 1 "/usr/include/bits/uio.h" 1 3 4 +# 43 "/usr/include/bits/uio.h" 3 4 +struct iovec + { + void *iov_base; + size_t iov_len; + }; +# 56 "/usr/include/bits/uio.h" 3 4 +extern "C" { + + +extern ssize_t process_vm_readv (pid_t __pid, const struct iovec *__lvec, + unsigned long int __liovcnt, + const struct iovec *__rvec, + unsigned long int __riovcnt, + unsigned long int __flags) + throw (); + + +extern ssize_t process_vm_writev (pid_t __pid, const struct iovec *__lvec, + unsigned long int __liovcnt, + const struct iovec *__rvec, + unsigned long int __riovcnt, + unsigned long int __flags) + throw (); + +} +# 30 "/usr/include/sys/uio.h" 2 3 4 +# 40 "/usr/include/sys/uio.h" 3 4 +extern ssize_t readv (int __fd, const struct iovec *__iovec, int __count) + ; +# 51 "/usr/include/sys/uio.h" 3 4 +extern ssize_t writev (int __fd, const struct iovec *__iovec, int __count) + ; +# 66 "/usr/include/sys/uio.h" 3 4 +extern ssize_t preadv (int __fd, const struct iovec *__iovec, int __count, + __off_t __offset) ; +# 78 "/usr/include/sys/uio.h" 3 4 +extern ssize_t pwritev (int __fd, const struct iovec *__iovec, int __count, + __off_t __offset) ; +# 104 "/usr/include/sys/uio.h" 3 4 +extern ssize_t preadv64 (int __fd, const struct iovec *__iovec, int __count, + __off64_t __offset) ; +# 116 "/usr/include/sys/uio.h" 3 4 +extern ssize_t pwritev64 (int __fd, const struct iovec *__iovec, int __count, + __off64_t __offset) ; + + + +} +# 28 "/usr/include/sys/socket.h" 2 3 4 + +# 1 "/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stddef.h" 1 3 4 +# 30 "/usr/include/sys/socket.h" 2 3 4 + + +# 1 "/usr/include/bits/sigset.h" 1 3 4 +# 33 "/usr/include/sys/socket.h" 2 3 4 + + + + + + +# 1 "/usr/include/bits/socket.h" 1 3 4 +# 28 "/usr/include/bits/socket.h" 3 4 +# 1 "/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stddef.h" 1 3 4 +# 29 "/usr/include/bits/socket.h" 2 3 4 +# 39 "/usr/include/bits/socket.h" 3 4 +# 1 "/usr/include/bits/socket_type.h" 1 3 4 +# 24 "/usr/include/bits/socket_type.h" 3 4 +enum __socket_type +{ + SOCK_STREAM = 1, + + + SOCK_DGRAM = 2, + + + SOCK_RAW = 3, + + SOCK_RDM = 4, + + SOCK_SEQPACKET = 5, + + + SOCK_DCCP = 6, + + SOCK_PACKET = 10, + + + + + + + + SOCK_CLOEXEC = 02000000, + + + SOCK_NONBLOCK = 00004000 + + +}; +# 40 "/usr/include/bits/socket.h" 2 3 4 +# 151 "/usr/include/bits/socket.h" 3 4 +# 1 "/usr/include/bits/sockaddr.h" 1 3 4 +# 28 "/usr/include/bits/sockaddr.h" 3 4 +typedef unsigned short int sa_family_t; +# 152 "/usr/include/bits/socket.h" 2 3 4 + + +struct sockaddr + { + sa_family_t sa_family; + char sa_data[14]; + }; +# 167 "/usr/include/bits/socket.h" 3 4 +struct sockaddr_storage + { + sa_family_t ss_family; + char __ss_padding[(128 - (sizeof (unsigned short int)) - sizeof (unsigned long int))]; + unsigned long int __ss_align; + }; + + + +enum + { + MSG_OOB = 0x01, + + MSG_PEEK = 0x02, + + MSG_DONTROUTE = 0x04, + + + + MSG_TRYHARD = MSG_DONTROUTE, + + + MSG_CTRUNC = 0x08, + + MSG_PROXY = 0x10, + + MSG_TRUNC = 0x20, + + MSG_DONTWAIT = 0x40, + + MSG_EOR = 0x80, + + MSG_WAITALL = 0x100, + + MSG_FIN = 0x200, + + MSG_SYN = 0x400, + + MSG_CONFIRM = 0x800, + + MSG_RST = 0x1000, + + MSG_ERRQUEUE = 0x2000, + + MSG_NOSIGNAL = 0x4000, + + MSG_MORE = 0x8000, + + MSG_WAITFORONE = 0x10000, + + MSG_FASTOPEN = 0x20000000, + + + MSG_CMSG_CLOEXEC = 0x40000000 + + + + }; + + + + +struct msghdr + { + void *msg_name; + socklen_t msg_namelen; + + struct iovec *msg_iov; + size_t msg_iovlen; + + void *msg_control; + size_t msg_controllen; + + + + + int msg_flags; + }; + + +struct cmsghdr + { + size_t cmsg_len; + + + + + int cmsg_level; + int cmsg_type; + + __extension__ unsigned char __cmsg_data []; + + }; +# 277 "/usr/include/bits/socket.h" 3 4 +extern struct cmsghdr *__cmsg_nxthdr (struct msghdr *__mhdr, + struct cmsghdr *__cmsg) throw (); +# 304 "/usr/include/bits/socket.h" 3 4 +enum + { + SCM_RIGHTS = 0x01 + + + , SCM_CREDENTIALS = 0x02 + + + }; + + + +struct ucred +{ + pid_t pid; + uid_t uid; + gid_t gid; +}; +# 350 "/usr/include/bits/socket.h" 3 4 +# 1 "/usr/include/asm/socket.h" 1 3 4 +# 1 "/usr/include/asm-generic/socket.h" 1 3 4 + + + +# 1 "/usr/include/asm/sockios.h" 1 3 4 +# 1 "/usr/include/asm-generic/sockios.h" 1 3 4 +# 1 "/usr/include/asm/sockios.h" 2 3 4 +# 5 "/usr/include/asm-generic/socket.h" 2 3 4 +# 1 "/usr/include/asm/socket.h" 2 3 4 +# 351 "/usr/include/bits/socket.h" 2 3 4 +# 384 "/usr/include/bits/socket.h" 3 4 +struct linger + { + int l_onoff; + int l_linger; + }; +# 40 "/usr/include/sys/socket.h" 2 3 4 + + + + +struct osockaddr + { + unsigned short int sa_family; + unsigned char sa_data[14]; + }; + + + + +enum +{ + SHUT_RD = 0, + + SHUT_WR, + + SHUT_RDWR + +}; +# 102 "/usr/include/sys/socket.h" 3 4 +struct mmsghdr + { + struct msghdr msg_hdr; + unsigned int msg_len; + + }; + + + + + + +extern int socket (int __domain, int __type, int __protocol) throw (); + + + + + +extern int socketpair (int __domain, int __type, int __protocol, + int __fds[2]) throw (); + + +extern int bind (int __fd, const struct sockaddr * __addr, socklen_t __len) + throw (); + + +extern int getsockname (int __fd, struct sockaddr *__restrict __addr, + socklen_t *__restrict __len) throw (); +# 138 "/usr/include/sys/socket.h" 3 4 +extern int connect (int __fd, const struct sockaddr * __addr, socklen_t __len); + + + +extern int getpeername (int __fd, struct sockaddr *__restrict __addr, + socklen_t *__restrict __len) throw (); + + + + + + +extern ssize_t send (int __fd, const void *__buf, size_t __n, int __flags); + + + + + + +extern ssize_t recv (int __fd, void *__buf, size_t __n, int __flags); + + + + + + +extern ssize_t sendto (int __fd, const void *__buf, size_t __n, + int __flags, const struct sockaddr * __addr, + socklen_t __addr_len); +# 175 "/usr/include/sys/socket.h" 3 4 +extern ssize_t recvfrom (int __fd, void *__restrict __buf, size_t __n, + int __flags, struct sockaddr *__restrict __addr, + socklen_t *__restrict __addr_len); + + + + + + + +extern ssize_t sendmsg (int __fd, const struct msghdr *__message, + int __flags); + + + + + + + +extern int sendmmsg (int __fd, struct mmsghdr *__vmessages, + unsigned int __vlen, int __flags); + + + + + + + +extern ssize_t recvmsg (int __fd, struct msghdr *__message, int __flags); + + + + + + + +extern int recvmmsg (int __fd, struct mmsghdr *__vmessages, + unsigned int __vlen, int __flags, + const struct timespec *__tmo); + + + + + + +extern int getsockopt (int __fd, int __level, int __optname, + void *__restrict __optval, + socklen_t *__restrict __optlen) throw (); + + + + +extern int setsockopt (int __fd, int __level, int __optname, + const void *__optval, socklen_t __optlen) throw (); + + + + + +extern int listen (int __fd, int __n) throw (); +# 244 "/usr/include/sys/socket.h" 3 4 +extern int accept (int __fd, struct sockaddr *__restrict __addr, + socklen_t *__restrict __addr_len); + + + + + + +extern int accept4 (int __fd, struct sockaddr *__restrict __addr, + socklen_t *__restrict __addr_len, int __flags); +# 262 "/usr/include/sys/socket.h" 3 4 +extern int shutdown (int __fd, int __how) throw (); + + + + +extern int sockatmark (int __fd) throw (); + + + + + + + +extern int isfdtype (int __fd, int __fdtype) throw (); +# 284 "/usr/include/sys/socket.h" 3 4 +} +# 25 "/usr/include/netinet/in.h" 2 3 4 + + + +extern "C" { + + +typedef uint32_t in_addr_t; +struct in_addr + { + in_addr_t s_addr; + }; + + +# 1 "/usr/include/bits/in.h" 1 3 4 +# 148 "/usr/include/bits/in.h" 3 4 +struct ip_opts + { + struct in_addr ip_dst; + char ip_opts[40]; + }; + + +struct ip_mreqn + { + struct in_addr imr_multiaddr; + struct in_addr imr_address; + int imr_ifindex; + }; + + +struct in_pktinfo + { + int ipi_ifindex; + struct in_addr ipi_spec_dst; + struct in_addr ipi_addr; + }; +# 39 "/usr/include/netinet/in.h" 2 3 4 + + +enum + { + IPPROTO_IP = 0, + + IPPROTO_ICMP = 1, + + IPPROTO_IGMP = 2, + + IPPROTO_IPIP = 4, + + IPPROTO_TCP = 6, + + IPPROTO_EGP = 8, + + IPPROTO_PUP = 12, + + IPPROTO_UDP = 17, + + IPPROTO_IDP = 22, + + IPPROTO_TP = 29, + + IPPROTO_DCCP = 33, + + IPPROTO_IPV6 = 41, + + IPPROTO_RSVP = 46, + + IPPROTO_GRE = 47, + + IPPROTO_ESP = 50, + + IPPROTO_AH = 51, + + IPPROTO_MTP = 92, + + IPPROTO_BEETPH = 94, + + IPPROTO_ENCAP = 98, + + IPPROTO_PIM = 103, + + IPPROTO_COMP = 108, + + IPPROTO_SCTP = 132, + + IPPROTO_UDPLITE = 136, + + IPPROTO_MPLS = 137, + + IPPROTO_RAW = 255, + + IPPROTO_MAX + }; + + + + + +enum + { + IPPROTO_HOPOPTS = 0, + + IPPROTO_ROUTING = 43, + + IPPROTO_FRAGMENT = 44, + + IPPROTO_ICMPV6 = 58, + + IPPROTO_NONE = 59, + + IPPROTO_DSTOPTS = 60, + + IPPROTO_MH = 135 + + }; + + + +typedef uint16_t in_port_t; + + +enum + { + IPPORT_ECHO = 7, + IPPORT_DISCARD = 9, + IPPORT_SYSTAT = 11, + IPPORT_DAYTIME = 13, + IPPORT_NETSTAT = 15, + IPPORT_FTP = 21, + IPPORT_TELNET = 23, + IPPORT_SMTP = 25, + IPPORT_TIMESERVER = 37, + IPPORT_NAMESERVER = 42, + IPPORT_WHOIS = 43, + IPPORT_MTP = 57, + + IPPORT_TFTP = 69, + IPPORT_RJE = 77, + IPPORT_FINGER = 79, + IPPORT_TTYLINK = 87, + IPPORT_SUPDUP = 95, + + + IPPORT_EXECSERVER = 512, + IPPORT_LOGINSERVER = 513, + IPPORT_CMDSERVER = 514, + IPPORT_EFSSERVER = 520, + + + IPPORT_BIFFUDP = 512, + IPPORT_WHOSERVER = 513, + IPPORT_ROUTESERVER = 520, + + + IPPORT_RESERVED = 1024, + + + IPPORT_USERRESERVED = 5000 + }; +# 212 "/usr/include/netinet/in.h" 3 4 +struct in6_addr + { + union + { + uint8_t __u6_addr8[16]; + + uint16_t __u6_addr16[8]; + uint32_t __u6_addr32[4]; + + } __in6_u; + + + + + + }; + + +extern const struct in6_addr in6addr_any; +extern const struct in6_addr in6addr_loopback; +# 240 "/usr/include/netinet/in.h" 3 4 +struct sockaddr_in + { + sa_family_t sin_family; + in_port_t sin_port; + struct in_addr sin_addr; + + + unsigned char sin_zero[sizeof (struct sockaddr) - + (sizeof (unsigned short int)) - + sizeof (in_port_t) - + sizeof (struct in_addr)]; + }; + + + +struct sockaddr_in6 + { + sa_family_t sin6_family; + in_port_t sin6_port; + uint32_t sin6_flowinfo; + struct in6_addr sin6_addr; + uint32_t sin6_scope_id; + }; + + + + +struct ip_mreq + { + + struct in_addr imr_multiaddr; + + + struct in_addr imr_interface; + }; + +struct ip_mreq_source + { + + struct in_addr imr_multiaddr; + + + struct in_addr imr_interface; + + + struct in_addr imr_sourceaddr; + }; + + + + +struct ipv6_mreq + { + + struct in6_addr ipv6mr_multiaddr; + + + unsigned int ipv6mr_interface; + }; + + + + +struct group_req + { + + uint32_t gr_interface; + + + struct sockaddr_storage gr_group; + }; + +struct group_source_req + { + + uint32_t gsr_interface; + + + struct sockaddr_storage gsr_group; + + + struct sockaddr_storage gsr_source; + }; + + + +struct ip_msfilter + { + + struct in_addr imsf_multiaddr; + + + struct in_addr imsf_interface; + + + uint32_t imsf_fmode; + + + uint32_t imsf_numsrc; + + struct in_addr imsf_slist[1]; + }; + + + + + +struct group_filter + { + + uint32_t gf_interface; + + + struct sockaddr_storage gf_group; + + + uint32_t gf_fmode; + + + uint32_t gf_numsrc; + + struct sockaddr_storage gf_slist[1]; +}; +# 377 "/usr/include/netinet/in.h" 3 4 +extern uint32_t ntohl (uint32_t __netlong) throw () __attribute__ ((__const__)); +extern uint16_t ntohs (uint16_t __netshort) + throw () __attribute__ ((__const__)); +extern uint32_t htonl (uint32_t __hostlong) + throw () __attribute__ ((__const__)); +extern uint16_t htons (uint16_t __hostshort) + throw () __attribute__ ((__const__)); + + + + +# 1 "/usr/include/bits/byteswap.h" 1 3 4 +# 389 "/usr/include/netinet/in.h" 2 3 4 +# 504 "/usr/include/netinet/in.h" 3 4 +extern int bindresvport (int __sockfd, struct sockaddr_in *__sock_in) throw (); + + +extern int bindresvport6 (int __sockfd, struct sockaddr_in6 *__sock_in) + throw (); +# 534 "/usr/include/netinet/in.h" 3 4 +struct cmsghdr; + + + +struct in6_pktinfo + { + struct in6_addr ipi6_addr; + unsigned int ipi6_ifindex; + }; + + +struct ip6_mtuinfo + { + struct sockaddr_in6 ip6m_addr; + uint32_t ip6m_mtu; + }; + + + +extern int inet6_option_space (int __nbytes) + throw () __attribute__ ((__deprecated__)); +extern int inet6_option_init (void *__bp, struct cmsghdr **__cmsgp, + int __type) throw () __attribute__ ((__deprecated__)); +extern int inet6_option_append (struct cmsghdr *__cmsg, + const uint8_t *__typep, int __multx, + int __plusy) throw () __attribute__ ((__deprecated__)); +extern uint8_t *inet6_option_alloc (struct cmsghdr *__cmsg, int __datalen, + int __multx, int __plusy) + throw () __attribute__ ((__deprecated__)); +extern int inet6_option_next (const struct cmsghdr *__cmsg, + uint8_t **__tptrp) + throw () __attribute__ ((__deprecated__)); +extern int inet6_option_find (const struct cmsghdr *__cmsg, + uint8_t **__tptrp, int __type) + throw () __attribute__ ((__deprecated__)); + + + +extern int inet6_opt_init (void *__extbuf, socklen_t __extlen) throw (); +extern int inet6_opt_append (void *__extbuf, socklen_t __extlen, int __offset, + uint8_t __type, socklen_t __len, uint8_t __align, + void **__databufp) throw (); +extern int inet6_opt_finish (void *__extbuf, socklen_t __extlen, int __offset) + throw (); +extern int inet6_opt_set_val (void *__databuf, int __offset, void *__val, + socklen_t __vallen) throw (); +extern int inet6_opt_next (void *__extbuf, socklen_t __extlen, int __offset, + uint8_t *__typep, socklen_t *__lenp, + void **__databufp) throw (); +extern int inet6_opt_find (void *__extbuf, socklen_t __extlen, int __offset, + uint8_t __type, socklen_t *__lenp, + void **__databufp) throw (); +extern int inet6_opt_get_val (void *__databuf, int __offset, void *__val, + socklen_t __vallen) throw (); + + + +extern socklen_t inet6_rth_space (int __type, int __segments) throw (); +extern void *inet6_rth_init (void *__bp, socklen_t __bp_len, int __type, + int __segments) throw (); +extern int inet6_rth_add (void *__bp, const struct in6_addr *__addr) throw (); +extern int inet6_rth_reverse (const void *__in, void *__out) throw (); +extern int inet6_rth_segments (const void *__bp) throw (); +extern struct in6_addr *inet6_rth_getaddr (const void *__bp, int __index) + throw (); + + + + + +extern int getipv4sourcefilter (int __s, struct in_addr __interface_addr, + struct in_addr __group, uint32_t *__fmode, + uint32_t *__numsrc, struct in_addr *__slist) + throw (); + + +extern int setipv4sourcefilter (int __s, struct in_addr __interface_addr, + struct in_addr __group, uint32_t __fmode, + uint32_t __numsrc, + const struct in_addr *__slist) + throw (); + + + +extern int getsourcefilter (int __s, uint32_t __interface_addr, + const struct sockaddr *__group, + socklen_t __grouplen, uint32_t *__fmode, + uint32_t *__numsrc, + struct sockaddr_storage *__slist) throw (); + + +extern int setsourcefilter (int __s, uint32_t __interface_addr, + const struct sockaddr *__group, + socklen_t __grouplen, uint32_t __fmode, + uint32_t __numsrc, + const struct sockaddr_storage *__slist) throw (); + + +} +# 23 "/usr/include/arpa/inet.h" 2 3 4 + + + + + + + +extern "C" { + + + +extern in_addr_t inet_addr (const char *__cp) throw (); + + +extern in_addr_t inet_lnaof (struct in_addr __in) throw (); + + + +extern struct in_addr inet_makeaddr (in_addr_t __net, in_addr_t __host) + throw (); + + +extern in_addr_t inet_netof (struct in_addr __in) throw (); + + + +extern in_addr_t inet_network (const char *__cp) throw (); + + + +extern char *inet_ntoa (struct in_addr __in) throw (); + + + + +extern int inet_pton (int __af, const char *__restrict __cp, + void *__restrict __buf) throw (); + + + + +extern const char *inet_ntop (int __af, const void *__restrict __cp, + char *__restrict __buf, socklen_t __len) + throw (); + + + + + + +extern int inet_aton (const char *__cp, struct in_addr *__inp) throw (); + + + +extern char *inet_neta (in_addr_t __net, char *__buf, size_t __len) throw (); + + + + +extern char *inet_net_ntop (int __af, const void *__cp, int __bits, + char *__buf, size_t __len) throw (); + + + + +extern int inet_net_pton (int __af, const char *__cp, + void *__buf, size_t __len) throw (); + + + + +extern unsigned int inet_nsap_addr (const char *__cp, + unsigned char *__buf, int __len) throw (); + + + +extern char *inet_nsap_ntoa (int __len, const unsigned char *__cp, + char *__buf) throw (); + + +} +# 18 "include/CTypedef.h" 2 +# 1 "include/CLog.h" 1 +# 10 "include/CLog.h" +# 1 "/usr/include/syslog.h" 1 3 4 +# 1 "/usr/include/sys/syslog.h" 1 3 4 +# 37 "/usr/include/sys/syslog.h" 3 4 +# 1 "/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stdarg.h" 1 3 4 +# 38 "/usr/include/sys/syslog.h" 2 3 4 + + +# 1 "/usr/include/bits/syslog-path.h" 1 3 4 +# 41 "/usr/include/sys/syslog.h" 2 3 4 +# 169 "/usr/include/sys/syslog.h" 3 4 +extern "C" { + + + + + +extern void closelog (void); + + + + + +extern void openlog (const char *__ident, int __option, int __facility); + + +extern int setlogmask (int __mask) throw (); + + + + + +extern void syslog (int __pri, const char *__fmt, ...) + __attribute__ ((__format__ (__printf__, 2, 3))); +# 200 "/usr/include/sys/syslog.h" 3 4 +extern void vsyslog (int __pri, const char *__fmt, __gnuc_va_list __ap) + __attribute__ ((__format__ (__printf__, 2, 0))); +# 213 "/usr/include/sys/syslog.h" 3 4 +} +# 1 "/usr/include/syslog.h" 2 3 4 +# 11 "include/CLog.h" 2 +# 1 "/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stdarg.h" 1 3 4 +# 98 "/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stdarg.h" 3 4 +typedef __gnuc_va_list va_list; +# 12 "include/CLog.h" 2 +# 1 "/usr/include/stdio.h" 1 3 4 +# 29 "/usr/include/stdio.h" 3 4 +extern "C" { + + + +# 1 "/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stddef.h" 1 3 4 +# 34 "/usr/include/stdio.h" 2 3 4 +# 74 "/usr/include/stdio.h" 3 4 +# 1 "/usr/include/libio.h" 1 3 4 +# 32 "/usr/include/libio.h" 3 4 +# 1 "/usr/include/_G_config.h" 1 3 4 +# 15 "/usr/include/_G_config.h" 3 4 +# 1 "/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stddef.h" 1 3 4 +# 16 "/usr/include/_G_config.h" 2 3 4 + + + + +# 1 "/usr/include/wchar.h" 1 3 4 +# 21 "/usr/include/_G_config.h" 2 3 4 +typedef struct +{ + __off_t __pos; + __mbstate_t __state; +} _G_fpos_t; +typedef struct +{ + __off64_t __pos; + __mbstate_t __state; +} _G_fpos64_t; +# 33 "/usr/include/libio.h" 2 3 4 +# 145 "/usr/include/libio.h" 3 4 +struct _IO_jump_t; struct _IO_FILE; +# 155 "/usr/include/libio.h" 3 4 +typedef void _IO_lock_t; + + + + + +struct _IO_marker { + struct _IO_marker *_next; + struct _IO_FILE *_sbuf; + + + + int _pos; +# 178 "/usr/include/libio.h" 3 4 +}; + + +enum __codecvt_result +{ + __codecvt_ok, + __codecvt_partial, + __codecvt_error, + __codecvt_noconv +}; +# 246 "/usr/include/libio.h" 3 4 +struct _IO_FILE { + int _flags; + + + + + char* _IO_read_ptr; + char* _IO_read_end; + char* _IO_read_base; + char* _IO_write_base; + char* _IO_write_ptr; + char* _IO_write_end; + char* _IO_buf_base; + char* _IO_buf_end; + + char *_IO_save_base; + char *_IO_backup_base; + char *_IO_save_end; + + struct _IO_marker *_markers; + + struct _IO_FILE *_chain; + + int _fileno; + + + + int _flags2; + + __off_t _old_offset; + + + + unsigned short _cur_column; + signed char _vtable_offset; + char _shortbuf[1]; + + + + _IO_lock_t *_lock; +# 294 "/usr/include/libio.h" 3 4 + __off64_t _offset; +# 303 "/usr/include/libio.h" 3 4 + void *__pad1; + void *__pad2; + void *__pad3; + void *__pad4; + size_t __pad5; + + int _mode; + + char _unused2[15 * sizeof (int) - 4 * sizeof (void *) - sizeof (size_t)]; + +}; + + + + + +struct _IO_FILE_plus; + +extern struct _IO_FILE_plus _IO_2_1_stdin_; +extern struct _IO_FILE_plus _IO_2_1_stdout_; +extern struct _IO_FILE_plus _IO_2_1_stderr_; +# 339 "/usr/include/libio.h" 3 4 +typedef __ssize_t __io_read_fn (void *__cookie, char *__buf, size_t __nbytes); + + + + + + + +typedef __ssize_t __io_write_fn (void *__cookie, const char *__buf, + size_t __n); + + + + + + + +typedef int __io_seek_fn (void *__cookie, __off64_t *__pos, int __w); + + +typedef int __io_close_fn (void *__cookie); + + + + +typedef __io_read_fn cookie_read_function_t; +typedef __io_write_fn cookie_write_function_t; +typedef __io_seek_fn cookie_seek_function_t; +typedef __io_close_fn cookie_close_function_t; + + +typedef struct +{ + __io_read_fn *read; + __io_write_fn *write; + __io_seek_fn *seek; + __io_close_fn *close; +} _IO_cookie_io_functions_t; +typedef _IO_cookie_io_functions_t cookie_io_functions_t; + +struct _IO_cookie_file; + + +extern void _IO_cookie_init (struct _IO_cookie_file *__cfile, int __read_write, + void *__cookie, _IO_cookie_io_functions_t __fns); + + + + +extern "C" { + + +extern int __underflow (_IO_FILE *); +extern int __uflow (_IO_FILE *); +extern int __overflow (_IO_FILE *, int); +# 435 "/usr/include/libio.h" 3 4 +extern int _IO_getc (_IO_FILE *__fp); +extern int _IO_putc (int __c, _IO_FILE *__fp); +extern int _IO_feof (_IO_FILE *__fp) throw (); +extern int _IO_ferror (_IO_FILE *__fp) throw (); + +extern int _IO_peekc_locked (_IO_FILE *__fp); + + + + + +extern void _IO_flockfile (_IO_FILE *) throw (); +extern void _IO_funlockfile (_IO_FILE *) throw (); +extern int _IO_ftrylockfile (_IO_FILE *) throw (); +# 465 "/usr/include/libio.h" 3 4 +extern int _IO_vfscanf (_IO_FILE * __restrict, const char * __restrict, + __gnuc_va_list, int *__restrict); +extern int _IO_vfprintf (_IO_FILE *__restrict, const char *__restrict, + __gnuc_va_list); +extern __ssize_t _IO_padn (_IO_FILE *, int, __ssize_t); +extern size_t _IO_sgetn (_IO_FILE *, void *, size_t); + +extern __off64_t _IO_seekoff (_IO_FILE *, __off64_t, int, int); +extern __off64_t _IO_seekpos (_IO_FILE *, __off64_t, int); + +extern void _IO_free_backup_area (_IO_FILE *) throw (); +# 527 "/usr/include/libio.h" 3 4 +} +# 75 "/usr/include/stdio.h" 2 3 4 +# 108 "/usr/include/stdio.h" 3 4 + + +typedef _G_fpos_t fpos_t; + + + + + +typedef _G_fpos64_t fpos64_t; +# 164 "/usr/include/stdio.h" 3 4 +# 1 "/usr/include/bits/stdio_lim.h" 1 3 4 +# 165 "/usr/include/stdio.h" 2 3 4 + + + +extern struct _IO_FILE *stdin; +extern struct _IO_FILE *stdout; +extern struct _IO_FILE *stderr; + + + + + + + +extern int remove (const char *__filename) throw (); + +extern int rename (const char *__old, const char *__new) throw (); + + + + +extern int renameat (int __oldfd, const char *__old, int __newfd, + const char *__new) throw (); + + + + + + + + +extern FILE *tmpfile (void) ; +# 205 "/usr/include/stdio.h" 3 4 +extern FILE *tmpfile64 (void) ; + + + +extern char *tmpnam (char *__s) throw () ; + + + + + +extern char *tmpnam_r (char *__s) throw () ; +# 227 "/usr/include/stdio.h" 3 4 +extern char *tempnam (const char *__dir, const char *__pfx) + throw () __attribute__ ((__malloc__)) ; + + + + + + + + +extern int fclose (FILE *__stream); + + + + +extern int fflush (FILE *__stream); + +# 252 "/usr/include/stdio.h" 3 4 +extern int fflush_unlocked (FILE *__stream); +# 262 "/usr/include/stdio.h" 3 4 +extern int fcloseall (void); + + + + + + + + + +extern FILE *fopen (const char *__restrict __filename, + const char *__restrict __modes) ; + + + + +extern FILE *freopen (const char *__restrict __filename, + const char *__restrict __modes, + FILE *__restrict __stream) ; +# 295 "/usr/include/stdio.h" 3 4 + + +extern FILE *fopen64 (const char *__restrict __filename, + const char *__restrict __modes) ; +extern FILE *freopen64 (const char *__restrict __filename, + const char *__restrict __modes, + FILE *__restrict __stream) ; + + + + +extern FILE *fdopen (int __fd, const char *__modes) throw () ; + + + + + +extern FILE *fopencookie (void *__restrict __magic_cookie, + const char *__restrict __modes, + _IO_cookie_io_functions_t __io_funcs) throw () ; + + + + +extern FILE *fmemopen (void *__s, size_t __len, const char *__modes) + throw () ; + + + + +extern FILE *open_memstream (char **__bufloc, size_t *__sizeloc) throw () ; + + + + + + +extern void setbuf (FILE *__restrict __stream, char *__restrict __buf) throw (); + + + +extern int setvbuf (FILE *__restrict __stream, char *__restrict __buf, + int __modes, size_t __n) throw (); + + + + + +extern void setbuffer (FILE *__restrict __stream, char *__restrict __buf, + size_t __size) throw (); + + +extern void setlinebuf (FILE *__stream) throw (); + + + + + + + + +extern int fprintf (FILE *__restrict __stream, + const char *__restrict __format, ...); + + + + +extern int printf (const char *__restrict __format, ...); + +extern int sprintf (char *__restrict __s, + const char *__restrict __format, ...) throw (); + + + + + +extern int vfprintf (FILE *__restrict __s, const char *__restrict __format, + __gnuc_va_list __arg); + + + + +extern int vprintf (const char *__restrict __format, __gnuc_va_list __arg); + +extern int vsprintf (char *__restrict __s, const char *__restrict __format, + __gnuc_va_list __arg) throw (); + + + + + +extern int snprintf (char *__restrict __s, size_t __maxlen, + const char *__restrict __format, ...) + throw () __attribute__ ((__format__ (__printf__, 3, 4))); + +extern int vsnprintf (char *__restrict __s, size_t __maxlen, + const char *__restrict __format, __gnuc_va_list __arg) + throw () __attribute__ ((__format__ (__printf__, 3, 0))); + + + + + + +extern int vasprintf (char **__restrict __ptr, const char *__restrict __f, + __gnuc_va_list __arg) + throw () __attribute__ ((__format__ (__printf__, 2, 0))) ; +extern int __asprintf (char **__restrict __ptr, + const char *__restrict __fmt, ...) + throw () __attribute__ ((__format__ (__printf__, 2, 3))) ; +extern int asprintf (char **__restrict __ptr, + const char *__restrict __fmt, ...) + throw () __attribute__ ((__format__ (__printf__, 2, 3))) ; + + + + +extern int vdprintf (int __fd, const char *__restrict __fmt, + __gnuc_va_list __arg) + __attribute__ ((__format__ (__printf__, 2, 0))); +extern int dprintf (int __fd, const char *__restrict __fmt, ...) + __attribute__ ((__format__ (__printf__, 2, 3))); + + + + + + + + +extern int fscanf (FILE *__restrict __stream, + const char *__restrict __format, ...) ; + + + + +extern int scanf (const char *__restrict __format, ...) ; + +extern int sscanf (const char *__restrict __s, + const char *__restrict __format, ...) throw (); +# 463 "/usr/include/stdio.h" 3 4 + + + + + + + + +extern int vfscanf (FILE *__restrict __s, const char *__restrict __format, + __gnuc_va_list __arg) + __attribute__ ((__format__ (__scanf__, 2, 0))) ; + + + + + +extern int vscanf (const char *__restrict __format, __gnuc_va_list __arg) + __attribute__ ((__format__ (__scanf__, 1, 0))) ; + + +extern int vsscanf (const char *__restrict __s, + const char *__restrict __format, __gnuc_va_list __arg) + throw () __attribute__ ((__format__ (__scanf__, 2, 0))); +# 522 "/usr/include/stdio.h" 3 4 + + + + + + + + + +extern int fgetc (FILE *__stream); +extern int getc (FILE *__stream); + + + + + +extern int getchar (void); + +# 550 "/usr/include/stdio.h" 3 4 +extern int getc_unlocked (FILE *__stream); +extern int getchar_unlocked (void); +# 561 "/usr/include/stdio.h" 3 4 +extern int fgetc_unlocked (FILE *__stream); + + + + + + + + + + + +extern int fputc (int __c, FILE *__stream); +extern int putc (int __c, FILE *__stream); + + + + + +extern int putchar (int __c); + +# 594 "/usr/include/stdio.h" 3 4 +extern int fputc_unlocked (int __c, FILE *__stream); + + + + + + + +extern int putc_unlocked (int __c, FILE *__stream); +extern int putchar_unlocked (int __c); + + + + + + +extern int getw (FILE *__stream); + + +extern int putw (int __w, FILE *__stream); + + + + + + + + +extern char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream) + ; +# 638 "/usr/include/stdio.h" 3 4 +extern char *gets (char *__s) __attribute__ ((__deprecated__)); + + +# 649 "/usr/include/stdio.h" 3 4 +extern char *fgets_unlocked (char *__restrict __s, int __n, + FILE *__restrict __stream) ; +# 665 "/usr/include/stdio.h" 3 4 +extern __ssize_t __getdelim (char **__restrict __lineptr, + size_t *__restrict __n, int __delimiter, + FILE *__restrict __stream) ; +extern __ssize_t getdelim (char **__restrict __lineptr, + size_t *__restrict __n, int __delimiter, + FILE *__restrict __stream) ; + + + + + + + +extern __ssize_t getline (char **__restrict __lineptr, + size_t *__restrict __n, + FILE *__restrict __stream) ; + + + + + + + + +extern int fputs (const char *__restrict __s, FILE *__restrict __stream); + + + + + +extern int puts (const char *__s); + + + + + + +extern int ungetc (int __c, FILE *__stream); + + + + + + +extern size_t fread (void *__restrict __ptr, size_t __size, + size_t __n, FILE *__restrict __stream) ; + + + + +extern size_t fwrite (const void *__restrict __ptr, size_t __size, + size_t __n, FILE *__restrict __s); + +# 726 "/usr/include/stdio.h" 3 4 +extern int fputs_unlocked (const char *__restrict __s, + FILE *__restrict __stream); +# 737 "/usr/include/stdio.h" 3 4 +extern size_t fread_unlocked (void *__restrict __ptr, size_t __size, + size_t __n, FILE *__restrict __stream) ; +extern size_t fwrite_unlocked (const void *__restrict __ptr, size_t __size, + size_t __n, FILE *__restrict __stream); + + + + + + + + +extern int fseek (FILE *__stream, long int __off, int __whence); + + + + +extern long int ftell (FILE *__stream) ; + + + + +extern void rewind (FILE *__stream); + +# 773 "/usr/include/stdio.h" 3 4 +extern int fseeko (FILE *__stream, __off_t __off, int __whence); + + + + +extern __off_t ftello (FILE *__stream) ; +# 792 "/usr/include/stdio.h" 3 4 + + + + + + +extern int fgetpos (FILE *__restrict __stream, fpos_t *__restrict __pos); + + + + +extern int fsetpos (FILE *__stream, const fpos_t *__pos); +# 815 "/usr/include/stdio.h" 3 4 + + + +extern int fseeko64 (FILE *__stream, __off64_t __off, int __whence); +extern __off64_t ftello64 (FILE *__stream) ; +extern int fgetpos64 (FILE *__restrict __stream, fpos64_t *__restrict __pos); +extern int fsetpos64 (FILE *__stream, const fpos64_t *__pos); + + + + +extern void clearerr (FILE *__stream) throw (); + +extern int feof (FILE *__stream) throw () ; + +extern int ferror (FILE *__stream) throw () ; + + + + +extern void clearerr_unlocked (FILE *__stream) throw (); +extern int feof_unlocked (FILE *__stream) throw () ; +extern int ferror_unlocked (FILE *__stream) throw () ; + + + + + + + + +extern void perror (const char *__s); + + + + + + +# 1 "/usr/include/bits/sys_errlist.h" 1 3 4 +# 26 "/usr/include/bits/sys_errlist.h" 3 4 +extern int sys_nerr; +extern const char *const sys_errlist[]; + + +extern int _sys_nerr; +extern const char *const _sys_errlist[]; +# 854 "/usr/include/stdio.h" 2 3 4 + + + + +extern int fileno (FILE *__stream) throw () ; + + + + +extern int fileno_unlocked (FILE *__stream) throw () ; +# 873 "/usr/include/stdio.h" 3 4 +extern FILE *popen (const char *__command, const char *__modes) ; + + + + + +extern int pclose (FILE *__stream); + + + + + +extern char *ctermid (char *__s) throw (); + + + + + +extern char *cuserid (char *__s); + + + + +struct obstack; + + +extern int obstack_printf (struct obstack *__restrict __obstack, + const char *__restrict __format, ...) + throw () __attribute__ ((__format__ (__printf__, 2, 3))); +extern int obstack_vprintf (struct obstack *__restrict __obstack, + const char *__restrict __format, + __gnuc_va_list __args) + throw () __attribute__ ((__format__ (__printf__, 2, 0))); + + + + + + + +extern void flockfile (FILE *__stream) throw (); + + + +extern int ftrylockfile (FILE *__stream) throw () ; + + +extern void funlockfile (FILE *__stream) throw (); +# 943 "/usr/include/stdio.h" 3 4 +} +# 13 "include/CLog.h" 2 +# 1 "/usr/include/signal.h" 1 3 4 +# 30 "/usr/include/signal.h" 3 4 +extern "C" { + +# 1 "/usr/include/bits/sigset.h" 1 3 4 +# 103 "/usr/include/bits/sigset.h" 3 4 +extern int __sigismember (const __sigset_t *, int); +extern int __sigaddset (__sigset_t *, int); +extern int __sigdelset (__sigset_t *, int); +# 33 "/usr/include/signal.h" 2 3 4 + + + + + + + +typedef __sig_atomic_t sig_atomic_t; + +# 57 "/usr/include/signal.h" 3 4 +# 1 "/usr/include/bits/signum.h" 1 3 4 +# 58 "/usr/include/signal.h" 2 3 4 +# 80 "/usr/include/signal.h" 3 4 +# 1 "/usr/include/bits/siginfo.h" 1 3 4 +# 24 "/usr/include/bits/siginfo.h" 3 4 +# 1 "/usr/include/bits/wordsize.h" 1 3 4 +# 25 "/usr/include/bits/siginfo.h" 2 3 4 + + + + + + + +typedef union sigval + { + int sival_int; + void *sival_ptr; + } sigval_t; +# 58 "/usr/include/bits/siginfo.h" 3 4 +typedef __clock_t __sigchld_clock_t; + + + +typedef struct + { + int si_signo; + int si_errno; + + int si_code; + + union + { + int _pad[((128 / sizeof (int)) - 4)]; + + + struct + { + __pid_t si_pid; + __uid_t si_uid; + } _kill; + + + struct + { + int si_tid; + int si_overrun; + sigval_t si_sigval; + } _timer; + + + struct + { + __pid_t si_pid; + __uid_t si_uid; + sigval_t si_sigval; + } _rt; + + + struct + { + __pid_t si_pid; + __uid_t si_uid; + int si_status; + __sigchld_clock_t si_utime; + __sigchld_clock_t si_stime; + } _sigchld; + + + struct + { + void *si_addr; + } _sigfault; + + + struct + { + long int si_band; + int si_fd; + } _sigpoll; + + + struct + { + void *_call_addr; + int _syscall; + unsigned int _arch; + } _sigsys; + } _sifields; + } siginfo_t ; +# 151 "/usr/include/bits/siginfo.h" 3 4 +enum +{ + SI_ASYNCNL = -60, + + SI_TKILL = -6, + + SI_SIGIO, + + SI_ASYNCIO, + + SI_MESGQ, + + SI_TIMER, + + SI_QUEUE, + + SI_USER, + + SI_KERNEL = 0x80 + +}; + + + +enum +{ + ILL_ILLOPC = 1, + + ILL_ILLOPN, + + ILL_ILLADR, + + ILL_ILLTRP, + + ILL_PRVOPC, + + ILL_PRVREG, + + ILL_COPROC, + + ILL_BADSTK + +}; + + +enum +{ + FPE_INTDIV = 1, + + FPE_INTOVF, + + FPE_FLTDIV, + + FPE_FLTOVF, + + FPE_FLTUND, + + FPE_FLTRES, + + FPE_FLTINV, + + FPE_FLTSUB + +}; + + +enum +{ + SEGV_MAPERR = 1, + + SEGV_ACCERR + +}; + + +enum +{ + BUS_ADRALN = 1, + + BUS_ADRERR, + + BUS_OBJERR + +}; + + +enum +{ + TRAP_BRKPT = 1, + + TRAP_TRACE + +}; + + +enum +{ + CLD_EXITED = 1, + + CLD_KILLED, + + CLD_DUMPED, + + CLD_TRAPPED, + + CLD_STOPPED, + + CLD_CONTINUED + +}; + + +enum +{ + POLL_IN = 1, + + POLL_OUT, + + POLL_MSG, + + POLL_ERR, + + POLL_PRI, + + POLL_HUP + +}; +# 301 "/usr/include/bits/siginfo.h" 3 4 +typedef struct sigevent + { + sigval_t sigev_value; + int sigev_signo; + int sigev_notify; + + union + { + int _pad[((64 / sizeof (int)) - 4)]; + + + + __pid_t _tid; + + struct + { + void (*_function) (sigval_t); + pthread_attr_t *_attribute; + } _sigev_thread; + } _sigev_un; + } sigevent_t; + + + + + + +enum +{ + SIGEV_SIGNAL = 0, + + SIGEV_NONE, + + SIGEV_THREAD, + + + SIGEV_THREAD_ID = 4 + +}; +# 81 "/usr/include/signal.h" 2 3 4 + + + + +typedef void (*__sighandler_t) (int); + + + + +extern __sighandler_t __sysv_signal (int __sig, __sighandler_t __handler) + throw (); + +extern __sighandler_t sysv_signal (int __sig, __sighandler_t __handler) + throw (); + + + + + + + +extern __sighandler_t signal (int __sig, __sighandler_t __handler) + throw (); +# 114 "/usr/include/signal.h" 3 4 + + + + + +extern __sighandler_t bsd_signal (int __sig, __sighandler_t __handler) + throw (); + + + + + + +extern int kill (__pid_t __pid, int __sig) throw (); + + + + + + +extern int killpg (__pid_t __pgrp, int __sig) throw (); + + + + +extern int raise (int __sig) throw (); + + + + +extern __sighandler_t ssignal (int __sig, __sighandler_t __handler) + throw (); +extern int gsignal (int __sig) throw (); + + + + +extern void psignal (int __sig, const char *__s); + + + + +extern void psiginfo (const siginfo_t *__pinfo, const char *__s); +# 169 "/usr/include/signal.h" 3 4 +extern int __sigpause (int __sig_or_mask, int __is_sig); +# 178 "/usr/include/signal.h" 3 4 +extern int sigpause (int __sig) __asm__ ("__xpg_sigpause"); +# 197 "/usr/include/signal.h" 3 4 +extern int sigblock (int __mask) throw () __attribute__ ((__deprecated__)); + + +extern int sigsetmask (int __mask) throw () __attribute__ ((__deprecated__)); + + +extern int siggetmask (void) throw () __attribute__ ((__deprecated__)); +# 212 "/usr/include/signal.h" 3 4 +typedef __sighandler_t sighandler_t; + + + + +typedef __sighandler_t sig_t; + + + + + +extern int sigemptyset (sigset_t *__set) throw () __attribute__ ((__nonnull__ (1))); + + +extern int sigfillset (sigset_t *__set) throw () __attribute__ ((__nonnull__ (1))); + + +extern int sigaddset (sigset_t *__set, int __signo) throw () __attribute__ ((__nonnull__ (1))); + + +extern int sigdelset (sigset_t *__set, int __signo) throw () __attribute__ ((__nonnull__ (1))); + + +extern int sigismember (const sigset_t *__set, int __signo) + throw () __attribute__ ((__nonnull__ (1))); + + + +extern int sigisemptyset (const sigset_t *__set) throw () __attribute__ ((__nonnull__ (1))); + + +extern int sigandset (sigset_t *__set, const sigset_t *__left, + const sigset_t *__right) throw () __attribute__ ((__nonnull__ (1, 2, 3))); + + +extern int sigorset (sigset_t *__set, const sigset_t *__left, + const sigset_t *__right) throw () __attribute__ ((__nonnull__ (1, 2, 3))); + + + + +# 1 "/usr/include/bits/sigaction.h" 1 3 4 +# 24 "/usr/include/bits/sigaction.h" 3 4 +struct sigaction + { + + + union + { + + __sighandler_t sa_handler; + + void (*sa_sigaction) (int, siginfo_t *, void *); + } + __sigaction_handler; + + + + + + + + __sigset_t sa_mask; + + + int sa_flags; + + + void (*sa_restorer) (void); + }; +# 254 "/usr/include/signal.h" 2 3 4 + + +extern int sigprocmask (int __how, const sigset_t *__restrict __set, + sigset_t *__restrict __oset) throw (); + + + + + + +extern int sigsuspend (const sigset_t *__set) __attribute__ ((__nonnull__ (1))); + + +extern int sigaction (int __sig, const struct sigaction *__restrict __act, + struct sigaction *__restrict __oact) throw (); + + +extern int sigpending (sigset_t *__set) throw () __attribute__ ((__nonnull__ (1))); + + + + + + +extern int sigwait (const sigset_t *__restrict __set, int *__restrict __sig) + __attribute__ ((__nonnull__ (1, 2))); + + + + + + +extern int sigwaitinfo (const sigset_t *__restrict __set, + siginfo_t *__restrict __info) __attribute__ ((__nonnull__ (1))); + + + + + + +extern int sigtimedwait (const sigset_t *__restrict __set, + siginfo_t *__restrict __info, + const struct timespec *__restrict __timeout) + __attribute__ ((__nonnull__ (1))); + + + +extern int sigqueue (__pid_t __pid, int __sig, const union sigval __val) + throw (); +# 311 "/usr/include/signal.h" 3 4 +extern const char *const _sys_siglist[65]; +extern const char *const sys_siglist[65]; + + +struct sigvec + { + __sighandler_t sv_handler; + int sv_mask; + + int sv_flags; + + }; +# 335 "/usr/include/signal.h" 3 4 +extern int sigvec (int __sig, const struct sigvec *__vec, + struct sigvec *__ovec) throw (); + + + +# 1 "/usr/include/bits/sigcontext.h" 1 3 4 +# 29 "/usr/include/bits/sigcontext.h" 3 4 +struct _fpx_sw_bytes +{ + __uint32_t magic1; + __uint32_t extended_size; + __uint64_t xstate_bv; + __uint32_t xstate_size; + __uint32_t padding[7]; +}; + +struct _fpreg +{ + unsigned short significand[4]; + unsigned short exponent; +}; + +struct _fpxreg +{ + unsigned short significand[4]; + unsigned short exponent; + unsigned short padding[3]; +}; + +struct _xmmreg +{ + __uint32_t element[4]; +}; +# 121 "/usr/include/bits/sigcontext.h" 3 4 +struct _fpstate +{ + + __uint16_t cwd; + __uint16_t swd; + __uint16_t ftw; + __uint16_t fop; + __uint64_t rip; + __uint64_t rdp; + __uint32_t mxcsr; + __uint32_t mxcr_mask; + struct _fpxreg _st[8]; + struct _xmmreg _xmm[16]; + __uint32_t padding[24]; +}; + +struct sigcontext +{ + __uint64_t r8; + __uint64_t r9; + __uint64_t r10; + __uint64_t r11; + __uint64_t r12; + __uint64_t r13; + __uint64_t r14; + __uint64_t r15; + __uint64_t rdi; + __uint64_t rsi; + __uint64_t rbp; + __uint64_t rbx; + __uint64_t rdx; + __uint64_t rax; + __uint64_t rcx; + __uint64_t rsp; + __uint64_t rip; + __uint64_t eflags; + unsigned short cs; + unsigned short gs; + unsigned short fs; + unsigned short __pad0; + __uint64_t err; + __uint64_t trapno; + __uint64_t oldmask; + __uint64_t cr2; + __extension__ union + { + struct _fpstate * fpstate; + __uint64_t __fpstate_word; + }; + __uint64_t __reserved1 [8]; +}; + + + +struct _xsave_hdr +{ + __uint64_t xstate_bv; + __uint64_t reserved1[2]; + __uint64_t reserved2[5]; +}; + +struct _ymmh_state +{ + __uint32_t ymmh_space[64]; +}; + +struct _xstate +{ + struct _fpstate fpstate; + struct _xsave_hdr xstate_hdr; + struct _ymmh_state ymmh; +}; +# 341 "/usr/include/signal.h" 2 3 4 + + +extern int sigreturn (struct sigcontext *__scp) throw (); + + + + + + +# 1 "/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stddef.h" 1 3 4 +# 351 "/usr/include/signal.h" 2 3 4 + + + + +extern int siginterrupt (int __sig, int __interrupt) throw (); + +# 1 "/usr/include/bits/sigstack.h" 1 3 4 +# 25 "/usr/include/bits/sigstack.h" 3 4 +struct sigstack + { + void *ss_sp; + int ss_onstack; + }; + + + +enum +{ + SS_ONSTACK = 1, + + SS_DISABLE + +}; +# 49 "/usr/include/bits/sigstack.h" 3 4 +typedef struct sigaltstack + { + void *ss_sp; + int ss_flags; + size_t ss_size; + } stack_t; +# 358 "/usr/include/signal.h" 2 3 4 + + +# 1 "/usr/include/sys/ucontext.h" 1 3 4 +# 22 "/usr/include/sys/ucontext.h" 3 4 +# 1 "/usr/include/signal.h" 1 3 4 +# 23 "/usr/include/sys/ucontext.h" 2 3 4 +# 31 "/usr/include/sys/ucontext.h" 3 4 +__extension__ typedef long long int greg_t; + + + + + +typedef greg_t gregset_t[23]; + + + +enum +{ + REG_R8 = 0, + + REG_R9, + + REG_R10, + + REG_R11, + + REG_R12, + + REG_R13, + + REG_R14, + + REG_R15, + + REG_RDI, + + REG_RSI, + + REG_RBP, + + REG_RBX, + + REG_RDX, + + REG_RAX, + + REG_RCX, + + REG_RSP, + + REG_RIP, + + REG_EFL, + + REG_CSGSFS, + + REG_ERR, + + REG_TRAPNO, + + REG_OLDMASK, + + REG_CR2 + +}; + + +struct _libc_fpxreg +{ + unsigned short int significand[4]; + unsigned short int exponent; + unsigned short int padding[3]; +}; + +struct _libc_xmmreg +{ + __uint32_t element[4]; +}; + +struct _libc_fpstate +{ + + __uint16_t cwd; + __uint16_t swd; + __uint16_t ftw; + __uint16_t fop; + __uint64_t rip; + __uint64_t rdp; + __uint32_t mxcsr; + __uint32_t mxcr_mask; + struct _libc_fpxreg _st[8]; + struct _libc_xmmreg _xmm[16]; + __uint32_t padding[24]; +}; + + +typedef struct _libc_fpstate *fpregset_t; + + +typedef struct + { + gregset_t gregs; + + fpregset_t fpregs; + __extension__ unsigned long long __reserved1 [8]; +} mcontext_t; + + +typedef struct ucontext + { + unsigned long int uc_flags; + struct ucontext *uc_link; + stack_t uc_stack; + mcontext_t uc_mcontext; + __sigset_t uc_sigmask; + struct _libc_fpstate __fpregs_mem; + } ucontext_t; +# 361 "/usr/include/signal.h" 2 3 4 + + + + + +extern int sigstack (struct sigstack *__ss, struct sigstack *__oss) + throw () __attribute__ ((__deprecated__)); + + + +extern int sigaltstack (const struct sigaltstack *__restrict __ss, + struct sigaltstack *__restrict __oss) throw (); + + + + + + + +extern int sighold (int __sig) throw (); + + +extern int sigrelse (int __sig) throw (); + + +extern int sigignore (int __sig) throw (); + + +extern __sighandler_t sigset (int __sig, __sighandler_t __disp) throw (); + + + + + + +# 1 "/usr/include/bits/sigthread.h" 1 3 4 +# 30 "/usr/include/bits/sigthread.h" 3 4 +extern int pthread_sigmask (int __how, + const __sigset_t *__restrict __newmask, + __sigset_t *__restrict __oldmask)throw (); + + +extern int pthread_kill (pthread_t __threadid, int __signo) throw (); + + + +extern int pthread_sigqueue (pthread_t __threadid, int __signo, + const union sigval __value) throw (); +# 397 "/usr/include/signal.h" 2 3 4 + + + + + + +extern int __libc_current_sigrtmin (void) throw (); + +extern int __libc_current_sigrtmax (void) throw (); + + + +} +# 14 "include/CLog.h" 2 +# 1 "/usr/include/stdlib.h" 1 3 4 +# 32 "/usr/include/stdlib.h" 3 4 +# 1 "/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stddef.h" 1 3 4 +# 33 "/usr/include/stdlib.h" 2 3 4 + +extern "C" { + + + + + + +# 1 "/usr/include/bits/waitflags.h" 1 3 4 +# 42 "/usr/include/stdlib.h" 2 3 4 +# 1 "/usr/include/bits/waitstatus.h" 1 3 4 +# 66 "/usr/include/bits/waitstatus.h" 3 4 +union wait + { + int w_status; + struct + { + + unsigned int __w_termsig:7; + unsigned int __w_coredump:1; + unsigned int __w_retcode:8; + unsigned int:16; + + + + + + + + } __wait_terminated; + struct + { + + unsigned int __w_stopval:8; + unsigned int __w_stopsig:8; + unsigned int:16; + + + + + + + } __wait_stopped; + }; +# 43 "/usr/include/stdlib.h" 2 3 4 +# 95 "/usr/include/stdlib.h" 3 4 + + +typedef struct + { + int quot; + int rem; + } div_t; + + + +typedef struct + { + long int quot; + long int rem; + } ldiv_t; + + + + + + + +__extension__ typedef struct + { + long long int quot; + long long int rem; + } lldiv_t; + + +# 139 "/usr/include/stdlib.h" 3 4 +extern size_t __ctype_get_mb_cur_max (void) throw () ; + + + + +extern double atof (const char *__nptr) + throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))) ; + +extern int atoi (const char *__nptr) + throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))) ; + +extern long int atol (const char *__nptr) + throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))) ; + + + + + +__extension__ extern long long int atoll (const char *__nptr) + throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))) ; + + + + + +extern double strtod (const char *__restrict __nptr, + char **__restrict __endptr) + throw () __attribute__ ((__nonnull__ (1))); + + + + + +extern float strtof (const char *__restrict __nptr, + char **__restrict __endptr) throw () __attribute__ ((__nonnull__ (1))); + +extern long double strtold (const char *__restrict __nptr, + char **__restrict __endptr) + throw () __attribute__ ((__nonnull__ (1))); + + + + + +extern long int strtol (const char *__restrict __nptr, + char **__restrict __endptr, int __base) + throw () __attribute__ ((__nonnull__ (1))); + +extern unsigned long int strtoul (const char *__restrict __nptr, + char **__restrict __endptr, int __base) + throw () __attribute__ ((__nonnull__ (1))); + + + + +__extension__ +extern long long int strtoq (const char *__restrict __nptr, + char **__restrict __endptr, int __base) + throw () __attribute__ ((__nonnull__ (1))); + +__extension__ +extern unsigned long long int strtouq (const char *__restrict __nptr, + char **__restrict __endptr, int __base) + throw () __attribute__ ((__nonnull__ (1))); + + + + + +__extension__ +extern long long int strtoll (const char *__restrict __nptr, + char **__restrict __endptr, int __base) + throw () __attribute__ ((__nonnull__ (1))); + +__extension__ +extern unsigned long long int strtoull (const char *__restrict __nptr, + char **__restrict __endptr, int __base) + throw () __attribute__ ((__nonnull__ (1))); + +# 239 "/usr/include/stdlib.h" 3 4 +extern long int strtol_l (const char *__restrict __nptr, + char **__restrict __endptr, int __base, + __locale_t __loc) throw () __attribute__ ((__nonnull__ (1, 4))); + +extern unsigned long int strtoul_l (const char *__restrict __nptr, + char **__restrict __endptr, + int __base, __locale_t __loc) + throw () __attribute__ ((__nonnull__ (1, 4))); + +__extension__ +extern long long int strtoll_l (const char *__restrict __nptr, + char **__restrict __endptr, int __base, + __locale_t __loc) + throw () __attribute__ ((__nonnull__ (1, 4))); + +__extension__ +extern unsigned long long int strtoull_l (const char *__restrict __nptr, + char **__restrict __endptr, + int __base, __locale_t __loc) + throw () __attribute__ ((__nonnull__ (1, 4))); + +extern double strtod_l (const char *__restrict __nptr, + char **__restrict __endptr, __locale_t __loc) + throw () __attribute__ ((__nonnull__ (1, 3))); + +extern float strtof_l (const char *__restrict __nptr, + char **__restrict __endptr, __locale_t __loc) + throw () __attribute__ ((__nonnull__ (1, 3))); + +extern long double strtold_l (const char *__restrict __nptr, + char **__restrict __endptr, + __locale_t __loc) + throw () __attribute__ ((__nonnull__ (1, 3))); +# 305 "/usr/include/stdlib.h" 3 4 +extern char *l64a (long int __n) throw () ; + + +extern long int a64l (const char *__s) + throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))) ; +# 321 "/usr/include/stdlib.h" 3 4 +extern long int random (void) throw (); + + +extern void srandom (unsigned int __seed) throw (); + + + + + +extern char *initstate (unsigned int __seed, char *__statebuf, + size_t __statelen) throw () __attribute__ ((__nonnull__ (2))); + + + +extern char *setstate (char *__statebuf) throw () __attribute__ ((__nonnull__ (1))); + + + + + + + +struct random_data + { + int32_t *fptr; + int32_t *rptr; + int32_t *state; + int rand_type; + int rand_deg; + int rand_sep; + int32_t *end_ptr; + }; + +extern int random_r (struct random_data *__restrict __buf, + int32_t *__restrict __result) throw () __attribute__ ((__nonnull__ (1, 2))); + +extern int srandom_r (unsigned int __seed, struct random_data *__buf) + throw () __attribute__ ((__nonnull__ (2))); + +extern int initstate_r (unsigned int __seed, char *__restrict __statebuf, + size_t __statelen, + struct random_data *__restrict __buf) + throw () __attribute__ ((__nonnull__ (2, 4))); + +extern int setstate_r (char *__restrict __statebuf, + struct random_data *__restrict __buf) + throw () __attribute__ ((__nonnull__ (1, 2))); + + + + + + +extern int rand (void) throw (); + +extern void srand (unsigned int __seed) throw (); + + + + +extern int rand_r (unsigned int *__seed) throw (); + + + + + + + +extern double drand48 (void) throw (); +extern double erand48 (unsigned short int __xsubi[3]) throw () __attribute__ ((__nonnull__ (1))); + + +extern long int lrand48 (void) throw (); +extern long int nrand48 (unsigned short int __xsubi[3]) + throw () __attribute__ ((__nonnull__ (1))); + + +extern long int mrand48 (void) throw (); +extern long int jrand48 (unsigned short int __xsubi[3]) + throw () __attribute__ ((__nonnull__ (1))); + + +extern void srand48 (long int __seedval) throw (); +extern unsigned short int *seed48 (unsigned short int __seed16v[3]) + throw () __attribute__ ((__nonnull__ (1))); +extern void lcong48 (unsigned short int __param[7]) throw () __attribute__ ((__nonnull__ (1))); + + + + + +struct drand48_data + { + unsigned short int __x[3]; + unsigned short int __old_x[3]; + unsigned short int __c; + unsigned short int __init; + unsigned long long int __a; + }; + + +extern int drand48_r (struct drand48_data *__restrict __buffer, + double *__restrict __result) throw () __attribute__ ((__nonnull__ (1, 2))); +extern int erand48_r (unsigned short int __xsubi[3], + struct drand48_data *__restrict __buffer, + double *__restrict __result) throw () __attribute__ ((__nonnull__ (1, 2))); + + +extern int lrand48_r (struct drand48_data *__restrict __buffer, + long int *__restrict __result) + throw () __attribute__ ((__nonnull__ (1, 2))); +extern int nrand48_r (unsigned short int __xsubi[3], + struct drand48_data *__restrict __buffer, + long int *__restrict __result) + throw () __attribute__ ((__nonnull__ (1, 2))); + + +extern int mrand48_r (struct drand48_data *__restrict __buffer, + long int *__restrict __result) + throw () __attribute__ ((__nonnull__ (1, 2))); +extern int jrand48_r (unsigned short int __xsubi[3], + struct drand48_data *__restrict __buffer, + long int *__restrict __result) + throw () __attribute__ ((__nonnull__ (1, 2))); + + +extern int srand48_r (long int __seedval, struct drand48_data *__buffer) + throw () __attribute__ ((__nonnull__ (2))); + +extern int seed48_r (unsigned short int __seed16v[3], + struct drand48_data *__buffer) throw () __attribute__ ((__nonnull__ (1, 2))); + +extern int lcong48_r (unsigned short int __param[7], + struct drand48_data *__buffer) + throw () __attribute__ ((__nonnull__ (1, 2))); + + + + + + + + + +extern void *malloc (size_t __size) throw () __attribute__ ((__malloc__)) ; + +extern void *calloc (size_t __nmemb, size_t __size) + throw () __attribute__ ((__malloc__)) ; + + + + + + + + + + +extern void *realloc (void *__ptr, size_t __size) + throw () __attribute__ ((__warn_unused_result__)); + +extern void free (void *__ptr) throw (); + + + + +extern void cfree (void *__ptr) throw (); + + + +# 1 "/usr/include/alloca.h" 1 3 4 +# 24 "/usr/include/alloca.h" 3 4 +# 1 "/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stddef.h" 1 3 4 +# 25 "/usr/include/alloca.h" 2 3 4 + +extern "C" { + + + + + +extern void *alloca (size_t __size) throw (); + + + + + +} +# 492 "/usr/include/stdlib.h" 2 3 4 + + + + + +extern void *valloc (size_t __size) throw () __attribute__ ((__malloc__)) ; + + + + +extern int posix_memalign (void **__memptr, size_t __alignment, size_t __size) + throw () __attribute__ ((__nonnull__ (1))) ; + + + + +extern void *aligned_alloc (size_t __alignment, size_t __size) + throw () __attribute__ ((__malloc__, __alloc_size__ (2))); + + + + +extern void abort (void) throw () __attribute__ ((__noreturn__)); + + + +extern int atexit (void (*__func) (void)) throw () __attribute__ ((__nonnull__ (1))); + + + + +extern "C++" int at_quick_exit (void (*__func) (void)) + throw () __asm ("at_quick_exit") __attribute__ ((__nonnull__ (1))); + + + + + + + + + +extern int on_exit (void (*__func) (int __status, void *__arg), void *__arg) + throw () __attribute__ ((__nonnull__ (1))); + + + + + + +extern void exit (int __status) throw () __attribute__ ((__noreturn__)); + + + + + +extern void quick_exit (int __status) throw () __attribute__ ((__noreturn__)); + + + + + + + +extern void _Exit (int __status) throw () __attribute__ ((__noreturn__)); + + + + + + +extern char *getenv (const char *__name) throw () __attribute__ ((__nonnull__ (1))) ; + + + + + +extern char *secure_getenv (const char *__name) + throw () __attribute__ ((__nonnull__ (1))) ; + + + + + + +extern int putenv (char *__string) throw () __attribute__ ((__nonnull__ (1))); + + + + + +extern int setenv (const char *__name, const char *__value, int __replace) + throw () __attribute__ ((__nonnull__ (2))); + + +extern int unsetenv (const char *__name) throw () __attribute__ ((__nonnull__ (1))); + + + + + + +extern int clearenv (void) throw (); +# 605 "/usr/include/stdlib.h" 3 4 +extern char *mktemp (char *__template) throw () __attribute__ ((__nonnull__ (1))); +# 619 "/usr/include/stdlib.h" 3 4 +extern int mkstemp (char *__template) __attribute__ ((__nonnull__ (1))) ; +# 629 "/usr/include/stdlib.h" 3 4 +extern int mkstemp64 (char *__template) __attribute__ ((__nonnull__ (1))) ; +# 641 "/usr/include/stdlib.h" 3 4 +extern int mkstemps (char *__template, int __suffixlen) __attribute__ ((__nonnull__ (1))) ; +# 651 "/usr/include/stdlib.h" 3 4 +extern int mkstemps64 (char *__template, int __suffixlen) + __attribute__ ((__nonnull__ (1))) ; +# 662 "/usr/include/stdlib.h" 3 4 +extern char *mkdtemp (char *__template) throw () __attribute__ ((__nonnull__ (1))) ; +# 673 "/usr/include/stdlib.h" 3 4 +extern int mkostemp (char *__template, int __flags) __attribute__ ((__nonnull__ (1))) ; +# 683 "/usr/include/stdlib.h" 3 4 +extern int mkostemp64 (char *__template, int __flags) __attribute__ ((__nonnull__ (1))) ; +# 693 "/usr/include/stdlib.h" 3 4 +extern int mkostemps (char *__template, int __suffixlen, int __flags) + __attribute__ ((__nonnull__ (1))) ; +# 705 "/usr/include/stdlib.h" 3 4 +extern int mkostemps64 (char *__template, int __suffixlen, int __flags) + __attribute__ ((__nonnull__ (1))) ; + + + + + + + + + +extern int system (const char *__command) ; + + + + + + +extern char *canonicalize_file_name (const char *__name) + throw () __attribute__ ((__nonnull__ (1))) ; +# 733 "/usr/include/stdlib.h" 3 4 +extern char *realpath (const char *__restrict __name, + char *__restrict __resolved) throw () ; + + + + + + +typedef int (*__compar_fn_t) (const void *, const void *); + + +typedef __compar_fn_t comparison_fn_t; + + + +typedef int (*__compar_d_fn_t) (const void *, const void *, void *); + + + + + +extern void *bsearch (const void *__key, const void *__base, + size_t __nmemb, size_t __size, __compar_fn_t __compar) + __attribute__ ((__nonnull__ (1, 2, 5))) ; + + + +extern void qsort (void *__base, size_t __nmemb, size_t __size, + __compar_fn_t __compar) __attribute__ ((__nonnull__ (1, 4))); + +extern void qsort_r (void *__base, size_t __nmemb, size_t __size, + __compar_d_fn_t __compar, void *__arg) + __attribute__ ((__nonnull__ (1, 4))); + + + + +extern int abs (int __x) throw () __attribute__ ((__const__)) ; +extern long int labs (long int __x) throw () __attribute__ ((__const__)) ; + + + +__extension__ extern long long int llabs (long long int __x) + throw () __attribute__ ((__const__)) ; + + + + + + + +extern div_t div (int __numer, int __denom) + throw () __attribute__ ((__const__)) ; +extern ldiv_t ldiv (long int __numer, long int __denom) + throw () __attribute__ ((__const__)) ; + + + + +__extension__ extern lldiv_t lldiv (long long int __numer, + long long int __denom) + throw () __attribute__ ((__const__)) ; + +# 807 "/usr/include/stdlib.h" 3 4 +extern char *ecvt (double __value, int __ndigit, int *__restrict __decpt, + int *__restrict __sign) throw () __attribute__ ((__nonnull__ (3, 4))) ; + + + + +extern char *fcvt (double __value, int __ndigit, int *__restrict __decpt, + int *__restrict __sign) throw () __attribute__ ((__nonnull__ (3, 4))) ; + + + + +extern char *gcvt (double __value, int __ndigit, char *__buf) + throw () __attribute__ ((__nonnull__ (3))) ; + + + + +extern char *qecvt (long double __value, int __ndigit, + int *__restrict __decpt, int *__restrict __sign) + throw () __attribute__ ((__nonnull__ (3, 4))) ; +extern char *qfcvt (long double __value, int __ndigit, + int *__restrict __decpt, int *__restrict __sign) + throw () __attribute__ ((__nonnull__ (3, 4))) ; +extern char *qgcvt (long double __value, int __ndigit, char *__buf) + throw () __attribute__ ((__nonnull__ (3))) ; + + + + +extern int ecvt_r (double __value, int __ndigit, int *__restrict __decpt, + int *__restrict __sign, char *__restrict __buf, + size_t __len) throw () __attribute__ ((__nonnull__ (3, 4, 5))); +extern int fcvt_r (double __value, int __ndigit, int *__restrict __decpt, + int *__restrict __sign, char *__restrict __buf, + size_t __len) throw () __attribute__ ((__nonnull__ (3, 4, 5))); + +extern int qecvt_r (long double __value, int __ndigit, + int *__restrict __decpt, int *__restrict __sign, + char *__restrict __buf, size_t __len) + throw () __attribute__ ((__nonnull__ (3, 4, 5))); +extern int qfcvt_r (long double __value, int __ndigit, + int *__restrict __decpt, int *__restrict __sign, + char *__restrict __buf, size_t __len) + throw () __attribute__ ((__nonnull__ (3, 4, 5))); + + + + + + + +extern int mblen (const char *__s, size_t __n) throw () ; + + +extern int mbtowc (wchar_t *__restrict __pwc, + const char *__restrict __s, size_t __n) throw () ; + + +extern int wctomb (char *__s, wchar_t __wchar) throw () ; + + + +extern size_t mbstowcs (wchar_t *__restrict __pwcs, + const char *__restrict __s, size_t __n) throw (); + +extern size_t wcstombs (char *__restrict __s, + const wchar_t *__restrict __pwcs, size_t __n) + throw (); + + + + + + + + +extern int rpmatch (const char *__response) throw () __attribute__ ((__nonnull__ (1))) ; +# 895 "/usr/include/stdlib.h" 3 4 +extern int getsubopt (char **__restrict __optionp, + char *const *__restrict __tokens, + char **__restrict __valuep) + throw () __attribute__ ((__nonnull__ (1, 2, 3))) ; + + + + + +extern void setkey (const char *__key) throw () __attribute__ ((__nonnull__ (1))); + + + + + + + +extern int posix_openpt (int __oflag) ; + + + + + + + +extern int grantpt (int __fd) throw (); + + + +extern int unlockpt (int __fd) throw (); + + + + +extern char *ptsname (int __fd) throw () ; + + + + + + +extern int ptsname_r (int __fd, char *__buf, size_t __buflen) + throw () __attribute__ ((__nonnull__ (2))); + + +extern int getpt (void); + + + + + + +extern int getloadavg (double __loadavg[], int __nelem) + throw () __attribute__ ((__nonnull__ (1))); + + +# 1 "/usr/include/bits/stdlib-float.h" 1 3 4 +# 952 "/usr/include/stdlib.h" 2 3 4 +# 964 "/usr/include/stdlib.h" 3 4 +} +# 15 "include/CLog.h" 2 + +# 1 "/usr/include/memory.h" 1 3 4 +# 29 "/usr/include/memory.h" 3 4 +# 1 "/usr/include/string.h" 1 3 4 +# 27 "/usr/include/string.h" 3 4 +extern "C" { + + + + +# 1 "/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stddef.h" 1 3 4 +# 33 "/usr/include/string.h" 2 3 4 + + + + + + + + + +extern void *memcpy (void *__restrict __dest, const void *__restrict __src, + size_t __n) throw () __attribute__ ((__nonnull__ (1, 2))); + + +extern void *memmove (void *__dest, const void *__src, size_t __n) + throw () __attribute__ ((__nonnull__ (1, 2))); + + + + + + +extern void *memccpy (void *__restrict __dest, const void *__restrict __src, + int __c, size_t __n) + throw () __attribute__ ((__nonnull__ (1, 2))); + + + + + +extern void *memset (void *__s, int __c, size_t __n) throw () __attribute__ ((__nonnull__ (1))); + + +extern int memcmp (const void *__s1, const void *__s2, size_t __n) + throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); + + + +extern "C++" +{ +extern void *memchr (void *__s, int __c, size_t __n) + throw () __asm ("memchr") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); +extern const void *memchr (const void *__s, int __c, size_t __n) + throw () __asm ("memchr") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); +# 90 "/usr/include/string.h" 3 4 +} + + + + + + + + + + +extern "C++" void *rawmemchr (void *__s, int __c) + throw () __asm ("rawmemchr") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); +extern "C++" const void *rawmemchr (const void *__s, int __c) + throw () __asm ("rawmemchr") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); + + + + + + + +extern "C++" void *memrchr (void *__s, int __c, size_t __n) + throw () __asm ("memrchr") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); +extern "C++" const void *memrchr (const void *__s, int __c, size_t __n) + throw () __asm ("memrchr") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); + + + + + + + + + +extern char *strcpy (char *__restrict __dest, const char *__restrict __src) + throw () __attribute__ ((__nonnull__ (1, 2))); + +extern char *strncpy (char *__restrict __dest, + const char *__restrict __src, size_t __n) + throw () __attribute__ ((__nonnull__ (1, 2))); + + +extern char *strcat (char *__restrict __dest, const char *__restrict __src) + throw () __attribute__ ((__nonnull__ (1, 2))); + +extern char *strncat (char *__restrict __dest, const char *__restrict __src, + size_t __n) throw () __attribute__ ((__nonnull__ (1, 2))); + + +extern int strcmp (const char *__s1, const char *__s2) + throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); + +extern int strncmp (const char *__s1, const char *__s2, size_t __n) + throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); + + +extern int strcoll (const char *__s1, const char *__s2) + throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); + +extern size_t strxfrm (char *__restrict __dest, + const char *__restrict __src, size_t __n) + throw () __attribute__ ((__nonnull__ (2))); + +# 162 "/usr/include/string.h" 3 4 +extern int strcoll_l (const char *__s1, const char *__s2, __locale_t __l) + throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2, 3))); + +extern size_t strxfrm_l (char *__dest, const char *__src, size_t __n, + __locale_t __l) throw () __attribute__ ((__nonnull__ (2, 4))); + + + + + +extern char *strdup (const char *__s) + throw () __attribute__ ((__malloc__)) __attribute__ ((__nonnull__ (1))); + + + + + + +extern char *strndup (const char *__string, size_t __n) + throw () __attribute__ ((__malloc__)) __attribute__ ((__nonnull__ (1))); +# 207 "/usr/include/string.h" 3 4 + + + +extern "C++" +{ +extern char *strchr (char *__s, int __c) + throw () __asm ("strchr") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); +extern const char *strchr (const char *__s, int __c) + throw () __asm ("strchr") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); +# 230 "/usr/include/string.h" 3 4 +} + + + + + + +extern "C++" +{ +extern char *strrchr (char *__s, int __c) + throw () __asm ("strrchr") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); +extern const char *strrchr (const char *__s, int __c) + throw () __asm ("strrchr") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); +# 257 "/usr/include/string.h" 3 4 +} + + + + + + + + + + +extern "C++" char *strchrnul (char *__s, int __c) + throw () __asm ("strchrnul") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); +extern "C++" const char *strchrnul (const char *__s, int __c) + throw () __asm ("strchrnul") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); + + + + + + + + + +extern size_t strcspn (const char *__s, const char *__reject) + throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); + + +extern size_t strspn (const char *__s, const char *__accept) + throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); + + +extern "C++" +{ +extern char *strpbrk (char *__s, const char *__accept) + throw () __asm ("strpbrk") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); +extern const char *strpbrk (const char *__s, const char *__accept) + throw () __asm ("strpbrk") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); +# 309 "/usr/include/string.h" 3 4 +} + + + + + + +extern "C++" +{ +extern char *strstr (char *__haystack, const char *__needle) + throw () __asm ("strstr") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); +extern const char *strstr (const char *__haystack, const char *__needle) + throw () __asm ("strstr") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); +# 336 "/usr/include/string.h" 3 4 +} + + + + + + + +extern char *strtok (char *__restrict __s, const char *__restrict __delim) + throw () __attribute__ ((__nonnull__ (2))); + + + + +extern char *__strtok_r (char *__restrict __s, + const char *__restrict __delim, + char **__restrict __save_ptr) + throw () __attribute__ ((__nonnull__ (2, 3))); + +extern char *strtok_r (char *__restrict __s, const char *__restrict __delim, + char **__restrict __save_ptr) + throw () __attribute__ ((__nonnull__ (2, 3))); + + + + + +extern "C++" char *strcasestr (char *__haystack, const char *__needle) + throw () __asm ("strcasestr") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); +extern "C++" const char *strcasestr (const char *__haystack, + const char *__needle) + throw () __asm ("strcasestr") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); +# 378 "/usr/include/string.h" 3 4 +extern void *memmem (const void *__haystack, size_t __haystacklen, + const void *__needle, size_t __needlelen) + throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 3))); + + + +extern void *__mempcpy (void *__restrict __dest, + const void *__restrict __src, size_t __n) + throw () __attribute__ ((__nonnull__ (1, 2))); +extern void *mempcpy (void *__restrict __dest, + const void *__restrict __src, size_t __n) + throw () __attribute__ ((__nonnull__ (1, 2))); + + + + + +extern size_t strlen (const char *__s) + throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); + + + + + +extern size_t strnlen (const char *__string, size_t __maxlen) + throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); + + + + + +extern char *strerror (int __errnum) throw (); + +# 434 "/usr/include/string.h" 3 4 +extern char *strerror_r (int __errnum, char *__buf, size_t __buflen) + throw () __attribute__ ((__nonnull__ (2))) ; + + + + + +extern char *strerror_l (int __errnum, __locale_t __l) throw (); + + + + + +extern void __bzero (void *__s, size_t __n) throw () __attribute__ ((__nonnull__ (1))); + + + +extern void bcopy (const void *__src, void *__dest, size_t __n) + throw () __attribute__ ((__nonnull__ (1, 2))); + + +extern void bzero (void *__s, size_t __n) throw () __attribute__ ((__nonnull__ (1))); + + +extern int bcmp (const void *__s1, const void *__s2, size_t __n) + throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); + + + +extern "C++" +{ +extern char *index (char *__s, int __c) + throw () __asm ("index") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); +extern const char *index (const char *__s, int __c) + throw () __asm ("index") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); +# 483 "/usr/include/string.h" 3 4 +} + + + + + + + +extern "C++" +{ +extern char *rindex (char *__s, int __c) + throw () __asm ("rindex") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); +extern const char *rindex (const char *__s, int __c) + throw () __asm ("rindex") __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); +# 511 "/usr/include/string.h" 3 4 +} + + + + + + + +extern int ffs (int __i) throw () __attribute__ ((__const__)); + + + + +extern int ffsl (long int __l) throw () __attribute__ ((__const__)); + +__extension__ extern int ffsll (long long int __ll) + throw () __attribute__ ((__const__)); + + + + +extern int strcasecmp (const char *__s1, const char *__s2) + throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); + + +extern int strncasecmp (const char *__s1, const char *__s2, size_t __n) + throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); + + + + + +extern int strcasecmp_l (const char *__s1, const char *__s2, + __locale_t __loc) + throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2, 3))); + +extern int strncasecmp_l (const char *__s1, const char *__s2, + size_t __n, __locale_t __loc) + throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2, 4))); + + + + + +extern char *strsep (char **__restrict __stringp, + const char *__restrict __delim) + throw () __attribute__ ((__nonnull__ (1, 2))); + + + + +extern char *strsignal (int __sig) throw (); + + +extern char *__stpcpy (char *__restrict __dest, const char *__restrict __src) + throw () __attribute__ ((__nonnull__ (1, 2))); +extern char *stpcpy (char *__restrict __dest, const char *__restrict __src) + throw () __attribute__ ((__nonnull__ (1, 2))); + + + +extern char *__stpncpy (char *__restrict __dest, + const char *__restrict __src, size_t __n) + throw () __attribute__ ((__nonnull__ (1, 2))); +extern char *stpncpy (char *__restrict __dest, + const char *__restrict __src, size_t __n) + throw () __attribute__ ((__nonnull__ (1, 2))); + + + + +extern int strverscmp (const char *__s1, const char *__s2) + throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); + + +extern char *strfry (char *__string) throw () __attribute__ ((__nonnull__ (1))); + + +extern void *memfrob (void *__s, size_t __n) throw () __attribute__ ((__nonnull__ (1))); + + + + + + + +extern "C++" char *basename (char *__filename) + throw () __asm ("basename") __attribute__ ((__nonnull__ (1))); +extern "C++" const char *basename (const char *__filename) + throw () __asm ("basename") __attribute__ ((__nonnull__ (1))); +# 642 "/usr/include/string.h" 3 4 +} +# 30 "/usr/include/memory.h" 2 3 4 +# 17 "include/CLog.h" 2 +# 41 "include/CLog.h" +typedef enum tagLogLevel +{ + FATAL = 0, + ALERT, + ERROR, + WARN, + NOTICE, + INFO, + DEBUG +} CYBERER_LOG_LEVEL_E; +# 84 "include/CLog.h" +extern void LogPrint(const int level,const char *proName,const char *func,const int line,const char *format, ...); +extern void BufPrint(const char *func,const int line, const char *pData, int iDataLen); +# 19 "include/CTypedef.h" 2 +# 1 "include/CSwitchCommon.h" 1 +# 13 "include/CSwitchCommon.h" +typedef enum Judge_Error_Code_E +{ + JUDGE_ALL_SUCCESS=0, + JUDGE_SUCC_WITH_TWO_STAGE, + JUDGE_SUCC_WITH_MANY_STAGE, + JUDGE_SUCC_WITH_TIMEOUT, + JUDGE_SUCC_WITH_TIMEOUT_TWO_STAGE, + JUDGE_SUCC_WITH_TIMEOUT_MANY_STAGE, + + JUDGE_ALL_FAIL_WITH_DIFF, + JUDGE_FAIL_WITH_TWO_STAGE, + JUDGE_FAIL_WITH_MANY_STAGE, + JUDGE_FAIL_WITH_TIMEOUT, + JUDGE_FAIL_WITH_TIMEOUT_TWO_STAGE, + JUDGE_FAIL_WITH_TIMEOUT_MANY_STAGE, + + ERROR_CODE_MAX +}Judge_Error_Code_T; + +typedef struct Judge_Error_Msg_S +{ + Judge_Error_Code_T uiErrorCode; +# 45 "include/CSwitchCommon.h" + uint uiNosIdx; + char szReserve[32]; +}Judge_Error_Msg_T; + +typedef enum Judge_Sys_Info_Error_Code_E +{ + JUDGE_EXCESSIVE_CPU_OCCUPY, + JUDGE_EXCESSIVE_MEM_OCCUPY, + JUDGE_EXCESSIVE_TCP_SOCKET, + JUDGE_EXCESSIVE_PROGRESS, + JUDGE_SOMEONE_BROKEN_INTO, + JUDGE_EXCEPTION_SHELL, + JUDGE_EXCEPTION_USER, + JUDGE_EXCEPTION_GROUP, + JUDGE_CHANGE_CRON, + JUDGE_CHANGE_FILE_IN_PATH, + JUDGE_CHANGE_FILE_IN_HOME, + JUDGE_EXCEPTION_APP, + JUDGE_EXCEPTION_AUTOSTART, + JUDGE_EXCEPTION_MANAGER, + JUDGE_EXCEPTION_PROTOCOL, + JUDGE_EXCEPTION_LOCAL_CONFIG_MANAGER, + JUDGE_EXCEPTION_FIREWALL, + JUDGE_TIME_OUT +}Judge_Sys_Info_Error_Code_T; + +typedef struct Judge_Sys_Info_Error_Msg_S +{ + Judge_Sys_Info_Error_Code_T uiErrorCode; +# 84 "include/CSwitchCommon.h" + uint uiNosIdx; + char szReserve[32]; +}Judge_Sys_Info_Error_Msg_T; + +typedef enum { + HB_JUDGE_E = 1, + HB_SHD_E, + HB_MYSQL_E, + HB_WEB_E, + HB_CFG_MANAGER_E, + HB_MAX_E +}HEARBEAT_E; +# 20 "include/CTypedef.h" 2 +# 29 "include/CTypedef.h" +typedef socklen_t SOCKLEN_T; +typedef struct timeval TIMEVAL_T; +typedef struct sockaddr SOCKADDR_T; +typedef struct sockaddr_in SOCKADDR_IN_T; + +typedef unsigned int uint; + +typedef struct +{ + unsigned int uiNosIdx; + TIMEVAL_T stRcvTime; + unsigned int uiDataLen; + unsigned int uiPort; + int iCmd; + unsigned char ucData[1024]; +}NosConfMsg_ST; + +typedef struct +{ + int iCmd; + unsigned char ucData[1024]; +}ConfJudgeMsg_ST; + +typedef struct +{ + unsigned int uiNosIdx; + unsigned char ucHost[16]; + int iState; +}NosState_T; + +typedef struct +{ + uint uiType; + char szIp[32]; + uint uiCpuRate; + uint uiMemRate; + uint uiTcpEstablishNum; + uint uiRunningProcessNum; + uint uiCronNum; + char szPasswdMd5[16]; +}SystemState_T; + +typedef struct +{ + uint uiType; + char szIp[32]; + uint uiProcessId; + uint uiProcessState; +}ProcessState_T; + +typedef struct +{ + uint uiType; + char szIp[32]; + char szFileName[32]; + char eventType[16]; + char szFileMd5[32]; +}FileState_T; + +typedef struct +{ + uint uiType; + char szIp[32]; + char szPath[32]; + char szFileName[32]; + uint uiFileNum; +}FileNum_T; + +typedef struct +{ + uint uiType; + char szIp[32]; + char szLogFile[32]; + char szMsg[128]; +}SysLog_T; + +typedef enum MESSAGE_QUQUQ_TYPE_E{ + MQT_CONFIG_E = 1, + MQT_SYSTEM_STATE_E, + MQT_PROCESS_STATE_E, + MQT_FILE_NUM_E, + MQT_FILE_STATE_E, + MQT_SYSTEM_LOG_E +}Message_QueueType_E; +# 11 "include/CMessageQueue.h" 2 +# 1 "include/CJudgeUtils.h" 1 +# 12 "include/CJudgeUtils.h" +# 1 "/usr/include/c++/4.8.2/cstdio" 1 3 +# 39 "/usr/include/c++/4.8.2/cstdio" 3 + +# 40 "/usr/include/c++/4.8.2/cstdio" 3 +# 94 "/usr/include/c++/4.8.2/cstdio" 3 +namespace std +{ + using ::FILE; + using ::fpos_t; + + using ::clearerr; + using ::fclose; + using ::feof; + using ::ferror; + using ::fflush; + using ::fgetc; + using ::fgetpos; + using ::fgets; + using ::fopen; + using ::fprintf; + using ::fputc; + using ::fputs; + using ::fread; + using ::freopen; + using ::fscanf; + using ::fseek; + using ::fsetpos; + using ::ftell; + using ::fwrite; + using ::getc; + using ::getchar; + using ::gets; + using ::perror; + using ::printf; + using ::putc; + using ::putchar; + using ::puts; + using ::remove; + using ::rename; + using ::rewind; + using ::scanf; + using ::setbuf; + using ::setvbuf; + using ::sprintf; + using ::sscanf; + using ::tmpfile; + using ::tmpnam; + using ::ungetc; + using ::vfprintf; + using ::vprintf; + using ::vsprintf; +} +# 150 "/usr/include/c++/4.8.2/cstdio" 3 +namespace __gnu_cxx +{ +# 168 "/usr/include/c++/4.8.2/cstdio" 3 + using ::snprintf; + using ::vfscanf; + using ::vscanf; + using ::vsnprintf; + using ::vsscanf; + +} + +namespace std +{ + using ::__gnu_cxx::snprintf; + using ::__gnu_cxx::vfscanf; + using ::__gnu_cxx::vscanf; + using ::__gnu_cxx::vsnprintf; + using ::__gnu_cxx::vsscanf; +} +# 13 "include/CJudgeUtils.h" 2 + + + + + + +class CNonCopyable +{ +protected: + CNonCopyable() {} + ~CNonCopyable() {} +private: + CNonCopyable(const CNonCopyable &); + const CNonCopyable& operator=(const CNonCopyable &); +}; + +class CMutexLockGuard:CNonCopyable +{ + public: + explicit CMutexLockGuard(pthread_mutex_t& mutex) + : m_mutex(mutex) + { + pthread_mutex_lock(&m_mutex); + } + + ~CMutexLockGuard() + { + pthread_mutex_unlock(&m_mutex); + } + +private: + pthread_mutex_t& m_mutex; +}; + +template +class CSingleton +{ +public: + static T* GetInstance() + { + if( _instance == __null ) + { + _instance = new T; + } + return _instance; + } + + static T* Instance() + { + if( _instance == __null ) + { + _instance = new T; + } + return _instance; + } + + static void Release() + { + if( _instance!= __null ) + { + delete _instance; + } + + _instance = __null; + } + +protected: + CSingleton(){} + virtual ~CSingleton(){} +protected: + static T* _instance; +}; + +template T* CSingleton::_instance=__null; + +class INIReader +{ +public: + explicit INIReader() {} + ~INIReader() {} + + + + + + int32_t Parse(const std::string& filename); + + void Clear(); + + + std::string Get(const std::string& section, const std::string& name, + const std::string& default_value); + + + + + int32_t GetInt32(const std::string& section, const std::string& name, + int32_t default_value); + + uint32_t GetUInt32(const std::string& section, const std::string& name, + uint32_t default_value); + + int64_t GetInt64(const std::string& section, const std::string& name, + int64_t default_value); + + uint64_t GetUInt64(const std::string& section, const std::string& name, + uint64_t default_value); + + + + + double GetReal(const std::string& section, const std::string& name, double default_value); + + + + + + bool GetBoolean(const std::string& section, const std::string& name, bool default_value); + + + + const std::set& GetSections() const; + + + + + std::set GetFields(const std::string& section); + + + + const char* GetLastError() const { return m_last_error; } +private: + int32_t ParseFile(FILE* file); +private: + char m_last_error[256]; + std::set m_sections; + std::map > m_fields; +}; +# 12 "include/CMessageQueue.h" 2 + +template +class CMessageQueue : public CSingleton > +{ +public: + CMessageQueue(); + ~CMessageQueue(); + + void push(T stData,Message_QueueType_E MessageType); + void pop(Message_QueueType_E MessageType); + T& front(Message_QueueType_E MessageType); + T& back(Message_QueueType_E MessageType); + int empty(Message_QueueType_E MessageType); + int size(Message_QueueType_E MessageType); + void remove(T stData, Message_QueueType_E MessageType); + +private: + + +private: + static const Message_QueueType_E m_MessageTypeE = MQT_CONFIG_E; + + pthread_mutex_t m_QueueMutex; + std::list m_queue; + + pthread_mutex_t ss_QueueMutex; + std::list q_SysState; + + pthread_mutex_t ps_QueueMutex; + std::list q_ProcessState; + + pthread_mutex_t fs_QueueMutex; + std::list q_FileState; + + pthread_mutex_t fn_QueueMutex; + std::list q_FileNum; + + pthread_mutex_t sl_QueueMutex; + std::list q_SysLog; +}; + + +template +CMessageQueue::CMessageQueue() +{ + pthread_mutex_init(&m_QueueMutex, __null); + + pthread_mutex_init(&ss_QueueMutex, __null); + pthread_mutex_init(&ps_QueueMutex, __null); + pthread_mutex_init(&fs_QueueMutex, __null); + pthread_mutex_init(&fn_QueueMutex, __null); + pthread_mutex_init(&sl_QueueMutex, __null); +} + +template +CMessageQueue::~CMessageQueue() +{ + pthread_mutex_destroy(&m_QueueMutex); + + pthread_mutex_destroy(&ss_QueueMutex); + pthread_mutex_destroy(&ps_QueueMutex); + pthread_mutex_destroy(&fs_QueueMutex); + pthread_mutex_destroy(&fn_QueueMutex); + pthread_mutex_destroy(&sl_QueueMutex); +} + +template +void CMessageQueue::push(T stData,Message_QueueType_E MessageType = m_MessageTypeE) +{ + switch(MessageType) + { + + + + + + + + case MQT_CONFIG_E: { CMutexLockGuard m_MutexLock(m_QueueMutex); m_queue.push_back(stData); break; }; + case MQT_SYSTEM_STATE_E: { CMutexLockGuard m_MutexLock(ss_QueueMutex); q_SysState.push_back(stData); break; }; + case MQT_PROCESS_STATE_E: { CMutexLockGuard m_MutexLock(ps_QueueMutex); q_ProcessState.push_back(stData); break; }; + case MQT_FILE_STATE_E: { CMutexLockGuard m_MutexLock(fs_QueueMutex); q_FileState.push_back(stData); break; }; + case MQT_FILE_NUM_E: { CMutexLockGuard m_MutexLock(fn_QueueMutex); q_FileNum.push_back(stData); break; }; + case MQT_SYSTEM_LOG_E: { CMutexLockGuard m_MutexLock(sl_QueueMutex); q_SysLog.push_back(stData); break; }; +# 136 "include/CMessageQueue.h" + default: + break; + } + +} + +template +void CMessageQueue::pop(Message_QueueType_E MessageType = m_MessageTypeE) +{ + switch(MessageType) + { + case MQT_CONFIG_E: + { + CMutexLockGuard m_MutexLock(m_QueueMutex); + m_queue.pop_front(); + break; + } + case MQT_SYSTEM_STATE_E: + { + CMutexLockGuard ss_MutexLock(ss_QueueMutex); + q_SysState.pop_front(); + break; + } + + case MQT_PROCESS_STATE_E: + { + CMutexLockGuard ps_MutexLock(ps_QueueMutex); + q_ProcessState.pop_front(); + break; + } + + case MQT_FILE_STATE_E: + { + CMutexLockGuard fs_MutexLock(fs_QueueMutex); + q_FileState.pop_front(); + break; + } + case MQT_FILE_NUM_E: + { + CMutexLockGuard fn_MutexLock(fn_QueueMutex); + q_FileNum.pop_front(); + break; + } + case MQT_SYSTEM_LOG_E: + { + CMutexLockGuard sl_MutexLock(sl_QueueMutex); + q_SysLog.pop_front(); + break; + } + default: + break; + } + +} + +template +T& CMessageQueue::front(Message_QueueType_E MessageType = m_MessageTypeE) +{ + + switch(MessageType) + { + case MQT_CONFIG_E: + { + CMutexLockGuard m_MutexLock(m_QueueMutex); + return m_queue.front(); + } + case MQT_SYSTEM_STATE_E: + { + CMutexLockGuard ss_MutexLock(ss_QueueMutex); + return q_SysState.front(); + } + case MQT_PROCESS_STATE_E: + { + CMutexLockGuard ps_MutexLock(ps_QueueMutex); + return q_ProcessState.front(); + } + case MQT_FILE_STATE_E: + { + CMutexLockGuard fs_MutexLock(fs_QueueMutex); + return q_FileState.front(); + } + case MQT_FILE_NUM_E: + { + CMutexLockGuard fn_MutexLock(fn_QueueMutex); + return q_FileNum.front(); + } + case MQT_SYSTEM_LOG_E: + { + CMutexLockGuard sl_MutexLock(sl_QueueMutex); + return q_SysLog.front(); + } + default: + return m_queue.front(); + } + +} + +template +T& CMessageQueue::back(Message_QueueType_E MessageType = m_MessageTypeE) +{ + switch(MessageType) + { + case MQT_CONFIG_E: + { + CMutexLockGuard m_MutexLock(m_QueueMutex); + return m_queue.back(); + } + case MQT_SYSTEM_STATE_E: + { + CMutexLockGuard ss_MutexLock(ss_QueueMutex); + return q_SysState.back(); + } + case MQT_PROCESS_STATE_E: + { + CMutexLockGuard ps_MutexLock(ps_QueueMutex); + return q_ProcessState.back(); + } + case MQT_FILE_STATE_E: + { + CMutexLockGuard fs_MutexLock(fs_QueueMutex); + return q_FileState.back(); + } + case MQT_FILE_NUM_E: + { + CMutexLockGuard fn_MutexLock(fn_QueueMutex); + return q_FileNum.back(); + } + case MQT_SYSTEM_LOG_E: + { + CMutexLockGuard sl_MutexLock(sl_QueueMutex); + return q_SysLog.back(); + } + default: + return m_queue.back(); + } +} + +template +int CMessageQueue::empty(Message_QueueType_E MessageType = m_MessageTypeE) +{ + switch(MessageType) + { + case MQT_CONFIG_E: + { + CMutexLockGuard m_MutexLock(m_QueueMutex); + return m_queue.empty(); + } + case MQT_SYSTEM_STATE_E: + { + CMutexLockGuard ss_MutexLock(ss_QueueMutex); + return q_SysState.empty(); + } + case MQT_PROCESS_STATE_E: + { + CMutexLockGuard ps_MutexLock(ps_QueueMutex); + return q_ProcessState.empty(); + } + case MQT_FILE_STATE_E: + { + CMutexLockGuard fs_MutexLock(fs_QueueMutex); + return q_FileState.empty(); + } + case MQT_FILE_NUM_E: + { + CMutexLockGuard fn_MutexLock(fn_QueueMutex); + return q_FileNum.empty(); + } + case MQT_SYSTEM_LOG_E: + { + CMutexLockGuard sl_MutexLock(sl_QueueMutex); + return q_SysLog.empty(); + } + default: + return 0; + } + return 0; +} + +template +int CMessageQueue::size(Message_QueueType_E MessageType = m_MessageTypeE) +{ + + switch(MessageType) + { + case MQT_CONFIG_E: + { + CMutexLockGuard MutexLock(m_QueueMutex); + return m_queue.size(); + } + case MQT_SYSTEM_STATE_E: + { + CMutexLockGuard MutexLock(ss_QueueMutex); + return q_SysState.size(); + } + case MQT_PROCESS_STATE_E: + { + CMutexLockGuard MutexLock(ps_QueueMutex); + return q_ProcessState.size(); + } + case MQT_FILE_STATE_E: + { + CMutexLockGuard MutexLock(fs_QueueMutex); + return q_FileState.size(); + } + case MQT_FILE_NUM_E: + { + CMutexLockGuard MutexLock(fn_QueueMutex); + return q_FileNum.size(); + } + case MQT_SYSTEM_LOG_E: + { + CMutexLockGuard MutexLock(sl_QueueMutex); + return q_SysLog.size(); + } + default: + return 0; + } + +} + +template +void CMessageQueue::remove(T stData, Message_QueueType_E MessageType = m_MessageTypeE) +{ + + switch(MessageType) + { + case MQT_CONFIG_E: + { + CMutexLockGuard MutexLock(m_QueueMutex); + m_queue.remove(stData); + break; + } + case MQT_SYSTEM_STATE_E: + { + CMutexLockGuard MutexLock(ss_QueueMutex); + q_SysState.remove(stData); + break; + } + case MQT_PROCESS_STATE_E: + { + CMutexLockGuard MutexLock(ps_QueueMutex); + q_ProcessState.remove(stData); + break; + } + case MQT_FILE_STATE_E: + { + CMutexLockGuard MutexLock(fs_QueueMutex); + q_FileState.remove(stData); + break; + } + case MQT_FILE_NUM_E: + { + CMutexLockGuard MutexLock(fn_QueueMutex); + q_FileNum.remove(stData); + break; + } + case MQT_SYSTEM_LOG_E: + { + CMutexLockGuard MutexLock(sl_QueueMutex); + q_SysLog.remove(stData); + break; + } + default: + break; + } +} +# 10 "test.cpp" 2 +# 1 "include/CTypedef.h" 1 +# 11 "test.cpp" 2 +# 1 "include/CLog.h" 1 +# 12 "test.cpp" 2 + + +using std::cout; +using std::endl; + +void check() +{ + cout << endl << "------------------ Check Message Queue--------------------" << endl; + cout << " ------- M_MessageQueue ------- " << endl; + cout << "队列空: " << CMessageQueue::Instance()->empty() << " ," + << "长度: " << CMessageQueue::Instance()->size() << " ," + << "队头: " << CMessageQueue::Instance()->front() << " ," + << "队尾: " << CMessageQueue::Instance()->back() << endl; + cout << " ------ MQT_SYSTEM_STATE_E ------ " << endl; + cout << "队列空: " << CMessageQueue::Instance()->empty(MQT_SYSTEM_STATE_E) << " ," + << "长度: " << CMessageQueue::Instance()->size(MQT_SYSTEM_STATE_E) << " ," + << "队头: " << CMessageQueue::Instance()->front(MQT_SYSTEM_STATE_E) << " ," + << "队尾: " << CMessageQueue::Instance()->back(MQT_SYSTEM_STATE_E) << endl; + cout << " ----- MQT_PROCESS_STATE_E ------ " << endl; + cout << "队列空: " << CMessageQueue::Instance()->empty(MQT_PROCESS_STATE_E) << " ," + << "长度: " << CMessageQueue::Instance()->size(MQT_PROCESS_STATE_E) << " ," + << "队头: " << CMessageQueue::Instance()->front(MQT_PROCESS_STATE_E) << " ," + << "队尾: " << CMessageQueue::Instance()->back(MQT_PROCESS_STATE_E) << endl; + cout << " ------- MQT_FILE_STATE_E ------- " << endl; + cout << "队列空: " << CMessageQueue::Instance()->empty(MQT_FILE_STATE_E) << " ," + << "长度: " << CMessageQueue::Instance()->size(MQT_FILE_STATE_E) << " ," + << "队头: " << CMessageQueue::Instance()->front(MQT_FILE_STATE_E) << " ," + << "队尾: " << CMessageQueue::Instance()->back(MQT_FILE_STATE_E) << endl; + cout << " -------- MQT_FILE_NUM_E -------- " << endl ; + cout << "队列空: " << CMessageQueue::Instance()->empty(MQT_FILE_NUM_E) << " ," + << "长度: " << CMessageQueue::Instance()->size(MQT_FILE_NUM_E) << " ," + << "队头: " << CMessageQueue::Instance()->front(MQT_FILE_NUM_E) << " ," + << "队尾: " << CMessageQueue::Instance()->back(MQT_FILE_NUM_E) << endl; + + cout << " ------ MQT_SYSTEM_LOG_E ------ " << endl; + cout << "队列空: " << CMessageQueue::Instance()->empty(MQT_SYSTEM_LOG_E) << " ," + << "长度: " << CMessageQueue::Instance()->size(MQT_SYSTEM_LOG_E) << " ," + << "队头: " << CMessageQueue::Instance()->front(MQT_SYSTEM_LOG_E) << " ," + << "队尾: " << CMessageQueue::Instance()->back(MQT_SYSTEM_LOG_E) << endl; + cout << endl << "------------------------- FINISH -------------------------" << endl; +} + +int main() +{ + cout << "step1: 默认队列入队3元素: 1 2 3" << endl; + for(int i=1;i<4;i++) + { + CMessageQueue::Instance()->push(i); + } + check(); + + cout << "step2: MQT_SYSTEM_STATE_E 队列入队3元素: 1 2 3" << endl; + for(int i=1;i<4;i++) + { + CMessageQueue::Instance()->push(i,MQT_SYSTEM_STATE_E); + } + check(); + + cout << "step3: MQT_PROCESS_STATE_E 队列入队3元素: 1 2 3" << endl; + for(int i=1;i<4;i++) + { + CMessageQueue::Instance()->push(i, MQT_PROCESS_STATE_E); + } + check(); + + cout << "step4: MQT_FILE_STATE_E 队列入队3元素: 1 2 3" << endl; + for(int i=1;i<4;i++) + { + CMessageQueue::Instance()->push(i, MQT_FILE_STATE_E); + } + check(); + + cout << "step5: MQT_FILE_NUM_E 队列入队3元素: 1 2 3" << endl; + for(int i=1;i<4;i++) + { + CMessageQueue::Instance()->push(i, MQT_FILE_NUM_E); + } + check(); + + cout << "step6: MQT_SYSTEM_LOG_E 队列入队3元素: 1 2 3" << endl; + for(int i=1;i<4;i++) + { + CMessageQueue::Instance()->push(i, MQT_SYSTEM_LOG_E); + sleep(1); + } + check(); + + + return 0; +} diff --git a/study_clang/Mimic/test_schedule/Makefile b/study_clang/Mimic/test_schedule/Makefile new file mode 100644 index 0000000..5a8148e --- /dev/null +++ b/study_clang/Mimic/test_schedule/Makefile @@ -0,0 +1,44 @@ + +ARCH ?= +CC = $(ARCH)g++ +STRIP = $(ARCH)strip + +#以下同根目录下的makefile的相同代码的解释 +INC_DIR=./include ../common +DIR_SRC=./src +OBJS_DIR=./obj +LD_DIR= + + +TARGETS=./test_schedule + +CUR_SOURCE=$(wildcard ${DIR_SRC}/*.cpp) +CFLAGS += $(foreach dir,$(INC_DIR),-I$(dir)) +CUR_OBJS = $(patsubst $(DIR_SRC)/%.cpp, $(OBJS_DIR)/%.o, $(CUR_SOURCE)) + +CFLAGS += -Wall -std=c++11 -g +LD=-lpthread $$(mysql_config --cflags --libs) -lzmq + +all:$(TARGETS) +$(OBJS_DIR)/%.o : $(DIR_SRC)/%.cpp + @mkdir -p $(OBJS_DIR) + @$(CC) $(CFLAGS) -c $< -o $@ + @echo $(CC) $(CFLAGS) "-c" $(notdir $<) "-o" $(notdir $@) + +$(TARGETS): $(CUR_OBJS) + @$(CC) $(CUR_OBJS) -o $(TARGETS) -L$(LD_DIR) $(LD) +#@$(STRIP) $(TARGETS) + +clean: + @rm -rf $(CUR_OBJS) + @rm -rf $(TARGETS) + @rm -rf $(OBJS_DIR) + +install: + $(INSTALL) $(TARGETS) $(BIN_DIR) + +print: + @echo $(CC) $(CFLAGS) + @echo $(CUR_OBJS) + @echo $(CUR_SOURCE) + diff --git a/study_clang/Mimic/test_schedule/include/CConfig.h b/study_clang/Mimic/test_schedule/include/CConfig.h new file mode 100644 index 0000000..3d0a19f --- /dev/null +++ b/study_clang/Mimic/test_schedule/include/CConfig.h @@ -0,0 +1,132 @@ +/************************************************************************* + > File Name : CConfig.h + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Fri 17 Jul 2020 09:31:50 AM CST + ************************************************************************/ + +#include +#include +#include +#include +#include "CJudgeUtils.h" +#include "CTypedef.h" + +class Config : public CSingleton +{ +public: + Config() {} + virtual ~Config() {} +public: + + void Init(const std::string& file_name) + { + INIReader reader; + reader.Parse(file_name); + + std::string strNosIdx; + for(int i = 0; i < NOS_MAX_NUM; i++) + { + strNosIdx.clear(); + strNosIdx = "nos" + std::to_string((i + 1)) + "_ip"; + nos_ip[i] = reader.Get("judge", strNosIdx, strNosIdx); + } + + #define _GET_JUDGE_CFG(value) value = reader.GetInt32("judge", #value, value) + _GET_JUDGE_CFG(schedule_port); + _GET_JUDGE_CFG(pluginsctrl_port); + _GET_JUDGE_CFG(sub_nos_state_port); + _GET_JUDGE_CFG(nos_num); + _GET_JUDGE_CFG(running_num); + + #undef _GET_JUDGE_CFG + + #define _GET_JUDGE_CFG(value) value = reader.Get("judge", #value, value) + _GET_JUDGE_CFG(config_manager_ip); + _GET_JUDGE_CFG(schedule_ip); + _GET_JUDGE_CFG(pluginsctrl_ip); + + #undef _GET_JUDGE_CFG + + // Judge_sys_info + #define _GET_JUDGE_SYS_INFO_CFG(value) value = reader.GetInt32("judge_sys_info", #value, value) + _GET_JUDGE_SYS_INFO_CFG(nos_report_port); + _GET_JUDGE_SYS_INFO_CFG(msg_time_out); + _GET_JUDGE_SYS_INFO_CFG(cpu_occupy_max); + _GET_JUDGE_SYS_INFO_CFG(mem_occupy_max); + _GET_JUDGE_SYS_INFO_CFG(tcp_socket_max); + _GET_JUDGE_SYS_INFO_CFG(process_max); + _GET_JUDGE_SYS_INFO_CFG(cron_max); + _GET_JUDGE_SYS_INFO_CFG(path_file_max); + _GET_JUDGE_SYS_INFO_CFG(home_file_max); + _GET_JUDGE_SYS_INFO_CFG(process_running_code); + + #undef _GET_JUDGE_SYS_INFO_CFG + + #define _GET_JUDGE_SYS_INFO_CFG(value) value = reader.Get("judge_sys_info", #value, value) + _GET_JUDGE_SYS_INFO_CFG(sys_shell_log_name); + _GET_JUDGE_SYS_INFO_CFG(sys_login_log_name); + _GET_JUDGE_SYS_INFO_CFG(user_md5); + _GET_JUDGE_SYS_INFO_CFG(group_md5); + _GET_JUDGE_SYS_INFO_CFG(config_manager_md5); + _GET_JUDGE_SYS_INFO_CFG(auto_start_md5); + _GET_JUDGE_SYS_INFO_CFG(process_manager_name); + _GET_JUDGE_SYS_INFO_CFG(process_protocol_name); + _GET_JUDGE_SYS_INFO_CFG(process_local_cfgm_name); + _GET_JUDGE_SYS_INFO_CFG(process_firewall_name); + + #undef _GET_JUDGE_SYS_INFO_CFG + + #define _GET_JUDGE_CFG(value) value = reader.GetInt32("trans", #value, value) + _GET_JUDGE_CFG(trans_send_port); + _GET_JUDGE_CFG(trans_recv_port); + + #undef _GET_JUDGE_CFG + + #define _GET_JUDGE_CFG(value) value = reader.Get("trans", #value, value) + _GET_JUDGE_CFG(trans_send_ip); + + #undef _GET_JUDGE_CFG + } + + std::string nos_ip[NOS_MAX_NUM]; + std::string config_manager_ip; + std::string schedule_ip; + std::string pluginsctrl_ip; + + std::string trans_send_ip; + + int sub_nos_state_port; + int schedule_port; + int pluginsctrl_port; + int nos_num; + int running_num; + + // Judge_sys_info + std::string sys_shell_log_name; + std::string sys_login_log_name; + std::string process_manager_name; + std::string process_protocol_name; + std::string process_local_cfgm_name; + std::string process_firewall_name; + + std::string user_md5; + std::string group_md5; + std::string config_manager_md5; + std::string auto_start_md5; + + int nos_report_port; + int msg_time_out; + int cpu_occupy_max; + int mem_occupy_max; + int tcp_socket_max; + int process_max; + int cron_max; + int path_file_max; + int home_file_max; + + int process_running_code; + + int trans_send_port; + int trans_recv_port; +}; diff --git a/study_clang/Mimic/test_schedule/include/CJudgeConf.h b/study_clang/Mimic/test_schedule/include/CJudgeConf.h new file mode 100644 index 0000000..1e90788 --- /dev/null +++ b/study_clang/Mimic/test_schedule/include/CJudgeConf.h @@ -0,0 +1,49 @@ +/************************************************************************* + > File Name : ../include/CJudge.h + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Thu 16 Jul 2020 11:33:38 AM CST + ************************************************************************/ + +#ifndef CJUDGE_H +#define CJUDGE_H + +#include +#include "CTypedef.h" +#include "CJudgeUtils.h" + +typedef std::map > CACHE_MAP; +typedef std::vector MSG_VEC; + +struct MsgGroup +{ + CACHE_MAP cache_map; // 一组执行体消息的对比缓存 + MSG_VEC msg_vec; // 一组执行体消息源 + time_t start_ms; // 一组新消息进入起始时间 + unsigned int uiPort; // 一组消息的端口 +}; + +class JudgeConf : public CSingleton +{ +public: + JudgeConf() { } + virtual ~JudgeConf() { } + +public: + void Init(int _nos_num, int _running_num); + void Judge(); + +private: + std::map group_map; // 按iCmd划分消息组,nos端口相同 + + int nos_num; + int running_num; + + int nos_status; // 各个nos是否running TODO + +private: + int GetCacheNosNum(CACHE_MAP& map); + +}; + +#endif diff --git a/study_clang/Mimic/test_schedule/include/CJudgeSysInfo.h b/study_clang/Mimic/test_schedule/include/CJudgeSysInfo.h new file mode 100644 index 0000000..79a05c1 --- /dev/null +++ b/study_clang/Mimic/test_schedule/include/CJudgeSysInfo.h @@ -0,0 +1,130 @@ +/************************************************************************* + > File Name : CJudgeSysInfo.h + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Fri 17 Jul 2020 09:47:20 AM CST + ************************************************************************/ + +#ifndef CJUDGE_SYS_INFO_H +#define CJUDGE_SYS_INFO_H + + +#include "CTypedef.h" +#include "CJudgeUtils.h" +#include +#include "CZeroMQ.h" + +#define MAX_MSG_BUFFER 1024 // 通信消息缓存区 +#define getbit(x,y) ((x) >> (y)&1) +#define setbit(x,y) x|=(1< SysState_MV; +typedef std::vector SysLog_MV; + +typedef struct +{ + SysState_MV sys_state_mv; + time_t start_ms; +}SysState_Group; + +typedef struct +{ + SysLog_MV sys_log_mv; + time_t start_ms; +}SysLog_Group; +*/ +class CJudgeSysInfo : public CSingleton +{ +public: + CJudgeSysInfo(); + virtual ~CJudgeSysInfo(); +public: + void Init(); + void RcvNosStateMessage(); + void Judge(); + int GetNosRunning(int nos_id); +private: + void JudgeSysState(std::vector& sys_state_v, uint& nos_time_out_bit); + void JudgeProcessState(); + void JudgeFileState(); + void JudgeFileNum(); + void JudgeSysLog(std::vector& SysShellLog_MV, std::vector& SysLoginLog_MV); + + int JudgeCpuOccupy(uint cpu_occupy, uint nos_id); + int JudgeMemOccupy(uint mem_occupy, uint nos_id); + int JudgeTcpSocket(uint tcp_establish_num, uint nos_id); + int JudgeProcessNum(uint running_process, uint nos_id); + void JudgeLoginLog(std::vector& SysLoginLog_CMV); + void JudgeShellLog(std::vector& SysShellLog_CMV); + int JudgeUserInfo(char passwd_md5[64], uint nos_id); + int JudgeGroupInfo(char group_md5[64], uint nos_id); + int JudgeCronNum(uint cron_num, uint nos_id); + void JudgePathFileNum(); + void JudgeHomeFileNum(); + void JudgeAppMd5(); + void JudgeAutoStartMd5(); + void JudgeManagerProgress(); + void JudgeProtocolProgress(); + void JudgeLocalConfigManager(); + void JudgeFirewell(); + + int SendDataToShd(const void *pvData, unsigned int uiDataLen); + int RecvDataFromShd(void *pvBuff, unsigned int uiBuffLen); + + // 消息解析函数 + SysState_T SplitMsgToSysState(char *buffer, int len_Buffer); + ProcessState_T SplitMsgToProcessState(char *buffer, int len_Buffer); + FileState_T SplitMsgToFileState(char *buffer, int len_Buffer); + FileNum_T SplitMsgToFileNum(char *buffer, int len_Buffer); + SysLog_T SplitMsgToSysLog(char *buffer, int len_Buffer); + + uint GetNosId(char ip[32]); + +private: + // 全局标志位 + uint nos_running_bit; + // 配置 + int nos_report_port; + int schedule_port; + int msg_time_out; + int nos_num; + uint running_num; + std::string schedule_ip; + + SysState_T m_SysState; // 系统运行状态消息 + ProcessState_T m_ProcessState; // 关键进程状态消息 + FileState_T m_FileState; // 关键文件状态消息 + FileNum_T m_FileNum; // 关键文件数量消息 + SysLog_T m_SysLog; // 关键日志增量消息 + + // Judge_sys_info + std::string sys_shell_log_name; + std::string sys_login_log_name; + std::string process_manager_name; + std::string process_protocol_name; + std::string process_local_cfgm_name; + std::string process_firewall_name; + + std::string user_md5; + std::string group_md5; + std::string config_manager_md5; + std::string auto_start_md5; + + uint cpu_occupy_max; + uint mem_occupy_max; + uint tcp_socket_max; + uint process_max; + uint cron_max; + uint path_file_max; + uint home_file_max; + + uint process_running_code; + + // ZeroMQ Connect + CZMQReqRep *m_pShdClient; + CZMQReqRep *m_pNosServer; +}; + + +#endif diff --git a/study_clang/Mimic/test_schedule/include/CJudgeUtils.h b/study_clang/Mimic/test_schedule/include/CJudgeUtils.h new file mode 100644 index 0000000..e254f2d --- /dev/null +++ b/study_clang/Mimic/test_schedule/include/CJudgeUtils.h @@ -0,0 +1,140 @@ +/************************************************************************* + > File Name : CJudgeUtils.h + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Fri 17 Jul 2020 09:34:47 AM CST + ************************************************************************/ + +#ifndef _JUDGE_COMMON_H_ +#define _JUDGE_COMMON_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "CLog.h" + +class CNonCopyable +{ +protected: + CNonCopyable() {} + ~CNonCopyable() {} +private: + CNonCopyable(const CNonCopyable &); + const CNonCopyable& operator=(const CNonCopyable &); +}; + +class CMutexLockGuard:CNonCopyable +{ + public: + explicit CMutexLockGuard(pthread_mutex_t& mutex) + : m_mutex(mutex) + { + pthread_mutex_lock(&m_mutex); + } + + ~CMutexLockGuard() + { + pthread_mutex_unlock(&m_mutex); + } + +private: + pthread_mutex_t& m_mutex; +}; + +template +class CSingleton +{ +private: + static std::once_flag SingletonFlag; + static std::unique_ptr Instance; + +protected: + CSingleton() = default; + CSingleton(const T&) = delete; + CSingleton& operator=(const T&) = delete; + +public: + static T& GetInstance() + { + std::call_once(SingletonFlag, [=]() { + Instance.reset(new T); + }); + + return *(Instance.get()); + } +}; + +template std::unique_ptr CSingleton ::Instance = nullptr; +template std::once_flag CSingleton ::SingletonFlag; + +class INIReader +{ +public: + explicit INIReader() {} + ~INIReader() {} + + /// @brief 解析文件 + /// @return 0 成功 + /// @return <0 失败 + /// @note 每次调用会清除上一次的解析结果 + int32_t Parse(const std::string& filename); + + void Clear(); + + /// @brief 获取string类型字段的值,字段未配置时使用默认值 + std::string Get(const std::string& section, const std::string& name, + const std::string& default_value); + + // Get an integer (long) value from INI file, returning default_value + // if not found or not a valid integer (decimal "1234", "-1234", + // or hex "0x4d2"). + int32_t GetInt32(const std::string& section, const std::string& name, + int32_t default_value); + + uint32_t GetUInt32(const std::string& section, const std::string& name, + uint32_t default_value); + + int64_t GetInt64(const std::string& section, const std::string& name, + int64_t default_value); + + uint64_t GetUInt64(const std::string& section, const std::string& name, + uint64_t default_value); + + // Get a real (floating point double) value from INI file, returning + // default_value if not found or not a valid floating point value + // according to strtod(). + double GetReal(const std::string& section, const std::string& name, double default_value); + + // Get a boolean value from INI file, returning default_value + // if not found or if not a valid true/false value. Valid true + // values are "true", "yes", "on", "1", and valid false values are + // "false", "no", "off", "0" (not case sensitive). + bool GetBoolean(const std::string& section, const std::string& name, bool default_value); + + // Returns all the section names from the INI file, in alphabetical order, + // but in the original casing + const std::set& GetSections() const; + + // Returns all the field names from a section in the INI file, in + // alphabetical order, but in the original casing. Returns an + // empty set if the field name is unknown + std::set GetFields(const std::string& section); + + /// @brief 返回最后错误字符串描述 + /// @return 最后一次错误的信息 + const char* GetLastError() const { return m_last_error; } +private: + int32_t ParseFile(FILE* file); +private: + char m_last_error[256]; + std::set m_sections; + std::map > m_fields; +}; + +#endif diff --git a/study_clang/Mimic/test_schedule/include/CLog.h b/study_clang/Mimic/test_schedule/include/CLog.h new file mode 100644 index 0000000..e8c6c20 --- /dev/null +++ b/study_clang/Mimic/test_schedule/include/CLog.h @@ -0,0 +1,93 @@ +/************************************************************************* + > File Name : CLog.h + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Fri 17 Jul 2020 09:33:22 AM CST + ************************************************************************/ + #ifndef CLOG_H + #define CLOG_H + +#include +#include +#include +#include +#include +#include +#include +#include + + +//颜色宏定义 +#define NONE "\033[m" +#define RED "\033[0;32;31m" +#define LIGHT_RED "\033[1;31m" +#define GREEN "\033[0;32;32m" +#define LIGHT_GREEN "\033[1;32m" +#define BLUE "\033[0;32;34m" +#define LIGHT_BLUE "\033[1;34m" +#define DARY_GRAY "\033[1;30m" +#define CYAN "\033[0;36m" +#define LIGHT_CYAN "\033[1;36m" +#define PURPLE "\033[0;35m" +#define LIGHT_PURPLE "\033[1;35m" +#define BROWN "\033[0;33m" +#define YELLOW "\033[1;33m" +#define LIGHT_GRAY "\033[0;37m" +#define WHITE "\033[1;37m" + +#define PRO_NAME "JUDGE" +#define _FUN_ __FUNCTION__ + +typedef enum tagLogLevel +{ + FATAL = 0, + ALERT, + ERROR, + WARN, + NOTICE, + INFO, + DEBUG +} CYBERER_LOG_LEVEL_E; + + +/* + * priorities/facilities are encoded into a single 32-bit quantity, where the + * bottom 3 bits are the priority (0-7) and the top 28 bits are the facility + * (0-big number). Both the priorities and the facilities map roughly + * one-to-one to strings in the syslogd(8) source code. This mapping is + * included in this file. + * + * priorities (these are ordered) + * + * #define LOG_EMERG 0 // system is unusable / + * #define LOG_ALERT 1 // action must be taken immediately / + * #define LOG_CRIT 2 // critical conditions / + * #define LOG_ERR 3 // error conditions / + * #define LOG_WARNING 4 // warning conditions / + * #define LOG_NOTICE 5 // normal but significant condition / + * #define LOG_INFO 6 // informational / + * #define LOG_DEBUG 7 // debug-level messages / +*/ +#define SLOG_EMERG LOG_EMERG /* system is unusable */ +#define SLOG_ALERT LOG_ALERT /* action must be taken immediately */ +#define SLOG_CRIT LOG_CRIT /* critical conditions */ +#define SLOG_ERR LOG_ERR /* error conditions */ +#define SLOG_WARNING LOG_WARNING /* warning conditions */ +#define SLOG_NOTICE LOG_NOTICE /* normal but significant condition */ +#define SLOG_INFO LOG_INFO /* informational */ +#define SLOG_DEBUG LOG_DEBUG /* debug-level messages */ +#define SysLog(_level, fmt, ...) \ + do{openlog("[JUDGE]", LOG_NDELAY | LOG_CONS | LOG_PID | LOG_PERROR , LOG_LOCAL5); \ + syslog(_level, "[%s:%d] " fmt "", __FILE__, __LINE__, ##__VA_ARGS__); \ + closelog();}while(0) + +extern void LogPrint(const int level,const char *proName,const char *func,const int line,const char *format, ...); +extern void BufPrint(const char *func,const int line, const char *pData, int iDataLen); + +#define cPrint(fmt, ...) do{fprintf(stderr, PRO_NAME "[%s:%d] " fmt "\r\n", __FILE__, __LINE__, ##__VA_ARGS__);}while(0) +#define dPrint(fmt, ...) do{fprintf(stderr, YELLOW PRO_NAME "[%s:%d] " fmt "\r\n" NONE, __FILE__, __LINE__, ##__VA_ARGS__);}while(0) +#define lPrint(DLevel, format, ...) LogPrint(DLevel, PRO_NAME, __FILE__, __LINE__,format, ##__VA_ARGS__) +#define bufPrint(pData, iDataLen) BufPrint(__FILE__, __LINE__, (const char *)pData, (int)iDataLen) + +#endif + diff --git a/study_clang/Mimic/test_schedule/include/CMain.h b/study_clang/Mimic/test_schedule/include/CMain.h new file mode 100644 index 0000000..a1b3d19 --- /dev/null +++ b/study_clang/Mimic/test_schedule/include/CMain.h @@ -0,0 +1,42 @@ +/************************************************************************* + > File Name : ../include/CMain.h + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Thu 16 Jul 2020 11:32:23 AM CST + ************************************************************************/ + +#ifndef CMAIN_H +#define CMAIN_H + + #include "CJudgeUtils.h" + +class CMain : public CSingleton +{ +public: + CMain(); + virtual ~CMain(); +public: + + void Init(); + int MainProcess(); + int ReleaseSource(); + +private: + int StartThreadTasks(); + + static void *NosHostConfMsgRcvThread(void *args); + static void *NosKernelConfMsgRcvThread(void *args); + static void *NosStateRcvThread(void *args); + static void *NosSysInfoRcvThread(void *args); + static void *NosSysInfoJudgeThread(void *args); + static void *SendPluginsCtrlThread(void *args); + static void *TransNosHostDataThread(void *args); + static void *TransNosKernelDataThread(void *args); + static void *TransDataToOtherThread(void *args); + +}; + + +#endif + + diff --git a/study_clang/Mimic/test_schedule/include/CMessageQueue.h b/study_clang/Mimic/test_schedule/include/CMessageQueue.h new file mode 100644 index 0000000..bed5e49 --- /dev/null +++ b/study_clang/Mimic/test_schedule/include/CMessageQueue.h @@ -0,0 +1,245 @@ +/************************************************************************* + > File Name : ../include/CMessageQueue.h + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Thu 16 Jul 2020 11:35:11 AM CST + ************************************************************************/ + +#ifndef CMESSAGEQUEUE_H +#define CMESSAGEQUEUE_H +#include "CTypedef.h" +#include "CJudgeUtils.h" + +template +class CMessageQueue : public CSingleton > +{ +public: + CMessageQueue(); + virtual ~CMessageQueue(); +public: + + void push(T stData,Message_QueueType_E MessageType = m_MessageTypeE); + void pop(Message_QueueType_E MessageType = m_MessageTypeE); + T& front(Message_QueueType_E MessageType = m_MessageTypeE); + T& back(Message_QueueType_E MessageType = m_MessageTypeE); + int empty(Message_QueueType_E MessageType = m_MessageTypeE); + uint size(Message_QueueType_E MessageType = m_MessageTypeE); + void remove(T stData, Message_QueueType_E MessageType = m_MessageTypeE); + +private: + + +private: + static const Message_QueueType_E m_MessageTypeE = MQT_CONFIG_E; + + pthread_mutex_t m_QueueMutex; + std::list m_queue; + + pthread_mutex_t ss_QueueMutex; + std::list q_SysState; + + pthread_mutex_t ps_QueueMutex; + std::list q_ProcessState; + + pthread_mutex_t fs_QueueMutex; + std::list q_FileState; + + pthread_mutex_t fn_QueueMutex; + std::list q_FileNum; + + pthread_mutex_t sl_QueueMutex; + std::list q_SysLog; +}; + + +template +CMessageQueue::CMessageQueue() +{ + pthread_mutex_init(&m_QueueMutex, NULL); + + pthread_mutex_init(&ss_QueueMutex, NULL); + pthread_mutex_init(&ps_QueueMutex, NULL); + pthread_mutex_init(&fs_QueueMutex, NULL); + pthread_mutex_init(&fn_QueueMutex, NULL); + pthread_mutex_init(&sl_QueueMutex, NULL); +} + +template +CMessageQueue::~CMessageQueue() +{ + pthread_mutex_destroy(&m_QueueMutex); + + pthread_mutex_destroy(&ss_QueueMutex); + pthread_mutex_destroy(&ps_QueueMutex); + pthread_mutex_destroy(&fs_QueueMutex); + pthread_mutex_destroy(&fn_QueueMutex); + pthread_mutex_destroy(&sl_QueueMutex); +} + +template +void CMessageQueue::push(T stData,Message_QueueType_E MessageType) +{ + switch(MessageType) + { +#define _MQT_PUSH(type, q, lock) \ + case MQT_##type##_E: \ + { \ + CMutexLockGuard MutexLock(lock##_QueueMutex); \ + q.push_back(stData); \ + break;\ + } + _MQT_PUSH(CONFIG, m_queue, m); + _MQT_PUSH(SYS_STATE, q_SysState, ss); + _MQT_PUSH(PROCESS_STATE, q_ProcessState, ps); + _MQT_PUSH(FILE_STATE, q_FileState, fs); + _MQT_PUSH(FILE_NUM, q_FileNum, fn); + _MQT_PUSH(SYS_LOG, q_SysLog, sl); +#undef _MQT_PUSH + default: + break; + } +} + +template +void CMessageQueue::pop(Message_QueueType_E MessageType) +{ + switch(MessageType) + { +#define _MQT_POP(type, q, lock ) \ + case MQT_##type##_E: \ + { \ + CMutexLockGuard MutexLock(lock##_QueueMutex); \ + q.pop_front(); \ + break; \ + } + _MQT_POP(CONFIG, m_queue, m); + _MQT_POP(SYS_STATE, q_SysState, ss); + _MQT_POP(PROCESS_STATE, q_ProcessState, ps); + _MQT_POP(FILE_STATE, q_FileState, fs); + _MQT_POP(FILE_NUM, q_FileNum, fn); + _MQT_POP(SYS_LOG, q_SysLog, sl); +#undef _MQT_POP + default: + break; + } + +} + +template +T& CMessageQueue::front(Message_QueueType_E MessageType) +{ + switch(MessageType) + { +#define _MQT_FRONT(type, q, lock) \ + case MQT_##type##_E: \ + { \ + CMutexLockGuard MutexLock(lock##_QueueMutex); \ + return q.front(); \ + } + _MQT_FRONT(CONFIG, m_queue, m); + _MQT_FRONT(SYS_STATE, q_SysState, ss); + _MQT_FRONT(PROCESS_STATE, q_ProcessState, ps); + _MQT_FRONT(FILE_STATE, q_FileState, fs); + _MQT_FRONT(FILE_NUM, q_FileNum, fn); + _MQT_FRONT(SYS_LOG, q_SysLog, sl); +#undef _MQT_FRONT + default: + return m_queue.front(); + } + +} + +template +T& CMessageQueue::back(Message_QueueType_E MessageType) +{ + switch(MessageType) + { +#define _MQT_BACK(type, q, lock) \ + case MQT_##type##_E: \ + { \ + CMutexLockGuard MutexLock(lock##_QueueMutex); \ + return q.back(); \ + } + _MQT_BACK(CONFIG, m_queue, m); + _MQT_BACK(SYS_STATE, q_SysState, ss); + _MQT_BACK(PROCESS_STATE, q_ProcessState, ps); + _MQT_BACK(FILE_STATE, q_FileState, fs); + _MQT_BACK(FILE_NUM, q_FileNum, fn); + _MQT_BACK(SYS_LOG, q_SysLog, sl); +#undef _MQT_BACK + default: + return m_queue.back(); + } +} + +template +int CMessageQueue::empty(Message_QueueType_E MessageType) +{ + switch(MessageType) + { +#define _MQT_EMPTY(type, q, lock) \ + case MQT_##type##_E: \ + { \ + CMutexLockGuard MutexLock(lock##_QueueMutex); \ + return q.empty(); \ + } + _MQT_EMPTY(CONFIG, m_queue, m); + _MQT_EMPTY(SYS_STATE, q_SysState, ss); + _MQT_EMPTY(PROCESS_STATE, q_ProcessState, ps); + _MQT_EMPTY(FILE_STATE, q_FileState, fs); + _MQT_EMPTY(FILE_NUM, q_FileNum, fn); + _MQT_EMPTY(SYS_LOG, q_SysLog, sl); +#undef _MQT_EMPTY + default: + return 0; + } + return 0; +} + +template +uint CMessageQueue::size(Message_QueueType_E MessageType) +{ + switch(MessageType) + { +#define _MQT_SIZE(type, q, lock) \ + case MQT_##type##_E: \ + { \ + CMutexLockGuard MutexLock(lock##_QueueMutex); \ + return q.size(); \ + } + _MQT_SIZE(CONFIG, m_queue, m); + _MQT_SIZE(SYS_STATE, q_SysState, ss); + _MQT_SIZE(PROCESS_STATE, q_ProcessState, ps); + _MQT_SIZE(FILE_STATE, q_FileState, fs); + _MQT_SIZE(FILE_NUM, q_FileNum, fn); + _MQT_SIZE(SYS_LOG, q_SysLog, sl); +#undef _MQT_SIZE + default: + return 0; + } +} + +template +void CMessageQueue::remove(T stData, Message_QueueType_E MessageType) +{ + switch(MessageType) + { +#define _MQT_REMOVE(type, q, lock) \ + case MQT_##type##_E: \ + { \ + CMutexLockGuard MutexLock(lock##_QueueMutex); \ + return q.remove(stData); \ + } + _MQT_REMOVE(CONFIG, m_queue, m); + _MQT_REMOVE(SYS_STATE, q_SysState, ss); + _MQT_REMOVE(PROCESS_STATE, q_ProcessState, ps); + _MQT_REMOVE(FILE_STATE, q_FileState, fs); + _MQT_REMOVE(FILE_NUM, q_FileNum, fn); + _MQT_REMOVE(SYS_LOG, q_SysLog, sl); +#undef _MQT_REMOVE + default: + break; + } +} +#endif + diff --git a/study_clang/Mimic/test_schedule/include/CMysqlPool.h b/study_clang/Mimic/test_schedule/include/CMysqlPool.h new file mode 100644 index 0000000..18075a2 --- /dev/null +++ b/study_clang/Mimic/test_schedule/include/CMysqlPool.h @@ -0,0 +1,98 @@ +/************************************************************************* + > File Name : CMysqlPool.h + > Author : liuzhao + > EMail : liuzhao@comleader.com.cn + > Created Time : Fri 17 Jul 2020 09:40:09 AM CST + ************************************************************************/ + +#ifndef MYSQLPOOL_H +#define MYSQLPOOL_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "CJudgeUtils.h" + +struct MysqlResults +{ + int field_count; + int record_count; + std::vector> value; + std::vector field_name; + + MysqlResults() : field_count(0), record_count(0) {} + void Print() + { + std::cout << "[field_count:" << field_count << "]" << std::endl; + std::cout << "[record_count:" << record_count << "]" << std::endl; + int i = 0; + std::cout << "[field]" << "\t"; + for (auto v : field_name) + { + std::cout << v << "\t"; + } + std::cout << std::endl; + + for (auto v : value) + { + int j = 0; + std::cout << "[row:" << i << "]" << "\t"; + for (auto x : v) + { + std::cout << x << "\t"; + j++; + } + std::cout << std::endl; + i ++; + } + } +}; + +class MysqlPool : public CSingleton +{ +public: + MysqlPool(); + virtual ~MysqlPool(); + +public: + void executeSql(MysqlResults& results, const char* sql);//sql语句的执行函数 + void setParameter( const char* _mysqlhost, + const char* _mysqluser, + const char* _mysqlpwd, + const char* _databasename, + unsigned int _port = 0, + const char* _socket = NULL, + unsigned long _client_flag = 0, + unsigned int MAX_CONNECT = 50 ); //设置数据库参数 + private: + MYSQL* createOneConnect(); //创建一个新的连接对象 + MYSQL* getOneConnect(); //获取一个连接对象 + void close(MYSQL* conn); //关闭连接对象 + bool isEmpty(); //连接池队列池是否为空 + MYSQL* poolFront(); //连接池队列的队头 + unsigned int poolSize(); //获取连接池的大小 + void poolPop(); //弹出连接池队列的队头 + private: + std::queue mysqlpool; //连接池队列 + const char* _mysqlhost; //mysql主机地址 + const char* _mysqluser; //mysql用户名 + const char* _mysqlpwd; //mysql密码 + const char* _databasename; //要使用的mysql数据库名字 + unsigned int _port; //mysql端口 + const char* _socket; //可以设置成Socket or Pipeline,通常设置为NULL + unsigned long _client_flag; //设置为0 + unsigned int MAX_CONNECT; //同时允许最大连接对象数量 + unsigned int connect_count; //目前连接池的连接对象数量 + static std::mutex objectlock; //对象锁 + static std::mutex poollock; //连接池锁 + static MysqlPool* mysqlpool_object; //类的对象 +}; + +#endif diff --git a/study_clang/Mimic/test_schedule/include/CNetManager.h b/study_clang/Mimic/test_schedule/include/CNetManager.h new file mode 100644 index 0000000..b7aa233 --- /dev/null +++ b/study_clang/Mimic/test_schedule/include/CNetManager.h @@ -0,0 +1,101 @@ +/************************************************************************* + > File Name : CNetManager.h + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Fri 17 Jul 2020 09:31:31 AM CST + ************************************************************************/ + +#ifndef CNETMANAGER_H +#define CNETMANAGER_H + +#include +#include "CTypedef.h" +#include "CUdpServer.h" +#include "CUdpClient.h" +#include "CZeroMQ.h" +#include "CJudgeUtils.h" + +#define PORT_BIND_SET_HOST 10014 +#define PORT_BIND_GET_HOST 10013 +#define PORT_BIND_SET_KERNEL 10012 +#define PORT_BIND_GET_KERNEL 10011 + +#define PORT_SET_HOST 10004 +#define PORT_GET_HOST 10003 +#define PORT_SET_KERNEL 10002 +#define PORT_GET_KERNEL 10001 + +class CNetManager : public CSingleton +{ +public: + CNetManager(); + virtual ~CNetManager(); +public: + int RecvDataToConfManagerHost(void *pvBuff, unsigned int uiBuffLen); + int SendDataToConfManagerHost(const void *pvData, unsigned int uiDataLen); + + int RecvDataToConfManagerKernel(void *pvBuff, unsigned int uiBuffLen); + int SendDataToConfManagerKernel(const void *pvData, unsigned int uiDataLen); + + int SendHostDataToAllNos(const void *pvData, unsigned int uiDataLen); + int SendHostDataToNos(int iNosIdx, const void *pvData, unsigned int uiDataLen); + + int SendKernelDataToAllNos(const void *pvData, unsigned int uiDataLen); + int SendKernelDataToNos(int iNosIdx, const void *pvData, unsigned int uiDataLen); + + int SendDataToShd(const void *pvData, unsigned int uiDataLen); + int RecvDataFromShd(void *pvBuff, unsigned int uiBuffLen); + + int SendDataToPCtl(const void *pvData, unsigned int uiDataLen); + int RecvDataFromPCtl(void *pvBuff, unsigned int uiBuffLen); + + void RecvNosDataHost(); + void RecvNosDataKernel(); + + void RecvNosStateFromShd(); + int GetNosStateById(int iIdx); + + int SetNosNetInfoHost(unsigned int uiIdx, const SOCKADDR_IN_T *pstInfo); + int GetNosNetInfoHost(unsigned int uiIdx, SOCKADDR_IN_T *pstInfo); + + int SetNosNetInfoKernel(unsigned int uiIdx, const SOCKADDR_IN_T *pstInfo); + int GetNosNetInfoKernel(unsigned int uiIdx, SOCKADDR_IN_T *pstInfo); + + void TransNosHostData(); + void TransNosKernelData(); + void TransBroadcastDataToOther(); + + void SendPluginsCtrl(); + +private: + int GetNosIdxBySock(SOCKADDR_IN_T *pstSockAddrIn); + +private: + pthread_mutex_t m_NosNetInfoHostMutex; + pthread_mutex_t m_NosNetInfoKernelMutex; + + SOCKADDR_IN_T m_stNosNetInfoHost[NOS_MAX_NUM]; + SOCKADDR_IN_T m_stNosNetInfoKernel[NOS_MAX_NUM]; + + CUdpClient m_ConfigManagerHost; + CUdpClient m_ConfigManagerKernel; + + CUdpServer m_NosDataHost; + CUdpServer m_NosDataKernel; + + CZMQReqRep *m_pShdClient; + CZMQReqRep *m_pPCtlClient; + CZMQSubscriber *m_pNosStateSub; + + NosState_T m_stNosState[NOS_MAX_NUM]; + + CUdpServer m_NosHostTrans; + CUdpServer m_NosKernelTrans; + + CUdpServer m_BroadcastDataTrans; +}; + + +#endif /*CNETMANAGER_H*/ + + diff --git a/study_clang/Mimic/test_schedule/include/CSwitchCommon.h b/study_clang/Mimic/test_schedule/include/CSwitchCommon.h new file mode 100644 index 0000000..a42e772 --- /dev/null +++ b/study_clang/Mimic/test_schedule/include/CSwitchCommon.h @@ -0,0 +1,192 @@ +/************************************************************************* + > File Name : CSwitchCommon.h + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Thu 23 Jul 2020 09:13:37 AM CST + ************************************************************************/ + +#ifndef CSWITCHCOMMON_H +#define CSWITCHCOMMON_H + +#define MAX_NOS_NUM 8 + +typedef enum Judge_Error_Code_E +{ + JUDGE_ALL_SUCCESS=0, /*接收到所有执行体消息,全部一致*/ + /* + ----+----+----- + | A | B | C | 1、线上执行体为A/B/C + ----+----+----- + | 1 | 1 | 1 | 2、收到A/B/C全部一致的消息 + ----+----+----- + + uiNosIdx = 0; + */ + JUDGE_SUCC_WITH_TWO_STAGE, /*接收到所有执行体消息,有多数一致,但少数也一致*/ + /* + ----+----+---- + | A | B | C 1、线上执行体为A/B/C + ----+----+---- + | 1 | 1 | 2 2、收到的消息中,A/B全部一致 + ----+----+---- + + uiNosIdx = C; + */ + JUDGE_SUCC_WITH_MANY_STAGE, /*接收到所有执行体消息,有多数一致,但有多个少数群体*/ + /* + ----+----+----+----+----- + | A | B | C | D | E 1、线上执行体为A/B/C/D/E + ----+----+----+----+----- + | 1 | 1 | 1 | 2 | 3 2、收到的消息中,A/B/C全部一致,D/E不一致 + ----+----+----+----+----- + + uiNosIdx = D | E; + */ + JUDGE_SUCC_WITH_TIMEOUT, /*未收到所有执行体消息,全部一致*/ + /* + ----+----+----- + | A | B | C | 1、线上执行体为A/B/C + ----+----+----- + | 1 | 1 | | 2、收到A/B全部一致的消息,未收到C的消息 + ----+----+----- + + uiNosIdx = 1 << C; + */ + JUDGE_SUCC_WITH_TIMEOUT_TWO_STAGE, /*未收到所有执行体消息,有多数一致,但少数也一致*/ + /* + ----+----+----+----+----- + | A | B | C | D | E 1、线上执行体为A/B/C/D/E + ----+----+----+----+----- + | 1 | 1 | 1 | 2 | 2、收到的消息中,A/B/C全部一致,收到D的消息,E超时 + ----+----+----+----+----- + + uiNosIdx = D | E; + */ + JUDGE_SUCC_WITH_TIMEOUT_MANY_STAGE, /*未收到所有执行体消息,有多数一致,但有多个少数群体*/ + /* + ----+----+----+----+----+----+----- + | A | B | C | D | E | F | G 1、线上执行体为A/B/C/D/E/F/G + ----+----+----+----+----+----+----- + | 1 | 1 | 1 | 1 | 2 | 3 | 2、收到的消息中,A/B/C全部一致,D/E不一致,G超时 + ----+----+----+----+----+----+----- + + uiNosIdx = E | F | G; + */ + JUDGE_ALL_FAIL_WITH_DIFF, /*收到所有执行体消息,全部不一致*/ + /* + ----+----+----- + | A | B | C | 1、线上执行体为A/B/C + ----+----+----- + | 1 | 2 | 3 | 2、收到A/B/C的消息,但完全不同 + ----+----+----- + + uiNosIdx = A | B | C; + */ + JUDGE_FAIL_WITH_TWO_STAGE, /*收到所有执行体消息,分为数目相同的两个群体*/ + /* + ----+----+----+---- + | A | B | C | D 1、线上执行体为A/B/C/D + ----+----+----+---- + | 1 | 1 | 2 | 2 2、收到A/B/C/D的消息,A/B一致,C/D一致 + ----+----+----+---- + + uiNosIdx = A | B | C | D; + */ + JUDGE_FAIL_WITH_MANY_STAGE, /*收到所有执行体信息,分为多个少数群体*/ + /* + ----+----+----+----+----- + | A | B | C | D | E 1、线上执行体为A/B/C/D/E + ----+----+----+----+----- + | 1 | 1 | 2 | 2 | 3 2、收到的消息中,A/B全部一致,C/D全部一致 + ----+----+----+----+----- + + uiNosIdx = A | B | C | D | E; + */ + JUDGE_FAIL_WITH_TIMEOUT, /*未收到所有执行体消息,达不到裁决条件*/ + /* + ----+----+----- + | A | B | C | 1、线上执行体为A/B/C + ----+----+----- + | 1 | | | 2、收到A/B/C的消息,但完全不同 + ----+----+----- + + uiNosIdx = A; + */ + JUDGE_FAIL_WITH_TIMEOUT_TWO_STAGE, /*未收到所有执行体消息,分为两个少数群体*/ + /* + ----+----+----- + | A | B | C | 1、线上执行体为A/B/C + ----+----+----- + | 1 | 2 | | 2、收到A/B的消息,A/B不同, C超时 + ----+----+----- + + uiNosIdx = A | B | C; + */ + JUDGE_FAIL_WITH_TIMEOUT_MANY_STAGE, /*未收到所有执行体消息,分为多个少数群体*/ + /* + ----+----+----+----+----- + | A | B | C | D | E 1、线上执行体为A/B/C/D/E + ----+----+----+----+----- + | 1 | 1 | 2 | 2 | 2、收到的消息中,A/B全部一致,C/D全部一致,E超时 + ----+----+----+----+----- + + uiNosIdx = A | B | C | D | E; + */ + JUDGE_RET_MAX, + + JUDGE_SYS_RUNNING, /* Nos正常运行 */ + JUDGE_EXCESSIVE_CPU_OCCUPY, /*CPU占用率偏高*/ + JUDGE_EXCESSIVE_MEM_OCCUPY, /*内存占用率偏高*/ + JUDGE_EXCESSIVE_TCP_SOCKET, /*TCP SOCKET连接数过多*/ + JUDGE_EXCESSIVE_PROGRESS, /*进程总数过多*/ + JUDGE_SOMEONE_BROKEN_INTO, /*执行体被登入*/ + JUDGE_EXCEPTION_SHELL, /*执行体运行了异常的shell命令*/ + JUDGE_EXCEPTION_USER, /*执行体系统用户账户信息发生变化*/ + JUDGE_EXCEPTION_GROUP, /*执行体系统用户组信息发生变化*/ + JUDGE_CHANGE_CRON, /*计划任务个数产生变动*/ + JUDGE_CHANGE_FILE_IN_PATH, /*PATH目录下文件个数产生变动*/ + JUDGE_CHANGE_FILE_IN_HOME, /*用户目录下文件个数产生变动*/ + JUDGE_EXCEPTION_APP, /*关键可执行文件被篡改*/ + JUDGE_EXCEPTION_AUTOSTART, /*开机自启文件被篡改*/ + JUDGE_EXCEPTION_MANAGER, /*管理进程被异常停止*/ + JUDGE_EXCEPTION_PROTOCOL, /*协议进程被异常停止*/ + JUDGE_EXCEPTION_LOCAL_CONFIG_MANAGER, /*本地配置管理器被异常停止*/ + JUDGE_EXCEPTION_FIREWALL, /*防火墙被异常关闭*/ + JUDGE_TIME_OUT, /*某执行体状态信息上报超时*/ + + ERROR_CODE_MAX +}Judge_Error_Code_T; + +typedef struct Judge_Error_Msg_S +{ + Judge_Error_Code_T uiErrorCode; //错误代码 +#define NOS1_FLAG 1<<0 +#define NOS2_FLAG 1<<1 +#define NOS3_FLAG 1<<2 +#define NOS4_FLAG 1<<3 +#define NOS5_FLAG 1<<4 +#define NOS6_FLAG 1<<5 +#define NOS7_FLAG 1<<6 +#define NOS8_FLAG 1<<7 +#define NOS9_FLAG 1<<8 +#define NOS10_FLAG 1<<9 + uint uiNosIdx; + char szReserve[32]; +}Judge_Error_Msg_T; + +typedef enum { + HB_JUDGE_E = 1, + HB_SHD_E, + HB_MYSQL_E, + HB_WEB_E, + HB_CFG_MANAGER_E, + HB_MAX_E +}HEARBEAT_E; + +typedef enum { + NOS_STATE_INVALID_E, + NOS_STATE_STOP_E, + NOS_STATE_START_E +}NOS_STATE_E; + +#endif /*CSWITCHCOMMON_H*/ diff --git a/study_clang/Mimic/test_schedule/include/CTypedef.h b/study_clang/Mimic/test_schedule/include/CTypedef.h new file mode 100644 index 0000000..4744e3b --- /dev/null +++ b/study_clang/Mimic/test_schedule/include/CTypedef.h @@ -0,0 +1,124 @@ +/************************************************************************* + > File Name : CTypedef.h + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Fri 17 Jul 2020 09:32:54 AM CST + ************************************************************************/ +#ifndef CTYPEDEF_H +#define CTYPEDEF_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include "CLog.h" +#include "CSwitchCommon.h" + +#ifndef MAX_NOS_NUM +#define NOS_MAX_NUM 8 +#else +#define NOS_MAX_NUM MAX_NOS_NUM +#endif + +#define CONF_FILE_PATH "./judge_conf.ini" + +#define JUDGE_PUBLIC_KEY (const char *)"p=lDOa9WKUKz!I9{G)uPX4@&CrV-(>tDg:kaSGzE" +#define JUDGE_PRIVATE_KEY (const char *)"q0]#)iuwR*H5hz.} File Name : CUdpClient.h + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Fri 17 Jul 2020 09:29:08 AM CST + ************************************************************************/ + +#ifndef CUDPCLIENT_H +#define CUDPCLIENT_H +#include "CTypedef.h" + + +class CUdpClient +{ +public: + CUdpClient(); + CUdpClient(const char *pcHost, unsigned int uiPort); + ~CUdpClient(); + + int CUdpRecvData(void *pcBuff, unsigned int uiBuffLen); + int CUdpSendData(const void *pcData, unsigned int uiDataLen); + int CUdpRecvData(void *pcBuff, unsigned int uiBuffLen, const char *pcHost, unsigned int uiPort); + int CUdpSendData(const void *pcData, unsigned int uiDataLen, const char *pcHost, unsigned int uiPort); + + int CUdpSetSendTimeout(unsigned int uiSeconds = 3); + int CUdpSetRecvTimeout(unsigned int uiSeconds = 3); + int CUdpSetBroadcastOpt(); + +private: + int CUdpSocket(); + int CUdpGetSockaddr(const char * pcHost, unsigned int uiPort, SOCKADDR_IN_T *pstSockaddr); + +private: + int m_iClientSock; + unsigned int m_uiPort; + unsigned char m_ucHost[16]; + SOCKADDR_IN_T m_stServerInfo; +}; + + + + + +#endif /*CUDPCLIENT_H*/ + diff --git a/study_clang/Mimic/test_schedule/include/CUdpServer.h b/study_clang/Mimic/test_schedule/include/CUdpServer.h new file mode 100644 index 0000000..4e2ddfe --- /dev/null +++ b/study_clang/Mimic/test_schedule/include/CUdpServer.h @@ -0,0 +1,32 @@ +/************************************************************************* + > File Name : CUdpServer.h + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Fri 17 Jul 2020 09:29:21 AM CST + ************************************************************************/ +#ifndef CUDPSERVER_H +#define CUDPSERVER_H + +#include "CTypedef.h" + + +class CUdpServer +{ +public: + CUdpServer(); + CUdpServer(unsigned int uiPort); + ~CUdpServer(); + + int CUdpSocket(); + int CUdpSocket(unsigned int uiPort); + int CUdpRecvData(void *pvBuff, unsigned int uiBuffLen, SOCKADDR_IN_T *pstClientInfo); + int CUdpSendData(const void *pvData, unsigned int uiDataLen, SOCKADDR_IN_T stClientInfo); + + +private: + int m_iSerSock; + unsigned int m_uiPort; +}; + +#endif /*CUDPSERVER_H*/ + diff --git a/study_clang/Mimic/test_schedule/include/CZeroMQ.h b/study_clang/Mimic/test_schedule/include/CZeroMQ.h new file mode 100644 index 0000000..d4cf2cc --- /dev/null +++ b/study_clang/Mimic/test_schedule/include/CZeroMQ.h @@ -0,0 +1,64 @@ +/***************************************************************************** + * @Descripttion: + * @Author: FengChao + * @Date: 2020-08-07 16:56:44 + * @LastEditors: LastEditors + * @LastEditTime: 2020-08-07 17:29:41 + *****************************************************************************/ +/************************************************************************* + > File Name : CZeroMQ.h + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Fri 17 Jul 2020 09:30:51 AM CST + ************************************************************************/ + +#ifndef CZEROMQ_H +#define CZEROMQ_H +#include + +class CZMQSubscriber +{ +public: + explicit CZMQSubscriber(const char *pcAddrPort, const char *pcPriKey = NULL, const char *pcPubKey = NULL); + ~CZMQSubscriber(); + + int SetRecvTimeout(unsigned int uiSeconds = 3); + int RecvData(void *pvBuff, unsigned int uiBuffLen); + +private: + int SocketInit(); + +private: + void *m_pvSubCtx; + void *m_pvSubSock; + std::string m_strAddrPort; + std::string m_StrPriKey; + std::string m_StrPubKey; +}; + + +class CZMQReqRep +{ +public: + explicit CZMQReqRep(int iType, const char *pcAddrPort, const char *pcPriKey = NULL, const char *pcPubKey = NULL); + ~CZMQReqRep(); + + int RecvData(void *pvBuff, unsigned int uiBuffLen); + int SendData(const void *pvData, unsigned int uiDataLen); + int SetRecvTimeout(unsigned int uiSeconds = 3); + int SetSendTimeout(unsigned int uiSeconds = 3); + +private: + int SocketInit(); + +private: + int m_iType; + void *m_pvCtx; + void *m_pvSock; + std::string m_strAddrPort; + std::string m_StrPriKey; + std::string m_StrPubKey; +}; + +#endif /*CZEROMQ_H*/ + diff --git a/study_clang/Mimic/test_schedule/judge_conf.ini b/study_clang/Mimic/test_schedule/judge_conf.ini new file mode 100644 index 0000000..8bf2a80 --- /dev/null +++ b/study_clang/Mimic/test_schedule/judge_conf.ini @@ -0,0 +1,44 @@ +[judge] +schedule_ip=30.30.30.2 +schedule_port=8100 +sub_nos_state_port=8200 + +pluginsctrl_ip=172.18.0.1 +pluginsctrl_port=8301 + +nos1_ip=10.10.10.241 +nos2_ip=10.10.10.242 +nos3_ip=10.10.10.243 +nos4_ip=10.10.10.244 + +config_manager_ip=192.168.0.250 + +running_num=3 +nos_num=3 + +[judge_sys_info] +nos_report_port=7002 +msg_time_out=3000 +sys_shell_log_name=history +sys_login_log_name=wtmp +process_manager_name=manager +process_protocol_name=protocol +process_local_cfgm_name=localcfgmanager +process_firewall=firewall + +cpu_occupy_max=900 +mem_occupy_max=900 +tcp_socket_max=30 +process_max=500 +cron_max=20 +path_file_max=500 +home_file_max=100 +user_md5=155c0f8a0aca2bfa5f2e85a32be41803 +group_md5=62bc68396162fda049d1ba7c7d04eb54 +config_manager_md5=62bc68396162fda049d1ba7c7d04eb54 +auto_start_md5=62bc68396162fda049d1ba7c7d04eb54 + +[trans] +trans_send_ip=192.168.0.250 +trans_send_port=6677 +trans_recv_port=8899 diff --git a/study_clang/Mimic/test_schedule/obj/CJudgeConf.o b/study_clang/Mimic/test_schedule/obj/CJudgeConf.o new file mode 100644 index 0000000..7960888 Binary files /dev/null and b/study_clang/Mimic/test_schedule/obj/CJudgeConf.o differ diff --git a/study_clang/Mimic/test_schedule/obj/CJudgeSysInfo.o b/study_clang/Mimic/test_schedule/obj/CJudgeSysInfo.o new file mode 100644 index 0000000..f0f392e Binary files /dev/null and b/study_clang/Mimic/test_schedule/obj/CJudgeSysInfo.o differ diff --git a/study_clang/Mimic/test_schedule/obj/CJudgeUtils.o b/study_clang/Mimic/test_schedule/obj/CJudgeUtils.o new file mode 100644 index 0000000..6e00e0f Binary files /dev/null and b/study_clang/Mimic/test_schedule/obj/CJudgeUtils.o differ diff --git a/study_clang/Mimic/test_schedule/obj/CLog.o b/study_clang/Mimic/test_schedule/obj/CLog.o new file mode 100644 index 0000000..b78816b Binary files /dev/null and b/study_clang/Mimic/test_schedule/obj/CLog.o differ diff --git a/study_clang/Mimic/test_schedule/obj/CMain.o b/study_clang/Mimic/test_schedule/obj/CMain.o new file mode 100644 index 0000000..fabd1b9 Binary files /dev/null and b/study_clang/Mimic/test_schedule/obj/CMain.o differ diff --git a/study_clang/Mimic/test_schedule/obj/CMessageQueue.o b/study_clang/Mimic/test_schedule/obj/CMessageQueue.o new file mode 100644 index 0000000..b81a800 Binary files /dev/null and b/study_clang/Mimic/test_schedule/obj/CMessageQueue.o differ diff --git a/study_clang/Mimic/test_schedule/obj/CMysqlPool.o b/study_clang/Mimic/test_schedule/obj/CMysqlPool.o new file mode 100644 index 0000000..21d82da Binary files /dev/null and b/study_clang/Mimic/test_schedule/obj/CMysqlPool.o differ diff --git a/study_clang/Mimic/test_schedule/obj/CNetManager.o b/study_clang/Mimic/test_schedule/obj/CNetManager.o new file mode 100644 index 0000000..284cf5f Binary files /dev/null and b/study_clang/Mimic/test_schedule/obj/CNetManager.o differ diff --git a/study_clang/Mimic/test_schedule/obj/CUdpClient.o b/study_clang/Mimic/test_schedule/obj/CUdpClient.o new file mode 100644 index 0000000..b6f68de Binary files /dev/null and b/study_clang/Mimic/test_schedule/obj/CUdpClient.o differ diff --git a/study_clang/Mimic/test_schedule/obj/CUdpServer.o b/study_clang/Mimic/test_schedule/obj/CUdpServer.o new file mode 100644 index 0000000..7fae856 Binary files /dev/null and b/study_clang/Mimic/test_schedule/obj/CUdpServer.o differ diff --git a/study_clang/Mimic/test_schedule/obj/CZeroMQ.o b/study_clang/Mimic/test_schedule/obj/CZeroMQ.o new file mode 100644 index 0000000..6d8f9e6 Binary files /dev/null and b/study_clang/Mimic/test_schedule/obj/CZeroMQ.o differ diff --git a/study_clang/Mimic/test_schedule/obj/main.o b/study_clang/Mimic/test_schedule/obj/main.o new file mode 100644 index 0000000..5e9b740 Binary files /dev/null and b/study_clang/Mimic/test_schedule/obj/main.o differ diff --git a/study_clang/Mimic/test_schedule/src/CJudgeConf.cpp b/study_clang/Mimic/test_schedule/src/CJudgeConf.cpp new file mode 100644 index 0000000..2afd148 --- /dev/null +++ b/study_clang/Mimic/test_schedule/src/CJudgeConf.cpp @@ -0,0 +1,334 @@ +/************************************************************************* + > File Name : CJudge.cpp + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Thu 16 Jul 2020 11:33:21 AM CST + ************************************************************************/ + +#include "CJudgeConf.h" +#include "CMessageQueue.h" +#include "CNetManager.h" +#include "CMysqlPool.h" + +#define MSG_TIMEOUT 3000 + +time_t GetTimeStampMS() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec*1000 + tv.tv_usec/1000; +} + +void JudgeConf::Init(int _nos_num, int _running_num) +{ + nos_num = _nos_num; + running_num = _running_num; + + nos_status = 0; + for (auto i = 0; i < running_num; i++) + { + nos_status |= 1 << i; + } + + group_map.clear(); +} + +int JudgeConf::GetCacheNosNum(CACHE_MAP& map) +{ + int num = 0; + for (auto &v : map) + { + num += v.second.size(); + } + return num; +} + +/* +* 其他线程 nos_status TODO +*/ +void JudgeConf::Judge() +{ + while(true) + { + time_t now_ms = GetTimeStampMS(); + if (CMessageQueue::GetInstance().empty()) + { + for (std::map::iterator it = group_map.begin(); it != group_map.end();) + { + MsgGroup& mg = it->second; + if (now_ms - mg.start_ms >= MSG_TIMEOUT) + { + // TODO 超时逻辑 + Judge_Error_Msg_T ret; + std::string succ_str; + bool succ = false; + + for (auto &v : mg.cache_map) + { + if ((int)v.second.size() >= running_num / 2 + 1) + { + succ = true; + succ_str = v.first; + break; + } + } + + // 裁决成功 str达到半数以上相同; 给ConfManager发消息 + ConfJudgeMsg_ST j2n_msg; + memset(&j2n_msg, 0, sizeof(j2n_msg)); + if (succ) + { + j2n_msg.iCmd = 1; // TODO + + /* + ConfJudgeMsg_ST j2c_msg; + memset(&j2c_msg, 0, sizeof(j2c_msg)); + + j2c_msg.iCmd = it->first; + memcpy(j2c_msg.ucData, succ_str.c_str(), succ_str.size()); + + if (mg.uiPort == PORT_BIND_SET_KERNEL) + { + CNetManager::GetInstance().SendDataToConfManagerKernel(&j2c_msg, sizeof(int) + succ_str.size()); + ConfJudgeMsg_ST c2j_msg; + if (CNetManager::GetInstance().RecvDataToConfManagerKernel(&c2j_msg, sizeof(c2j_msg)) < 0) + { + SysLog(LOG_ERR, "recv confManagerKernel error"); + } + } + else if (mg.uiPort == PORT_BIND_SET_HOST) + { + CNetManager::GetInstance().SendDataToConfManagerHost(&j2c_msg, sizeof(int) + succ_str.size()); + if (CNetManager::GetInstance().RecvDataToConfManagerHost(&j2n_msg, sizeof(j2n_msg)) < 0) + { + SysLog(LOG_ERR, "recv confManagerHost error"); + } + } + else + { + SysLog(LOG_ERR, "[uiPort:%d] error", mg.uiPort); + }*/ + } + + // 给NOS回消息 + CNetManager::GetInstance().SendHostDataToAllNos(&j2n_msg, sizeof(j2n_msg)); + + // 裁决结果给调度 + if (succ) + { + if (mg.cache_map.size() == 1) + { + ret.uiErrorCode = Judge_Error_Code_E::JUDGE_SUCC_WITH_TIMEOUT; + } + else if (mg.cache_map.size() == 2) + { + ret.uiErrorCode = Judge_Error_Code_E::JUDGE_SUCC_WITH_TIMEOUT_TWO_STAGE; + } + else + { + ret.uiErrorCode = Judge_Error_Code_E::JUDGE_SUCC_WITH_TIMEOUT_MANY_STAGE; + } + } + else + { + if (mg.cache_map.size() == 1) + { + ret.uiErrorCode = Judge_Error_Code_E::JUDGE_FAIL_WITH_TIMEOUT; + } + else if (mg.cache_map.size() == 2) + { + ret.uiErrorCode = Judge_Error_Code_E::JUDGE_FAIL_WITH_TIMEOUT_TWO_STAGE; + } + else + { + ret.uiErrorCode = Judge_Error_Code_E::JUDGE_FAIL_WITH_TIMEOUT_MANY_STAGE; + } + } + + ret.uiNosIdx = 0; + for (auto &v : mg.cache_map) + { + if ((int)v.second.size() < running_num / 2 + 1) + { + for (auto x : v.second) + { + ret.uiNosIdx |= 1 << x; + } + } + } + + int send_num = CNetManager::GetInstance().SendDataToShd(&ret, sizeof(ret)); + int recv_num = CNetManager::GetInstance().RecvDataFromShd(&ret, sizeof(ret)); + if (recv_num <= 0) + { + SysLog(LOG_ERR, "recv Shd error send_num:%d recv_num%d", send_num, recv_num); + } + + // 清理消息组缓存 + mg.cache_map.clear(); + mg.msg_vec.clear(); + SysLog(LOG_INFO, "judge [result:%d] [mask:%d] [type:%d] [succ:%d] [succ_str:%s]", + ret.uiErrorCode, ret.uiNosIdx, it->first, succ, succ_str.c_str()); + + char sql[128]; + memset(sql, 0, sizeof(sql)); + sprintf(sql, "insert into judge_info(msg, ret, mask, date) values(\"%s\", %d, %d, now())", + "TimeOut", ret.uiErrorCode, ret.uiNosIdx); + MysqlResults m; + MysqlPool::GetInstance().executeSql(m , sql); + + group_map.erase(it++); + continue; + } + it++; + } + usleep(1000); + continue; + } + else + { + NosConfMsg_ST& msg = CMessageQueue::GetInstance().front(); + msg.uiNosIdx = msg.iCmd; // TODO del + msg.iCmd = 1; // TODO del + /*if (!(nos_status & (1 << (msg.uiNosIdx - 1)))) + { + SysLog(LOG_ERR, "judge get [nosid:%d] [type:%d] [msg:%s] not running", msg.uiNosIdx, msg.iCmd, msg.ucData); + CMessageQueue::GetInstance().pop(); + continue; + }*/ + + std::string str((const char *)msg.ucData, msg.uiDataLen); + + auto it = group_map.find(msg.iCmd); + if (it == group_map.end()) + { + MsgGroup mg; + mg.start_ms = now_ms; + mg.uiPort = msg.uiPort; + mg.cache_map[str].insert(msg.uiNosIdx); + mg.msg_vec.push_back(msg); + group_map.insert(std::make_pair(msg.iCmd, mg)); + } + else + { + MsgGroup& mg = it->second; + mg.cache_map[str].insert(msg.uiNosIdx); + mg.msg_vec.push_back(msg); + + // 一组消息接收完毕, 开始裁决 + if (GetCacheNosNum(mg.cache_map) >= running_num) + { + Judge_Error_Msg_T ret; + bool succ = false; + std::string succ_str; + + for (auto &v : mg.cache_map) + { + if ((int)v.second.size() >= running_num / 2 + 1) + { + succ = true; + succ_str = v.first; + break; + } + } + + // 裁决成功 str达到半数以上相同; 给ConfManager发消息 + ConfJudgeMsg_ST j2n_msg; + memset(&j2n_msg, 0, sizeof(j2n_msg)); + if (succ) + { + j2n_msg.iCmd = 1; // TODO + + /*ConfJudgeMsg_ST j2c_msg; + memset(&j2c_msg, 0, sizeof(j2c_msg)); + + j2c_msg.iCmd = msg.iCmd; + memcpy(j2c_msg.ucData, succ_str.c_str(), succ_str.size()); + + if (mg.uiPort == PORT_BIND_SET_KERNEL) + { + CNetManager::GetInstance().SendDataToConfManagerKernel(&j2c_msg, sizeof(int) + succ_str.size()); + ConfJudgeMsg_ST j2n_msg; + if (CNetManager::GetInstance().RecvDataToConfManagerKernel(&j2n_msg, sizeof(j2n_msg)) < 0) + { + SysLog(LOG_ERR, "recv confManagerKernel error"); + } + } + else if (mg.uiPort == PORT_BIND_SET_HOST) + { + CNetManager::GetInstance().SendDataToConfManagerHost(&j2c_msg, sizeof(int) + succ_str.size()); + if (CNetManager::GetInstance().RecvDataToConfManagerHost(&j2n_msg, sizeof(j2n_msg)) < 0) + { + SysLog(LOG_ERR, "recv confManagerHost error"); + } + } + else + { + SysLog(LOG_ERR, "[uiPort:%d] error", mg.uiPort); + }*/ + } + + // 给NOS回消息 + CNetManager::GetInstance().SendHostDataToAllNos(&j2n_msg, sizeof(j2n_msg)); + + // 裁决结果给调度 + if (succ) + { + if (mg.cache_map.size() == 1) + { + ret.uiErrorCode = Judge_Error_Code_E::JUDGE_ALL_SUCCESS; + } + else if (mg.cache_map.size() == 2) + { + ret.uiErrorCode = Judge_Error_Code_E::JUDGE_SUCC_WITH_TWO_STAGE; + } + else + { + ret.uiErrorCode = Judge_Error_Code_E::JUDGE_SUCC_WITH_MANY_STAGE; + } + } + else + { + ret.uiErrorCode = Judge_Error_Code_E::JUDGE_ALL_FAIL_WITH_DIFF; + } + + ret.uiNosIdx = 0; + for (auto &v : mg.cache_map) + { + if ((int)v.second.size() < running_num / 2 + 1) + { + for (auto x : v.second) + { + ret.uiNosIdx |= 1 << x; + } + } + } + + CNetManager::GetInstance().SendDataToShd(&ret, sizeof(ret)); + if (CNetManager::GetInstance().RecvDataFromShd(&ret, sizeof(ret)) < 0) + { + SysLog(LOG_ERR, "recv Shd error"); + } + + // 清理消息组缓存 + mg.cache_map.clear(); + mg.msg_vec.clear(); + SysLog(LOG_INFO, "judge [result:%d] [mask:%d] [type:%d] [succ:%d] [succ_str:%s]", + ret.uiErrorCode, ret.uiNosIdx, it->first, succ, succ_str.c_str()); + + char sql[128]; + memset(sql, 0, sizeof(sql)); + sprintf(sql, "insert into judge_info(msg, ret, mask, date) values(\"%s\", %d, %d, now())", + "ok", ret.uiErrorCode, ret.uiNosIdx); + MysqlResults m; + MysqlPool::GetInstance().executeSql(m , sql); + + group_map.erase(it); + } + } + + SysLog(LOG_INFO, "judge get [nosid:%d] [type:%d] [msg:%s] ", msg.uiNosIdx, msg.iCmd, msg.ucData); + CMessageQueue::GetInstance().pop(); + } + } +} diff --git a/study_clang/Mimic/test_schedule/src/CJudgeSysInfo.cpp b/study_clang/Mimic/test_schedule/src/CJudgeSysInfo.cpp new file mode 100644 index 0000000..8ee3e66 --- /dev/null +++ b/study_clang/Mimic/test_schedule/src/CJudgeSysInfo.cpp @@ -0,0 +1,623 @@ +/************************************************************************* + > File Name: CJudgeSysInfo.cpp + > Author: SongTL + > Mail: songtianlun@comleader.com.cn + > Created Time: 2020年07月22日 星期三 15时37分13秒 + ************************************************************************/ + +#include "CJudgeSysInfo.h" +#include "CConfig.h" +#include "CMessageQueue.h" +#include + +//#include "CZeroMQ.cpp" + +CJudgeSysInfo::CJudgeSysInfo() +{} + +CJudgeSysInfo::~CJudgeSysInfo() +{} + +void CJudgeSysInfo::Init() +{ + nos_report_port = Config::GetInstance().nos_report_port; + msg_time_out = Config::GetInstance().msg_time_out; + nos_num = Config::GetInstance().nos_num; + running_num = Config::GetInstance().running_num; + schedule_ip = Config::GetInstance().schedule_ip; + schedule_port = Config::GetInstance().schedule_port; + process_running_code = Config::GetInstance().process_running_code; + + sys_shell_log_name = Config::GetInstance().sys_shell_log_name; + sys_login_log_name = Config::GetInstance().sys_login_log_name; + process_manager_name = Config::GetInstance().process_manager_name; + process_protocol_name = Config::GetInstance().process_protocol_name; + process_local_cfgm_name = Config::GetInstance().process_local_cfgm_name; + process_firewall_name = Config::GetInstance().process_firewall_name; + + user_md5 = Config::GetInstance().user_md5; + group_md5 = Config::GetInstance().group_md5; + config_manager_md5 = Config::GetInstance().config_manager_md5; + auto_start_md5 = Config::GetInstance().auto_start_md5; + + cpu_occupy_max = Config::GetInstance().cpu_occupy_max; + mem_occupy_max = Config::GetInstance().mem_occupy_max; + tcp_socket_max = Config::GetInstance().tcp_socket_max; + process_max = Config::GetInstance().process_max; + cron_max = Config::GetInstance().cron_max; + path_file_max = Config::GetInstance().path_file_max; + home_file_max = Config::GetInstance().home_file_max; + + nos_running_bit = 0; + +#define _LOG_INT_CONFIG(type) \ + SysLog(LOG_DEBUG,"Load Config %s: %d", #type, type); + _LOG_INT_CONFIG(nos_report_port); + _LOG_INT_CONFIG(schedule_port); + _LOG_INT_CONFIG(msg_time_out); + _LOG_INT_CONFIG(nos_num); +#undef __LOG_INT_CONFIG + +#define _LOG_UINT_CONFIG(type) \ + SysLog(LOG_DEBUG, "Load Config %s: %d", #type, type); + _LOG_UINT_CONFIG(running_num); + _LOG_UINT_CONFIG(cpu_occupy_max); + _LOG_UINT_CONFIG(mem_occupy_max); + _LOG_UINT_CONFIG(tcp_socket_max); + _LOG_UINT_CONFIG(process_max); + _LOG_UINT_CONFIG(cron_max); + _LOG_UINT_CONFIG(path_file_max); + _LOG_UINT_CONFIG(home_file_max); +#undef __LOG_UINT_CONFIG + +#define _LOG_STRING_CONFIG(type) \ + SysLog(LOG_DEBUG, "Load Config %s: %s",#type ,type.c_str()); + _LOG_STRING_CONFIG(schedule_ip); + _LOG_STRING_CONFIG(sys_shell_log_name); + _LOG_STRING_CONFIG(sys_login_log_name); + _LOG_STRING_CONFIG(user_md5); + _LOG_STRING_CONFIG(group_md5); + _LOG_STRING_CONFIG(config_manager_md5); + _LOG_STRING_CONFIG(auto_start_md5); +#undef __LOG_STRING_CONFIG + + char ZMQAddrPort[16]; + sprintf(ZMQAddrPort, "tcp://*:%d", nos_report_port); + m_pNosServer = new CZMQReqRep(ZMQ_REP, ZMQAddrPort); + SysLog(LOG_DEBUG, "creative zmq communication with nos, port: %d", nos_report_port); + + std::string strShdSvrAddr; + strShdSvrAddr.clear(); + strShdSvrAddr = "tcp://" + schedule_ip + ":" + std::to_string(schedule_port); + m_pShdClient = new CZMQReqRep(ZMQ_REQ, strShdSvrAddr.c_str(), JUDGE_PRIVATE_KEY, JUDGE_PUBLIC_KEY); + SysLog(LOG_DEBUG, "creative zmq communication with schedule, ip %s, port: %d", schedule_ip.c_str(), nos_report_port); + } + + +void CJudgeSysInfo::RcvNosStateMessage() +{ + while(true){ + char buffer[MAX_MSG_BUFFER]; + memset(buffer, 0x00, sizeof(buffer)); + int recvNum = m_pNosServer->RecvData(buffer, MAX_MSG_BUFFER); + if(recvNum <= 0) + { + int err = errno; + SysLog(LOG_ERR, "revc nos error, recvNum%d err:%d", recvNum, err); + //sleep(1); + continue; + } + int sendNum = m_pNosServer->SendData(buffer, sizeof(buffer)); + if (recvNum <= 0) + { + int err = errno; + SysLog(LOG_ERR, "send nos error, sendNum:%d recvNum%d errno=%d", sendNum, recvNum, err); + continue; + } + if(buffer!=NULL) + { + SysLog(LOG_DEBUG, "recv msg from nos, msg type: %d", *(uint *)buffer); + switch(*(uint *)buffer) + { + case 1: + m_SysState = CJudgeSysInfo::SplitMsgToSysState(buffer, sizeof(buffer)); + CMessageQueue::GetInstance().push(m_SysState, MQT_SYS_STATE_E); + SysLog(LOG_DEBUG, "--------------------------------------------------------"); + SysLog(LOG_DEBUG, "szIP : %s", m_SysState.szIp); + SysLog(LOG_DEBUG, "stRcvTime : %ld.%ld", m_SysState.stRcvTime.tv_sec,m_SysState.stRcvTime.tv_usec); + SysLog(LOG_DEBUG, "uiCpuRate : %d", m_SysState.uiCpuRate); + SysLog(LOG_DEBUG, "uiMemRate : %d", m_SysState.uiMemRate); + SysLog(LOG_DEBUG, "uiTcpEstablishNum : %d", m_SysState.uiTcpEstablishNum); + SysLog(LOG_DEBUG, "uiRunningProcessNum : %d", m_SysState.uiRunningProcessNum); + SysLog(LOG_DEBUG, "uiCronNum : %d", m_SysState.uiCronNum); + SysLog(LOG_DEBUG, "szPasswdMd5 : %s", m_SysState.szPasswdMd5); + SysLog(LOG_DEBUG, "szGroupMd5 : %s", m_SysState.szGroupMd5); + SysLog(LOG_DEBUG, "--------------------------------------------------------"); + break; + case 2: + m_ProcessState = CJudgeSysInfo::SplitMsgToProcessState(buffer, sizeof(buffer)); + CMessageQueue::GetInstance().push(m_ProcessState, MQT_PROCESS_STATE_E); + SysLog(LOG_DEBUG, "--------------------------------------------------------"); + SysLog(LOG_DEBUG, "szIP : %s", m_ProcessState.szIp); + SysLog(LOG_DEBUG, "stRcvTime : %ld.%ld", m_ProcessState.stRcvTime.tv_sec,m_ProcessState.stRcvTime.tv_usec); + SysLog(LOG_DEBUG, "szProcessName : %s", m_ProcessState.szProcessName); + SysLog(LOG_DEBUG, "uiProcessState : %d", m_ProcessState.uiProcessState); + SysLog(LOG_DEBUG, "--------------------------------------------------------"); + break; + case 3: + m_FileState = CJudgeSysInfo::SplitMsgToFileState(buffer, sizeof(buffer)); + CMessageQueue::GetInstance().push(m_FileState, MQT_FILE_STATE_E); + break; + case 4: + m_FileNum = CJudgeSysInfo::SplitMsgToFileNum(buffer, sizeof(buffer)); + CMessageQueue::GetInstance().push(m_FileNum, MQT_FILE_NUM_E); + break; + case 5: + m_SysLog = CJudgeSysInfo::SplitMsgToSysLog(buffer, sizeof(buffer)); + CMessageQueue::GetInstance().push(m_SysLog, MQT_SYS_LOG_E); + break; + default: + break; + } + } + else + { + SysLog(LOG_ERR, "recv nos msg error"); + } + } +} + +void CJudgeSysInfo::Judge() +{ + std::vector sys_state_v; + //uint nos_running_bit = 0; + uint nos_not_time_out_bit = 0; + + std::vector sys_shell_log_v; + std::vector sys_login_log_v; + + // Check Message Queue + while(true) + { + // 系统状态裁决在收到所有执行体消息后开始 + if(CMessageQueue::GetInstance().size(MQT_SYS_STATE_E)>=running_num / 2 + 1 ) + { + JudgeSysState(sys_state_v, nos_not_time_out_bit); + } + // 系统日志分情况进行,系统命令日志在收到所有执行体信息后开始,用户登录信息立即开始裁决。 + if(!CMessageQueue::GetInstance().empty(MQT_SYS_LOG_E)) + { + JudgeSysLog(sys_shell_log_v, sys_login_log_v); + } + if(!CMessageQueue::GetInstance().empty(MQT_PROCESS_STATE_E)) + { + JudgeProcessState(); + } + if(!CMessageQueue::GetInstance().empty(MQT_FILE_STATE_E)) + { + JudgeFileState(); + } + if(!CMessageQueue::GetInstance().empty(MQT_FILE_NUM_E)) + { + JudgeFileNum(); + } + //sleep(1); + } +} + +void CJudgeSysInfo::JudgeSysState(std::vector& sys_state_v, uint& nos_not_time_out_bit) +{ + bool second_timeout = false; + uint nos_time_out_bit = 0; + + if(nos_not_time_out_bit!=0) + second_timeout = true; + while(!CMessageQueue::GetInstance().empty(MQT_SYS_STATE_E)) + { + SysState_T sys_state_t = CMessageQueue::GetInstance().front(MQT_SYS_STATE_E); + CMessageQueue::GetInstance().pop(MQT_SYS_STATE_E); + sys_state_v.push_back(sys_state_t); + + nos_not_time_out_bit |= 1<= (running_num / 2 + 1)) + { + for(auto sys_state_it=sys_state_v.begin(); sys_state_it!=sys_state_v.end(); sys_state_it++) + { + int nos_id = GetNosId(sys_state_it->szIp); + if(JudgeCpuOccupy(sys_state_it->uiCpuRate, nos_id)==0) + clrbit(nos_running_bit, nos_id); + if(JudgeMemOccupy(sys_state_it->uiMemRate, nos_id)==0) + clrbit(nos_running_bit, nos_id); + if(JudgeTcpSocket(sys_state_it->uiTcpEstablishNum, nos_id)==0) + clrbit(nos_running_bit, nos_id); + if(JudgeProcessNum(sys_state_it->uiRunningProcessNum, nos_id)==0) + clrbit(nos_running_bit, nos_id); + if(JudgeCronNum(sys_state_it->uiCronNum, nos_id)==0) + clrbit(nos_running_bit, nos_id); + if(JudgeUserInfo(sys_state_it->szPasswdMd5, nos_id)==0) + clrbit(nos_running_bit, nos_id); + if(JudgeGroupInfo(sys_state_it->szGroupMd5, nos_id)==0) + clrbit(nos_running_bit, nos_id); + } + sys_state_v.clear(); + } + // TODO normal report + if(nos_running_bit) + { + for(int i=0;i::GetInstance().empty(MQT_PROCESS_STATE_E)) + { + ProcessState_T tProcessState = CMessageQueue::GetInstance().front(MQT_PROCESS_STATE_E); + CMessageQueue::GetInstance().pop(MQT_PROCESS_STATE_E); + uint nosID = GetNosId(tProcessState.szIp); + if(tProcessState.uiProcessState != process_running_code) + { + Judge_Error_Msg_T eMsg; + if(strcmp(tProcessState.szProcessName,process_manager_name.c_str())==0) + { + eMsg.uiErrorCode = JUDGE_EXCEPTION_MANAGER; + SysLog(LOG_ERR, "Nos %d manager process exception.", nosID); + } + else if(strcmp(tProcessState.szProcessName,process_protocol_name.c_str())==0) + { + eMsg.uiErrorCode = JUDGE_EXCEPTION_PROTOCOL; + SysLog(LOG_ERR, "Nos %d protocol process exception.", nosID); + } + else if(strcmp(tProcessState.szProcessName,process_local_cfgm_name.c_str())==0) + { + eMsg.uiErrorCode = JUDGE_EXCEPTION_LOCAL_CONFIG_MANAGER; + SysLog(LOG_ERR, "Nos %d local-config-manager process exception.", nosID); + } + else if(strcmp(tProcessState.szProcessName,process_firewall_name.c_str())==0) + { + eMsg.uiErrorCode = JUDGE_EXCEPTION_FIREWALL; + SysLog(LOG_ERR, "Nos %d firewall exception.", nosID); + } + else + { + SysLog(LOG_ERR, "Recv a error process report from Nos %d.", nosID); + return; + } + eMsg.uiNosIdx = 1>>nosID; + int sendNum = SendDataToShd(&eMsg, sizeof(eMsg)); + int recvNum = RecvDataFromShd(&eMsg, sizeof(eMsg)); + if (recvNum <= 0) + { + SysLog(LOG_ERR, "recv shd error sendNum:%d recvNum%d", sendNum, recvNum); + } + } + } + //sleep(1); +} + +void CJudgeSysInfo::JudgeFileState() +{ + //sleep(1); +} + +void CJudgeSysInfo::JudgeFileNum() +{ + //sleep(1); +} + +void CJudgeSysInfo::JudgeSysLog(std::vector& SysShellLog_MV, std::vector& SysLoginLog_MV) +{ + while(!CMessageQueue::GetInstance().empty(MQT_SYS_LOG_E)) + { + SysLog_T SysLog_CT = CMessageQueue::GetInstance().front(MQT_SYS_LOG_E); + CMessageQueue::GetInstance().pop(MQT_SYS_LOG_E); + if(strcmp(SysLog_CT.szLogFile,sys_shell_log_name.c_str())==0) + { + SysShellLog_MV.push_back(SysLog_CT); + //SysLog(LOG_DEBUG, "Recv a set of sys shell log from %s",SysLog_CT.szIp); + //SysLog(LOG_DEBUG, "Size of shell log message queue: %d",SysShellLog_MV.size()); + } + else if(strcmp(SysLog_CT.szLogFile,sys_login_log_name.c_str())==0) + { + SysLoginLog_MV.push_back(SysLog_CT); + //SysLog(LOG_DEBUG, "Recv a set of sys login log from %s",SysLog_CT.szIp); + } + else + { + SysLog(LOG_ERR, "recv nos error sys_log: %s", SysLog_CT.szLogFile); + } + } + if(SysShellLog_MV.size()>=running_num) + { + JudgeShellLog(SysShellLog_MV); + SysShellLog_MV.clear(); + } + if(SysLoginLog_MV.size()>0) + { + JudgeLoginLog(SysLoginLog_MV); + SysLoginLog_MV.clear(); + } + //sleep(1); +} + +int CJudgeSysInfo::JudgeCpuOccupy(uint cpu_occupy, uint nos_id) +{ + if(cpu_occupy>cpu_occupy_max) + { + Judge_Error_Msg_T ret; + ret.uiErrorCode = Judge_Error_Code_E::JUDGE_EXCESSIVE_CPU_OCCUPY; + ret.uiNosIdx = nos_id; + SysLog(LOG_ERR, "Nos %d Cpu occupy is too hight! Used:%d", nos_id, cpu_occupy); + int sendNum = SendDataToShd(&ret, sizeof(ret)); + int recvNum = RecvDataFromShd(&ret, sizeof(ret)); + if (recvNum <= 0) + { + SysLog(LOG_ERR, "recv shd error sendNum:%d recvNum%d", sendNum, recvNum); + } + return 0; + } + return 1; +} +int CJudgeSysInfo::JudgeMemOccupy(uint mem_occupy, uint nos_id) +{ + if(mem_occupy>mem_occupy_max) + { + Judge_Error_Msg_T ret; + ret.uiErrorCode = Judge_Error_Code_E::JUDGE_EXCESSIVE_MEM_OCCUPY; + ret.uiNosIdx = nos_id; + SysLog(LOG_ERR, "Nos %d Mem occupy is too hight! Used:%d", nos_id, mem_occupy); + int sendNum = SendDataToShd(&ret, sizeof(ret)); + int recvNum = RecvDataFromShd(&ret, sizeof(ret)); + if (recvNum <= 0) + { + SysLog(LOG_ERR, "recv shd error sendNum:%d recvNum%d", sendNum, recvNum); + } + return 0; + } + return 1; +} +int CJudgeSysInfo::JudgeTcpSocket(uint tcp_establish_num, uint nos_id) +{ + if(tcp_establish_num > tcp_socket_max) + { + Judge_Error_Msg_T ret; + ret.uiErrorCode = Judge_Error_Code_E::JUDGE_EXCESSIVE_TCP_SOCKET; + ret.uiNosIdx = nos_id; + SysLog(LOG_ERR, "Nos %d build too many Tcp socket! Establish num:%d", nos_id, tcp_establish_num); + int sendNum = SendDataToShd(&ret, sizeof(ret)); + int recvNum = RecvDataFromShd(&ret, sizeof(ret)); + if (recvNum <= 0) + { + SysLog(LOG_ERR, "recv shd error sendNum:%d recvNum%d", sendNum, recvNum); + } + return 0; + } + return 1; +} +int CJudgeSysInfo::JudgeProcessNum(uint running_process_num, uint nos_id) +{ + if(running_process_num > process_max) + { + Judge_Error_Msg_T ret; + ret.uiErrorCode = Judge_Error_Code_E::JUDGE_EXCESSIVE_PROGRESS; + ret.uiNosIdx = nos_id; + SysLog(LOG_ERR, "Nos %d is starting too many Process! Process num:%d",nos_id, running_process_num); + int sendNum = SendDataToShd(&ret, sizeof(ret)); + int recvNum = RecvDataFromShd(&ret, sizeof(ret)); + if (recvNum <= 0) + { + SysLog(LOG_ERR, "recv shd error sendNum:%d recvNum%d", sendNum, recvNum); + } + return 0; + } + return 1; +} +int CJudgeSysInfo::JudgeCronNum(uint cron_num, uint nos_id) +{ + if(cron_num != cron_max) + { + Judge_Error_Msg_T ret; + ret.uiErrorCode = Judge_Error_Code_E::JUDGE_CHANGE_CRON; + ret.uiNosIdx = nos_id; + SysLog(LOG_ERR, "The number of Nos %d booting tasks bas been changed to %d, plan num is %d", nos_id, cron_num, cron_max); + int sendNum = SendDataToShd(&ret, sizeof(ret)); + int recvNum = RecvDataFromShd(&ret, sizeof(ret)); + if (recvNum <= 0) + { + SysLog(LOG_ERR, "recv shd error sendNum:%d recvNum%d", sendNum, recvNum); + } + return 0; + } + return 1; +} +int CJudgeSysInfo::JudgeUserInfo(char passwd_md5[64], uint nos_id) +{ + if(strcmp(passwd_md5, user_md5.c_str())!=0) + { + Judge_Error_Msg_T ret; + ret.uiErrorCode = Judge_Error_Code_E::JUDGE_EXCEPTION_USER; + ret.uiNosIdx = nos_id; + SysLog(LOG_ERR, "There has been a change in the nos %d user account, passwd md5 changs to: %s", nos_id, passwd_md5); + int sendNum = SendDataToShd(&ret, sizeof(ret)); + int recvNum = RecvDataFromShd(&ret, sizeof(ret)); + if (recvNum <= 0) + { + SysLog(LOG_ERR, "recv shd error sendNum:%d recvNum%d", sendNum, recvNum); + } + return 0; + } + return 1; +} +int CJudgeSysInfo::JudgeGroupInfo(char cgroup_md5[64], uint nos_id) +{ + if(strcmp(cgroup_md5, group_md5.c_str())!=0) + { + Judge_Error_Msg_T ret; + ret.uiErrorCode = Judge_Error_Code_E::JUDGE_EXCEPTION_GROUP; + ret.uiNosIdx = nos_id; + SysLog(LOG_ERR, "There has been a change in the nos %d user group, group md5 changs to: %s", nos_id, cgroup_md5); + int sendNum = SendDataToShd(&ret, sizeof(ret)); + int recvNum = RecvDataFromShd(&ret, sizeof(ret)); + if (recvNum <= 0) + { + SysLog(LOG_ERR, "recv shd error sendNum:%d recvNum%d", sendNum, recvNum); + } + return 0; + } + return 1; +} + +void CJudgeSysInfo::JudgeLoginLog(std::vector& SysLoginLog_CMV) +{ + // 遍历容器,若消息非空则向调度发送错误警报 + Judge_Error_Msg_T Msg_e; + for(auto SysLoginLog_it=SysLoginLog_CMV.begin(); SysLoginLog_it!=SysLoginLog_CMV.end(); SysLoginLog_it++) + { + Msg_e.uiErrorCode = JUDGE_SOMEONE_BROKEN_INTO; + //Msg_e.uiNosIdx = GetNosId(SysLoginLog_it->szIp); + Msg_e.uiNosIdx = 1 << GetNosId(SysLoginLog_it->szIp); + int sendNum = SendDataToShd(&Msg_e, sizeof(Msg_e)); + int recvNum = RecvDataFromShd(&Msg_e, sizeof(Msg_e)); + if (recvNum <= 0) + { + SysLog(LOG_ERR, "recv shd error sendNum:%d recvNum%d", sendNum, recvNum); + } + + for(auto &it : SysLoginLog_it->szMsg) + SysLog(LOG_ERR, "Warning, someone broke into the nos body, nos ip: %s, log: %s", SysLoginLog_it->szIp, it); + } +} +void CJudgeSysInfo::JudgeShellLog(std::vector& SysShellLog_CMV) +{ + std::map > log_map; + for(auto &SysShellLog_it : SysShellLog_CMV) + { + for(auto &p_count : SysShellLog_it.szMsg) + { + uint nos_id = GetNosId(SysShellLog_it.szIp); + log_map[(std::string)p_count].insert(nos_id); + } + } + for(auto &p_check : log_map) + { + for(auto iter=p_check.second.begin();iter!=p_check.second.end();iter++) + { + + if(p_check.second.size() < running_num / 2 + 1) + SysLog(LOG_ERR, "nos %d run an abnormal command: %s",*iter , p_check.first.c_str()); + else + SysLog(LOG_ERR, "nos %d run an command: %s",*iter , p_check.first.c_str()); + } + } + log_map.clear(); +} + +void CJudgeSysInfo::JudgePathFileNum() +{} +void CJudgeSysInfo::JudgeHomeFileNum() +{} +void CJudgeSysInfo::JudgeAppMd5() +{} +void CJudgeSysInfo::JudgeAutoStartMd5() +{} +void CJudgeSysInfo::JudgeManagerProgress() +{} +void CJudgeSysInfo::JudgeProtocolProgress() +{} +void CJudgeSysInfo::JudgeLocalConfigManager() +{} +void CJudgeSysInfo::JudgeFirewell() +{} + +SysState_T CJudgeSysInfo::SplitMsgToSysState(char *buffer, int lenBuffer) +{ + memcpy(&(m_SysState),buffer,sizeof(m_SysState)); + return m_SysState; +} +ProcessState_T CJudgeSysInfo::SplitMsgToProcessState(char *buffer, int lenBuffer) +{ + memcpy(&(m_ProcessState),buffer,sizeof(m_ProcessState)); + return m_ProcessState; +} +FileState_T CJudgeSysInfo::SplitMsgToFileState(char *buffer, int lenBuffer) +{ + memcpy(&(m_FileState),buffer,sizeof(m_FileState)); + return m_FileState; +} +FileNum_T CJudgeSysInfo::SplitMsgToFileNum(char *buffer, int lenBuffer) +{ + memcpy(&(m_FileNum),buffer,sizeof(m_FileNum)); + return m_FileNum; +} +SysLog_T CJudgeSysInfo::SplitMsgToSysLog(char *buffer, int lenBuffer) +{ + memcpy(&m_SysLog,buffer,sizeof(m_SysLog)); + return m_SysLog; +} + +uint CJudgeSysInfo::GetNosId(char ip[32]) +{ + for(int i=0; iSendData(pvData, uiDataLen); +} + +int CJudgeSysInfo::RecvDataFromShd(void *pvBuff, unsigned int uiBuffLen) +{ + return 1; + //return m_pShdClient->RecvData(pvBuff, uiBuffLen); +} + diff --git a/study_clang/Mimic/test_schedule/src/CJudgeUtils.cpp b/study_clang/Mimic/test_schedule/src/CJudgeUtils.cpp new file mode 100644 index 0000000..cee7bde --- /dev/null +++ b/study_clang/Mimic/test_schedule/src/CJudgeUtils.cpp @@ -0,0 +1,273 @@ +#include +#include +#include +#include +#include +#include + +#include "CJudgeUtils.h" + +std::string& Ltrim(std::string& str) +{ + // NOLINT + std::string::iterator it = find_if(str.begin(), str.end(), std::not1(std::ptr_fun(::isspace))); + str.erase(str.begin(), it); + return str; +} + +std::string& Rtrim(std::string& str) +{ + // NOLINT + std::string::reverse_iterator it = find_if(str.rbegin(), + str.rend(), std::not1(std::ptr_fun(::isspace))); + + str.erase(it.base(), str.end()); + return str; +} + +std::string& Trim(std::string& str) +{ + // NOLINT + return Rtrim(Ltrim(str)); +} + +int INIReader::Parse(const std::string& filename) +{ + FILE* file = fopen(filename.c_str(), "r"); + if (NULL == file) + { + //_LOG_LAST_ERROR("open %s failed(%d:%s)", filename.c_str(), errno, strerror(errno)); + return -1; + } + + Clear(); + + int32_t ret = ParseFile(file); + + fclose(file); + + return ret; +} + +void INIReader::Clear() +{ + m_sections.clear(); + m_fields.clear(); +} + +int32_t INIReader::ParseFile(FILE* file) +{ + static const int32_t MAX_BUFF_LEN = 2048; + char buff[MAX_BUFF_LEN] = {0}; + + int32_t line_no = 0; + std::string key, value, line; + std::string utf8bom; + utf8bom.push_back(0xEF); + utf8bom.push_back(0xBB); + utf8bom.push_back(0xBF); + std::map* fields_map = NULL; + while (fgets(buff, MAX_BUFF_LEN, file) != NULL) + { + line_no++; + line = buff; + + // 0. 支持UTF-8 BOM + if (1 == line_no && line.find_first_of(utf8bom) == 0) + { + line.erase(0, 3); + } + + // 1. 去掉注释 + for (size_t i = 0; i < line.length(); ++i) + { + if (';' == line[i] || '#' == line[i]) + { + line.erase(i); + break; + } + } + + // 2. 去掉首尾空格 + Trim(line); + // 3. 去掉空行 + if (line.empty()) + { + continue; + } + + // section + if (line[0] == '[' && line[line.length() - 1] == ']') + { + std::string section(line.substr(1, line.length() - 2)); + Trim(section); + if (section.empty()) + { + return line_no; + } + m_sections.insert(section); + fields_map = &(m_fields[section]); + key.clear(); + continue; + } + + if (NULL == fields_map) + { + key.clear(); + continue; + } + + // fileds + size_t pos = line.find('='); + if (std::string::npos == pos) + { + if (!key.empty()) + { + if ((*fields_map).find(key) == fields_map->end()) + { + (*fields_map)[key] = line; + } + else + { + (*fields_map)[key] += line; + } + } + continue; + } + + key = line.substr(0, pos); + value = line.substr(pos + 1); + Trim(key); + Trim(value); + if (key.empty() || value.empty()) + { + continue; + } + + (*fields_map)[key] = value; + } + + return 0; +} + +std::string INIReader::Get(const std::string& section, const std::string& name, + const std::string& default_value) +{ + + std::map >::iterator it = m_fields.find(section); + if (m_fields.end() == it) + { + return default_value; + } + + std::map& fields_map = it->second; + std::map::iterator cit = fields_map.find(name); + if (fields_map.end() == cit) + { + return default_value; + } + + return cit->second; +} + +int32_t INIReader::GetInt32(const std::string& section, const std::string& name, int32_t default_value) +{ + std::string value = Get(section, name, ""); + + const char* begin = value.c_str(); + char* end = NULL; + + int32_t n = strtol(begin, &end, 0); + return end > begin ? n : default_value; +} + +uint32_t INIReader::GetUInt32(const std::string& section, const std::string& name, uint32_t default_value) +{ + std::string value = Get(section, name, ""); + const char* begin = value.c_str(); + char* end = NULL; + + int32_t n = strtol(begin, &end, 0); + if (end > begin && n >= 0) + { + return n; + } + return default_value; +} + +int64_t INIReader::GetInt64(const std::string& section, const std::string& name, int64_t default_value) +{ + std::string value = Get(section, name, ""); + const char* begin = value.c_str(); + char* end = NULL; + + int64_t n = strtoll(begin, &end, 0); + return end > begin ? n : default_value; +} + +uint64_t INIReader::GetUInt64(const std::string& section, const std::string& name, uint64_t default_value) +{ + std::string value = Get(section, name, ""); + const char* begin = value.c_str(); + char* end = NULL; + + int64_t n = strtoll(begin, &end, 0); + if (end > begin && n >= 0) + { + return n; + } + return default_value; +} + +double INIReader::GetReal(const std::string& section, const std::string& name, double default_value) +{ + std::string value = Get(section, name, ""); + const char* begin = value.c_str(); + char* end = NULL; + double n = strtod(begin, &end); + return end > begin ? n : default_value; +} + +bool INIReader::GetBoolean(const std::string& section, const std::string& name, bool default_value) +{ + std::string value = Get(section, name, ""); + + std::transform(value.begin(), value.end(), value.begin(), ::tolower); + if (value == "true" || value == "yes" || value == "on" || value == "1") + { + return true; + } + else if (value == "false" || value == "no" || value == "off" || value == "0") + { + return false; + } + else + { + return default_value; + } +} + +const std::set& INIReader::GetSections() const +{ + return m_sections; +} + +std::set INIReader::GetFields(const std::string& section) +{ + std::set fields; + + std::map >::iterator it = m_fields.find(section); + if (m_fields.end() == it) + { + return fields; + } + + std::map& fields_map = it->second; + std::map::iterator cit = fields_map.begin(); + for (; cit != fields_map.end(); ++cit) + { + fields.insert(cit->first); + } + + return fields; +} diff --git a/study_clang/Mimic/test_schedule/src/CLog.cpp b/study_clang/Mimic/test_schedule/src/CLog.cpp new file mode 100644 index 0000000..8f3e79d --- /dev/null +++ b/study_clang/Mimic/test_schedule/src/CLog.cpp @@ -0,0 +1,135 @@ +/************************************************************************* + > File Name : CLog.cpp + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Fri 17 Jul 2020 05:36:24 PM CST + ************************************************************************/ + +#include "CLog.h" + +#define DEBUG_LOG //lPrint()打印开关 + +// 打印信息级别 +char *PutOutLevel[] = +{ + (char *)"[FATEL ]", + (char *)"[ALERT ]", + (char *)"[ERROR ]", + (char *)"[ WARN ]", + (char *)"[NOTICE]", + (char *)"[ INFO ]", + (char *)"[DEBUG ]" +}; + +// 打印信息颜色 +char *PutOutColor[] = +{ + (char *)LIGHT_RED, //FATEL + (char *)PURPLE, // ALERT + (char *)RED, // ERROR + (char *)YELLOW, // WARM + (char *)BLUE, // NOTICE + (char *)CYAN, // INFO + (char *)GREEN // DEBUG +}; +/***************************************************************************** + Prototype : GetTimeString + Description : 获取格式化收后的时间字符串 + Input : char *pTimeBuf + int s32Len + Output : None + Return Value : char + + History : + 1.Date : 20181011 + Author : FengChao + Modification : Created function + +*****************************************************************************/ +char *GetTimeString(char *pTimeBuf, int s32Len) +{ + char timeBuf[32] = {0}; + time_t nowTime = 0; + struct tm *pTm = NULL; + + if (s32Len < (int)sizeof(timeBuf)) + { + return NULL; + } + + nowTime = time((time_t *)NULL); + pTm = localtime(&nowTime); + if (strftime(timeBuf, sizeof(timeBuf), "%D %H:%M:%S", pTm) == 0) + { + return NULL; + } + + if(pTimeBuf != NULL) + { + memcpy(pTimeBuf, timeBuf, sizeof(timeBuf)); + } + else + { + return NULL; + } + + return pTimeBuf; +} + + +/***************************************************************************** + Prototype : + Description : + Input : None + Output : None + Return Value : int + + History : + 1.Date : 20181011 + Author : FengChao + Modification : Created function + +*****************************************************************************/ +void LogPrint(const int level,const char *proName,const char *func,const int line,const char *format, ...) +{ + #ifdef DEBUG_LOG + va_list args; + + if ((level > DEBUG) || (level < FATAL)) + { + printf("Gole Printf Input Err Level %d\n", level); + return; + } + + char timeBuf[32] = {0}; + + va_start(args, format); + printf("%s%s:%-8s: %s %s [%d]: ",PutOutColor[level],\ + GetTimeString(timeBuf,sizeof(timeBuf)),\ + PutOutLevel[level],\ + proName,func,line); + + vprintf(format, args); + printf("\r\n" NONE); + + va_end(args); + #endif +} + +void BufPrint(const char *func,const int line, const char *pData, int iDataLen) +{ + int i = 0; + + printf("[%s:%d] :\n", func, line); + printf("*****************************\n" GREEN); + for(i = 0; i < iDataLen; i++) + { + printf("%02x ", pData[i] & 0xFF); + if(!((i+1) % 10)) printf("\n"); + } + + printf("\nsize = %d\n", iDataLen); + printf(NONE "*****************************\r\n"); +} + + diff --git a/study_clang/Mimic/test_schedule/src/CMain.cpp b/study_clang/Mimic/test_schedule/src/CMain.cpp new file mode 100644 index 0000000..1eab886 --- /dev/null +++ b/study_clang/Mimic/test_schedule/src/CMain.cpp @@ -0,0 +1,154 @@ +/************************************************************************* + > File Name : CMain.cpp + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Thu 16 Jul 2020 11:31:56 AM CST + ************************************************************************/ + +#include +#include "CMain.h" +#include "CConfig.h" +#include "CJudgeConf.h" +#include "CNetManager.h" +#include "CJudgeSysInfo.h" +#include "CMysqlPool.h" + +using namespace std; + +CMain::CMain() +{ + + +} + +CMain::~CMain() +{ + +} + +void CMain::Init() +{ + Config::GetInstance().Init(CONF_FILE_PATH); + JudgeConf::GetInstance().Init(Config::GetInstance().nos_num, Config::GetInstance().running_num); + CJudgeSysInfo::GetInstance().Init(); + + MysqlPool::GetInstance().setParameter("172.18.0.4","root","root","mimicswdb",3306,NULL,0,2); + MysqlResults m; + MysqlPool::GetInstance().executeSql(m ,"CREATE TABLE IF NOT EXISTS `judge_info`( \ + `id` INT UNSIGNED AUTO_INCREMENT, \ + `msg` VARCHAR(100) NOT NULL, \ + `ret` INT UNSIGNED, \ + `mask` INT UNSIGNED, \ + `date` DATETIME, \ + PRIMARY KEY (id) \ + ) ENGINE=InnoDB DEFAULT CHARSET=utf8;"); + + StartThreadTasks(); +} + +int CMain::MainProcess() +{ + //Judge process + while(1) + { + JudgeConf::GetInstance().Judge(); + } + + return 0; +} + +int CMain::ReleaseSource() +{ + //release source + return 0; +} + +int CMain::StartThreadTasks() +{ + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); //设置线程可分离 + + pthread_t tNosHostConfMsgRcvThread; + pthread_create(&tNosHostConfMsgRcvThread, &attr, NosHostConfMsgRcvThread, NULL); + + pthread_t tNosKernelConfMsgRcvThread; + pthread_create(&tNosKernelConfMsgRcvThread, &attr, NosKernelConfMsgRcvThread, NULL); + + pthread_t tNosStateRcvThread; + pthread_create(&tNosStateRcvThread, &attr, NosStateRcvThread, NULL); + + pthread_t tSysInfoRcvThread; + pthread_create(&tSysInfoRcvThread, &attr, NosSysInfoRcvThread, NULL); + + pthread_t tSysInfoJudgeThread; + pthread_create(&tSysInfoJudgeThread, &attr, NosSysInfoJudgeThread, NULL); + + pthread_t tSendPluginsCtrlThread; + pthread_create(&tSendPluginsCtrlThread, &attr, SendPluginsCtrlThread, NULL); + + pthread_t tTransNosHostDataThread; + pthread_create(&tTransNosHostDataThread, &attr, TransNosHostDataThread, NULL); + + pthread_t tTransNosKernelDataThread; + pthread_create(&tTransNosKernelDataThread, &attr, TransNosKernelDataThread, NULL); + + pthread_t tTransDataToOtherThread; + pthread_create(&tTransDataToOtherThread, &attr, TransDataToOtherThread, NULL); + + return 0; +} + +void *CMain::NosHostConfMsgRcvThread(void *args) +{ + CNetManager::GetInstance().RecvNosDataHost(); + return NULL; +} + +void *CMain::NosKernelConfMsgRcvThread(void *args) +{ + CNetManager::GetInstance().RecvNosDataKernel(); + return NULL; +} + +void *CMain::NosStateRcvThread(void *args) +{ + CNetManager::GetInstance().RecvNosStateFromShd(); + return NULL; +} + +void *CMain::NosSysInfoRcvThread(void *args) +{ + CJudgeSysInfo::GetInstance().RcvNosStateMessage(); + return NULL; +} + +void *CMain::NosSysInfoJudgeThread(void *args) +{ + CJudgeSysInfo::GetInstance().Judge(); + return NULL; +} + +void *CMain::SendPluginsCtrlThread(void *args) +{ + CNetManager::GetInstance().SendPluginsCtrl(); + return NULL; +} + +void *CMain::TransNosHostDataThread(void *args) +{ + CNetManager::GetInstance().TransNosHostData(); + return NULL; +} + +void *CMain::TransNosKernelDataThread(void *args) +{ + CNetManager::GetInstance().TransNosKernelData(); + return NULL; +} + +void *CMain::TransDataToOtherThread(void *args) +{ + CNetManager::GetInstance().TransBroadcastDataToOther(); + return NULL; +} diff --git a/study_clang/Mimic/test_schedule/src/CMessageQueue.cpp b/study_clang/Mimic/test_schedule/src/CMessageQueue.cpp new file mode 100644 index 0000000..c9a2522 --- /dev/null +++ b/study_clang/Mimic/test_schedule/src/CMessageQueue.cpp @@ -0,0 +1,14 @@ +/************************************************************************* + > File Name : CMessageQueue.cpp + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Thu 16 Jul 2020 11:34:46 AM CST + ************************************************************************/ + +#include +#include "CMessageQueue.h" + +using namespace std; + + + diff --git a/study_clang/Mimic/test_schedule/src/CMysqlPool.cpp b/study_clang/Mimic/test_schedule/src/CMysqlPool.cpp new file mode 100644 index 0000000..4c2485e --- /dev/null +++ b/study_clang/Mimic/test_schedule/src/CMysqlPool.cpp @@ -0,0 +1,230 @@ +/************************************************************************* + > File Name : CMysqlPool.cpp + > Author : liuzhao + > EMail : liuzhao@comleader.com.cn + > Created Time : Thu 16 Jul 2020 11:33:21 AM CST + ************************************************************************/ + +#include "CMysqlPool.h" +#include "CLog.h" + +std::mutex MysqlPool::poollock; + +MysqlPool::MysqlPool() {} + +/* + *配置数据库参数 + */ +void MysqlPool::setParameter( const char* mysqlhost, + const char* mysqluser, + const char* mysqlpwd, + const char* databasename, + unsigned int port, + const char* socket, + unsigned long client_flag, + unsigned int max_connect ) +{ + _mysqlhost = mysqlhost; + _mysqluser = mysqluser; + _mysqlpwd = mysqlpwd; + _databasename = databasename; + _port = port; + _socket = socket; + _client_flag = client_flag; + MAX_CONNECT = max_connect; + connect_count = 0; +} + +/* + *创建一个连接对象 + */ +MYSQL* MysqlPool::createOneConnect() +{ + MYSQL* conn = NULL; + conn = mysql_init(conn); + if (conn != NULL) + { + if (mysql_real_connect(conn, + _mysqlhost, + _mysqluser, + _mysqlpwd, + _databasename, + _port, + _socket, + _client_flag)) + { + connect_count++; + return conn; + } + else + { + SysLog(LOG_ERR, "mysql:%s", mysql_error(conn)); + return NULL; + } + } + else + { + SysLog(LOG_ERR, "mysql:init failed"); + return NULL; + } +} + +/* + *判断当前MySQL连接池的是否空 + */ +bool MysqlPool::isEmpty() +{ + return mysqlpool.empty(); +} +/* + *获取当前连接池队列的队头 + */ +MYSQL* MysqlPool::poolFront() +{ + return mysqlpool.front(); +} +/* + * + */ +unsigned int MysqlPool::poolSize() +{ + return mysqlpool.size(); +} +/* + *弹出当前连接池队列的队头 + */ +void MysqlPool::poolPop() +{ + mysqlpool.pop(); +} +/* + *获取连接对象,如果连接池中有连接,就取用;没有,就重新创建一个连接对象。 + *同时注意到MySQL的连接的时效性,即在连接队列中,连接对象在超过一定的时间后没有进行操作, + *MySQL会自动关闭连接,当然还有其他原因,比如:网络不稳定,带来的连接中断。 + *所以在获取连接对象前,需要先判断连接池中连接对象是否有效。 + *考虑到数据库同时建立的连接数量有限制,在创建新连接需提前判断当前开启的连接数不超过设定值。 + */ +MYSQL* MysqlPool::getOneConnect() +{ + poollock.lock(); + MYSQL *conn = NULL; + if (!isEmpty()) + { + while (!isEmpty() && mysql_ping(poolFront())) + { + mysql_close(poolFront()); + poolPop(); + connect_count--; + } + if (!isEmpty()) + { + conn = poolFront(); + poolPop(); + } + else + { + if (connect_count < MAX_CONNECT) + conn = createOneConnect(); + else + SysLog(LOG_ERR, "mysql:the number of mysql connections is too much!"); + } + } + else + { + if (connect_count < MAX_CONNECT) + conn = createOneConnect(); + else + SysLog(LOG_ERR, "mysql:the number of mysql connections is too much!"); + } + poollock.unlock(); + return conn; +} +/* + *将有效的链接对象放回链接池队列中,以待下次的取用。 + */ +void MysqlPool::close(MYSQL* conn) +{ + if (conn != NULL) + { + poollock.lock(); + mysqlpool.push(conn); + poollock.unlock(); + } +} +/* + * sql语句执行函数,并返回结果,没有结果的SQL语句返回空结果, + * 每次执行SQL语句都会先去连接队列中去一个连接对象, + * 执行完SQL语句,就把连接对象放回连接池队列中。 + * 返回对象用map主要考虑,用户可以通过数据库字段,直接获得查询的字。 + * 例如:m["字段"][index]。 + */ +void MysqlPool::executeSql(MysqlResults& results, const char* sql) +{ + MYSQL* conn = getOneConnect(); + if (conn) + { + mysql_query(conn, "SET NAMES UTF8"); // TODO + if (mysql_query(conn,sql) == 0) + { + MYSQL_RES *res = mysql_store_result(conn); + if (res) + { + results.field_count = (int32_t)mysql_num_fields(res); + results.record_count = (int32_t)mysql_num_rows(res); + + MYSQL_ROW row = NULL; + unsigned long *row_len = NULL; + + while ((row = mysql_fetch_row(res)) != NULL) + { + if ((row_len = mysql_fetch_lengths(res)) != NULL ) + { + std::vector f_vec; + for (auto i = 0; i < results.field_count; i++) + { + if (row[i] != NULL && row_len[i] > 0) + { + f_vec.push_back(row[i]); + } + } + results.value.push_back(f_vec); + } + } + + MYSQL_FIELD* field = NULL; + for (auto i = 0; (field = mysql_fetch_field(res)) != NULL; i++) + { + results.field_name.push_back(field->name);//field->type; + } + + mysql_free_result(res); + } + else + { + if (mysql_field_count(conn) != 0) + SysLog(LOG_ERR, "mysql:%s", mysql_error(conn)); + } + } + else + { + SysLog(LOG_ERR, "mysql:%s", mysql_error(conn)); + } + close(conn); + } + else + { + SysLog(LOG_ERR, "mysql:%s", mysql_error(conn)); + } +} +/* + * 析构函数,将连接池队列中的连接全部关闭 + */ +MysqlPool::~MysqlPool() +{ + while (poolSize() != 0) + { + mysql_close(poolFront()); + poolPop(); + connect_count--; + } +} diff --git a/study_clang/Mimic/test_schedule/src/CNetManager.cpp b/study_clang/Mimic/test_schedule/src/CNetManager.cpp new file mode 100644 index 0000000..cdd7982 --- /dev/null +++ b/study_clang/Mimic/test_schedule/src/CNetManager.cpp @@ -0,0 +1,483 @@ +/************************************************************************* + > File Name : CNetManager.cpp + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Wed 22 Jul 2020 07:04:38 PM CST + ************************************************************************/ + +#include +#include +#include +#include +#include +#include "CNetManager.h" +#include "CLog.h" +#include "CConfig.h" +#include "CMessageQueue.h" +#include "CJudgeUtils.h" + +CNetManager::CNetManager() +{ + pthread_mutex_init(&m_NosNetInfoHostMutex, NULL); + pthread_mutex_init(&m_NosNetInfoKernelMutex, NULL); + + memset(m_stNosState, 0x00, sizeof(m_stNosState)); + memset(m_stNosNetInfoHost, 0x00, sizeof(m_stNosNetInfoHost)); + memset(m_stNosNetInfoKernel, 0x00, sizeof(m_stNosNetInfoKernel)); + + std::string strShdSvrAddr; + strShdSvrAddr.clear(); + strShdSvrAddr = "tcp://" + Config::GetInstance().schedule_ip + ":" + std::to_string(Config::GetInstance().schedule_port); + m_pShdClient = new CZMQReqRep(ZMQ_REQ, strShdSvrAddr.c_str()); + + strShdSvrAddr.clear(); + strShdSvrAddr = "tcp://" + Config::GetInstance().pluginsctrl_ip + ":" + std::to_string(Config::GetInstance().pluginsctrl_port); + m_pPCtlClient = new CZMQReqRep(ZMQ_REQ, strShdSvrAddr.c_str()); + + strShdSvrAddr.clear(); + strShdSvrAddr = "tcp://" + Config::GetInstance().schedule_ip + ":" + std::to_string(Config::GetInstance().sub_nos_state_port); + m_pNosStateSub = new CZMQSubscriber(strShdSvrAddr.c_str()); +} + +CNetManager::~CNetManager() +{ + pthread_mutex_destroy(&m_NosNetInfoHostMutex); + pthread_mutex_destroy(&m_NosNetInfoKernelMutex); + delete m_pShdClient; + delete m_pPCtlClient; +} + +int CNetManager::RecvDataToConfManagerHost(void *pvBuff, unsigned int uiBuffLen) +{ + return m_ConfigManagerHost.CUdpRecvData(pvBuff, uiBuffLen, \ + Config::GetInstance().config_manager_ip.c_str(), \ + PORT_SET_HOST); +} + +int CNetManager::SendDataToConfManagerHost(const void *pvData, unsigned int uiDataLen) +{ + return m_ConfigManagerHost.CUdpSendData(pvData, uiDataLen, \ + Config::GetInstance().config_manager_ip.c_str(), \ + PORT_SET_HOST); +} + +int CNetManager::RecvDataToConfManagerKernel(void *pvBuff, unsigned int uiBuffLen) +{ + return m_ConfigManagerHost.CUdpRecvData(pvBuff, uiBuffLen, \ + Config::GetInstance().config_manager_ip.c_str(), \ + PORT_SET_KERNEL); +} + +int CNetManager::SendDataToConfManagerKernel(const void *pvData, unsigned int uiDataLen) +{ + return m_ConfigManagerHost.CUdpSendData(pvData, uiDataLen, \ + Config::GetInstance().config_manager_ip.c_str(), \ + PORT_SET_KERNEL); +} + +int CNetManager::SendHostDataToAllNos(const void *pvData, unsigned int uiDataLen) +{ + SOCKADDR_IN_T stSockAddr; + + for(int i = 0; i < NOS_MAX_NUM; i++) + { + memset(&stSockAddr, 0x00, sizeof(stSockAddr)); + if(0 == GetNosNetInfoHost((unsigned int)(i + 1), &stSockAddr)) + { + if(stSockAddr.sin_addr.s_addr != INADDR_NONE) + { + m_NosDataHost.CUdpSendData(pvData, uiDataLen, stSockAddr); + } + } + } + + return 0; +} + +int CNetManager::SendHostDataToNos(int iNosIdx, const void *pvData, unsigned int uiDataLen) +{ + SOCKADDR_IN_T stSockAddr; + + memset(&stSockAddr, 0x00, sizeof(stSockAddr)); + if(0 != GetNosNetInfoHost((unsigned int)iNosIdx, &stSockAddr)) + { + SysLog(SLOG_ERR, "Get net info error!"); + return -1; + } + + return m_NosDataHost.CUdpSendData(pvData, uiDataLen, stSockAddr); +} + + +int CNetManager::SendKernelDataToAllNos(const void *pvData, unsigned int uiDataLen) +{ + SOCKADDR_IN_T stSockAddr; + + for(int i = 0; i < NOS_MAX_NUM; i++) + { + memset(&stSockAddr, 0x00, sizeof(stSockAddr)); + if(0 == GetNosNetInfoKernel((unsigned int)(i + 1), &stSockAddr)) + { + if(stSockAddr.sin_addr.s_addr != INADDR_NONE) + { + m_NosDataKernel.CUdpSendData(pvData, uiDataLen, stSockAddr); + } + } + } + + return 0; +} + +int CNetManager::SendKernelDataToNos(int iNosIdx, const void *pvData, unsigned int uiDataLen) +{ + SOCKADDR_IN_T stSockAddr; + + memset(&stSockAddr, 0x00, sizeof(stSockAddr)); + if(0 != GetNosNetInfoKernel((unsigned int)iNosIdx, &stSockAddr)) + { + SysLog(SLOG_ERR, "Get net info error!"); + return -1; + } + + return m_NosDataKernel.CUdpSendData(pvData, uiDataLen, stSockAddr); +} + + +int CNetManager::SendDataToShd(const void *pvData, unsigned int uiDataLen) +{ + return m_pShdClient->SendData(pvData, uiDataLen); +} + +int CNetManager::RecvDataFromShd(void *pvBuff, unsigned int uiBuffLen) +{ + return m_pShdClient->RecvData(pvBuff, uiBuffLen); +} + +int CNetManager::SendDataToPCtl(const void *pvData, unsigned int uiDataLen) +{ + return m_pPCtlClient->SendData(pvData, uiDataLen); +} + +int CNetManager::RecvDataFromPCtl(void *pvBuff, unsigned int uiBuffLen) +{ + return m_pPCtlClient->RecvData(pvBuff, uiBuffLen); +} + +int CNetManager::GetNosIdxBySock(SOCKADDR_IN_T *pstSockAddrIn) +{ + for(int i = 0; i < NOS_MAX_NUM; i++) + { + if(pstSockAddrIn->sin_addr.s_addr == inet_addr(Config::GetInstance().nos_ip[i].c_str())) + { + return (i + 1); + } + } + + return -1; +} + +void CNetManager::RecvNosDataHost() +{ + int iNosId = 0; + int inRead = 0; + NosConfMsg_ST stNosConfData; + SOCKADDR_IN_T stSockAddrIn; + + m_NosDataHost.CUdpSocket(PORT_BIND_SET_HOST); + while(1) + { + memset(&stSockAddrIn, 0x00, sizeof(stSockAddrIn)); + memset(&stNosConfData, 0x00, sizeof(stNosConfData)); + inRead = m_NosDataHost.CUdpRecvData(&stNosConfData.iCmd, sizeof(stNosConfData.ucData) + sizeof(int), &stSockAddrIn); + if (inRead <= 0) + { + int err = errno; + if (err != EAGAIN && err != EWOULDBLOCK) + { + SysLog(LOG_ERR, "[uiPort:%d] error", err); + dPrint("[RECV ERROR] inRead = %d, %d", inRead, err); + } + usleep(100); + continue; + } + else + { + //bufPrint(&stNosConfData.iCmd, inRead); + //continue; + } + iNosId = GetNosIdxBySock(&stSockAddrIn); + if((-1 != iNosId) && (NOS_MAX_NUM >= iNosId)) + { + SetNosNetInfoHost((unsigned int)iNosId, (const SOCKADDR_IN_T *)&stSockAddrIn); + } + + stNosConfData.uiNosIdx = iNosId; + gettimeofday(&stNosConfData.stRcvTime, NULL); + stNosConfData.uiPort = PORT_SET_HOST; + stNosConfData.uiDataLen = inRead - sizeof(int); + CMessageQueue::GetInstance().push(stNosConfData); + } +} + +void CNetManager::RecvNosDataKernel() +{ + int iNosId = 0; + int inRead = 0; + NosConfMsg_ST stNosConfData; + SOCKADDR_IN_T stSockAddrIn; + + m_NosDataKernel.CUdpSocket(PORT_BIND_SET_KERNEL); + while(1) + { + memset(&stSockAddrIn, 0x00, sizeof(stSockAddrIn)); + memset(&stNosConfData, 0x00, sizeof(stNosConfData)); + inRead = m_NosDataKernel.CUdpRecvData(&stNosConfData.iCmd, sizeof(stNosConfData.ucData) + sizeof(int), &stSockAddrIn); + if (inRead <= 0) + { + int err = errno; + if (err != EAGAIN && err != EWOULDBLOCK) + { + SysLog(LOG_ERR, "[uiPort:%d] error", err); + dPrint("[RECV ERROR] inRead = %d, %d", inRead, err); + } + usleep(100); + continue; + } + else + { + bufPrint(&stNosConfData.iCmd, inRead); + } + iNosId = GetNosIdxBySock(&stSockAddrIn); + if((-1 != iNosId) && (NOS_MAX_NUM >= iNosId)) + { + memcpy(&m_stNosNetInfoKernel[iNosId - 1], &stSockAddrIn, sizeof(SOCKADDR_IN_T)); + } + + stNosConfData.uiNosIdx = iNosId; + gettimeofday(&stNosConfData.stRcvTime, NULL); + stNosConfData.uiPort = PORT_SET_KERNEL; + stNosConfData.uiDataLen = inRead - sizeof(int); + CMessageQueue::GetInstance().push(stNosConfData); + } +} + + +void CNetManager::RecvNosStateFromShd() +{ + int inRead = 0; + NosState_T stNosState; + + while(1) + { + memset(&stNosState, 0x00, sizeof(stNosState)); + inRead = m_pNosStateSub->RecvData(&stNosState, sizeof(stNosState)); + if(0 < inRead) + { + if((0 < stNosState.uiNosIdx) && (NOS_MAX_NUM > stNosState.uiNosIdx)) + { + memcpy(&m_stNosState[stNosState.uiNosIdx - 1], &stNosState, sizeof(NosState_T)); + } + } + } +} + +int CNetManager::GetNosStateById(int iIdx) +{ + return m_stNosState[iIdx - 1].iState; +} + +int CNetManager::SetNosNetInfoHost(unsigned int uiIdx, const SOCKADDR_IN_T *pstInfo) +{ + if((0 > uiIdx) || (uiIdx > NOS_MAX_NUM) || (NULL == pstInfo)) + { + SysLog(SLOG_ERR, "Para is error!"); + return -1; + } + + CMutexLockGuard MutexInfo(m_NosNetInfoHostMutex); + memcpy(&m_stNosNetInfoHost[uiIdx - 1], pstInfo, sizeof(SOCKADDR_IN_T)); + char IPdotdec[20]; + inet_pton(AF_INET, IPdotdec, (void *)&(m_stNosNetInfoHost[uiIdx - 1].sin_addr)); + inet_ntop(AF_INET, (void *)&(m_stNosNetInfoHost[uiIdx - 1].sin_addr), IPdotdec, 16);// 反转换 + SysLog(SLOG_ERR, "SetNosNetInfoHost %d %s", uiIdx - 1, IPdotdec); + SysLog(LOG_ERR, "SetNosNetInfoHost [tid:%ld] [addr:%p] [lock_p:%p]", syscall(SYS_gettid), this, &m_NosNetInfoHostMutex); + + return 0; +} + +int CNetManager::GetNosNetInfoHost(unsigned int uiIdx, SOCKADDR_IN_T *pstInfo) +{ + if((0 > uiIdx) || (uiIdx > NOS_MAX_NUM) || (NULL == pstInfo)) + { + SysLog(SLOG_ERR, "Para is error!"); + return -1; + } + + CMutexLockGuard MutexInfo(m_NosNetInfoHostMutex); + char IPdotdec[20]; + inet_pton(AF_INET, IPdotdec, (void *)&(m_stNosNetInfoHost[uiIdx - 1].sin_addr)); + inet_ntop(AF_INET, (void *)&(m_stNosNetInfoHost[uiIdx - 1].sin_addr), IPdotdec, 16);// 反转换 + SysLog(SLOG_ERR, "GetNosNetInfoHost %d %s", uiIdx - 1, IPdotdec); + SysLog(LOG_ERR, "GetNosNetInfoHost tid:%ld [addr:%p] [lock_p:%p]", syscall(SYS_gettid), this, &m_NosNetInfoHostMutex); + memcpy(pstInfo, &m_stNosNetInfoHost[uiIdx - 1], sizeof(SOCKADDR_IN_T)); + + return 0; +} + +int CNetManager::SetNosNetInfoKernel(unsigned int uiIdx, const SOCKADDR_IN_T *pstInfo) +{ + if((0 > uiIdx) || (uiIdx > NOS_MAX_NUM) || (NULL == pstInfo)) + { + SysLog(SLOG_ERR, "Para is error!"); + return -1; + } + + CMutexLockGuard MutexInfo(m_NosNetInfoKernelMutex); + memcpy(&m_stNosNetInfoKernel[uiIdx - 1], pstInfo, sizeof(SOCKADDR_IN_T)); + + return 0; +} + +int CNetManager::GetNosNetInfoKernel(unsigned int uiIdx, SOCKADDR_IN_T *pstInfo) +{ + if((0 > uiIdx) || (uiIdx > NOS_MAX_NUM) || (NULL == pstInfo)) + { + SysLog(SLOG_ERR, "Para is error!"); + return -1; + } + + CMutexLockGuard MutexInfo(m_NosNetInfoKernelMutex); + memcpy(pstInfo, &m_stNosNetInfoKernel[uiIdx - 1], sizeof(SOCKADDR_IN_T)); + + return 0; +} + +void CNetManager::TransNosHostData() +{ + int inRead = 0; + unsigned char ucBuff[2048]; + SOCKADDR_IN_T stSockAddr; + CUdpClient TransClient(Config::GetInstance().config_manager_ip.c_str(), PORT_GET_HOST); + + TransClient.CUdpSetSendTimeout(0); + m_NosHostTrans.CUdpSocket(PORT_BIND_GET_HOST); + + while(1) + { + memset(ucBuff, 0x00, sizeof(ucBuff)); + inRead = m_NosHostTrans.CUdpRecvData(ucBuff, sizeof(ucBuff), &stSockAddr); + if(0 >= inRead) + { + continue; + } + + if(0 >= TransClient.CUdpSendData(ucBuff, inRead)) + { + SysLog(SLOG_ERR, "Trans host data failed!"); + continue; + } + + memset(ucBuff, 0x00, sizeof(ucBuff)); + inRead = TransClient.CUdpRecvData(ucBuff, sizeof(ucBuff)); + if(0 >= inRead) + { + SysLog(SLOG_ERR, "Trans host data failed!"); + continue; + } + + if(0 >= m_NosHostTrans.CUdpSendData(ucBuff, inRead, stSockAddr)) + { + SysLog(SLOG_ERR, "Trans host data failed!"); + continue; + } + usleep(1000); + } +} + + +void CNetManager::TransNosKernelData() +{ + int inRead = 0; + unsigned char ucBuff[2048]; + SOCKADDR_IN_T stSockAddr; + CUdpClient TransClient(Config::GetInstance().config_manager_ip.c_str(), PORT_GET_KERNEL); + + TransClient.CUdpSetSendTimeout(0); + m_NosKernelTrans.CUdpSocket(PORT_BIND_GET_KERNEL); + + while(1) + { + memset(ucBuff, 0x00, sizeof(ucBuff)); + inRead = m_NosKernelTrans.CUdpRecvData(ucBuff, sizeof(ucBuff), &stSockAddr); + if(0 >= inRead) + { + continue; + } + + if(0 >= TransClient.CUdpSendData(ucBuff, inRead)) + { + SysLog(SLOG_ERR, "Trans host data failed!"); + continue; + } + + memset(ucBuff, 0x00, sizeof(ucBuff)); + inRead = TransClient.CUdpRecvData(ucBuff, sizeof(ucBuff)); + if(0 >= inRead) + { + SysLog(SLOG_ERR, "Trans host data failed!"); + continue; + } + + if(0 >= m_NosKernelTrans.CUdpSendData(ucBuff, inRead, stSockAddr)) + { + SysLog(SLOG_ERR, "Trans host data failed!"); + continue; + } + usleep(1000); + } +} + +void CNetManager::SendPluginsCtrl() +{ + m_pPCtlClient->SetRecvTimeout(1); + m_pPCtlClient->SetSendTimeout(1); + while(1) + { + int index = HEARBEAT_E::HB_JUDGE_E; + SendDataToPCtl(&index, sizeof(index)); + if (RecvDataFromPCtl(&index, sizeof(index)) < 0) + { + SysLog(SLOG_ERR, "recv plugins ctrl error"); + } + sleep(1); + } +} + +void CNetManager::TransBroadcastDataToOther() +{ + int inRead = 0; + unsigned char ucBuff[2048]; + SOCKADDR_IN_T stSockAddr; + CUdpClient TransClient(Config::GetInstance().trans_send_ip.c_str(), Config::GetInstance().trans_send_port); + + TransClient.CUdpSetBroadcastOpt(); + TransClient.CUdpSetSendTimeout(0); + m_BroadcastDataTrans.CUdpSocket(Config::GetInstance().trans_recv_port); + + while(1) + { + memset(ucBuff, 0x00, sizeof(ucBuff)); + inRead = m_BroadcastDataTrans.CUdpRecvData(ucBuff, sizeof(ucBuff), &stSockAddr); + if(0 >= inRead) + { + continue; + } + + if(0 >= TransClient.CUdpSendData(ucBuff, inRead)) + { + SysLog(SLOG_ERR, "Trans data to other failed!"); + continue; + } + usleep(1000); + } +} diff --git a/study_clang/Mimic/test_schedule/src/CUdpClient.cpp b/study_clang/Mimic/test_schedule/src/CUdpClient.cpp new file mode 100644 index 0000000..9fca04e --- /dev/null +++ b/study_clang/Mimic/test_schedule/src/CUdpClient.cpp @@ -0,0 +1,170 @@ +/************************************************************************* + > File Name : CUdpClient.cpp + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Tue 21 Jul 2020 02:02:08 PM CST + ************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "CUdpClient.h" +#include "CLog.h" + +CUdpClient::CUdpClient() +{ + m_iClientSock = -1; + m_uiPort = 0; + memset(m_ucHost, 0x00, sizeof(m_ucHost)); + memset(&m_stServerInfo, 0x00, sizeof(m_stServerInfo)); + CUdpSocket(); +} + +CUdpClient::CUdpClient(const char *pcHost, unsigned int uiPort) +{ + m_iClientSock = -1; + m_uiPort = uiPort; + memset(m_ucHost, 0x00, sizeof(m_ucHost)); + strcpy((char*)m_ucHost, pcHost); + memset(&m_stServerInfo, 0x00, sizeof(m_stServerInfo)); + CUdpSocket(); +} + +CUdpClient::~CUdpClient() +{ + if(0 < m_iClientSock) close(m_iClientSock); +} + +int CUdpClient::CUdpGetSockaddr(const char * pcHost, unsigned int uiPort, SOCKADDR_IN_T *pstSockaddr) +{ + SOCKADDR_IN_T stSockaddr; + + if((NULL == pcHost) || (0 == uiPort) || (NULL == pstSockaddr)) + { + SysLog(SLOG_ERR, "Para is error!"); + return -1; + } + + memset(&stSockaddr, 0x00, sizeof(stSockaddr)); + stSockaddr.sin_family = AF_INET; + stSockaddr.sin_port = htons(uiPort); + stSockaddr.sin_addr.s_addr = inet_addr(pcHost); + if(stSockaddr.sin_addr.s_addr == INADDR_NONE) + { + SysLog(SLOG_ERR, "Incorrect ip address!"); + return -1; + } + + memcpy(pstSockaddr, &stSockaddr, sizeof(SOCKADDR_IN_T)); + + return 0; +} + + +int CUdpClient::CUdpSocket() +{ + m_iClientSock = socket(AF_INET, SOCK_DGRAM, 0); + if(0 > m_iClientSock) + { + SysLog(SLOG_ERR, "Udp client socket failed!"); + return 0; + } + + CUdpSetRecvTimeout(3); + CUdpSetSendTimeout(0); + + return 0; +} + +int CUdpClient::CUdpSetSendTimeout(unsigned int uiSeconds) +{ + TIMEVAL_T stTimeout; + + stTimeout.tv_sec = uiSeconds; + stTimeout.tv_usec = 0; + + return setsockopt(m_iClientSock, SOL_SOCKET, SO_SNDTIMEO, &stTimeout, sizeof(stTimeout)); +} + +int CUdpClient::CUdpSetRecvTimeout(unsigned int uiSeconds) +{ + TIMEVAL_T stTimeout; + + stTimeout.tv_sec = uiSeconds; + stTimeout.tv_usec = 0; + + return setsockopt(m_iClientSock, SOL_SOCKET, SO_RCVTIMEO, &stTimeout, sizeof(stTimeout)); +} + +int CUdpClient::CUdpSetBroadcastOpt() +{ + int iOptval = 1; + return setsockopt(m_iClientSock, SOL_SOCKET, SO_BROADCAST | SO_REUSEADDR, &iOptval, sizeof(int)); +} + +int CUdpClient::CUdpRecvData(void *pcBuff, unsigned int uiBuffLen) +{ + return CUdpRecvData(pcBuff, uiBuffLen, (const char *)m_ucHost, m_uiPort); +} + +int CUdpClient::CUdpRecvData(void *pcBuff, unsigned int uiBuffLen, const char *pcHost, unsigned int uiPort) +{ + SOCKLEN_T stSockLen = 0; + SOCKADDR_IN_T stSockaddr; + + if((NULL == pcBuff) || (NULL == pcHost) || (0 == uiPort)) + { + SysLog(SLOG_ERR, "Para is error!"); + return -1; + } + + memset(&stSockaddr, 0x00, sizeof(stSockaddr)); + if(0 != CUdpGetSockaddr(pcHost, uiPort, &stSockaddr)) + { + SysLog(SLOG_ERR, "Get sockaddr failed!"); + return -1; + } + + stSockLen = sizeof(SOCKADDR_IN_T); + return recvfrom(m_iClientSock, pcBuff, uiBuffLen, 0, (SOCKADDR_T *)&stSockaddr, (SOCKLEN_T *)&stSockLen); +} + +int CUdpClient::CUdpSendData(const void *pcData, unsigned int uiDataLen) +{ + return CUdpSendData(pcData, uiDataLen, (const char*)m_ucHost, m_uiPort); +} + +int CUdpClient::CUdpSendData(const void *pcData, unsigned int uiDataLen, const char *pcHost, unsigned int uiPort) +{ + SOCKADDR_IN_T stSockaddr; + + if((NULL == pcData) || (NULL == pcHost) || (0 == uiPort)) + { + SysLog(SLOG_ERR, "Para is error!"); + return -1; + } + + memset(&stSockaddr, 0x00, sizeof(stSockaddr)); + if(0 != CUdpGetSockaddr(pcHost, uiPort, &stSockaddr)) + { + SysLog(SLOG_ERR, "Get sockaddr failed!"); + return -1; + } + + return sendto(m_iClientSock, pcData, uiDataLen, 0, (SOCKADDR_T *)&stSockaddr, (SOCKLEN_T)sizeof(stSockaddr)); +} + + + + diff --git a/study_clang/Mimic/test_schedule/src/CUdpServer.cpp b/study_clang/Mimic/test_schedule/src/CUdpServer.cpp new file mode 100644 index 0000000..b9e9c14 --- /dev/null +++ b/study_clang/Mimic/test_schedule/src/CUdpServer.cpp @@ -0,0 +1,141 @@ +/************************************************************************* + > File Name : CUdpServer.cpp + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Tue 21 Jul 2020 10:31:10 AM CST + ************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "CUdpServer.h" +#include "CLog.h" + +CUdpServer::CUdpServer() +{ + m_uiPort = 0; + m_iSerSock = -1; +} + +CUdpServer::CUdpServer(unsigned int uiPort) +{ + m_uiPort = uiPort; + CUdpSocket(); +} + +CUdpServer::~CUdpServer() +{ + m_uiPort = 0; + if(0 < m_iSerSock) close(m_iSerSock); +} + +int CUdpServer::CUdpSocket() +{ + if(0 == m_uiPort) + { + SysLog(SLOG_ERR, "Para is error!"); + return -1; + } + + return CUdpSocket(m_uiPort); +} + +int CUdpServer::CUdpSocket(unsigned int uiPort) +{ + int iRet = 0; + + m_uiPort = uiPort; + if(0 == m_uiPort) + { + assert(true); + SysLog(SLOG_ERR, "Para is error!"); + return -1; + } + + m_iSerSock = socket(AF_INET, SOCK_DGRAM, 0); + if(0 > m_iSerSock) + { + SysLog(SLOG_ERR, "Udp server socket failed!"); + return -1; + } + + int flag = fcntl(m_iSerSock, F_GETFL, 0); + if (flag < 0) { + SysLog(SLOG_ERR, "fcntl F_GETFL fail!"); + return -1; + } + if (fcntl(m_iSerSock, F_SETFL, flag | O_NONBLOCK) < 0) { + SysLog(SLOG_ERR, "fcntl F_SETFL fail"); + return -1; + } + + TIMEVAL_T stTimeout; + stTimeout.tv_sec = 3; + stTimeout.tv_usec = 0; + setsockopt(m_iSerSock, SOL_SOCKET, SO_RCVTIMEO, &stTimeout, sizeof(stTimeout)); + + int iOptval = 1; + setsockopt(m_iSerSock, SOL_SOCKET, SO_REUSEADDR, &iOptval, sizeof(int)); + + struct sockaddr_in stAddr; + stAddr.sin_family = AF_INET; + stAddr.sin_port = htons(m_uiPort); + stAddr.sin_addr.s_addr = htonl(INADDR_ANY); + iRet = bind(m_iSerSock, (struct sockaddr *)&stAddr, (socklen_t)sizeof(stAddr)); + if(0 > iRet) + { + SysLog(SLOG_ERR, "Udp server bind failed!"); + return -1; + } + + return m_iSerSock; +} + +int CUdpServer::CUdpRecvData(void *pvBuff, unsigned int uiBuffLen, SOCKADDR_IN_T *pstClientInfo) +{ + int inRead = 0; + SOCKLEN_T stAddrLen; + + if((NULL == pvBuff) || (NULL == pstClientInfo)) + { + SysLog(SLOG_ERR, "Para is error!"); + return -1; + } + + stAddrLen = sizeof(SOCKADDR_IN_T); + inRead = recvfrom(m_iSerSock, pvBuff, uiBuffLen, 0, (SOCKADDR_T *)pstClientInfo,(SOCKLEN_T *)&stAddrLen); + + return inRead; +} + +int CUdpServer::CUdpSendData(const void *pvData, unsigned int uiDataLen, SOCKADDR_IN_T stClientInfo) +{ + int inSend = 0; + + if(NULL == pvData) + { + SysLog(SLOG_ERR, "Para is error!"); + return -1; + } + + inSend = sendto(m_iSerSock, pvData, uiDataLen, 0, (SOCKADDR_T *)&stClientInfo, sizeof(SOCKADDR_T)); + + return inSend; +} + + + diff --git a/study_clang/Mimic/test_schedule/src/CZeroMQ.cpp b/study_clang/Mimic/test_schedule/src/CZeroMQ.cpp new file mode 100644 index 0000000..8b452ca --- /dev/null +++ b/study_clang/Mimic/test_schedule/src/CZeroMQ.cpp @@ -0,0 +1,222 @@ +/************************************************************************* + > File Name : CZeroMQ.cpp + > Author : FengChao + > EMail : smile.fengchao@gmail.com + > Created Time : Fri 17 Jul 2020 10:00:33 AM CST + ************************************************************************/ + +#include +#include +#include "CZeroMQ.h" +#include "CLog.h" +#include "CTypedef.h" + +CZMQSubscriber::CZMQSubscriber(const char *pcAddrPort, const char *pcPriKey, const char *pcPubKey) +{ + m_strAddrPort = pcAddrPort; + m_StrPriKey.clear(); + m_StrPubKey.clear(); + if(NULL != pcPriKey) m_StrPriKey = pcPriKey; + if(NULL != pcPubKey) m_StrPubKey = pcPubKey; + m_pvSubCtx = NULL; + m_pvSubSock = NULL; + SocketInit(); +} + +CZMQSubscriber::~CZMQSubscriber() +{ + if(NULL != m_pvSubSock) zmq_close(m_pvSubSock); + if(NULL != m_pvSubCtx) zmq_ctx_destroy(m_pvSubCtx); +} + +int CZMQSubscriber::SocketInit() +{ + int iRet = 0; + + m_pvSubCtx = zmq_ctx_new(); + if(NULL == m_pvSubCtx) + { + SysLog(SLOG_ERR, "ZMQ ctx new failed!"); + return -1; + } + + m_pvSubSock = zmq_socket(m_pvSubCtx, ZMQ_SUB); + if(NULL == m_pvSubSock) + { + SysLog(SLOG_ERR, "ZMQ socket failed!"); + zmq_ctx_destroy(m_pvSubCtx); + m_pvSubCtx = NULL; + return -1; + } + + if(!m_StrPubKey.empty()) + { + zmq_setsockopt(m_pvSubSock, ZMQ_CURVE_SERVERKEY, m_StrPubKey.c_str(), m_StrPubKey.length()); + + char szPubKey[64] = {0}; + char szPriKey[64] = {0}; + zmq_curve_keypair(szPubKey, szPriKey); + zmq_setsockopt(m_pvSubSock, ZMQ_CURVE_PUBLICKEY, szPubKey, strlen(szPubKey)); + zmq_setsockopt(m_pvSubSock, ZMQ_CURVE_SECRETKEY, szPriKey, strlen(szPriKey)); + } + + iRet = zmq_connect(m_pvSubSock, m_strAddrPort.c_str()); + if(0 > iRet) + { + SysLog(SLOG_ERR, "ZMQ connect failed!"); + zmq_close(m_pvSubSock); + zmq_ctx_destroy(m_pvSubCtx); + m_pvSubCtx = NULL; + m_pvSubSock = NULL; + return -1; + } + + iRet = zmq_setsockopt(m_pvSubSock, ZMQ_SUBSCRIBE, "", 0); + if(0 != iRet) + { + SysLog(SLOG_ERR, "ZMQ set ZMQ_SUBSCRIBE failed"); + zmq_close(m_pvSubSock); + zmq_ctx_destroy(m_pvSubCtx); + m_pvSubCtx = NULL; + m_pvSubSock = NULL; + return -1; + } + + SetRecvTimeout(); + + return 0; +} + +int CZMQSubscriber::SetRecvTimeout(unsigned int uiSeconds) +{ + unsigned int uiTimeout = uiSeconds * 1000; + + return zmq_setsockopt(m_pvSubSock, ZMQ_RCVTIMEO, &uiTimeout, sizeof(uiTimeout)); +} + +int CZMQSubscriber::RecvData(void *pvBuff, unsigned int uiBuffLen) +{ + if(NULL == m_pvSubSock) SocketInit(); + + return zmq_recv(m_pvSubSock, pvBuff, uiBuffLen, 0); +} + +CZMQReqRep::CZMQReqRep(int iType, const char *pcAddrPort, const char *pcPriKey, const char *pcPubKey) +{ + m_iType = iType; + m_strAddrPort = pcAddrPort; + m_StrPriKey.clear(); + m_StrPubKey.clear(); + if(NULL != pcPriKey) m_StrPriKey = pcPriKey; + if(NULL != pcPubKey) m_StrPubKey = pcPubKey; + m_pvCtx = NULL; + m_pvSock = NULL; + SocketInit(); +} + +CZMQReqRep::~CZMQReqRep() +{ + if(NULL != m_pvSock) zmq_close(m_pvSock); + if(NULL != m_pvCtx) zmq_ctx_destroy(m_pvCtx); +} + +int CZMQReqRep::RecvData(void *pvBuff, unsigned int uiBuffLen) +{ + return zmq_recv(m_pvSock, pvBuff, uiBuffLen, 0); +} + +int CZMQReqRep::SendData(const void *pvData, unsigned int uiDataLen) +{ + return zmq_send(m_pvSock, pvData, uiDataLen, 0); +} + +int CZMQReqRep::SetRecvTimeout(unsigned int uiSeconds) +{ + unsigned int uiTimeout = uiSeconds * 1000; + + return zmq_setsockopt(m_pvSock, ZMQ_RCVTIMEO, &uiTimeout, sizeof(uiTimeout)); +} + +int CZMQReqRep::SetSendTimeout(unsigned int uiSeconds) +{ + unsigned int uiTimeout = uiSeconds * 1000; + + return zmq_setsockopt(m_pvSock, ZMQ_SNDTIMEO, &uiTimeout, sizeof(uiTimeout)); +} + +int CZMQReqRep::SocketInit() +{ + unsigned int uiTimeout = 0; + + m_pvCtx = zmq_ctx_new(); + if(NULL == m_pvCtx) + { + SysLog(SLOG_ERR, "ZMQ ctx new failed!"); + return -1; + } + + m_pvSock = zmq_socket(m_pvCtx, m_iType); + if(NULL == m_pvSock) + { + SysLog(SLOG_ERR, "ZMQ socket failed!"); + zmq_ctx_destroy(m_pvCtx); + m_pvCtx = NULL; + return -1; + } + + uiTimeout = 3*1000; + zmq_setsockopt(m_pvSock, ZMQ_LINGER, &uiTimeout, sizeof(uiTimeout)); + + SetRecvTimeout(); + SetSendTimeout(); + + int iCurveRet = 0; + if(ZMQ_REQ == m_iType) + { + if(!m_StrPubKey.empty()) + { + dPrint("ZMQ with curve."); + dPrint("Pubkey <%s> <%d>", m_StrPubKey.c_str(), m_StrPubKey.length()); + iCurveRet = zmq_setsockopt(m_pvSock, ZMQ_CURVE_SERVERKEY, m_StrPubKey.c_str(), m_StrPubKey.length()); + dPrint("iCurveRet = %d", iCurveRet); + + char szPubKey[64] = {0}; + char szPriKey[64] = {0}; + iCurveRet = zmq_curve_keypair(szPubKey, szPriKey); + zmq_setsockopt(m_pvSock, ZMQ_CURVE_PUBLICKEY, szPubKey, strlen(szPubKey)); + dPrint("iCurveRet = %d", iCurveRet); + iCurveRet = zmq_setsockopt(m_pvSock, ZMQ_CURVE_SECRETKEY, szPriKey, strlen(szPriKey)); + dPrint("iCurveRet = %d", iCurveRet); + } + if(0 > zmq_connect(m_pvSock, m_strAddrPort.c_str())) + { + zmq_close(m_pvSock); + zmq_ctx_destroy(m_pvCtx); + m_pvCtx = NULL; + m_pvSock = NULL; + return -1; + } + } + else if(ZMQ_REP == m_iType) + { + if(!m_StrPriKey.empty()) + { + int option = 1; + zmq_setsockopt(m_pvSock, ZMQ_CURVE_SERVER, &option, sizeof(option)); + zmq_setsockopt(m_pvSock, ZMQ_CURVE_SECRETKEY, m_StrPriKey.c_str(), m_StrPriKey.length()); + } + if(0 > zmq_bind(m_pvSock, m_strAddrPort.c_str())) + { + zmq_close(m_pvSock); + zmq_ctx_destroy(m_pvCtx); + m_pvCtx = NULL; + m_pvSock = NULL; + return -1; + } + } + + return 0; +} + + + diff --git a/study_clang/Mimic/test_schedule/src/main.cpp b/study_clang/Mimic/test_schedule/src/main.cpp new file mode 100644 index 0000000..ed3b46e --- /dev/null +++ b/study_clang/Mimic/test_schedule/src/main.cpp @@ -0,0 +1,46 @@ +#include +#include + +#include "CTypedef.h" +#include "CZeroMQ.h" +#define getbit(x,y) ((x) >> (y)&1) +using std::cout; +using std::endl; + +CZMQReqRep *server; + +int main() +{ + Judge_Error_Msg_T recv; + server = new CZMQReqRep(ZMQ_REP, "tcp://*:8100", JUDGE_PRIVATE_KEY, JUDGE_PUBLIC_KEY); + char buffer[1024]; + while(true) + { + int recvCode; + recvCode = server->RecvData(buffer, 1024); + if(recvCode<0) + { + SysLog(LOG_DEBUG, "recv error code: %d", recvCode); + } + else + { + server->SendData(buffer, 1024); + memcpy(&recv, buffer, sizeof(Judge_Error_Msg_T)); + SysLog(LOG_DEBUG, "-------------------- SysState Msg -----------------------"); + SysLog(LOG_DEBUG, "> uiErrorCode : %d", recv.uiErrorCode); + SysLog(LOG_DEBUG, "> uiNosIdx : %d", recv.uiNosIdx); + SysLog(LOG_DEBUG, "> szReserve : %s", recv.szReserve); + for(int i=0;i<3;i++) + { + if(getbit(recv.uiNosIdx,i)) + { + SysLog(LOG_DEBUG, "Nos %d Error Code: %d, Msg: %s", (i+1),recv.uiErrorCode,recv.szReserve); + } + } + + SysLog(LOG_DEBUG, "--------------------------------------------------------"); + } + + } + return 0; +} diff --git a/study_clang/Mimic/test_schedule/test_schedule b/study_clang/Mimic/test_schedule/test_schedule new file mode 100755 index 0000000..90143f7 Binary files /dev/null and b/study_clang/Mimic/test_schedule/test_schedule differ diff --git a/study_clang/Mimic/time_sync/Makefile b/study_clang/Mimic/time_sync/Makefile new file mode 100644 index 0000000..96984f7 --- /dev/null +++ b/study_clang/Mimic/time_sync/Makefile @@ -0,0 +1,22 @@ +# Batch Single C file MakeFile + +# 指定CPU架构 Architecture -> ARCH +ARCH ?= +CC = $(ARCH)g++ +SUFFIX = .cpp +CFLAGS += -Wall -g -std=c++11 -lpcap +LD = + +CUR_SOURCE = $(wildcard *$(SUFFIX)) +CUR_TARGETS = $(patsubst %$(SUFFIX), %, $(CUR_SOURCE)) + +all:$(CUR_TARGETS) + +# %:%.c 是一个表示与目标相同 文件的模式变量 +$(CUR_TARGETS):%:%$(SUFFIX) + $(CC) $< $(CFLAGS) -o $@ $(LD) + +# 指定伪目标 +.PHONY:clean all + clean: + -rm -rf $(TARGETS) diff --git a/study_clang/Mimic/time_sync/frame_incrypt b/study_clang/Mimic/time_sync/frame_incrypt new file mode 100755 index 0000000..e6af2d5 Binary files /dev/null and b/study_clang/Mimic/time_sync/frame_incrypt differ diff --git a/study_clang/Mimic/time_sync/frame_incrypt.cpp b/study_clang/Mimic/time_sync/frame_incrypt.cpp new file mode 100644 index 0000000..3eca014 --- /dev/null +++ b/study_clang/Mimic/time_sync/frame_incrypt.cpp @@ -0,0 +1,344 @@ +/***************************************************************************** + * @Author : Songsk + * @Date : 2020-07-17 00:02:36 + * @LastEditors : songshuaikang@comleader.com.cn + * @LastEditTime : 2020-07-20 23:17:04 + * @Description : file content + *******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define ACTIVE_NUM_NUM 3 +#define UNSIGNED_INT_LEN 32 +#define MAX_PADDING_SIZE 128 +#define uint unsigned int +#define uchar unsigned char + +#define _ENCRYPT(a,b,c) (a=(b^c)) +#define _DECRYPT _ENCRYPT +#define _CHECKSUM(_checksum, _cipher, _key, _len)\ + {\ + uint _m_i = 0;\ + uint sum = 0;\ + for(_m_i=0; _m_i< _len; _m_i++)\ + sum = sum + (0xffffffff & _cipher[_m_i]) + (0xffffffff & _key[_m_i]);\ + _checksum = 0xff - (0xff & (sum)) - ((sum) >> 8);\ + } +#define ENCRYPT_FUNC(_cipher, _plain, _key, _len)\ +{\ + int _m_i = 0;\ + for(_m_i=0; _m_i< _len; _m_i++)\ + _ENCRYPT(_cipher[_m_i], _plain[_m_i], _key[_m_i]);\ +} + +#define DECRYPT_FUNC(_plain, _cipher, _key, _len)\ +{\ + int _m_i = 0;\ + for(_m_i=0; _m_i< _len; _m_i++)\ + _DECRYPT( _plain[_m_i],_cipher[_m_i], _key[_m_i]);\ +} + +static unsigned int seed = 0; +#define SNAP_LEN 65536 +#define INTERFACE_STR "eno3" + +#define SHD_PRIVATE_PROTOCOL_H 0x09 + +#define HexPrint(_buf, _len) \ +{\ + int _m_i = 0;\ + char *_m_buf = (char *)(_buf);\ + int _m_len = (int)(_len);\ + printf("[%s:%d] \r\n", __FUNCTION__, __LINE__);\ + printf("***************************************************\n");\ + for(_m_i = 0; _m_i < _m_len; _m_i++)\ + {\ + if(_m_i == 0) printf("\033[31m%02x \033[0m",_m_i);\ + printf("\033[32m%02x \033[0m", _m_buf[_m_i] & 0xff);\ + if(!((_m_i+1) % 16)) printf("\n\033[31m%02x \033[0m",_m_i);\ + }\ + printf("\nsize = %d\n***************************************************\n", _m_len);\ +} + +typedef struct frame_head_t +{ + uchar dmac[6]; + uchar smac[6]; + uchar dot1q[4]; + uchar protocol[2]; + uchar padding; + uchar len; +}FRAME_HEAD_T; + +typedef struct msg_to_proxy_t +{ + uchar master_nos = 1; + uchar active_nos[3]; +}MSG_TO_PROXY_T; + +typedef struct timeval TS_TO_PROXY_T; + +typedef enum shd_action_type_e +{ + ACTION_TELL_ACTIVE_NOS =1, + ACTION_SEND_TIMESTAMP, + ACTINON_MAX +}SHD_ACTION; + +typedef enum shd_private_protocol_code_low_e +{ + PROTOCOL_TELL_ACTIVE_NOS = 0x88, + PROTOCOL_SEND_TIMESTAMP, + PROTOCOL_MAX +}SHD_PROTOCOL; + +/** + * @description: 发送数据包,发送的网卡在宏定义中指定 + * @param {pkt:数据包内容,包含包头与payload; len:数据包长度} + * @return: 0:success + */ +int send_packet_with_pcap(const uchar *pkt, uint len) +{ + static pcap_t *handle = NULL; + char dev_str[64]; + char err_buf[PCAP_ERRBUF_SIZE]; + + strcpy(dev_str, INTERFACE_STR); + if(NULL == handle) + { + handle = pcap_open_live(dev_str, SNAP_LEN, 1, 1000, err_buf); + if (handle == NULL) + { + fprintf(stderr, "Couldn't open device %s: %s\n", dev_str, err_buf); + return 0; + } + } + + return pcap_sendpacket(handle, pkt, len); +} + +/** + * @description: 随机函数,原子操作,提供一个字节的随机值 + * @param void + * @return: unsigned char + */ +uchar _random(void) +{ + seed += (unsigned int)time(0) + 781; + srand(seed); + uchar temp = (uchar)(rand()%256); + return temp; +} + +uint fill_with_random(uchar* buf , uint len) +{ + for(int i = 0; i< len; i++) + *(buf+i) =(_random()); + return len; +} + +void print_buffer_hex(const char * text, uchar * buf, uint len) +{ + printf("%s\n", text); + // for(int i = 0; i < len; i++) + // { + // printf("%2X ",buf[i]); + // if(i != 0 && i % 16 == 0) + // printf("\n"); + // } + HexPrint(buf, len); + printf("\n"); +} + +int is_unicast_macaddr(uchar * mac) +{ + if(mac[0] & 1) + return 1; + return 0; +} + +int make_frame_up(const int type, uchar *frame, uchar * ciphertext, uchar * key, uint len, uint frame_len) +{ + //int p = 0; + + /*fill buffer with random value*/ + fill_with_random(frame, frame_len); + + /*create a frame header, include Ehthernet header | vlan header | protocol code */ + FRAME_HEAD_T frame_head; + do + { + printf("."); + fill_with_random(frame_head.smac, sizeof(frame_head.smac)); + } + while (is_unicast_macaddr(frame_head.smac)); + printf("\nfill smac\n"); + do + { + printf("."); + fill_with_random(frame_head.dmac, sizeof(frame_head.dmac)); + } + while (is_unicast_macaddr(frame_head.dmac)); + printf("\nfill dmac\n"); + frame_head.dot1q[0] = 0x81; + frame_head.dot1q[1] = 0x00; + frame_head.dot1q[2] = 0x07; + frame_head.dot1q[3] = 0xd0; + frame_head.protocol[0] = 0x08; + //frame_head.protocol[1] = 0x06; + (ACTION_TELL_ACTIVE_NOS == type) ? frame_head.protocol[1] = PROTOCOL_TELL_ACTIVE_NOS : frame_head.protocol[1] = PROTOCOL_SEND_TIMESTAMP; + + /*get a padding*/ + uchar padding = 0; + while(1) + { + srand(time(NULL)); + int a = sizeof(FRAME_HEAD_T) + len * 2 + 1; + printf("a is %d, frame_len is %d\n", a, frame_len); + padding = (uchar)rand()%(frame_len + - sizeof(FRAME_HEAD_T) + - len * 2 - 1) + + sizeof(FRAME_HEAD_T); + if(padding + len * 2 > frame_len) + continue; + frame_head.padding = padding; + printf("padding is 0x%x\n", padding); + frame_head.len = len; + break; + } + + /*copy frame header and payload into buffer*/ + memcpy(frame, &frame_head, sizeof(frame_head)); + memcpy(frame + padding, ciphertext, len); + memcpy(frame + padding + len, key, len); + char checksum=0; + _CHECKSUM(checksum, ciphertext, key, len); + print_buffer_hex("计算校验和:", (unsigned char *)&checksum,sizeof(checksum)); + memcpy(frame + padding + len + len, &checksum, 1); + /*send packet finally*/ + print_buffer_hex("产生报文:", frame,frame_len); + return send_packet_with_pcap(frame, frame_len); +} + +int shd_send_cmd_to_proxy(MSG_TO_PROXY_T * msg) +{ + int ret = 0; + uchar key[sizeof(MSG_TO_PROXY_T)]; + uchar ciphertext[sizeof(MSG_TO_PROXY_T)]; + + /*get plaintext*/ + uchar plaintext[sizeof(MSG_TO_PROXY_T)]; + memcpy(plaintext, msg, sizeof(MSG_TO_PROXY_T)); + print_buffer_hex("产生明文:", plaintext, sizeof(plaintext)); + + /*create a key with random num*/ + ret = fill_with_random(key, sizeof(key)); + print_buffer_hex("产生掩码:", key, sizeof(key)); + + /*incrypt*/ + ENCRYPT_FUNC(ciphertext, plaintext, key,sizeof(MSG_TO_PROXY_T)); + print_buffer_hex("计算密文:", ciphertext, sizeof(ciphertext)); + /*create and send frame*/ + srand(seed); + uint frame_len = sizeof(FRAME_HEAD_T) //以太网帧头 + + sizeof(MSG_TO_PROXY_T) * 2 //信息量长度 + + 1 + + 10 + + rand()%MAX_PADDING_SIZE; //padding长度 + uchar * frame = (uchar*)malloc(frame_len); + ret = make_frame_up(ACTION_TELL_ACTIVE_NOS ,frame, ciphertext, key, sizeof(key), frame_len); + if(ret) + { + printf("send packet error\n"); + free(frame); + return -1; + } + free(frame); + + return 0; +} + +int shd_send_timestamp_to_nos() +{ + int ret = 0; + uchar key[sizeof(TS_TO_PROXY_T)]; + uchar ciphertext[sizeof(TS_TO_PROXY_T)]; + uchar plaintext[sizeof(TS_TO_PROXY_T)]; + + TS_TO_PROXY_T time; + gettimeofday(&time,NULL); + + memcpy(plaintext, &time, sizeof(TS_TO_PROXY_T)); + print_buffer_hex("产生明文:", plaintext, sizeof(plaintext)); + ret = fill_with_random(key, sizeof(key)); + print_buffer_hex("产生掩码:", key, sizeof(key)); + ENCRYPT_FUNC(ciphertext, plaintext, key,sizeof(TS_TO_PROXY_T)); + print_buffer_hex("计算密文:", ciphertext, sizeof(ciphertext)); + srand(seed); + int a = rand(); + printf("seed is %x, rand is %d, MAX_PADDING_SIZE is %d\n", seed, a, MAX_PADDING_SIZE); + uint frame_len = sizeof(FRAME_HEAD_T) //以太网帧头 + + sizeof(TS_TO_PROXY_T) * 2 //信息量长度 + + 1 + + 10 + + a % MAX_PADDING_SIZE; //padding长度 + printf("frame_len is %u\n", frame_len); + uchar * frame = (uchar*)malloc(frame_len); + if(NULL == frame) + { + printf("malloc error!!\n"); + }else + { + printf("frame addr is %x\n", frame); + } + + ret = make_frame_up(ACTION_SEND_TIMESTAMP,frame, ciphertext, key, sizeof(key), frame_len); + if(ret) + { + printf("send packet error\n"); + free(frame); + return -1; + } + free(frame); + return 0; +} + +int main() +{ + int ret = 0; + while(1) + { + #if 0 + #else + MSG_TO_PROXY_T msg; + msg.master_nos = 1; + msg.active_nos[0] = 1; + msg.active_nos[1] = 2; + msg.active_nos[2] = 3; + + // ret = shd_send_cmd_to_proxy(&msg); + // if(ret) + // { + // printf("cmd send error\n"); + // return -1; + // } + ret = shd_send_timestamp_to_nos(); + if(ret) + { + printf("cmd send error\n"); + return -1; + } + #endif + // usleep(5000); + getchar(); + } + + return 0; +} diff --git a/study_clang/Mimic/time_sync/pcap_sniff b/study_clang/Mimic/time_sync/pcap_sniff new file mode 100755 index 0000000..99fd1e0 Binary files /dev/null and b/study_clang/Mimic/time_sync/pcap_sniff differ diff --git a/study_clang/Mimic/time_sync/pcap_sniff.cpp b/study_clang/Mimic/time_sync/pcap_sniff.cpp new file mode 100644 index 0000000..891c5fa --- /dev/null +++ b/study_clang/Mimic/time_sync/pcap_sniff.cpp @@ -0,0 +1,165 @@ +/***************************************************************************** + * @Author : Songsk + * @Date : 2020-11-10 + * @LastEditors : songshuaikang@comleader.com.cn + * @Description : Sync Time with Schedule. + *******************************************************************************/ +#include +#include +#include +#include +#include + +#define uint unsigned int +#define uchar unsigned char + +typedef struct frame_head_t +{ + uchar dmac[6]; + uchar smac[6]; + uchar dot1q[4]; + uchar protocol[2]; + uchar padding; + uchar len; +}FRAME_HEAD_T; +typedef struct timeval TS_TO_PROXY_T; + +#define SNAP_LEN 65536 + +#define _ENCRYPT(a,b,c) (a=(b^c)) +#define _DECRYPT _ENCRYPT +#define _CHECKSUM(_checksum, _cipher, _key, _len)\ + {\ + uint _m_i = 0;\ + uint sum = 0;\ + for(_m_i=0; _m_i< _len; _m_i++)\ + sum = sum + (0xffffffff & _cipher[_m_i]) + (0xffffffff & _key[_m_i]);\ + _checksum = 0xff - (0xff & (sum)) - ((sum) >> 8);\ + } +#define ENCRYPT_FUNC(_cipher, _plain, _key, _len)\ +{\ + int _m_i = 0;\ + for(_m_i=0; _m_i< _len; _m_i++)\ + _ENCRYPT(_cipher[_m_i], _plain[_m_i], _key[_m_i]);\ +} + +#define DECRYPT_FUNC(_plain, _cipher, _key, _len)\ +{\ + int _m_i = 0;\ + for(_m_i=0; _m_i< _len; _m_i++)\ + _DECRYPT( _plain[_m_i],_cipher[_m_i], _key[_m_i]);\ +} + +#define dPrint(fmt, ...) do{fprintf(stderr, "[%s:%d] " fmt "\r\n", __FUNCTION__, __LINE__, ##__VA_ARGS__);}while(0) +#define HexPrint(_buf, _len) \ +{\ + int _m_i = 0;\ + char *_m_buf = (char *)(_buf);\ + int _m_len = (int)(_len);\ + printf("[%s:%d] \r\n", __FUNCTION__, __LINE__);\ + printf("*****************************\n");\ + for(_m_i = 0; _m_i < _m_len; _m_i++)\ + {\ + printf("\033[32m%02x \033[0m", _m_buf[_m_i] & 0xff);\ + if(!((_m_i+1) % 10)) printf("\n");\ + }\ + printf("\nsize = %d\n*****************************\n", _m_len);\ +} + +/************************************************ + * Add By Tianlun Song in Nov 11, 2020. + * Title: 设置操作系统时间 + * Argu Type: struct timeval + * Usage: + * set_sys_time(time); +**************************************************/ +void set_sys_time(TS_TO_PROXY_T *time) +{ + char strTime[26] = {0}; + //printf("%d.%d\n", time->tv_sec, time->tv_usec); + printf("The time before set:"); + fflush(stdout); + system("date"); + + settimeofday(time,NULL); + + printf("The time after set:"); + fflush(stdout); + system("date"); +} + +void dispatcher_handler(u_char *temp1, const struct pcap_pkthdr *header, const u_char *pkt_data) +{ + // HexPrint((const char *)pkt_data, header->caplen); + + FRAME_HEAD_T head; + TS_TO_PROXY_T time; + memset(&head, 0, sizeof(head)); + memset(&time, 0, sizeof(time)); + + memcpy(&head, pkt_data, sizeof(head)); + printf("head info: protocol is [0x%X 0x%X], padding is [0x%X], len is [0x%X]\n", + head.protocol[0],head.protocol[1], head.padding, head.len ); + if(head.protocol[1] == 0x89) + { + uchar plantext[head.len],ciphertext[head.len],key[head.len]; + memset(plantext, 0, head.len); + memset(ciphertext, 0, head.len); + memset(key, 0, head.len); + + memcpy(ciphertext, pkt_data + head.padding, head.len); + memcpy(key, pkt_data + head.padding + head.len, head.len); + + printf("ciphertext:[0x%x]\tkey:[0x%x]\n", + ciphertext, key); + + DECRYPT_FUNC(plantext, ciphertext, key, head.len); + printf("plaintext:[0x%x]\n", + plantext); + + memcpy(&time, plantext, sizeof(time)); + set_sys_time(&time); + } +} + +int main() +{ + pcap_t *handle; + char err_buf[PCAP_ERRBUF_SIZE]; + char dev_str[64]; + struct bpf_program fp; + + strcpy(dev_str, "eno3"); + + /* open capture device */ + handle = pcap_open_live(dev_str, SNAP_LEN, 1, 1000, err_buf); + if (handle == NULL) + { + fprintf(stderr, "Couldn't open device %s: %s\n", dev_str, err_buf); + return 0; + } + + /* compile the filter expression */ + if (pcap_compile(handle, &fp, "vlan", 0, 24) == -1) + { + fprintf(stderr, "Couldn't parse filter %s: %s\n", + "***", pcap_geterr(handle)); + return 0; + } + + /* apply the compiled filter */ + if (pcap_setfilter(handle, &fp) == -1) + { + fprintf(stderr, "Couldn't install filter %s: %s\n", + "***", pcap_geterr(handle)); + return 0; + } + + pcap_loop(handle, -1, dispatcher_handler, NULL); + /* cleanup */ + pcap_freecode(&fp); + pcap_close(handle); + + dPrint("Capture complete."); + return 0; +} diff --git a/study_clang/Mimic/time_sync/sync_time b/study_clang/Mimic/time_sync/sync_time new file mode 100755 index 0000000..6aae404 Binary files /dev/null and b/study_clang/Mimic/time_sync/sync_time differ diff --git a/study_clang/Mimic/time_sync/sync_time.cpp b/study_clang/Mimic/time_sync/sync_time.cpp new file mode 100644 index 0000000..507bb48 --- /dev/null +++ b/study_clang/Mimic/time_sync/sync_time.cpp @@ -0,0 +1,165 @@ +/***************************************************************************** + * @Author : Songsk + * @Date : 2020-11-10 + * @LastEditors : songshuaikang@comleader.com.cn + * @Description : Sync Time with Schedule. + *******************************************************************************/ +#include +#include +#include +#include +#include + +#define uint unsigned int +#define uchar unsigned char + +typedef struct frame_head_t +{ + uchar dmac[6]; + uchar smac[6]; + // uchar dot1q[4]; + uchar protocol[2]; + uchar padding; + uchar len; +}FRAME_HEAD_T; +typedef struct timeval TS_TO_PROXY_T; + +#define SNAP_LEN 65536 + +#define _ENCRYPT(a,b,c) (a=(b^c)) +#define _DECRYPT _ENCRYPT +#define _CHECKSUM(_checksum, _cipher, _key, _len)\ + {\ + uint _m_i = 0;\ + uint sum = 0;\ + for(_m_i=0; _m_i< _len; _m_i++)\ + sum = sum + (0xffffffff & _cipher[_m_i]) + (0xffffffff & _key[_m_i]);\ + _checksum = 0xff - (0xff & (sum)) - ((sum) >> 8);\ + } +#define ENCRYPT_FUNC(_cipher, _plain, _key, _len)\ +{\ + int _m_i = 0;\ + for(_m_i=0; _m_i< _len; _m_i++)\ + _ENCRYPT(_cipher[_m_i], _plain[_m_i], _key[_m_i]);\ +} + +#define DECRYPT_FUNC(_plain, _cipher, _key, _len)\ +{\ + int _m_i = 0;\ + for(_m_i=0; _m_i< _len; _m_i++)\ + _DECRYPT( _plain[_m_i],_cipher[_m_i], _key[_m_i]);\ +} + +#define dPrint(fmt, ...) do{fprintf(stderr, "[%s:%d] " fmt "\r\n", __FUNCTION__, __LINE__, ##__VA_ARGS__);}while(0) +#define HexPrint(_buf, _len) \ +{\ + int _m_i = 0;\ + char *_m_buf = (char *)(_buf);\ + int _m_len = (int)(_len);\ + printf("[%s:%d] \r\n", __FUNCTION__, __LINE__);\ + printf("*****************************\n");\ + for(_m_i = 0; _m_i < _m_len; _m_i++)\ + {\ + printf("\033[32m%02x \033[0m", _m_buf[_m_i] & 0xff);\ + if(!((_m_i+1) % 10)) printf("\n");\ + }\ + printf("\nsize = %d\n*****************************\n", _m_len);\ +} + +/************************************************ + * Add By Tianlun Song in Nov 11, 2020. + * Title: 设置操作系统时间 + * Argu Type: struct timeval + * Usage: + * set_sys_time(time); +**************************************************/ +void set_sys_time(TS_TO_PROXY_T *time) +{ + // char strTime[26] = {0}; + //printf("%d.%d\n", time->tv_sec, time->tv_usec); + printf("The time before set:"); + fflush(stdout); + system("date"); + + settimeofday(time,NULL); + + printf("The time after set :"); + fflush(stdout); + system("date"); +} + +void dispatcher_handler(u_char *temp1, const struct pcap_pkthdr *header, const u_char *pkt_data) +{ + // HexPrint((const char *)pkt_data, header->caplen); + + FRAME_HEAD_T head; + TS_TO_PROXY_T time; + memset(&head, 0, sizeof(head)); + memset(&time, 0, sizeof(time)); + + memcpy(&head, pkt_data, sizeof(head)); + // printf("head info: protocol is [0x%X 0x%X], padding is [0x%X], len is [0x%X]\n", + // head.protocol[0],head.protocol[1], head.padding, head.len ); + if(head.protocol[1] == 0x89) + { + uchar plantext[head.len],ciphertext[head.len],key[head.len]; + memset(plantext, 0, head.len); + memset(ciphertext, 0, head.len); + memset(key, 0, head.len); + + head.padding -= 4; + memcpy(ciphertext, pkt_data + head.padding, head.len); + memcpy(key, pkt_data + head.padding + head.len, head.len); + + //printf("ciphertext:[0x%x]\tkey:[0x%x]\n",ciphertext, key); + + DECRYPT_FUNC(plantext, ciphertext, key, head.len); + //printf("plaintext:[0x%x]\n",plantext); + + memcpy(&time, plantext, sizeof(time)); + set_sys_time(&time); + } +} + +int main() +{ + pcap_t *handle; + char err_buf[PCAP_ERRBUF_SIZE]; + char dev_str[64]; + struct bpf_program fp; + + strcpy(dev_str, "linux_dal"); + printf("Sniff Device is %s\n", dev_str); + + /* open capture device */ + handle = pcap_open_live(dev_str, SNAP_LEN, 1, 1000, err_buf); + if (handle == NULL) + { + fprintf(stderr, "Couldn't open device %s: %s\n", dev_str, err_buf); + return 0; + } + + /* compile the filter expression */ + if (pcap_compile(handle, &fp, "ether proto 0x889", 0, 24) == -1) + { + fprintf(stderr, "Couldn't parse filter %s: %s\n", + "***", pcap_geterr(handle)); + return 0; + } + + /* apply the compiled filter */ + if (pcap_setfilter(handle, &fp) == -1) + { + fprintf(stderr, "Couldn't install filter %s: %s\n", + "***", pcap_geterr(handle)); + return 0; + } + + pcap_loop(handle, -1, dispatcher_handler, NULL); + /* cleanup */ + pcap_freecode(&fp); + pcap_close(handle); + + dPrint("Capture complete."); + return 0; +} diff --git a/study_clang/build/fork_num b/study_clang/build/fork_num new file mode 100755 index 0000000..f03f532 Binary files /dev/null and b/study_clang/build/fork_num differ diff --git a/study_clang/build/fork_test b/study_clang/build/fork_test new file mode 100755 index 0000000..11e203f Binary files /dev/null and b/study_clang/build/fork_test differ diff --git a/study_clang/build/num b/study_clang/build/num new file mode 100755 index 0000000..2b830d3 Binary files /dev/null and b/study_clang/build/num differ diff --git a/study_clang/c_rpc/Makefile b/study_clang/c_rpc/Makefile new file mode 100644 index 0000000..6945ce0 --- /dev/null +++ b/study_clang/c_rpc/Makefile @@ -0,0 +1,44 @@ +# This is a template Makefile generated by rpcgen + +# Parameters + +CLIENT = rdict_client +SERVER = rdict_server + +SOURCES_CLNT.c = +SOURCES_CLNT.h = +SOURCES_SVC.c = +SOURCES_SVC.h = +SOURCES.x = rdict.x + +TARGETS_SVC.c = rdict_svc.c rdict_xdr.c rdict_srv_func.c +TARGETS_CLNT.c = rdict_clnt.c rdict_xdr.c rdict_client.c +TARGETS = rdict.h rdict_xdr.c rdict_clnt.c rdict_svc.c + +OBJECTS_CLNT = $(SOURCES_CLNT.c:%.c=%.o) $(TARGETS_CLNT.c:%.c=%.o) +OBJECTS_SVC = $(SOURCES_SVC.c:%.c=%.o) $(TARGETS_SVC.c:%.c=%.o) +# Compiler flags + +CFLAGS += -g +LDLIBS += -lnsl +RPCGENFLAGS = + +# Targets + +all : $(CLIENT) $(SERVER) + +$(TARGETS) : $(SOURCES.x) + rpcgen $(RPCGENFLAGS) $(SOURCES.x) + +$(OBJECTS_CLNT) : $(SOURCES_CLNT.c) $(SOURCES_CLNT.h) $(TARGETS_CLNT.c) + +$(OBJECTS_SVC) : $(SOURCES_SVC.c) $(SOURCES_SVC.h) $(TARGETS_SVC.c) + +$(CLIENT) : $(OBJECTS_CLNT) + $(LINK.c) -o $(CLIENT) $(OBJECTS_CLNT) $(LDLIBS) + +$(SERVER) : $(OBJECTS_SVC) + $(LINK.c) -o $(SERVER) $(OBJECTS_SVC) $(LDLIBS) + +clean: + $(RM) core $(TARGETS) $(OBJECTS_CLNT) $(OBJECTS_SVC) $(CLIENT) $(SERVER) *~ \ No newline at end of file diff --git a/study_clang/c_rpc/dict1.c b/study_clang/c_rpc/dict1.c new file mode 100644 index 0000000..583fea1 --- /dev/null +++ b/study_clang/c_rpc/dict1.c @@ -0,0 +1,88 @@ +/* dict1.c -- main, nextin */ +#include +#include +#define MAXWORD 50 /* maximum length of a command or word */ +/* ------------------------------------------------------------------ +* main -- insert, delete, or lookup words in a dictionary as specified +* ------------------------------------------------------------------ */ +int main(int argc, char *argv[]) +{ + char word[MAXWORD + 1]; /* space to hold word from input line */ + char cmd; + int wordlen; /* length of input word */ + printf("Please input:\n"); + while (1) { + wordlen = nextin(&cmd, word); + if (wordlen < 0) { + exit(0); + } + switch (cmd) { + case 'I': /* 初始化 */ + initw(); + printf("Dictionary initialized to empty.\n"); + break; + case 'i': /* 插入 */ + insertw(word); + printf("%s inserted.\n", word); + break; + case 'd': /* 删除 */ + if (deletew(word)) { + printf("%s deleted.\n", word); + } else { + printf("%s not found.\n", word); + } + break; + case 'l': /* 查询 */ + if (lookupw(word)) { + printf("%s was found.\n", word); + } else { + printf("%s was not found.\n", word); + } + break; + case 'q': /* 退出 */ + printf("Program quits.\n"); + exit(0); + break; + default: /* 非法输入 */ + printf("command %c invalid.\n", cmd); + break; + } /* end of switch */ + } /* end of while */ + return 0; +} /* end of main */ +/* ------------------------------------------------------------------ +* nextin -- read a command and(possibly) a word from the next input line +* ------------------------------------------------------------------ */ +int nextin(char *cmd, char *word) +{ +int i, ch; +ch = getc(stdin); +while (isspace(ch)) { +ch = getc(stdin); +} /* end of while */ +if (ch == EOF) { +return (-1); +} +*cmd = (char) ch; +ch = getc(stdin); +while (isspace(ch)) { +ch = getc(stdin); +} /* end of while */ +if (ch == EOF) { +return (-1); +} +if (ch == '\n') { +return (0); +} +i = 0; +while (!isspace(ch)) { +if (++i > MAXWORD) { +printf("error: word too long.\n"); +exit(1); +} +*word++ = ch; +ch = getc(stdin); +} /* end of while */ +*word = '\0'; +return i; +} /* end of nextin */ \ No newline at end of file diff --git a/study_clang/c_rpc/dict2.c b/study_clang/c_rpc/dict2.c new file mode 100644 index 0000000..98d044b --- /dev/null +++ b/study_clang/c_rpc/dict2.c @@ -0,0 +1,53 @@ +/* dict2.c -- initw, insertw, deletew, lookupw */ +#include +#define MAXWORD 50 /* maximum length of a command or word */ +#define DICTSIZ 100 /* maximum number of entries in dictionary. */ +char dict[DICTSIZ][MAXWORD + 1]; /* storage for a dictionary of words */ +int nwords = 0; /* number of words in the dictionary */ +/* ------------------------------------------------------------------ +* initw -- initialize the dictionary to contain no words at all +* ------------------------------------------------------------------ */ +int initw(void) +{ + nwords = 0; + return 1; +} /* end of initw */ +/* ------------------------------------------------------------------ +* insertw -- insert a word in the dictionary +* ------------------------------------------------------------------ */ +int insertw(const char *word) +{ +strcpy(dict[nwords], word); +nwords++; +return (nwords); +} /* end of insertw */ + +/* ------------------------------------------------------------------ +* deletew -- delete a word from the dictionary +* ------------------------------------------------------------------ */ +int deletew(const char *word) +{ +int i; +for (i = 0; i < nwords; i++) { +if (strcmp(word, dict[i]) == 0) { +nwords--; +strcpy(dict[i], dict[nwords]); +return (1); +} +} /* end of for */ +return (0); +} /* end of deletew */ + +/* ------------------------------------------------------------------ +* lookupw -- look up a word in the dictionary +* ------------------------------------------------------------------ */ +int lookupw(const char *word) +{ +int i; +for (i = 0; i < nwords; i++) { +if (strcmp(word, dict[i]) == 0) { +return (1); +} +} /* end of for */ +return (0); +} /* end of lookupw */ \ No newline at end of file diff --git a/study_clang/c_rpc/rdict.x b/study_clang/c_rpc/rdict.x new file mode 100644 index 0000000..55e45da --- /dev/null +++ b/study_clang/c_rpc/rdict.x @@ -0,0 +1,22 @@ +/* filename: test.x */ + +const ADD = 0; +const SUB = 1; +const MUL = 2; +const DIV = 3; + +struct TEST +{ + int op; /* 0-ADD, 1-SUB, 2-MUL, 3-DIV */ + float arg1; + float arg2; + float result; +}; + +program TEST_PROG +{ + version TEST_VER + { + struct TEST TEST_PROC(struct TEST) = 1; + } = 2; +} = 0x20000001; \ No newline at end of file diff --git a/study_clang/c_rpc/rdict_client.c b/study_clang/c_rpc/rdict_client.c new file mode 100644 index 0000000..f0b937b --- /dev/null +++ b/study_clang/c_rpc/rdict_client.c @@ -0,0 +1,139 @@ +/* + * This is sample code generated by rpcgen. + * These are only templates and you can use them + * as a guideline for developing your own functions. + */ +#include "rdict.h" + +/* ------------------------------------------------------------------ +* nextin -- read a command and(possibly) a word from the next input line +* ------------------------------------------------------------------ */ +int nextin(char *cmd, char *word) +{ +int i, ch; +ch = getc(stdin); +while (isspace(ch)) { +ch = getc(stdin); +} /* end of while */ +if (ch == EOF) { +return (-1); +} +*cmd = (char) ch; +ch = getc(stdin); +while (isspace(ch)) { +ch = getc(stdin); +} /* end of while */ +if (ch == EOF) { +return (-1); +} +if (ch == '\n') { +return (0); +} +i = 0; +while (!isspace(ch)) { +if (++i > MAXWORD) { +printf("error: word too long.\n"); +exit(1); +} +*word++ = ch; +ch = getc(stdin); +} /* end of while */ +*word = '\0'; +return i; +} /* end of nextin */ + +void rdictprog_1(char *host) +{ +CLIENT *clnt; +int *result_1; +char *initw_1_arg; +int *result_2; +char *insertw_1_arg; +int *result_3; +char *deletew_1_arg; +int *result_4; +char *lookupw_1_arg; + +#ifndef DEBUG +clnt = clnt_create(host, RDICTPROG, RDICTVERS, "udp"); +if (clnt == NULL) { +clnt_pcreateerror(host); +exit(1); +} +#endif /* DEBUG */ +char word[MAXWORD + 1]; /* space to hold word from input line */ +char cmd; +int wordlen; /* length of input word */ +while (1) { +printf("\nPlease input:"); +wordlen = nextin(&cmd, word); +if (wordlen < 0) { +exit(0); +} +/* printf("\nYour cmd is:%c, your word is:%s\n", cmd, word); */ +switch (cmd) { +case 'I': /* 初始化 */ +result_1 = initw_1((void *) &initw_1_arg, clnt); +/* printf("\nYour result is:%d\n", *result_1); */ +if (result_1 == (int *) NULL) +clnt_perror(clnt, "call failed"); +else +if(*result_1 ==0) printf("Dictionary initialized to empty.\n"); +else printf("Dictionary have already initialized.\n"); +break; +case 'i': /* 插入 */ +insertw_1_arg = word; +result_2 = insertw_1(&insertw_1_arg, clnt); +/* printf("\nYour result is:%d, your string is:%s(%d)\n", *result_2, insertw_1_arg, strlen(insertw_1_arg)); */ +if (result_2 == (int *) NULL) +clnt_perror(clnt, "call failed"); +else +printf("%s inserted.\n", word); +break; +case 'd': /* 删除 */ +deletew_1_arg = word; +result_3 = deletew_1(&deletew_1_arg, clnt); +/* printf("\nYour result is:%d, your string is:%s(%d)\n", *result_3, deletew_1_arg, strlen(deletew_1_arg)); */ +if (result_3 == (int *) NULL) +clnt_perror(clnt, "call failed"); +else +printf("%s deleted.\n", word); +break; +case 'l': /* 查询 */ +lookupw_1_arg = word; +result_4 = lookupw_1(&lookupw_1_arg, clnt); +/* printf("\nYour result is:%d, your string is:%s(%d)\n", *result_4, lookupw_1_arg, strlen(lookupw_1_arg)); */ +if (result_4 == (int *) NULL) +clnt_perror(clnt, "call failed"); +else +if(*result_4 ==0) printf("%s found.\n", word); +else printf("%s not found.\n", word); +break; +case 'q': /* 退出 */ +printf("Program quits.\n"); +exit(0); +break; +default: /* 非法输入 */ +printf("Command %c(%s) invalid.\n", cmd, word); +break; +} /* end of switch */ +} /* end of while */ + +#ifndef DEBUG +clnt_destroy(clnt); +#endif /* DEBUG */ +} + + +int main(int argc, char *argv[]) +{ +char *host; + +if (argc < 2) { +printf("usage: %s server_host\n", argv[0]); +exit(1); +} +host = argv[1]; +rdictprog_1(host); +exit(0); +} \ No newline at end of file diff --git a/study_clang/c_rpc/rdict_srv_func.c b/study_clang/c_rpc/rdict_srv_func.c new file mode 100644 index 0000000..11a1346 --- /dev/null +++ b/study_clang/c_rpc/rdict_srv_func.c @@ -0,0 +1,109 @@ +/* + * This is sample code generated by rpcgen. + * These are only templates and you can use them + * as a guideline for developing your own functions. + */ +#include "rdict.h" + +char dict[DICTSIZ][MAXWORD + 1]; /* storage for a dictionary of words */ +int nwords = 0; /* number of words in the dictionary */ +char init_bool = 0; + +int initw(void) +{ +if(init_bool) return 1; +nwords = 0; +init_bool = 1; +return 0; +} /* end of initw */ + +/* ------------------------------------------------------------------ +* insertw -- insert a word in the dictionary +* ------------------------------------------------------------------ */ +int insertw(const char *word) +{ +strcpy(dict[nwords%DICTSIZ], word); +nwords++; +return (nwords); +} /* end of insertw */ + +/* ------------------------------------------------------------------ +* deletew -- delete a word from the dictionary +* ------------------------------------------------------------------ */ +int deletew(const char *word) +{ +int i; +for (i = 0; i < nwords; i++) { +if (strcmp(word, dict[i]) == 0) { +nwords--; +strcpy(dict[i], dict[nwords]); +return (1); +} +} /* end of for */ +return (0); +} /* end of deletew */ + +/* ------------------------------------------------------------------ +* lookupw -- look up a word in the dictionary +* ------------------------------------------------------------------ */ +int lookupw(const char *word) +{ +int i; +for (i = 0; i < nwords; i++) { +if (strcmp(word, dict[i]) == 0) { +return 0; +} +} /* end of for */ +return 1; +} /* end of lookupw */ + +int *initw_1_svc(void *argp, struct svc_req *rqstp) +{ +static int result; + +/* +* insert server code here +*/ + +result = initw(); + +return &result; +} + +int *insertw_1_svc(char **argp, struct svc_req *rqstp) +{ +static int result; + +/* +* insert server code here +*/ +result = insertw(*argp); + +return &result; +} + +int *deletew_1_svc(char **argp, struct svc_req *rqstp) +{ +static int result; + +/* +* insert server code here +*/ + +result = deletew(*argp); + +return &result; +} + +int *lookupw_1_svc(char **argp, struct svc_req *rqstp) +{ +static int result; + +/* +* insert server code here +*/ + +result = lookupw(*argp); + +return &result; +} \ No newline at end of file diff --git a/study_clang/fork/fork_num b/study_clang/fork/fork_num new file mode 100755 index 0000000..aa905bb Binary files /dev/null and b/study_clang/fork/fork_num differ diff --git a/study_clang/fork/fork_num.c b/study_clang/fork/fork_num.c new file mode 100644 index 0000000..a98e3e5 --- /dev/null +++ b/study_clang/fork/fork_num.c @@ -0,0 +1,16 @@ +/************************************************************************* + > File Name : fork_num.c + > Author : TL Song + > EMail : songtianlun@frytea.com + > Created Time : Wed 23 Dec 2020 03:52:27 PM CST + ************************************************************************/ + +#include +int main() +{ + fork(); + fork() && fork() || fork(); + fork(); + while(1); + return 0; +} diff --git a/study_clang/fork/fork_test b/study_clang/fork/fork_test new file mode 100755 index 0000000..567b4db Binary files /dev/null and b/study_clang/fork/fork_test differ diff --git a/study_clang/fork/fork_test.c b/study_clang/fork/fork_test.c new file mode 100644 index 0000000..414de52 --- /dev/null +++ b/study_clang/fork/fork_test.c @@ -0,0 +1,63 @@ +/************************************************************************* + > File Name : fork_test.c + > Author : TL Song + > EMail : songtianlun@frytea.com + > Created Time : Wed 23 Dec 2020 08:46:47 AM CST + ************************************************************************/ + +#include +#include +#include +#include + +int main(int arg,char* argv[]) { + + int i = 0; + time_t t; + struct tm *timeinfo; + // int 被 typedef为 pid_t + pid_t pid=fork(); + + // 当pid==0时,是子进程代码运行区域。其他则是父进程运行区域。 + if(pid<0) { + printf("Create child process failure ...\n"); + }else if(pid==0) { + //子进程执行体 + printf("Hi i am child process ,my processId is %i \n",getpid()); + i = 0; + while (1) { + sleep(1); + time(&t); + timeinfo = localtime(&t); + printf("Child: %d %s\n", i++, asctime(timeinfo)); + fflush(stdout); + if(i>100) + break; + } + } + else{ + //父进程执行体 + printf("parent process is run ,myid is %i \n",getpid()); + i = 0; + while (1) { + sleep(1); + time(&t); + timeinfo = localtime(&t); + printf("Main : %d %s\n", i++, asctime(timeinfo)); + fflush(stdout); + if(i>100) + break; + } + } + // 执行体结束标志 + if(pid==0) { + printf("pid=%i child process end ... \n",getpid()); + } + else { + // 睡眠5s,等待子先进程结束 + sleep(5); + printf("pid=%i Parent process End ... \n",getpid()); + } + + return 0; +} diff --git a/study_clang/fork/fork_test_ipc b/study_clang/fork/fork_test_ipc new file mode 100755 index 0000000..b6d1545 Binary files /dev/null and b/study_clang/fork/fork_test_ipc differ diff --git a/study_clang/fork/fork_test_ipc.c b/study_clang/fork/fork_test_ipc.c new file mode 100644 index 0000000..ecb1f61 --- /dev/null +++ b/study_clang/fork/fork_test_ipc.c @@ -0,0 +1,66 @@ +/************************************************************************* + > File Name : fork_test.c + > Author : TL Song + > EMail : songtianlun@frytea.com + > Created Time : Wed 23 Dec 2020 08:46:47 AM CST + ************************************************************************/ + +#include +#include +#include +/* IPC */ +#include +#include +#include + +int main(int arg,char* argv[]) { + + int i = 0; + time_t t; + struct tm *timeinfo; + // int 被 typedef为 pid_t + pid_t pid=fork(); + + // 当pid==0时,是子进程代码运行区域。其他则是父进程运行区域。 + if(pid<0) { + printf("Create child process failure ...\n"); + }else if(pid==0) { + //子进程执行体 + printf("Hi i am child process ,my processId is %i \n",getpid()); + i = 0; + while (1) { + sleep(1); + time(&t); + timeinfo = localtime(&t); + printf("Child: %d %s\n", i++, asctime(timeinfo)); + fflush(stdout); + if(i>100) + break; + } + } + else{ + //父进程执行体 + printf("parent process is run ,myid is %i \n",getpid()); + i = 0; + while (1) { + sleep(1); + time(&t); + timeinfo = localtime(&t); + printf("Main : %d %s\n", i++, asctime(timeinfo)); + fflush(stdout); + if(i>100) + break; + } + } + // 执行体结束标志 + if(pid==0) { + printf("pid=%i child process end ... \n",getpid()); + } + else { + // 睡眠5s,等待子先进程结束 + sleep(5); + printf("pid=%i Parent process End ... \n",getpid()); + } + + return 0; +} diff --git a/study_clang/gcc/a.out b/study_clang/gcc/a.out new file mode 100755 index 0000000..8e7e3a9 Binary files /dev/null and b/study_clang/gcc/a.out differ diff --git a/study_clang/gcc/hello b/study_clang/gcc/hello new file mode 100755 index 0000000..8e7e3a9 Binary files /dev/null and b/study_clang/gcc/hello differ diff --git a/study_clang/gcc/hello.c b/study_clang/gcc/hello.c new file mode 100644 index 0000000..663b16a --- /dev/null +++ b/study_clang/gcc/hello.c @@ -0,0 +1,6 @@ +# include +void main() +{ + char msg[80] = "Hello, World!"; + printf("%s\n",msg); +} diff --git a/study_clang/gcc/hello.i b/study_clang/gcc/hello.i new file mode 100644 index 0000000..d95b108 --- /dev/null +++ b/study_clang/gcc/hello.i @@ -0,0 +1,842 @@ +# 1 "hello.c" +# 1 "" +# 1 "" +# 1 "/usr/include/stdc-predef.h" 1 3 4 +# 1 "" 2 +# 1 "hello.c" +# 1 "/usr/include/stdio.h" 1 3 4 +# 27 "/usr/include/stdio.h" 3 4 +# 1 "/usr/include/features.h" 1 3 4 +# 375 "/usr/include/features.h" 3 4 +# 1 "/usr/include/sys/cdefs.h" 1 3 4 +# 392 "/usr/include/sys/cdefs.h" 3 4 +# 1 "/usr/include/bits/wordsize.h" 1 3 4 +# 393 "/usr/include/sys/cdefs.h" 2 3 4 +# 376 "/usr/include/features.h" 2 3 4 +# 399 "/usr/include/features.h" 3 4 +# 1 "/usr/include/gnu/stubs.h" 1 3 4 +# 10 "/usr/include/gnu/stubs.h" 3 4 +# 1 "/usr/include/gnu/stubs-64.h" 1 3 4 +# 11 "/usr/include/gnu/stubs.h" 2 3 4 +# 400 "/usr/include/features.h" 2 3 4 +# 28 "/usr/include/stdio.h" 2 3 4 + + + + + +# 1 "/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stddef.h" 1 3 4 +# 212 "/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stddef.h" 3 4 +typedef long unsigned int size_t; +# 34 "/usr/include/stdio.h" 2 3 4 + +# 1 "/usr/include/bits/types.h" 1 3 4 +# 27 "/usr/include/bits/types.h" 3 4 +# 1 "/usr/include/bits/wordsize.h" 1 3 4 +# 28 "/usr/include/bits/types.h" 2 3 4 + + +typedef unsigned char __u_char; +typedef unsigned short int __u_short; +typedef unsigned int __u_int; +typedef unsigned long int __u_long; + + +typedef signed char __int8_t; +typedef unsigned char __uint8_t; +typedef signed short int __int16_t; +typedef unsigned short int __uint16_t; +typedef signed int __int32_t; +typedef unsigned int __uint32_t; + +typedef signed long int __int64_t; +typedef unsigned long int __uint64_t; + + + + + + + +typedef long int __quad_t; +typedef unsigned long int __u_quad_t; +# 130 "/usr/include/bits/types.h" 3 4 +# 1 "/usr/include/bits/typesizes.h" 1 3 4 +# 131 "/usr/include/bits/types.h" 2 3 4 + + +typedef unsigned long int __dev_t; +typedef unsigned int __uid_t; +typedef unsigned int __gid_t; +typedef unsigned long int __ino_t; +typedef unsigned long int __ino64_t; +typedef unsigned int __mode_t; +typedef unsigned long int __nlink_t; +typedef long int __off_t; +typedef long int __off64_t; +typedef int __pid_t; +typedef struct { int __val[2]; } __fsid_t; +typedef long int __clock_t; +typedef unsigned long int __rlim_t; +typedef unsigned long int __rlim64_t; +typedef unsigned int __id_t; +typedef long int __time_t; +typedef unsigned int __useconds_t; +typedef long int __suseconds_t; + +typedef int __daddr_t; +typedef int __key_t; + + +typedef int __clockid_t; + + +typedef void * __timer_t; + + +typedef long int __blksize_t; + + + + +typedef long int __blkcnt_t; +typedef long int __blkcnt64_t; + + +typedef unsigned long int __fsblkcnt_t; +typedef unsigned long int __fsblkcnt64_t; + + +typedef unsigned long int __fsfilcnt_t; +typedef unsigned long int __fsfilcnt64_t; + + +typedef long int __fsword_t; + +typedef long int __ssize_t; + + +typedef long int __syscall_slong_t; + +typedef unsigned long int __syscall_ulong_t; + + + +typedef __off64_t __loff_t; +typedef __quad_t *__qaddr_t; +typedef char *__caddr_t; + + +typedef long int __intptr_t; + + +typedef unsigned int __socklen_t; +# 36 "/usr/include/stdio.h" 2 3 4 +# 44 "/usr/include/stdio.h" 3 4 +struct _IO_FILE; + + + +typedef struct _IO_FILE FILE; + + + + + +# 64 "/usr/include/stdio.h" 3 4 +typedef struct _IO_FILE __FILE; +# 74 "/usr/include/stdio.h" 3 4 +# 1 "/usr/include/libio.h" 1 3 4 +# 32 "/usr/include/libio.h" 3 4 +# 1 "/usr/include/_G_config.h" 1 3 4 +# 15 "/usr/include/_G_config.h" 3 4 +# 1 "/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stddef.h" 1 3 4 +# 16 "/usr/include/_G_config.h" 2 3 4 + + + + +# 1 "/usr/include/wchar.h" 1 3 4 +# 82 "/usr/include/wchar.h" 3 4 +typedef struct +{ + int __count; + union + { + + unsigned int __wch; + + + + char __wchb[4]; + } __value; +} __mbstate_t; +# 21 "/usr/include/_G_config.h" 2 3 4 +typedef struct +{ + __off_t __pos; + __mbstate_t __state; +} _G_fpos_t; +typedef struct +{ + __off64_t __pos; + __mbstate_t __state; +} _G_fpos64_t; +# 33 "/usr/include/libio.h" 2 3 4 +# 50 "/usr/include/libio.h" 3 4 +# 1 "/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stdarg.h" 1 3 4 +# 40 "/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stdarg.h" 3 4 +typedef __builtin_va_list __gnuc_va_list; +# 51 "/usr/include/libio.h" 2 3 4 +# 145 "/usr/include/libio.h" 3 4 +struct _IO_jump_t; struct _IO_FILE; +# 155 "/usr/include/libio.h" 3 4 +typedef void _IO_lock_t; + + + + + +struct _IO_marker { + struct _IO_marker *_next; + struct _IO_FILE *_sbuf; + + + + int _pos; +# 178 "/usr/include/libio.h" 3 4 +}; + + +enum __codecvt_result +{ + __codecvt_ok, + __codecvt_partial, + __codecvt_error, + __codecvt_noconv +}; +# 246 "/usr/include/libio.h" 3 4 +struct _IO_FILE { + int _flags; + + + + + char* _IO_read_ptr; + char* _IO_read_end; + char* _IO_read_base; + char* _IO_write_base; + char* _IO_write_ptr; + char* _IO_write_end; + char* _IO_buf_base; + char* _IO_buf_end; + + char *_IO_save_base; + char *_IO_backup_base; + char *_IO_save_end; + + struct _IO_marker *_markers; + + struct _IO_FILE *_chain; + + int _fileno; + + + + int _flags2; + + __off_t _old_offset; + + + + unsigned short _cur_column; + signed char _vtable_offset; + char _shortbuf[1]; + + + + _IO_lock_t *_lock; +# 294 "/usr/include/libio.h" 3 4 + __off64_t _offset; +# 303 "/usr/include/libio.h" 3 4 + void *__pad1; + void *__pad2; + void *__pad3; + void *__pad4; + size_t __pad5; + + int _mode; + + char _unused2[15 * sizeof (int) - 4 * sizeof (void *) - sizeof (size_t)]; + +}; + + +typedef struct _IO_FILE _IO_FILE; + + +struct _IO_FILE_plus; + +extern struct _IO_FILE_plus _IO_2_1_stdin_; +extern struct _IO_FILE_plus _IO_2_1_stdout_; +extern struct _IO_FILE_plus _IO_2_1_stderr_; +# 339 "/usr/include/libio.h" 3 4 +typedef __ssize_t __io_read_fn (void *__cookie, char *__buf, size_t __nbytes); + + + + + + + +typedef __ssize_t __io_write_fn (void *__cookie, const char *__buf, + size_t __n); + + + + + + + +typedef int __io_seek_fn (void *__cookie, __off64_t *__pos, int __w); + + +typedef int __io_close_fn (void *__cookie); +# 391 "/usr/include/libio.h" 3 4 +extern int __underflow (_IO_FILE *); +extern int __uflow (_IO_FILE *); +extern int __overflow (_IO_FILE *, int); +# 435 "/usr/include/libio.h" 3 4 +extern int _IO_getc (_IO_FILE *__fp); +extern int _IO_putc (int __c, _IO_FILE *__fp); +extern int _IO_feof (_IO_FILE *__fp) __attribute__ ((__nothrow__ , __leaf__)); +extern int _IO_ferror (_IO_FILE *__fp) __attribute__ ((__nothrow__ , __leaf__)); + +extern int _IO_peekc_locked (_IO_FILE *__fp); + + + + + +extern void _IO_flockfile (_IO_FILE *) __attribute__ ((__nothrow__ , __leaf__)); +extern void _IO_funlockfile (_IO_FILE *) __attribute__ ((__nothrow__ , __leaf__)); +extern int _IO_ftrylockfile (_IO_FILE *) __attribute__ ((__nothrow__ , __leaf__)); +# 465 "/usr/include/libio.h" 3 4 +extern int _IO_vfscanf (_IO_FILE * __restrict, const char * __restrict, + __gnuc_va_list, int *__restrict); +extern int _IO_vfprintf (_IO_FILE *__restrict, const char *__restrict, + __gnuc_va_list); +extern __ssize_t _IO_padn (_IO_FILE *, int, __ssize_t); +extern size_t _IO_sgetn (_IO_FILE *, void *, size_t); + +extern __off64_t _IO_seekoff (_IO_FILE *, __off64_t, int, int); +extern __off64_t _IO_seekpos (_IO_FILE *, __off64_t, int); + +extern void _IO_free_backup_area (_IO_FILE *) __attribute__ ((__nothrow__ , __leaf__)); +# 75 "/usr/include/stdio.h" 2 3 4 + + + + +typedef __gnuc_va_list va_list; +# 90 "/usr/include/stdio.h" 3 4 +typedef __off_t off_t; +# 102 "/usr/include/stdio.h" 3 4 +typedef __ssize_t ssize_t; + + + + + + + +typedef _G_fpos_t fpos_t; + + + + +# 164 "/usr/include/stdio.h" 3 4 +# 1 "/usr/include/bits/stdio_lim.h" 1 3 4 +# 165 "/usr/include/stdio.h" 2 3 4 + + + +extern struct _IO_FILE *stdin; +extern struct _IO_FILE *stdout; +extern struct _IO_FILE *stderr; + + + + + + + +extern int remove (const char *__filename) __attribute__ ((__nothrow__ , __leaf__)); + +extern int rename (const char *__old, const char *__new) __attribute__ ((__nothrow__ , __leaf__)); + + + + +extern int renameat (int __oldfd, const char *__old, int __newfd, + const char *__new) __attribute__ ((__nothrow__ , __leaf__)); + + + + + + + + +extern FILE *tmpfile (void) ; +# 209 "/usr/include/stdio.h" 3 4 +extern char *tmpnam (char *__s) __attribute__ ((__nothrow__ , __leaf__)) ; + + + + + +extern char *tmpnam_r (char *__s) __attribute__ ((__nothrow__ , __leaf__)) ; +# 227 "/usr/include/stdio.h" 3 4 +extern char *tempnam (const char *__dir, const char *__pfx) + __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__malloc__)) ; + + + + + + + + +extern int fclose (FILE *__stream); + + + + +extern int fflush (FILE *__stream); + +# 252 "/usr/include/stdio.h" 3 4 +extern int fflush_unlocked (FILE *__stream); +# 266 "/usr/include/stdio.h" 3 4 + + + + + + +extern FILE *fopen (const char *__restrict __filename, + const char *__restrict __modes) ; + + + + +extern FILE *freopen (const char *__restrict __filename, + const char *__restrict __modes, + FILE *__restrict __stream) ; +# 295 "/usr/include/stdio.h" 3 4 + +# 306 "/usr/include/stdio.h" 3 4 +extern FILE *fdopen (int __fd, const char *__modes) __attribute__ ((__nothrow__ , __leaf__)) ; +# 319 "/usr/include/stdio.h" 3 4 +extern FILE *fmemopen (void *__s, size_t __len, const char *__modes) + __attribute__ ((__nothrow__ , __leaf__)) ; + + + + +extern FILE *open_memstream (char **__bufloc, size_t *__sizeloc) __attribute__ ((__nothrow__ , __leaf__)) ; + + + + + + +extern void setbuf (FILE *__restrict __stream, char *__restrict __buf) __attribute__ ((__nothrow__ , __leaf__)); + + + +extern int setvbuf (FILE *__restrict __stream, char *__restrict __buf, + int __modes, size_t __n) __attribute__ ((__nothrow__ , __leaf__)); + + + + + +extern void setbuffer (FILE *__restrict __stream, char *__restrict __buf, + size_t __size) __attribute__ ((__nothrow__ , __leaf__)); + + +extern void setlinebuf (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)); + + + + + + + + +extern int fprintf (FILE *__restrict __stream, + const char *__restrict __format, ...); + + + + +extern int printf (const char *__restrict __format, ...); + +extern int sprintf (char *__restrict __s, + const char *__restrict __format, ...) __attribute__ ((__nothrow__)); + + + + + +extern int vfprintf (FILE *__restrict __s, const char *__restrict __format, + __gnuc_va_list __arg); + + + + +extern int vprintf (const char *__restrict __format, __gnuc_va_list __arg); + +extern int vsprintf (char *__restrict __s, const char *__restrict __format, + __gnuc_va_list __arg) __attribute__ ((__nothrow__)); + + + + + +extern int snprintf (char *__restrict __s, size_t __maxlen, + const char *__restrict __format, ...) + __attribute__ ((__nothrow__)) __attribute__ ((__format__ (__printf__, 3, 4))); + +extern int vsnprintf (char *__restrict __s, size_t __maxlen, + const char *__restrict __format, __gnuc_va_list __arg) + __attribute__ ((__nothrow__)) __attribute__ ((__format__ (__printf__, 3, 0))); + +# 412 "/usr/include/stdio.h" 3 4 +extern int vdprintf (int __fd, const char *__restrict __fmt, + __gnuc_va_list __arg) + __attribute__ ((__format__ (__printf__, 2, 0))); +extern int dprintf (int __fd, const char *__restrict __fmt, ...) + __attribute__ ((__format__ (__printf__, 2, 3))); + + + + + + + + +extern int fscanf (FILE *__restrict __stream, + const char *__restrict __format, ...) ; + + + + +extern int scanf (const char *__restrict __format, ...) ; + +extern int sscanf (const char *__restrict __s, + const char *__restrict __format, ...) __attribute__ ((__nothrow__ , __leaf__)); +# 443 "/usr/include/stdio.h" 3 4 +extern int fscanf (FILE *__restrict __stream, const char *__restrict __format, ...) __asm__ ("" "__isoc99_fscanf") + + ; +extern int scanf (const char *__restrict __format, ...) __asm__ ("" "__isoc99_scanf") + ; +extern int sscanf (const char *__restrict __s, const char *__restrict __format, ...) __asm__ ("" "__isoc99_sscanf") __attribute__ ((__nothrow__ , __leaf__)) + + ; +# 463 "/usr/include/stdio.h" 3 4 + + + + + + + + +extern int vfscanf (FILE *__restrict __s, const char *__restrict __format, + __gnuc_va_list __arg) + __attribute__ ((__format__ (__scanf__, 2, 0))) ; + + + + + +extern int vscanf (const char *__restrict __format, __gnuc_va_list __arg) + __attribute__ ((__format__ (__scanf__, 1, 0))) ; + + +extern int vsscanf (const char *__restrict __s, + const char *__restrict __format, __gnuc_va_list __arg) + __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__format__ (__scanf__, 2, 0))); +# 494 "/usr/include/stdio.h" 3 4 +extern int vfscanf (FILE *__restrict __s, const char *__restrict __format, __gnuc_va_list __arg) __asm__ ("" "__isoc99_vfscanf") + + + + __attribute__ ((__format__ (__scanf__, 2, 0))) ; +extern int vscanf (const char *__restrict __format, __gnuc_va_list __arg) __asm__ ("" "__isoc99_vscanf") + + __attribute__ ((__format__ (__scanf__, 1, 0))) ; +extern int vsscanf (const char *__restrict __s, const char *__restrict __format, __gnuc_va_list __arg) __asm__ ("" "__isoc99_vsscanf") __attribute__ ((__nothrow__ , __leaf__)) + + + + __attribute__ ((__format__ (__scanf__, 2, 0))); +# 522 "/usr/include/stdio.h" 3 4 + + + + + + + + + +extern int fgetc (FILE *__stream); +extern int getc (FILE *__stream); + + + + + +extern int getchar (void); + +# 550 "/usr/include/stdio.h" 3 4 +extern int getc_unlocked (FILE *__stream); +extern int getchar_unlocked (void); +# 561 "/usr/include/stdio.h" 3 4 +extern int fgetc_unlocked (FILE *__stream); + + + + + + + + + + + +extern int fputc (int __c, FILE *__stream); +extern int putc (int __c, FILE *__stream); + + + + + +extern int putchar (int __c); + +# 594 "/usr/include/stdio.h" 3 4 +extern int fputc_unlocked (int __c, FILE *__stream); + + + + + + + +extern int putc_unlocked (int __c, FILE *__stream); +extern int putchar_unlocked (int __c); + + + + + + +extern int getw (FILE *__stream); + + +extern int putw (int __w, FILE *__stream); + + + + + + + + +extern char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream) + ; +# 638 "/usr/include/stdio.h" 3 4 +extern char *gets (char *__s) __attribute__ ((__deprecated__)); + + +# 665 "/usr/include/stdio.h" 3 4 +extern __ssize_t __getdelim (char **__restrict __lineptr, + size_t *__restrict __n, int __delimiter, + FILE *__restrict __stream) ; +extern __ssize_t getdelim (char **__restrict __lineptr, + size_t *__restrict __n, int __delimiter, + FILE *__restrict __stream) ; + + + + + + + +extern __ssize_t getline (char **__restrict __lineptr, + size_t *__restrict __n, + FILE *__restrict __stream) ; + + + + + + + + +extern int fputs (const char *__restrict __s, FILE *__restrict __stream); + + + + + +extern int puts (const char *__s); + + + + + + +extern int ungetc (int __c, FILE *__stream); + + + + + + +extern size_t fread (void *__restrict __ptr, size_t __size, + size_t __n, FILE *__restrict __stream) ; + + + + +extern size_t fwrite (const void *__restrict __ptr, size_t __size, + size_t __n, FILE *__restrict __s); + +# 737 "/usr/include/stdio.h" 3 4 +extern size_t fread_unlocked (void *__restrict __ptr, size_t __size, + size_t __n, FILE *__restrict __stream) ; +extern size_t fwrite_unlocked (const void *__restrict __ptr, size_t __size, + size_t __n, FILE *__restrict __stream); + + + + + + + + +extern int fseek (FILE *__stream, long int __off, int __whence); + + + + +extern long int ftell (FILE *__stream) ; + + + + +extern void rewind (FILE *__stream); + +# 773 "/usr/include/stdio.h" 3 4 +extern int fseeko (FILE *__stream, __off_t __off, int __whence); + + + + +extern __off_t ftello (FILE *__stream) ; +# 792 "/usr/include/stdio.h" 3 4 + + + + + + +extern int fgetpos (FILE *__restrict __stream, fpos_t *__restrict __pos); + + + + +extern int fsetpos (FILE *__stream, const fpos_t *__pos); +# 815 "/usr/include/stdio.h" 3 4 + +# 824 "/usr/include/stdio.h" 3 4 + + +extern void clearerr (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)); + +extern int feof (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ; + +extern int ferror (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ; + + + + +extern void clearerr_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)); +extern int feof_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ; +extern int ferror_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ; + + + + + + + + +extern void perror (const char *__s); + + + + + + +# 1 "/usr/include/bits/sys_errlist.h" 1 3 4 +# 26 "/usr/include/bits/sys_errlist.h" 3 4 +extern int sys_nerr; +extern const char *const sys_errlist[]; +# 854 "/usr/include/stdio.h" 2 3 4 + + + + +extern int fileno (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ; + + + + +extern int fileno_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ; +# 873 "/usr/include/stdio.h" 3 4 +extern FILE *popen (const char *__command, const char *__modes) ; + + + + + +extern int pclose (FILE *__stream); + + + + + +extern char *ctermid (char *__s) __attribute__ ((__nothrow__ , __leaf__)); +# 913 "/usr/include/stdio.h" 3 4 +extern void flockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)); + + + +extern int ftrylockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ; + + +extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)); +# 943 "/usr/include/stdio.h" 3 4 + +# 2 "hello.c" 2 +void main() +{ + char msg[80] = "Hello, World!"; + printf("%s\n",msg); +} diff --git a/study_clang/gcc/hello.o b/study_clang/gcc/hello.o new file mode 100644 index 0000000..5d9d92d Binary files /dev/null and b/study_clang/gcc/hello.o differ diff --git a/study_clang/gcc/hello.s b/study_clang/gcc/hello.s new file mode 100644 index 0000000..341de6f --- /dev/null +++ b/study_clang/gcc/hello.s @@ -0,0 +1,34 @@ + .file "hello.c" + .text + .globl main + .type main, @function +main: +.LFB0: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $80, %rsp + movabsq $6278066737626506568, %rax + movq %rax, -80(%rbp) + movabsq $143418749551, %rax + movq %rax, -72(%rbp) + leaq -64(%rbp), %rsi + movl $0, %eax + movl $8, %edx + movq %rsi, %rdi + movq %rdx, %rcx + rep stosq + leaq -80(%rbp), %rax + movq %rax, %rdi + call puts + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE0: + .size main, .-main + .ident "GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-39)" + .section .note.GNU-stack,"",@progbits diff --git a/study_clang/gcc/hello_o b/study_clang/gcc/hello_o new file mode 100755 index 0000000..8e7e3a9 Binary files /dev/null and b/study_clang/gcc/hello_o differ diff --git a/study_clang/ini/Config.ini b/study_clang/ini/Config.ini new file mode 100644 index 0000000..1f1782d --- /dev/null +++ b/study_clang/ini/Config.ini @@ -0,0 +1,11 @@ +[EMPLOYEEINFO] +;the name of employee +EmployeeName=wang +;the age of employee +EmployeeAge=25 + +[EMPLOYERINFO] +;the name of employer +EmployerName=zhou +;the age of employer +EmployerAge=38 \ No newline at end of file diff --git a/study_clang/ini/GetConfig b/study_clang/ini/GetConfig new file mode 100755 index 0000000..c7d6bf1 Binary files /dev/null and b/study_clang/ini/GetConfig differ diff --git a/study_clang/ini/GetConfig.c b/study_clang/ini/GetConfig.c new file mode 100644 index 0000000..531977b --- /dev/null +++ b/study_clang/ini/GetConfig.c @@ -0,0 +1,335 @@ +/********************************************************************** +* 版权所有 (C)2015, Zhou Zhaoxiong。 +* +* 文件名称:GetConfig.c +* 文件标识:无 +* 内容摘要:演示Linux下配置文件的读取方法 +* 其它说明:无 +* 当前版本:V1.0 +* 作 者:Zhou Zhaoxiong +* 完成日期:20150507 +* +**********************************************************************/ +#include +#include +#include + +// 数据类型重定义 +typedef unsigned char UINT8; +typedef signed int INT32; +typedef unsigned int UINT32; + +// 员工信息结构体定义 +typedef struct +{ + UINT8 szEmployeeName[128]; // 员工姓名 + INT32 iEmployeeAge; // 员工年龄 +} T_EmployeeInfo; + +// 雇主信息结构体定义 +typedef struct +{ + UINT8 szEmployerName[128]; // 雇主姓名 + INT32 iEmployerAge; // 雇主年龄 +} T_EmployerInfo; + +// 函数声明 +void GetCompletePath(UINT8 *pszConfigFileName, UINT8 *pszWholePath); +void GetStringContentValue(FILE *fp, UINT8 *pszSectionName, UINT8 *pszKeyName, UINT8 *pszOutput, UINT32 iOutputLen); +void GetConfigFileStringValue(UINT8 *pszSectionName, UINT8 *pszKeyName, UINT8 *pDefaultVal, UINT8 *pszOutput, UINT32 iOutputLen, UINT8 *pszConfigFileName); +INT32 GetConfigFileIntValue(UINT8 *pszSectionName, UINT8 *pszKeyName, UINT32 iDefaultVal, UINT8 *pszConfigFileName); +INT32 main(); + + +/********************************************************************** +* 功能描述:主函数 +* 输入参数:无 +* 输出参数:无 +* 返 回 值:无 +* 其它说明:无 +* 修改日期 版本号 修改人 修改内容 +* --------------------------------------------------------------- +* 20150507 V1.0 Zhou Zhaoxiong 创建 +***********************************************************************/ +INT32 main() +{ + T_EmployeeInfo tEmployeeInfo = {0}; + T_EmployerInfo tEmployerInfo = {0}; + + // 获取并打印员工信息 + // 获取员工姓名 + GetConfigFileStringValue("EMPLOYEEINFO", "EmployeeName", "", tEmployeeInfo.szEmployeeName, sizeof(tEmployeeInfo.szEmployeeName), "Config.ini"); + + // 获取员工年龄 + tEmployeeInfo.iEmployeeAge = GetConfigFileIntValue("EMPLOYEEINFO", "EmployeeAge", 20, "Config.ini"); + if (tEmployeeInfo.iEmployeeAge == -1) // 判断获取到的年龄是否正确 + { + printf("Get EmployeeAge failed!\n"); + return -1; + } + + // 打印读取到的员工姓名和年龄 + printf("EmployeeName is %s, EmployeeAge is %d\n", tEmployeeInfo.szEmployeeName, tEmployeeInfo.iEmployeeAge); + + // 获取并打印雇主信息 + // 获取雇主姓名 + GetConfigFileStringValue("EMPLOYERINFO", "EmployerName", "", tEmployerInfo.szEmployerName, sizeof(tEmployerInfo.szEmployerName), "Config.ini"); + + // 获取员工年龄 + tEmployerInfo.iEmployerAge = GetConfigFileIntValue("EMPLOYERINFO", "EmployerAge", 30, "Config.ini"); + if (tEmployerInfo.iEmployerAge == -1) // 判断获取到的年龄是否正确 + { + printf("Get EmployerAge failed!\n"); + return -1; + } + + // 打印读取到的员工姓名和年龄 + printf("EmployerName is %s, EmployerAge is %d\n", tEmployerInfo.szEmployerName, tEmployerInfo.iEmployerAge); + + return 0; +} + + +/********************************************************************** +* 功能描述: 获取配置文件完整路径(包含文件名) +* 输入参数: pszConfigFileName-配置文件名 + pszWholePath-配置文件完整路径(包含文件名) +* 输出参数: 无 +* 返 回 值: 无 +* 其它说明: 无 +* 修改日期 版本号 修改人 修改内容 +* ------------------------------------------------------------------ +* 20150507 V1.0 Zhou Zhaoxiong 创建 +********************************************************************/ +void GetCompletePath(UINT8 *pszConfigFileName, UINT8 *pszWholePath) +{ + UINT8 *pszHomePath = NULL; + UINT8 szWholePath[256] = {0}; + + // 先对输入参数进行异常判断 + if (pszConfigFileName == NULL || pszWholePath == NULL) + { + printf("GetCompletePath: input parameter(s) is NULL!\n"); + return; + } + + pszHomePath = (UINT8 *)getenv("HOME"); // 获取当前用户所在的路径 + if (pszHomePath == NULL) + { + printf("GetCompletePath: Can't find home path!\n"); + return; + } + + // 拼装配置文件路径 + snprintf(szWholePath, sizeof(szWholePath)-1, "%s/PracticeDev/ini/%s", pszHomePath, pszConfigFileName); + + strncpy(pszWholePath, szWholePath, strlen(szWholePath)); +} + + +/********************************************************************** +* 功能描述: 获取具体的字符串值 +* 输入参数: fp-配置文件指针 + pszSectionName-段名, 如: GENERAL + pszKeyName-配置项名, 如: EmployeeName + iOutputLen-输出缓存长度 +* 输出参数: pszOutput-输出缓存 +* 返 回 值: 无 +* 其它说明: 无 +* 修改日期 版本号 修改人 修改内容 +* ------------------------------------------------------------------ +* 20150507 V1.0 Zhou Zhaoxiong 创建 +********************************************************************/ +void GetStringContentValue(FILE *fp, UINT8 *pszSectionName, UINT8 *pszKeyName, UINT8 *pszOutput, UINT32 iOutputLen) +{ + UINT8 szSectionName[100] = {0}; + UINT8 szKeyName[100] = {0}; + UINT8 szContentLine[256] = {0}; + UINT8 szContentLineBak[256] = {0}; + UINT32 iContentLineLen = 0; + UINT32 iPositionFlag = 0; + + // 先对输入参数进行异常判断 + if (fp == NULL || pszSectionName == NULL || pszKeyName == NULL || pszOutput == NULL) + { + printf("GetStringContentValue: input parameter(s) is NULL!\n"); + return; + } + + sprintf(szSectionName, "[%s]", pszSectionName); + strcpy(szKeyName, pszKeyName); + + while (feof(fp) == 0) + { + memset(szContentLine, 0x00, sizeof(szContentLine)); + fgets(szContentLine, sizeof(szContentLine), fp); // 获取段名 + + // 判断是否是注释行(以;开头的行就是注释行)或以其他特殊字符开头的行 + if (szContentLine[0] == ';' || szContentLine[0] == '\r' || szContentLine[0] == '\n' || szContentLine[0] == '\0') + { + continue; + } + + // 匹配段名 + if (strncasecmp(szSectionName, szContentLine, strlen(szSectionName)) == 0) + { + while (feof(fp) == 0) + { + memset(szContentLine, 0x00, sizeof(szContentLine)); + memset(szContentLineBak, 0x00, sizeof(szContentLineBak)); + fgets(szContentLine, sizeof(szContentLine), fp); // 获取字段值 + + // 判断是否是注释行(以;开头的行就是注释行) + if (szContentLine[0] == ';') + { + continue; + } + + memcpy(szContentLineBak, szContentLine, strlen(szContentLine)); + + // 匹配配置项名 + if (strncasecmp(szKeyName, szContentLineBak, strlen(szKeyName)) == 0) + { + iContentLineLen = strlen(szContentLine); + for (iPositionFlag = strlen(szKeyName); iPositionFlag <= iContentLineLen; iPositionFlag ++) + { + if (szContentLine[iPositionFlag] == ' ') + { + continue; + } + if (szContentLine[iPositionFlag] == '=') + { + break; + } + + iPositionFlag = iContentLineLen + 1; + break; + } + + iPositionFlag = iPositionFlag + 1; // 跳过=的位置 + + if (iPositionFlag > iContentLineLen) + { + continue; + } + + memset(szContentLine, 0x00, sizeof(szContentLine)); + strcpy(szContentLine, szContentLineBak + iPositionFlag); + + // 去掉内容中的无关字符 + for (iPositionFlag = 0; iPositionFlag < strlen(szContentLine); iPositionFlag ++) + { + if (szContentLine[iPositionFlag] == '\r' || szContentLine[iPositionFlag] == '\n' || szContentLine[iPositionFlag] == '\0') + { + szContentLine[iPositionFlag] = '\0'; + break; + } + } + + // 将配置项内容拷贝到输出缓存中 + strncpy(pszOutput, szContentLine, iOutputLen-1); + break; + } + else if (szContentLine[0] == '[') + { + break; + } + } + break; + } + } +} + + +/********************************************************************** +* 功能描述: 从配置文件中获取字符串 +* 输入参数: pszSectionName-段名, 如: GENERAL + pszKeyName-配置项名, 如: EmployeeName + pDefaultVal-默认值 + iOutputLen-输出缓存长度 + pszConfigFileName-配置文件名 +* 输出参数: pszOutput-输出缓存 +* 返 回 值: 无 +* 其它说明: 无 +* 修改日期 版本号 修改人 修改内容 +* ------------------------------------------------------------------ +* 20150507 V1.0 Zhou Zhaoxiong 创建 +********************************************************************/ +void GetConfigFileStringValue(UINT8 *pszSectionName, UINT8 *pszKeyName, UINT8 *pDefaultVal, UINT8 *pszOutput, UINT32 iOutputLen, UINT8 *pszConfigFileName) +{ + FILE *fp = NULL; + UINT8 szWholePath[256] = {0}; + + // 先对输入参数进行异常判断 + if (pszSectionName == NULL || pszKeyName == NULL || pszOutput == NULL || pszConfigFileName == NULL) + { + printf("GetConfigFileStringValue: input parameter(s) is NULL!\n"); + return; + } + + // 获取默认值 + if (pDefaultVal == NULL) + { + strcpy(pszOutput, ""); + } + else + { + strcpy(pszOutput, pDefaultVal); + } + + // 打开配置文件 + GetCompletePath(pszConfigFileName, szWholePath); + fp = fopen(szWholePath, "r"); + if (fp == NULL) + { + printf("GetConfigFileStringValue: open %s failed!\n", szWholePath); + return; + } + + // 调用函数用于获取具体配置项的值 + GetStringContentValue(fp, pszSectionName, pszKeyName, pszOutput, iOutputLen); + + // 关闭文件 + fclose(fp); + fp = NULL; +} + + +/********************************************************************** +* 功能描述: 从配置文件中获取整型变量 +* 输入参数: pszSectionName-段名, 如: GENERAL + pszKeyName-配置项名, 如: EmployeeName + iDefaultVal-默认值 + pszConfigFileName-配置文件名 +* 输出参数: 无 +* 返 回 值: iGetValue-获取到的整数值 -1-获取失败 +* 其它说明: 无 +* 修改日期 版本号 修改人 修改内容 +* ------------------------------------------------------------------ +* 20150507 V1.0 Zhou Zhaoxiong 创建 +********************************************************************/ +INT32 GetConfigFileIntValue(UINT8 *pszSectionName, UINT8 *pszKeyName, UINT32 iDefaultVal, UINT8 *pszConfigFileName) +{ + UINT8 szGetValue[512] = {0}; + INT32 iGetValue = 0; + + // 先对输入参数进行异常判断 + if (pszSectionName == NULL || pszKeyName == NULL || pszConfigFileName == NULL) + { + printf("GetConfigFileIntValue: input parameter(s) is NULL!\n"); + return -1; + } + + GetConfigFileStringValue(pszSectionName, pszKeyName, NULL, szGetValue, 512-1, pszConfigFileName); // 先将获取的值存放在字符型缓存中 + + if (szGetValue[0] == '\0' || szGetValue[0] == ';') // 如果是结束符或分号, 则使用默认值 + { + iGetValue = iDefaultVal; + } + else + { + iGetValue = atoi(szGetValue); + } + + return iGetValue; +} diff --git a/study_clang/ipc_test/Makefile b/study_clang/ipc_test/Makefile new file mode 100644 index 0000000..b10df75 --- /dev/null +++ b/study_clang/ipc_test/Makefile @@ -0,0 +1,22 @@ +# Batch Single C file MakeFile + +# 指定CPU架构 Architecture -> ARCH +ARCH ?= +CC = $(ARCH)gcc +SUFFIX = .c +CFLAGS += -Wall -g +LD = + +CUR_SOURCE = $(wildcard *$(SUFFIX)) +CUR_TARGETS = $(patsubst %$(SUFFIX), %, $(CUR_SOURCE)) + +all:$(CUR_TARGETS) + +# %:%.c 是一个表示与目标相同 文件的模式变量 +$(CUR_TARGETS):%:%$(SUFFIX) + $(CC) $< $(CFLAGS) -o $@ $(LD) + +# 指定伪目标 +.PHONY:clean all + clean: + -rm -rf $(TARGETS) diff --git a/study_clang/ipc_test/ipc_pip_named_read b/study_clang/ipc_test/ipc_pip_named_read new file mode 100755 index 0000000..7a8225b Binary files /dev/null and b/study_clang/ipc_test/ipc_pip_named_read differ diff --git a/study_clang/ipc_test/ipc_pip_named_read.c b/study_clang/ipc_test/ipc_pip_named_read.c new file mode 100644 index 0000000..d9211e1 --- /dev/null +++ b/study_clang/ipc_test/ipc_pip_named_read.c @@ -0,0 +1,50 @@ +/************************************************************************* + > File Name : ipc_pip_named_read.c + > Author : TL Song + > EMail : songtianlun@frytea.com + > Created Time : Mon 28 Dec 2020 03:51:07 PM CST + ************************************************************************/ +//reading +#include +#include +#include +#include +#include +#include +#include +#include +#define N 80 + +int main(void) { + int in_file; + int count = 1; + char buf[N]; + if((mkfifo("myfifo",0666))<0)//创建有名管道 + { + if(errno==EEXIST)//管道已经存在 + { + printf("The fifo is exist.\n"); + } + else{ + printf("creat myfifo failed!\n"); + exit(-1); + } + } + else + { + printf("created by this process.\n"); + } + in_file = open("myfifo",O_RDONLY); + if (in_file < 0) { + printf("Error in opening.\n"); + exit(1); + } + + while ((count = read(in_file,buf,N)) > 0) + { + printf("received from fifo: %s\n", buf); + memset(buf,0,N); + } + close(in_file); + return 0; +} diff --git a/study_clang/ipc_test/ipc_pip_named_writ b/study_clang/ipc_test/ipc_pip_named_writ new file mode 100755 index 0000000..2421029 Binary files /dev/null and b/study_clang/ipc_test/ipc_pip_named_writ differ diff --git a/study_clang/ipc_test/ipc_pip_named_writ.c b/study_clang/ipc_test/ipc_pip_named_writ.c new file mode 100644 index 0000000..3c09e5b --- /dev/null +++ b/study_clang/ipc_test/ipc_pip_named_writ.c @@ -0,0 +1,49 @@ +/************************************************************************* + > File Name : ipc_pip_named_writ.c + > Author : TL Song + > EMail : songtianlun@frytea.com + > Created Time : Mon 28 Dec 2020 03:49:50 PM CST + ************************************************************************/ + +//writing +#include +#include +#include +#include +#include +#include +#include +#include + +#define N 80 + +int main() { + int out_file; + int nbyte; + char buf[N]; + if((mkfifo("myfifo",0666))<0) //创建有名管道 + { + if(errno==EEXIST) + { + printf("The fifo is exist.\n"); + } + else{ + perror("creat myfifo failed!\n"); + exit(-1); + } + }else{ + printf("created by this process.\n"); + } + out_file = open("myfifo",O_WRONLY); + if (out_file < 0) { + printf("Error opening fifo."); + exit(1); + } + printf("please input something:\n"); + while((nbyte = read(0,buf,N))){ + write(out_file,buf,nbyte); + printf("please input something:\n"); + } + close(out_file); + return 0; +} diff --git a/study_clang/ipc_test/ipc_pip_nameless b/study_clang/ipc_test/ipc_pip_nameless new file mode 100755 index 0000000..ed7d413 Binary files /dev/null and b/study_clang/ipc_test/ipc_pip_nameless differ diff --git a/study_clang/ipc_test/ipc_pip_nameless.c b/study_clang/ipc_test/ipc_pip_nameless.c new file mode 100644 index 0000000..2cec091 --- /dev/null +++ b/study_clang/ipc_test/ipc_pip_nameless.c @@ -0,0 +1,54 @@ +/************************************************************************* + > File Name : ipc_pip_nameless.c + > Author : TL Song + > EMail : songtianlun@frytea.com + > Created Time : Mon 28 Dec 2020 03:46:41 PM CST + ************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +int main() +{ + int pipe_fd[2]; + pid_t pid; + char r_buf[10]; + char w_buf[4]; + int r_num; + + memset(r_buf,0,sizeof(r_buf)); + memset(w_buf,0,sizeof(w_buf)); + if(pipe(pipe_fd)<0) + { + printf("pipe create error\n"); + return -1; + } + + if((pid=fork())==0) + { + printf("\n"); + close(pipe_fd[1]); + sleep(3);//确保父进程关闭写端 + r_num=read(pipe_fd[0],r_buf,10); + printf( "read num is %d the data read from the pipe is %d\n",r_num,atoi(r_buf)); + + close(pipe_fd[0]); + exit(1); + } + else if(pid>0) + { + close(pipe_fd[0]);//close read + strcpy(w_buf,"111"); + if(write(pipe_fd[1],w_buf,4)!=-1) + printf("parent write over\n"); + printf("parent close fd[1] over\n"); + close(pipe_fd[1]);//write + sleep(10); + } + return 0; +} diff --git a/study_clang/ipc_test/ipc_unix_socket_client b/study_clang/ipc_test/ipc_unix_socket_client new file mode 100755 index 0000000..0c6de55 Binary files /dev/null and b/study_clang/ipc_test/ipc_unix_socket_client differ diff --git a/study_clang/ipc_test/ipc_unix_socket_client.c b/study_clang/ipc_test/ipc_unix_socket_client.c new file mode 100644 index 0000000..3256acd --- /dev/null +++ b/study_clang/ipc_test/ipc_unix_socket_client.c @@ -0,0 +1,54 @@ +/************************************************************************* + > File Name : ipc_unix_socket_client.c + > Author : TL Song + > EMail : songtianlun@frytea.com + > Created Time : Thu 31 Dec 2020 08:55:49 AM CST + ************************************************************************/ +#include +#include +#include +#include +#include + +const char path[]="/tmp/server"; +int main(){ + int server_fd,client_fd; + struct sockaddr_un server_addr, client_addr; + //unlink(path); + server_fd = socket(AF_UNIX,SOCK_STREAM,0); + if(server_fd == -1){ + perror("socket: "); + exit(1); + } + server_addr.sun_family=AF_UNIX; + strcpy(server_addr.sun_path,path); + if(connect(server_fd,(struct sockaddr *)&server_addr,sizeof(server_addr)) == -1){ + perror("connect: "); + exit(1); + } + char recv[105],send[105]; + int i; + puts("the client started, please enter your message: "); + while(1){ + memset(send,0,sizeof(send)); + if(read(STDIN_FILENO,send,105)==-1){ + perror("read: "); + break; + } + if(write(server_fd,send,strlen(send))==-1){ + perror("send: "); + break; + } + if(strcmp(send,"end\n")==0){ + printf("the client process end.\n"); + break; + } + memset(recv,0,sizeof(recv)); + if(read(server_fd,recv,105)==-1){ + perror("recv: "); + break; + } + printf("recv message from server: %s",recv); + } + close(server_fd); +} diff --git a/study_clang/ipc_test/ipc_unix_socket_server b/study_clang/ipc_test/ipc_unix_socket_server new file mode 100755 index 0000000..6d0ca57 Binary files /dev/null and b/study_clang/ipc_test/ipc_unix_socket_server differ diff --git a/study_clang/ipc_test/ipc_unix_socket_server.c b/study_clang/ipc_test/ipc_unix_socket_server.c new file mode 100644 index 0000000..cda459b --- /dev/null +++ b/study_clang/ipc_test/ipc_unix_socket_server.c @@ -0,0 +1,62 @@ +/************************************************************************* + > File Name : ipc_unix_socket_server.c + > Author : TL Song + > EMail : songtianlun@frytea.com + > Created Time : Thu 31 Dec 2020 08:55:11 AM CST + ************************************************************************/ +#include +#include +#include +#include +#include + +const char path[]="/tmp/server"; +int main(){ + int server_fd,client_fd; + struct sockaddr_un server_addr, client_addr; + unlink(path); + server_fd = socket(AF_UNIX,SOCK_STREAM,0); + if(server_fd == -1){ + perror("socket: "); + exit(1); + } + server_addr.sun_family=AF_UNIX; + strcpy(server_addr.sun_path,path); + if(bind(server_fd,(struct sockaddr *)&server_addr,sizeof(server_addr))==-1){ + perror("bind: "); + exit(1); + } + listen(server_fd,10); //server listen most 10 requests. + puts("server is listening: "); + int client_len=sizeof(client_addr); + client_fd=accept(server_fd,(struct sockaddr *)&client_addr,(int *)&client_len); + if(client_fd == -1){ + perror("accept: "); + exit(1); + } + char recv[105], send[105]; + int i; + while(1){ + memset(recv,0,sizeof(recv)); + if(read(client_fd,recv,105)==-1){ + perror("read: "); + break; + } + if(strcmp(recv,"end\n")==0){ + printf("the server process end.\n"); + break; + } + printf("recv message from client: %s",recv); + memset(send,0,sizeof(send)); + if(read(STDIN_FILENO,send,sizeof(send))==-1){ + perror("read: "); + break; + } + if(write(client_fd,send,strlen(send))==-1){ + perror("write: "); + break; + } + } + close(server_fd); + unlink(path); +} diff --git a/study_clang/ipc_test/shared_mem/ipc_share_mem_client b/study_clang/ipc_test/shared_mem/ipc_share_mem_client new file mode 100755 index 0000000..8da266c Binary files /dev/null and b/study_clang/ipc_test/shared_mem/ipc_share_mem_client differ diff --git a/study_clang/ipc_test/shared_mem/ipc_share_mem_client.c b/study_clang/ipc_test/shared_mem/ipc_share_mem_client.c new file mode 100644 index 0000000..7ad5bd6 --- /dev/null +++ b/study_clang/ipc_test/shared_mem/ipc_share_mem_client.c @@ -0,0 +1,152 @@ +/************************************************************************* + > File Name : ipc_share_mem_client.c + > Author : TL Song + > EMail : songtianlun@frytea.com + > Created Time : Mon 28 Dec 2020 03:54:50 PM CST + ************************************************************************/ +#include +#include +#include // shared memory +#include // semaphore +#include // message queue +#include // memcpy + +// 消息队列结构 +struct msg_form { + long mtype; + char mtext; +}; + +// 联合体,用于semctl初始化 +union semun +{ + int val; /*for SETVAL*/ + struct semid_ds *buf; + unsigned short *array; +}; + +// P操作: +// 若信号量值为1,获取资源并将信号量值-1 +// 若信号量值为0,进程挂起等待 +int sem_p(int sem_id) +{ + struct sembuf sbuf; + sbuf.sem_num = 0; /*序号*/ + sbuf.sem_op = -1; /*P操作*/ + sbuf.sem_flg = SEM_UNDO; + + if(semop(sem_id, &sbuf, 1) == -1) + { + perror("P operation Error"); + return -1; + } + return 0; +} + +// V操作: +// 释放资源并将信号量值+1 +// 如果有进程正在挂起等待,则唤醒它们 +int sem_v(int sem_id) +{ + struct sembuf sbuf; + sbuf.sem_num = 0; /*序号*/ + sbuf.sem_op = 1; /*V操作*/ + sbuf.sem_flg = SEM_UNDO; + + if(semop(sem_id, &sbuf, 1) == -1) + { + perror("V operation Error"); + return -1; + } + return 0; +} + + +int main() +{ + key_t key; + int shmid, semid, msqid; + char *shm; + struct msg_form msg; + int flag = 1; /*while循环条件*/ + + // 获取key值 + if((key = ftok(".", 'z')) < 0) + { + perror("ftok error"); + exit(1); + } + + // 获取共享内存 + if((shmid = shmget(key, 1024, 0)) == -1) + { + perror("shmget error"); + exit(1); + } + + // 连接共享内存 + shm = (char*)shmat(shmid, 0, 0); + if((int)shm == -1) + { + perror("Attach Shared Memory Error"); + exit(1); + } + + // 创建消息队列 + if ((msqid = msgget(key, 0)) == -1) + { + perror("msgget error"); + exit(1); + } + + // 获取信号量 + if((semid = semget(key, 0, 0)) == -1) + { + perror("semget error"); + exit(1); + } + + // 写数据 + printf("***************************************\n"); + printf("* IPC *\n"); + printf("* Input r to send data to server. *\n"); + printf("* Input q to quit. *\n"); + printf("***************************************\n"); +system("/proc/$$/ns"); + while(flag) + { + char c = 'r'; + printf("Please input command: "); + //scanf("%c", &c); + switch(c) + { + case 'r': + printf("Data to send: "); + sem_p(semid); /*访问资源*/ + //scanf("%s", shm); + strcpy(shm, "hello"); + sem_v(semid); /*释放资源*/ + /*清空标准输入缓冲区*/ + while((c=getchar())!='\n' && c!=EOF); + msg.mtype = 888; + msg.mtext = 'r'; /*发送消息通知服务器读数据*/ + msgsnd(msqid, &msg, sizeof(msg.mtext), 0); + break; + case 'q': + msg.mtype = 888; + msg.mtext = 'q'; + msgsnd(msqid, &msg, sizeof(msg.mtext), 0); + flag = 0; + break; + default: + printf("Wrong input!\n"); + /*清空标准输入缓冲区*/ + while((c=getchar())!='\n' && c!=EOF); + } + } + + // 断开连接 + shmdt(shm); + + return 0; +} diff --git a/study_clang/ipc_test/shared_mem/ipc_share_mem_posix_read.c b/study_clang/ipc_test/shared_mem/ipc_share_mem_posix_read.c new file mode 100644 index 0000000..d18b0be --- /dev/null +++ b/study_clang/ipc_test/shared_mem/ipc_share_mem_posix_read.c @@ -0,0 +1,28 @@ +/************************************************************************* + > File Name : ipc_share_mem_posix_read.c + > Author : TL Song + > EMail : songtianlun@frytea.com + > Created Time : Wed 30 Dec 2020 03:22:20 PM CST + ************************************************************************/ + +#include +#include +#include +#include +#include + +int main(int argc, char ** argv) +{ + int fd = shm_open("posixsm", O_RDONLY, 0666); + ftruncate(fd, 0x400000); + + char *p = mmap(NULL, 0x400000, PROT_READ, MAP_SHARED, fd, 0); + int i = 0; + for(i = 0 ;i < 100; i++) + { + printf("Read '%c' in mem '%p'\n", *p, p); + sleep(1); + } + munmap(p, 0x400000); + return 0; +} diff --git a/study_clang/ipc_test/shared_mem/ipc_share_mem_posix_write b/study_clang/ipc_test/shared_mem/ipc_share_mem_posix_write new file mode 100755 index 0000000..015e993 Binary files /dev/null and b/study_clang/ipc_test/shared_mem/ipc_share_mem_posix_write differ diff --git a/study_clang/ipc_test/shared_mem/ipc_share_mem_posix_write.c b/study_clang/ipc_test/shared_mem/ipc_share_mem_posix_write.c new file mode 100644 index 0000000..83fa288 --- /dev/null +++ b/study_clang/ipc_test/shared_mem/ipc_share_mem_posix_write.c @@ -0,0 +1,30 @@ +/************************************************************************* + > File Name : ipc_share_mem_posix_write.c + > Author : TL Song + > EMail : songtianlun@frytea.com + > Created Time : Wed 30 Dec 2020 03:17:00 PM CST + ************************************************************************/ + +#include +#include +#include +#include +#include +#include + +int main(int argc, char ** argv) +{ + int fd = shm_open("posixsm", O_CREAT | O_RDWR, 0666); + ftruncate(fd, 0x400000); + + char *p = mmap(NULL, 0x400000, PROT_READ| PROT_WRITE, MAP_SHARED, fd, 0); + char cIndex = 'A'; + int i = 0; + for(i=0;i<100;i++){ + memset(p, cIndex++, 0x400000); + printf("Write '%c' to mem '%p'\n", *p, p); + sleep(1); + } + munmap(p, 0x400000); + return 0; +} diff --git a/study_clang/ipc_test/shared_mem/ipc_share_mem_read b/study_clang/ipc_test/shared_mem/ipc_share_mem_read new file mode 100755 index 0000000..6e2539c Binary files /dev/null and b/study_clang/ipc_test/shared_mem/ipc_share_mem_read differ diff --git a/study_clang/ipc_test/shared_mem/ipc_share_mem_read.c b/study_clang/ipc_test/shared_mem/ipc_share_mem_read.c new file mode 100644 index 0000000..4cff92d --- /dev/null +++ b/study_clang/ipc_test/shared_mem/ipc_share_mem_read.c @@ -0,0 +1,25 @@ +/************************************************************************* + > File Name : ipc_share_mem_read.c + > Author : TL Song + > EMail : songtianlun@frytea.com + > Created Time : Wed 30 Dec 2020 03:22:20 PM CST + ************************************************************************/ + +#include +#include +#include + +int main(int argc, char ** argv) +{ + key_t key = ftok("/dev/shm/myshm2", 0); + int shm_id = shmget(key, 0x400000, 0666); + char *p = (char *)shmat(shm_id, NULL, 0); + int i = 0; + for(i = 0 ;i < 100; i++) + { + printf("Read '%c' in mem '%p'\n", *p, p); + sleep(1); + } + shmdt(p); + return 0; +} diff --git a/study_clang/ipc_test/shared_mem/ipc_share_mem_server b/study_clang/ipc_test/shared_mem/ipc_share_mem_server new file mode 100755 index 0000000..2c495fd Binary files /dev/null and b/study_clang/ipc_test/shared_mem/ipc_share_mem_server differ diff --git a/study_clang/ipc_test/shared_mem/ipc_share_mem_server.c b/study_clang/ipc_test/shared_mem/ipc_share_mem_server.c new file mode 100644 index 0000000..b79442d --- /dev/null +++ b/study_clang/ipc_test/shared_mem/ipc_share_mem_server.c @@ -0,0 +1,168 @@ +/************************************************************************* + > File Name : ipc_share_mem_server.c + > Author : TL Song + > EMail : songtianlun@frytea.com + > Created Time : Mon 28 Dec 2020 03:55:22 PM CST + ************************************************************************/ +#include +#include +#include // shared memory +#include // semaphore +#include // message queue +#include // memcpy +// 消息队列结构 +struct msg_form { + long mtype; + char mtext; +}; + +// 联合体,用于semctl初始化 +union semun +{ + int val; /*for SETVAL*/ + struct semid_ds *buf; + unsigned short *array; +}; + +// 初始化信号量 +int init_sem(int sem_id, int value) +{ + union semun tmp; + tmp.val = value; + if(semctl(sem_id, 0, SETVAL, tmp) == -1) + { + perror("Init Semaphore Error"); + return -1; + } + return 0; +} + +// P操作: +// 若信号量值为1,获取资源并将信号量值-1 +// 若信号量值为0,进程挂起等待 +int sem_p(int sem_id) +{ + struct sembuf sbuf; + sbuf.sem_num = 0; /*序号*/ + sbuf.sem_op = -1; /*P操作*/ + sbuf.sem_flg = SEM_UNDO; + + if(semop(sem_id, &sbuf, 1) == -1) + { + perror("P operation Error"); + return -1; + } + return 0; +} +// V操作: +// 释放资源并将信号量值+1 +// 如果有进程正在挂起等待,则唤醒它们 +int sem_v(int sem_id) +{ + struct sembuf sbuf; + sbuf.sem_num = 0; /*序号*/ + sbuf.sem_op = 1; /*V操作*/ + sbuf.sem_flg = SEM_UNDO; + + if(semop(sem_id, &sbuf, 1) == -1) + { + perror("V operation Error"); + return -1; + } + return 0; +} + +// 删除信号量集 +int del_sem(int sem_id) +{ + union semun tmp; + if(semctl(sem_id, 0, IPC_RMID, tmp) == -1) + { + perror("Delete Semaphore Error"); + return -1; + } + return 0; +} + +// 创建一个信号量集 +int creat_sem(key_t key) +{ + int sem_id; + if((sem_id = semget(key, 1, IPC_CREAT|0666)) == -1) + { + perror("semget error"); + exit(-1); + } + init_sem(sem_id, 1); /*初值设为1资源未占用*/ + return sem_id; +} + + +int main() +{ + key_t key; + int shmid, semid, msqid; + char *shm; + char data[] = "this is server"; + struct shmid_ds buf1; /*用于删除共享内存*/ + struct msqid_ds buf2; /*用于删除消息队列*/ + struct msg_form msg; /*消息队列用于通知对方更新了共享内存*/ + + // 获取key值 + if((key = ftok(".", 'z')) < 0) + { + perror("ftok error"); + exit(1); + } + + // 创建共享内存 + if((shmid = shmget(key, 1024, IPC_CREAT|0666)) == -1) + { + perror("Create Shared Memory Error"); + exit(1); + } + + + // 连接共享内存 + shm = (char*)shmat(shmid, 0, 0); + if((int)shm == -1) + { + perror("Attach Shared Memory Error"); + exit(1); + } + + + // 创建消息队列 + if ((msqid = msgget(key, IPC_CREAT|0777)) == -1) + { + perror("msgget error"); + exit(1); + } + + // 创建信号量 + semid = creat_sem(key); + +system("/proc/$$/ns"); + // 读数据 + while(1) + { + msgrcv(msqid, &msg, 1, 888, 0); /*读取类型为888的消息*/ + if(msg.mtext == 'q') /*quit - 跳出循环*/ + break; + if(msg.mtext == 'r') /*read - 读共享内存*/ + { + sem_p(semid); + printf("%s\n",shm); + sem_v(semid); + } + } + + // 断开连接 + shmdt(shm); + + /*删除共享内存、消息队列、信号量*/ + shmctl(shmid, IPC_RMID, &buf1); + msgctl(msqid, IPC_RMID, &buf2); + del_sem(semid); + return 0; +} diff --git a/study_clang/ipc_test/shared_mem/ipc_share_mem_single b/study_clang/ipc_test/shared_mem/ipc_share_mem_single new file mode 100755 index 0000000..a01200e Binary files /dev/null and b/study_clang/ipc_test/shared_mem/ipc_share_mem_single differ diff --git a/study_clang/ipc_test/shared_mem/ipc_share_mem_single.c b/study_clang/ipc_test/shared_mem/ipc_share_mem_single.c new file mode 100644 index 0000000..3616c55 --- /dev/null +++ b/study_clang/ipc_test/shared_mem/ipc_share_mem_single.c @@ -0,0 +1,41 @@ +/************************************************************************* + > File Name : ipc_share_mem_single.c + > Author : TL Song + > EMail : songtianlun@frytea.com + > Created Time : Wed 30 Dec 2020 03:12:37 PM CST + ************************************************************************/ +#include +#include +#include +#include +#include +#include + +int main(void) { + + pid_t pid; + int *shared; /* pointer to the shm */ + int shmid; + + shmid = shmget(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0666); + if (fork() == 0) { /* Child */ + /* Attach to shared memory and print the pointer */ + shared = shmat(shmid, (void *) 0, 0); + printf("Child pointer %p\n", shared); + *shared=1; + printf("Child value=%d\n", *shared); + sleep(10); + printf("Child value=%d\n", *shared); + + } else { /* Parent */ + /* Attach to shared memory and print the pointer */ + shared = shmat(shmid, (void *) 0, 0); + printf("Parent pointer %p\n", shared); + printf("Parent value=%d\n", *shared); + sleep(1); + *shared=42; + printf("Parent value=%d\n", *shared); + sleep(14); + shmctl(shmid, IPC_RMID, 0); + } +} diff --git a/study_clang/ipc_test/shared_mem/ipc_share_mem_write b/study_clang/ipc_test/shared_mem/ipc_share_mem_write new file mode 100755 index 0000000..a30e6e0 Binary files /dev/null and b/study_clang/ipc_test/shared_mem/ipc_share_mem_write differ diff --git a/study_clang/ipc_test/shared_mem/ipc_share_mem_write.c b/study_clang/ipc_test/shared_mem/ipc_share_mem_write.c new file mode 100644 index 0000000..a7a44a6 --- /dev/null +++ b/study_clang/ipc_test/shared_mem/ipc_share_mem_write.c @@ -0,0 +1,27 @@ +/************************************************************************* + > File Name : ipc_share_mem_write.c + > Author : TL Song + > EMail : songtianlun@frytea.com + > Created Time : Wed 30 Dec 2020 03:17:00 PM CST + ************************************************************************/ + +#include +#include +#include +#include + +int main(int argc, char ** argv) +{ + key_t key = ftok("/dev/shm/myshm2",0); + int shm_id = shmget(key, 0x400000, IPC_CREAT | 0666); + char *p = (char *)shmat(shm_id, NULL, 0); + char cIndex = 'A'; + int i = 0; + for(i=0;i<100;i++){ + memset(p, cIndex++, 0x400000); + printf("Write '%c' to mem '%p'\n", *p, p); + sleep(1); + } + shmdt(p); + return 0; +} diff --git a/study_clang/ipc_test/unix_socket/Makefile b/study_clang/ipc_test/unix_socket/Makefile new file mode 100644 index 0000000..b10df75 --- /dev/null +++ b/study_clang/ipc_test/unix_socket/Makefile @@ -0,0 +1,22 @@ +# Batch Single C file MakeFile + +# 指定CPU架构 Architecture -> ARCH +ARCH ?= +CC = $(ARCH)gcc +SUFFIX = .c +CFLAGS += -Wall -g +LD = + +CUR_SOURCE = $(wildcard *$(SUFFIX)) +CUR_TARGETS = $(patsubst %$(SUFFIX), %, $(CUR_SOURCE)) + +all:$(CUR_TARGETS) + +# %:%.c 是一个表示与目标相同 文件的模式变量 +$(CUR_TARGETS):%:%$(SUFFIX) + $(CC) $< $(CFLAGS) -o $@ $(LD) + +# 指定伪目标 +.PHONY:clean all + clean: + -rm -rf $(TARGETS) diff --git a/study_clang/ipc_test/unix_socket/clinet b/study_clang/ipc_test/unix_socket/clinet new file mode 100755 index 0000000..a6f9198 Binary files /dev/null and b/study_clang/ipc_test/unix_socket/clinet differ diff --git a/study_clang/ipc_test/unix_socket/clinet.c b/study_clang/ipc_test/unix_socket/clinet.c new file mode 100644 index 0000000..9e4cd8d --- /dev/null +++ b/study_clang/ipc_test/unix_socket/clinet.c @@ -0,0 +1,65 @@ +/************************************************************************* + > File Name: clinet.c + > Author: TianLun Song + > Mail: songtianlun@frytea.com + > Blog: https://blog.frytea.com + > Created Time: Wed 13 Jan 2021 09:26:49 AM CST + ************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAXLINE 80 + +char *client_path = "client.socket"; +char *server_path = "server.socket"; + +int main() { + struct sockaddr_un cliun, serun; + int len; + char buf[100]; + int sockfd, n; + + if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0){ + perror("client socket error"); + exit(1); + } + + // 一般显式调用bind函数,以便服务器区分不同客户端 + memset(&cliun, 0, sizeof(cliun)); + cliun.sun_family = AF_UNIX; + strcpy(cliun.sun_path, client_path); + len = offsetof(struct sockaddr_un, sun_path) + strlen(cliun.sun_path); + unlink(cliun.sun_path); + if (bind(sockfd, (struct sockaddr *)&cliun, len) < 0) { + perror("bind error"); + exit(1); + } + + memset(&serun, 0, sizeof(serun)); + serun.sun_family = AF_UNIX; + strcpy(serun.sun_path, server_path); + len = offsetof(struct sockaddr_un, sun_path) + strlen(serun.sun_path); + if (connect(sockfd, (struct sockaddr *)&serun, len) < 0){ + perror("connect error"); + exit(1); + } + + while(fgets(buf, MAXLINE, stdin) != NULL) { + write(sockfd, buf, strlen(buf)); + n = read(sockfd, buf, MAXLINE); + if ( n < 0 ) { + printf("the other side has been closed.\n"); + }else { + write(STDOUT_FILENO, buf, n); + } + } + close(sockfd); + return 0; +} diff --git a/study_clang/ipc_test/unix_socket/mult_udp/Makefile b/study_clang/ipc_test/unix_socket/mult_udp/Makefile new file mode 100644 index 0000000..93f3659 --- /dev/null +++ b/study_clang/ipc_test/unix_socket/mult_udp/Makefile @@ -0,0 +1,22 @@ +# Batch Single C file MakeFile + +# 指定CPU架构 Architecture -> ARCH +ARCH ?= +CC = $(ARCH)g++ +SUFFIX = .cpp +CFLAGS += -Wall -g +LD = -lpthread + +CUR_SOURCE = $(wildcard *$(SUFFIX)) +CUR_TARGETS = $(patsubst %$(SUFFIX), %, $(CUR_SOURCE)) + +all:$(CUR_TARGETS) + +# %:%.c 是一个表示与目标相同 文件的模式变量 +$(CUR_TARGETS):%:%$(SUFFIX) + $(CC) $< $(CFLAGS) -o $@ $(LD) + +# 指定伪目标 +.PHONY:clean all + clean: + -rm -rf $(TARGETS) diff --git a/study_clang/ipc_test/unix_socket/mult_udp/point.h b/study_clang/ipc_test/unix_socket/mult_udp/point.h new file mode 100644 index 0000000..66c55b2 --- /dev/null +++ b/study_clang/ipc_test/unix_socket/mult_udp/point.h @@ -0,0 +1,79 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +#define server1_file "/tmp/criu/ipc_server1.sock" +#define client1_file "/tmp/criu/ipc_client1.sock" +#define server2_file "/tmp/criu/ipc_server2.sock" +#define client2_file "/tmp/criu/ipc_client2.sock" + +// Global var for unix socket udp; +int socket_fd_server_1; +int socket_fd_server_2; +int socket_fd_client_1; +int socket_fd_client_2; +struct sockaddr_un server_addr1; +struct sockaddr_un server_addr2; +struct sockaddr_un client_addr1; +struct sockaddr_un client_addr2; +socklen_t server_addr_len1; +socklen_t server_addr_len2; +socklen_t client_addr_len1; +socklen_t client_addr_len2; + +void init_socket() +{ + memset(&server_addr1,0,sizeof(server_addr1)); + memset(&server_addr2,0,sizeof(server_addr2)); + server_addr1.sun_family = AF_UNIX; + server_addr2.sun_family = AF_UNIX; + strcpy(server_addr1.sun_path,server1_file); + strcpy(server_addr2.sun_path,server2_file); + server_addr_len1 = sizeof(server_addr1); + server_addr_len2 = sizeof(server_addr2); +} +ssize_t ipc_udp_server_recv(int __fd, void *__restrict__ __buf, size_t __n, int __flags) +{ + client_addr_len1 = sizeof(client_addr1); + client_addr_len2 = sizeof(client_addr2); + if(socket_fd_server_1 == __fd) + return recvfrom(__fd, __buf, __n, __flags, (sockaddr*)&client_addr1, &client_addr_len1); + else if(socket_fd_server_2 == __fd) + return recvfrom(__fd, __buf, __n, __flags, (sockaddr*)&client_addr2, &client_addr_len2); + else + return -1; +} +ssize_t ipc_udp_server_send(int __fd, void *__restrict__ __buf, size_t __n, int __flags) +{ + if(socket_fd_server_1 == __fd) + return sendto(__fd, __buf, __n, __flags, (sockaddr*)&client_addr1, client_addr_len1); + else if(socket_fd_server_2 == __fd) + return sendto(__fd, __buf, __n, __flags, (sockaddr*)&client_addr2, client_addr_len2); + else + return -1; +} +ssize_t ipc_udp_client_send(int __fd, void *__restrict__ __buf, size_t __n, int __flags) +{ + if(socket_fd_client_1 == __fd) + return sendto(__fd, __buf, __n, __flags, (sockaddr*)&server_addr1, server_addr_len1); + else if(socket_fd_client_2 == __fd) + return sendto(__fd, __buf, __n, __flags, (sockaddr*)&server_addr2, server_addr_len2); + else + return -1; +} +ssize_t ipc_udp_client_recv(int __fd, void *__restrict__ __buf, size_t __n, int __flags) +{ + if(socket_fd_client_1 == __fd) + return recvfrom(__fd, __buf, __n, __flags, (sockaddr*)&server_addr1, &server_addr_len1); + else if(socket_fd_client_2 == __fd) + return recvfrom(__fd, __buf, __n, __flags, (sockaddr*)&server_addr2, &server_addr_len2); + else + return -1; +} \ No newline at end of file diff --git a/study_clang/ipc_test/unix_socket/mult_udp/point1 b/study_clang/ipc_test/unix_socket/mult_udp/point1 new file mode 100755 index 0000000..d4841bd Binary files /dev/null and b/study_clang/ipc_test/unix_socket/mult_udp/point1 differ diff --git a/study_clang/ipc_test/unix_socket/mult_udp/point1.cpp b/study_clang/ipc_test/unix_socket/mult_udp/point1.cpp new file mode 100644 index 0000000..42382b6 --- /dev/null +++ b/study_clang/ipc_test/unix_socket/mult_udp/point1.cpp @@ -0,0 +1,139 @@ +/************************************************************************* + > File Name: point1.cpp + > Author: TianLun Song + > Mail: songtianlun@frytea.com + > Blog: https://blog.frytea.com + > Created Time: Wed 13 Jan 2021 09:53:06 AM CST + ************************************************************************/ +#include "point.h" + +void *t_server_1(void *args) +{ + char msg_buf[1024]; + int iMsgIndex = 0; + + printf("Start UDP Server 1.\n"); + socket_fd_server_1 = socket(AF_UNIX,SOCK_DGRAM,0); + printf("server 1 fd %d after socket.\n", socket_fd_server_1); + if (socket_fd_server_1 < 0) + { + perror("server 1 socket"); + return NULL; + } + if (access(server_addr1.sun_path,0) != -1) + { + unlink(server_addr1.sun_path); + } + if (bind(socket_fd_server_1,(sockaddr*)&server_addr1,sizeof server_addr1 ) < 0) + { + perror("server 1 bind"); + return NULL; + } + printf("server 1 fd %d after bind.\n", socket_fd_server_1); + while (1) + { + memset(msg_buf,'\0',1024); + int rsize = ipc_udp_server_recv(socket_fd_server_1,msg_buf,sizeof(msg_buf),0); + if (rsize < 0) + { + perror("server 1 recv error!"); + sleep(1); + continue; + } + printf("UN_UDP server 1, fd: %d,receive a msg from %s :%s\n",socket_fd_server_1 , client_addr1.sun_path, msg_buf); + snprintf(msg_buf,sizeof msg_buf, "OK,I got it! No.%d",iMsgIndex++); + int ssize = ipc_udp_server_send(socket_fd_server_1, msg_buf, sizeof msg_buf,0); + if (ssize < 0) + { + perror("server 1 send error!"); + sleep(1); + continue; + } + sleep(1); + } + if (close(socket_fd_server_1) < 0) + { + perror("server 1 close socket"); + return NULL; + } + return NULL; +} + +void *t_client_2(void *args) +{ + printf("Start UDP Client 2.\n"); + char msg_buf[1024]; + int iMsgIndex = 0; + + memset(&client_addr2,0,sizeof(client_addr2)); + client_addr2.sun_family = AF_UNIX; + strcpy(client_addr2.sun_path,client2_file); + socket_fd_client_2 = socket(AF_UNIX,SOCK_DGRAM,0); + printf("client 2 fd %d after socket.\n", socket_fd_client_2); + if (socket_fd_client_2 < 0) + { + perror("client 2 socket"); + return NULL; + } + if (access(client_addr2.sun_path,0) != -1) + { + remove(client_addr2.sun_path); + } + if(bind(socket_fd_client_2,(sockaddr*)&client_addr2,sizeof(client_addr2)) < 0) + { + perror("client 2 bind"); + return NULL; + } + printf("client 2 fd %d after bind.\n", socket_fd_client_2); + while(1) + { + snprintf(msg_buf,sizeof msg_buf, "I'm UN_UDP client 2, NO.%d.", iMsgIndex++); + int ssize = ipc_udp_client_send(socket_fd_client_2, msg_buf, sizeof msg_buf, 0); + if (ssize < 0) + { + printf("send to %s error.\n", server_addr2.sun_path); + perror("client 2 sendto"); + sleep(1); + continue; + } + int rsize = ipc_udp_client_recv(socket_fd_client_2, msg_buf, sizeof(msg_buf), 0); + if (rsize < 0) + { + perror("client 2 recv"); + sleep(1); + continue; + } + printf("UN_UDP client 2, fd: %d,receive a msg :%s\n",socket_fd_client_2 , msg_buf); + sleep(1); + } + if (close(socket_fd_client_2) < 0) + { + perror("client 2 close"); + return NULL; + } + return NULL; +} + +int main(int argc,char** argv) +{ + pthread_t tid[2]; + int iRet1, iRet2 = 0; + + init_socket(); + + iRet1 = pthread_create(&tid[0], NULL, t_server_1, NULL); + if(iRet1 != 0){ + printf("pthread_create 1 error: error_code = %d\n", iRet1); + } + iRet2 = pthread_create(&tid[1], NULL, t_client_2, NULL); + if(iRet2 != 0){ + printf("pthread_create 2 error: error_code = %d\n", iRet2); + } + while(1) + { + sleep(1); + } + pthread_exit(NULL); + + return 0; +} \ No newline at end of file diff --git a/study_clang/ipc_test/unix_socket/mult_udp/point2 b/study_clang/ipc_test/unix_socket/mult_udp/point2 new file mode 100755 index 0000000..412d0a5 Binary files /dev/null and b/study_clang/ipc_test/unix_socket/mult_udp/point2 differ diff --git a/study_clang/ipc_test/unix_socket/mult_udp/point2.cpp b/study_clang/ipc_test/unix_socket/mult_udp/point2.cpp new file mode 100644 index 0000000..e0192ca --- /dev/null +++ b/study_clang/ipc_test/unix_socket/mult_udp/point2.cpp @@ -0,0 +1,139 @@ +/************************************************************************* + > File Name: point2.cpp + > Author: TianLun Song + > Mail: songtianlun@frytea.com + > Blog: https://blog.frytea.com + > Created Time: Wed 13 Jan 2021 10:14:09 AM CST + ************************************************************************/ +#include "point.h" + +void *t_client_1(void *args) +{ + printf("Start UDP Client 1.\n"); + char msg_buf[1024]; + int iMsgIndex = 0; + + memset(&client_addr1,0,sizeof(client_addr1)); + client_addr1.sun_family = AF_UNIX; + strcpy(client_addr1.sun_path,client1_file); + + + socket_fd_client_1 = socket(AF_UNIX,SOCK_DGRAM,0); + if (socket_fd_client_1 < 0) + { + perror("client 1 socket"); + return NULL; + } + if (access(client_addr1.sun_path,0) != -1) + { + remove(client_addr1.sun_path); + } + if(bind(socket_fd_client_1,(sockaddr*)&client_addr1,sizeof(client_addr1)) < 0) + { + perror("client 1 bind"); + return NULL; + } + while(1) + { + snprintf(msg_buf,sizeof msg_buf, "I'm UN_UDP client 1, NO.%d.", iMsgIndex++); + int ssize = ipc_udp_client_send(socket_fd_client_1, msg_buf, sizeof msg_buf, 0); + if (ssize < 0) + { + printf("sent error to: %s\n",server_addr1.sun_path); + perror("client 1 sendto "); + sleep(1); + continue; + } + int rsize = ipc_udp_client_recv(socket_fd_client_1, msg_buf, sizeof(msg_buf), 0); + if (rsize < 0) + { + perror("client 1 recv"); + sleep(1); + continue; + } + cout << "UN_UDP client 1,receive a msg :" << msg_buf << endl; + sleep(1); + } + if (close(socket_fd_client_1) < 0) + { + perror("client 1 close"); + return NULL; + } + return NULL; +} + +void *t_server_2(void *args) +{ + char msg_buf[1024]; + int iMsgIndex = 0; + + printf("Start UDP Server 2.\n"); + socket_fd_server_2 = socket(AF_UNIX,SOCK_DGRAM,0); + printf("server 2 fd %d after socket.\n", socket_fd_server_2); + if (socket_fd_server_2 < 0) + { + perror("server 2 socket"); + return NULL; + } + if (access(server_addr2.sun_path,0) != -1) + { + remove(server_addr2.sun_path); + } + if (bind(socket_fd_server_2,(sockaddr*)&server_addr2,server_addr_len2) < 0) + { + printf("server 2 fd %d after bind.\n", socket_fd_server_2); + printf("bind to %s error.\n", server_addr2.sun_path); + perror("server 2 bind"); + return NULL; + } + while (1) + { + memset(msg_buf,'\0',1024); + int rsize = ipc_udp_server_recv(socket_fd_server_2,msg_buf,sizeof(msg_buf),0); + if (rsize < 0) + { + perror("server 2 recv error"); + sleep(1); + continue; + } + printf("UN_UDP server 2, fd: %d, receive a msg from %s :%s\n",socket_fd_server_2 , client_addr2.sun_path, msg_buf); + snprintf(msg_buf,sizeof msg_buf, "OK,I got it! No.%d",iMsgIndex++); + int ssize = ipc_udp_server_send(socket_fd_server_2, msg_buf, sizeof msg_buf,0); + if (ssize < 0) + { + perror("server 2 send error"); + sleep(1); + continue; + } + sleep(1); + } + if (close(socket_fd_server_2) < 0) + { + perror("server 2 close socket"); + return NULL; + } + return NULL; +} + +int main(int argc,char** argv) +{ + pthread_t tid[2]; + int iRet1, iRet2 = 0; + + init_socket(); + + iRet1 = pthread_create(&tid[0], NULL, t_client_1, NULL); + if(iRet1 != 0){ + printf("pthread_create 1 error: error_code = %d\n", iRet1); + } + iRet2 = pthread_create(&tid[1], NULL, t_server_2, NULL); + if(iRet2 != 0){ + printf("pthread_create 2 error: error_code = %d\n", iRet2); + } + while(1) + { + sleep(1); + } + pthread_exit(NULL); + return 0; +} \ No newline at end of file diff --git a/study_clang/ipc_test/unix_socket/mult_udp_POSIX/Makefile b/study_clang/ipc_test/unix_socket/mult_udp_POSIX/Makefile new file mode 100644 index 0000000..0de52da --- /dev/null +++ b/study_clang/ipc_test/unix_socket/mult_udp_POSIX/Makefile @@ -0,0 +1,22 @@ +# Batch Single C file MakeFile + +# 指定CPU架构 Architecture -> ARCH +ARCH ?= +CC = $(ARCH)g++ +SUFFIX = .cpp +CFLAGS += -Wall -g +LD = -lpthread -lrt + +CUR_SOURCE = $(wildcard *$(SUFFIX)) +CUR_TARGETS = $(patsubst %$(SUFFIX), %, $(CUR_SOURCE)) + +all:$(CUR_TARGETS) + +# %:%.c 是一个表示与目标相同 文件的模式变量 +$(CUR_TARGETS):%:%$(SUFFIX) + $(CC) $< $(CFLAGS) -o $@ $(LD) + +# 指定伪目标 +.PHONY:clean all + clean: + -rm -rf $(TARGETS) diff --git a/study_clang/ipc_test/unix_socket/mult_udp_POSIX/point.h b/study_clang/ipc_test/unix_socket/mult_udp_POSIX/point.h new file mode 100644 index 0000000..9d95b4e --- /dev/null +++ b/study_clang/ipc_test/unix_socket/mult_udp_POSIX/point.h @@ -0,0 +1,172 @@ +#include +#include +#include /* POSIX SHM */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +#define server1_file "/tmp/criu/ipc_server1.sock" +#define client1_file "/tmp/criu/ipc_client1.sock" +#define server2_file "/tmp/criu/ipc_server2.sock" +#define client2_file "/tmp/criu/ipc_client2.sock" +#define SHM_KEY "UNIX_SOCKET_ADDR" + +enum UnAddrType{ + USERVER = 1, + UCLIENT = 2 +}; + +typedef struct UnAddr +{ + int iPid; + int iType; + int iFD; + struct sockaddr_un stAddr; + socklen_t sLen; + struct UnAddr *next; +}stUnAddr; + +// Global var for unix socket udp; +int socket_fd_server_1; +int socket_fd_server_2; +int socket_fd_client_1; +int socket_fd_client_2; +struct sockaddr_un server_addr1; +struct sockaddr_un server_addr2; +struct sockaddr_un client_addr1; +struct sockaddr_un client_addr2; +socklen_t server_addr_len1; +socklen_t server_addr_len2; +socklen_t client_addr_len1; +socklen_t client_addr_len2; + +void init_socket() +{ + memset(&server_addr1,0,sizeof(server_addr1)); + memset(&server_addr2,0,sizeof(server_addr2)); + server_addr1.sun_family = AF_UNIX; + server_addr2.sun_family = AF_UNIX; + strcpy(server_addr1.sun_path,server1_file); + strcpy(server_addr2.sun_path,server2_file); + server_addr_len1 = sizeof(server_addr1); + server_addr_len2 = sizeof(server_addr2); +} + +/* + * 用于替换 TCP 连接中的 connect() 函数 + * */ +int init_server_for_client(int sockfd, const struct sockaddr *addr, + socklen_t addrlen) +{ + stUnAddr *pHead; + stUnAddr *pNext; + stUnAddr *pNew; + int shmFD = shm_open(SHM_KEY, O_CREAT | O_RDWR, 0666); + printf("init server addr\n"); + ftruncate(shmFD, sizeof(stUnAddr)); + pHead = (stUnAddr*)mmap(NULL, sizeof(stUnAddr), PROT_READ|PROT_WRITE, MAP_SHARED, shmFD, 0); + pNext = pHead; + if(NULL == pNext->next) + { + pNext->iPid = getpid(); + pNext->iType = USERVER; + pNext->iFD = sockfd; + memcpy(&pNext->stAddr, addr, (size_t)addrlen); + pNext->sLen = addrlen; + pNext->next = NULL; + pNext = NULL; + close(shmFD); + return 0; + } + while(NULL!= pNext) + pNext = pNext->next; + pNew = (stUnAddr*)mmap(NULL, sizeof(stUnAddr), PROT_READ|PROT_WRITE, MAP_SHARED, shmFD, 0); + pNew->iPid = getpid(); + pNew->iType = USERVER; + pNew->iFD = sockfd; + memcpy(&pNew->stAddr, addr, (size_t)addrlen); + pNew->sLen = addrlen; + pNew->next = NULL; + pNext = pNew; + // shm_unlink(SHM_KEY); // 增加到析构函数 + close(shmFD); + return 0; +} +/* + * Unix Domain Socket 服务端处理 + * (1) ~~创建 socket 时记录 pid、fd、type;~~ + * (2)收消息时根据 Pid、fd、type 将得到的客户端连接存入共享内存; + * (3)回复后将客户端地址删除(多个客户端同时连接一个服务端时,单线程一个一个处理,处理完成一个即删掉客户端地址再接收下一个,回复下一个。) +*/ +ssize_t ipc_udp_server_recv(int __fd, void *__restrict__ __buf, size_t __n, int __flags) +{ + client_addr_len1 = sizeof(client_addr1); + client_addr_len2 = sizeof(client_addr2); + if(socket_fd_server_1 == __fd) + return recvfrom(__fd, __buf, __n, __flags, (sockaddr*)&client_addr1, &client_addr_len1); + else if(socket_fd_server_2 == __fd) + return recvfrom(__fd, __buf, __n, __flags, (sockaddr*)&client_addr2, &client_addr_len2); + else + return -1; +} +ssize_t ipc_udp_server_send(int __fd, void *__restrict__ __buf, size_t __n, int __flags) +{ + if(socket_fd_server_1 == __fd) + return sendto(__fd, __buf, __n, __flags, (sockaddr*)&client_addr1, client_addr_len1); + else if(socket_fd_server_2 == __fd) + return sendto(__fd, __buf, __n, __flags, (sockaddr*)&client_addr2, client_addr_len2); + else + return -1; +} +/* + * Unix Domain Socket 客户端 + * (1)创建 socket 时记录 pid,fd,type,并指定 server addr 存入共享内存; + * (1)收发时根据 POD、fd、type 获取对应的 server addr,补全剩余参数。 +*/ +ssize_t ipc_udp_client_send(int __fd, void *__restrict__ __buf, size_t __n, int __flags) +{ + /* 从共享内存检索出当前PID当前FD的服务端地址 */ + stUnAddr *pHead; + stUnAddr *pNext; + int shmFD = shm_open(SHM_KEY, O_CREAT | O_RDWR, 0666); + if( -1 == shmFD) + { + perror("shm"); + return -1; + } + ftruncate(shmFD, sizeof(stUnAddr)); + pHead = (stUnAddr*)mmap(NULL, sizeof(stUnAddr), PROT_READ|PROT_WRITE, MAP_SHARED, shmFD, 0); + if (pHead == MAP_FAILED) + perror("mmap"); + pNext = pHead; + while(NULL!= pNext) + { + printf("PID: %d, Type: %d, FD: %d, Addr: %s, ", pNext->iPid, pNext->iType, pNext->iFD, pNext->stAddr.sun_path); + pNext = pNext->next; + } + munmap(pHead, sizeof(stUnAddr)); + close(shmFD); + + if(socket_fd_client_1 == __fd) + return sendto(__fd, __buf, __n, __flags, (sockaddr*)&server_addr1, server_addr_len1); + else if(socket_fd_client_2 == __fd) + return sendto(__fd, __buf, __n, __flags, (sockaddr*)&server_addr2, server_addr_len2); + else + return -1; +} +ssize_t ipc_udp_client_recv(int __fd, void *__restrict__ __buf, size_t __n, int __flags) +{ + if(socket_fd_client_1 == __fd) + return recvfrom(__fd, __buf, __n, __flags, (sockaddr*)&server_addr1, &server_addr_len1); + else if(socket_fd_client_2 == __fd) + return recvfrom(__fd, __buf, __n, __flags, (sockaddr*)&server_addr2, &server_addr_len2); + else + return -1; +} diff --git a/study_clang/ipc_test/unix_socket/mult_udp_POSIX/point1 b/study_clang/ipc_test/unix_socket/mult_udp_POSIX/point1 new file mode 100755 index 0000000..714a1e5 Binary files /dev/null and b/study_clang/ipc_test/unix_socket/mult_udp_POSIX/point1 differ diff --git a/study_clang/ipc_test/unix_socket/mult_udp_POSIX/point1.cpp b/study_clang/ipc_test/unix_socket/mult_udp_POSIX/point1.cpp new file mode 100644 index 0000000..b39ca2b --- /dev/null +++ b/study_clang/ipc_test/unix_socket/mult_udp_POSIX/point1.cpp @@ -0,0 +1,135 @@ +/************************************************************************* + > File Name: point1.cpp + > Author: TianLun Song + > Mail: songtianlun@frytea.com + > Blog: https://blog.frytea.com + > Created Time: Wed 13 Jan 2021 09:53:06 AM CST + ************************************************************************/ +#include "point.h" + +void *t_server_1(void *args) +{ + char msg_buf[1024]; + int iMsgIndex = 0; + + printf("Start UDP Server 1.\n"); + socket_fd_server_1 = socket(AF_UNIX,SOCK_DGRAM,0); + printf("server 1 fd %d after socket.\n", socket_fd_server_1); + if (socket_fd_server_1 < 0) + { + perror("server 1 socket"); + return NULL; + } + if (access(server_addr1.sun_path,0) != -1) + { + unlink(server_addr1.sun_path); + } + if (bind(socket_fd_server_1,(sockaddr*)&server_addr1,sizeof server_addr1 ) < 0) + { + perror("server 1 bind"); + return NULL; + } + printf("server 1 fd %d after bind.\n", socket_fd_server_1); + while (1) + { + memset(msg_buf,'\0',1024); + int rsize = ipc_udp_server_recv(socket_fd_server_1,msg_buf,sizeof(msg_buf),0); + if (rsize < 0) + { + perror("server 1 recv error!"); + sleep(1); + continue; + } + printf("UN_UDP server 1, fd: %d,receive a msg from %s :%s\n",socket_fd_server_1 , client_addr1.sun_path, msg_buf); + snprintf(msg_buf,sizeof msg_buf, "OK,I got it! No.%d",iMsgIndex++); + int ssize = ipc_udp_server_send(socket_fd_server_1, msg_buf, sizeof msg_buf,0); + if (ssize < 0) + { + perror("server 1 send error!"); + sleep(1); + continue; + } + usleep(10); + } + if (close(socket_fd_server_1) < 0) + { + perror("server 1 close socket"); + return NULL; + } + return NULL; +} + +void *t_client_2(void *args) +{ + printf("Start UDP Client 2.\n"); + char msg_buf[1024]; + int iMsgIndex = 0; + + memset(&client_addr2,0,sizeof(client_addr2)); + client_addr2.sun_family = AF_UNIX; + strcpy(client_addr2.sun_path,client2_file); + socket_fd_client_2 = socket(AF_UNIX,SOCK_DGRAM,0); + printf("client 2 fd %d after socket.\n", socket_fd_client_2); + if (socket_fd_client_2 < 0) + { + perror("client 2 socket"); + return NULL; + } + if (access(client_addr2.sun_path,0) != -1) + { + remove(client_addr2.sun_path); + } + if(bind(socket_fd_client_2,(sockaddr*)&client_addr2,sizeof(client_addr2)) < 0) + { + perror("client 2 bind"); + return NULL; + } + printf("client 2 fd %d after bind.\n", socket_fd_client_2); + while(1) + { + snprintf(msg_buf,sizeof msg_buf, "I'm UN_UDP client 2, NO.%d.", iMsgIndex++); + int ssize = ipc_udp_client_send(socket_fd_client_2, msg_buf, sizeof msg_buf, 0); + if (ssize < 0) + { + printf("send to %s error.\n", server_addr2.sun_path); + perror("client 2 sendto"); + sleep(1); + continue; + } + int rsize = ipc_udp_client_recv(socket_fd_client_2, msg_buf, sizeof(msg_buf), 0); + if (rsize < 0) + { + perror("client 2 recv"); + sleep(1); + continue; + } + printf("UN_UDP client 2, fd: %d,receive a msg :%s\n",socket_fd_client_2 , msg_buf); + sleep(1); + } + if (close(socket_fd_client_2) < 0) + { + perror("client 2 close"); + return NULL; + } + return NULL; +} + +int main(int argc,char** argv) +{ + pthread_t tid[2]; + int iRet1, iRet2 = 0; + + init_socket(); + + iRet1 = pthread_create(&tid[0], NULL, t_server_1, NULL); + if(iRet1 != 0){ + printf("pthread_create 1 error: error_code = %d\n", iRet1); + } + // iRet2 = pthread_create(&tid[1], NULL, t_client_2, NULL); + // if(iRet2 != 0){ + // printf("pthread_create 2 error: error_code = %d\n", iRet2); + // } + pthread_exit(NULL); + + return 0; +} diff --git a/study_clang/ipc_test/unix_socket/mult_udp_POSIX/point2 b/study_clang/ipc_test/unix_socket/mult_udp_POSIX/point2 new file mode 100755 index 0000000..2509b3e Binary files /dev/null and b/study_clang/ipc_test/unix_socket/mult_udp_POSIX/point2 differ diff --git a/study_clang/ipc_test/unix_socket/mult_udp_POSIX/point2.cpp b/study_clang/ipc_test/unix_socket/mult_udp_POSIX/point2.cpp new file mode 100644 index 0000000..11ea845 --- /dev/null +++ b/study_clang/ipc_test/unix_socket/mult_udp_POSIX/point2.cpp @@ -0,0 +1,137 @@ +/************************************************************************* + > File Name: point2.cpp + > Author: TianLun Song + > Mail: songtianlun@frytea.com + > Blog: https://blog.frytea.com + > Created Time: Wed 13 Jan 2021 10:14:09 AM CST + ************************************************************************/ +#include "point.h" + +void *t_client_1(void *args) +{ + printf("Start UDP Client 1.\n"); + char msg_buf[1024]; + int iMsgIndex = 0; + + memset(&client_addr1,0,sizeof(client_addr1)); + client_addr1.sun_family = AF_UNIX; + strcpy(client_addr1.sun_path,client1_file); + + + socket_fd_client_1 = socket(AF_UNIX,SOCK_DGRAM,0); + if (socket_fd_client_1 < 0) + { + perror("client 1 socket"); + return NULL; + } + if (access(client_addr1.sun_path,0) != -1) + { + remove(client_addr1.sun_path); + } + if(bind(socket_fd_client_1,(sockaddr*)&client_addr1,sizeof(client_addr1)) < 0) + { + perror("client 1 bind"); + return NULL; + } + init_server_for_client(socket_fd_client_1, (sockaddr*)&server_addr1, server_addr_len1); + init_server_for_client(socket_fd_client_1, (sockaddr*)&server_addr1, server_addr_len1); + while(1) + { + snprintf(msg_buf,sizeof msg_buf, "I'm UN_UDP client 1, NO.%d.", iMsgIndex++); + int ssize = ipc_udp_client_send(socket_fd_client_1, msg_buf, sizeof msg_buf, 0); + if (ssize < 0) + { + printf("sent error to: %s\n",server_addr1.sun_path); + perror("client 1 sendto "); + sleep(1); + continue; + } + int rsize = ipc_udp_client_recv(socket_fd_client_1, msg_buf, sizeof(msg_buf), 0); + if (rsize < 0) + { + perror("client 1 recv"); + sleep(1); + continue; + } + cout << "UN_UDP client 1,receive a msg :" << msg_buf << endl; + usleep(10); + } + if (close(socket_fd_client_1) < 0) + { + perror("client 1 close"); + return NULL; + } + return NULL; +} + +void *t_server_2(void *args) +{ + char msg_buf[1024]; + int iMsgIndex = 0; + + printf("Start UDP Server 2.\n"); + socket_fd_server_2 = socket(AF_UNIX,SOCK_DGRAM,0); + printf("server 2 fd %d after socket.\n", socket_fd_server_2); + if (socket_fd_server_2 < 0) + { + perror("server 2 socket"); + return NULL; + } + if (access(server_addr2.sun_path,0) != -1) + { + remove(server_addr2.sun_path); + } + if (bind(socket_fd_server_2,(sockaddr*)&server_addr2,server_addr_len2) < 0) + { + printf("server 2 fd %d after bind.\n", socket_fd_server_2); + printf("bind to %s error.\n", server_addr2.sun_path); + perror("server 2 bind"); + return NULL; + } + while (1) + { + memset(msg_buf,'\0',1024); + int rsize = ipc_udp_server_recv(socket_fd_server_2,msg_buf,sizeof(msg_buf),0); + if (rsize < 0) + { + perror("server 2 recv error"); + sleep(1); + continue; + } + printf("UN_UDP server 2, fd: %d, receive a msg from %s :%s\n",socket_fd_server_2 , client_addr2.sun_path, msg_buf); + snprintf(msg_buf,sizeof msg_buf, "OK,I got it! No.%d",iMsgIndex++); + int ssize = ipc_udp_server_send(socket_fd_server_2, msg_buf, sizeof msg_buf,0); + if (ssize < 0) + { + perror("server 2 send error"); + sleep(1); + continue; + } + sleep(1); + } + if (close(socket_fd_server_2) < 0) + { + perror("server 2 close socket"); + return NULL; + } + return NULL; +} + +int main(int argc,char** argv) +{ + pthread_t tid[2]; + int iRet1, iRet2 = 0; + + init_socket(); + + iRet1 = pthread_create(&tid[0], NULL, t_client_1, NULL); + if(iRet1 != 0){ + printf("pthread_create 1 error: error_code = %d\n", iRet1); + } + // iRet2 = pthread_create(&tid[1], NULL, t_server_2, NULL); + // if(iRet2 != 0){ + // printf("pthread_create 2 error: error_code = %d\n", iRet2); + // } + pthread_exit(NULL); + return 0; +} diff --git a/study_clang/ipc_test/unix_socket/server b/study_clang/ipc_test/unix_socket/server new file mode 100755 index 0000000..0a6aa3e Binary files /dev/null and b/study_clang/ipc_test/unix_socket/server differ diff --git a/study_clang/ipc_test/unix_socket/server.c b/study_clang/ipc_test/unix_socket/server.c new file mode 100644 index 0000000..52d3e64 --- /dev/null +++ b/study_clang/ipc_test/unix_socket/server.c @@ -0,0 +1,91 @@ +/************************************************************************* + > File Name: server.c + > Author: TianLun Song + > Mail: songtianlun@frytea.com + > Blog: https://blog.frytea.com + > Created Time: Wed 13 Jan 2021 09:26:32 AM CST + ************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAXLINE 80 + +char *socket_path = "server.socket"; + +int main(void) +{ + struct sockaddr_un serun, cliun; + socklen_t cliun_len; + int listenfd, connfd, size; + char buf[MAXLINE]; + int i, n; + + // SOCK_STREAM 指定 TCP + // SOCK_DGRAM 指定 UDP + // SOCK_RAW 原始套接字 + /*modify for udp*/ + if ((listenfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { + perror("socket error"); + exit(1); + } + + memset(&serun, 0, sizeof(serun)); + serun.sun_family = AF_UNIX; + strcpy(serun.sun_path, socket_path); + size = offsetof(struct sockaddr_un, sun_path) + strlen(serun.sun_path); + /* add for udp + access(serun.sun_path,0); + */ + unlink(socket_path); + if (bind(listenfd, (struct sockaddr *)&serun, size) < 0) { + perror("bind error"); + exit(1); + } + printf("UNIX domain socket bound\n"); + + /* + * move for udp*/ + if (listen(listenfd, 20) < 0) { + perror("listen error"); + exit(1); + } + /**/ + printf("Accepting connections ...\n"); + + while(1) { + cliun_len = sizeof(cliun); + if ((connfd = accept(listenfd, (struct sockaddr *)&cliun, &cliun_len)) < 0){ + perror("accept error"); + continue; + } + + while(1) { + n = read(connfd, buf, sizeof(buf)); + if (n < 0) { + perror("read error"); + break; + } else if(n == 0) { + printf("EOF\n"); + break; + } + + printf("received: %s", buf); + + for(i = 0; i < n; i++) { + buf[i] = toupper(buf[i]); + } + write(connfd, buf, n); + } + close(connfd); + } + close(listenfd); + return 0; +} + diff --git a/study_clang/ipc_test/unix_socket/tcp/Makefile b/study_clang/ipc_test/unix_socket/tcp/Makefile new file mode 100644 index 0000000..3b198e9 --- /dev/null +++ b/study_clang/ipc_test/unix_socket/tcp/Makefile @@ -0,0 +1,22 @@ +# Batch Single C file MakeFile + +# 指定CPU架构 Architecture -> ARCH +ARCH ?= +CC = $(ARCH)g++ +SUFFIX = .cpp +CFLAGS += -Wall -g +LD = + +CUR_SOURCE = $(wildcard *$(SUFFIX)) +CUR_TARGETS = $(patsubst %$(SUFFIX), %, $(CUR_SOURCE)) + +all:$(CUR_TARGETS) + +# %:%.c 是一个表示与目标相同 文件的模式变量 +$(CUR_TARGETS):%:%$(SUFFIX) + $(CC) $< $(CFLAGS) -o $@ $(LD) + +# 指定伪目标 +.PHONY:clean all + clean: + -rm -rf $(TARGETS) diff --git a/study_clang/ipc_test/unix_socket/tcp/client_tcp b/study_clang/ipc_test/unix_socket/tcp/client_tcp new file mode 100755 index 0000000..38c7d7f Binary files /dev/null and b/study_clang/ipc_test/unix_socket/tcp/client_tcp differ diff --git a/study_clang/ipc_test/unix_socket/tcp/client_tcp.cpp b/study_clang/ipc_test/unix_socket/tcp/client_tcp.cpp new file mode 100644 index 0000000..6d24e61 --- /dev/null +++ b/study_clang/ipc_test/unix_socket/tcp/client_tcp.cpp @@ -0,0 +1,81 @@ +/************************************************************************* + > File Name: ipc_tcp_client.cpp + > Author: TianLun Song + > Mail: songtianlun@frytea.com + > Blog: https://blog.frytea.com + > Created Time: Wed 13 Jan 2021 10:14:09 AM CST + ************************************************************************/ +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +const char* server_file = "/tmp/ipc_tcp_server.sock"; +const char* client_file = "/tmp/ipc_tcp_client.sock"; + +int main(int argc,char** argv) +{ + int socket_fd = socket(AF_UNIX,SOCK_STREAM,0); + if (socket_fd < 0) + { + perror("client socket"); + return -1; + } + struct sockaddr_un client_addr; + memset(&client_addr,0,sizeof(client_addr)); + client_addr.sun_family = AF_UNIX; + strcpy(client_addr.sun_path,client_file); + + if (access(client_addr.sun_path,0) != -1) + { + remove(client_addr.sun_path); + } + + if(bind(socket_fd,(sockaddr*)&client_addr,sizeof(client_addr)) < 0) + { + perror("client bind"); + return -1; + } + struct sockaddr_un serveraddr; + memset(&serveraddr,0,sizeof(serveraddr)); + socklen_t addrlen = sizeof(serveraddr); + serveraddr.sun_family = AF_UNIX; + strcpy(serveraddr.sun_path,server_file); + char msg_buf[1024]; + /* --------DIFF, ipc tcp only------------ */ + int newcon = -1; + newcon = connect(socket_fd,(sockaddr*)&serveraddr,addrlen); + if (newcon < 0){ + perror("client connect"); + } + /* ---------------end------------ */ + while(1) + { + strcpy(msg_buf, "How are you !!!"); + int ssize = send(socket_fd, msg_buf, sizeof msg_buf, 0); + if (ssize < 0) + { + perror("client send"); + continue; + } + int rsize = recv(socket_fd, msg_buf, sizeof(msg_buf), 0); + if (rsize < 0) + { + perror("client recv"); + continue; + } + cout << "I'm Unix socket(TCP) client,receive a msg :" << msg_buf << endl; + sleep(1); + } + if (close(socket_fd) < 0) + { + perror("close"); + return -1; + } + return 0; +} \ No newline at end of file diff --git a/study_clang/ipc_test/unix_socket/tcp/server_tcp b/study_clang/ipc_test/unix_socket/tcp/server_tcp new file mode 100755 index 0000000..fb0cf06 Binary files /dev/null and b/study_clang/ipc_test/unix_socket/tcp/server_tcp differ diff --git a/study_clang/ipc_test/unix_socket/tcp/server_tcp.cpp b/study_clang/ipc_test/unix_socket/tcp/server_tcp.cpp new file mode 100644 index 0000000..c94ff10 --- /dev/null +++ b/study_clang/ipc_test/unix_socket/tcp/server_tcp.cpp @@ -0,0 +1,91 @@ +/************************************************************************* + > File Name: ipc_tcp_server.cpp + > Author: TianLun Song + > Mail: songtianlun@frytea.com + > Blog: https://blog.frytea.com + > Created Time: Wed 13 Jan 2021 09:53:06 AM CST + ************************************************************************/ +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +const char* server_file = "/tmp/ipc_tcp_server.sock"; + +int main(int argc,char** argv) +{ + int socket_fd = socket(AF_UNIX,SOCK_STREAM,0); + if (socket_fd < 0) + { + perror("socket"); + return -1; + } + struct sockaddr_un addr; + memset(&addr,0,sizeof(addr)); + addr.sun_family = AF_UNIX; + strcpy(addr.sun_path,server_file); + if (access(addr.sun_path,0) != -1) + { + remove(addr.sun_path); + } + if (bind(socket_fd,(sockaddr*)&addr,sizeof(addr)) < 0) + { + perror("bind"); + return -1; + } + /* --------DIFF, ipc tcp only------------ */ + if (listen(socket_fd,12) < 0) + { + perror("listen"); + return -1; + } + /* ---------------end------------ */ + struct sockaddr_un clientaddr; + socklen_t addrlen = sizeof(clientaddr); + char msg_buf[1024]; + /* --------DIFF, ipc tcp only------------ */ + int newcon = -1; + newcon = accept(socket_fd,(sockaddr*)&clientaddr,&addrlen); + if (newcon < 0) + { + perror("accept"); + return -1; + } + /* ---------------end------------ */ + while (1) + { + memset(msg_buf,'\0',1024); + int rsize = recv(newcon,msg_buf,sizeof(msg_buf),0); + if (rsize < 0) + { + perror("server recv error!"); + break; + } + cout << "I'm Unix socket(TCP) server, recv a msg:" << msg_buf << " from: " << clientaddr.sun_path << endl; + strcpy(msg_buf, "OK,I got it!"); + int ssize = send(newcon, msg_buf, sizeof msg_buf, 0); + if (ssize < 0) + { + perror("server send error!"); + break; + } + sleep(1); + } + /* --------DIFF, ipc tcp only------------ */ + if (close(newcon) < 0) + { + perror("close accept"); + return -1; + } + /* ---------------end------------ */ + if (close(socket_fd) < 0) + { + perror("close socket"); + return -1; + } + return 0; +} \ No newline at end of file diff --git a/study_clang/ipc_test/unix_socket/tcp2udp/Makefile b/study_clang/ipc_test/unix_socket/tcp2udp/Makefile new file mode 100644 index 0000000..b10df75 --- /dev/null +++ b/study_clang/ipc_test/unix_socket/tcp2udp/Makefile @@ -0,0 +1,22 @@ +# Batch Single C file MakeFile + +# 指定CPU架构 Architecture -> ARCH +ARCH ?= +CC = $(ARCH)gcc +SUFFIX = .c +CFLAGS += -Wall -g +LD = + +CUR_SOURCE = $(wildcard *$(SUFFIX)) +CUR_TARGETS = $(patsubst %$(SUFFIX), %, $(CUR_SOURCE)) + +all:$(CUR_TARGETS) + +# %:%.c 是一个表示与目标相同 文件的模式变量 +$(CUR_TARGETS):%:%$(SUFFIX) + $(CC) $< $(CFLAGS) -o $@ $(LD) + +# 指定伪目标 +.PHONY:clean all + clean: + -rm -rf $(TARGETS) diff --git a/study_clang/ipc_test/unix_socket/tcp2udp/client b/study_clang/ipc_test/unix_socket/tcp2udp/client new file mode 100755 index 0000000..ad918c4 Binary files /dev/null and b/study_clang/ipc_test/unix_socket/tcp2udp/client differ diff --git a/study_clang/ipc_test/unix_socket/tcp2udp/client.c b/study_clang/ipc_test/unix_socket/tcp2udp/client.c new file mode 100644 index 0000000..9e4cd8d --- /dev/null +++ b/study_clang/ipc_test/unix_socket/tcp2udp/client.c @@ -0,0 +1,65 @@ +/************************************************************************* + > File Name: clinet.c + > Author: TianLun Song + > Mail: songtianlun@frytea.com + > Blog: https://blog.frytea.com + > Created Time: Wed 13 Jan 2021 09:26:49 AM CST + ************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAXLINE 80 + +char *client_path = "client.socket"; +char *server_path = "server.socket"; + +int main() { + struct sockaddr_un cliun, serun; + int len; + char buf[100]; + int sockfd, n; + + if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0){ + perror("client socket error"); + exit(1); + } + + // 一般显式调用bind函数,以便服务器区分不同客户端 + memset(&cliun, 0, sizeof(cliun)); + cliun.sun_family = AF_UNIX; + strcpy(cliun.sun_path, client_path); + len = offsetof(struct sockaddr_un, sun_path) + strlen(cliun.sun_path); + unlink(cliun.sun_path); + if (bind(sockfd, (struct sockaddr *)&cliun, len) < 0) { + perror("bind error"); + exit(1); + } + + memset(&serun, 0, sizeof(serun)); + serun.sun_family = AF_UNIX; + strcpy(serun.sun_path, server_path); + len = offsetof(struct sockaddr_un, sun_path) + strlen(serun.sun_path); + if (connect(sockfd, (struct sockaddr *)&serun, len) < 0){ + perror("connect error"); + exit(1); + } + + while(fgets(buf, MAXLINE, stdin) != NULL) { + write(sockfd, buf, strlen(buf)); + n = read(sockfd, buf, MAXLINE); + if ( n < 0 ) { + printf("the other side has been closed.\n"); + }else { + write(STDOUT_FILENO, buf, n); + } + } + close(sockfd); + return 0; +} diff --git a/study_clang/ipc_test/unix_socket/tcp2udp/server b/study_clang/ipc_test/unix_socket/tcp2udp/server new file mode 100755 index 0000000..730b279 Binary files /dev/null and b/study_clang/ipc_test/unix_socket/tcp2udp/server differ diff --git a/study_clang/ipc_test/unix_socket/tcp2udp/server.c b/study_clang/ipc_test/unix_socket/tcp2udp/server.c new file mode 100644 index 0000000..0b8584b --- /dev/null +++ b/study_clang/ipc_test/unix_socket/tcp2udp/server.c @@ -0,0 +1,103 @@ +/************************************************************************* + > File Name: server.c + > Author: TianLun Song + > Mail: songtianlun@frytea.com + > Blog: https://blog.frytea.com + > Created Time: Wed 13 Jan 2021 09:26:32 AM CST + ************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAXLINE 80 + +char *socket_path = "server.socket"; + +int main(void) +{ + struct sockaddr_un serun, cliun; + socklen_t cliun_len; + int listenfd, connfd, size; + char buf[MAXLINE]; + int i, n; + + // SOCK_STREAM 指定 TCP + // SOCK_DGRAM 指定 UDP + // SOCK_RAW 原始套接字 + /*modify for udp*/ + if ((listenfd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) { + perror("socket error"); + exit(1); + } + #include + memset(&serun, 0, sizeof(serun)); + serun.sun_family = AF_UNIX; + strcpy(serun.sun_path, socket_path); + size = offsetof(struct sockaddr_un, sun_path) + strlen(serun.sun_path); + /* add for udp */ + access(serun.sun_path,0); + + unlink(socket_path); + if (bind(listenfd, (struct sockaddr *)&serun, size) < 0) { + perror("bind error"); + exit(1); + } + printf("UNIX domain socket bound\n"); + + /* + * move for udp + * + if (listen(listenfd, 20) < 0) { + perror("listen error"); + exit(1); + } */ + + printf("Accepting connections ...\n"); + + while(1) { + memset(buf, 0x00, sizeof buf); + int iMsgSize = recvfrom(listenfd, buf, sizeof(buf), 0, (struct sockaddr*)&serun, &size); + printf("Recv Msg: %s, len: %d", buf, iMsgSize); + strcpy(buf, "Ok, i got it!"); + sendto(listenfd, buf, sizeof(buf), 0, (struct sockaddr*)&serun, size); + sleep(1); + + /* + cliun_len = sizeof(cliun); + if ((connfd = accept(listenfd, (struct sockaddr *)&cliun, &cliun_len)) < 0){ + perror("accept error"); + continue; + } + + while(1) { + n = read(connfd, buf, sizeof(buf)); + if (n < 0) { + perror("read error"); + break; + } else if(n == 0) { + printf("EOF\n"); + break; + } + + printf("received: %s", buf); + + for(i = 0; i < n; i++) { + buf[i] = toupper(buf[i]); + } + write(connfd, buf, n); + } + + close(connfd); + */ + } + close(listenfd); + return 0; +} + diff --git a/study_clang/ipc_test/unix_socket/test_socket.c b/study_clang/ipc_test/unix_socket/test_socket.c new file mode 100644 index 0000000..9e9d5e0 --- /dev/null +++ b/study_clang/ipc_test/unix_socket/test_socket.c @@ -0,0 +1,17 @@ +/************************************************************************* + > File Name: test_socket.c + > Author: TianLun Song + > Mail: songtianlun@frytea.com + > Blog: https://blog.frytea.com + > Created Time: Thu 14 Jan 2021 06:51:32 PM CST + ************************************************************************/ +#include +#include + +int main() +{ + int fd = (AF_UNIX,SOCK_DGRAM,0); + printf("socket name: %s", getsocketname(fd)); + return 0; +} + diff --git a/study_clang/ipc_test/unix_socket/udp/Makefile b/study_clang/ipc_test/unix_socket/udp/Makefile new file mode 100644 index 0000000..3b198e9 --- /dev/null +++ b/study_clang/ipc_test/unix_socket/udp/Makefile @@ -0,0 +1,22 @@ +# Batch Single C file MakeFile + +# 指定CPU架构 Architecture -> ARCH +ARCH ?= +CC = $(ARCH)g++ +SUFFIX = .cpp +CFLAGS += -Wall -g +LD = + +CUR_SOURCE = $(wildcard *$(SUFFIX)) +CUR_TARGETS = $(patsubst %$(SUFFIX), %, $(CUR_SOURCE)) + +all:$(CUR_TARGETS) + +# %:%.c 是一个表示与目标相同 文件的模式变量 +$(CUR_TARGETS):%:%$(SUFFIX) + $(CC) $< $(CFLAGS) -o $@ $(LD) + +# 指定伪目标 +.PHONY:clean all + clean: + -rm -rf $(TARGETS) diff --git a/study_clang/ipc_test/unix_socket/udp/client_udp b/study_clang/ipc_test/unix_socket/udp/client_udp new file mode 100755 index 0000000..b8ad1ff Binary files /dev/null and b/study_clang/ipc_test/unix_socket/udp/client_udp differ diff --git a/study_clang/ipc_test/unix_socket/udp/client_udp.cpp b/study_clang/ipc_test/unix_socket/udp/client_udp.cpp new file mode 100644 index 0000000..440db0f --- /dev/null +++ b/study_clang/ipc_test/unix_socket/udp/client_udp.cpp @@ -0,0 +1,74 @@ +/************************************************************************* + > File Name: ipc_udp_client.cpp + > Author: TianLun Song + > Mail: songtianlun@frytea.com + > Blog: https://blog.frytea.com + > Created Time: Wed 13 Jan 2021 10:14:09 AM CST + ************************************************************************/ +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +const char* server_file = "/tmp/criu/ipc_udp_server.sock"; +const char* client_file = "/tmp/criu/ipc_udp_client.sock"; + +int main(int argc,char** argv) +{ + int socket_fd = socket(AF_UNIX,SOCK_DGRAM,0); + if (socket_fd < 0) + { + perror("client socket"); + return -1; + } + struct sockaddr_un client_addr; + memset(&client_addr,0,sizeof(client_addr)); + client_addr.sun_family = AF_UNIX; + strcpy(client_addr.sun_path,client_file); + + if (access(client_addr.sun_path,0) != -1) + { + remove(client_addr.sun_path); + } + + if(bind(socket_fd,(sockaddr*)&client_addr,sizeof(client_addr)) < 0) + { + perror("client bind"); + return -1; + } + struct sockaddr_un serveraddr; + memset(&serveraddr,0,sizeof(serveraddr)); + socklen_t addrlen = sizeof(serveraddr); + serveraddr.sun_family = AF_UNIX; + strcpy(serveraddr.sun_path,server_file); + char msg_buf[1024]; + while(1) + { + strcpy(msg_buf, "How are you !!!"); + int ssize = sendto(socket_fd, msg_buf, sizeof msg_buf, 0, (sockaddr*)&serveraddr,addrlen); + if (ssize < 0) + { + perror("client sendto"); + continue; + } + int rsize = recvfrom(socket_fd, msg_buf, sizeof(msg_buf), 0,(sockaddr*)&serveraddr, &addrlen); + if (rsize < 0) + { + perror("client recv"); + continue; + } + cout << "I'm Unix socket(UDP) client,receive a msg :" << msg_buf << endl; + sleep(1); + } + if (close(socket_fd) < 0) + { + perror("close"); + return -1; + } + return 0; +} \ No newline at end of file diff --git a/study_clang/ipc_test/unix_socket/udp/server_udp b/study_clang/ipc_test/unix_socket/udp/server_udp new file mode 100755 index 0000000..887b718 Binary files /dev/null and b/study_clang/ipc_test/unix_socket/udp/server_udp differ diff --git a/study_clang/ipc_test/unix_socket/udp/server_udp.cpp b/study_clang/ipc_test/unix_socket/udp/server_udp.cpp new file mode 100644 index 0000000..80e0d0a --- /dev/null +++ b/study_clang/ipc_test/unix_socket/udp/server_udp.cpp @@ -0,0 +1,74 @@ +/************************************************************************* + > File Name: ipc_udp_server.cpp + > Author: TianLun Song + > Mail: songtianlun@frytea.com + > Blog: https://blog.frytea.com + > Created Time: Wed 13 Jan 2021 09:53:06 AM CST + ************************************************************************/ +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +const char* server_file = "/tmp/criu/ipc_udp_server.sock"; + +int main(int argc,char** argv) +{ + int socket_fd = socket(AF_UNIX,SOCK_DGRAM,0); + if (socket_fd < 0) + { + perror("socket"); + return -1; + } + struct sockaddr_un addr; + memset(&addr,0,sizeof(addr)); + addr.sun_family = AF_UNIX; + strcpy(addr.sun_path,server_file); + if (access(addr.sun_path,0) != -1) + { + remove(addr.sun_path); + } + if (bind(socket_fd,(sockaddr*)&addr,sizeof(addr)) < 0) + { + perror("bind"); + return -1; + } + struct sockaddr_un clientaddr; + socklen_t addrlen = sizeof(clientaddr); + char msg_buf[1024]; + while (1) + { + // printf("socket file is ok: %d", access(addr.sun_path, F_OK)); + // if(access(addr.sun_path, F_OK) !=0 ) + // { + // bind(socket(AF_UNIX,SOCK_DGRAM,0),(sockaddr*)&addr,sizeof(addr)); + // printf("socket file is missing, rebind.\n"); + // } + memset(msg_buf,'\0',1024); + int rsize = recvfrom(socket_fd,msg_buf,sizeof(msg_buf),0,(sockaddr*)&clientaddr,&addrlen); + if (rsize < 0) + { + perror("server recv error!"); + continue; + } + cout << "I'm Unix socket(UDP) server, recv a msg: " << msg_buf << " from: " << clientaddr.sun_path << endl; + strcpy(msg_buf, "OK,I got it!"); + int ssize = sendto(socket_fd, msg_buf, sizeof msg_buf,0,(sockaddr*)&clientaddr,addrlen); + if (ssize < 0) + { + perror("server send error!"); + continue; + } + sleep(1); + } + if (close(socket_fd) < 0) + { + perror("close socket"); + return -1; + } + return 0; +} \ No newline at end of file diff --git a/study_clang/ipc_test/unix_socket/udpserver.cpp b/study_clang/ipc_test/unix_socket/udpserver.cpp new file mode 100644 index 0000000..7f792c3 --- /dev/null +++ b/study_clang/ipc_test/unix_socket/udpserver.cpp @@ -0,0 +1,96 @@ +/************************************************************************* + > File Name: udpserver.cpp + > Author: TianLun Song + > Mail: songtianlun@frytea.com + > Blog: https://blog.frytea.com + > Created Time: Wed 13 Jan 2021 09:53:06 AM CST + ************************************************************************/ +#include +#include +#include +#include +#include +#include + +using namespace std; + + +char* server_file = "server.sock"; + +int main(int argc,char** argv) +{ + int fd = socket(AF_UNIX,SOCK_DGRAM,0); + + if (fd < 0) + { + perror("socket"); + return -1; + } + + + struct sockaddr_un addr; + memset(&addr,0,sizeof(addr)); + addr.sun_family = AF_UNIX; + strcpy(addr.sun_path,server_file); + + if (access(addr.sun_path,0) != -1) + { + remove(addr.sun_path); + } + + if(bind(fd,(sockaddr*)&addr,sizeof(addr)) < 0) + { + perror("bind"); + return -1; + } + + + struct sockaddr_un clientaddr; + socklen_t len = sizeof(clientaddr); + + char msgrecv[1024]; + + + + while (1) + { + memset(msgrecv,'\0',1024); + int size = recvfrom(fd,msgrecv,sizeof(msgrecv),0,(sockaddr*)&clientaddr,&len); + if (size < 0) + { + perror("recv"); + return -1; + } + + + cout << "I'm server,receive a msg: " << msgrecv << " from: " << clientaddr.sun_path << endl; + + if (strncmp("quit",msgrecv,4) == 0) + { + cout << "Server is exiting!" << endl; + break; + } + + char *p = "OK,I got id!"; + int ssize = sendto(fd,p,strlen(p),0,(sockaddr*)&clientaddr,len); + if (ssize < 0) + { + perror("sendto"); + return -1; + } + + sleep(1); + } + + + if (close(fd) < 0) + { + perror("close"); + return -1; + } + + return 0; + +} + + diff --git a/study_clang/makefile_1/Makefile b/study_clang/makefile_1/Makefile new file mode 100644 index 0000000..8d52b1a --- /dev/null +++ b/study_clang/makefile_1/Makefile @@ -0,0 +1,9 @@ +CC=gcc +TARGET=All +OBJECTS= m.o visit.o listen.o watch.o study.o play.o +$(TARGET):$(OBJECTS) + $(CC) $^ -o m +*.o:*.c + $(CC) -c $< -o $@ +clean: + rm *.o diff --git a/study_clang/makefile_1/Makefile.backup1 b/study_clang/makefile_1/Makefile.backup1 new file mode 100644 index 0000000..c9fedb3 --- /dev/null +++ b/study_clang/makefile_1/Makefile.backup1 @@ -0,0 +1,19 @@ +CC=gcc +TARGET=All +OBJECTS= m.o visit.o listen.o watch.o study.o play.o +$(TARGET):$(OBJECTS) + $(CC) $(OBJECTS) -o m +m.o:m.c m.h + $(CC) -c m.c -o m.o +visio.o:visit.c + $(CC) -c visit.c -o visit.o +listen.o:listen.c + $(CC) -c listen.c -o listen.o +watch.o:watch.c + $(CC) -c watch.c -o watch.o +study.o:study.c + $(CC) -c study.c -o study.o +play.o:play.c + $(CC) -c play.c -o play.o +clean: + rm * .o diff --git a/study_clang/makefile_1/Makefile.backup2 b/study_clang/makefile_1/Makefile.backup2 new file mode 100644 index 0000000..b2714e9 --- /dev/null +++ b/study_clang/makefile_1/Makefile.backup2 @@ -0,0 +1,19 @@ +CC=gcc +TARGET=All +OBJECTS= m.o visit.o listen.o watch.o study.o play.o +$(TARGET):$(OBJECTS) + $(CC) $^ -o m +m.o:m.c m.h + $(CC) -c $< -o $@ +visio.o:visit.c + $(CC) -c $< -o $@ +listen.o:listen.c + $(CC) -c $< -o $@ +watch.o:watch.c + $(CC) -c $< -o $@ +study.o:study.c + $(CC) -c $< -o $@ +play.o:play.c + $(CC) -c $< -o $@ +clean: + rm -rf *.o diff --git a/study_clang/makefile_1/listen.c b/study_clang/makefile_1/listen.c new file mode 100644 index 0000000..64d41a6 --- /dev/null +++ b/study_clang/makefile_1/listen.c @@ -0,0 +1,5 @@ +#include +void listen() +{ + printf("listen english today\n"); +} diff --git a/study_clang/makefile_1/listen.o b/study_clang/makefile_1/listen.o new file mode 100644 index 0000000..f4fdad7 Binary files /dev/null and b/study_clang/makefile_1/listen.o differ diff --git a/study_clang/makefile_1/m b/study_clang/makefile_1/m new file mode 100755 index 0000000..3220a53 Binary files /dev/null and b/study_clang/makefile_1/m differ diff --git a/study_clang/makefile_1/m.c b/study_clang/makefile_1/m.c new file mode 100644 index 0000000..0f5d11f --- /dev/null +++ b/study_clang/makefile_1/m.c @@ -0,0 +1,21 @@ +# include +int main() +{ + int i; + printf("Please input the value of i from 1 to 5:\n"); + scanf("%d",&i); + if(i==1) + visit(); + else if(i==2) + study(); + else if(i==3) + play(); + else if(i==4) + watch(); + else if(i==5) + listen(); + else + printf("nothing to do\n"); + printf("This is a wonderful day\n"); + return 0; +} diff --git a/study_clang/makefile_1/m.h b/study_clang/makefile_1/m.h new file mode 100644 index 0000000..42b1e10 --- /dev/null +++ b/study_clang/makefile_1/m.h @@ -0,0 +1,6 @@ +void visit(); +void listen(); +void watch(); +void study(); +void play(); + diff --git a/study_clang/makefile_1/m.o b/study_clang/makefile_1/m.o new file mode 100644 index 0000000..e630d11 Binary files /dev/null and b/study_clang/makefile_1/m.o differ diff --git a/study_clang/makefile_1/play.c b/study_clang/makefile_1/play.c new file mode 100644 index 0000000..d87ba18 --- /dev/null +++ b/study_clang/makefile_1/play.c @@ -0,0 +1,5 @@ +#include +void play() +{ + printf("play football today\n"); +} diff --git a/study_clang/makefile_1/play.o b/study_clang/makefile_1/play.o new file mode 100644 index 0000000..42436cf Binary files /dev/null and b/study_clang/makefile_1/play.o differ diff --git a/study_clang/makefile_1/study.c b/study_clang/makefile_1/study.c new file mode 100644 index 0000000..ba5f95a --- /dev/null +++ b/study_clang/makefile_1/study.c @@ -0,0 +1,4 @@ +void study() +{ + printf("study embedded system today\n"); +} diff --git a/study_clang/makefile_1/study.o b/study_clang/makefile_1/study.o new file mode 100644 index 0000000..8e6bf19 Binary files /dev/null and b/study_clang/makefile_1/study.o differ diff --git a/study_clang/makefile_1/visit.c b/study_clang/makefile_1/visit.c new file mode 100644 index 0000000..60e2d36 --- /dev/null +++ b/study_clang/makefile_1/visit.c @@ -0,0 +1,5 @@ +#include +void visit() +{ + printf("visit friend today\n"); +} diff --git a/study_clang/makefile_1/visit.o b/study_clang/makefile_1/visit.o new file mode 100644 index 0000000..1b73dca Binary files /dev/null and b/study_clang/makefile_1/visit.o differ diff --git a/study_clang/makefile_1/watch.c b/study_clang/makefile_1/watch.c new file mode 100644 index 0000000..293e150 --- /dev/null +++ b/study_clang/makefile_1/watch.c @@ -0,0 +1,5 @@ +#include +void watch() +{ + printf("watch TV today\n"); +} diff --git a/study_clang/makefile_1/watch.o b/study_clang/makefile_1/watch.o new file mode 100644 index 0000000..6a5c30f Binary files /dev/null and b/study_clang/makefile_1/watch.o differ diff --git a/study_clang/mult-progress/test b/study_clang/mult-progress/test new file mode 100755 index 0000000..8d9afa7 Binary files /dev/null and b/study_clang/mult-progress/test differ diff --git a/study_clang/mult-progress/test.c b/study_clang/mult-progress/test.c new file mode 100644 index 0000000..a6e040c --- /dev/null +++ b/study_clang/mult-progress/test.c @@ -0,0 +1,48 @@ +/* + * @Author: 123123 + * @Date: 2020-07-18 18:30:18 + * @LastEditors: your name + * @LastEditTime: 2020-07-18 18:35:12 + * @Description: file content + * @new: + */ + +#include +#include +#include +/** + * @description: + * @param {type} + * @return: + */ +main() +{ + pid_t pid; + char *msg; + int k; + + pid=fork(); + switch(pid){ + //子进程执行部分 + case 0: + msg="Child process is running.\n"; + k=3; + break; + case -1: + perror("Process creation failed.\n"); + break; + //父进程执行部分 + default: + msg="Parent process is running.\n"; + k=5; + break; + } + + //父子进程共同执行部分 + while(k>0){ + puts(msg); + sleep(1); + k--; + } +} + diff --git a/study_clang/mult-progress/test2 b/study_clang/mult-progress/test2 new file mode 100755 index 0000000..3b372a0 Binary files /dev/null and b/study_clang/mult-progress/test2 differ diff --git a/study_clang/mult-progress/test2.c b/study_clang/mult-progress/test2.c new file mode 100644 index 0000000..df559f5 --- /dev/null +++ b/study_clang/mult-progress/test2.c @@ -0,0 +1,33 @@ +#include +#include + +int main(int arg,char* argv[]){ + + // int 被 typedef 为 pid_t + pid_t pid=fork(); + + // 当pid==0时,是子进程代码运行区域。其他则是父进程运行区域。 + if(pid<0){ + printf("Create child process failed ...\n"); + }else if(pid==0){ + //子进程执行体 + printf("Create child process successfully %i \n",getpid()); + } + else{ + //父进程执行体 + printf("This is parent process %i \n",getpid()); + } + + // 执行体结束标志 + if(pid==0) + { + sleep(3); + printf("pid=%i child process end ... \n",getpid()); + } + else{ + // 睡眠5s,等待子进程结束 + sleep(5); + printf("pid=%i Parent process end ... \n",getpid()); + } + return 0; +} diff --git a/study_clang/multthread/pthread_create b/study_clang/multthread/pthread_create new file mode 100755 index 0000000..5e1b091 Binary files /dev/null and b/study_clang/multthread/pthread_create differ diff --git a/study_clang/multthread/pthread_create.c b/study_clang/multthread/pthread_create.c new file mode 100644 index 0000000..c3de4c2 --- /dev/null +++ b/study_clang/multthread/pthread_create.c @@ -0,0 +1,30 @@ +#include +#include +#include +void * thread(void *str) +{ + int i; + for(i=0;i<6;++i) + { + sleep(2); + printf("This is the thread: %d\n", i); + } + return NULL; +} + +int main() +{ + pthread_t pth; + int i; + int ret; + ret=pthread_create(&pth,NULL,thread,(void *)(i)); + printf("Test start\n"); + for(i=0;i<6;++i) + { + sleep(1); + printf("This is the main: %d\n",i); + } + + pthread_join(pth,NULL); + return 0; +} diff --git a/study_clang/multthread/test b/study_clang/multthread/test new file mode 100755 index 0000000..45be8d0 Binary files /dev/null and b/study_clang/multthread/test differ diff --git a/study_clang/multthread/test.c b/study_clang/multthread/test.c new file mode 100644 index 0000000..918fe2f --- /dev/null +++ b/study_clang/multthread/test.c @@ -0,0 +1,28 @@ +#include +#include +#include +#define NUM_THREADS 5 //线程个数 + +void *say_hello(void *args) +{ + printf("Hello Runoob!\n"); + sleep(2); +} + +int main() +{ + //定义线程的 id 变量,多个变量使用数组 + pthread_t tids[NUM_THREADS]; + for (int i = 0; i < NUM_THREADS; ++i) { + sleep(2); + //参数依次是:创建的线程id,线程参数,调用的函数,传入的函数参数 + int ret = pthread_create(&tids[i], NULL, say_hello, NULL); + if (ret != 0) { + printf("pthread_create error: error_code = %d\n", ret); + } + } + + //等各个线程退出后,进程才结束,否则进程强制结束了,线程可能还没反应过来; + pthread_exit(NULL); +} +//g++ test.cpp -lpthread -o test diff --git a/study_clang/neon/neon_intrinsic.c b/study_clang/neon/neon_intrinsic.c new file mode 100644 index 0000000..0529f7d --- /dev/null +++ b/study_clang/neon/neon_intrinsic.c @@ -0,0 +1,15 @@ +#include +#include + +unsigned short int a[8] = {1, 2, 3, 4, 5, 6, 7, 8}; + +int main() +{ + uint16x8_t va = vld1q_u16(a); + uint16x8_t vb = vrev64q_u16(va); + uint16_t b[8]; + vst1q_u16(b, vb); + for (int i = 0; i < 8; i++) + printf("%d ", b[i]); + return 0; +} diff --git a/study_clang/pcap/Makefile b/study_clang/pcap/Makefile new file mode 100644 index 0000000..7926777 --- /dev/null +++ b/study_clang/pcap/Makefile @@ -0,0 +1,22 @@ +# Batch Single C file MakeFile + +# 指定CPU架构 Architecture -> ARCH +ARCH ?= +CC = $(ARCH)gcc +SUFFIX = .c +CFLAGS += -Wall -g +LD = -lpcap -pthread + +CUR_SOURCE = $(wildcard *$(SUFFIX)) +CUR_TARGETS = $(patsubst %$(SUFFIX), %, $(CUR_SOURCE)) + +all:$(CUR_TARGETS) + +# %:%.c 是一个表示与目标相同 文件的模式变量 +$(CUR_TARGETS):%:%$(SUFFIX) + $(CC) $< $(CFLAGS) -o $@ $(LD) + +# 指定伪目标 +.PHONY:clean all + clean: + -rm -rf $(TARGETS) diff --git a/study_clang/pcap/demo1 b/study_clang/pcap/demo1 new file mode 100755 index 0000000..efd2277 Binary files /dev/null and b/study_clang/pcap/demo1 differ diff --git a/study_clang/pcap/demo1.c b/study_clang/pcap/demo1.c new file mode 100644 index 0000000..c789e0d --- /dev/null +++ b/study_clang/pcap/demo1.c @@ -0,0 +1,27 @@ +/************************************************************************* + > File Name : demo1.c + > Author : TL Song + > EMail : songtianlun@frytea.com + > Created Time : Thu Feb 18 16:25:53 2021 + ************************************************************************/ + +#include +#include + +int main() +{ + char errBuf[PCAP_ERRBUF_SIZE], * device; + + device = pcap_lookupdev(errBuf); + + if(device) + { + printf("success: device: %s\n", device); + } + else + { + printf("error: %s\n", errBuf); + } + + return 0; +} \ No newline at end of file diff --git a/study_clang/pcap/demo2 b/study_clang/pcap/demo2 new file mode 100755 index 0000000..85073e6 Binary files /dev/null and b/study_clang/pcap/demo2 differ diff --git a/study_clang/pcap/demo2.c b/study_clang/pcap/demo2.c new file mode 100644 index 0000000..d655df9 --- /dev/null +++ b/study_clang/pcap/demo2.c @@ -0,0 +1,111 @@ +/************************************************************************* + > File Name : demo2.c + > Author : TL Song + > EMail : songtianlun@frytea.com + > Created Time : Thu Feb 18 20:31:49 2021 + ************************************************************************/ + +#include +#include +#include +#include + +#define SNAP_LEN 65536 +#define dPrint(fmt, ...) do{fprintf(stderr, "[%s:%d] " fmt "\r\n", __FUNCTION__, __LINE__, ##__VA_ARGS__);}while(0) +#define HexPrint(_buf, _len) \ +{\ + int _m_i = 0;\ + char *_m_buf = (char *)(_buf);\ + int _m_len = (int)(_len);\ + printf("[%s:%d] \r\n", __FUNCTION__, __LINE__);\ + printf("*****************************\n");\ + for(_m_i = 0; _m_i < _m_len; _m_i++)\ + {\ + printf("\033[32m%02x \033[0m", _m_buf[_m_i] & 0xff);\ + if(!((_m_i+1) % 10)) printf("\n");\ + }\ + printf("\nsize = %d\n*****************************\n", _m_len);\ +} + + +int send_pkt_pcap(const u_char *pkt, int len) +{ + static pcap_t *handle = NULL; + char dev_str[64]; + char err_buf[PCAP_ERRBUF_SIZE]; + + strcpy(dev_str, "eth1"); + if(NULL == handle) + { + handle = pcap_open_live(dev_str, SNAP_LEN, 1, 1000, err_buf); + if (handle == NULL) + { + fprintf(stderr, "Couldn't open device %s: %s\n", dev_str, err_buf); + return 0; + } + } + + return pcap_sendpacket(handle, pkt, len); +} + + +void dispatcher_handler(u_char *temp1, const struct pcap_pkthdr *header, const u_char *pkt_data) +{ + HexPrint((const char *)pkt_data, header->caplen); + + u_char pkt_send[header->caplen]; + + memset(pkt_send, 0x00, sizeof(pkt_send)); + memcpy(pkt_send, pkt_data, header->caplen); + HexPrint((const char *)pkt_send, sizeof(pkt_send)); + + dPrint("Send ret : %d", send_pkt_pcap((const u_char *)pkt_send, sizeof(pkt_send))); +} + +int main(int argc, char *argv[]) +{ + char *dev, errbuf[PCAP_ERRBUF_SIZE]; + struct bpf_program fp; /* The compiled filter expression */ + char filter_exp[] = "vlan and src host 192.168.1.123"; /* The filter expression (filter 53 port)*/ + pcap_t *handle; + bpf_u_int32 mask; /* The netmask of our sniffing device */ + bpf_u_int32 net; /* The IP of our sniffing device */ + + dev = pcap_lookupdev(errbuf); + if (dev == NULL) { + fprintf(stderr, "Couldn't find default device: %s\n", errbuf); + return(2); + } + printf("Device: %s\n", dev); + + /*get network mask*/ + if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) { + fprintf(stderr, "Can't get netmask for device %s\n", dev); + net = 0; + mask = 0; + } + /*Open the session in promiscuous mode*/ + handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf); + if (handle == NULL) { + fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf); + return(2); + } + /* Compile and apply the filter */ + if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) { + fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle)); + return(2); + } + if (pcap_setfilter(handle, &fp) == -1) { + fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle)); + return(2); + } + pcap_loop(handle, -1, dispatcher_handler, NULL); + + /* cleanup */ + pcap_freecode(&fp); + pcap_close(handle); + + dPrint("Capture complete."); + + return(0); +} \ No newline at end of file diff --git a/study_clang/pcap/demo3 b/study_clang/pcap/demo3 new file mode 100755 index 0000000..ba96e06 Binary files /dev/null and b/study_clang/pcap/demo3 differ diff --git a/study_clang/pcap/demo3.c b/study_clang/pcap/demo3.c new file mode 100644 index 0000000..c9c74ef --- /dev/null +++ b/study_clang/pcap/demo3.c @@ -0,0 +1,68 @@ +/************************************************************************* + > File Name : demo3.c + > Author : TL Song + > EMail : songtianlun@frytea.com + > Created Time : Thu Feb 18 20:14:21 2021 + ************************************************************************/ + +#include +#include +#include +#include + +void getPacket(u_char * arg, const struct pcap_pkthdr * pkthdr, const u_char * packet) +{ + int * id = (int *)arg; + + printf("id: %d\n", ++(*id)); + printf("Packet length: %d\n", pkthdr->len); + printf("Number of bytes: %d\n", pkthdr->caplen); + printf("Recieved time: %s", ctime((const time_t *)&pkthdr->ts.tv_sec)); + + int i; + for(i=0; ilen; ++i) + { + printf(" %02x", packet[i]); + if( (i + 1) % 16 == 0 ) + { + printf("\n"); + } + } + + printf("\n\n"); +} + +int main() +{ + char errBuf[PCAP_ERRBUF_SIZE], * devStr; + + /* get a device */ + devStr = pcap_lookupdev(errBuf); + + if(devStr) + { + printf("success: device: %s\n", devStr); + } + else + { + printf("error: %s\n", errBuf); + exit(1); + } + + /* open a device, wait until a packet arrives */ + pcap_t * device = pcap_open_live(devStr, 65535, 1, 0, errBuf); + + if(!device) + { + printf("error: pcap_open_live(): %s\n", errBuf); + exit(1); + } + + /* wait loop forever */ + int id = 0; + pcap_loop(device, -1, getPacket, (u_char*)&id); + + pcap_close(device); + + return 0; +} \ No newline at end of file diff --git a/study_clang/pcap/icmp_proxy b/study_clang/pcap/icmp_proxy new file mode 100755 index 0000000..952dd0d Binary files /dev/null and b/study_clang/pcap/icmp_proxy differ diff --git a/study_clang/pcap/icmp_proxy.c b/study_clang/pcap/icmp_proxy.c new file mode 100644 index 0000000..54dde1a --- /dev/null +++ b/study_clang/pcap/icmp_proxy.c @@ -0,0 +1,135 @@ +/************************************************************************* + > File Name : icmp_proxy.c + > Author : TL Song + > EMail : songtianlun@frytea.com + > Created Time : Thu Feb 18 19:23:50 2021 + ************************************************************************/ + +#include +#include +#include + + +#define SNAP_LEN 65536 +static char g_ftag[6] = {0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE}; + + +/* +struct pcap_pkthdr +{ + struct timeval ts; ts是一个结构struct timeval,它有两个部分,第一部分是1900开始以来的秒数,第二部分是当前秒之后的毫秒数 + bpf_u_int32 caplen; 表示抓到的数据长度 + bpf_u_int32 len; 表示数据包的实际长度 +} + + +*/ +#define dPrint(fmt, ...) do{fprintf(stderr, "[%s:%d] " fmt "\r\n", __FUNCTION__, __LINE__, ##__VA_ARGS__);}while(0) +#define HexPrint(_buf, _len) \ +{\ + int _m_i = 0;\ + char *_m_buf = (char *)(_buf);\ + int _m_len = (int)(_len);\ + printf("[%s:%d] \r\n", __FUNCTION__, __LINE__);\ + printf("*****************************\n");\ + for(_m_i = 0; _m_i < _m_len; _m_i++)\ + {\ + printf("\033[32m%02x \033[0m", _m_buf[_m_i] & 0xff);\ + if(!((_m_i+1) % 10)) printf("\n");\ + }\ + printf("\nsize = %d\n*****************************\n", _m_len);\ +} + + +int send_pkt_pcap(const u_char *pkt, int len) +{ + static pcap_t *handle = NULL; + char dev_str[64]; + char err_buf[PCAP_ERRBUF_SIZE]; + + + + strcpy(dev_str, "eth1"); + if(NULL == handle) + { + handle = pcap_open_live(dev_str, SNAP_LEN, 1, 1000, err_buf); + if (handle == NULL) + { + fprintf(stderr, "Couldn't open device %s: %s\n", dev_str, err_buf); + return 0; + } + } + + return pcap_sendpacket(handle, pkt, len); +} + + +void dispatcher_handler(u_char *temp1, const struct pcap_pkthdr *header, const u_char *pkt_data) +{ + HexPrint((const char *)pkt_data, header->caplen); + + u_char pkt_send[header->caplen + sizeof(g_ftag)]; + + memset(pkt_send, 0x00, sizeof(pkt_send)); + memcpy(pkt_send, g_ftag, sizeof(g_ftag)); + memcpy(pkt_send + sizeof(g_ftag), pkt_data, header->caplen); + + HexPrint((const char *)pkt_send, sizeof(pkt_send)); + + dPrint("Send ret : %d", send_pkt_pcap((const u_char *)pkt_send, sizeof(pkt_send))); +} + + + + +int main() +{ + pcap_t *handle; + char err_buf[PCAP_ERRBUF_SIZE]; + char dev_str[64]; + struct bpf_program fp; + + strcpy(dev_str, "eth0"); + + /* open capture device */ + handle = pcap_open_live(dev_str, SNAP_LEN, 1, 1000, err_buf); + if (handle == NULL) + { + fprintf(stderr, "Couldn't open device %s: %s\n", dev_str, err_buf); + return 0; + } + + /* make sure we're capturing on an Ethernet device*/ + if (pcap_datalink(handle) != DLT_EN10MB) + { + fprintf(stderr, "%s is not an Ethernet\n", dev_str); + return 0; + } + + /* compile the filter expression */ + if (pcap_compile(handle, &fp, "vlan and src host 192.168.1.123", 0, 24) == -1) + { + fprintf(stderr, "Couldn't parse filter %s: %s\n", + "***", pcap_geterr(handle)); + return 0; + } + + /* apply the compiled filter */ + if (pcap_setfilter(handle, &fp) == -1) + { + fprintf(stderr, "Couldn't install filter %s: %s\n", + "***", pcap_geterr(handle)); + return 0; + } + + pcap_loop(handle, -1, dispatcher_handler, NULL); + + /* cleanup */ + pcap_freecode(&fp); + pcap_close(handle); + + dPrint("Capture complete."); + + + return 0; +} \ No newline at end of file diff --git a/study_clang/pcap/telnet_proxy b/study_clang/pcap/telnet_proxy new file mode 100755 index 0000000..efb0d5d Binary files /dev/null and b/study_clang/pcap/telnet_proxy differ diff --git a/study_clang/pcap/telnet_proxy.c b/study_clang/pcap/telnet_proxy.c new file mode 100644 index 0000000..9c99818 --- /dev/null +++ b/study_clang/pcap/telnet_proxy.c @@ -0,0 +1,224 @@ +/************************************************************************* + > File Name : telnet_proxy.c + > Author : TL Song + > EMail : songtianlun@frytea.com + > Created Time : Thu Feb 18 18:57:20 2021 + ************************************************************************/ +#include +#include +// #include +#include + +#define SNAP_LEN 65536 +// #define Make_VLAN +#ifdef Make_VLAN +#define RECV_DEVICE "eth0.3000" +#else +#define RECV_DEVICE "eth0" +#endif + +#define RECV_SEND_DEVICE "eth1" +#define RETU_DEVICE "linux_dal" +#define RETU_SEND_DEVICE "eth0" +#define RECV_FILTER "src host 192.168.8.123 and arp or icmp or dst port 23" +#define RETU_FILTER "" + + + +static char g_vlan_tag[4] = {0x81, 0x00, 0x0B, 0xB8}; +#define dPrint(fmt, ...) do{fprintf(stderr, "[%s:%d] " fmt "\r\n", __FUNCTION__, __LINE__, ##__VA_ARGS__);}while(0) +#define HexPrint(_buf, _len) \ +{\ + int _m_i = 0;\ + char *_m_buf = (char *)(_buf);\ + int _m_len = (int)(_len);\ + printf("[%s:%d] \r\n", __FUNCTION__, __LINE__);\ + printf("*****************************\n");\ + for(_m_i = 0; _m_i < _m_len; _m_i++)\ + {\ + printf("\033[32m%02x \033[0m", _m_buf[_m_i] & 0xff);\ + if(!((_m_i+1) % 10)) printf("\n");\ + }\ + printf("\nsize = %d\n*****************************\n", _m_len);\ +} + + +int send_pkt_pcap(char *dev, const u_char *pkt, int len) +{ + static pcap_t *handle = NULL; + char dev_str[64]; + char err_buf[PCAP_ERRBUF_SIZE]; + + strcpy(dev_str, dev); + if(NULL == handle) + { + handle = pcap_open_live(dev_str, SNAP_LEN, 1, 1000, err_buf); + if (handle == NULL) + { + fprintf(stderr, "Couldn't open device %s: %s\n", dev_str, err_buf); + return 0; + } + } + + return pcap_sendpacket(handle, pkt, len); +} + + +void recv_dispatcher_handler(u_char *temp1, const struct pcap_pkthdr *header, const u_char *pkt_data) +{ + HexPrint((const char *)pkt_data, header->caplen); + +#ifdef Make_VLAN + u_char pkt_send[header->caplen + sizeof(g_vlan_tag)]; + memset(pkt_send, 0x00, sizeof(pkt_send)); + memcpy(pkt_send, pkt_data, header->caplen); + memcpy(pkt_send+16, pkt_send+12, header->caplen-12); + memcpy(pkt_send+12, g_vlan_tag, sizeof(g_vlan_tag)); +#else + u_char pkt_send[header->caplen]; + memset(pkt_send, 0x00, sizeof(pkt_send)); + memcpy(pkt_send, pkt_data, header->caplen); +#endif + + HexPrint((const char *)pkt_send, sizeof(pkt_send)); + + dPrint("Send to %s ret : %d\n", RECV_SEND_DEVICE, send_pkt_pcap(RECV_SEND_DEVICE, (const u_char *)pkt_send, sizeof(pkt_send))); + // sleep(1); +} + +void retu_dispatcher_handler(u_char *temp1, const struct pcap_pkthdr *header, const u_char *pkt_data) +{ + // HexPrint((const char *)pkt_data, header->caplen); + + u_char pkt_send[header->caplen]; + + memset(pkt_send, 0x00, sizeof(pkt_send)); + memcpy(pkt_send, pkt_data, header->caplen); + + // HexPrint((const char *)pkt_send, sizeof(pkt_send)); + + dPrint("Send to %s ret : %d\n",RETU_SEND_DEVICE, send_pkt_pcap(RETU_SEND_DEVICE, (const u_char *)pkt_send, sizeof(pkt_send))); +} + +// 接收前面板 eth0 发来的消息,转发到 eth1 +void *recv_handl(void *args) +{ + char errbuf[PCAP_ERRBUF_SIZE]; + struct bpf_program fp; /* The compiled filter expression */ + char filter_exp[] = RECV_FILTER; /* The filter expression (filter 53 port)*/ + pcap_t *handle; + bpf_u_int32 mask; /* The netmask of our sniffing device */ + bpf_u_int32 net; /* The IP of our sniffing device */ + + printf("Recv Device: %s\n", RECV_DEVICE); + + /*get network mask*/ + if (pcap_lookupnet(RECV_DEVICE, &net, &mask, errbuf) == -1) { + fprintf(stderr, "Can't get netmask for device %s\n", RECV_DEVICE); + net = 0; + mask = 0; + } + /*Open the session in promiscuous mode*/ + handle = pcap_open_live(RECV_DEVICE, BUFSIZ, 1, 1000, errbuf); + if (handle == NULL) { + fprintf(stderr, "Couldn't open device %s: %s\n", RECV_DEVICE, errbuf); + return; + } + /* Compile and apply the filter */ + if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) { + fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle)); + return; + } + if (pcap_setfilter(handle, &fp) == -1) { + fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle)); + return; + } + pcap_loop(handle, -1, recv_dispatcher_handler, NULL); + + /* cleanup */ + pcap_freecode(&fp); + pcap_close(handle); + + dPrint("Capture complete."); +} + +// 接收 linux_dal 发来的流量,转发到 eth0 +void *retu_handl(void *args) +{ + char errbuf[PCAP_ERRBUF_SIZE]; + struct bpf_program fp; /* The compiled filter expression */ + char filter_exp[] = RETU_FILTER; /* The filter expression (filter 53 port)*/ + pcap_t *handle; + bpf_u_int32 mask; /* The netmask of our sniffing device */ + bpf_u_int32 net; /* The IP of our sniffing device */ + + printf("Recv Device: %s\n", RETU_DEVICE); + + /*get network mask*/ + if (pcap_lookupnet(RETU_DEVICE, &net, &mask, errbuf) == -1) { + fprintf(stderr, "Can't get netmask for device %s\n", RETU_DEVICE); + net = 0; + mask = 0; + } + /*Open the session in promiscuous mode*/ + handle = pcap_open_live(RETU_DEVICE, BUFSIZ, 1, 1000, errbuf); + if (handle == NULL) { + fprintf(stderr, "Couldn't open device %s: %s\n", RETU_DEVICE, errbuf); + return; + } + /* Compile and apply the filter */ + if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) { + fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle)); + return; + } + if (pcap_setfilter(handle, &fp) == -1) { + fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle)); + return; + } + pcap_loop(handle, -1, retu_dispatcher_handler, NULL); + + /* cleanup */ + pcap_freecode(&fp); + pcap_close(handle); + + dPrint("Capture complete."); +} + +int main() +{ + int ret = 0; + pthread_t tid_recv, tid_return; + + // pthread_attr_t attr; + // pthread_attr_init(&attr); + // pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); //设置线程可分离 + + // 创建线程,参数依次是:创建的线程id,线程参数,调用的函数,传入的函数参数 + // ret = pthread_create(&tid_recv, NULL, recv_handl, NULL); + // if (ret != 0) { + // printf("pthread_create error: error_code = %d\n", ret); + // } + // ret = pthread_create(&tid_return, NULL, retu_handl, NULL); + // if (ret != 0) { + // printf("pthread_create error: error_code = %d\n", ret); + // } + // while(1) {}; + + // 线程分离 + // pthread_exit(NULL); + + pid_t fpid=fork(); + if(fpid==0) + { + retu_handl(NULL); + printf("son/n"); + } + else + { + recv_handl(NULL); + printf("father/n"); + } + + + return 0; +} diff --git a/study_clang/pcap/telnet_proxy_single b/study_clang/pcap/telnet_proxy_single new file mode 100755 index 0000000..5b6925e Binary files /dev/null and b/study_clang/pcap/telnet_proxy_single differ diff --git a/study_clang/pcap/telnet_proxy_single.c b/study_clang/pcap/telnet_proxy_single.c new file mode 100644 index 0000000..a8a8253 --- /dev/null +++ b/study_clang/pcap/telnet_proxy_single.c @@ -0,0 +1,186 @@ +/************************************************************************* + > File Name : telnet_proxy.c + > Author : TL Song + > EMail : songtianlun@frytea.com + > Created Time : Thu Feb 18 18:57:20 2021 + ************************************************************************/ +#include +#include +// #include +#include + +#define RECV_SEND_DEVICE "eth1" +#define RETU_DEVICE "linux_dal" +#define RETU_SEND_DEVICE RECV_DEVICE +#define RECV_FILTER "src host 192.168.8.123 and arp or icmp or dst port 23" +#define RETU_FILTER "" +// switch, 1、定义后以多进程模式运行;2、定义后为抓到的包追加vlan标签。 +// #define RUNNING_WITH_MULT_PROGRESS 0 +// #define GREP_WITH_MAKE_VLAN 0 + +#define SNAP_LEN 65536 +#ifndef GREP_WITH_MAKE_VLAN +#define RECV_DEVICE "eth0" +#else +#define RECV_DEVICE "eth0.3000" +#endif + +static char g_vlan_tag[4] = {0x81, 0x00, 0x0B, 0xB8}; +#define dPrint(fmt, ...) do{fprintf(stderr, "[%s:%d] " fmt "\r\n", __FUNCTION__, __LINE__, ##__VA_ARGS__);}while(0) +#define HexPrint(_buf, _len) \ +{\ + int _m_i = 0;\ + char *_m_buf = (char *)(_buf);\ + int _m_len = (int)(_len);\ + printf("[%s:%d] \r\n", __FUNCTION__, __LINE__);\ + printf("*****************************\n");\ + for(_m_i = 0; _m_i < _m_len; _m_i++)\ + {\ + printf("\033[32m%02x \033[0m", _m_buf[_m_i] & 0xff);\ + if(!((_m_i+1) % 10)) printf("\n");\ + }\ + printf("\nsize = %d\n*****************************\n", _m_len);\ +} + + char err_buf[PCAP_ERRBUF_SIZE]; + struct bpf_program fp_recv; /* The compiled filter expression */ + struct bpf_program fp_retu; /* The compiled filter expression */ + char filter_recv[] = RECV_FILTER; /* The filter expression (filter 53 port)*/ + char filter_retu[] = RETU_FILTER; /* The filter expression (filter 53 port)*/ + pcap_t *handle_recv; + pcap_t *handle_retu; + pcap_t *handle_recv_send; + bpf_u_int32 mask_recv; /* The netmask of our sniffing device */ + bpf_u_int32 mask_retu; /* The netmask of our sniffing device */ + bpf_u_int32 net_recv; /* The IP of our sniffing device */ + bpf_u_int32 net_retu; /* The IP of our sniffing device */ + +void recv_dispatcher_handler(u_char *temp1, const struct pcap_pkthdr *header, const u_char *pkt_data) +{ + // HexPrint((const char *)pkt_data, header->caplen); +#ifndef GREP_WITH_MAKE_VLAN + u_char pkt_send[header->caplen]; + memset(pkt_send, 0x00, sizeof(pkt_send)); + memcpy(pkt_send, pkt_data, header->caplen); +#else + u_char pkt_send[header->caplen + sizeof(g_vlan_tag)]; + memset(pkt_send, 0x00, sizeof(pkt_send)); + memcpy(pkt_send, pkt_data, header->caplen); + memcpy(pkt_send+16, pkt_send+12, header->caplen-12); + memcpy(pkt_send+12, g_vlan_tag, sizeof(g_vlan_tag)); +#endif + + // HexPrint((const char *)pkt_send, sizeof(pkt_send)); + dPrint("Send to %s ret : %d", RECV_SEND_DEVICE, pcap_sendpacket(handle_recv_send, pkt_send, sizeof(pkt_send)) ); +} + +void retu_dispatcher_handler(u_char *temp1, const struct pcap_pkthdr *header, const u_char *pkt_data) +{ + // HexPrint((const char *)pkt_data, header->caplen); + u_char pkt_send[header->caplen]; + memset(pkt_send, 0x00, sizeof(pkt_send)); + memcpy(pkt_send, pkt_data, header->caplen); + // HexPrint((const char *)pkt_send, sizeof(pkt_send)); + + dPrint("Send to %s ret : %d", RECV_DEVICE, pcap_sendpacket(handle_recv, pkt_send, sizeof(pkt_send)) ); +} + +// 接收前面板 eth0 发来的消息,转发到 eth1 +void *recv_handl(void *args) +{ + pcap_loop(handle_recv, -1, recv_dispatcher_handler, NULL); + dPrint("Capture complete."); +} + +// 接收 linux_dal 发来的流量,转发到 eth0 +void *retu_handl(void *args) +{ + pcap_loop(handle_retu, -1, retu_dispatcher_handler, NULL); + dPrint("Capture complete."); +} + +int main() +{ + pthread_t tid_retu; + + printf("Recv Device: %s\n", RECV_DEVICE); + printf("Retu Device: %s\n", RETU_DEVICE); + printf("Recv Send Device: %s\n", RECV_SEND_DEVICE); + printf("Retu Send Device: %s\n", RETU_SEND_DEVICE); + + /*get network mask*/ + if (pcap_lookupnet(RECV_DEVICE, &net_recv, &mask_recv, err_buf) == -1) { + fprintf(stderr, "Can't get netmask for device %s\n", RECV_DEVICE); + net_recv = 0; + mask_recv = 0; + } + if (pcap_lookupnet(RETU_DEVICE, &net_retu, &mask_retu, err_buf) == -1) { + fprintf(stderr, "Can't get netmask for device %s\n", RETU_DEVICE); + net_retu = 0; + mask_retu = 0; + } + /*Open the session in promiscuous mode*/ + handle_recv = pcap_open_live(RECV_DEVICE, BUFSIZ, 1, 1000, err_buf); + if (handle_recv == NULL) { + fprintf(stderr, "Couldn't open device %s: %s\n", RECV_DEVICE, err_buf); + return; + } + handle_recv_send = pcap_open_live(RECV_SEND_DEVICE, SNAP_LEN, 1, 1000, err_buf); + if (handle_recv_send == NULL) + { + fprintf(stderr, "Couldn't open device %s: %s\n", RECV_SEND_DEVICE, err_buf); + return 0; + } + handle_retu = pcap_open_live(RETU_DEVICE, BUFSIZ, 1, 1000, err_buf); + if (handle_retu == NULL) { + fprintf(stderr, "Couldn't open device %s: %s\n", RETU_DEVICE, err_buf); + return; + } + /* Compile and apply the filter */ + if (pcap_compile(handle_recv, &fp_recv, filter_recv, 0, net_recv) == -1) { + fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_recv, pcap_geterr(handle_recv)); + return; + } + if (pcap_compile(handle_retu, &fp_retu, filter_retu, 0, net_retu) == -1) { + fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_retu, pcap_geterr(handle_retu)); + return; + } + if (pcap_setfilter(handle_recv, &fp_recv) == -1) { + fprintf(stderr, "Couldn't install filter %s: %s\n", filter_recv, pcap_geterr(handle_recv)); + return; + } + if (pcap_setfilter(handle_retu, &fp_retu) == -1) { + fprintf(stderr, "Couldn't install filter %s: %s\n", filter_retu, pcap_geterr(handle_retu)); + return; + } + +#ifndef RUNNING_WITH_MULT_PROGRESS + int ret = pthread_create(&tid_retu, NULL, retu_handl, NULL); + if (ret != 0) { + printf("pthread_create error: error_code = %d\n", ret); + } + recv_handl(NULL); + pthread_exit(NULL); +#else + pid_t fpid=fork(); + if(fpid==0) + { + retu_handl(NULL); + printf("son/n"); + } + else + { + recv_handl(NULL); + printf("father/n"); + } +#endif + + /* cleanup */ + pcap_freecode(&fp_recv); + pcap_close(handle_recv); + pcap_freecode(&fp_retu); + pcap_close(handle_retu); + + dPrint("Capture complete."); + return 0; +} diff --git a/study_clang/socket/Makefile b/study_clang/socket/Makefile new file mode 100644 index 0000000..83f8bd3 --- /dev/null +++ b/study_clang/socket/Makefile @@ -0,0 +1,22 @@ +# Batch Single C file MakrFile + +# 指定CPU架构 Architecture -> ARCH +ARCH ?= +CC = $(ARCH)gcc +SUFFIX = .c +CFLAGS += -Wall -g +LD = + +CUR_SOURCE = $(wildcard *$(SUFFIX)) +CUR_TARGETS = $(patsubst %$(SUFFIX), %, $(CUR_SOURCE)) + +all:$(CUR_TARGETS) + +# %:%.c 是一个表示与目标相同 文件的模式变量 +$(CUR_TARGETS):%:%$(SUFFIX) + $(CC) $< $(CFLAGS) -o $@ $(LD) + +# 指定伪目标 +.PHONY:clean all + clean: + -rm -rf $(TARGETS) diff --git a/study_clang/socket/demo_tcp6_client b/study_clang/socket/demo_tcp6_client new file mode 100755 index 0000000..3766d26 Binary files /dev/null and b/study_clang/socket/demo_tcp6_client differ diff --git a/study_clang/socket/demo_tcp6_client.c b/study_clang/socket/demo_tcp6_client.c new file mode 100644 index 0000000..6ee196d --- /dev/null +++ b/study_clang/socket/demo_tcp6_client.c @@ -0,0 +1,49 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int main() +{ + int client_fd = socket(AF_INET6, SOCK_STREAM, 0); + if (client_fd < 0) + { + printf("create socket error=%d(%s)!!!\n", errno, strerror(errno)); + exit(1); + } + + struct sockaddr_in6 server_addr; + server_addr.sin6_family = AF_INET6; + server_addr.sin6_port = htons(12500); + if (inet_pton(AF_INET6, "::1", &server_addr.sin6_addr) <= 0) + { + printf("inet_pton error!!!\n"); + exit(1); + } + + if (connect(client_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) + { + printf("socket connect error=%d(%s)!!!\n", errno, strerror(errno)); + exit(1); + } + printf("connect to server ok!\n"); + + char msg[1024]; + int rbytes = -1; + while ( (rbytes = read(client_fd, msg, sizeof(msg)-1)) > 0) + { + msg[rbytes] = 0; // null terminate + printf("%s\n", msg); + } + if (rbytes < 0) + { + printf("read error=%d(%s)!!!\n", errno, strerror(errno)); + } + exit(0); +} \ No newline at end of file diff --git a/study_clang/socket/demo_tcp6_server b/study_clang/socket/demo_tcp6_server new file mode 100755 index 0000000..06332d0 Binary files /dev/null and b/study_clang/socket/demo_tcp6_server differ diff --git a/study_clang/socket/demo_tcp6_server.c b/study_clang/socket/demo_tcp6_server.c new file mode 100644 index 0000000..31b4027 --- /dev/null +++ b/study_clang/socket/demo_tcp6_server.c @@ -0,0 +1,79 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BACKLOG 16 + +int listen_fd = -1; + +void sigINT(int signo); + +int main() +{ + if (signal(SIGINT, sigINT) == SIG_ERR) + { + printf("set signal handler(SIGINT) error!!!\n"); + exit(1); + } + + // socket + if ( (listen_fd = socket(AF_INET6, SOCK_STREAM, 0)) < 0 ) + { + printf("create socket error=%d(%s)!!!\n", errno, strerror(errno)); + exit(1); + } + + // bind + struct sockaddr_in6 server_addr; + server_addr.sin6_family = AF_INET6; // IPv4 + server_addr.sin6_port = htons(12500); // Port + server_addr.sin6_addr = in6addr_any; // IP + if (bind(listen_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) + { + printf("socket bind error=%d(%s)!!!\n", errno, strerror(errno)); + exit(1); + } + + // listen + if (listen(listen_fd, BACKLOG) < 0) + { + printf("socket listen error=%d(%s)!!!\n", errno, strerror(errno)); + exit(1); + } + + printf("server init ok, start to accept new connect...\n"); + + while (1) + { + // accept + int client_fd = accept(listen_fd, NULL, NULL); + if (client_fd < 0) + { + printf("socket accept error=%d(%s)!!!\n", errno, strerror(errno)); + exit(1); + } + printf("accept one new connect(%d)!!!\n", client_fd); + + static const char *msg = "Hello, Client!\n"; + if (write(client_fd, msg, strlen(msg)) != strlen(msg)) + { + printf("send msg to client error!!!\n"); + } + close(client_fd); + } +} + +void sigINT(int signo) +{ + printf("catch SIGINT, quit...\n"); + close(listen_fd); + exit(0); +} \ No newline at end of file diff --git a/study_clang/socket/socket_tcp_client b/study_clang/socket/socket_tcp_client new file mode 100755 index 0000000..a3d6f50 Binary files /dev/null and b/study_clang/socket/socket_tcp_client differ diff --git a/study_clang/socket/socket_tcp_client.c b/study_clang/socket/socket_tcp_client.c new file mode 100644 index 0000000..704a5ce --- /dev/null +++ b/study_clang/socket/socket_tcp_client.c @@ -0,0 +1,45 @@ +#include +#include +#include +#include +#include +#include +#include + +#define PORT 23 //目标地址端口号 +#define ADDR "192.168.6.234" //目标地址IP + +int main() +{ + int iSocketFD = 0; //socket句柄 + unsigned int iRemoteAddr = 0; + struct sockaddr_in stRemoteAddr = {0}; //对端,即目标地址信息 + socklen_t socklen = 0; + char buf[4096] = {0}; //存储接收到的数据 + + iSocketFD = socket(AF_INET, SOCK_STREAM, 0); //建立socket + if(0 > iSocketFD) + { + printf("创建socket失败!\n"); + return 0; + } + + stRemoteAddr.sin_family = AF_INET; + stRemoteAddr.sin_port = htons(PORT); + inet_pton(AF_INET, ADDR, &iRemoteAddr); + stRemoteAddr.sin_addr.s_addr=iRemoteAddr; + + //连接方法: 传入句柄,目标地址,和大小 + if(0 > connect(iSocketFD, (void *)&stRemoteAddr, sizeof(stRemoteAddr))) + { + printf("连接失败!\n"); + //printf("connect failed:%d",errno);//失败时也可打印errno + }else{ + printf("连接成功!\n"); + recv(iSocketFD, buf, sizeof(buf), 0); ////将接收数据打入buf,参数分别是句柄,储存处,最大长度,其他信息(设为0即可)。  + printf("Received:%s\n", buf); + } + + close(iSocketFD);//关闭socket + return 0; +} \ No newline at end of file diff --git a/study_clang/socket/socket_tcp_server b/study_clang/socket/socket_tcp_server new file mode 100755 index 0000000..1add478 Binary files /dev/null and b/study_clang/socket/socket_tcp_server differ diff --git a/study_clang/socket/socket_tcp_server.c b/study_clang/socket/socket_tcp_server.c new file mode 100644 index 0000000..a67be39 --- /dev/null +++ b/study_clang/socket/socket_tcp_server.c @@ -0,0 +1,73 @@ +#include +#include +#include +#include +#include +#include +#include + +#define PORT 23 //端口号 +#define BACKLOG 5 //最大监听数 + +int main() +{ + int iSocketFD = 0; //socket句柄 + int iRecvLen = 0; //接收成功后的返回值 + int new_fd = 0; //建立连接后的句柄 + char buf[4096] = {0}; // + struct sockaddr_in stLocalAddr = {0}; //本地地址信息结构图,下面有具体的属性赋值 + struct sockaddr_in stRemoteAddr = {0}; //对方地址信息 + socklen_t socklen = 0; + + iSocketFD = socket(AF_INET, SOCK_STREAM, 0); //建立socket + if(0 > iSocketFD) + { + printf("创建socket失败!\n"); + return 0; + } + + stLocalAddr.sin_family = AF_INET; /*该属性表示接收本机或其他机器传输*/ + stLocalAddr.sin_port = htons(PORT); /*端口号*/ + stLocalAddr.sin_addr.s_addr=htonl(INADDR_ANY); /*IP,括号内容表示本机IP*/ + + //绑定地址结构体和socket + if(0 > bind(iSocketFD, (void *)&stLocalAddr, sizeof(stLocalAddr))) + { + printf("绑定失败!\n"); + return 0; + } + + //开启监听 ,第二个参数是最大监听数 + if(0 > listen(iSocketFD, BACKLOG)) + { + printf("监听失败!\n"); + return 0; + } + + printf("iSocketFD: %d\n", iSocketFD); + //在这里阻塞知道接收到消息,参数分别是socket句柄,接收到的地址信息以及大小  + new_fd = accept(iSocketFD, (void *)&stRemoteAddr, &socklen); + if(0 > new_fd) + { + printf("接收失败!\n"); + return 0; + }else{ + printf("接收成功!\n"); + //发送内容,参数分别是连接句柄,内容,大小,其他信息(设为0即可)  + send(new_fd, "这是服务器接收成功后发回的信息!", sizeof("这是服务器接收成功后发回的信息!"), 0); + } + + printf("new_fd: %d\n", new_fd); + iRecvLen = recv(new_fd, buf, sizeof(buf), 0); + if(0 >= iRecvLen) //对端关闭连接 返回0 + { + printf("接收失败或者对端关闭连接!\n"); + }else{ + printf("buf: %s\n", buf); + } + + close(new_fd); + close(iSocketFD); + + return 0; +} \ No newline at end of file diff --git a/study_clang/socket/socket_udp_client b/study_clang/socket/socket_udp_client new file mode 100755 index 0000000..9859579 Binary files /dev/null and b/study_clang/socket/socket_udp_client differ diff --git a/study_clang/socket/socket_udp_client.c b/study_clang/socket/socket_udp_client.c new file mode 100644 index 0000000..9e7378a --- /dev/null +++ b/study_clang/socket/socket_udp_client.c @@ -0,0 +1,40 @@ +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + int client_sockfd; + int len; + struct sockaddr_in remote_addr; //服务器端网络地址结构体 + int sin_size; + char buf[BUFSIZ]; //数据传送的缓冲区 + memset(&remote_addr,0,sizeof(remote_addr)); //数据初始化--清零 + remote_addr.sin_family=AF_INET; //设置为IP通信 + remote_addr.sin_addr.s_addr=inet_addr("127.0.0.1");//服务器IP地址 + remote_addr.sin_port=htons(8000); //服务器端口号 + + /*创建客户端套接字--IPv4协议,面向无连接通信,UDP协议*/ + if((client_sockfd=socket(PF_INET,SOCK_DGRAM,0))<0) + { + perror("socket error"); + return 1; + } + strcpy(buf,"This is a test message"); // 发送的内容 + printf("sending: '%s'\n",buf); + sin_size=sizeof(struct sockaddr_in); + + /*向服务器发送数据包*/ + if((len=sendto(client_sockfd,buf,strlen(buf),0,(struct sockaddr *)&remote_addr,sizeof(struct sockaddr)))<0) + { + perror("recvfrom"); + return 1; + } + + /*关闭套接字*/ + close(client_sockfd); + + return 0; +} \ No newline at end of file diff --git a/study_clang/socket/socket_udp_server b/study_clang/socket/socket_udp_server new file mode 100755 index 0000000..b86e3ec Binary files /dev/null and b/study_clang/socket/socket_udp_server differ diff --git a/study_clang/socket/socket_udp_server.c b/study_clang/socket/socket_udp_server.c new file mode 100644 index 0000000..4f91112 --- /dev/null +++ b/study_clang/socket/socket_udp_server.c @@ -0,0 +1,50 @@ +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + int server_sockfd; + int len; + struct sockaddr_in my_addr; //服务器网络地址结构体 + struct sockaddr_in remote_addr; //客户端网络地址结构体 + int sin_size; + char buf[BUFSIZ]; //数据传送的缓冲区 + memset(&my_addr,0,sizeof(my_addr)); //数据初始化--清零 + my_addr.sin_family=AF_INET; //设置为IP通信 + my_addr.sin_addr.s_addr=INADDR_ANY;//服务器IP地址--允许连接到所有本地地址上 + my_addr.sin_port=htons(8000); //服务器端口号 + + /*创建服务器端套接字--IPv4协议,面向无连接通信,UDP协议*/ + if((server_sockfd=socket(PF_INET,SOCK_DGRAM,0))<0) + { + perror("socket error"); + return 1; + } + + /*将套接字绑定到服务器的网络地址上*/ + if (bind(server_sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))<0) + { + perror("bind error"); + return 1; + } + sin_size=sizeof(struct sockaddr_in); + printf("waiting for a packet...\n"); + + /*接收客户端的数据并将其发送给客户端--recvfrom是无连接的*/ + if((len=recvfrom(server_sockfd,buf,BUFSIZ,0,(struct sockaddr *)&remote_addr,&sin_size))<0) + { + perror("recvfrom error"); + return 1; + } + printf("received packet from %s:\n",inet_ntoa(remote_addr.sin_addr)); + buf[len]='\0'; + printf("contents: %s\n",buf); + + /*关闭套接字*/ + close(server_sockfd); + + return 0; +} \ No newline at end of file diff --git a/study_clang/system-test/control-docker b/study_clang/system-test/control-docker new file mode 100755 index 0000000..d839b84 Binary files /dev/null and b/study_clang/system-test/control-docker differ diff --git a/study_clang/system-test/control-docker.c b/study_clang/system-test/control-docker.c new file mode 100644 index 0000000..407b203 --- /dev/null +++ b/study_clang/system-test/control-docker.c @@ -0,0 +1,139 @@ +#include +#include +#include + +int print() +{ + printf("\n"); + printf("************* Docker控制程序 **************\n"); + printf("************ 1. 启动Docker程序 **************\n"); + printf("************ 2.启动Docker容器 ***********\n"); + printf("************ 3.停止Docker容器 *************\n"); + printf("************ 4.重启Docker容器 *************\n"); + printf("************ 5.进入Docker容器 *************\n"); + printf("************ 6.正在运行的容器 *************\n"); + printf("************ 7.删除Docker容器 *************\n"); + printf("************* 0.退出控制程序 ****************\n"); + printf("\n"); +} + +void StartDocker(){ + system("sudo systemctl start docker"); + +} + +void StartNode(){ + system("docker run -itd --name ubuntu-test ubuntu /bin/bash"); +} + +void StopNode(){ + char cmd[100] = "docker stop "; + char str[20]; + printf("Please enter the CONTAINER ID: "); + scanf("%s",str); + strcat(cmd, str); + // printf(cmd); + system(cmd); +} + +void RestartNode(){ + char cmd[100] = "docker restart "; + char str[20]; + printf("Please enter the CONTAINER ID: "); + scanf("%s",str); + strcat(cmd, str); + // printf(cmd); + system(cmd); +} + +void EnterNode(){ + char cmd[100] = "docker exec -it "; + char str[20]; + printf("Please enter the CONTAINER ID: "); + scanf("%s",str); + strcat(cmd, str); + strcat(cmd, " /bin/bash"); + // printf(cmd); + system(cmd); +} + +void RunningNode(){ + system("docker ps"); +} + +void DeleteNode(){ + char cmd[100] = "docker rm -f "; + char str[20]; + printf("Please enter the CONTAINER ID: "); + scanf("%s",str); + strcat(cmd, str); + // printf(cmd); + system(cmd); +} + +int Operation(int operID) +{ + switch (operID) + { + case 1: + printf("1.启动Docker\n"); + StartDocker(); + break; + case 2: + printf("2.启动Docker实例容器\n"); + StartNode(); + break; + case 3: + printf("3.停止Docker容器\n"); + StopNode(); + break; + case 4: + printf("4.重启Docker容器\n"); + RestartNode(); + break; + case 5: + printf("5.进入Docker容器\n"); + EnterNode(); + break; + case 6: + printf("6.正在运行的容器\n"); + RunningNode(); + break; + case 7: + printf("7.删除Docker容器\n"); + DeleteNode(); + break; + case 0: + return 0; + default: + printf("Error!\n"); + } +} + +int main(int argc,char *argv[]) +{ + int operID; + //const char* operID = NULL; + if(argc>1) + { + if(strlen(argv[1])>1) + { + printf("Operation ID Error!\n"); + return 0; + } + operID = argv[1][0] - '0'; + Operation(operID); + //operID = argv[1]; + //char id[2]; + //sprintf(id, operID); + } + else + { + print(); + scanf("%d",&operID); + // getchar(); + // printf("%d",c); + Operation(operID); + } + return 0; +} diff --git a/study_clang/system-test/output-system b/study_clang/system-test/output-system new file mode 100755 index 0000000..58f6a90 Binary files /dev/null and b/study_clang/system-test/output-system differ diff --git a/study_clang/system-test/output-system.c b/study_clang/system-test/output-system.c new file mode 100644 index 0000000..927f16f --- /dev/null +++ b/study_clang/system-test/output-system.c @@ -0,0 +1,47 @@ +#include + +/* just get lastest info */ +int _System(const char * cmd, char *pRetMsg, int msg_len) +{ + FILE * fp; + char * p = NULL; + int res = -1; + if (cmd == NULL || pRetMsg == NULL || msg_len < 0) + { + printf("Param Error!\n"); + return -1; + } + if ((fp = popen(cmd, "r") ) == NULL) + { + printf("Popen Error!\n"); + return -2; + } + else + { + memset(pRetMsg, 0, msg_len); + //get lastest result + while(fgets(pRetMsg, msg_len, fp) != NULL) + { + printf("Msg:%s",pRetMsg); //print all info + } + + if ( (res = pclose(fp)) == -1) + { + printf("close popenerror!\n"); + return -3; + } + pRetMsg[strlen(pRetMsg)-1] = '\0'; + return 0; + } +} + +int main() +{ + //test cmd + char *cmd = "lsmod"; + char a8Result[128] = {0}; + int ret = 0; + ret = _System(cmd, a8Result, sizeof(a8Result)); + printf("ret = %d \na8Result = %s\nlength = %d \n", ret, a8Result, strlen(a8Result)); + return 0; +} \ No newline at end of file diff --git a/study_clang/system-test/start-docker b/study_clang/system-test/start-docker new file mode 100755 index 0000000..40dda6b Binary files /dev/null and b/study_clang/system-test/start-docker differ diff --git a/study_clang/system-test/start-docker.c b/study_clang/system-test/start-docker.c new file mode 100644 index 0000000..49a2ef9 --- /dev/null +++ b/study_clang/system-test/start-docker.c @@ -0,0 +1,8 @@ +#include +#include + +int main() +{ + system("docker run ubuntu:15.10 /bin/echo 'Hello world' "); + return 0; +} diff --git a/study_clang/system-test/stop-docker b/study_clang/system-test/stop-docker new file mode 100755 index 0000000..c4315a2 Binary files /dev/null and b/study_clang/system-test/stop-docker differ diff --git a/study_clang/system-test/stop-docker.c b/study_clang/system-test/stop-docker.c new file mode 100644 index 0000000..db21189 --- /dev/null +++ b/study_clang/system-test/stop-docker.c @@ -0,0 +1,24 @@ +#include +#include +#include + +int main(int argc,char *argv[]) +{ + const char* id = NULL; + char cmd[100] = "docker stop "; + if(argc>1) + { + id = argv[1]; + char addr[40]; + sprintf(addr, id); + strcat(cmd, addr); + printf(cmd); + system(cmd); + return 1; + } + else + { + printf("Please enter the docker id!\n"); + return -1; + } +} diff --git a/study_clang/system_status/get_current_progress.c b/study_clang/system_status/get_current_progress.c new file mode 100644 index 0000000..98c9e49 --- /dev/null +++ b/study_clang/system_status/get_current_progress.c @@ -0,0 +1,39 @@ +#include +#include +#include +#include + +#define MAX 1024 +#define PID 6 +#define PATH_SIZE 128 + +int main(void) +{ + FILE *fp; + pid_t pid; + char pid_str[MAX]; + char path[PATH_SIZE]; + char buf[MAX]; + + pid = getpid(); + sprintf(pid_str, "%d", pid); + strcpy(path, "/proc/self/task/"); + + strcat(path, pid_str); + strcat(path, "/status"); + + fp = fopen(path, "r"); + if(fp == NULL) + { + perror("fail to pen file"); + exit(1); + } + + while (fgets(buf, MAX, fp) != NULL) + { + printf("%s", buf); + } + fclose(fp); + + return 0; +} diff --git a/study_clang/system_status/get_sys_basic_info b/study_clang/system_status/get_sys_basic_info new file mode 100755 index 0000000..f74372c Binary files /dev/null and b/study_clang/system_status/get_sys_basic_info differ diff --git a/study_clang/system_status/get_sys_basic_info.c b/study_clang/system_status/get_sys_basic_info.c new file mode 100644 index 0000000..ad6cd6a --- /dev/null +++ b/study_clang/system_status/get_sys_basic_info.c @@ -0,0 +1,24 @@ +#include +#include +#include + +int main(int argc,char **argv) +{ + struct utsname buf; + + if(uname(&buf)) + { + perror("uname"); + exit(1); + } + + printf("-------------------------------\n"); + printf("sysname:%s\n",buf.sysname); + printf("nodename:%s\n",buf.nodename); + printf("release:%s\n",buf.release); + printf("version:%s\n",buf.version); + printf("machine:%s\n",buf.machine); + printf("-------------------------------\n"); + + return 0; +} diff --git a/study_clang/system_status/monitor_sys_status_test b/study_clang/system_status/monitor_sys_status_test new file mode 100755 index 0000000..ea1c9d0 Binary files /dev/null and b/study_clang/system_status/monitor_sys_status_test differ diff --git a/study_clang/system_status/monitor_sys_status_test.c b/study_clang/system_status/monitor_sys_status_test.c new file mode 100644 index 0000000..648bf17 --- /dev/null +++ b/study_clang/system_status/monitor_sys_status_test.c @@ -0,0 +1,371 @@ +#include +#include +#include +#include +#include +#include //包含套接字的函数库 +#include //包含AF_INET的相关结构 +#include //包含AF_INET的操作函数 + + +#define MAXBUFSIZE 1024 +#define WAIT_SECOND 3 //暂停时间,单位为“秒” +#define PROJECTNAME "haojiangbo" + +#define PORT 9999 //你服务器的端口号 +#define HOST "127.0.0.1" //你服务器的IP +typedef struct occupy +{ + char name[20]; + unsigned int user; + unsigned int nice; + unsigned int system; + unsigned int idle; +} CPU_OCCUPY ; + +typedef struct SysInfo +{ + int me_cpu_num; + float me_cpu_used; + float me_mem_used; + float me_io_used; + char me_disk_used[10]; + char me_download[1024]; +}SysInfo; + + +typedef struct HJB_MEM{ + char title[20]; + char total[20]; + char used[20]; + char free[20]; + char sjared[20]; + char catch[20]; + char available[20]; +}HJB_MEM; + + +typedef struct HJB_NETWORK{ + char rxkb[20]; + char txkb[20]; + char name[100]; +}HJB_NETWORK; + + +float g_cpu_used; +int cpu_num; //定义一个全局的int类型cup_num +void cal_occupy(CPU_OCCUPY *, CPU_OCCUPY *); +void get_occupy(CPU_OCCUPY *); +float get_io_occupy(); +void get_disk_occupy(char **reused); +float hjbGetMemInfo(HJB_MEM *mem); +void hjbGetNetWorkInfo(HJB_NETWORK *hjb_network); +int main(){ + CPU_OCCUPY ocpu,ncpu; + HJB_MEM hjb_mem; + HJB_NETWORK hjb_network; + + //描述客户端的socket + struct sockaddr_in addr; + //消息长度 + int dataBytes = 0; + //消息 + char sendbuf[MAXBUFSIZE]; + char recvbuf[MAXBUFSIZE]; + + //客户端套接字标识符,只需要一个套接字文件描述符,用于和客户端通信 + int sockfd; + //创建套接字 + sockfd = socket(AF_INET,SOCK_STREAM,0); + if(sockfd < 0){ + perror("创建套接字失败"); + return 0; + } + printf("创建套接字成功\n"); + addr.sin_family = AF_INET; + //定义服务端的套接字端口 + addr.sin_port = htons(PORT); + + //指定服务器端的ip,本地测试:127.0.0.1 + //inet_addr()函数,将点分十进制IP转换成网络字节序IP + addr.sin_addr.s_addr = inet_addr(HOST); + + /**********************连接服务器**********************/ + if(connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) + { + perror("连接服务器失败"); + } + printf("连接到服务器成功...\n"); + + while (true){ + SysInfo *sysInfo; + sysInfo = (SysInfo *)malloc(sizeof(SysInfo)); + sleep(3); + printf("--------------------------------\n"); + //获取cpu核数 + cpu_num = sysconf(_SC_NPROCESSORS_ONLN); + sysInfo->me_cpu_num = cpu_num; + printf("cpu mum:%d\n",sysInfo->me_cpu_num); + //获取cpu使用率 + get_occupy(&ocpu); + sleep(1); + get_occupy(&ncpu); + cal_occupy(&ocpu, &ncpu); + sysInfo->me_cpu_used = g_cpu_used; + //获取内存使用率 + sysInfo->me_mem_used = hjbGetMemInfo(&hjb_mem)*100; + + //IO内存使用率 + sysInfo->me_io_used = get_io_occupy(); + + //获取当前磁盘的使用率 + char *used; + get_disk_occupy(&used); + printf("used_path2 = %d \n",&used); + strcpy(sysInfo->me_disk_used,used); + free(used); + printf("sysInfo->me_disk_used = %s \n",sysInfo->me_disk_used); + + //获取网卡信息 + hjbGetNetWorkInfo(&hjb_network); + printf("network read Info %s %s %s \n", hjb_network.name,hjb_network.rxkb, + hjb_network.txkb); + + strcat(sysInfo->me_download,hjb_network.name); + strcat(sysInfo->me_download,"> rxkb: "); + strcat(sysInfo->me_download,hjb_network.rxkb); + strcat(sysInfo->me_download," txkb: "); + strcat(sysInfo->me_download,hjb_network.txkb); + + char *sendInfo = (char *)malloc(1024); + if(sendInfo != NULL){ + //memcpy(sendInfo,sysInfo, sizeof(SysInfo)); + sprintf(sendInfo,"{\"cpunuber\":%d,\n" + "\"cpu_used\":%4.2f,\n" + "\"mem_used\":%4.2f,\n" + "\"download\":\" %s \",\n" + "\"io_used\":%4.2f,\n" + "\"disk_used\":\"%s\",\n" + "\"projectName\":\"%s\"}\n", + sysInfo->me_cpu_num, + sysInfo->me_cpu_used, + sysInfo->me_mem_used, + sysInfo->me_download, + sysInfo->me_io_used, + sysInfo->me_disk_used, + PROJECTNAME); + + if (sockfd > 0){ + int resultValue = send(sockfd,sendInfo, strlen(sendInfo),MSG_NOSIGNAL); + printf("sendMessage value = \n %s \n", sendInfo); + printf("sendMessage len -> %d \n",strlen(sendInfo)); + if (resultValue == -1){ + close(sockfd); + /**********************连接服务器**********************/ + printf("正在尝试重新连接........\n"); + //创建套接字 + sockfd = socket(AF_INET,SOCK_STREAM,0); + if(sockfd < 0){ + perror("创建套接字失败..\n"); + return 0; + } + printf("创建套接字成功\n"); + addr.sin_family = AF_INET; + //定义服务端的套接字端口 + addr.sin_port = htons(PORT); + + //指定服务器端的ip,本地测试:127.0.0.1 + //inet_addr()函数,将点分十进制IP转换成网络字节序IP + addr.sin_addr.s_addr = inet_addr(HOST); + + /**********************连接服务器**********************/ + if(connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) + { + perror("连接服务器失败"); + } + printf("重新连接成功...\n"); + } + printf("发送消息返回指 %d \n",resultValue); + } else{ + printf("正在尝试重新连接........\n"); + //创建套接字 + sockfd = socket(AF_INET,SOCK_STREAM,0); + if(sockfd < 0){ + perror("创建套接字失败..\n"); + return 0; + } + printf("创建套接字成功..\n"); + addr.sin_family = AF_INET; + //定义服务端的套接字端口 + addr.sin_port = htons(PORT); + + //指定服务器端的ip,本地测试:127.0.0.1 + //inet_addr()函数,将点分十进制IP转换成网络字节序IP + addr.sin_addr.s_addr = inet_addr(HOST); + + /**********************连接服务器**********************/ + if(connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) + { + perror("连接服务器失败"); + } + printf("重新连接成功...\n"); + } + + //recv(sockfd,recvbuf,MAXBUFSIZE,0); + free(sysInfo); + free(sendInfo); + // close(sockfd); + } + + + } + + //close(sockfd); + +} + + +float hjbGetMemInfo(HJB_MEM *mem) { + char buff1[MAXBUFSIZE]; + char buff2[MAXBUFSIZE]; + FILE *free; + free = popen("free", "r"); + if (free == NULL) { + return 0; + } + fgets(buff1, sizeof(buff1), free); + fgets(buff2, sizeof(buff2), free); + // printf("read = %s, \n",buff2); + sscanf(buff2, "%s %s %s %s %s %s %s", + mem->title, mem->total, + mem->used, mem->free, + mem->sjared, mem->catch, + mem->available); + int total ; + int used; + int catch; + sscanf(mem->total,"%d",&total); + sscanf(mem->used,"%d",&used); + sscanf(mem->catch,"%d",&catch); + float use = (used+catch)/((double)total); + pclose(free); + return use; +} + + + void cal_occupy (CPU_OCCUPY *o, CPU_OCCUPY *n){ + double od, nd; + double id, sd; + double scale; + od = (double) (o->user + o->nice + o->system +o->idle);//第一次(用户+优先级+系统+空闲)的时间再赋给od + nd = (double) (n->user + n->nice + n->system +n->idle);//第二次(用户+优先级+系统+空闲)的时间再赋给od + scale = 100.0 / (float)(nd-od); //100除强制转换(nd-od)之差为float类型再赋给scale这个变量 + id = (double) (n->user - o->user); //用户第一次和第二次的时间之差再赋给id + sd = (double) (n->system - o->system);//系统第一次和第二次的时间之差再赋给sd + g_cpu_used = ((sd+id)*100.0)/(nd-od); //((用户+系统)乖100)除(第一次和第二次的时间差)再赋给g_cpu_used +} +void get_occupy (CPU_OCCUPY *o) { + + FILE *fd; + char buff[MAXBUFSIZE]; + fd = fopen ("/proc/stat", "r"); //这里只读取stat文件的第一行及cpu总信息,如需获取每核cpu的使用情况,请分析stat文件的接下来几行。 + fgets (buff, sizeof(buff), fd); + sscanf (buff, "%s %u %u %u %u", o->name, &o->user, &o->nice,&o->system, &o->idle); + fclose(fd); +} + + +float get_io_occupy(){ + char cmd[] ="iostat -d -x"; + char buffer[MAXBUFSIZE]; + char a[20]; + float arr[20]; + FILE* pipe = popen(cmd, "r"); + if (!pipe) return -1; + fgets(buffer, sizeof(buffer), pipe); + fgets(buffer, sizeof(buffer), pipe); + fgets(buffer, sizeof(buffer), pipe); + fgets(buffer, sizeof(buffer), pipe); + sscanf(buffer,"%s %f %f %f %f %f %f %f %f %f %f %f %f %f ",a,&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5],&arr[6],&arr[7],&arr[8],&arr[9],&arr[10],&arr[11],&arr[12]); + //printf("%f\n",arr[12]); + pclose(pipe); + return arr[12]; +} + +void get_disk_occupy(char **reused){ + char currentDirectoryPath[ MAXBUFSIZE ]; + getcwd(currentDirectoryPath, MAXBUFSIZE); + //printf("当前目录:%s\n",currentDirectoryPath); + char cmd[50]="df "; + strcat(cmd,currentDirectoryPath); + //printf("%s\n",cmd); + + char buffer[MAXBUFSIZE]; + FILE* pipe = popen(cmd, "r"); + char fileSys[20]; + char blocks[20]; + char used[20]; + char free_[20]; + char percent[10]; + char moment[20]; + + if (!pipe) return ; + + if(fgets(buffer, sizeof(buffer), pipe)!=NULL){ + sscanf(buffer,"%s %s %s %s %s %s",fileSys,blocks,used,free_,percent,moment); + } + if(fgets(buffer, sizeof(buffer), pipe)!=NULL){ + sscanf(buffer,"%s %s %s %s %s %s",fileSys,blocks,used,free_,percent,moment); + } + *reused = (char *)malloc(sizeof(percent)); + memcpy(*reused,&percent, sizeof(percent)); + /*printf("used_path1 = %d \n",&*reused); + printf("percent mem used: = %s\n",percent); + printf("reused mem used: = %s\n",*reused);*/ + pclose(pipe); +} + +void hjbGetNetWorkInfo(HJB_NETWORK *hjb_network){ + FILE *file; + file = popen("sar -n DEV 1 1 | grep e","r"); + char buff1[1024]; + if(NULL == file){ + return; + } + fgets(buff1, sizeof(buff1),file); + fgets(buff1, sizeof(buff1),file); + //printf("netWordReadData1 = %s \n",buff1); + sscanf(buff1,"%*s %*s %s %*s %*s %s %s %*s %*s %*s", + hjb_network->name,hjb_network->rxkb, + hjb_network->txkb); + pclose(file); +} + +void getCurrentDownloadRates(long int * save_rate) +{ + char intface[] = "eth0:"; //这是网络接口名,根据主机配置 + //char intface[] = "wlan0:"; + FILE * net_dev_file; + char buffer[1024]; + size_t bytes_read; + char * match; + if ( (net_dev_file=fopen("/proc/net/dev", "r")) == NULL ) + { + printf("open file /proc/net/dev/ error!\n"); + exit(EXIT_FAILURE); + } + + int i = 0; + while(i++<20){ + if(fgets(buffer, sizeof(buffer), net_dev_file)!=NULL){ + if(strstr(buffer,intface)!=NULL){ + //printf("%d %s\n",i,buffer); + sscanf(buffer,"%s %ld",buffer,save_rate); + break; + } + } + } + if(i==20) *save_rate=0.01; + fclose(net_dev_file); //关闭文件 + return ; +} \ No newline at end of file diff --git a/study_clang/system_status/test_get_sys_info b/study_clang/system_status/test_get_sys_info new file mode 100755 index 0000000..bd638db Binary files /dev/null and b/study_clang/system_status/test_get_sys_info differ diff --git a/study_clang/system_status/test_get_sys_info.c b/study_clang/system_status/test_get_sys_info.c new file mode 100644 index 0000000..ad44082 --- /dev/null +++ b/study_clang/system_status/test_get_sys_info.c @@ -0,0 +1,302 @@ +/* ===================================================================================== +* +* Filename: proc_more.c +* +* Description: +* +* Version: 1.0 +* Created: 2013年08月07日 11时34分40秒 +* Revision: none +* Compiler: gcc +* +* Author: linkscue (scue), linkscue@gmail.com +* Organization: +* +* =====================================================================================*/ + + #include + #include + #include + #include + #include + #include + #include + #include + void sampleLoadAvg(){ + int f=0; + char buffer[80]=""; /* 定义字符串并初始化为'\0' */ + char buf[5][10]; + char *file="/proc/loadavg"; + f = open(file, O_RDONLY); + if (f == 0) + { + printf("error to open: %s\n", file); + exit(EXIT_FAILURE); + } + read(f, (void *)buffer, 80); + sscanf(buffer, "%s %s %s %s %s", /* sscanf()拆分成多个字符串 */ + &buf[0],&buf[1],&buf[2],&buf[3],&buf[4]); + printf("一分钟平均负载:%s\n", buf[0]); + printf("五分钟平均负载:%s\n", buf[1]); + printf("一刻钟平均负载:%s\n", buf[2]); + printf("采样时刻的间隔:%s\n", buf[3]); + printf("最大线程的数目:%s\n", buf[4]); + close(f); + } + void sampleTime(){ + int f=0; + char buffer[80]=""; + char buf[2][10]; + float seconds=0; + float secondr=0; + char *file="/proc/uptime"; + f = open(file, O_RDONLY); + if (f == 0) + { + printf("error to open: %s\n", file); + exit(EXIT_FAILURE); + } + read(f, (void *)buffer, 80); + sscanf(buffer, "%s %s", &buf[0], &buf[1]); + close(f); + printf("系统运行时间:\t%s秒\n", buf[0]); + printf("系统空闲时间:\t%s秒\n", buf[1]); + close(f); + seconds=strtof(buf[0],NULL); + secondr=strtof(buf[1],NULL); + printf("系统运行时间:\t%03d天%02d时%02d分%02.6f秒\n", + (int)seconds/(24*3600), /* 天 */ + ((int)seconds/(3600))%(24), /* 时 */ + ((int)seconds/60)%60, /* 分 */ + ((int)seconds%60)+(seconds-(int)seconds)); /* 秒(精确至毫秒) */ + printf("系统空闲时间:\t%03d天%02d时%02d分%02.6f秒\n", + (int)secondr/(24*3600), /* 天 */ + ((int)secondr/(3600))%(24), /* 时 */ + ((int)secondr/60)%60, /* 分 */ + ((int)secondr%60)+(secondr-(int)secondr)); /* 秒(精确至毫秒) */ + } + + void sampleKernelVersion(){ + int f=0; + char buffer[80]=""; + char *file="/proc/sys/kernel/version"; + f = open(file, O_RDONLY); + if (f == 0) + { + printf("error to open: %s\n", file); + exit(EXIT_FAILURE); + } + read(f, (void *)buffer, 80); + buffer[strlen(buffer)-1]=0; /* 简单实现tr()函数的功能 */ + printf("当前内核版本:\t%s\n", buffer); + close(f); + } + + void sampleOsRelease(){ + int f=0; + char buffer[80]=""; + char *file="/proc/sys/kernel/osrelease"; + f = open(file, O_RDONLY); + if (f == 0) + { + printf("error to open: %s\n", file); + exit(EXIT_FAILURE); + } + read(f, (void *)buffer, 80); + buffer[strlen(buffer)-1]=0; + printf("当前内核发行版本:\t%s\n", buffer); + close(f); + } + + void sampleOsType(){ + int f=0; + char buffer[80]=""; + char *file="/proc/sys/kernel/ostype"; + f = open(file, O_RDONLY); + if (f == 0) + { + printf("error to open: %s\n", file); + exit(EXIT_FAILURE); + } + read(f, (void *)buffer, 80); + buffer[strlen(buffer)-1]=0; + printf("当前操作系统内核:\t%s\n", buffer); + close(f); + } + + void sampleDiskStat(){ + int i; + FILE *fp; + int nread=0; + ssize_t len = 0; + char *buffer=NULL; + char buf[20][32]; + char *file="/proc/diskstats"; + char *p; + fp = fopen(file, "rb"); + if (fp == NULL) + { + printf("error to open: %s\n", file); + exit(EXIT_FAILURE); + } + printf(" 磁盘 读次数 写次数\n"); + while((nread = getline(&buffer, &len, fp)) != -1) { /* 简单实现读行的功能 */ + sscanf(buffer, "%04s%08s%s %s %s %s %s %s %s %s %s %s %s %s", + &buf[0],&buf[1],&buf[2],&buf[3],&buf[4],&buf[5],&buf[6], + &buf[7],&buf[8],&buf[9],&buf[10],&buf[11],&buf[12],&buf[13]); + if ((p=strstr(buf[2], "loop"))!=NULL) + { + ; /* loop本地回路不作操作 */ + } + else { + printf("%06s%08s%08s\n", + &buf[2],&buf[3], &buf[7]); + } + } + } + + void sampleProcesses(void) + { + FILE *fp; + int nread=0; + ssize_t len = 0; + char *buf=NULL; + char *buffer=NULL; + char *file="/proc/stat"; + fp = fopen(file, "rb"); + if (fp == NULL) + { + printf("error to open: %s\n", file); + exit(EXIT_FAILURE); + } + while((nread = getline(&buffer, &len, fp)) != -1) { + if((buf=strstr(buffer, "processes"))!=NULL) /* 简单实现grep的功能 */ + break; + } + buffer[strlen(buffer)-1]=0; /* 简单实现tr()函数的功能 */ + char count[16]=""; + sscanf(buffer, "%s%s", count, count); + printf("执行线程数目:\t%s\n", count); + } + + void sampleContext(void) + { + FILE *fp; + int nread=0; + ssize_t len = 0; + char *buf=NULL; + char *buffer=NULL; + char *file="/proc/stat"; + fp = fopen(file, "rb"); + if (fp == NULL) + { + printf("error to open: %s\n", file); + exit(EXIT_FAILURE); + } + while((nread = getline(&buffer, &len, fp)) != -1) { + if((buf=strstr(buffer, "ctxt"))!=NULL) /* 简单实现grep的功能 */ + break; + } + buffer[strlen(buffer)-1]=0; /* 简单实现tr()函数的功能 */ + char count[16]=""; + sscanf(buffer, "%s%s", count, count); + printf("上下文切换次数:\t%s\n", count); + } + + void sampleMeminfo() + { + FILE *fp; + int nread=0; + ssize_t len = 0; + char *buf=NULL; + char *buffer=NULL; + char *file="/proc/meminfo"; + char content[16]=""; + fp = fopen(file, "rb"); + if (fp == NULL) + { + printf("error to open: %s\n", file); + exit(EXIT_FAILURE); + } + while((nread = getline(&buffer, &len, fp)) != -1) { + if((buf=strstr(buffer, "MemTotal"))!=NULL) /* 简单实现grep的功能 */ + { + buffer[strlen(buffer)-1]=0; /* 简单实现tr()函数的功能 */ + sscanf(buffer, "%s%s", content, content); + int memtotal_kb=(int)(strtof(content, NULL)); + printf("内存总容量:\t%dG%4dM %4dK\n", + memtotal_kb/(1024*1024), /* Gb */ + (memtotal_kb/(1024))%1024, /* Mb */ + (memtotal_kb%(1024*1024))%1024); /* Kb */ + } + if((buf=strstr(buffer, "MemFree"))!=NULL) /* 简单实现grep的功能 */ + { + buffer[strlen(buffer)-1]=0; /* 简单实现tr()函数的功能 */ + sscanf(buffer, "%s%s", content, content); + int memfree_kb=(int)(strtof(content, NULL)); + printf("内存可用容量:\t%dG%4dM %4dK\n", + memfree_kb/(1024*1024), /* Gb */ + (memfree_kb/(1024))%1024, /* Mb */ + (memfree_kb%(1024*1024))%1024); /* Kb */ + } + if((buf=strstr(buffer, "SwapTotal"))!=NULL) /* 简单实现grep的功能 */ + { + buffer[strlen(buffer)-1]=0; /* 简单实现tr()函数的功能 */ + sscanf(buffer, "%s%s", content, content); + int swaptotal_kb=(int)(strtof(content, NULL)); + printf("SWAP总容量:\t%dG%4dM %4dK\n", + swaptotal_kb/(1024*1024), /* Gb */ + (swaptotal_kb/(1024))%1024, /* Mb */ + (swaptotal_kb%(1024*1024))%1024); /* Kb */ + } + if((buf=strstr(buffer, "SwapFree"))!=NULL) /* 简单实现grep的功能 */ + { + buffer[strlen(buffer)-1]=0; /* 简单实现tr()函数的功能 */ + sscanf(buffer, "%s%s", content, content); + int swapfree_kb=(int)(strtof(content, NULL)); + printf("SWAP可用容量:\t%dG%4dM %4dK\n", + swapfree_kb/(1024*1024), /* Gb */ + (swapfree_kb/(1024))%1024, /* Mb */ + (swapfree_kb%(1024*1024))%1024); /* Kb */ + break; /* 所需的信息已满足,退出循环 */ + } + } + } +/* +* === FUNCTION ====================================================================== +* Name: main +* Description: +* ===================================================================================== +*/ + int main ( int argc, char *argv[] ) + { + printf(">>>系统负载<<<\n"); + sampleLoadAvg(); + printf("----------------------------------------\n"); + printf("\n"); + printf(">>>运行时间<<<\n"); + sampleTime(); + printf("\n"); + printf(">>>版本信息<<<\n"); + sampleOsType(); + sampleOsRelease(); + sampleKernelVersion(); + printf("----------------------------------------\n"); + printf("\n"); + printf(">>>磁盘信息<<<\n"); + sampleDiskStat(); + printf("----------------------------------------\n"); + printf("\n"); + printf(">>>上下文切换<<<\n"); + sampleContext(); + printf("----------------------------------------\n"); + printf("\n"); + printf(">>>线程数目<<<\n"); + sampleProcesses(); + printf("----------------------------------------\n"); + printf("\n"); + printf(">>>内存信息<<<\n"); + sampleMeminfo(); + printf("----------------------------------------\n"); + return EXIT_SUCCESS; + } diff --git a/study_clang/system_status/test_popen b/study_clang/system_status/test_popen new file mode 100755 index 0000000..0e391a9 Binary files /dev/null and b/study_clang/system_status/test_popen differ diff --git a/study_clang/system_status/test_popen.c b/study_clang/system_status/test_popen.c new file mode 100644 index 0000000..66caeb8 --- /dev/null +++ b/study_clang/system_status/test_popen.c @@ -0,0 +1,22 @@ +#include +#include + +#define BUF_SIZE 1024 +char buf[BUF_SIZE]; + +int main(void) +{ + FILE * p_file = NULL; + + p_file = popen("cat /proc/version", "r"); + if (!p_file) { + fprintf(stderr, "Erro to popen"); + } + + while (fgets(buf, BUF_SIZE, p_file) != NULL) { + fprintf(stdout, "%s", buf); + } + pclose(p_file); + + return 0; +} diff --git a/study_clang/telnetd/Makefile b/study_clang/telnetd/Makefile new file mode 100644 index 0000000..5828bd2 --- /dev/null +++ b/study_clang/telnetd/Makefile @@ -0,0 +1,22 @@ +# Batch Single C file MakeFile + +# 指定CPU架构 Architecture -> ARCH +ARCH ?= +CC = $(ARCH)gcc +SUFFIX = .c +CFLAGS += -Wall -g +LD = -lpthread + +CUR_SOURCE = $(wildcard *$(SUFFIX)) +CUR_TARGETS = $(patsubst %$(SUFFIX), %, $(CUR_SOURCE)) + +all:$(CUR_TARGETS) + +# %:%.c 是一个表示与目标相同 文件的模式变量 +$(CUR_TARGETS):%:%$(SUFFIX) + $(CC) $< $(CFLAGS) -o $@ $(LD) + +# 指定伪目标 +.PHONY:clean all + clean: + -rm -rf $(TARGETS) diff --git a/study_clang/telnetd/telnetd b/study_clang/telnetd/telnetd new file mode 100755 index 0000000..ae8a0ff Binary files /dev/null and b/study_clang/telnetd/telnetd differ diff --git a/study_clang/telnetd/telnetd.c b/study_clang/telnetd/telnetd.c new file mode 100644 index 0000000..42b28b1 --- /dev/null +++ b/study_clang/telnetd/telnetd.c @@ -0,0 +1,272 @@ +/************************************************************************* + > File Name : telnetd.c + > Author : TL Song + > EMail : songtianlun@frytea.com + > Created Time : Thu Feb 18 10:04:25 2021 + ************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int save_fd; +#define BUFSIZE 1024 +/*telnet_cmd:ff fb 01 ff fb 03 ff fc 1f*/ +const unsigned char cmd_telnet[9] = {0xff, 0xfb, 0x01, 0xff, 0xfb, 0x03, 0xff, 0xfc, 0x1f}; +char cmdLine[1024] = {0}; + +void task_process(int sockfd); +int telnetd(void); +void *telnetd_pthread(void * arg); +void *task_process_pthread(void *arg) ; + +/*启动telnet服务*/ +int telnetd_start() +{ +#if 1 + pthread_t id; + int i,ret; + + ret=pthread_create(&id,NULL,(void *) telnetd_pthread,NULL); + if(ret!=0){ + printf ("Telnet: telnet_starting.......err!\n"); + return -1; + } + +#else + int pid; + int status; + + if(pid=fork()) { + //exit(0); //是父进程,结束父进程 + waitpid(-1, &status, WNOHANG | WUNTRACED | WCONTINUED); + return 0; + } else if(pid < 0) { + return -1;//exit(1); //fork失败,退出 + } + printf("Telnet: telnet_starting.......\n"); + telnetd(); +#endif +} + + +/*telnet 主服务任务*/ +int main(int argc, char *argv[]) +{ + return telnetd_start(); +} +int telnetd(void) +{ + pid_t fpid; + int status; + int server_sockfd;//服务器端套接字 + int client_sockfd;//客户端套接字 + int len; + struct sockaddr_in server_addr; //服务器网络地址结构体 + struct sockaddr_in remote_addr; //客户端网络地址结构体 + int sin_size; + memset(&server_addr,0,sizeof(server_addr)); //数据初始化--清零 + server_addr.sin_family=AF_INET; //设置为IP通信 + server_addr.sin_addr.s_addr=htonl(INADDR_ANY);//服务器IP地址--允许连接到所有本地地址上 + server_addr.sin_port=htons(23); //服务器telnet端口号 + + //init_telnetd(); + + /*创建服务器端套接字--IPv4协议,面向连接通信,TCP协议*/ + if((server_sockfd=socket(AF_INET,SOCK_STREAM,0))<0) + { + perror("socket"); + return -1; + } + + /*将套接字绑定到服务器的网络地址上*/ + if (bind(server_sockfd,(struct sockaddr *)&server_addr,sizeof(struct sockaddr))<0) + { + perror("bind"); + return -1; + } + + /*监听连接请求*/ + listen(server_sockfd,1); + + printf("Telnet: listening for telnet requests....\n"); + + sin_size=sizeof(struct sockaddr_in); + while(1) { + /*等待客户端连接请求到达*/ + if((client_sockfd=accept(server_sockfd,(struct sockaddr *)&remote_addr,&sin_size))<0) + { + perror("accept"); + return 1; + } + //printf("accept client %s\n",inet_ntoa(remote_addr.sin_addr)); +#if 0 + fpid = fork(); + if (fpid < 0) { + perror("call fork() err!\n"); + exit(1); + } else if (fpid == 0) { + task_process(client_sockfd); + close(client_sockfd); + exit(0); + } else { + waitpid(-1, &status, WNOHANG | WUNTRACED | WCONTINUED); + } +#else + pthread_t id; + int i,ret; + + ret=pthread_create(&id,NULL,(void *) task_process_pthread,(void *)client_sockfd); + if(ret!=0){ + printf ("Telnet: telnet_starting.......err!\n"); + return -1; + } + pthread_join(id,NULL); +#endif + + } + close(client_sockfd); + close(server_sockfd); + return 0; +} +void * telnetd_pthread(void *arg) +{ + telnetd(); +} +/*发送telnet协议命令*/ +int send_telnet_cmd(int fd) +{ + return write(fd, cmd_telnet, sizeof(cmd_telnet)); +} +/*读取命令字符串*/ +int read_cmdline(int sockfd, char *cmdLine, int size) +{ + int ret, rev_count = 0; + char *buf = NULL; + buf = cmdLine; + while(1 == (ret = read(sockfd, buf, 1))) { + rev_count++; + if(rev_count > BUFSIZE - 2) { + return rev_count; + } + if(*buf == '\n') { + return rev_count; + } + buf++; + } + return ret; +} +/*输出重定向*/ +int ioStdSet(int src_fd, int dest_fd, int *save_fd) +{ + *save_fd = dup(dest_fd); + dup2(src_fd, dest_fd); + //close(src_fd); + return *save_fd; +} +/*恢复输出重定向*/ +void recoverIoStdSet(int src_fd, int dest_fd) +{ + dup2(src_fd, dest_fd); + close(src_fd); +} +/*解析字符串*/ +int cmd_analyze(char *cmd) +{ + unsigned char *ptr = NULL; + unsigned char *ptr_tmp; + + if(strlen(cmd) < 12 || strlen(cmd) > 48) { + return -1; + } + /*去除多余的换行符及其他多余字符*/ + while((ptr = strstr(cmd, "\r")) != 0 ) { + while(*ptr != 0) { + *ptr = *(ptr+1); + ptr++; + } + } + + while((ptr = strstr(cmd, "\n")) != 0 ) { + while(*ptr != 0) { + *ptr = *(ptr+1); + ptr++; + } + } + +#if 1 + ptr = cmd; + while((!((*ptr > 'a' && *ptr < 'z') || (*ptr > 'A' && *ptr < 'Z') || (*ptr > '0' && *ptr < '9'))) && (*ptr != 0)) { + ptr_tmp = ptr; + while(*ptr_tmp != 0) { + *ptr_tmp = *(ptr_tmp+1); + ptr_tmp++; + } + } + +#endif + if(strlen(cmd) < 12 || strlen(cmd) > 48) { + return -1; + } + return 0; +} +/*执行命令并回显到telnet终端*/ +int cmd_process(int fd, char *cmdLine) +{ + ioStdSet(fd, 1, &save_fd); /*标准输出重定向*/ + + /*这里添加命令处理函数*/ + /*示例*/ + printf("Welcome to Telnet server.[%s]\n",cmdLine); + + recoverIoStdSet(save_fd, 1); /*恢复输出重定向*/ + return 0; +} +/*telnet交互处理函数*/ +void task_process(int sockfd) +{ + char cmdLine[BUFSIZE]={0}; + int count = 0; + int i=0,tmp = 0; + int ret; + + while(1) { + + send_telnet_cmd(sockfd); + + ioStdSet(sockfd, 1, &save_fd); + printf("\r\r\nlinux>"); + recoverIoStdSet(save_fd, 1); + + memset(cmdLine, 0, sizeof(cmdLine)); + + count = read_cmdline(sockfd, cmdLine, BUFSIZE); + if(count <= 0) { + //perror("read err"); + //exit(1);对方断开连接,返回 + return ; + } + ret = cmd_analyze(cmdLine); + //printf("[%s,%d]rev count:%d,buf:%s\n",__FUNCTION__,__LINE__,count, cmdLine); + if(ret == 0) { + cmd_process(sockfd, cmdLine); + } + + } +} +void *task_process_pthread(void *arg) +{ + int sockfd; + sockfd = (int) arg; + task_process(sockfd); + + pthread_exit((void *)1); +} \ No newline at end of file diff --git a/study_clang/test b/study_clang/test new file mode 100755 index 0000000..3909c8f Binary files /dev/null and b/study_clang/test differ diff --git a/study_clang/test.c b/study_clang/test.c new file mode 100644 index 0000000..dd69f36 --- /dev/null +++ b/study_clang/test.c @@ -0,0 +1,13 @@ +/************************************************************************* + > File Name: test.c + > Author: TianLun Song + > Mail: songtianlun@frytea.com + > Blog: https://blog.frytea.com + > Created Time: Thu 04 Feb 2021 03:52:13 PM CST + ************************************************************************/ +#include +#include +int main() +{ + printf("true: %d, false: %d\n", true, false); +} diff --git a/study_clang/two-way-merge-sort.c b/study_clang/two-way-merge-sort.c new file mode 100644 index 0000000..6366a0b --- /dev/null +++ b/study_clang/two-way-merge-sort.c @@ -0,0 +1,81 @@ +/************************************************************************* + > File Name: two-way-merge-sort.c + > Description: two-way-merge-sort.c + > Author: lkong + > Mail: lkong@tencent.com + > Created Time: 2021-12-15 21:33:35 + ************************************************************************/ + +#include +#include + +// https://www.cnblogs.com/horizonice/p/4102553.html +// https://blog.csdn.net/darkrabbit/article/details/90240709 + +void Merge(int array[], int p, int q, int r); +void MergeSort(int array[], int p, int q); + +int main() +{ + //int array[7] = {1,3,5,2,4,5,10}; + int array[8] = {5,2,4,7,1,3,2,6}; + int i = 0; + + MergeSort(array, 0, 7); + //Merge(array, 0, 2, 6); + + for(i; i < 8; i++) + printf("%d ", array[i]); + return 0; +} + +//合并过程中 p<=q ARCH +ARCH ?= +CC = $(ARCH)gcc +SUFFIX = .c +CFLAGS += -Wall -g -lzmq -lpthread +LD = + +CUR_SOURCE = $(wildcard *$(SUFFIX)) +CUR_TARGETS = $(patsubst %$(SUFFIX), %, $(CUR_SOURCE)) + +all:$(CUR_TARGETS) + +# %:%.c 是一个表示与目标相同 文件的模式变量 +$(CUR_TARGETS):%:%$(SUFFIX) + $(CC) $< $(CFLAGS) -o $@ $(LD) + +# 指定伪目标 +.PHONY:clean all + clean: + -rm -rf $(TARGETS) \ No newline at end of file diff --git a/study_clang/zmq/curve_one_key/client b/study_clang/zmq/curve_one_key/client new file mode 100755 index 0000000..d6beda8 Binary files /dev/null and b/study_clang/zmq/curve_one_key/client differ diff --git a/study_clang/zmq/curve_one_key/client.c b/study_clang/zmq/curve_one_key/client.c new file mode 100644 index 0000000..59b9590 --- /dev/null +++ b/study_clang/zmq/curve_one_key/client.c @@ -0,0 +1,62 @@ +/************************************************************************* + > File Name : client.c + > Author : TL Song + > EMail : songtianlun@frytea.com + > Created Time : Wed 02 Dec 2020 04:50:49 PM CST + ************************************************************************/ + +#include +#include +#include + +#define ZMQ_PUBLIC_KEY_1 "@M[-VQ%R2MKguD/h/0w7.fNq%GGjV!1Q:bVeu*u>" +#define ZMQ_PRIVATE_KEY_1 "S*{[[V$7f<(jAp^]M>I!n?dN]SXgB]" + +#define ZMQ_PUBLIC_KEY_2 "p=lDOa9WKUKz!I9{G)uPX4@&CrV-(>tDg:kaSGzE" +#define ZMQ_PRIVATE_KEY_2 "q0]#)iuwR*H5hz.} File Name : server.c + > Author : TL Song + > EMail : songtianlun@frytea.com + > Created Time : Wed 02 Dec 2020 04:50:40 PM CST + ************************************************************************/ + +#include +#include +#include + +#define ZMQ_PUBLIC_KEY_1 "@M[-VQ%R2MKguD/h/0w7.fNq%GGjV!1Q:bVeu*u>" +#define ZMQ_PRIVATE_KEY_1 "S*{[[V$7f<(jAp^]M>I!n?dN]SXgB]" + +#define ZMQ_PUBLIC_KEY_2 "p=lDOa9WKUKz!I9{G)uPX4@&CrV-(>tDg:kaSGzE" +#define ZMQ_PRIVATE_KEY_2 "q0]#)iuwR*H5hz.} ARCH +ARCH ?= +CC = $(ARCH)gcc +SUFFIX = .c +CFLAGS += -Wall -g -lzmq -lpthread +LD = + +CUR_SOURCE = $(wildcard *$(SUFFIX)) +CUR_TARGETS = $(patsubst %$(SUFFIX), %, $(CUR_SOURCE)) + +all:$(CUR_TARGETS) + +# %:%.c 是一个表示与目标相同 文件的模式变量 +$(CUR_TARGETS):%:%$(SUFFIX) + $(CC) $< $(CFLAGS) -o $@ $(LD) + +# 指定伪目标 +.PHONY:clean all + clean: + -rm -rf $(TARGETS) \ No newline at end of file diff --git a/study_clang/zmq/curve_sendkey/client b/study_clang/zmq/curve_sendkey/client new file mode 100755 index 0000000..8330eda Binary files /dev/null and b/study_clang/zmq/curve_sendkey/client differ diff --git a/study_clang/zmq/curve_sendkey/client.c b/study_clang/zmq/curve_sendkey/client.c new file mode 100644 index 0000000..8af3c0a --- /dev/null +++ b/study_clang/zmq/curve_sendkey/client.c @@ -0,0 +1,140 @@ +/* + * ===================================================================================== + * + * Filename: client.c + * + * Description: + * + * Version: 1.0 + * Created: 09/28/2018 07:14:50 PM + * Revision: none + * Compiler: gcc + * + * Author: YOUR NAME (), + * Organization: + * + * ===================================================================================== + */ + +#include +#include +#include + +#define fb_debug(fmt, arg...) \ + do{\ + printf("%s %d : ", __FILE__, __LINE__); \ + printf(fmt, ##arg); \ + printf("\n"); \ + }while(0) + +#define fb_assert(x, info) \ + do{\ + if(!(x)) { \ + fb_debug(info); \ + return -1;\ + } \ + }while(0) + +int without_curve(const char *ip, int port) { + fb_debug("test tZMQ without curve"); + void * ctx = zmq_ctx_new(); + fb_assert(ctx, "create zmq context faild"); + + void *sock = zmq_socket(ctx, ZMQ_DEALER); + fb_assert(sock, "create zmq socket faild"); + + char szaddr[128] = {0}; + snprintf(szaddr, sizeof(szaddr), "tcp://%s:%d", ip, port); + zmq_connect(sock, szaddr); + + char szmsg[1024] = {0}; + int count = 0; + while(1) { + snprintf(szmsg, sizeof(szmsg), "I say %d", ++count); + fb_debug("send msg : [%s]", szmsg); + zmq_send(sock, szmsg, strlen(szmsg), 0); + zmq_recv(sock, szmsg, sizeof(szmsg) - 1, 0); + fb_debug("recv msg : [%s]", szmsg); + getchar(); + } + zmq_unbind(sock, szaddr); + zmq_close(sock); + zmq_ctx_term(ctx); + zmq_ctx_destroy(ctx); + return 0; +} + +char *get_server_publickey(void *ctx, char *publickey, int len, const char *ip, int port) { + void *sock = zmq_socket(ctx, ZMQ_DEALER); + char szmsg[1024] = {0}; + snprintf(szmsg, sizeof(szmsg), "tcp://%s:%d", ip, port); + zmq_connect(sock, szmsg); + snprintf(szmsg, sizeof(szmsg), "%s", "request publickey"); + zmq_send(sock, szmsg, strlen(szmsg), 0); + bzero(szmsg, sizeof(szmsg)); + zmq_recv(sock, szmsg, sizeof(szmsg), 0); + snprintf(publickey, len, "%s", szmsg); + + return publickey; +} + +int with_curve(const char * ip, int port) { + fb_debug("test tZMQ with curve"); + void * ctx = zmq_ctx_new(); + fb_assert(ctx, "create zmq context faild"); + + void *sock = zmq_socket(ctx, ZMQ_DEALER); + fb_assert(sock, "create zmq socket faild"); + + char szaddr[128] = {0}; + snprintf(szaddr, sizeof(szaddr), "tcp://%s:%d", ip, port); + + char szmsg[1024] = {0}; + get_server_publickey(ctx, szmsg, sizeof(szmsg), ip, port + 1); + fb_debug("server publickey : [%s]", szmsg); + zmq_setsockopt(sock, ZMQ_CURVE_SERVERKEY, szmsg, strlen(szmsg)); + + char szpubkey[64] = {0}; + char szprikey[64] = {0}; + zmq_curve_keypair(szpubkey, szprikey); + zmq_setsockopt(sock, ZMQ_CURVE_PUBLICKEY, szpubkey, strlen(szpubkey)); + zmq_setsockopt(sock, ZMQ_CURVE_SECRETKEY, szprikey, strlen(szprikey)); + fb_debug("start secert comunication"); + zmq_connect(sock, szaddr); + + int count = 0; + while(1) { + bzero(szmsg, sizeof(szmsg)); + snprintf(szmsg, sizeof(szmsg), "I say %d", ++count); + fb_debug("send msg : [%s]", szmsg); + zmq_send(sock, szmsg, strlen(szmsg), 0); + zmq_recv(sock, szmsg, sizeof(szmsg) - 1, 0); + fb_debug("recv msg : [%s]", szmsg); + getchar(); + } + zmq_close(sock); + zmq_ctx_term(ctx); + zmq_ctx_destroy(ctx); + return 0; +} + +int main(int argc, char * argv[]) { + const char *ip = "127.0.0.1"; + int port = 5678; + + int is_withvurve = 0; + int i = 0; + for(i = 0; i < argc; i++) { + if(strcmp("-s", argv[i]) == 0) { + is_withvurve = 1; + } + } + if(is_withvurve) { + with_curve(ip, port); + } else { + without_curve(ip, port); + } + + return 0; +} + diff --git a/study_clang/zmq/curve_sendkey/server b/study_clang/zmq/curve_sendkey/server new file mode 100755 index 0000000..39e72d2 Binary files /dev/null and b/study_clang/zmq/curve_sendkey/server differ diff --git a/study_clang/zmq/curve_sendkey/server.c b/study_clang/zmq/curve_sendkey/server.c new file mode 100644 index 0000000..eaefeec --- /dev/null +++ b/study_clang/zmq/curve_sendkey/server.c @@ -0,0 +1,181 @@ +/* + * ===================================================================================== + * + * Filename: server.c + * + * Description: + * + * Version: 1.0 + * Created: 09/28/2018 07:14:44 PM + * Revision: none + * Compiler: gcc + * + * Author: YOUR NAME (), + * Organization: + * + * ===================================================================================== + */ + +#include +#include +#include +#include + +#define fb_debug(fmt, arg...) \ + do{\ + printf("%s %d : ", __FILE__, __LINE__); \ + printf(fmt, ##arg); \ + printf("\n"); \ + }while(0) + +#define fb_assert(x, info) \ + do{\ + if(!(x)) { \ + fb_debug(info); \ + return -1;\ + } \ + }while(0) + +struct ser_opt { + void *zmq_ctx; + const char *publickey; + const char *ip; + int port; +}; + +void *publickey_server(void *arg) { + pthread_detach(pthread_self()); + if(!arg) { + fb_debug("no arg when thread start"); + return NULL; + } + struct ser_opt *server = (struct ser_opt*)arg; + void *sock = zmq_socket(server -> zmq_ctx, ZMQ_DEALER); + char szaddr[64] = {0}; + snprintf(szaddr, sizeof(szaddr), "tcp://%s:%d", server -> ip, server -> port); + zmq_bind(sock, szaddr); + char szmsg[1024] = {0}; + while(1) { + bzero(szmsg, sizeof(szmsg)); + zmq_recv(sock, szmsg, sizeof(szmsg) - 1, 0); + if (strcmp("request publickey", szmsg) == 0) { + snprintf(szmsg, sizeof(szmsg), "%s", server -> publickey); + } else { + snprintf(szmsg, sizeof(szmsg), "%s", "no such service"); + } + zmq_send(sock, szmsg, strlen(szmsg), 0); + } + + return NULL; +} + +int start_publickey_server(struct ser_opt *server) { + pthread_t pt; + pthread_create(&pt, NULL, publickey_server, server); + + return 0; +} + +int with_curve(const char *ip, int port) { + fb_debug("test tZMQ with curve"); + void * ctx = zmq_ctx_new(); + fb_assert(ctx, "create zmq context failed"); + + void *sock = zmq_socket(ctx, ZMQ_DEALER); + fb_assert(sock, "create zmq socket failed"); + + char szsecertkey[128] = {0}; + char szpublickey[128] = {0}; + zmq_curve_keypair(szpublickey, szsecertkey); + fb_debug("szsecertkey = [%s]", szsecertkey); + fb_debug("szpublickey = [%s]", szpublickey); + struct ser_opt server; + server.publickey = szpublickey; + server.ip = ip; + server.port = port + 1; + server.zmq_ctx = ctx; + start_publickey_server(&server); + + int option = 1; + zmq_setsockopt(sock, ZMQ_CURVE_SERVER, &option, sizeof(option)); + zmq_setsockopt(sock, ZMQ_CURVE_SECRETKEY, szsecertkey, strlen(szsecertkey)); + fb_debug("start secert comunication"); + + char szaddr[128] = {0}; + snprintf(szaddr, sizeof(szaddr), "tcp://%s:%d", ip, port); + zmq_bind(sock, szaddr); + + char szmsg[1024] = {0}; + while(1) { + bzero(szmsg, sizeof(szmsg)); + zmq_recv(sock, szmsg, sizeof(szmsg) - 1, 0); + fb_debug("recv msg : [%s]", szmsg); + if(strcasecmp("bye", szmsg) == 0) { + fb_debug("send msg : [%s]", szmsg); + zmq_send(sock, szmsg, strlen(szmsg), 0); + break; + } + strcat(szmsg, ", too"); + fb_debug("send msg : [%s]", szmsg); + zmq_send(sock, szmsg, strlen(szmsg), 0); + } + zmq_unbind(sock, szaddr); + zmq_close(sock); + zmq_ctx_term(ctx); + zmq_ctx_destroy(ctx); + + return 0; +} + +int without_curve(const char *ip, int port) { + fb_debug("test tZMQ without curve"); + void * ctx = zmq_ctx_new(); + fb_assert(ctx, "create zmq context failed"); + + void *sock = zmq_socket(ctx, ZMQ_DEALER); + fb_assert(sock, "create zmq socket failed"); + + char szaddr[128] = {0}; + snprintf(szaddr, sizeof(szaddr), "tcp://%s:%d", ip, port); + zmq_bind(sock, szaddr); + + char szmsg[1024] = {0}; + while(1) { + bzero(szmsg, sizeof(szmsg)); + zmq_recv(sock, szmsg, sizeof(szmsg) - 1, 0); + fb_debug("recv psg : [%s]", szmsg); + if(strcasecmp("bye", szmsg) == 0) { + fb_debug("send msg : [%s]", szmsg); + zmq_send(sock, szmsg, strlen(szmsg), 0); + break; + } + strcat(szmsg, ", too"); + fb_debug("send msg : [%s]", szmsg); + zmq_send(sock, szmsg, strlen(szmsg), 0); + } + zmq_unbind(sock, szaddr); + zmq_close(sock); + zmq_ctx_term(ctx); + zmq_ctx_destroy(ctx); + + return 0; +} + +int main(int argc, char * argv[]) { + const char *ip = "127.0.0.1"; + int port = 5678; + int is_withcurve = 0; + int i = 0; + for(i = 0; i < argc; i++) { + if(strcmp("-s", argv[i]) == 0) { + is_withcurve = 1; + } + } + if(is_withcurve) { + with_curve(ip, port); + } else { + without_curve(ip, port); + } + + return 0; +} diff --git a/study_clang/zmq/docker_zmq_centos_client/Dockerfile b/study_clang/zmq/docker_zmq_centos_client/Dockerfile new file mode 100644 index 0000000..5505426 --- /dev/null +++ b/study_clang/zmq/docker_zmq_centos_client/Dockerfile @@ -0,0 +1,20 @@ +FROM centos:7 as centos_zmq_centos_client +MAINTAINER tlsong + +COPY hw_client.cpp /home/ +COPY hw_client /home/hw_client_host + +WORKDIR /home +RUN yum install wget -y \ + && yum install libtool -y \ + && yum install gcc-c++ -y \ + && yum install make -y \ + && wget http://res.frytea.com/Library/zeromq-4.1.4.tar.gz \ + && tar zvxf zeromq-4.1.4.tar.gz \ + && cd zeromq-4.1.4 \ + && ./autogen.sh \ + && ./configure --without-libsodium \ + && make \ + && make install \ + && echo "/usr/local/lib">>/etc/ld.so.conf \ + && ldconfig \ No newline at end of file diff --git a/study_clang/zmq/docker_zmq_centos_client/hw_client b/study_clang/zmq/docker_zmq_centos_client/hw_client new file mode 100755 index 0000000..268d92f Binary files /dev/null and b/study_clang/zmq/docker_zmq_centos_client/hw_client differ diff --git a/study_clang/zmq/docker_zmq_centos_client/hw_client.cpp b/study_clang/zmq/docker_zmq_centos_client/hw_client.cpp new file mode 100644 index 0000000..086a65d --- /dev/null +++ b/study_clang/zmq/docker_zmq_centos_client/hw_client.cpp @@ -0,0 +1,43 @@ +// Hello World client +#include +#include +#include +#include +#include + +using std::string; + +struct send_msg // 接收指针头 +{ + int msgId; + string msgData; +}; + +int main (void) +{ + printf ("Connecting to hello world server…\n"); + void *context = zmq_ctx_new (); + void *requester = zmq_socket (context, ZMQ_REQ); + zmq_connect (requester, "tcp://localhost:5555"); + + int request_nbr; + for (request_nbr = 0; request_nbr != 10; request_nbr++) { + char buffer [10]; + //printf ("Sending Hello %d…\n", request_nbr); + //zmq_send (requester, "HHHHH", 16, 0); + //zmq_recv (requester, buffer, 10, 0); + //printf ("Received World %d\n", request_nbr); + + send_msg msg; + msg.msgId = 1; + msg.msgData = "First Message"; + printf ("Sending size: %d, %d…\n", sizeof(msg),request_nbr); + zmq_send (requester, &msg, sizeof(msg), 0); + zmq_recv (requester, buffer, 10, 0); + printf ("Received %s, %d\n", buffer, request_nbr); + + } + zmq_close (requester); + zmq_ctx_destroy (context); + return 0; +} diff --git a/study_clang/zmq/docker_zmq_client/Dockerfile b/study_clang/zmq/docker_zmq_client/Dockerfile new file mode 100644 index 0000000..771e3f9 --- /dev/null +++ b/study_clang/zmq/docker_zmq_client/Dockerfile @@ -0,0 +1,15 @@ +FROM alpine:latest as centos_zmq_server +MAINTAINER tlsong + +RUN echo "https://mirror.tuna.tsinghua.edu.cn/alpine/v3.8/main" > /etc/apk/repositories +RUN echo "https://mirror.tuna.tsinghua.edu.cn/alpine/v3.8/community" >> /etc/apk/repositories +RUN apk add zeromq-dev +RUN apk add g++ + +COPY hw_client.cpp /home/ +COPY hw_client /home/hw_client_host + +WORKDIR /home +RUN g++ hw_client.cpp -o hw_client -lzmq + +CMD ["./hw_client"] diff --git a/study_clang/zmq/docker_zmq_client/hw_client b/study_clang/zmq/docker_zmq_client/hw_client new file mode 100755 index 0000000..26aaf88 Binary files /dev/null and b/study_clang/zmq/docker_zmq_client/hw_client differ diff --git a/study_clang/zmq/docker_zmq_client/hw_client.cpp b/study_clang/zmq/docker_zmq_client/hw_client.cpp new file mode 100644 index 0000000..c0ccf45 --- /dev/null +++ b/study_clang/zmq/docker_zmq_client/hw_client.cpp @@ -0,0 +1,25 @@ +// Hello World client +#include +#include +#include +#include + +int main (void) +{ + printf ("Connecting to hello world server…\n"); + void *context = zmq_ctx_new (); + void *requester = zmq_socket (context, ZMQ_REQ); + zmq_connect (requester, "tcp://192.168.6.234:5555"); + + int request_nbr; + for (request_nbr = 0; request_nbr != 10; request_nbr++) { + char buffer [10]; + printf ("Sending Hello %d…\n", request_nbr); + zmq_send (requester, "HHHHH", 16, 0); + zmq_recv (requester, buffer, 10, 0); + printf ("Received World %d\n", request_nbr); + } + zmq_close (requester); + zmq_ctx_destroy (context); + return 0; +} diff --git a/study_clang/zmq/docker_zmq_server/Dockerfile b/study_clang/zmq/docker_zmq_server/Dockerfile new file mode 100644 index 0000000..78f4517 --- /dev/null +++ b/study_clang/zmq/docker_zmq_server/Dockerfile @@ -0,0 +1,15 @@ +FROM alpine:latest as centos_zmq_server +MAINTAINER tlsong + +RUN echo "https://mirror.tuna.tsinghua.edu.cn/alpine/v3.8/main" > /etc/apk/repositories +RUN echo "https://mirror.tuna.tsinghua.edu.cn/alpine/v3.8/community" >> /etc/apk/repositories +RUN apk add zeromq-dev +RUN apk add g++ + +COPY hw_server.cpp /home/ + +WORKDIR /home + +RUN g++ hw_server.cpp -o hw_server -lzmq + +CMD ["./hw_server"] diff --git a/study_clang/zmq/docker_zmq_server/hw_server b/study_clang/zmq/docker_zmq_server/hw_server new file mode 100755 index 0000000..c5f06f8 Binary files /dev/null and b/study_clang/zmq/docker_zmq_server/hw_server differ diff --git a/study_clang/zmq/docker_zmq_server/hw_server.cpp b/study_clang/zmq/docker_zmq_server/hw_server.cpp new file mode 100644 index 0000000..4533639 --- /dev/null +++ b/study_clang/zmq/docker_zmq_server/hw_server.cpp @@ -0,0 +1,24 @@ +// Hello World server +#include +#include +#include +#include +#include + +int main (void) +{ + // Socket to talk to clients + void *context = zmq_ctx_new (); + void *responder = zmq_socket (context, ZMQ_REP); + int rc = zmq_bind (responder, "tcp://*:5555"); + assert (rc == 0); + + while (1) { + char buffer [10]; + zmq_recv (responder, buffer, 10, 0); + printf ("Received Hello\n"); + sleep (1); // Do some 'work' + zmq_send (responder, "World", 5, 0); + } + return 0; +} \ No newline at end of file diff --git a/study_clang/zmq/docker_zmq_ubuntu_client/Dockerfile b/study_clang/zmq/docker_zmq_ubuntu_client/Dockerfile new file mode 100644 index 0000000..5bc1a5e --- /dev/null +++ b/study_clang/zmq/docker_zmq_ubuntu_client/Dockerfile @@ -0,0 +1,7 @@ +FROM ubuntu:18.04 as docker_zmq_ubuntu_client +MAINTAINER tlsong + +COPY hw_client.cpp /home/ +COPY hw_client /home/hw_client_host + + diff --git a/study_clang/zmq/docker_zmq_ubuntu_client/hw_client b/study_clang/zmq/docker_zmq_ubuntu_client/hw_client new file mode 100755 index 0000000..26aaf88 Binary files /dev/null and b/study_clang/zmq/docker_zmq_ubuntu_client/hw_client differ diff --git a/study_clang/zmq/docker_zmq_ubuntu_client/hw_client.cpp b/study_clang/zmq/docker_zmq_ubuntu_client/hw_client.cpp new file mode 100644 index 0000000..c0ccf45 --- /dev/null +++ b/study_clang/zmq/docker_zmq_ubuntu_client/hw_client.cpp @@ -0,0 +1,25 @@ +// Hello World client +#include +#include +#include +#include + +int main (void) +{ + printf ("Connecting to hello world server…\n"); + void *context = zmq_ctx_new (); + void *requester = zmq_socket (context, ZMQ_REQ); + zmq_connect (requester, "tcp://192.168.6.234:5555"); + + int request_nbr; + for (request_nbr = 0; request_nbr != 10; request_nbr++) { + char buffer [10]; + printf ("Sending Hello %d…\n", request_nbr); + zmq_send (requester, "HHHHH", 16, 0); + zmq_recv (requester, buffer, 10, 0); + printf ("Received World %d\n", request_nbr); + } + zmq_close (requester); + zmq_ctx_destroy (context); + return 0; +} diff --git a/study_clang/zmq/docker_zmq_ubuntu_client_test/Dockerfile b/study_clang/zmq/docker_zmq_ubuntu_client_test/Dockerfile new file mode 100644 index 0000000..5bc1a5e --- /dev/null +++ b/study_clang/zmq/docker_zmq_ubuntu_client_test/Dockerfile @@ -0,0 +1,7 @@ +FROM ubuntu:18.04 as docker_zmq_ubuntu_client +MAINTAINER tlsong + +COPY hw_client.cpp /home/ +COPY hw_client /home/hw_client_host + + diff --git a/study_clang/zmq/docker_zmq_ubuntu_client_test/hw_client b/study_clang/zmq/docker_zmq_ubuntu_client_test/hw_client new file mode 100755 index 0000000..26aaf88 Binary files /dev/null and b/study_clang/zmq/docker_zmq_ubuntu_client_test/hw_client differ diff --git a/study_clang/zmq/docker_zmq_ubuntu_client_test/hw_client.cpp b/study_clang/zmq/docker_zmq_ubuntu_client_test/hw_client.cpp new file mode 100644 index 0000000..c0ccf45 --- /dev/null +++ b/study_clang/zmq/docker_zmq_ubuntu_client_test/hw_client.cpp @@ -0,0 +1,25 @@ +// Hello World client +#include +#include +#include +#include + +int main (void) +{ + printf ("Connecting to hello world server…\n"); + void *context = zmq_ctx_new (); + void *requester = zmq_socket (context, ZMQ_REQ); + zmq_connect (requester, "tcp://192.168.6.234:5555"); + + int request_nbr; + for (request_nbr = 0; request_nbr != 10; request_nbr++) { + char buffer [10]; + printf ("Sending Hello %d…\n", request_nbr); + zmq_send (requester, "HHHHH", 16, 0); + zmq_recv (requester, buffer, 10, 0); + printf ("Received World %d\n", request_nbr); + } + zmq_close (requester); + zmq_ctx_destroy (context); + return 0; +} diff --git a/study_clang/zmq/docker_zmq_ubuntu_server/Dockerfile b/study_clang/zmq/docker_zmq_ubuntu_server/Dockerfile new file mode 100644 index 0000000..49c270a --- /dev/null +++ b/study_clang/zmq/docker_zmq_ubuntu_server/Dockerfile @@ -0,0 +1,11 @@ +FROM ubuntu:18.04 as docker_zmq_ubuntu_server +MAINTAINER tlsong + +COPY hw_server.cpp /home/ +COPY hw_server /home/hw_server_host + +WORKDIR /home +RUN apt-get update \ + && apt-get install libtool -y \ + && apt-get install libzmq3-dev -y +CMD ["./hw_server_host"] \ No newline at end of file diff --git a/study_clang/zmq/docker_zmq_ubuntu_server/hw_server b/study_clang/zmq/docker_zmq_ubuntu_server/hw_server new file mode 100755 index 0000000..f1fe896 Binary files /dev/null and b/study_clang/zmq/docker_zmq_ubuntu_server/hw_server differ diff --git a/study_clang/zmq/docker_zmq_ubuntu_server/hw_server.cpp b/study_clang/zmq/docker_zmq_ubuntu_server/hw_server.cpp new file mode 100644 index 0000000..5490af3 --- /dev/null +++ b/study_clang/zmq/docker_zmq_ubuntu_server/hw_server.cpp @@ -0,0 +1,44 @@ +// Hello World server +#include +#include +#include +#include +#include +#include + +#include + +using std::string; +using std::cout; +using std::endl; + +struct send_msg +{ + int msgId; + string msgData; +}; + +int main (void) +{ + // Socket to talk to clients + void *context = zmq_ctx_new (); + void *responder = zmq_socket (context, ZMQ_REP); + int rc = zmq_bind (responder, "tcp://*:5555"); + assert (rc == 0); + + while (1) { + send_msg msg; + memset(&msg, 0, sizeof(send_msg)); + char buffer [10]; + cout << "Recv Message..." << endl; + zmq_recv (responder, &msg, sizeof(send_msg), 0); + cout << "Received msgid: " << msg.msgId << ", msdData: " << msg.msgData << endl; + + //printf ("Received msgid: %d, msdData: %s\n",msg.msgId,msg.msgData); + + + sleep (1); // Do some 'work' + zmq_send (responder, "World", 5, 0); + } + return 0; +} \ No newline at end of file diff --git a/study_clang/zmq/hello_world_client b/study_clang/zmq/hello_world_client new file mode 100755 index 0000000..4e1e5ae Binary files /dev/null and b/study_clang/zmq/hello_world_client differ diff --git a/study_clang/zmq/hello_world_client.cpp b/study_clang/zmq/hello_world_client.cpp new file mode 100644 index 0000000..0fbc1dc --- /dev/null +++ b/study_clang/zmq/hello_world_client.cpp @@ -0,0 +1,25 @@ +// Hello World client +#include +#include +#include +#include + +int main (void) +{ + printf ("Connecting to hello world server…\n"); + void *context = zmq_ctx_new (); + void *requester = zmq_socket (context, ZMQ_REQ); + zmq_connect (requester, "tcp://127.0.0.1:5555"); + + int request_nbr; + for (request_nbr = 0; request_nbr != 1; request_nbr++) { + char buffer [10]; + printf ("Sending Hello %d…\n", request_nbr); + zmq_send (requester, "Hello", 5, 0); + zmq_recv (requester, buffer, 10, 0); + printf ("Received World %d\n", request_nbr); + } + zmq_close (requester); + zmq_ctx_destroy (context); + return 0; +} diff --git a/study_clang/zmq/hello_world_server b/study_clang/zmq/hello_world_server new file mode 100755 index 0000000..4a632c4 Binary files /dev/null and b/study_clang/zmq/hello_world_server differ diff --git a/study_clang/zmq/hello_world_server.c b/study_clang/zmq/hello_world_server.c new file mode 100644 index 0000000..4533639 --- /dev/null +++ b/study_clang/zmq/hello_world_server.c @@ -0,0 +1,24 @@ +// Hello World server +#include +#include +#include +#include +#include + +int main (void) +{ + // Socket to talk to clients + void *context = zmq_ctx_new (); + void *responder = zmq_socket (context, ZMQ_REP); + int rc = zmq_bind (responder, "tcp://*:5555"); + assert (rc == 0); + + while (1) { + char buffer [10]; + zmq_recv (responder, buffer, 10, 0); + printf ("Received Hello\n"); + sleep (1); // Do some 'work' + zmq_send (responder, "World", 5, 0); + } + return 0; +} \ No newline at end of file diff --git a/study_clang/zmq/hello_world_server.cpp b/study_clang/zmq/hello_world_server.cpp new file mode 100644 index 0000000..4533639 --- /dev/null +++ b/study_clang/zmq/hello_world_server.cpp @@ -0,0 +1,24 @@ +// Hello World server +#include +#include +#include +#include +#include + +int main (void) +{ + // Socket to talk to clients + void *context = zmq_ctx_new (); + void *responder = zmq_socket (context, ZMQ_REP); + int rc = zmq_bind (responder, "tcp://*:5555"); + assert (rc == 0); + + while (1) { + char buffer [10]; + zmq_recv (responder, buffer, 10, 0); + printf ("Received Hello\n"); + sleep (1); // Do some 'work' + zmq_send (responder, "World", 5, 0); + } + return 0; +} \ No newline at end of file diff --git a/study_clang/zmq/hwclient.c b/study_clang/zmq/hwclient.c new file mode 100755 index 0000000..401a3df --- /dev/null +++ b/study_clang/zmq/hwclient.c @@ -0,0 +1,38 @@ +// +// Hello World 客户端 +// 连接REQ套接字至 tcp://localhost:5555 +// 发送Hello给服务端,并接收World +// +#include +#include +#include +#include + +int main (void) +{ + void *context = zmq_init (1); + + // 连接至服务端的套接字 + printf ("正在连接至hello world服务端...\n"); + void *requester = zmq_socket (context, ZMQ_REQ); + zmq_connect (requester, "tcp://localhost:5555"); + + int request_nbr; + for (request_nbr = 0; request_nbr != 10; request_nbr++) { + zmq_msg_t request; + zmq_msg_init_size (&request, 5); + memcpy (zmq_msg_data (&request), "Hello", 5); + printf ("正在发送 Hello %d...\n", request_nbr); + zmq_send (requester, &request, 0); + zmq_msg_close (&request); + + zmq_msg_t reply; + zmq_msg_init (&reply); + zmq_recv (requester, &reply, 0); + printf ("接收到 World %d\n", request_nbr); + zmq_msg_close (&reply); + } + zmq_close (requester); + zmq_term (context); + return 0; +} \ No newline at end of file diff --git a/study_clang/zmq/hwserver.c b/study_clang/zmq/hwserver.c new file mode 100755 index 0000000..b4eee39 --- /dev/null +++ b/study_clang/zmq/hwserver.c @@ -0,0 +1,41 @@ +// +// Hello World 服务端 +// 绑定一个REP套接字至tcp://*:5555 +// 从客户端接收Hello,并应答World +// +#include +#include +#include +#include + +int main (void) +{ + void *context = zmq_init (1); + + // 与客户端通信的套接字 + void *responder = zmq_socket (context, ZMQ_REP); + zmq_bind (responder, "tcp://*:5555"); + + while (1) { + // 等待客户端请求 + zmq_msg_t request; + zmq_msg_init (&request); + zmq_recv (responder, &request, 0); + printf ("收到 Hello\n"); + zmq_msg_close (&request); + + // 做些“处理” + sleep (1); + + // 返回应答 + zmq_msg_t reply; + zmq_msg_init_size (&reply, 5); + memcpy (zmq_msg_data (&reply), "World", 5); + zmq_send (responder, &reply, 0); + zmq_msg_close (&reply); + } + // 程序不会运行到这里,以下只是演示我们应该如何结束 + zmq_close (responder); + zmq_term (context); + return 0; +} \ No newline at end of file diff --git a/study_clang/zmq/libzmq_client b/study_clang/zmq/libzmq_client new file mode 100755 index 0000000..5439a28 Binary files /dev/null and b/study_clang/zmq/libzmq_client differ diff --git a/study_clang/zmq/libzmq_client.c b/study_clang/zmq/libzmq_client.c new file mode 100644 index 0000000..35614fc --- /dev/null +++ b/study_clang/zmq/libzmq_client.c @@ -0,0 +1,24 @@ +#include +#include +#include +#include + +int main (void) +{ + printf ("Connecting to hello world server…\n"); + void *context = zmq_ctx_new (); + void *requester = zmq_socket (context, ZMQ_REQ); + zmq_connect (requester, "tcp://localhost:5555"); + + int request_nbr; + for (request_nbr = 0; request_nbr != 10; request_nbr++) { + char buffer [10]; + printf ("Sending Hello %d…\n", request_nbr); + zmq_send (requester, "Hello", 5, 0); + zmq_recv (requester, buffer, 10, 0); + printf ("Received World %d\n", request_nbr); + } + zmq_close (requester); + zmq_ctx_destroy (context); + return 0; +} diff --git a/study_clang/zmq/libzmq_server b/study_clang/zmq/libzmq_server new file mode 100755 index 0000000..bc11ebe Binary files /dev/null and b/study_clang/zmq/libzmq_server differ diff --git a/study_clang/zmq/libzmq_server.c b/study_clang/zmq/libzmq_server.c new file mode 100644 index 0000000..173c745 --- /dev/null +++ b/study_clang/zmq/libzmq_server.c @@ -0,0 +1,23 @@ +#include +#include +#include +#include +#include + +int main (void) +{ + // Socket to talk to clients + void *context = zmq_ctx_new (); + void *responder = zmq_socket (context, ZMQ_REP); + int rc = zmq_bind (responder, "tcp://*:5555"); + assert (rc == 0); + + while (1) { + char buffer [10]; + zmq_recv (responder, buffer, 10, 0); + printf ("Received Hello\n"); + sleep (1); // Do some 'work' + zmq_send (responder, "World", 5, 0); + } + return 0; +} diff --git a/study_clang/zmq/mult-thread-reqrep/Makefile b/study_clang/zmq/mult-thread-reqrep/Makefile new file mode 100644 index 0000000..8d74b33 --- /dev/null +++ b/study_clang/zmq/mult-thread-reqrep/Makefile @@ -0,0 +1,22 @@ +# Batch Single C file MakeFile + +# 指定CPU架构 Architecture -> ARCH +ARCH ?= +CC = $(ARCH)gcc +SUFFIX = .c +CFLAGS += -Wall -g -lzmq +LD = + +CUR_SOURCE = $(wildcard *$(SUFFIX)) +CUR_TARGETS = $(patsubst %$(SUFFIX), %, $(CUR_SOURCE)) + +all:$(CUR_TARGETS) + +# %:%.c 是一个表示与目标相同 文件的模式变量 +$(CUR_TARGETS):%:%$(SUFFIX) + $(CC) $< $(CFLAGS) -o $@ $(LD) + +# 指定伪目标 +.PHONY:clean all + clean: + -rm -rf $(TARGETS) diff --git a/study_clang/zmq/mult-thread-reqrep/client b/study_clang/zmq/mult-thread-reqrep/client new file mode 100755 index 0000000..0dbc66e Binary files /dev/null and b/study_clang/zmq/mult-thread-reqrep/client differ diff --git a/study_clang/zmq/mult-thread-reqrep/client.c b/study_clang/zmq/mult-thread-reqrep/client.c new file mode 100644 index 0000000..f2357fa --- /dev/null +++ b/study_clang/zmq/mult-thread-reqrep/client.c @@ -0,0 +1,106 @@ +#include +#include +#include +#include +#include + +void *context; +void *requester; + +void initSocket() +{ + context = zmq_ctx_new (); + requester = zmq_socket (context, ZMQ_REQ); + unsigned int uiTimeout = 3 * 1000; + + zmq_setsockopt(requester, ZMQ_RCVTIMEO, &uiTimeout, sizeof(uiTimeout)); + zmq_setsockopt(requester, ZMQ_SNDTIMEO, &uiTimeout, sizeof(uiTimeout)); + zmq_connect (requester, "tcp://localhost:5555"); +} + +int SendData(const void *pvData, unsigned int uiDataLen) +{ + initSocket(); + return zmq_send (requester, pvData, uiDataLen, 0); +} +int RecvData(void *pvData, unsigned int uiDataLen) +{ + int rst = zmq_recv (requester, pvData, uiDataLen, 0); + zmq_close (requester); + zmq_ctx_destroy (context); + return rst; +} + +void *client1(void *args) +{ + int rst; + printf ("Connecting to hello world server…\n"); + + int request_nbr; + for (request_nbr = 0; request_nbr != 100; request_nbr++) { + char buffer [20]; + sprintf(buffer, "Hellooooooooooooooooooooooooooooooooooo %d", request_nbr); + printf ("-----------------%d--------------\n",request_nbr); + printf ("Sending %s…, rst:", buffer); + rst = SendData(buffer, 20); + if(rst < 0) + { + printf("Send error: %s\n", zmq_strerror(zmq_errno())); + sleep(1); + continue; + } + else + printf ("...ok\n"); + rst = RecvData(buffer, 20); + if(rst < 0) + { + printf("recv error: %s\n", zmq_strerror(zmq_errno())); + } + else + printf ("Received World %d\n", request_nbr); + sleep(1); + } + zmq_close (requester); + zmq_ctx_destroy (context); +} + + + +int main (void) +{ + int rst; + printf ("Connecting to hello world server…\n"); + + int request_nbr; + for (request_nbr = 0; request_nbr != 100; request_nbr++) { + char buffer [1024]; + sprintf(buffer, "Hello00000000000000000000 %d", request_nbr); + printf ("-----------------%d--------------\n",request_nbr); + printf ("Sending %s…, rst:", buffer); + // rst = zmq_send (requester, buffer, sizeof(buffer), 0); + rst = SendData(buffer, sizeof(buffer)); + if(rst < 0) + { + printf("Send error: %s\n", zmq_strerror(zmq_errno())); + sleep(1); + continue; + } + else + printf ("...ok\n"); + // rst = zmq_recv (requester, buffer, 10, 0); + rst = RecvData(buffer, sizeof(buffer)); + if(rst < 0) + { + printf("recv error: %s\n", zmq_strerror(zmq_errno())); + // sleep(1); + // continue; + } + else + printf ("Received World %d\n", request_nbr); + + // sleep(1); + } + zmq_close (requester); + zmq_ctx_destroy (context); + return 0; +} diff --git a/study_clang/zmq/mult-thread-reqrep/server b/study_clang/zmq/mult-thread-reqrep/server new file mode 100755 index 0000000..b06ec46 Binary files /dev/null and b/study_clang/zmq/mult-thread-reqrep/server differ diff --git a/study_clang/zmq/mult-thread-reqrep/server.c b/study_clang/zmq/mult-thread-reqrep/server.c new file mode 100644 index 0000000..2c36fe3 --- /dev/null +++ b/study_clang/zmq/mult-thread-reqrep/server.c @@ -0,0 +1,50 @@ +#include +#include +#include +#include +#include + +void *context; +void *responder; + +int SendData(const void *pvData, unsigned int uiDataLen) +{ + return zmq_send (responder, pvData, uiDataLen, 0); +} +int RecvData(void *pvData, unsigned int uiDataLen) +{ + return zmq_recv (responder, pvData, uiDataLen, 0); +} + +int main (void) +{ + // Socket to talk to clients + context = zmq_ctx_new (); + responder = zmq_socket (context, ZMQ_REP); + unsigned int uiTimeout = 5 * 1000; + int rst = 0; + + zmq_setsockopt(responder, ZMQ_RCVTIMEO, &uiTimeout, sizeof(uiTimeout)); + zmq_setsockopt(responder, ZMQ_SNDTIMEO, &uiTimeout, sizeof(uiTimeout)); + int rc = zmq_bind (responder, "tcp://*:5555"); + assert (rc == 0); + + while (1) { + char buffer [10]; + // zmq_recv (responder, buffer, sizeof buffer, 0); + printf("start\n"); + rst = RecvData(buffer, sizeof buffer); + printf("end\n"); + if(rst <= 0 ) + { + printf("recv error: %d\n", rst); + continue; + } + printf ("Received %s\n", buffer); + sleep (3); // Do some 'work' + // zmq_send (responder, buffer, sizeof buffer, 0); + SendData(buffer, sizeof buffer); + // sleep(4); + } + return 0; +} diff --git a/study_clang/zmq/reqrep/Makefile b/study_clang/zmq/reqrep/Makefile new file mode 100644 index 0000000..8d74b33 --- /dev/null +++ b/study_clang/zmq/reqrep/Makefile @@ -0,0 +1,22 @@ +# Batch Single C file MakeFile + +# 指定CPU架构 Architecture -> ARCH +ARCH ?= +CC = $(ARCH)gcc +SUFFIX = .c +CFLAGS += -Wall -g -lzmq +LD = + +CUR_SOURCE = $(wildcard *$(SUFFIX)) +CUR_TARGETS = $(patsubst %$(SUFFIX), %, $(CUR_SOURCE)) + +all:$(CUR_TARGETS) + +# %:%.c 是一个表示与目标相同 文件的模式变量 +$(CUR_TARGETS):%:%$(SUFFIX) + $(CC) $< $(CFLAGS) -o $@ $(LD) + +# 指定伪目标 +.PHONY:clean all + clean: + -rm -rf $(TARGETS) diff --git a/study_clang/zmq/reqrep/client b/study_clang/zmq/reqrep/client new file mode 100755 index 0000000..03a1499 Binary files /dev/null and b/study_clang/zmq/reqrep/client differ diff --git a/study_clang/zmq/reqrep/client.c b/study_clang/zmq/reqrep/client.c new file mode 100644 index 0000000..f1d1b59 --- /dev/null +++ b/study_clang/zmq/reqrep/client.c @@ -0,0 +1,48 @@ +#include +#include +#include +#include + +int main (void) +{ + int rst; + printf ("Connecting to hello world server…\n"); + void *context = zmq_ctx_new (); + void *requester = zmq_socket (context, ZMQ_REQ); + unsigned int uiTimeout = 3 * 1000; + + zmq_setsockopt(requester, ZMQ_RCVTIMEO, &uiTimeout, sizeof(uiTimeout)); + zmq_setsockopt(requester, ZMQ_SNDTIMEO, &uiTimeout, sizeof(uiTimeout)); + zmq_connect (requester, "tcp://localhost:5555"); + + int request_nbr; + for (request_nbr = 0; request_nbr != 100; request_nbr++) { + char buffer [10]; + sprintf(buffer, "Hello %d", request_nbr); + printf ("-----------------%d--------------\n",request_nbr); + printf ("Sending %s…, rst:", buffer); + rst = zmq_send (requester, buffer, sizeof(buffer), 0); + if(rst < 0) + { + printf("Send error: %s\n", zmq_strerror(zmq_errno())); + // sleep(1); + // continue; + } + else + printf ("...ok\n"); + rst = zmq_recv (requester, buffer, 10, 0); + if(rst < 0) + { + printf("recv error: %s\n", zmq_strerror(zmq_errno())); + // sleep(1); + // continue; + } + else + printf ("Received World %d\n", request_nbr); + + // sleep(1); + } + zmq_close (requester); + zmq_ctx_destroy (context); + return 0; +} diff --git a/study_clang/zmq/reqrep/server b/study_clang/zmq/reqrep/server new file mode 100755 index 0000000..7178734 Binary files /dev/null and b/study_clang/zmq/reqrep/server differ diff --git a/study_clang/zmq/reqrep/server.c b/study_clang/zmq/reqrep/server.c new file mode 100644 index 0000000..780ba5d --- /dev/null +++ b/study_clang/zmq/reqrep/server.c @@ -0,0 +1,33 @@ +#include +#include +#include +#include +#include + +int main (void) +{ + // Socket to talk to clients + void *context = zmq_ctx_new (); + void *responder = zmq_socket (context, ZMQ_REP); + unsigned int uiTimeout = 5 * 1000; + + // zmq_setsockopt(responder, ZMQ_RCVTIMEO, &uiTimeout, sizeof(uiTimeout)); + zmq_setsockopt(responder, ZMQ_SNDTIMEO, &uiTimeout, sizeof(uiTimeout)); + int rc = zmq_bind (responder, "tcp://*:5555"); + assert (rc == 0); + + while (1) { + char buffer [10]; + int recv_num = zmq_recv (responder, buffer, sizeof buffer, 0); + if(recv_num < 0) + { + printf("1111111111111111111\n"); + continue; + } + printf ("Received %s\n", buffer); + sleep (4); // Do some 'work' + zmq_send (responder, "World", 5, 0); + // sleep(4); + } + return 0; +} diff --git a/study_clang/zmq/v4.2.3.tar.gz b/study_clang/zmq/v4.2.3.tar.gz new file mode 100644 index 0000000..44e4b24 Binary files /dev/null and b/study_clang/zmq/v4.2.3.tar.gz differ diff --git a/study_clang/zmq/wuclient b/study_clang/zmq/wuclient new file mode 100755 index 0000000..4ceaad8 Binary files /dev/null and b/study_clang/zmq/wuclient differ diff --git a/study_clang/zmq/wuclient.c b/study_clang/zmq/wuclient.c new file mode 100755 index 0000000..b18a6ee --- /dev/null +++ b/study_clang/zmq/wuclient.c @@ -0,0 +1,38 @@ +// +// 气象信息客户端 +// 连接SUB套接字至tcp://*:5556端点 +// 收集指定邮编的气象信息,并计算平均温度 +// +#include "zhelpers.h" + +int main (int argc, char *argv []) +{ + void *context = zmq_init (1); + + // 创建连接至服务端的套接字 + printf ("正在收集气象信息...\n"); + void *subscriber = zmq_socket (context, ZMQ_SUB); + zmq_connect (subscriber, "tcp://localhost:5556"); + + // 设置订阅信息,默认为纽约,邮编10001 + char *filter = (argc > 1)? argv [1]: "10001 "; + zmq_setsockopt (subscriber, ZMQ_SUBSCRIBE, filter, strlen (filter)); + + // 处理100条更新信息 + int update_nbr; + long total_temp = 0; + for (update_nbr = 0; update_nbr < 100; update_nbr++) { + char *string = s_recv (subscriber); + int zipcode, temperature, relhumidity; + sscanf (string, "%d %d %d", + &zipcode, &temperature, &relhumidity); + total_temp += temperature; + free (string); + } + printf ("地区邮编 '%s' 的平均温度为 %dF\n", + filter, (int) (total_temp / update_nbr)); + + zmq_close (subscriber); + zmq_term (context); + return 0; +} \ No newline at end of file diff --git a/study_clang/zmq/wuserver b/study_clang/zmq/wuserver new file mode 100755 index 0000000..540ec21 Binary files /dev/null and b/study_clang/zmq/wuserver differ diff --git a/study_clang/zmq/wuserver.c b/study_clang/zmq/wuserver.c new file mode 100755 index 0000000..f38c568 --- /dev/null +++ b/study_clang/zmq/wuserver.c @@ -0,0 +1,33 @@ +// +// 气象信息更新服务 +// 绑定PUB套接字至tcp://*:5556端点 +// 发布随机气象信息 +// +#include "zhelpers.h" + +int main (void) +{ + // 准备上下文和PUB套接字 + void *context = zmq_init (1); + void *publisher = zmq_socket (context, ZMQ_PUB); + zmq_bind (publisher, "tcp://*:5556"); + zmq_bind (publisher, "ipc://weather.ipc"); + + // 初始化随机数生成器 + srandom ((unsigned) time (NULL)); + while (1) { + // 生成数据 + int zipcode, temperature, relhumidity; + zipcode = randof (100000); + temperature = randof (215) - 80; + relhumidity = randof (50) + 10; + + // 向所有订阅者发送消息 + char update [20]; + sprintf (update, "%05d %d %d", zipcode, temperature, relhumidity); + s_send (publisher, update); + } + zmq_close (publisher); + zmq_term (context); + return 0; +} \ No newline at end of file diff --git a/study_clang/zmq/zeromq-curve.tar.gz b/study_clang/zmq/zeromq-curve.tar.gz new file mode 100644 index 0000000..ae1aa0f Binary files /dev/null and b/study_clang/zmq/zeromq-curve.tar.gz differ diff --git a/study_clang/zmq/zeromq-curve/TEST b/study_clang/zmq/zeromq-curve/TEST new file mode 100644 index 0000000..3fcac26 --- /dev/null +++ b/study_clang/zmq/zeromq-curve/TEST @@ -0,0 +1,11 @@ + 1. 移动光标到本行。 + + 2. 接着按 v 键,将光标移动至下面第五个条目上。您会注意到之间的文本被高亮了。 + + 3. 然后按 : 字符。您将看到屏幕底部会出现 :'<,'> 。 + + 4. 现在请输入 w TEST,其中 TEST 是一个未被使用的文件名。确认您看到了 + :'<,'>w TEST 之后按 <回车> 键。 + + 5. 这时 Vim 会把选中的行写入到以 TEST 命名的文件中去。使用 :!dir 或 :!ls + 确认文件被正确保存。这次先别删除它!我们在下一讲中会用到它。 diff --git a/study_clang/zmq/zeromq-curve/client b/study_clang/zmq/zeromq-curve/client new file mode 100755 index 0000000..8efed2e Binary files /dev/null and b/study_clang/zmq/zeromq-curve/client differ diff --git a/study_clang/zmq/zeromq-curve/client.c b/study_clang/zmq/zeromq-curve/client.c new file mode 100644 index 0000000..d55c194 --- /dev/null +++ b/study_clang/zmq/zeromq-curve/client.c @@ -0,0 +1,141 @@ +/* + * ===================================================================================== + * + * Filename: recv.c + * + * Description: + * + * Version: 1.0 + * Created: 09/28/2018 07:14:50 PM + * Revision: none + * Compiler: gcc + * + * Author: YOUR NAME (), + * Organization: + * + * ===================================================================================== + */ + +#include +#include +#include + +#define fb_debug(fmt, arg...) \ + do{\ + printf("%s %d : ", __FILE__, __LINE__); \ + printf(fmt, ##arg); \ + printf("\n"); \ + }while(0) + +#define fb_assert(x, info) \ + do{\ + if(!(x)) { \ + fb_debug(info); \ + return -1;\ + } \ + }while(0) + +int without_curve(const char *ip, int port) { + fb_debug("test tZMQ without curve"); + void * ctx = zmq_ctx_new(); + fb_assert(ctx, "create zmq context faild"); + + void *sock = zmq_socket(ctx, ZMQ_DEALER); + fb_assert(sock, "create zmq socket faild"); + + char szaddr[128] = {0}; + snprintf(szaddr, sizeof(szaddr), "tcp://%s:%d", ip, port); + zmq_connect(sock, szaddr); + + char szmsg[1024] = {0}; + int count = 0; + while(1) { + snprintf(szmsg, sizeof(szmsg), "I say %d", ++count); + fb_debug("send msg : [%s]", szmsg); + zmq_send(sock, szmsg, strlen(szmsg), 0); + zmq_recv(sock, szmsg, sizeof(szmsg) - 1, 0); + fb_debug("recv msg : [%s]", szmsg); + getchar(); + } + zmq_unbind(sock, szaddr); + zmq_close(sock); + zmq_ctx_term(ctx); + zmq_ctx_destroy(ctx); + return 0; +} + +char *get_server_publickey(void *ctx, char *publickey, int len, const char *ip, int port) { + void *sock = zmq_socket(ctx, ZMQ_DEALER); + char szmsg[1024] = {0}; + snprintf(szmsg, sizeof(szmsg), "tcp://%s:%d", ip, port); + zmq_connect(sock, szmsg); + snprintf(szmsg, sizeof(szmsg), "%s", "request publickey"); + zmq_send(sock, szmsg, strlen(szmsg), 0); + bzero(szmsg, sizeof(szmsg)); + zmq_recv(sock, szmsg, sizeof(szmsg), 0); + snprintf(publickey, len, "%s", szmsg); + + return publickey; +} + +int with_curve(const char * ip, int port) { + fb_debug("test tZMQ with curve"); + void * ctx = zmq_ctx_new(); + fb_assert(ctx, "create zmq context faild"); + + void *sock = zmq_socket(ctx, ZMQ_DEALER); + fb_assert(sock, "create zmq socket faild"); + + char szaddr[128] = {0}; + snprintf(szaddr, sizeof(szaddr), "tcp://%s:%d", ip, port); + + char szmsg[1024] = {0}; + get_server_publickey(ctx, szmsg, sizeof(szmsg), ip, port + 1); + fb_debug("server publickey : [%s]", szmsg); + zmq_setsockopt(sock, ZMQ_CURVE_SERVERKEY, szmsg, strlen(szmsg)); + + char szpubkey[64] = {0}; + char szprikey[64] = {0}; + zmq_curve_keypair(szpubkey, szprikey); + zmq_setsockopt(sock, ZMQ_CURVE_PUBLICKEY, szpubkey, strlen(szpubkey)); + zmq_setsockopt(sock, ZMQ_CURVE_SECRETKEY, szprikey, strlen(szprikey)); + fb_debug("start secert comunication"); + zmq_connect(sock, szaddr); + + int count = 0; + while(1) { + bzero(szmsg, sizeof(szmsg)); + snprintf(szmsg, sizeof(szmsg), "I say %d", ++count); + fb_debug("send msg : [%s]", szmsg); + zmq_send(sock, szmsg, strlen(szmsg), 0); + zmq_recv(sock, szmsg, sizeof(szmsg) - 1, 0); + fb_debug("recv msg : [%s]", szmsg); + getchar(); + } + zmq_close(sock); + zmq_ctx_term(ctx); + zmq_ctx_destroy(ctx); + return 0; +} + +int main(int argc, char * argv[]) { + const char *ip = "127.0.0.1"; + int port = 5678; + + int is_withvurve = 0; + int i = 0; + for(i = 0; i < argc; i++) { + if(strcmp("-s", argv[i]) == 0) { + is_withvurve = 1; + } + } + if(is_withvurve) { + with_curve(ip, port); + } else { + without_curve(ip, port); + } + + return 0; +} + + diff --git a/study_clang/zmq/zeromq-curve/server b/study_clang/zmq/zeromq-curve/server new file mode 100755 index 0000000..cec40fb Binary files /dev/null and b/study_clang/zmq/zeromq-curve/server differ diff --git a/study_clang/zmq/zeromq-curve/server.c b/study_clang/zmq/zeromq-curve/server.c new file mode 100644 index 0000000..88d9648 --- /dev/null +++ b/study_clang/zmq/zeromq-curve/server.c @@ -0,0 +1,182 @@ +/* + * ===================================================================================== + * + * Filename: send.c + * + * Description: + * + * Version: 1.0 + * Created: 09/28/2018 07:14:44 PM + * Revision: none + * Compiler: gcc + * + * Author: YOUR NAME (), + * Organization: + * + * ===================================================================================== + */ + +#include +#include +#include +#include + +#define fb_debug(fmt, arg...) \ + do{\ + printf("%s %d : ", __FILE__, __LINE__); \ + printf(fmt, ##arg); \ + printf("\n"); \ + }while(0) + +#define fb_assert(x, info) \ + do{\ + if(!(x)) { \ + fb_debug(info); \ + return -1;\ + } \ + }while(0) + +struct ser_opt { + void *zmq_ctx; + const char *publickey; + const char *ip; + int port; +}; + +void *publickey_server(void *arg) { + pthread_detach(pthread_self()); + if(!arg) { + fb_debug("no arg when thread start"); + return NULL; + } + struct ser_opt *server = (struct ser_opt*)arg; + void *sock = zmq_socket(server -> zmq_ctx, ZMQ_DEALER); + char szaddr[64] = {0}; + snprintf(szaddr, sizeof(szaddr), "tcp://%s:%d", server -> ip, server -> port); + zmq_bind(sock, szaddr); + char szmsg[1024] = {0}; + while(1) { + bzero(szmsg, sizeof(szmsg)); + zmq_recv(sock, szmsg, sizeof(szmsg) - 1, 0); + if (strcmp("request publickey", szmsg) == 0) { + snprintf(szmsg, sizeof(szmsg), "%s", server -> publickey); + } else { + snprintf(szmsg, sizeof(szmsg), "%s", "no such service"); + } + zmq_send(sock, szmsg, strlen(szmsg), 0); + } + + return NULL; +} + +int start_publickey_server(struct ser_opt *server) { + pthread_t pt; + pthread_create(&pt, NULL, publickey_server, server); + + return 0; +} + +int with_curve(const char *ip, int port) { + fb_debug("test tZMQ with curve"); + void * ctx = zmq_ctx_new(); + fb_assert(ctx, "create zmq context failed"); + + void *sock = zmq_socket(ctx, ZMQ_DEALER); + fb_assert(sock, "create zmq socket failed"); + + char szsecertkey[128] = {0}; + char szpublickey[128] = {0}; + zmq_curve_keypair(szpublickey, szsecertkey); + fb_debug("szsecertkey = [%s]", szsecertkey); + fb_debug("szpublickey = [%s]", szpublickey); + struct ser_opt server; + server.publickey = szpublickey; + server.ip = ip; + server.port = port + 1; + server.zmq_ctx = ctx; + start_publickey_server(&server); + + int option = 1; + zmq_setsockopt(sock, ZMQ_CURVE_SERVER, &option, sizeof(option)); + zmq_setsockopt(sock, ZMQ_CURVE_SECRETKEY, szsecertkey, strlen(szsecertkey)); + fb_debug("start secert comunication"); + + char szaddr[128] = {0}; + snprintf(szaddr, sizeof(szaddr), "tcp://%s:%d", ip, port); + zmq_bind(sock, szaddr); + + char szmsg[1024] = {0}; + while(1) { + bzero(szmsg, sizeof(szmsg)); + zmq_recv(sock, szmsg, sizeof(szmsg) - 1, 0); + fb_debug("recv msg : [%s]", szmsg); + if(strcasecmp("bye", szmsg) == 0) { + fb_debug("send msg : [%s]", szmsg); + zmq_send(sock, szmsg, strlen(szmsg), 0); + break; + } + strcat(szmsg, ", too"); + fb_debug("send msg : [%s]", szmsg); + zmq_send(sock, szmsg, strlen(szmsg), 0); + } + zmq_unbind(sock, szaddr); + zmq_close(sock); + zmq_ctx_term(ctx); + zmq_ctx_destroy(ctx); + + return 0; +} + +int without_curve(const char *ip, int port) { + fb_debug("test tZMQ without curve"); + void * ctx = zmq_ctx_new(); + fb_assert(ctx, "create zmq context failed"); + + void *sock = zmq_socket(ctx, ZMQ_DEALER); + fb_assert(sock, "create zmq socket failed"); + + char szaddr[128] = {0}; + snprintf(szaddr, sizeof(szaddr), "tcp://%s:%d", ip, port); + zmq_bind(sock, szaddr); + + char szmsg[1024] = {0}; + while(1) { + bzero(szmsg, sizeof(szmsg)); + zmq_recv(sock, szmsg, sizeof(szmsg) - 1, 0); + fb_debug("recv psg : [%s]", szmsg); + if(strcasecmp("bye", szmsg) == 0) { + fb_debug("send msg : [%s]", szmsg); + zmq_send(sock, szmsg, strlen(szmsg), 0); + break; + } + strcat(szmsg, ", too"); + fb_debug("send msg : [%s]", szmsg); + zmq_send(sock, szmsg, strlen(szmsg), 0); + } + zmq_unbind(sock, szaddr); + zmq_close(sock); + zmq_ctx_term(ctx); + zmq_ctx_destroy(ctx); + + return 0; +} + +int main(int argc, char * argv[]) { + const char *ip = "127.0.0.1"; + int port = 5678; + int is_withcurve = 0; + int i = 0; + for(i = 0; i < argc; i++) { + if(strcmp("-s", argv[i]) == 0) { + is_withcurve = 1; + } + } + if(is_withcurve) { + with_curve(ip, port); + } else { + without_curve(ip, port); + } + + return 0; +} + diff --git a/study_clang/zmq/zhelpers.h b/study_clang/zmq/zhelpers.h new file mode 100755 index 0000000..6e06dc9 --- /dev/null +++ b/study_clang/zmq/zhelpers.h @@ -0,0 +1,198 @@ +/* ===================================================================== + zhelpers.h + Helper header file for example applications. + ===================================================================== +*/ + +#ifndef __ZHELPERS_H_INCLUDED__ +#define __ZHELPERS_H_INCLUDED__ + +// Include a bunch of headers that we will need in the examples + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#if (!defined (WIN32)) +# include +#endif + +#if (defined (WIN32)) +# include +#endif + +// Version checking, and patch up missing constants to match 2.1 +#if ZMQ_VERSION_MAJOR == 2 +# error "Please upgrade to ZeroMQ/3.2 for these examples" +#endif + +// On some version of Windows, POSIX subsystem is not installed by default. +// So define srandom and random ourself. +#if (defined (WIN32)) +# define srandom srand +# define random rand +#endif + +// Provide random number from 0..(num-1) +#define randof(num) (int) ((float) (num) * random () / (RAND_MAX + 1.0)) + +// Receive 0MQ string from socket and convert into C string +// Caller must free returned string. Returns NULL if the context +// is being terminated. +static char * +s_recv (void *socket) { + enum { cap = 256 }; + char buffer [cap]; + int size = zmq_recv (socket, buffer, cap - 1, 0); + if (size == -1) + return NULL; + buffer[size < cap ? size : cap - 1] = '\0'; + +#if (defined (WIN32)) + return strdup (buffer); +#else + return strndup (buffer, sizeof(buffer) - 1); +#endif + + // remember that the strdup family of functions use malloc/alloc for space for the new string. It must be manually + // freed when you are done with it. Failure to do so will allow a heap attack. +} + +// Convert C string to 0MQ string and send to socket +static int +s_send (void *socket, char *string) { + int size = zmq_send (socket, string, strlen (string), 0); + return size; +} + +// Sends string as 0MQ string, as multipart non-terminal +static int +s_sendmore (void *socket, char *string) { + int size = zmq_send (socket, string, strlen (string), ZMQ_SNDMORE); + return size; +} + +// Receives all message parts from socket, prints neatly +// +static void +s_dump (void *socket) +{ + int rc; + + zmq_msg_t message; + rc = zmq_msg_init (&message); + assert (rc == 0); + + puts ("----------------------------------------"); + // Process all parts of the message + do { + int size = zmq_msg_recv (&message, socket, 0); + assert (size >= 0); + + // Dump the message as text or binary + char *data = (char*)zmq_msg_data (&message); + assert (data != 0); + int is_text = 1; + int char_nbr; + for (char_nbr = 0; char_nbr < size; char_nbr++) { + if ((unsigned char) data [char_nbr] < 32 + || (unsigned char) data [char_nbr] > 126) { + is_text = 0; + } + } + + printf ("[%03d] ", size); + for (char_nbr = 0; char_nbr < size; char_nbr++) { + if (is_text) { + printf ("%c", data [char_nbr]); + } else { + printf ("%02X", (unsigned char) data [char_nbr]); + } + } + printf ("\n"); + } while (zmq_msg_more (&message)); + + rc = zmq_msg_close (&message); + assert (rc == 0); +} + +#if (!defined (WIN32)) +// Set simple random printable identity on socket +// Caution: +// DO NOT call this version of s_set_id from multiple threads on MS Windows +// since s_set_id will call rand() on MS Windows. rand(), however, is not +// reentrant or thread-safe. See issue #521. +static void +s_set_id (void *socket) +{ + char identity [10]; + sprintf (identity, "%04X-%04X", randof (0x10000), randof (0x10000)); + zmq_setsockopt (socket, ZMQ_IDENTITY, identity, strlen (identity)); +} +#else +// Fix #521 for MS Windows. +static void +s_set_id(void *socket, intptr_t id) +{ + char identity [10]; + sprintf(identity, "%04X", (int)id); + zmq_setsockopt(socket, ZMQ_IDENTITY, identity, strlen(identity)); +} +#endif + +// Sleep for a number of milliseconds +static void +s_sleep (int msecs) +{ +#if (defined (WIN32)) + Sleep (msecs); +#else + struct timespec t; + t.tv_sec = msecs / 1000; + t.tv_nsec = (msecs % 1000) * 1000000; + nanosleep (&t, NULL); +#endif +} + +// Return current system clock as milliseconds +static int64_t +s_clock (void) +{ +#if (defined (WIN32)) + SYSTEMTIME st; + GetSystemTime (&st); + return (int64_t) st.wSecond * 1000 + st.wMilliseconds; +#else + struct timeval tv; + gettimeofday (&tv, NULL); + return (int64_t) (tv.tv_sec * 1000 + tv.tv_usec / 1000); +#endif +} + +// Print formatted string to stdout, prefixed by date/time and +// terminated with a newline. + +static void +s_console (const char *format, ...) +{ + time_t curtime = time (NULL); + struct tm *loctime = localtime (&curtime); + char *formatted = (char*)malloc (20); + strftime (formatted, 20, "%y-%m-%d %H:%M:%S ", loctime); + printf ("%s", formatted); + free (formatted); + + va_list argptr; + va_start (argptr, format); + vprintf (format, argptr); + va_end (argptr); + printf ("\n"); +} + +#endif // __ZHELPERS_H_INCLUDED__ \ No newline at end of file diff --git a/study_clang/zmq/zhelpers_client b/study_clang/zmq/zhelpers_client new file mode 100755 index 0000000..c8580dc Binary files /dev/null and b/study_clang/zmq/zhelpers_client differ diff --git a/study_clang/zmq/zhelpers_client2.c b/study_clang/zmq/zhelpers_client2.c new file mode 100755 index 0000000..940dbf3 --- /dev/null +++ b/study_clang/zmq/zhelpers_client2.c @@ -0,0 +1,64 @@ +// +// 气象信息客户端 +// 连接SUB套接字至tcp://*:5556端点 +// 收集指定邮编的气象信息,并计算平均温度 +// +#include "zhelpers.h" + +struct Msg +{ + int stat; + char id[100]; +}; + +int main (int argc, char *argv []) +{ + /* + struct Msg msg; + msg.stat = 1; + const char *str = "hellow world!"; + memset(msg.id, 0, sizeof(msg.id)); + memcpy(msg.id, str, strlen(str)); + int len = sizeof(struct Msg); + printf("sizeofid = %d strlen = %d len = %d\n", sizeof(msg.id), strlen(str), len); + */ + + const char* param = NULL; + if (argc > 1) + { + param = argv[1]; + } + else + { + printf("connect where: ip/port!\n"); + } + + char addr[40]; + sprintf(addr, "tcp://%s", param); + + void *context = zmq_init (1); + + printf ("正在收集气象信息...\n"); + void *subscriber = zmq_socket (context, ZMQ_SUB); + zmq_connect (subscriber, addr); + + char *filter = "0"; + zmq_setsockopt (subscriber, ZMQ_SUBSCRIBE, filter, strlen (filter)); + + int update_nbr; + for (update_nbr = 0; update_nbr < 100; update_nbr++) { + char *string = s_recv (subscriber); + printf("string=%s %d \n", string ,strlen(string)); + int protocol_serial = 0; + int len = 0; + struct Msg msg; + sscanf (string, "%d|%d|%d|%s", &protocol_serial, &msg.stat, &len, msg.id); + printf("recv ps=%d stat=%d len=%d id=%s\n", + protocol_serial, msg.stat, len, msg.id); + free (string); + } + + zmq_close (subscriber); + zmq_term (context); + return 0; +} diff --git a/study_clang/zmq/zhelpers_server b/study_clang/zmq/zhelpers_server new file mode 100755 index 0000000..5e9e82f Binary files /dev/null and b/study_clang/zmq/zhelpers_server differ diff --git a/study_clang/zmq/zhelpers_server2.c b/study_clang/zmq/zhelpers_server2.c new file mode 100755 index 0000000..00b8c40 --- /dev/null +++ b/study_clang/zmq/zhelpers_server2.c @@ -0,0 +1,57 @@ +#include "zhelpers.h" + +struct Msg +{ + int stat; + char id[100]; +}; + +int main (int argc, char *argv []) +{ + const char* param = NULL; + if (argc > 1) + { + param = argv[1]; + } + else + { + printf("connect where: ip/port!\n"); + } + char addr[40]; + sprintf(addr, "tcp://%s", param); + + // 准备上下文和PUB套接字 + void *context = zmq_init (1); + void *publisher = zmq_socket (context, ZMQ_PUB); + zmq_bind (publisher, addr); + //zmq_bind (publisher, "ipc://weather.ipc"); + + // 初始化随机数生成器 + srandom ((unsigned) time (NULL)); + while (1) { + // 生成数据 + int protocol_serial; + protocol_serial = randof (1); + + char buf [200]; + size_t buf_len = 0; + + memset(buf, 0, sizeof(buf)); + printf("buf: %d %s\n", strlen(buf), buf); + + struct Msg msg; + msg.stat = 0; + const char * str = "aa"; + memcpy(msg.id, str, strlen(str)); + + sprintf (buf, "%d|%d|%d|%s", protocol_serial, msg.stat, strlen(msg.id), msg.id); + + printf("buf: %d %s\n", strlen(buf), buf); + printf("send %d %d %d %s --> %s \n", protocol_serial, msg.stat, strlen(msg.id), buf, addr); + s_send (publisher, buf); + sleep(2); + } + zmq_close (publisher); + zmq_term (context); + return 0; +} diff --git a/study_clang/zmq/zmq.h b/study_clang/zmq/zmq.h new file mode 100755 index 0000000..5b22acf --- /dev/null +++ b/study_clang/zmq/zmq.h @@ -0,0 +1,778 @@ +/* + Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file + This file is part of libzmq, the ZeroMQ core engine in C++. + libzmq is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License (LGPL) as published + by the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + As a special exception, the Contributors give you permission to link + this library with independent modules to produce an executable, + regardless of the license terms of these independent modules, and to + copy and distribute the resulting executable under terms of your choice, + provided that you also meet, for each linked independent module, the + terms and conditions of the license of that module. An independent + module is a module which is not derived from or based on this library. + If you modify this library, you must extend this exception to your + version of the library. + libzmq is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . + ************************************************************************* + NOTE to contributors. This file comprises the principal public contract + for ZeroMQ API users. Any change to this file supplied in a stable + release SHOULD not break existing applications. + In practice this means that the value of constants must not change, and + that old values may not be reused for new constants. + ************************************************************************* +*/ + +#ifndef __ZMQ_H_INCLUDED__ +#define __ZMQ_H_INCLUDED__ + +/* Version macros for compile-time API version detection */ +#define ZMQ_VERSION_MAJOR 4 +#define ZMQ_VERSION_MINOR 3 +#define ZMQ_VERSION_PATCH 3 + +#define ZMQ_MAKE_VERSION(major, minor, patch) \ + ((major) *10000 + (minor) *100 + (patch)) +#define ZMQ_VERSION \ + ZMQ_MAKE_VERSION (ZMQ_VERSION_MAJOR, ZMQ_VERSION_MINOR, ZMQ_VERSION_PATCH) + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined _WIN32_WCE +#include +#endif +#include +#include +#if defined _WIN32 +// Set target version to Windows Server 2008, Windows Vista or higher. +// Windows XP (0x0501) is supported but without client & server socket types. +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0600 +#endif + +#ifdef __MINGW32__ +// Require Windows XP or higher with MinGW for getaddrinfo(). +#if (_WIN32_WINNT >= 0x0501) +#else +#error You need at least Windows XP target +#endif +#endif +#endif + +/* Handle DSO symbol visibility */ +#if defined _WIN32 +#if defined ZMQ_STATIC +#define ZMQ_EXPORT +#elif defined DLL_EXPORT +#define ZMQ_EXPORT __declspec(dllexport) +#else +#define ZMQ_EXPORT __declspec(dllimport) +#endif +#else +#if defined __SUNPRO_C || defined __SUNPRO_CC +#define ZMQ_EXPORT __global +#elif (defined __GNUC__ && __GNUC__ >= 4) || defined __INTEL_COMPILER +#define ZMQ_EXPORT __attribute__ ((visibility ("default"))) +#else +#define ZMQ_EXPORT +#endif +#endif + +/* Define integer types needed for event interface */ +#define ZMQ_DEFINED_STDINT 1 +#if defined ZMQ_HAVE_SOLARIS || defined ZMQ_HAVE_OPENVMS +#include +#elif defined _MSC_VER && _MSC_VER < 1600 +#ifndef uint64_t +typedef unsigned __int64 uint64_t; +#endif +#ifndef int32_t +typedef __int32 int32_t; +#endif +#ifndef uint32_t +typedef unsigned __int32 uint32_t; +#endif +#ifndef uint16_t +typedef unsigned __int16 uint16_t; +#endif +#ifndef uint8_t +typedef unsigned __int8 uint8_t; +#endif +#else +#include +#endif + +// 32-bit AIX's pollfd struct members are called reqevents and rtnevents so it +// defines compatibility macros for them. Need to include that header first to +// stop build failures since zmq_pollset_t defines them as events and revents. +#ifdef ZMQ_HAVE_AIX +#include +#endif + + +/******************************************************************************/ +/* 0MQ errors. */ +/******************************************************************************/ + +/* A number random enough not to collide with different errno ranges on */ +/* different OSes. The assumption is that error_t is at least 32-bit type. */ +#define ZMQ_HAUSNUMERO 156384712 + +/* On Windows platform some of the standard POSIX errnos are not defined. */ +#ifndef ENOTSUP +#define ENOTSUP (ZMQ_HAUSNUMERO + 1) +#endif +#ifndef EPROTONOSUPPORT +#define EPROTONOSUPPORT (ZMQ_HAUSNUMERO + 2) +#endif +#ifndef ENOBUFS +#define ENOBUFS (ZMQ_HAUSNUMERO + 3) +#endif +#ifndef ENETDOWN +#define ENETDOWN (ZMQ_HAUSNUMERO + 4) +#endif +#ifndef EADDRINUSE +#define EADDRINUSE (ZMQ_HAUSNUMERO + 5) +#endif +#ifndef EADDRNOTAVAIL +#define EADDRNOTAVAIL (ZMQ_HAUSNUMERO + 6) +#endif +#ifndef ECONNREFUSED +#define ECONNREFUSED (ZMQ_HAUSNUMERO + 7) +#endif +#ifndef EINPROGRESS +#define EINPROGRESS (ZMQ_HAUSNUMERO + 8) +#endif +#ifndef ENOTSOCK +#define ENOTSOCK (ZMQ_HAUSNUMERO + 9) +#endif +#ifndef EMSGSIZE +#define EMSGSIZE (ZMQ_HAUSNUMERO + 10) +#endif +#ifndef EAFNOSUPPORT +#define EAFNOSUPPORT (ZMQ_HAUSNUMERO + 11) +#endif +#ifndef ENETUNREACH +#define ENETUNREACH (ZMQ_HAUSNUMERO + 12) +#endif +#ifndef ECONNABORTED +#define ECONNABORTED (ZMQ_HAUSNUMERO + 13) +#endif +#ifndef ECONNRESET +#define ECONNRESET (ZMQ_HAUSNUMERO + 14) +#endif +#ifndef ENOTCONN +#define ENOTCONN (ZMQ_HAUSNUMERO + 15) +#endif +#ifndef ETIMEDOUT +#define ETIMEDOUT (ZMQ_HAUSNUMERO + 16) +#endif +#ifndef EHOSTUNREACH +#define EHOSTUNREACH (ZMQ_HAUSNUMERO + 17) +#endif +#ifndef ENETRESET +#define ENETRESET (ZMQ_HAUSNUMERO + 18) +#endif + +/* Native 0MQ error codes. */ +#define EFSM (ZMQ_HAUSNUMERO + 51) +#define ENOCOMPATPROTO (ZMQ_HAUSNUMERO + 52) +#define ETERM (ZMQ_HAUSNUMERO + 53) +#define EMTHREAD (ZMQ_HAUSNUMERO + 54) + +/* This function retrieves the errno as it is known to 0MQ library. The goal */ +/* of this function is to make the code 100% portable, including where 0MQ */ +/* compiled with certain CRT library (on Windows) is linked to an */ +/* application that uses different CRT library. */ +ZMQ_EXPORT int zmq_errno (void); + +/* Resolves system errors and 0MQ errors to human-readable string. */ +ZMQ_EXPORT const char *zmq_strerror (int errnum_); + +/* Run-time API version detection */ +ZMQ_EXPORT void zmq_version (int *major_, int *minor_, int *patch_); + +/******************************************************************************/ +/* 0MQ infrastructure (a.k.a. context) initialisation & termination. */ +/******************************************************************************/ + +/* Context options */ +#define ZMQ_IO_THREADS 1 +#define ZMQ_MAX_SOCKETS 2 +#define ZMQ_SOCKET_LIMIT 3 +#define ZMQ_THREAD_PRIORITY 3 +#define ZMQ_THREAD_SCHED_POLICY 4 +#define ZMQ_MAX_MSGSZ 5 +#define ZMQ_MSG_T_SIZE 6 +#define ZMQ_THREAD_AFFINITY_CPU_ADD 7 +#define ZMQ_THREAD_AFFINITY_CPU_REMOVE 8 +#define ZMQ_THREAD_NAME_PREFIX 9 + +/* Default for new contexts */ +#define ZMQ_IO_THREADS_DFLT 1 +#define ZMQ_MAX_SOCKETS_DFLT 1023 +#define ZMQ_THREAD_PRIORITY_DFLT -1 +#define ZMQ_THREAD_SCHED_POLICY_DFLT -1 + +ZMQ_EXPORT void *zmq_ctx_new (void); +ZMQ_EXPORT int zmq_ctx_term (void *context_); +ZMQ_EXPORT int zmq_ctx_shutdown (void *context_); +ZMQ_EXPORT int zmq_ctx_set (void *context_, int option_, int optval_); +ZMQ_EXPORT int zmq_ctx_get (void *context_, int option_); + +/* Old (legacy) API */ +ZMQ_EXPORT void *zmq_init (int io_threads_); +ZMQ_EXPORT int zmq_term (void *context_); +ZMQ_EXPORT int zmq_ctx_destroy (void *context_); + + +/******************************************************************************/ +/* 0MQ message definition. */ +/******************************************************************************/ + +/* Some architectures, like sparc64 and some variants of aarch64, enforce pointer + * alignment and raise sigbus on violations. Make sure applications allocate + * zmq_msg_t on addresses aligned on a pointer-size boundary to avoid this issue. + */ +typedef struct zmq_msg_t +{ +#if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_ARM64)) + __declspec(align (8)) unsigned char _[64]; +#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_ARM_ARMV7VE)) + __declspec(align (4)) unsigned char _[64]; +#elif defined(__GNUC__) || defined(__INTEL_COMPILER) \ + || (defined(__SUNPRO_C) && __SUNPRO_C >= 0x590) \ + || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x590) + unsigned char _[64] __attribute__ ((aligned (sizeof (void *)))); +#else + unsigned char _[64]; +#endif +} zmq_msg_t; + +typedef void(zmq_free_fn) (void *data_, void *hint_); + +ZMQ_EXPORT int zmq_msg_init (zmq_msg_t *msg_); +ZMQ_EXPORT int zmq_msg_init_size (zmq_msg_t *msg_, size_t size_); +ZMQ_EXPORT int zmq_msg_init_data ( + zmq_msg_t *msg_, void *data_, size_t size_, zmq_free_fn *ffn_, void *hint_); +ZMQ_EXPORT int zmq_msg_send (zmq_msg_t *msg_, void *s_, int flags_); +ZMQ_EXPORT int zmq_msg_recv (zmq_msg_t *msg_, void *s_, int flags_); +ZMQ_EXPORT int zmq_msg_close (zmq_msg_t *msg_); +ZMQ_EXPORT int zmq_msg_move (zmq_msg_t *dest_, zmq_msg_t *src_); +ZMQ_EXPORT int zmq_msg_copy (zmq_msg_t *dest_, zmq_msg_t *src_); +ZMQ_EXPORT void *zmq_msg_data (zmq_msg_t *msg_); +ZMQ_EXPORT size_t zmq_msg_size (const zmq_msg_t *msg_); +ZMQ_EXPORT int zmq_msg_more (const zmq_msg_t *msg_); +ZMQ_EXPORT int zmq_msg_get (const zmq_msg_t *msg_, int property_); +ZMQ_EXPORT int zmq_msg_set (zmq_msg_t *msg_, int property_, int optval_); +ZMQ_EXPORT const char *zmq_msg_gets (const zmq_msg_t *msg_, + const char *property_); + +/******************************************************************************/ +/* 0MQ socket definition. */ +/******************************************************************************/ + +/* Socket types. */ +#define ZMQ_PAIR 0 +#define ZMQ_PUB 1 +#define ZMQ_SUB 2 +#define ZMQ_REQ 3 +#define ZMQ_REP 4 +#define ZMQ_DEALER 5 +#define ZMQ_ROUTER 6 +#define ZMQ_PULL 7 +#define ZMQ_PUSH 8 +#define ZMQ_XPUB 9 +#define ZMQ_XSUB 10 +#define ZMQ_STREAM 11 + +/* Deprecated aliases */ +#define ZMQ_XREQ ZMQ_DEALER +#define ZMQ_XREP ZMQ_ROUTER + +/* Socket options. */ +#define ZMQ_AFFINITY 4 +#define ZMQ_ROUTING_ID 5 +#define ZMQ_SUBSCRIBE 6 +#define ZMQ_UNSUBSCRIBE 7 +#define ZMQ_RATE 8 +#define ZMQ_RECOVERY_IVL 9 +#define ZMQ_SNDBUF 11 +#define ZMQ_RCVBUF 12 +#define ZMQ_RCVMORE 13 +#define ZMQ_FD 14 +#define ZMQ_EVENTS 15 +#define ZMQ_TYPE 16 +#define ZMQ_LINGER 17 +#define ZMQ_RECONNECT_IVL 18 +#define ZMQ_BACKLOG 19 +#define ZMQ_RECONNECT_IVL_MAX 21 +#define ZMQ_MAXMSGSIZE 22 +#define ZMQ_SNDHWM 23 +#define ZMQ_RCVHWM 24 +#define ZMQ_MULTICAST_HOPS 25 +#define ZMQ_RCVTIMEO 27 +#define ZMQ_SNDTIMEO 28 +#define ZMQ_LAST_ENDPOINT 32 +#define ZMQ_ROUTER_MANDATORY 33 +#define ZMQ_TCP_KEEPALIVE 34 +#define ZMQ_TCP_KEEPALIVE_CNT 35 +#define ZMQ_TCP_KEEPALIVE_IDLE 36 +#define ZMQ_TCP_KEEPALIVE_INTVL 37 +#define ZMQ_IMMEDIATE 39 +#define ZMQ_XPUB_VERBOSE 40 +#define ZMQ_ROUTER_RAW 41 +#define ZMQ_IPV6 42 +#define ZMQ_MECHANISM 43 +#define ZMQ_PLAIN_SERVER 44 +#define ZMQ_PLAIN_USERNAME 45 +#define ZMQ_PLAIN_PASSWORD 46 +#define ZMQ_CURVE_SERVER 47 +#define ZMQ_CURVE_PUBLICKEY 48 +#define ZMQ_CURVE_SECRETKEY 49 +#define ZMQ_CURVE_SERVERKEY 50 +#define ZMQ_PROBE_ROUTER 51 +#define ZMQ_REQ_CORRELATE 52 +#define ZMQ_REQ_RELAXED 53 +#define ZMQ_CONFLATE 54 +#define ZMQ_ZAP_DOMAIN 55 +#define ZMQ_ROUTER_HANDOVER 56 +#define ZMQ_TOS 57 +#define ZMQ_CONNECT_ROUTING_ID 61 +#define ZMQ_GSSAPI_SERVER 62 +#define ZMQ_GSSAPI_PRINCIPAL 63 +#define ZMQ_GSSAPI_SERVICE_PRINCIPAL 64 +#define ZMQ_GSSAPI_PLAINTEXT 65 +#define ZMQ_HANDSHAKE_IVL 66 +#define ZMQ_SOCKS_PROXY 68 +#define ZMQ_XPUB_NODROP 69 +#define ZMQ_BLOCKY 70 +#define ZMQ_XPUB_MANUAL 71 +#define ZMQ_XPUB_WELCOME_MSG 72 +#define ZMQ_STREAM_NOTIFY 73 +#define ZMQ_INVERT_MATCHING 74 +#define ZMQ_HEARTBEAT_IVL 75 +#define ZMQ_HEARTBEAT_TTL 76 +#define ZMQ_HEARTBEAT_TIMEOUT 77 +#define ZMQ_XPUB_VERBOSER 78 +#define ZMQ_CONNECT_TIMEOUT 79 +#define ZMQ_TCP_MAXRT 80 +#define ZMQ_THREAD_SAFE 81 +#define ZMQ_MULTICAST_MAXTPDU 84 +#define ZMQ_VMCI_BUFFER_SIZE 85 +#define ZMQ_VMCI_BUFFER_MIN_SIZE 86 +#define ZMQ_VMCI_BUFFER_MAX_SIZE 87 +#define ZMQ_VMCI_CONNECT_TIMEOUT 88 +#define ZMQ_USE_FD 89 +#define ZMQ_GSSAPI_PRINCIPAL_NAMETYPE 90 +#define ZMQ_GSSAPI_SERVICE_PRINCIPAL_NAMETYPE 91 +#define ZMQ_BINDTODEVICE 92 + +/* Message options */ +#define ZMQ_MORE 1 +#define ZMQ_SHARED 3 + +/* Send/recv options. */ +#define ZMQ_DONTWAIT 1 +#define ZMQ_SNDMORE 2 + +/* Security mechanisms */ +#define ZMQ_NULL 0 +#define ZMQ_PLAIN 1 +#define ZMQ_CURVE 2 +#define ZMQ_GSSAPI 3 + +/* RADIO-DISH protocol */ +#define ZMQ_GROUP_MAX_LENGTH 255 + +/* Deprecated options and aliases */ +#define ZMQ_IDENTITY ZMQ_ROUTING_ID +#define ZMQ_CONNECT_RID ZMQ_CONNECT_ROUTING_ID +#define ZMQ_TCP_ACCEPT_FILTER 38 +#define ZMQ_IPC_FILTER_PID 58 +#define ZMQ_IPC_FILTER_UID 59 +#define ZMQ_IPC_FILTER_GID 60 +#define ZMQ_IPV4ONLY 31 +#define ZMQ_DELAY_ATTACH_ON_CONNECT ZMQ_IMMEDIATE +#define ZMQ_NOBLOCK ZMQ_DONTWAIT +#define ZMQ_FAIL_UNROUTABLE ZMQ_ROUTER_MANDATORY +#define ZMQ_ROUTER_BEHAVIOR ZMQ_ROUTER_MANDATORY + +/* Deprecated Message options */ +#define ZMQ_SRCFD 2 + +/******************************************************************************/ +/* GSSAPI definitions */ +/******************************************************************************/ + +/* GSSAPI principal name types */ +#define ZMQ_GSSAPI_NT_HOSTBASED 0 +#define ZMQ_GSSAPI_NT_USER_NAME 1 +#define ZMQ_GSSAPI_NT_KRB5_PRINCIPAL 2 + +/******************************************************************************/ +/* 0MQ socket events and monitoring */ +/******************************************************************************/ + +/* Socket transport events (TCP, IPC and TIPC only) */ + +#define ZMQ_EVENT_CONNECTED 0x0001 +#define ZMQ_EVENT_CONNECT_DELAYED 0x0002 +#define ZMQ_EVENT_CONNECT_RETRIED 0x0004 +#define ZMQ_EVENT_LISTENING 0x0008 +#define ZMQ_EVENT_BIND_FAILED 0x0010 +#define ZMQ_EVENT_ACCEPTED 0x0020 +#define ZMQ_EVENT_ACCEPT_FAILED 0x0040 +#define ZMQ_EVENT_CLOSED 0x0080 +#define ZMQ_EVENT_CLOSE_FAILED 0x0100 +#define ZMQ_EVENT_DISCONNECTED 0x0200 +#define ZMQ_EVENT_MONITOR_STOPPED 0x0400 +#define ZMQ_EVENT_ALL 0xFFFF +/* Unspecified system errors during handshake. Event value is an errno. */ +#define ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL 0x0800 +/* Handshake complete successfully with successful authentication (if * + * enabled). Event value is unused. */ +#define ZMQ_EVENT_HANDSHAKE_SUCCEEDED 0x1000 +/* Protocol errors between ZMTP peers or between server and ZAP handler. * + * Event value is one of ZMQ_PROTOCOL_ERROR_* */ +#define ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL 0x2000 +/* Failed authentication requests. Event value is the numeric ZAP status * + * code, i.e. 300, 400 or 500. */ +#define ZMQ_EVENT_HANDSHAKE_FAILED_AUTH 0x4000 +#define ZMQ_PROTOCOL_ERROR_ZMTP_UNSPECIFIED 0x10000000 +#define ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND 0x10000001 +#define ZMQ_PROTOCOL_ERROR_ZMTP_INVALID_SEQUENCE 0x10000002 +#define ZMQ_PROTOCOL_ERROR_ZMTP_KEY_EXCHANGE 0x10000003 +#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_UNSPECIFIED 0x10000011 +#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_MESSAGE 0x10000012 +#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO 0x10000013 +#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE 0x10000014 +#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_ERROR 0x10000015 +#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_READY 0x10000016 +#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_WELCOME 0x10000017 +#define ZMQ_PROTOCOL_ERROR_ZMTP_INVALID_METADATA 0x10000018 +// the following two may be due to erroneous configuration of a peer +#define ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC 0x11000001 +#define ZMQ_PROTOCOL_ERROR_ZMTP_MECHANISM_MISMATCH 0x11000002 +#define ZMQ_PROTOCOL_ERROR_ZAP_UNSPECIFIED 0x20000000 +#define ZMQ_PROTOCOL_ERROR_ZAP_MALFORMED_REPLY 0x20000001 +#define ZMQ_PROTOCOL_ERROR_ZAP_BAD_REQUEST_ID 0x20000002 +#define ZMQ_PROTOCOL_ERROR_ZAP_BAD_VERSION 0x20000003 +#define ZMQ_PROTOCOL_ERROR_ZAP_INVALID_STATUS_CODE 0x20000004 +#define ZMQ_PROTOCOL_ERROR_ZAP_INVALID_METADATA 0x20000005 +#define ZMQ_PROTOCOL_ERROR_WS_UNSPECIFIED 0x30000000 + +ZMQ_EXPORT void *zmq_socket (void *, int type_); +ZMQ_EXPORT int zmq_close (void *s_); +ZMQ_EXPORT int +zmq_setsockopt (void *s_, int option_, const void *optval_, size_t optvallen_); +ZMQ_EXPORT int +zmq_getsockopt (void *s_, int option_, void *optval_, size_t *optvallen_); +ZMQ_EXPORT int zmq_bind (void *s_, const char *addr_); +ZMQ_EXPORT int zmq_connect (void *s_, const char *addr_); +ZMQ_EXPORT int zmq_unbind (void *s_, const char *addr_); +ZMQ_EXPORT int zmq_disconnect (void *s_, const char *addr_); +ZMQ_EXPORT int zmq_send (void *s_, const void *buf_, size_t len_, int flags_); +ZMQ_EXPORT int +zmq_send_const (void *s_, const void *buf_, size_t len_, int flags_); +ZMQ_EXPORT int zmq_recv (void *s_, void *buf_, size_t len_, int flags_); +ZMQ_EXPORT int zmq_socket_monitor (void *s_, const char *addr_, int events_); + +/******************************************************************************/ +/* Hide socket fd type; this was before zmq_poller_event_t typedef below */ +/******************************************************************************/ + +#if defined _WIN32 +// Windows uses a pointer-sized unsigned integer to store the socket fd. +#if defined _WIN64 +typedef unsigned __int64 zmq_fd_t; +#else +typedef unsigned int zmq_fd_t; +#endif +#else +typedef int zmq_fd_t; +#endif + +/******************************************************************************/ +/* Deprecated I/O multiplexing. Prefer using zmq_poller API */ +/******************************************************************************/ + +#define ZMQ_POLLIN 1 +#define ZMQ_POLLOUT 2 +#define ZMQ_POLLERR 4 +#define ZMQ_POLLPRI 8 + +typedef struct zmq_pollitem_t +{ + void *socket; + zmq_fd_t fd; + short events; + short revents; +} zmq_pollitem_t; + +#define ZMQ_POLLITEMS_DFLT 16 + +ZMQ_EXPORT int zmq_poll (zmq_pollitem_t *items_, int nitems_, long timeout_); + +/******************************************************************************/ +/* Message proxying */ +/******************************************************************************/ + +ZMQ_EXPORT int zmq_proxy (void *frontend_, void *backend_, void *capture_); +ZMQ_EXPORT int zmq_proxy_steerable (void *frontend_, + void *backend_, + void *capture_, + void *control_); + +/******************************************************************************/ +/* Probe library capabilities */ +/******************************************************************************/ + +#define ZMQ_HAS_CAPABILITIES 1 +ZMQ_EXPORT int zmq_has (const char *capability_); + +/* Deprecated aliases */ +#define ZMQ_STREAMER 1 +#define ZMQ_FORWARDER 2 +#define ZMQ_QUEUE 3 + +/* Deprecated methods */ +ZMQ_EXPORT int zmq_device (int type_, void *frontend_, void *backend_); +ZMQ_EXPORT int zmq_sendmsg (void *s_, zmq_msg_t *msg_, int flags_); +ZMQ_EXPORT int zmq_recvmsg (void *s_, zmq_msg_t *msg_, int flags_); +struct iovec; +ZMQ_EXPORT int +zmq_sendiov (void *s_, struct iovec *iov_, size_t count_, int flags_); +ZMQ_EXPORT int +zmq_recviov (void *s_, struct iovec *iov_, size_t *count_, int flags_); + +/******************************************************************************/ +/* Encryption functions */ +/******************************************************************************/ + +/* Encode data with Z85 encoding. Returns encoded data */ +ZMQ_EXPORT char * +zmq_z85_encode (char *dest_, const uint8_t *data_, size_t size_); + +/* Decode data with Z85 encoding. Returns decoded data */ +ZMQ_EXPORT uint8_t *zmq_z85_decode (uint8_t *dest_, const char *string_); + +/* Generate z85-encoded public and private keypair with tweetnacl/libsodium. */ +/* Returns 0 on success. */ +ZMQ_EXPORT int zmq_curve_keypair (char *z85_public_key_, char *z85_secret_key_); + +/* Derive the z85-encoded public key from the z85-encoded secret key. */ +/* Returns 0 on success. */ +ZMQ_EXPORT int zmq_curve_public (char *z85_public_key_, + const char *z85_secret_key_); + +/******************************************************************************/ +/* Atomic utility methods */ +/******************************************************************************/ + +ZMQ_EXPORT void *zmq_atomic_counter_new (void); +ZMQ_EXPORT void zmq_atomic_counter_set (void *counter_, int value_); +ZMQ_EXPORT int zmq_atomic_counter_inc (void *counter_); +ZMQ_EXPORT int zmq_atomic_counter_dec (void *counter_); +ZMQ_EXPORT int zmq_atomic_counter_value (void *counter_); +ZMQ_EXPORT void zmq_atomic_counter_destroy (void **counter_p_); + +/******************************************************************************/ +/* Scheduling timers */ +/******************************************************************************/ + +#define ZMQ_HAVE_TIMERS + +typedef void(zmq_timer_fn) (int timer_id, void *arg); + +ZMQ_EXPORT void *zmq_timers_new (void); +ZMQ_EXPORT int zmq_timers_destroy (void **timers_p); +ZMQ_EXPORT int +zmq_timers_add (void *timers, size_t interval, zmq_timer_fn handler, void *arg); +ZMQ_EXPORT int zmq_timers_cancel (void *timers, int timer_id); +ZMQ_EXPORT int +zmq_timers_set_interval (void *timers, int timer_id, size_t interval); +ZMQ_EXPORT int zmq_timers_reset (void *timers, int timer_id); +ZMQ_EXPORT long zmq_timers_timeout (void *timers); +ZMQ_EXPORT int zmq_timers_execute (void *timers); + + +/******************************************************************************/ +/* These functions are not documented by man pages -- use at your own risk. */ +/* If you need these to be part of the formal ZMQ API, then (a) write a man */ +/* page, and (b) write a test case in tests. */ +/******************************************************************************/ + +/* Helper functions are used by perf tests so that they don't have to care */ +/* about minutiae of time-related functions on different OS platforms. */ + +/* Starts the stopwatch. Returns the handle to the watch. */ +ZMQ_EXPORT void *zmq_stopwatch_start (void); + +/* Returns the number of microseconds elapsed since the stopwatch was */ +/* started, but does not stop or deallocate the stopwatch. */ +ZMQ_EXPORT unsigned long zmq_stopwatch_intermediate (void *watch_); + +/* Stops the stopwatch. Returns the number of microseconds elapsed since */ +/* the stopwatch was started, and deallocates that watch. */ +ZMQ_EXPORT unsigned long zmq_stopwatch_stop (void *watch_); + +/* Sleeps for specified number of seconds. */ +ZMQ_EXPORT void zmq_sleep (int seconds_); + +typedef void(zmq_thread_fn) (void *); + +/* Start a thread. Returns a handle to the thread. */ +ZMQ_EXPORT void *zmq_threadstart (zmq_thread_fn *func_, void *arg_); + +/* Wait for thread to complete then free up resources. */ +ZMQ_EXPORT void zmq_threadclose (void *thread_); + + +/******************************************************************************/ +/* These functions are DRAFT and disabled in stable releases, and subject to */ +/* change at ANY time until declared stable. */ +/******************************************************************************/ + +#ifdef ZMQ_BUILD_DRAFT_API + +/* DRAFT Socket types. */ +#define ZMQ_SERVER 12 +#define ZMQ_CLIENT 13 +#define ZMQ_RADIO 14 +#define ZMQ_DISH 15 +#define ZMQ_GATHER 16 +#define ZMQ_SCATTER 17 +#define ZMQ_DGRAM 18 +#define ZMQ_PEER 19 +#define ZMQ_CHANNEL 20 + +/* DRAFT Socket options. */ +#define ZMQ_ZAP_ENFORCE_DOMAIN 93 +#define ZMQ_LOOPBACK_FASTPATH 94 +#define ZMQ_METADATA 95 +#define ZMQ_MULTICAST_LOOP 96 +#define ZMQ_ROUTER_NOTIFY 97 +#define ZMQ_XPUB_MANUAL_LAST_VALUE 98 +#define ZMQ_SOCKS_USERNAME 99 +#define ZMQ_SOCKS_PASSWORD 100 +#define ZMQ_IN_BATCH_SIZE 101 +#define ZMQ_OUT_BATCH_SIZE 102 +#define ZMQ_WSS_KEY_PEM 103 +#define ZMQ_WSS_CERT_PEM 104 +#define ZMQ_WSS_TRUST_PEM 105 +#define ZMQ_WSS_HOSTNAME 106 +#define ZMQ_WSS_TRUST_SYSTEM 107 +#define ZMQ_ONLY_FIRST_SUBSCRIBE 108 +#define ZMQ_RECONNECT_STOP 109 +#define ZMQ_HELLO_MSG 110 +#define ZMQ_DISCONNECT_MSG 111 + +/* DRAFT ZMQ_RECONNECT_STOP options */ +#define ZMQ_RECONNECT_STOP_CONN_REFUSED 0x1 + +/* DRAFT Context options */ +#define ZMQ_ZERO_COPY_RECV 10 + +/* DRAFT Context methods. */ +ZMQ_EXPORT int zmq_ctx_set_ext (void *context_, + int option_, + const void *optval_, + size_t optvallen_); +ZMQ_EXPORT int zmq_ctx_get_ext (void *context_, + int option_, + void *optval_, + size_t *optvallen_); + +/* DRAFT Socket methods. */ +ZMQ_EXPORT int zmq_join (void *s, const char *group); +ZMQ_EXPORT int zmq_leave (void *s, const char *group); +ZMQ_EXPORT uint32_t zmq_connect_peer (void *s_, const char *addr_); + +/* DRAFT Msg methods. */ +ZMQ_EXPORT int zmq_msg_set_routing_id (zmq_msg_t *msg, uint32_t routing_id); +ZMQ_EXPORT uint32_t zmq_msg_routing_id (zmq_msg_t *msg); +ZMQ_EXPORT int zmq_msg_set_group (zmq_msg_t *msg, const char *group); +ZMQ_EXPORT const char *zmq_msg_group (zmq_msg_t *msg); +ZMQ_EXPORT int +zmq_msg_init_buffer (zmq_msg_t *msg_, const void *buf_, size_t size_); + +/* DRAFT Msg property names. */ +#define ZMQ_MSG_PROPERTY_ROUTING_ID "Routing-Id" +#define ZMQ_MSG_PROPERTY_SOCKET_TYPE "Socket-Type" +#define ZMQ_MSG_PROPERTY_USER_ID "User-Id" +#define ZMQ_MSG_PROPERTY_PEER_ADDRESS "Peer-Address" + +/* Router notify options */ +#define ZMQ_NOTIFY_CONNECT 1 +#define ZMQ_NOTIFY_DISCONNECT 2 + +/******************************************************************************/ +/* Poller polling on sockets,fd and thread-safe sockets */ +/******************************************************************************/ + +#define ZMQ_HAVE_POLLER + +typedef struct zmq_poller_event_t +{ + void *socket; + zmq_fd_t fd; + void *user_data; + short events; +} zmq_poller_event_t; + +ZMQ_EXPORT void *zmq_poller_new (void); +ZMQ_EXPORT int zmq_poller_destroy (void **poller_p); +ZMQ_EXPORT int zmq_poller_size (void *poller); +ZMQ_EXPORT int +zmq_poller_add (void *poller, void *socket, void *user_data, short events); +ZMQ_EXPORT int zmq_poller_modify (void *poller, void *socket, short events); +ZMQ_EXPORT int zmq_poller_remove (void *poller, void *socket); +ZMQ_EXPORT int +zmq_poller_wait (void *poller, zmq_poller_event_t *event, long timeout); +ZMQ_EXPORT int zmq_poller_wait_all (void *poller, + zmq_poller_event_t *events, + int n_events, + long timeout); +ZMQ_EXPORT int zmq_poller_fd (void *poller, zmq_fd_t *fd); + +ZMQ_EXPORT int +zmq_poller_add_fd (void *poller, zmq_fd_t fd, void *user_data, short events); +ZMQ_EXPORT int zmq_poller_modify_fd (void *poller, zmq_fd_t fd, short events); +ZMQ_EXPORT int zmq_poller_remove_fd (void *poller, zmq_fd_t fd); + +ZMQ_EXPORT int zmq_socket_get_peer_state (void *socket, + const void *routing_id, + size_t routing_id_size); + +/* DRAFT Socket monitoring events */ +#define ZMQ_EVENT_PIPES_STATS 0x10000 + +#define ZMQ_CURRENT_EVENT_VERSION 1 +#define ZMQ_CURRENT_EVENT_VERSION_DRAFT 2 + +#define ZMQ_EVENT_ALL_V1 ZMQ_EVENT_ALL +#define ZMQ_EVENT_ALL_V2 ZMQ_EVENT_ALL_V1 | ZMQ_EVENT_PIPES_STATS + +ZMQ_EXPORT int zmq_socket_monitor_versioned ( + void *s_, const char *addr_, uint64_t events_, int event_version_, int type_); +ZMQ_EXPORT int zmq_socket_monitor_pipes_stats (void *s); + +#endif // ZMQ_BUILD_DRAFT_API + + +#undef ZMQ_EXPORT + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/study_clang/zmq/zmq_experiment/client b/study_clang/zmq/zmq_experiment/client new file mode 100755 index 0000000..f0f65b8 Binary files /dev/null and b/study_clang/zmq/zmq_experiment/client differ diff --git a/study_clang/zmq/zmq_experiment/data_mode.h b/study_clang/zmq/zmq_experiment/data_mode.h new file mode 100644 index 0000000..d5627c5 --- /dev/null +++ b/study_clang/zmq/zmq_experiment/data_mode.h @@ -0,0 +1,23 @@ +/***************************************************************************** + * Copyright: 2016-2026, Ieucd Tech. Co., Ltd. + * File name: data_mode.h + * Description: 用于实现zmq多线程收发结构体消息的通信框架。 + * Author: TLSong + * Version: V0.0.1 + * Date: 2020/7/7 + * History: + * 2020/7/7 创建文件。 + * *****************************************************************************/ + + +struct MSG //发送消息 +{ + int Int; + char Char; + short Short; + long Long; + float Float; + double Double; + char String[100]; +}; +typedef struct MSG Msg; diff --git a/study_clang/zmq/zmq_experiment/server b/study_clang/zmq/zmq_experiment/server new file mode 100755 index 0000000..0877536 Binary files /dev/null and b/study_clang/zmq/zmq_experiment/server differ diff --git a/study_clang/zmq/zmq_experiment/server.c b/study_clang/zmq/zmq_experiment/server.c new file mode 100644 index 0000000..1fa48db --- /dev/null +++ b/study_clang/zmq/zmq_experiment/server.c @@ -0,0 +1,104 @@ +/***************************************************************************** + * Copyright: 2016-2026, Ieucd Tech. Co., Ltd. + * File name: server.c + * Description: 用于实现zmq多线程收发结构体消息的通信框架。 + * Author: TLSong + * Version: V0.0.1 + * Date: 2020/7/7 + * History: + * 2020/7/7 创建文件。 + * *****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "data_mode.h" + +void *value_server(void *args) +{ + Msg max_msg = {INT_MAX, CHAR_MAX, SHRT_MAX, LONG_MAX, FLT_MAX, DBL_MAX, "Hello Max Value!"}; + Msg min_msg = {INT_MIN, CHAR_MIN, SHRT_MIN, LONG_MIN, FLT_MIN, DBL_MIN, "Hello Min Value!"}; + Msg random_msg = {233, 'h', 244, 255, 0.01, 0.0001, "Hello Random Value!"}; + + + // Socket to talk to clients + void *context = zmq_ctx_new (); + void *responder = zmq_socket (context, ZMQ_REP); + int rc = zmq_bind (responder, "tcp://*:5555"); + assert (rc == 0); + + while (1) { + char buffer [10]; + zmq_recv (responder, buffer, 10, 0); + printf ("Received: %s\n",buffer); + sleep (1); // Do some 'work' + Msg send_msg; + if(strcmp(buffer,"MAX")==0) + send_msg = max_msg; + else if(strcmp(buffer,"MIN")==0) + send_msg = min_msg; + else + send_msg = random_msg; + zmq_send (responder, &send_msg, sizeof(send_msg), 0); + printf ("Sned message: \n"); + printf ("---------------start---------------\n"); + printf ("int: %d\n",send_msg.Int); + printf ("char: %c\n",send_msg.Char); + printf ("short: %hd\n",send_msg.Short); + printf ("long: %ld\n",send_msg.Long); + printf ("float: %d\n",send_msg.Float); + printf ("double: %d\n",send_msg.Double); + printf ("String: %s\n",send_msg.String); + printf ("--------------- end ---------------\n"); + + } + +} + +void *sub_weather(void *args) +{ + void* context = zmq_ctx_new(); + assert(context != NULL); + + void* subscriber = zmq_socket(context, ZMQ_SUB); + assert(subscriber != NULL); + + int ret = zmq_connect(subscriber, "tcp://localhost:5556"); + assert(ret == 0); + + ret = zmq_setsockopt(subscriber, ZMQ_SUBSCRIBE, "", 0); + assert(ret == 0); + + while(1) + { + printf("into while\n"); + char szBuf[1024] = {0}; + ret = zmq_recv(subscriber, szBuf, sizeof(szBuf) - 1, 0); + if (ret > 0) + { + printf("%s\n", szBuf); + } + } + + zmq_close(subscriber); + zmq_ctx_destroy(context); +} + +int main (void) +{ + int value_ret, sub_weather_ret; + pthread_t value_pth, sub_weather_pth; //线程ID变量 + // 参数:创建的线程ID,线程参数,调用函数,函数参数 + value_ret = pthread_create(&value_pth,NULL,value_server,NULL); + sub_weather_ret = pthread_create(&sub_weather_pth,NULL,sub_weather,NULL); + + pthread_join(value_pth,NULL); // 等待线程结束 + //pthread_join(sub_weather_pth.NULL); + + return 0; +} diff --git a/study_clang/zmq/zmq_experiment/sub_pub/pub b/study_clang/zmq/zmq_experiment/sub_pub/pub new file mode 100755 index 0000000..02d1e34 Binary files /dev/null and b/study_clang/zmq/zmq_experiment/sub_pub/pub differ diff --git a/study_clang/zmq/zmq_experiment/sub_pub/pub.c b/study_clang/zmq/zmq_experiment/sub_pub/pub.c new file mode 100644 index 0000000..c810676 --- /dev/null +++ b/study_clang/zmq/zmq_experiment/sub_pub/pub.c @@ -0,0 +1,34 @@ +#include +#include +#include +#include +#include +#include "zmq.h" + +int main() +{ + void* context = zmq_ctx_new(); + assert(context != NULL); + + void* publisher = zmq_socket(context, ZMQ_PUB); + assert(publisher != NULL); + + int ret = zmq_bind(publisher, "tcp://*:5555"); + assert(ret == 0); + + int i = 0; + while(1) + { + char szBuf[1024] = {0}; + snprintf(szBuf, sizeof(szBuf), "server i=%d", i); + ret = zmq_send(publisher, szBuf, strlen(szBuf) + 1, 0); + i++; + + sleep(1); + } + + zmq_close (publisher); + zmq_ctx_destroy (context); + + return 0; +} diff --git a/study_clang/zmq/zmq_experiment/sub_pub/sub b/study_clang/zmq/zmq_experiment/sub_pub/sub new file mode 100755 index 0000000..4f23dbb Binary files /dev/null and b/study_clang/zmq/zmq_experiment/sub_pub/sub differ diff --git a/study_clang/zmq/zmq_experiment/sub_pub/sub.c b/study_clang/zmq/zmq_experiment/sub_pub/sub.c new file mode 100644 index 0000000..f38efa0 --- /dev/null +++ b/study_clang/zmq/zmq_experiment/sub_pub/sub.c @@ -0,0 +1,38 @@ +#include +#include +#include +#include +#include "zmq.h" + +int main() +{ + printf("Hello world!\n"); + + void* context = zmq_ctx_new(); + assert(context != NULL); + + void* subscriber = zmq_socket(context, ZMQ_SUB); + assert(subscriber != NULL); + + int ret = zmq_connect(subscriber, "tcp://localhost:5555"); + assert(ret == 0); + + ret = zmq_setsockopt(subscriber, ZMQ_SUBSCRIBE, "", 0); + assert(ret == 0); + + while(1) + { + printf("into while\n"); + char szBuf[1024] = {0}; + ret = zmq_recv(subscriber, szBuf, sizeof(szBuf) - 1, 0); + if (ret > 0) + { + printf("%s\n", szBuf); + } + } + + zmq_close(subscriber); + zmq_ctx_destroy(context); + + return 0; +} diff --git a/study_clang/zmq/zmq_experiment/value_client b/study_clang/zmq/zmq_experiment/value_client new file mode 100755 index 0000000..1dbde6e Binary files /dev/null and b/study_clang/zmq/zmq_experiment/value_client differ diff --git a/study_clang/zmq/zmq_experiment/value_client.c b/study_clang/zmq/zmq_experiment/value_client.c new file mode 100644 index 0000000..6b14e82 --- /dev/null +++ b/study_clang/zmq/zmq_experiment/value_client.c @@ -0,0 +1,51 @@ +/***************************************************************************** + * Copyright: 2016-2026, Ieucd Tech. Co., Ltd. + * File name: client.c + * Description: 用于实现zmq多线程收发结构体消息的通信框架中的客户端部分。 + * Author: TLSong + * Version: V0.0.1 + * Date: 2020/7/7 + * History: + * 2020/7/7 创建文件。 + * *****************************************************************************/ + +#include +#include +#include +#include +#include "data_mode.h" + +int main (void) +{ + printf ("Connecting to hello world server…\n"); + void *context = zmq_ctx_new (); + void *requester = zmq_socket (context, ZMQ_REQ); + zmq_connect (requester, "tcp://127.0.0.1:5555"); + + int request_nbr; + for (request_nbr = 0; request_nbr < 3; request_nbr++) { + Msg recv_msg; + char send_ask[10] = "Random"; + if(request_nbr==1) + strcpy(send_ask,"MAX"); + else if(request_nbr==2) + strcpy(send_ask,"MIN"); + char buffer [10]; + printf ("Sending Hello %d…\n", request_nbr); + zmq_send (requester, send_ask, sizeof(send_ask), 0); + zmq_recv (requester, &recv_msg, sizeof(recv_msg), 0); + printf ("Reply received %d, content: \n", request_nbr); + printf ("---------------start---------------\n"); + printf ("int: %d\n",recv_msg.Int); + printf ("char: %c\n",recv_msg.Char); + printf ("short: %hd\n",recv_msg.Short); + printf ("long: %ld\n",recv_msg.Long); + printf ("float: %d\n",recv_msg.Float); + printf ("double: %d\n",recv_msg.Double); + printf ("String: %s\n",recv_msg.String); + printf ("--------------- end ---------------\n"); + } + zmq_close (requester); + zmq_ctx_destroy (context); + return 0; +} diff --git a/study_clang/zmq/zmq_experiment/weather_pub b/study_clang/zmq/zmq_experiment/weather_pub new file mode 100755 index 0000000..a446be1 Binary files /dev/null and b/study_clang/zmq/zmq_experiment/weather_pub differ diff --git a/study_clang/zmq/zmq_experiment/weather_pub.c b/study_clang/zmq/zmq_experiment/weather_pub.c new file mode 100644 index 0000000..0066a68 --- /dev/null +++ b/study_clang/zmq/zmq_experiment/weather_pub.c @@ -0,0 +1,34 @@ +#include +#include +#include +#include +#include +#include "zmq.h" + +int main() +{ + void* context = zmq_ctx_new(); + assert(context != NULL); + + void* publisher = zmq_socket(context, ZMQ_PUB); + assert(publisher != NULL); + + int ret = zmq_bind(publisher, "tcp://*:5556"); + assert(ret == 0); + + int i = 0; + while(1) + { + char szBuf[1024] = {0}; + snprintf(szBuf, sizeof(szBuf), "server i=%d", i); + ret = zmq_send(publisher, szBuf, strlen(szBuf) + 1, 0); + i++; + + sleep(1); + } + + zmq_close (publisher); + zmq_ctx_destroy (context); + + return 0; +} diff --git a/study_clang/zmq/zmq_experiment/weather_sub b/study_clang/zmq/zmq_experiment/weather_sub new file mode 100755 index 0000000..d55507f Binary files /dev/null and b/study_clang/zmq/zmq_experiment/weather_sub differ diff --git a/study_clang/zmq/zmq_experiment/weather_sub.c b/study_clang/zmq/zmq_experiment/weather_sub.c new file mode 100644 index 0000000..2bc449a --- /dev/null +++ b/study_clang/zmq/zmq_experiment/weather_sub.c @@ -0,0 +1,38 @@ +#include +#include +#include +#include +#include "zmq.h" + +int main() +{ + printf("Hello world!\n"); + + void* context = zmq_ctx_new(); + assert(context != NULL); + + void* subscriber = zmq_socket(context, ZMQ_SUB); + assert(subscriber != NULL); + + int ret = zmq_connect(subscriber, "tcp://localhost:5556"); + assert(ret == 0); + + ret = zmq_setsockopt(subscriber, ZMQ_SUBSCRIBE, "", 0); + assert(ret == 0); + + while(1) + { + printf("into while\n"); + char szBuf[1024] = {0}; + ret = zmq_recv(subscriber, szBuf, sizeof(szBuf) - 1, 0); + if (ret > 0) + { + printf("%s\n", szBuf); + } + } + + zmq_close(subscriber); + zmq_ctx_destroy(context); + + return 0; +} diff --git a/study_clang/zmq/zmq_experiment/weather_sun b/study_clang/zmq/zmq_experiment/weather_sun new file mode 100755 index 0000000..d55507f Binary files /dev/null and b/study_clang/zmq/zmq_experiment/weather_sun differ diff --git a/study_clang/zmq/zmq_server_dockerfile b/study_clang/zmq/zmq_server_dockerfile new file mode 100644 index 0000000..7288976 --- /dev/null +++ b/study_clang/zmq/zmq_server_dockerfile @@ -0,0 +1,9 @@ +FROM alpine:latest as centos_zmq_server +MAINTAINER tlsong + +RUN apk add zeromq-dev +COPY /root/dev/zmq/hello_world_server /home/ + +WORKDIR /home + +CMD ["./hello_world_server"] diff --git a/study_cpp/Makefile b/study_cpp/Makefile new file mode 100644 index 0000000..b10df75 --- /dev/null +++ b/study_cpp/Makefile @@ -0,0 +1,22 @@ +# Batch Single C file MakeFile + +# 指定CPU架构 Architecture -> ARCH +ARCH ?= +CC = $(ARCH)gcc +SUFFIX = .c +CFLAGS += -Wall -g +LD = + +CUR_SOURCE = $(wildcard *$(SUFFIX)) +CUR_TARGETS = $(patsubst %$(SUFFIX), %, $(CUR_SOURCE)) + +all:$(CUR_TARGETS) + +# %:%.c 是一个表示与目标相同 文件的模式变量 +$(CUR_TARGETS):%:%$(SUFFIX) + $(CC) $< $(CFLAGS) -o $@ $(LD) + +# 指定伪目标 +.PHONY:clean all + clean: + -rm -rf $(TARGETS) diff --git a/study_cpp/P2P-Share/README.md b/study_cpp/P2P-Share/README.md new file mode 100644 index 0000000..5000d57 --- /dev/null +++ b/study_cpp/P2P-Share/README.md @@ -0,0 +1,10 @@ + +``` +sudo apt-get install libboost-filesystem-dev +``` + +## 参考文献 + +- [fatal error: boost/filesystem.hpp: No such file or directory](https://stackoverflow.com/questions/50511546/fatal-error-boost-filesystem-hpp-no-such-file-or-directory) +- [小项目---基于局域网的P2P文件共享工具](https://blog.csdn.net/tomatolee221/article/details/99078659) +- [P2P下载器](https://github.com/gaecoli/MiniProject/tree/master/P2P%E4%B8%8B%E8%BD%BD%E5%99%A8) \ No newline at end of file diff --git a/study_cpp/P2P-Share/cli b/study_cpp/P2P-Share/cli new file mode 100755 index 0000000..6cfba99 Binary files /dev/null and b/study_cpp/P2P-Share/cli differ diff --git a/study_cpp/P2P-Share/httplib.h b/study_cpp/P2P-Share/httplib.h new file mode 100644 index 0000000..ea600db --- /dev/null +++ b/study_cpp/P2P-Share/httplib.h @@ -0,0 +1,7834 @@ +// +// httplib.h +// +// Copyright (c) 2021 Yuji Hirose. All rights reserved. +// MIT License +// + +#ifndef CPPHTTPLIB_HTTPLIB_H +#define CPPHTTPLIB_HTTPLIB_H + +/* + * Configuration + */ + +#ifndef CPPHTTPLIB_KEEPALIVE_TIMEOUT_SECOND +#define CPPHTTPLIB_KEEPALIVE_TIMEOUT_SECOND 5 +#endif + +#ifndef CPPHTTPLIB_KEEPALIVE_MAX_COUNT +#define CPPHTTPLIB_KEEPALIVE_MAX_COUNT 5 +#endif + +#ifndef CPPHTTPLIB_CONNECTION_TIMEOUT_SECOND +#define CPPHTTPLIB_CONNECTION_TIMEOUT_SECOND 300 +#endif + +#ifndef CPPHTTPLIB_CONNECTION_TIMEOUT_USECOND +#define CPPHTTPLIB_CONNECTION_TIMEOUT_USECOND 0 +#endif + +#ifndef CPPHTTPLIB_READ_TIMEOUT_SECOND +#define CPPHTTPLIB_READ_TIMEOUT_SECOND 5 +#endif + +#ifndef CPPHTTPLIB_READ_TIMEOUT_USECOND +#define CPPHTTPLIB_READ_TIMEOUT_USECOND 0 +#endif + +#ifndef CPPHTTPLIB_WRITE_TIMEOUT_SECOND +#define CPPHTTPLIB_WRITE_TIMEOUT_SECOND 5 +#endif + +#ifndef CPPHTTPLIB_WRITE_TIMEOUT_USECOND +#define CPPHTTPLIB_WRITE_TIMEOUT_USECOND 0 +#endif + +#ifndef CPPHTTPLIB_IDLE_INTERVAL_SECOND +#define CPPHTTPLIB_IDLE_INTERVAL_SECOND 0 +#endif + +#ifndef CPPHTTPLIB_IDLE_INTERVAL_USECOND +#ifdef _WIN32 +#define CPPHTTPLIB_IDLE_INTERVAL_USECOND 10000 +#else +#define CPPHTTPLIB_IDLE_INTERVAL_USECOND 0 +#endif +#endif + +#ifndef CPPHTTPLIB_REQUEST_URI_MAX_LENGTH +#define CPPHTTPLIB_REQUEST_URI_MAX_LENGTH 8192 +#endif + +#ifndef CPPHTTPLIB_REDIRECT_MAX_COUNT +#define CPPHTTPLIB_REDIRECT_MAX_COUNT 20 +#endif + +#ifndef CPPHTTPLIB_PAYLOAD_MAX_LENGTH +#define CPPHTTPLIB_PAYLOAD_MAX_LENGTH ((std::numeric_limits::max)()) +#endif + +#ifndef CPPHTTPLIB_TCP_NODELAY +#define CPPHTTPLIB_TCP_NODELAY false +#endif + +#ifndef CPPHTTPLIB_RECV_BUFSIZ +#define CPPHTTPLIB_RECV_BUFSIZ size_t(4096u) +#endif + +#ifndef CPPHTTPLIB_COMPRESSION_BUFSIZ +#define CPPHTTPLIB_COMPRESSION_BUFSIZ size_t(16384u) +#endif + +#ifndef CPPHTTPLIB_THREAD_POOL_COUNT +#define CPPHTTPLIB_THREAD_POOL_COUNT \ + ((std::max)(8u, std::thread::hardware_concurrency() > 0 \ + ? std::thread::hardware_concurrency() - 1 \ + : 0)) +#endif + +#ifndef CPPHTTPLIB_RECV_FLAGS +#define CPPHTTPLIB_RECV_FLAGS 0 +#endif + +#ifndef CPPHTTPLIB_SEND_FLAGS +#define CPPHTTPLIB_SEND_FLAGS 0 +#endif + +/* + * Headers + */ + +#ifdef _WIN32 +#ifndef _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS +#endif //_CRT_SECURE_NO_WARNINGS + +#ifndef _CRT_NONSTDC_NO_DEPRECATE +#define _CRT_NONSTDC_NO_DEPRECATE +#endif //_CRT_NONSTDC_NO_DEPRECATE + +#if defined(_MSC_VER) +#ifdef _WIN64 +using ssize_t = __int64; +#else +using ssize_t = int; +#endif + +#if _MSC_VER < 1900 +#define snprintf _snprintf_s +#endif +#endif // _MSC_VER + +#ifndef S_ISREG +#define S_ISREG(m) (((m)&S_IFREG) == S_IFREG) +#endif // S_ISREG + +#ifndef S_ISDIR +#define S_ISDIR(m) (((m)&S_IFDIR) == S_IFDIR) +#endif // S_ISDIR + +#ifndef NOMINMAX +#define NOMINMAX +#endif // NOMINMAX + +#include +#include + +#include +#include + +#ifndef WSA_FLAG_NO_HANDLE_INHERIT +#define WSA_FLAG_NO_HANDLE_INHERIT 0x80 +#endif + +#ifdef _MSC_VER +#pragma comment(lib, "ws2_32.lib") +#pragma comment(lib, "crypt32.lib") +#pragma comment(lib, "cryptui.lib") +#endif + +#ifndef strcasecmp +#define strcasecmp _stricmp +#endif // strcasecmp + +using socket_t = SOCKET; +#ifdef CPPHTTPLIB_USE_POLL +#define poll(fds, nfds, timeout) WSAPoll(fds, nfds, timeout) +#endif + +#else // not _WIN32 + +#include +#include +#include +#include +#include +#ifdef __linux__ +#include +#endif +#include +#ifdef CPPHTTPLIB_USE_POLL +#include +#endif +#include +#include +#include +#include +#include + +using socket_t = int; +#ifndef INVALID_SOCKET +#define INVALID_SOCKET (-1) +#endif +#endif //_WIN32 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +#include +#include +#include +#include + +#if defined(_WIN32) && defined(OPENSSL_USE_APPLINK) +#include +#endif + +#include +#include + +#if OPENSSL_VERSION_NUMBER < 0x1010100fL +#error Sorry, OpenSSL versions prior to 1.1.1 are not supported +#endif + +#if OPENSSL_VERSION_NUMBER < 0x10100000L +#include +inline const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *asn1) { + return M_ASN1_STRING_data(asn1); +} +#endif +#endif + +#ifdef CPPHTTPLIB_ZLIB_SUPPORT +#include +#endif + +#ifdef CPPHTTPLIB_BROTLI_SUPPORT +#include +#include +#endif + +/* + * Declaration + */ +namespace httplib { + +namespace detail { + +/* + * Backport std::make_unique from C++14. + * + * NOTE: This code came up with the following stackoverflow post: + * https://stackoverflow.com/questions/10149840/c-arrays-and-make-unique + * + */ + +template +typename std::enable_if::value, std::unique_ptr>::type +make_unique(Args &&... args) { + return std::unique_ptr(new T(std::forward(args)...)); +} + +template +typename std::enable_if::value, std::unique_ptr>::type +make_unique(std::size_t n) { + typedef typename std::remove_extent::type RT; + return std::unique_ptr(new RT[n]); +} + +struct ci { + bool operator()(const std::string &s1, const std::string &s2) const { + return std::lexicographical_compare(s1.begin(), s1.end(), s2.begin(), + s2.end(), + [](unsigned char c1, unsigned char c2) { + return ::tolower(c1) < ::tolower(c2); + }); + } +}; + +} // namespace detail + +using Headers = std::multimap; + +using Params = std::multimap; +using Match = std::smatch; + +using Progress = std::function; + +struct Response; +using ResponseHandler = std::function; + +struct MultipartFormData { + std::string name; + std::string content; + std::string filename; + std::string content_type; +}; +using MultipartFormDataItems = std::vector; +using MultipartFormDataMap = std::multimap; + +class DataSink { +public: + DataSink() : os(&sb_), sb_(*this) {} + + DataSink(const DataSink &) = delete; + DataSink &operator=(const DataSink &) = delete; + DataSink(DataSink &&) = delete; + DataSink &operator=(DataSink &&) = delete; + + std::function write; + std::function done; + std::function is_writable; + std::ostream os; + +private: + class data_sink_streambuf : public std::streambuf { + public: + explicit data_sink_streambuf(DataSink &sink) : sink_(sink) {} + + protected: + std::streamsize xsputn(const char *s, std::streamsize n) { + sink_.write(s, static_cast(n)); + return n; + } + + private: + DataSink &sink_; + }; + + data_sink_streambuf sb_; +}; + +using ContentProvider = + std::function; + +using ContentProviderWithoutLength = + std::function; + +using ContentProviderResourceReleaser = std::function; + +using ContentReceiverWithProgress = + std::function; + +using ContentReceiver = + std::function; + +using MultipartContentHeader = + std::function; + +class ContentReader { +public: + using Reader = std::function; + using MultipartReader = std::function; + + ContentReader(Reader reader, MultipartReader multipart_reader) + : reader_(std::move(reader)), + multipart_reader_(std::move(multipart_reader)) {} + + bool operator()(MultipartContentHeader header, + ContentReceiver receiver) const { + return multipart_reader_(std::move(header), std::move(receiver)); + } + + bool operator()(ContentReceiver receiver) const { + return reader_(std::move(receiver)); + } + + Reader reader_; + MultipartReader multipart_reader_; +}; + +using Range = std::pair; +using Ranges = std::vector; + +struct Request { + std::string method; + std::string path; + Headers headers; + std::string body; + + std::string remote_addr; + int remote_port = -1; + + // for server + std::string version; + std::string target; + Params params; + MultipartFormDataMap files; + Ranges ranges; + Match matches; + + // for client + ResponseHandler response_handler; + ContentReceiverWithProgress content_receiver; + Progress progress; +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + const SSL *ssl = nullptr; +#endif + + bool has_header(const char *key) const; + std::string get_header_value(const char *key, size_t id = 0) const; + template + T get_header_value(const char *key, size_t id = 0) const; + size_t get_header_value_count(const char *key) const; + void set_header(const char *key, const char *val); + void set_header(const char *key, const std::string &val); + + bool has_param(const char *key) const; + std::string get_param_value(const char *key, size_t id = 0) const; + size_t get_param_value_count(const char *key) const; + + bool is_multipart_form_data() const; + + bool has_file(const char *key) const; + MultipartFormData get_file_value(const char *key) const; + + // private members... + size_t redirect_count_ = CPPHTTPLIB_REDIRECT_MAX_COUNT; + size_t content_length_ = 0; + ContentProvider content_provider_; + bool is_chunked_content_provider_ = false; + size_t authorization_count_ = 0; +}; + +struct Response { + std::string version; + int status = -1; + std::string reason; + Headers headers; + std::string body; + std::string location; // Redirect location + + bool has_header(const char *key) const; + std::string get_header_value(const char *key, size_t id = 0) const; + template + T get_header_value(const char *key, size_t id = 0) const; + size_t get_header_value_count(const char *key) const; + void set_header(const char *key, const char *val); + void set_header(const char *key, const std::string &val); + + void set_redirect(const char *url, int status = 302); + void set_redirect(const std::string &url, int status = 302); + void set_content(const char *s, size_t n, const char *content_type); + void set_content(const std::string &s, const char *content_type); + + void set_content_provider( + size_t length, const char *content_type, ContentProvider provider, + ContentProviderResourceReleaser resource_releaser = nullptr); + + void set_content_provider( + const char *content_type, ContentProviderWithoutLength provider, + ContentProviderResourceReleaser resource_releaser = nullptr); + + void set_chunked_content_provider( + const char *content_type, ContentProviderWithoutLength provider, + ContentProviderResourceReleaser resource_releaser = nullptr); + + Response() = default; + Response(const Response &) = default; + Response &operator=(const Response &) = default; + Response(Response &&) = default; + Response &operator=(Response &&) = default; + ~Response() { + if (content_provider_resource_releaser_) { + content_provider_resource_releaser_(content_provider_success_); + } + } + + // private members... + size_t content_length_ = 0; + ContentProvider content_provider_; + ContentProviderResourceReleaser content_provider_resource_releaser_; + bool is_chunked_content_provider_ = false; + bool content_provider_success_ = false; +}; + +class Stream { +public: + virtual ~Stream() = default; + + virtual bool is_readable() const = 0; + virtual bool is_writable() const = 0; + + virtual ssize_t read(char *ptr, size_t size) = 0; + virtual ssize_t write(const char *ptr, size_t size) = 0; + virtual void get_remote_ip_and_port(std::string &ip, int &port) const = 0; + virtual socket_t socket() const = 0; + + template + ssize_t write_format(const char *fmt, const Args &... args); + ssize_t write(const char *ptr); + ssize_t write(const std::string &s); +}; + +class TaskQueue { +public: + TaskQueue() = default; + virtual ~TaskQueue() = default; + + virtual void enqueue(std::function fn) = 0; + virtual void shutdown() = 0; + + virtual void on_idle(){}; +}; + +class ThreadPool : public TaskQueue { +public: + explicit ThreadPool(size_t n) : shutdown_(false) { + while (n) { + threads_.emplace_back(worker(*this)); + n--; + } + } + + ThreadPool(const ThreadPool &) = delete; + ~ThreadPool() override = default; + + void enqueue(std::function fn) override { + std::unique_lock lock(mutex_); + jobs_.push_back(std::move(fn)); + cond_.notify_one(); + } + + void shutdown() override { + // Stop all worker threads... + { + std::unique_lock lock(mutex_); + shutdown_ = true; + } + + cond_.notify_all(); + + // Join... + for (auto &t : threads_) { + t.join(); + } + } + +private: + struct worker { + explicit worker(ThreadPool &pool) : pool_(pool) {} + + void operator()() { + for (;;) { + std::function fn; + { + std::unique_lock lock(pool_.mutex_); + + pool_.cond_.wait( + lock, [&] { return !pool_.jobs_.empty() || pool_.shutdown_; }); + + if (pool_.shutdown_ && pool_.jobs_.empty()) { break; } + + fn = pool_.jobs_.front(); + pool_.jobs_.pop_front(); + } + + assert(true == static_cast(fn)); + fn(); + } + } + + ThreadPool &pool_; + }; + friend struct worker; + + std::vector threads_; + std::list> jobs_; + + bool shutdown_; + + std::condition_variable cond_; + std::mutex mutex_; +}; + +using Logger = std::function; + +using SocketOptions = std::function; + +inline void default_socket_options(socket_t sock) { + int yes = 1; +#ifdef _WIN32 + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast(&yes), + sizeof(yes)); + setsockopt(sock, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, + reinterpret_cast(&yes), sizeof(yes)); +#else +#ifdef SO_REUSEPORT + setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, reinterpret_cast(&yes), + sizeof(yes)); +#else + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast(&yes), + sizeof(yes)); +#endif +#endif +} + +class Server { +public: + using Handler = std::function; + + using ExceptionHandler = + std::function; + + enum class HandlerResponse { + Handled, + Unhandled, + }; + using HandlerWithResponse = + std::function; + + using HandlerWithContentReader = std::function; + + using Expect100ContinueHandler = + std::function; + + Server(); + + virtual ~Server(); + + virtual bool is_valid() const; + + Server &Get(const std::string &pattern, Handler handler); + Server &Post(const std::string &pattern, Handler handler); + Server &Post(const std::string &pattern, HandlerWithContentReader handler); + Server &Put(const std::string &pattern, Handler handler); + Server &Put(const std::string &pattern, HandlerWithContentReader handler); + Server &Patch(const std::string &pattern, Handler handler); + Server &Patch(const std::string &pattern, HandlerWithContentReader handler); + Server &Delete(const std::string &pattern, Handler handler); + Server &Delete(const std::string &pattern, HandlerWithContentReader handler); + Server &Options(const std::string &pattern, Handler handler); + + bool set_base_dir(const std::string &dir, + const std::string &mount_point = nullptr); + bool set_mount_point(const std::string &mount_point, const std::string &dir, + Headers headers = Headers()); + bool remove_mount_point(const std::string &mount_point); + Server &set_file_extension_and_mimetype_mapping(const char *ext, + const char *mime); + Server &set_file_request_handler(Handler handler); + + Server &set_error_handler(HandlerWithResponse handler); + Server &set_error_handler(Handler handler); + Server &set_exception_handler(ExceptionHandler handler); + Server &set_pre_routing_handler(HandlerWithResponse handler); + Server &set_post_routing_handler(Handler handler); + + Server &set_expect_100_continue_handler(Expect100ContinueHandler handler); + Server &set_logger(Logger logger); + + Server &set_address_family(int family); + Server &set_tcp_nodelay(bool on); + Server &set_socket_options(SocketOptions socket_options); + + Server &set_default_headers(Headers headers); + + Server &set_keep_alive_max_count(size_t count); + Server &set_keep_alive_timeout(time_t sec); + + Server &set_read_timeout(time_t sec, time_t usec = 0); + template + Server &set_read_timeout(const std::chrono::duration &duration); + + Server &set_write_timeout(time_t sec, time_t usec = 0); + template + Server &set_write_timeout(const std::chrono::duration &duration); + + Server &set_idle_interval(time_t sec, time_t usec = 0); + template + Server &set_idle_interval(const std::chrono::duration &duration); + + Server &set_payload_max_length(size_t length); + + bool bind_to_port(const char *host, int port, int socket_flags = 0); + int bind_to_any_port(const char *host, int socket_flags = 0); + bool listen_after_bind(); + + bool listen(const char *host, int port, int socket_flags = 0); + + bool is_running() const; + void stop(); + + std::function new_task_queue; + +protected: + bool process_request(Stream &strm, bool close_connection, + bool &connection_closed, + const std::function &setup_request); + + std::atomic svr_sock_; + size_t keep_alive_max_count_ = CPPHTTPLIB_KEEPALIVE_MAX_COUNT; + time_t keep_alive_timeout_sec_ = CPPHTTPLIB_KEEPALIVE_TIMEOUT_SECOND; + time_t read_timeout_sec_ = CPPHTTPLIB_READ_TIMEOUT_SECOND; + time_t read_timeout_usec_ = CPPHTTPLIB_READ_TIMEOUT_USECOND; + time_t write_timeout_sec_ = CPPHTTPLIB_WRITE_TIMEOUT_SECOND; + time_t write_timeout_usec_ = CPPHTTPLIB_WRITE_TIMEOUT_USECOND; + time_t idle_interval_sec_ = CPPHTTPLIB_IDLE_INTERVAL_SECOND; + time_t idle_interval_usec_ = CPPHTTPLIB_IDLE_INTERVAL_USECOND; + size_t payload_max_length_ = CPPHTTPLIB_PAYLOAD_MAX_LENGTH; + +private: + using Handlers = std::vector>; + using HandlersForContentReader = + std::vector>; + + socket_t create_server_socket(const char *host, int port, int socket_flags, + SocketOptions socket_options) const; + int bind_internal(const char *host, int port, int socket_flags); + bool listen_internal(); + + bool routing(Request &req, Response &res, Stream &strm); + bool handle_file_request(const Request &req, Response &res, + bool head = false); + bool dispatch_request(Request &req, Response &res, const Handlers &handlers); + bool + dispatch_request_for_content_reader(Request &req, Response &res, + ContentReader content_reader, + const HandlersForContentReader &handlers); + + bool parse_request_line(const char *s, Request &req); + void apply_ranges(const Request &req, Response &res, + std::string &content_type, std::string &boundary); + bool write_response(Stream &strm, bool close_connection, const Request &req, + Response &res); + bool write_response_with_content(Stream &strm, bool close_connection, + const Request &req, Response &res); + bool write_response_core(Stream &strm, bool close_connection, + const Request &req, Response &res, + bool need_apply_ranges); + bool write_content_with_provider(Stream &strm, const Request &req, + Response &res, const std::string &boundary, + const std::string &content_type); + bool read_content(Stream &strm, Request &req, Response &res); + bool + read_content_with_content_receiver(Stream &strm, Request &req, Response &res, + ContentReceiver receiver, + MultipartContentHeader multipart_header, + ContentReceiver multipart_receiver); + bool read_content_core(Stream &strm, Request &req, Response &res, + ContentReceiver receiver, + MultipartContentHeader mulitpart_header, + ContentReceiver multipart_receiver); + + virtual bool process_and_close_socket(socket_t sock); + + struct MountPointEntry { + std::string mount_point; + std::string base_dir; + Headers headers; + }; + std::vector base_dirs_; + + std::atomic is_running_; + std::map file_extension_and_mimetype_map_; + Handler file_request_handler_; + Handlers get_handlers_; + Handlers post_handlers_; + HandlersForContentReader post_handlers_for_content_reader_; + Handlers put_handlers_; + HandlersForContentReader put_handlers_for_content_reader_; + Handlers patch_handlers_; + HandlersForContentReader patch_handlers_for_content_reader_; + Handlers delete_handlers_; + HandlersForContentReader delete_handlers_for_content_reader_; + Handlers options_handlers_; + HandlerWithResponse error_handler_; + ExceptionHandler exception_handler_; + HandlerWithResponse pre_routing_handler_; + Handler post_routing_handler_; + Logger logger_; + Expect100ContinueHandler expect_100_continue_handler_; + + int address_family_ = AF_UNSPEC; + bool tcp_nodelay_ = CPPHTTPLIB_TCP_NODELAY; + SocketOptions socket_options_ = default_socket_options; + + Headers default_headers_; +}; + +enum class Error { + Success = 0, + Unknown, + Connection, + BindIPAddress, + Read, + Write, + ExceedRedirectCount, + Canceled, + SSLConnection, + SSLLoadingCerts, + SSLServerVerification, + UnsupportedMultipartBoundaryChars, + Compression, +}; + +inline std::string to_string(const Error error) { + switch (error) { + case Error::Success: return "Success"; + case Error::Connection: return "Connection"; + case Error::BindIPAddress: return "BindIPAddress"; + case Error::Read: return "Read"; + case Error::Write: return "Write"; + case Error::ExceedRedirectCount: return "ExceedRedirectCount"; + case Error::Canceled: return "Canceled"; + case Error::SSLConnection: return "SSLConnection"; + case Error::SSLLoadingCerts: return "SSLLoadingCerts"; + case Error::SSLServerVerification: return "SSLServerVerification"; + case Error::UnsupportedMultipartBoundaryChars: + return "UnsupportedMultipartBoundaryChars"; + case Error::Compression: return "Compression"; + case Error::Unknown: return "Unknown"; + default: break; + } + + return "Invalid"; +} + +inline std::ostream &operator<<(std::ostream &os, const Error &obj) { + os << to_string(obj); + os << " (" << static_cast::type>(obj) << ')'; + return os; +} + +class Result { +public: + Result(std::unique_ptr &&res, Error err, + Headers &&request_headers = Headers{}) + : res_(std::move(res)), err_(err), + request_headers_(std::move(request_headers)) {} + // Response + operator bool() const { return res_ != nullptr; } + bool operator==(std::nullptr_t) const { return res_ == nullptr; } + bool operator!=(std::nullptr_t) const { return res_ != nullptr; } + const Response &value() const { return *res_; } + Response &value() { return *res_; } + const Response &operator*() const { return *res_; } + Response &operator*() { return *res_; } + const Response *operator->() const { return res_.get(); } + Response *operator->() { return res_.get(); } + + // Error + Error error() const { return err_; } + + // Request Headers + bool has_request_header(const char *key) const; + std::string get_request_header_value(const char *key, size_t id = 0) const; + template + T get_request_header_value(const char *key, size_t id = 0) const; + size_t get_request_header_value_count(const char *key) const; + +private: + std::unique_ptr res_; + Error err_; + Headers request_headers_; +}; + +class ClientImpl { +public: + explicit ClientImpl(const std::string &host); + + explicit ClientImpl(const std::string &host, int port); + + explicit ClientImpl(const std::string &host, int port, + const std::string &client_cert_path, + const std::string &client_key_path); + + virtual ~ClientImpl(); + + virtual bool is_valid() const; + + Result Get(const char *path); + Result Get(const char *path, const Headers &headers); + Result Get(const char *path, Progress progress); + Result Get(const char *path, const Headers &headers, Progress progress); + Result Get(const char *path, ContentReceiver content_receiver); + Result Get(const char *path, const Headers &headers, + ContentReceiver content_receiver); + Result Get(const char *path, ContentReceiver content_receiver, + Progress progress); + Result Get(const char *path, const Headers &headers, + ContentReceiver content_receiver, Progress progress); + Result Get(const char *path, ResponseHandler response_handler, + ContentReceiver content_receiver); + Result Get(const char *path, const Headers &headers, + ResponseHandler response_handler, + ContentReceiver content_receiver); + Result Get(const char *path, ResponseHandler response_handler, + ContentReceiver content_receiver, Progress progress); + Result Get(const char *path, const Headers &headers, + ResponseHandler response_handler, ContentReceiver content_receiver, + Progress progress); + + Result Get(const char *path, const Params ¶ms, const Headers &headers, + Progress progress = nullptr); + Result Get(const char *path, const Params ¶ms, const Headers &headers, + ContentReceiver content_receiver, Progress progress = nullptr); + Result Get(const char *path, const Params ¶ms, const Headers &headers, + ResponseHandler response_handler, ContentReceiver content_receiver, + Progress progress = nullptr); + + Result Head(const char *path); + Result Head(const char *path, const Headers &headers); + + Result Post(const char *path); + Result Post(const char *path, const char *body, size_t content_length, + const char *content_type); + Result Post(const char *path, const Headers &headers, const char *body, + size_t content_length, const char *content_type); + Result Post(const char *path, const std::string &body, + const char *content_type); + Result Post(const char *path, const Headers &headers, const std::string &body, + const char *content_type); + Result Post(const char *path, size_t content_length, + ContentProvider content_provider, const char *content_type); + Result Post(const char *path, ContentProviderWithoutLength content_provider, + const char *content_type); + Result Post(const char *path, const Headers &headers, size_t content_length, + ContentProvider content_provider, const char *content_type); + Result Post(const char *path, const Headers &headers, + ContentProviderWithoutLength content_provider, + const char *content_type); + Result Post(const char *path, const Params ¶ms); + Result Post(const char *path, const Headers &headers, const Params ¶ms); + Result Post(const char *path, const MultipartFormDataItems &items); + Result Post(const char *path, const Headers &headers, + const MultipartFormDataItems &items); + Result Post(const char *path, const Headers &headers, + const MultipartFormDataItems &items, const std::string &boundary); + + Result Put(const char *path); + Result Put(const char *path, const char *body, size_t content_length, + const char *content_type); + Result Put(const char *path, const Headers &headers, const char *body, + size_t content_length, const char *content_type); + Result Put(const char *path, const std::string &body, + const char *content_type); + Result Put(const char *path, const Headers &headers, const std::string &body, + const char *content_type); + Result Put(const char *path, size_t content_length, + ContentProvider content_provider, const char *content_type); + Result Put(const char *path, ContentProviderWithoutLength content_provider, + const char *content_type); + Result Put(const char *path, const Headers &headers, size_t content_length, + ContentProvider content_provider, const char *content_type); + Result Put(const char *path, const Headers &headers, + ContentProviderWithoutLength content_provider, + const char *content_type); + Result Put(const char *path, const Params ¶ms); + Result Put(const char *path, const Headers &headers, const Params ¶ms); + + Result Patch(const char *path); + Result Patch(const char *path, const char *body, size_t content_length, + const char *content_type); + Result Patch(const char *path, const Headers &headers, const char *body, + size_t content_length, const char *content_type); + Result Patch(const char *path, const std::string &body, + const char *content_type); + Result Patch(const char *path, const Headers &headers, + const std::string &body, const char *content_type); + Result Patch(const char *path, size_t content_length, + ContentProvider content_provider, const char *content_type); + Result Patch(const char *path, ContentProviderWithoutLength content_provider, + const char *content_type); + Result Patch(const char *path, const Headers &headers, size_t content_length, + ContentProvider content_provider, const char *content_type); + Result Patch(const char *path, const Headers &headers, + ContentProviderWithoutLength content_provider, + const char *content_type); + + Result Delete(const char *path); + Result Delete(const char *path, const Headers &headers); + Result Delete(const char *path, const char *body, size_t content_length, + const char *content_type); + Result Delete(const char *path, const Headers &headers, const char *body, + size_t content_length, const char *content_type); + Result Delete(const char *path, const std::string &body, + const char *content_type); + Result Delete(const char *path, const Headers &headers, + const std::string &body, const char *content_type); + + Result Options(const char *path); + Result Options(const char *path, const Headers &headers); + + bool send(Request &req, Response &res, Error &error); + Result send(const Request &req); + + size_t is_socket_open() const; + + void stop(); + + void set_default_headers(Headers headers); + + void set_address_family(int family); + void set_tcp_nodelay(bool on); + void set_socket_options(SocketOptions socket_options); + + void set_connection_timeout(time_t sec, time_t usec = 0); + template + void + set_connection_timeout(const std::chrono::duration &duration); + + void set_read_timeout(time_t sec, time_t usec = 0); + template + void set_read_timeout(const std::chrono::duration &duration); + + void set_write_timeout(time_t sec, time_t usec = 0); + template + void set_write_timeout(const std::chrono::duration &duration); + + void set_basic_auth(const char *username, const char *password); + void set_bearer_token_auth(const char *token); +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + void set_digest_auth(const char *username, const char *password); +#endif + + void set_keep_alive(bool on); + void set_follow_location(bool on); + + void set_url_encode(bool on); + + void set_compress(bool on); + + void set_decompress(bool on); + + void set_interface(const char *intf); + + void set_proxy(const char *host, int port); + void set_proxy_basic_auth(const char *username, const char *password); + void set_proxy_bearer_token_auth(const char *token); +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + void set_proxy_digest_auth(const char *username, const char *password); +#endif + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + void set_ca_cert_path(const char *ca_cert_file_path, + const char *ca_cert_dir_path = nullptr); + void set_ca_cert_store(X509_STORE *ca_cert_store); +#endif + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + void enable_server_certificate_verification(bool enabled); +#endif + + void set_logger(Logger logger); + +protected: + struct Socket { + socket_t sock = INVALID_SOCKET; +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + SSL *ssl = nullptr; +#endif + + bool is_open() const { return sock != INVALID_SOCKET; } + }; + + Result send_(Request &&req); + + virtual bool create_and_connect_socket(Socket &socket, Error &error); + + // All of: + // shutdown_ssl + // shutdown_socket + // close_socket + // should ONLY be called when socket_mutex_ is locked. + // Also, shutdown_ssl and close_socket should also NOT be called concurrently + // with a DIFFERENT thread sending requests using that socket. + virtual void shutdown_ssl(Socket &socket, bool shutdown_gracefully); + void shutdown_socket(Socket &socket); + void close_socket(Socket &socket); + + bool process_request(Stream &strm, Request &req, Response &res, + bool close_connection, Error &error); + + bool write_content_with_provider(Stream &strm, const Request &req, + Error &error); + + void copy_settings(const ClientImpl &rhs); + + // Socket endoint information + const std::string host_; + const int port_; + const std::string host_and_port_; + + // Current open socket + Socket socket_; + mutable std::mutex socket_mutex_; + std::recursive_mutex request_mutex_; + + // These are all protected under socket_mutex + size_t socket_requests_in_flight_ = 0; + std::thread::id socket_requests_are_from_thread_ = std::thread::id(); + bool socket_should_be_closed_when_request_is_done_ = false; + + // Default headers + Headers default_headers_; + + // Settings + std::string client_cert_path_; + std::string client_key_path_; + + time_t connection_timeout_sec_ = CPPHTTPLIB_CONNECTION_TIMEOUT_SECOND; + time_t connection_timeout_usec_ = CPPHTTPLIB_CONNECTION_TIMEOUT_USECOND; + time_t read_timeout_sec_ = CPPHTTPLIB_READ_TIMEOUT_SECOND; + time_t read_timeout_usec_ = CPPHTTPLIB_READ_TIMEOUT_USECOND; + time_t write_timeout_sec_ = CPPHTTPLIB_WRITE_TIMEOUT_SECOND; + time_t write_timeout_usec_ = CPPHTTPLIB_WRITE_TIMEOUT_USECOND; + + std::string basic_auth_username_; + std::string basic_auth_password_; + std::string bearer_token_auth_token_; +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + std::string digest_auth_username_; + std::string digest_auth_password_; +#endif + + bool keep_alive_ = false; + bool follow_location_ = false; + + bool url_encode_ = true; + + int address_family_ = AF_UNSPEC; + bool tcp_nodelay_ = CPPHTTPLIB_TCP_NODELAY; + SocketOptions socket_options_ = nullptr; + + bool compress_ = false; + bool decompress_ = true; + + std::string interface_; + + std::string proxy_host_; + int proxy_port_ = -1; + + std::string proxy_basic_auth_username_; + std::string proxy_basic_auth_password_; + std::string proxy_bearer_token_auth_token_; +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + std::string proxy_digest_auth_username_; + std::string proxy_digest_auth_password_; +#endif + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + std::string ca_cert_file_path_; + std::string ca_cert_dir_path_; + + X509_STORE *ca_cert_store_ = nullptr; +#endif + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + bool server_certificate_verification_ = true; +#endif + + Logger logger_; + +private: + socket_t create_client_socket(Error &error) const; + bool read_response_line(Stream &strm, const Request &req, Response &res); + bool write_request(Stream &strm, Request &req, bool close_connection, + Error &error); + bool redirect(Request &req, Response &res, Error &error); + bool handle_request(Stream &strm, Request &req, Response &res, + bool close_connection, Error &error); + std::unique_ptr send_with_content_provider( + Request &req, + // const char *method, const char *path, const Headers &headers, + const char *body, size_t content_length, ContentProvider content_provider, + ContentProviderWithoutLength content_provider_without_length, + const char *content_type, Error &error); + Result send_with_content_provider( + const char *method, const char *path, const Headers &headers, + const char *body, size_t content_length, ContentProvider content_provider, + ContentProviderWithoutLength content_provider_without_length, + const char *content_type); + + std::string adjust_host_string(const std::string &host) const; + + virtual bool process_socket(const Socket &socket, + std::function callback); + virtual bool is_ssl() const; +}; + +class Client { +public: + // Universal interface + explicit Client(const std::string &scheme_host_port); + + explicit Client(const std::string &scheme_host_port, + const std::string &client_cert_path, + const std::string &client_key_path); + + // HTTP only interface + explicit Client(const std::string &host, int port); + + explicit Client(const std::string &host, int port, + const std::string &client_cert_path, + const std::string &client_key_path); + + ~Client(); + + bool is_valid() const; + + Result Get(const char *path); + Result Get(const char *path, const Headers &headers); + Result Get(const char *path, Progress progress); + Result Get(const char *path, const Headers &headers, Progress progress); + Result Get(const char *path, ContentReceiver content_receiver); + Result Get(const char *path, const Headers &headers, + ContentReceiver content_receiver); + Result Get(const char *path, ContentReceiver content_receiver, + Progress progress); + Result Get(const char *path, const Headers &headers, + ContentReceiver content_receiver, Progress progress); + Result Get(const char *path, ResponseHandler response_handler, + ContentReceiver content_receiver); + Result Get(const char *path, const Headers &headers, + ResponseHandler response_handler, + ContentReceiver content_receiver); + Result Get(const char *path, const Headers &headers, + ResponseHandler response_handler, ContentReceiver content_receiver, + Progress progress); + Result Get(const char *path, ResponseHandler response_handler, + ContentReceiver content_receiver, Progress progress); + + Result Get(const char *path, const Params ¶ms, const Headers &headers, + Progress progress = nullptr); + Result Get(const char *path, const Params ¶ms, const Headers &headers, + ContentReceiver content_receiver, Progress progress = nullptr); + Result Get(const char *path, const Params ¶ms, const Headers &headers, + ResponseHandler response_handler, ContentReceiver content_receiver, + Progress progress = nullptr); + + Result Head(const char *path); + Result Head(const char *path, const Headers &headers); + + Result Post(const char *path); + Result Post(const char *path, const char *body, size_t content_length, + const char *content_type); + Result Post(const char *path, const Headers &headers, const char *body, + size_t content_length, const char *content_type); + Result Post(const char *path, const std::string &body, + const char *content_type); + Result Post(const char *path, const Headers &headers, const std::string &body, + const char *content_type); + Result Post(const char *path, size_t content_length, + ContentProvider content_provider, const char *content_type); + Result Post(const char *path, ContentProviderWithoutLength content_provider, + const char *content_type); + Result Post(const char *path, const Headers &headers, size_t content_length, + ContentProvider content_provider, const char *content_type); + Result Post(const char *path, const Headers &headers, + ContentProviderWithoutLength content_provider, + const char *content_type); + Result Post(const char *path, const Params ¶ms); + Result Post(const char *path, const Headers &headers, const Params ¶ms); + Result Post(const char *path, const MultipartFormDataItems &items); + Result Post(const char *path, const Headers &headers, + const MultipartFormDataItems &items); + Result Post(const char *path, const Headers &headers, + const MultipartFormDataItems &items, const std::string &boundary); + Result Put(const char *path); + Result Put(const char *path, const char *body, size_t content_length, + const char *content_type); + Result Put(const char *path, const Headers &headers, const char *body, + size_t content_length, const char *content_type); + Result Put(const char *path, const std::string &body, + const char *content_type); + Result Put(const char *path, const Headers &headers, const std::string &body, + const char *content_type); + Result Put(const char *path, size_t content_length, + ContentProvider content_provider, const char *content_type); + Result Put(const char *path, ContentProviderWithoutLength content_provider, + const char *content_type); + Result Put(const char *path, const Headers &headers, size_t content_length, + ContentProvider content_provider, const char *content_type); + Result Put(const char *path, const Headers &headers, + ContentProviderWithoutLength content_provider, + const char *content_type); + Result Put(const char *path, const Params ¶ms); + Result Put(const char *path, const Headers &headers, const Params ¶ms); + Result Patch(const char *path); + Result Patch(const char *path, const char *body, size_t content_length, + const char *content_type); + Result Patch(const char *path, const Headers &headers, const char *body, + size_t content_length, const char *content_type); + Result Patch(const char *path, const std::string &body, + const char *content_type); + Result Patch(const char *path, const Headers &headers, + const std::string &body, const char *content_type); + Result Patch(const char *path, size_t content_length, + ContentProvider content_provider, const char *content_type); + Result Patch(const char *path, ContentProviderWithoutLength content_provider, + const char *content_type); + Result Patch(const char *path, const Headers &headers, size_t content_length, + ContentProvider content_provider, const char *content_type); + Result Patch(const char *path, const Headers &headers, + ContentProviderWithoutLength content_provider, + const char *content_type); + + Result Delete(const char *path); + Result Delete(const char *path, const Headers &headers); + Result Delete(const char *path, const char *body, size_t content_length, + const char *content_type); + Result Delete(const char *path, const Headers &headers, const char *body, + size_t content_length, const char *content_type); + Result Delete(const char *path, const std::string &body, + const char *content_type); + Result Delete(const char *path, const Headers &headers, + const std::string &body, const char *content_type); + + Result Options(const char *path); + Result Options(const char *path, const Headers &headers); + + bool send(Request &req, Response &res, Error &error); + Result send(const Request &req); + + size_t is_socket_open() const; + + void stop(); + + void set_default_headers(Headers headers); + + void set_address_family(int family); + void set_tcp_nodelay(bool on); + void set_socket_options(SocketOptions socket_options); + + void set_connection_timeout(time_t sec, time_t usec = 0); + template + void + set_connection_timeout(const std::chrono::duration &duration); + + void set_read_timeout(time_t sec, time_t usec = 0); + template + void set_read_timeout(const std::chrono::duration &duration); + + void set_write_timeout(time_t sec, time_t usec = 0); + template + void set_write_timeout(const std::chrono::duration &duration); + + void set_basic_auth(const char *username, const char *password); + void set_bearer_token_auth(const char *token); +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + void set_digest_auth(const char *username, const char *password); +#endif + + void set_keep_alive(bool on); + void set_follow_location(bool on); + + void set_url_encode(bool on); + + void set_compress(bool on); + + void set_decompress(bool on); + + void set_interface(const char *intf); + + void set_proxy(const char *host, int port); + void set_proxy_basic_auth(const char *username, const char *password); + void set_proxy_bearer_token_auth(const char *token); +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + void set_proxy_digest_auth(const char *username, const char *password); +#endif + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + void enable_server_certificate_verification(bool enabled); +#endif + + void set_logger(Logger logger); + + // SSL +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + void set_ca_cert_path(const char *ca_cert_file_path, + const char *ca_cert_dir_path = nullptr); + + void set_ca_cert_store(X509_STORE *ca_cert_store); + + long get_openssl_verify_result() const; + + SSL_CTX *ssl_context() const; +#endif + +private: + std::unique_ptr cli_; + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + bool is_ssl_ = false; +#endif +}; + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +class SSLServer : public Server { +public: + SSLServer(const char *cert_path, const char *private_key_path, + const char *client_ca_cert_file_path = nullptr, + const char *client_ca_cert_dir_path = nullptr); + + SSLServer(X509 *cert, EVP_PKEY *private_key, + X509_STORE *client_ca_cert_store = nullptr); + + ~SSLServer() override; + + bool is_valid() const override; + +private: + bool process_and_close_socket(socket_t sock) override; + + SSL_CTX *ctx_; + std::mutex ctx_mutex_; +}; + +class SSLClient : public ClientImpl { +public: + explicit SSLClient(const std::string &host); + + explicit SSLClient(const std::string &host, int port); + + explicit SSLClient(const std::string &host, int port, + const std::string &client_cert_path, + const std::string &client_key_path); + + explicit SSLClient(const std::string &host, int port, X509 *client_cert, + EVP_PKEY *client_key); + + ~SSLClient() override; + + bool is_valid() const override; + + void set_ca_cert_store(X509_STORE *ca_cert_store); + + long get_openssl_verify_result() const; + + SSL_CTX *ssl_context() const; + +private: + bool create_and_connect_socket(Socket &socket, Error &error) override; + void shutdown_ssl(Socket &socket, bool shutdown_gracefully) override; + void shutdown_ssl_impl(Socket &socket, bool shutdown_socket); + + bool process_socket(const Socket &socket, + std::function callback) override; + bool is_ssl() const override; + + bool connect_with_proxy(Socket &sock, Response &res, bool &success, + Error &error); + bool initialize_ssl(Socket &socket, Error &error); + + bool load_certs(); + + bool verify_host(X509 *server_cert) const; + bool verify_host_with_subject_alt_name(X509 *server_cert) const; + bool verify_host_with_common_name(X509 *server_cert) const; + bool check_host_name(const char *pattern, size_t pattern_len) const; + + SSL_CTX *ctx_; + std::mutex ctx_mutex_; + std::once_flag initialize_cert_; + + std::vector host_components_; + + long verify_result_ = 0; + + friend class ClientImpl; +}; +#endif + +/* + * Implementation of template methods. + */ + +namespace detail { + +template +inline void duration_to_sec_and_usec(const T &duration, U callback) { + auto sec = std::chrono::duration_cast(duration).count(); + auto usec = std::chrono::duration_cast( + duration - std::chrono::seconds(sec)) + .count(); + callback(sec, usec); +} + +template +inline T get_header_value(const Headers & /*headers*/, const char * /*key*/, + size_t /*id*/ = 0, uint64_t /*def*/ = 0) {} + +template <> +inline uint64_t get_header_value(const Headers &headers, + const char *key, size_t id, + uint64_t def) { + auto rng = headers.equal_range(key); + auto it = rng.first; + std::advance(it, static_cast(id)); + if (it != rng.second) { + return std::strtoull(it->second.data(), nullptr, 10); + } + return def; +} + +} // namespace detail + +template +inline T Request::get_header_value(const char *key, size_t id) const { + return detail::get_header_value(headers, key, id, 0); +} + +template +inline T Response::get_header_value(const char *key, size_t id) const { + return detail::get_header_value(headers, key, id, 0); +} + +template +inline ssize_t Stream::write_format(const char *fmt, const Args &... args) { + const auto bufsiz = 2048; + std::array buf; + +#if defined(_MSC_VER) && _MSC_VER < 1900 + auto sn = _snprintf_s(buf.data(), bufsiz - 1, buf.size() - 1, fmt, args...); +#else + auto sn = snprintf(buf.data(), buf.size() - 1, fmt, args...); +#endif + if (sn <= 0) { return sn; } + + auto n = static_cast(sn); + + if (n >= buf.size() - 1) { + std::vector glowable_buf(buf.size()); + + while (n >= glowable_buf.size() - 1) { + glowable_buf.resize(glowable_buf.size() * 2); +#if defined(_MSC_VER) && _MSC_VER < 1900 + n = static_cast(_snprintf_s(&glowable_buf[0], glowable_buf.size(), + glowable_buf.size() - 1, fmt, + args...)); +#else + n = static_cast( + snprintf(&glowable_buf[0], glowable_buf.size() - 1, fmt, args...)); +#endif + } + return write(&glowable_buf[0], n); + } else { + return write(buf.data(), n); + } +} + +template +inline Server & +Server::set_read_timeout(const std::chrono::duration &duration) { + detail::duration_to_sec_and_usec( + duration, [&](time_t sec, time_t usec) { set_read_timeout(sec, usec); }); + return *this; +} + +template +inline Server & +Server::set_write_timeout(const std::chrono::duration &duration) { + detail::duration_to_sec_and_usec( + duration, [&](time_t sec, time_t usec) { set_write_timeout(sec, usec); }); + return *this; +} + +template +inline Server & +Server::set_idle_interval(const std::chrono::duration &duration) { + detail::duration_to_sec_and_usec( + duration, [&](time_t sec, time_t usec) { set_idle_interval(sec, usec); }); + return *this; +} + +template +inline T Result::get_request_header_value(const char *key, size_t id) const { + return detail::get_header_value(request_headers_, key, id, 0); +} + +template +inline void ClientImpl::set_connection_timeout( + const std::chrono::duration &duration) { + detail::duration_to_sec_and_usec(duration, [&](time_t sec, time_t usec) { + set_connection_timeout(sec, usec); + }); +} + +template +inline void ClientImpl::set_read_timeout( + const std::chrono::duration &duration) { + detail::duration_to_sec_and_usec( + duration, [&](time_t sec, time_t usec) { set_read_timeout(sec, usec); }); +} + +template +inline void ClientImpl::set_write_timeout( + const std::chrono::duration &duration) { + detail::duration_to_sec_and_usec( + duration, [&](time_t sec, time_t usec) { set_write_timeout(sec, usec); }); +} + +template +inline void Client::set_connection_timeout( + const std::chrono::duration &duration) { + cli_->set_connection_timeout(duration); +} + +template +inline void +Client::set_read_timeout(const std::chrono::duration &duration) { + cli_->set_read_timeout(duration); +} + +template +inline void +Client::set_write_timeout(const std::chrono::duration &duration) { + cli_->set_write_timeout(duration); +} + +/* + * Forward declarations and types that will be part of the .h file if split into + * .h + .cc. + */ + +std::pair make_range_header(Ranges ranges); + +std::pair +make_basic_authentication_header(const std::string &username, + const std::string &password, + bool is_proxy = false); + +namespace detail { + +std::string encode_query_param(const std::string &value); + +void read_file(const std::string &path, std::string &out); + +std::string trim_copy(const std::string &s); + +void split(const char *b, const char *e, char d, + std::function fn); + +bool process_client_socket(socket_t sock, time_t read_timeout_sec, + time_t read_timeout_usec, time_t write_timeout_sec, + time_t write_timeout_usec, + std::function callback); + +socket_t create_client_socket(const char *host, int port, int address_family, + bool tcp_nodelay, SocketOptions socket_options, + time_t connection_timeout_sec, + time_t connection_timeout_usec, + time_t read_timeout_sec, time_t read_timeout_usec, + time_t write_timeout_sec, + time_t write_timeout_usec, + const std::string &intf, Error &error); + +const char *get_header_value(const Headers &headers, const char *key, + size_t id = 0, const char *def = nullptr); + +std::string params_to_query_str(const Params ¶ms); + +void parse_query_text(const std::string &s, Params ¶ms); + +bool parse_range_header(const std::string &s, Ranges &ranges); + +int close_socket(socket_t sock); + +enum class EncodingType { None = 0, Gzip, Brotli }; + +EncodingType encoding_type(const Request &req, const Response &res); + +class BufferStream : public Stream { +public: + BufferStream() = default; + ~BufferStream() override = default; + + bool is_readable() const override; + bool is_writable() const override; + ssize_t read(char *ptr, size_t size) override; + ssize_t write(const char *ptr, size_t size) override; + void get_remote_ip_and_port(std::string &ip, int &port) const override; + socket_t socket() const override; + + const std::string &get_buffer() const; + +private: + std::string buffer; + size_t position = 0; +}; + +class compressor { +public: + virtual ~compressor() = default; + + typedef std::function Callback; + virtual bool compress(const char *data, size_t data_length, bool last, + Callback callback) = 0; +}; + +class decompressor { +public: + virtual ~decompressor() = default; + + virtual bool is_valid() const = 0; + + typedef std::function Callback; + virtual bool decompress(const char *data, size_t data_length, + Callback callback) = 0; +}; + +class nocompressor : public compressor { +public: + virtual ~nocompressor() = default; + + bool compress(const char *data, size_t data_length, bool /*last*/, + Callback callback) override; +}; + +#ifdef CPPHTTPLIB_ZLIB_SUPPORT +class gzip_compressor : public compressor { +public: + gzip_compressor(); + ~gzip_compressor(); + + bool compress(const char *data, size_t data_length, bool last, + Callback callback) override; + +private: + bool is_valid_ = false; + z_stream strm_; +}; + +class gzip_decompressor : public decompressor { +public: + gzip_decompressor(); + ~gzip_decompressor(); + + bool is_valid() const override; + + bool decompress(const char *data, size_t data_length, + Callback callback) override; + +private: + bool is_valid_ = false; + z_stream strm_; +}; +#endif + +#ifdef CPPHTTPLIB_BROTLI_SUPPORT +class brotli_compressor : public compressor { +public: + brotli_compressor(); + ~brotli_compressor(); + + bool compress(const char *data, size_t data_length, bool last, + Callback callback) override; + +private: + BrotliEncoderState *state_ = nullptr; +}; + +class brotli_decompressor : public decompressor { +public: + brotli_decompressor(); + ~brotli_decompressor(); + + bool is_valid() const override; + + bool decompress(const char *data, size_t data_length, + Callback callback) override; + +private: + BrotliDecoderResult decoder_r; + BrotliDecoderState *decoder_s = nullptr; +}; +#endif + +// NOTE: until the read size reaches `fixed_buffer_size`, use `fixed_buffer` +// to store data. The call can set memory on stack for performance. +class stream_line_reader { +public: + stream_line_reader(Stream &strm, char *fixed_buffer, + size_t fixed_buffer_size); + const char *ptr() const; + size_t size() const; + bool end_with_crlf() const; + bool getline(); + +private: + void append(char c); + + Stream &strm_; + char *fixed_buffer_; + const size_t fixed_buffer_size_; + size_t fixed_buffer_used_size_ = 0; + std::string glowable_buffer_; +}; + +} // namespace detail + +// ---------------------------------------------------------------------------- + +/* + * Implementation that will be part of the .cc file if split into .h + .cc. + */ + +namespace detail { + +inline bool is_hex(char c, int &v) { + if (0x20 <= c && isdigit(c)) { + v = c - '0'; + return true; + } else if ('A' <= c && c <= 'F') { + v = c - 'A' + 10; + return true; + } else if ('a' <= c && c <= 'f') { + v = c - 'a' + 10; + return true; + } + return false; +} + +inline bool from_hex_to_i(const std::string &s, size_t i, size_t cnt, + int &val) { + if (i >= s.size()) { return false; } + + val = 0; + for (; cnt; i++, cnt--) { + if (!s[i]) { return false; } + int v = 0; + if (is_hex(s[i], v)) { + val = val * 16 + v; + } else { + return false; + } + } + return true; +} + +inline std::string from_i_to_hex(size_t n) { + const char *charset = "0123456789abcdef"; + std::string ret; + do { + ret = charset[n & 15] + ret; + n >>= 4; + } while (n > 0); + return ret; +} + +inline size_t to_utf8(int code, char *buff) { + if (code < 0x0080) { + buff[0] = (code & 0x7F); + return 1; + } else if (code < 0x0800) { + buff[0] = static_cast(0xC0 | ((code >> 6) & 0x1F)); + buff[1] = static_cast(0x80 | (code & 0x3F)); + return 2; + } else if (code < 0xD800) { + buff[0] = static_cast(0xE0 | ((code >> 12) & 0xF)); + buff[1] = static_cast(0x80 | ((code >> 6) & 0x3F)); + buff[2] = static_cast(0x80 | (code & 0x3F)); + return 3; + } else if (code < 0xE000) { // D800 - DFFF is invalid... + return 0; + } else if (code < 0x10000) { + buff[0] = static_cast(0xE0 | ((code >> 12) & 0xF)); + buff[1] = static_cast(0x80 | ((code >> 6) & 0x3F)); + buff[2] = static_cast(0x80 | (code & 0x3F)); + return 3; + } else if (code < 0x110000) { + buff[0] = static_cast(0xF0 | ((code >> 18) & 0x7)); + buff[1] = static_cast(0x80 | ((code >> 12) & 0x3F)); + buff[2] = static_cast(0x80 | ((code >> 6) & 0x3F)); + buff[3] = static_cast(0x80 | (code & 0x3F)); + return 4; + } + + // NOTREACHED + return 0; +} + +// NOTE: This code came up with the following stackoverflow post: +// https://stackoverflow.com/questions/180947/base64-decode-snippet-in-c +inline std::string base64_encode(const std::string &in) { + static const auto lookup = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + std::string out; + out.reserve(in.size()); + + int val = 0; + int valb = -6; + + for (auto c : in) { + val = (val << 8) + static_cast(c); + valb += 8; + while (valb >= 0) { + out.push_back(lookup[(val >> valb) & 0x3F]); + valb -= 6; + } + } + + if (valb > -6) { out.push_back(lookup[((val << 8) >> (valb + 8)) & 0x3F]); } + + while (out.size() % 4) { + out.push_back('='); + } + + return out; +} + +inline bool is_file(const std::string &path) { + struct stat st; + return stat(path.c_str(), &st) >= 0 && S_ISREG(st.st_mode); +} + +inline bool is_dir(const std::string &path) { + struct stat st; + return stat(path.c_str(), &st) >= 0 && S_ISDIR(st.st_mode); +} + +inline bool is_valid_path(const std::string &path) { + size_t level = 0; + size_t i = 0; + + // Skip slash + while (i < path.size() && path[i] == '/') { + i++; + } + + while (i < path.size()) { + // Read component + auto beg = i; + while (i < path.size() && path[i] != '/') { + i++; + } + + auto len = i - beg; + assert(len > 0); + + if (!path.compare(beg, len, ".")) { + ; + } else if (!path.compare(beg, len, "..")) { + if (level == 0) { return false; } + level--; + } else { + level++; + } + + // Skip slash + while (i < path.size() && path[i] == '/') { + i++; + } + } + + return true; +} + +inline std::string encode_query_param(const std::string &value) { + std::ostringstream escaped; + escaped.fill('0'); + escaped << std::hex; + + for (auto c : value) { + if (std::isalnum(static_cast(c)) || c == '-' || c == '_' || + c == '.' || c == '!' || c == '~' || c == '*' || c == '\'' || c == '(' || + c == ')') { + escaped << c; + } else { + escaped << std::uppercase; + escaped << '%' << std::setw(2) + << static_cast(static_cast(c)); + escaped << std::nouppercase; + } + } + + return escaped.str(); +} + +inline std::string encode_url(const std::string &s) { + std::string result; + result.reserve(s.size()); + + for (size_t i = 0; s[i]; i++) { + switch (s[i]) { + case ' ': result += "%20"; break; + case '+': result += "%2B"; break; + case '\r': result += "%0D"; break; + case '\n': result += "%0A"; break; + case '\'': result += "%27"; break; + case ',': result += "%2C"; break; + // case ':': result += "%3A"; break; // ok? probably... + case ';': result += "%3B"; break; + default: + auto c = static_cast(s[i]); + if (c >= 0x80) { + result += '%'; + char hex[4]; + auto len = snprintf(hex, sizeof(hex) - 1, "%02X", c); + assert(len == 2); + result.append(hex, static_cast(len)); + } else { + result += s[i]; + } + break; + } + } + + return result; +} + +inline std::string decode_url(const std::string &s, + bool convert_plus_to_space) { + std::string result; + + for (size_t i = 0; i < s.size(); i++) { + if (s[i] == '%' && i + 1 < s.size()) { + if (s[i + 1] == 'u') { + int val = 0; + if (from_hex_to_i(s, i + 2, 4, val)) { + // 4 digits Unicode codes + char buff[4]; + size_t len = to_utf8(val, buff); + if (len > 0) { result.append(buff, len); } + i += 5; // 'u0000' + } else { + result += s[i]; + } + } else { + int val = 0; + if (from_hex_to_i(s, i + 1, 2, val)) { + // 2 digits hex codes + result += static_cast(val); + i += 2; // '00' + } else { + result += s[i]; + } + } + } else if (convert_plus_to_space && s[i] == '+') { + result += ' '; + } else { + result += s[i]; + } + } + + return result; +} + +inline void read_file(const std::string &path, std::string &out) { + std::ifstream fs(path, std::ios_base::binary); + fs.seekg(0, std::ios_base::end); + auto size = fs.tellg(); + fs.seekg(0); + out.resize(static_cast(size)); + fs.read(&out[0], static_cast(size)); +} + +inline std::string file_extension(const std::string &path) { + std::smatch m; + static auto re = std::regex("\\.([a-zA-Z0-9]+)$"); + if (std::regex_search(path, m, re)) { return m[1].str(); } + return std::string(); +} + +inline bool is_space_or_tab(char c) { return c == ' ' || c == '\t'; } + +inline std::pair trim(const char *b, const char *e, size_t left, + size_t right) { + while (b + left < e && is_space_or_tab(b[left])) { + left++; + } + while (right > 0 && is_space_or_tab(b[right - 1])) { + right--; + } + return std::make_pair(left, right); +} + +inline std::string trim_copy(const std::string &s) { + auto r = trim(s.data(), s.data() + s.size(), 0, s.size()); + return s.substr(r.first, r.second - r.first); +} + +inline void split(const char *b, const char *e, char d, + std::function fn) { + size_t i = 0; + size_t beg = 0; + + while (e ? (b + i < e) : (b[i] != '\0')) { + if (b[i] == d) { + auto r = trim(b, e, beg, i); + if (r.first < r.second) { fn(&b[r.first], &b[r.second]); } + beg = i + 1; + } + i++; + } + + if (i) { + auto r = trim(b, e, beg, i); + if (r.first < r.second) { fn(&b[r.first], &b[r.second]); } + } +} + +inline stream_line_reader::stream_line_reader(Stream &strm, char *fixed_buffer, + size_t fixed_buffer_size) + : strm_(strm), fixed_buffer_(fixed_buffer), + fixed_buffer_size_(fixed_buffer_size) {} + +inline const char *stream_line_reader::ptr() const { + if (glowable_buffer_.empty()) { + return fixed_buffer_; + } else { + return glowable_buffer_.data(); + } +} + +inline size_t stream_line_reader::size() const { + if (glowable_buffer_.empty()) { + return fixed_buffer_used_size_; + } else { + return glowable_buffer_.size(); + } +} + +inline bool stream_line_reader::end_with_crlf() const { + auto end = ptr() + size(); + return size() >= 2 && end[-2] == '\r' && end[-1] == '\n'; +} + +inline bool stream_line_reader::getline() { + fixed_buffer_used_size_ = 0; + glowable_buffer_.clear(); + + for (size_t i = 0;; i++) { + char byte; + auto n = strm_.read(&byte, 1); + + if (n < 0) { + return false; + } else if (n == 0) { + if (i == 0) { + return false; + } else { + break; + } + } + + append(byte); + + if (byte == '\n') { break; } + } + + return true; +} + +inline void stream_line_reader::append(char c) { + if (fixed_buffer_used_size_ < fixed_buffer_size_ - 1) { + fixed_buffer_[fixed_buffer_used_size_++] = c; + fixed_buffer_[fixed_buffer_used_size_] = '\0'; + } else { + if (glowable_buffer_.empty()) { + assert(fixed_buffer_[fixed_buffer_used_size_] == '\0'); + glowable_buffer_.assign(fixed_buffer_, fixed_buffer_used_size_); + } + glowable_buffer_ += c; + } +} + +inline int close_socket(socket_t sock) { +#ifdef _WIN32 + return closesocket(sock); +#else + return close(sock); +#endif +} + +template inline ssize_t handle_EINTR(T fn) { + ssize_t res = false; + while (true) { + res = fn(); + if (res < 0 && errno == EINTR) { continue; } + break; + } + return res; +} + +inline ssize_t select_read(socket_t sock, time_t sec, time_t usec) { +#ifdef CPPHTTPLIB_USE_POLL + struct pollfd pfd_read; + pfd_read.fd = sock; + pfd_read.events = POLLIN; + + auto timeout = static_cast(sec * 1000 + usec / 1000); + + return handle_EINTR([&]() { return poll(&pfd_read, 1, timeout); }); +#else +#ifndef _WIN32 + if (sock >= FD_SETSIZE) { return 1; } +#endif + + fd_set fds; + FD_ZERO(&fds); + FD_SET(sock, &fds); + + timeval tv; + tv.tv_sec = static_cast(sec); + tv.tv_usec = static_cast(usec); + + return handle_EINTR([&]() { + return select(static_cast(sock + 1), &fds, nullptr, nullptr, &tv); + }); +#endif +} + +inline ssize_t select_write(socket_t sock, time_t sec, time_t usec) { +#ifdef CPPHTTPLIB_USE_POLL + struct pollfd pfd_read; + pfd_read.fd = sock; + pfd_read.events = POLLOUT; + + auto timeout = static_cast(sec * 1000 + usec / 1000); + + return handle_EINTR([&]() { return poll(&pfd_read, 1, timeout); }); +#else +#ifndef _WIN32 + if (sock >= FD_SETSIZE) { return 1; } +#endif + + fd_set fds; + FD_ZERO(&fds); + FD_SET(sock, &fds); + + timeval tv; + tv.tv_sec = static_cast(sec); + tv.tv_usec = static_cast(usec); + + return handle_EINTR([&]() { + return select(static_cast(sock + 1), nullptr, &fds, nullptr, &tv); + }); +#endif +} + +inline bool wait_until_socket_is_ready(socket_t sock, time_t sec, time_t usec) { +#ifdef CPPHTTPLIB_USE_POLL + struct pollfd pfd_read; + pfd_read.fd = sock; + pfd_read.events = POLLIN | POLLOUT; + + auto timeout = static_cast(sec * 1000 + usec / 1000); + + auto poll_res = handle_EINTR([&]() { return poll(&pfd_read, 1, timeout); }); + + if (poll_res > 0 && pfd_read.revents & (POLLIN | POLLOUT)) { + int error = 0; + socklen_t len = sizeof(error); + auto res = getsockopt(sock, SOL_SOCKET, SO_ERROR, + reinterpret_cast(&error), &len); + return res >= 0 && !error; + } + return false; +#else +#ifndef _WIN32 + if (sock >= FD_SETSIZE) { return false; } +#endif + + fd_set fdsr; + FD_ZERO(&fdsr); + FD_SET(sock, &fdsr); + + auto fdsw = fdsr; + auto fdse = fdsr; + + timeval tv; + tv.tv_sec = static_cast(sec); + tv.tv_usec = static_cast(usec); + + auto ret = handle_EINTR([&]() { + return select(static_cast(sock + 1), &fdsr, &fdsw, &fdse, &tv); + }); + + if (ret > 0 && (FD_ISSET(sock, &fdsr) || FD_ISSET(sock, &fdsw))) { + int error = 0; + socklen_t len = sizeof(error); + return getsockopt(sock, SOL_SOCKET, SO_ERROR, + reinterpret_cast(&error), &len) >= 0 && + !error; + } + return false; +#endif +} + +class SocketStream : public Stream { +public: + SocketStream(socket_t sock, time_t read_timeout_sec, time_t read_timeout_usec, + time_t write_timeout_sec, time_t write_timeout_usec); + ~SocketStream() override; + + bool is_readable() const override; + bool is_writable() const override; + ssize_t read(char *ptr, size_t size) override; + ssize_t write(const char *ptr, size_t size) override; + void get_remote_ip_and_port(std::string &ip, int &port) const override; + socket_t socket() const override; + +private: + socket_t sock_; + time_t read_timeout_sec_; + time_t read_timeout_usec_; + time_t write_timeout_sec_; + time_t write_timeout_usec_; +}; + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +class SSLSocketStream : public Stream { +public: + SSLSocketStream(socket_t sock, SSL *ssl, time_t read_timeout_sec, + time_t read_timeout_usec, time_t write_timeout_sec, + time_t write_timeout_usec); + ~SSLSocketStream() override; + + bool is_readable() const override; + bool is_writable() const override; + ssize_t read(char *ptr, size_t size) override; + ssize_t write(const char *ptr, size_t size) override; + void get_remote_ip_and_port(std::string &ip, int &port) const override; + socket_t socket() const override; + +private: + socket_t sock_; + SSL *ssl_; + time_t read_timeout_sec_; + time_t read_timeout_usec_; + time_t write_timeout_sec_; + time_t write_timeout_usec_; +}; +#endif + +inline bool keep_alive(socket_t sock, time_t keep_alive_timeout_sec) { + using namespace std::chrono; + auto start = steady_clock::now(); + while (true) { + auto val = select_read(sock, 0, 10000); + if (val < 0) { + return false; + } else if (val == 0) { + auto current = steady_clock::now(); + auto duration = duration_cast(current - start); + auto timeout = keep_alive_timeout_sec * 1000; + if (duration.count() > timeout) { return false; } + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } else { + return true; + } + } +} + +template +inline bool +process_server_socket_core(socket_t sock, size_t keep_alive_max_count, + time_t keep_alive_timeout_sec, T callback) { + assert(keep_alive_max_count > 0); + auto ret = false; + auto count = keep_alive_max_count; + while (count > 0 && keep_alive(sock, keep_alive_timeout_sec)) { + auto close_connection = count == 1; + auto connection_closed = false; + ret = callback(close_connection, connection_closed); + if (!ret || connection_closed) { break; } + count--; + } + return ret; +} + +template +inline bool +process_server_socket(socket_t sock, size_t keep_alive_max_count, + time_t keep_alive_timeout_sec, time_t read_timeout_sec, + time_t read_timeout_usec, time_t write_timeout_sec, + time_t write_timeout_usec, T callback) { + return process_server_socket_core( + sock, keep_alive_max_count, keep_alive_timeout_sec, + [&](bool close_connection, bool &connection_closed) { + SocketStream strm(sock, read_timeout_sec, read_timeout_usec, + write_timeout_sec, write_timeout_usec); + return callback(strm, close_connection, connection_closed); + }); +} + +inline bool process_client_socket(socket_t sock, time_t read_timeout_sec, + time_t read_timeout_usec, + time_t write_timeout_sec, + time_t write_timeout_usec, + std::function callback) { + SocketStream strm(sock, read_timeout_sec, read_timeout_usec, + write_timeout_sec, write_timeout_usec); + return callback(strm); +} + +inline int shutdown_socket(socket_t sock) { +#ifdef _WIN32 + return shutdown(sock, SD_BOTH); +#else + return shutdown(sock, SHUT_RDWR); +#endif +} + +template +socket_t create_socket(const char *host, int port, int address_family, + int socket_flags, bool tcp_nodelay, + SocketOptions socket_options, + BindOrConnect bind_or_connect) { + // Get address info + struct addrinfo hints; + struct addrinfo *result; + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = address_family; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = socket_flags; + hints.ai_protocol = 0; + + auto service = std::to_string(port); + + if (getaddrinfo(host, service.c_str(), &hints, &result)) { +#if defined __linux__ && !defined __ANDROID__ + res_init(); +#endif + return INVALID_SOCKET; + } + + for (auto rp = result; rp; rp = rp->ai_next) { + // Create a socket +#ifdef _WIN32 + auto sock = + WSASocketW(rp->ai_family, rp->ai_socktype, rp->ai_protocol, nullptr, 0, + WSA_FLAG_NO_HANDLE_INHERIT | WSA_FLAG_OVERLAPPED); + /** + * Since the WSA_FLAG_NO_HANDLE_INHERIT is only supported on Windows 7 SP1 + * and above the socket creation fails on older Windows Systems. + * + * Let's try to create a socket the old way in this case. + * + * Reference: + * https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsasocketa + * + * WSA_FLAG_NO_HANDLE_INHERIT: + * This flag is supported on Windows 7 with SP1, Windows Server 2008 R2 with + * SP1, and later + * + */ + if (sock == INVALID_SOCKET) { + sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + } +#else + auto sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); +#endif + if (sock == INVALID_SOCKET) { continue; } + +#ifndef _WIN32 + if (fcntl(sock, F_SETFD, FD_CLOEXEC) == -1) { continue; } +#endif + + if (tcp_nodelay) { + int yes = 1; + setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast(&yes), + sizeof(yes)); + } + + if (socket_options) { socket_options(sock); } + + if (rp->ai_family == AF_INET6) { + int no = 0; + setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, reinterpret_cast(&no), + sizeof(no)); + } + + // bind or connect + if (bind_or_connect(sock, *rp)) { + freeaddrinfo(result); + return sock; + } + + close_socket(sock); + } + + freeaddrinfo(result); + return INVALID_SOCKET; +} + +inline void set_nonblocking(socket_t sock, bool nonblocking) { +#ifdef _WIN32 + auto flags = nonblocking ? 1UL : 0UL; + ioctlsocket(sock, FIONBIO, &flags); +#else + auto flags = fcntl(sock, F_GETFL, 0); + fcntl(sock, F_SETFL, + nonblocking ? (flags | O_NONBLOCK) : (flags & (~O_NONBLOCK))); +#endif +} + +inline bool is_connection_error() { +#ifdef _WIN32 + return WSAGetLastError() != WSAEWOULDBLOCK; +#else + return errno != EINPROGRESS; +#endif +} + +inline bool bind_ip_address(socket_t sock, const char *host) { + struct addrinfo hints; + struct addrinfo *result; + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = 0; + + if (getaddrinfo(host, "0", &hints, &result)) { return false; } + + auto ret = false; + for (auto rp = result; rp; rp = rp->ai_next) { + const auto &ai = *rp; + if (!::bind(sock, ai.ai_addr, static_cast(ai.ai_addrlen))) { + ret = true; + break; + } + } + + freeaddrinfo(result); + return ret; +} + +#if !defined _WIN32 && !defined ANDROID +#define USE_IF2IP +#endif + +#ifdef USE_IF2IP +inline std::string if2ip(const std::string &ifn) { + struct ifaddrs *ifap; + getifaddrs(&ifap); + for (auto ifa = ifap; ifa; ifa = ifa->ifa_next) { + if (ifa->ifa_addr && ifn == ifa->ifa_name) { + if (ifa->ifa_addr->sa_family == AF_INET) { + auto sa = reinterpret_cast(ifa->ifa_addr); + char buf[INET_ADDRSTRLEN]; + if (inet_ntop(AF_INET, &sa->sin_addr, buf, INET_ADDRSTRLEN)) { + freeifaddrs(ifap); + return std::string(buf, INET_ADDRSTRLEN); + } + } + } + } + freeifaddrs(ifap); + return std::string(); +} +#endif + +inline socket_t create_client_socket( + const char *host, int port, int address_family, bool tcp_nodelay, + SocketOptions socket_options, time_t connection_timeout_sec, + time_t connection_timeout_usec, time_t read_timeout_sec, + time_t read_timeout_usec, time_t write_timeout_sec, + time_t write_timeout_usec, const std::string &intf, Error &error) { + auto sock = create_socket( + host, port, address_family, 0, tcp_nodelay, std::move(socket_options), + [&](socket_t sock2, struct addrinfo &ai) -> bool { + if (!intf.empty()) { +#ifdef USE_IF2IP + auto ip = if2ip(intf); + if (ip.empty()) { ip = intf; } + if (!bind_ip_address(sock2, ip.c_str())) { + error = Error::BindIPAddress; + return false; + } +#endif + } + + set_nonblocking(sock2, true); + + auto ret = + ::connect(sock2, ai.ai_addr, static_cast(ai.ai_addrlen)); + + if (ret < 0) { + if (is_connection_error() || + !wait_until_socket_is_ready(sock2, connection_timeout_sec, + connection_timeout_usec)) { + error = Error::Connection; + return false; + } + } + + set_nonblocking(sock2, false); + + { + timeval tv; + tv.tv_sec = static_cast(read_timeout_sec); + tv.tv_usec = static_cast(read_timeout_usec); + setsockopt(sock2, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv)); + } + { + timeval tv; + tv.tv_sec = static_cast(write_timeout_sec); + tv.tv_usec = static_cast(write_timeout_usec); + setsockopt(sock2, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv, sizeof(tv)); + } + + error = Error::Success; + return true; + }); + + if (sock != INVALID_SOCKET) { + error = Error::Success; + } else { + if (error == Error::Success) { error = Error::Connection; } + } + + return sock; +} + +inline void get_remote_ip_and_port(const struct sockaddr_storage &addr, + socklen_t addr_len, std::string &ip, + int &port) { + if (addr.ss_family == AF_INET) { + port = ntohs(reinterpret_cast(&addr)->sin_port); + } else if (addr.ss_family == AF_INET6) { + port = + ntohs(reinterpret_cast(&addr)->sin6_port); + } + + std::array ipstr{}; + if (!getnameinfo(reinterpret_cast(&addr), addr_len, + ipstr.data(), static_cast(ipstr.size()), nullptr, + 0, NI_NUMERICHOST)) { + ip = ipstr.data(); + } +} + +inline void get_remote_ip_and_port(socket_t sock, std::string &ip, int &port) { + struct sockaddr_storage addr; + socklen_t addr_len = sizeof(addr); + + if (!getpeername(sock, reinterpret_cast(&addr), + &addr_len)) { + get_remote_ip_and_port(addr, addr_len, ip, port); + } +} + +inline constexpr unsigned int str2tag_core(const char *s, size_t l, + unsigned int h) { + return (l == 0) ? h + : str2tag_core(s + 1, l - 1, + (h * 33) ^ static_cast(*s)); +} + +inline unsigned int str2tag(const std::string &s) { + return str2tag_core(s.data(), s.size(), 0); +} + +namespace udl { + +inline constexpr unsigned int operator"" _t(const char *s, size_t l) { + return str2tag_core(s, l, 0); +} + +} // namespace udl + +inline const char * +find_content_type(const std::string &path, + const std::map &user_data) { + auto ext = file_extension(path); + + auto it = user_data.find(ext); + if (it != user_data.end()) { return it->second.c_str(); } + + using udl::operator""_t; + + switch (str2tag(ext)) { + default: return nullptr; + case "css"_t: return "text/css"; + case "csv"_t: return "text/csv"; + case "txt"_t: return "text/plain"; + case "vtt"_t: return "text/vtt"; + case "htm"_t: + case "html"_t: return "text/html"; + + case "apng"_t: return "image/apng"; + case "avif"_t: return "image/avif"; + case "bmp"_t: return "image/bmp"; + case "gif"_t: return "image/gif"; + case "png"_t: return "image/png"; + case "svg"_t: return "image/svg+xml"; + case "webp"_t: return "image/webp"; + case "ico"_t: return "image/x-icon"; + case "tif"_t: return "image/tiff"; + case "tiff"_t: return "image/tiff"; + case "jpg"_t: + case "jpeg"_t: return "image/jpeg"; + + case "mp4"_t: return "video/mp4"; + case "mpeg"_t: return "video/mpeg"; + case "webm"_t: return "video/webm"; + + case "mp3"_t: return "audio/mp3"; + case "mpga"_t: return "audio/mpeg"; + case "weba"_t: return "audio/webm"; + case "wav"_t: return "audio/wave"; + + case "otf"_t: return "font/otf"; + case "ttf"_t: return "font/ttf"; + case "woff"_t: return "font/woff"; + case "woff2"_t: return "font/woff2"; + + case "7z"_t: return "application/x-7z-compressed"; + case "atom"_t: return "application/atom+xml"; + case "pdf"_t: return "application/pdf"; + case "js"_t: + case "mjs"_t: return "application/javascript"; + case "json"_t: return "application/json"; + case "rss"_t: return "application/rss+xml"; + case "tar"_t: return "application/x-tar"; + case "xht"_t: + case "xhtml"_t: return "application/xhtml+xml"; + case "xslt"_t: return "application/xslt+xml"; + case "xml"_t: return "application/xml"; + case "gz"_t: return "application/gzip"; + case "zip"_t: return "application/zip"; + case "wasm"_t: return "application/wasm"; + } +} + +inline const char *status_message(int status) { + switch (status) { + case 100: return "Continue"; + case 101: return "Switching Protocol"; + case 102: return "Processing"; + case 103: return "Early Hints"; + case 200: return "OK"; + case 201: return "Created"; + case 202: return "Accepted"; + case 203: return "Non-Authoritative Information"; + case 204: return "No Content"; + case 205: return "Reset Content"; + case 206: return "Partial Content"; + case 207: return "Multi-Status"; + case 208: return "Already Reported"; + case 226: return "IM Used"; + case 300: return "Multiple Choice"; + case 301: return "Moved Permanently"; + case 302: return "Found"; + case 303: return "See Other"; + case 304: return "Not Modified"; + case 305: return "Use Proxy"; + case 306: return "unused"; + case 307: return "Temporary Redirect"; + case 308: return "Permanent Redirect"; + case 400: return "Bad Request"; + case 401: return "Unauthorized"; + case 402: return "Payment Required"; + case 403: return "Forbidden"; + case 404: return "Not Found"; + case 405: return "Method Not Allowed"; + case 406: return "Not Acceptable"; + case 407: return "Proxy Authentication Required"; + case 408: return "Request Timeout"; + case 409: return "Conflict"; + case 410: return "Gone"; + case 411: return "Length Required"; + case 412: return "Precondition Failed"; + case 413: return "Payload Too Large"; + case 414: return "URI Too Long"; + case 415: return "Unsupported Media Type"; + case 416: return "Range Not Satisfiable"; + case 417: return "Expectation Failed"; + case 418: return "I'm a teapot"; + case 421: return "Misdirected Request"; + case 422: return "Unprocessable Entity"; + case 423: return "Locked"; + case 424: return "Failed Dependency"; + case 425: return "Too Early"; + case 426: return "Upgrade Required"; + case 428: return "Precondition Required"; + case 429: return "Too Many Requests"; + case 431: return "Request Header Fields Too Large"; + case 451: return "Unavailable For Legal Reasons"; + case 501: return "Not Implemented"; + case 502: return "Bad Gateway"; + case 503: return "Service Unavailable"; + case 504: return "Gateway Timeout"; + case 505: return "HTTP Version Not Supported"; + case 506: return "Variant Also Negotiates"; + case 507: return "Insufficient Storage"; + case 508: return "Loop Detected"; + case 510: return "Not Extended"; + case 511: return "Network Authentication Required"; + + default: + case 500: return "Internal Server Error"; + } +} + +inline bool can_compress_content_type(const std::string &content_type) { + return (!content_type.find("text/") && content_type != "text/event-stream") || + content_type == "image/svg+xml" || + content_type == "application/javascript" || + content_type == "application/json" || + content_type == "application/xml" || + content_type == "application/xhtml+xml"; +} + +inline EncodingType encoding_type(const Request &req, const Response &res) { + auto ret = + detail::can_compress_content_type(res.get_header_value("Content-Type")); + if (!ret) { return EncodingType::None; } + + const auto &s = req.get_header_value("Accept-Encoding"); + (void)(s); + +#ifdef CPPHTTPLIB_BROTLI_SUPPORT + // TODO: 'Accept-Encoding' has br, not br;q=0 + ret = s.find("br") != std::string::npos; + if (ret) { return EncodingType::Brotli; } +#endif + +#ifdef CPPHTTPLIB_ZLIB_SUPPORT + // TODO: 'Accept-Encoding' has gzip, not gzip;q=0 + ret = s.find("gzip") != std::string::npos; + if (ret) { return EncodingType::Gzip; } +#endif + + return EncodingType::None; +} + +inline bool nocompressor::compress(const char *data, size_t data_length, + bool /*last*/, Callback callback) { + if (!data_length) { return true; } + return callback(data, data_length); +} + +#ifdef CPPHTTPLIB_ZLIB_SUPPORT +inline gzip_compressor::gzip_compressor() { + std::memset(&strm_, 0, sizeof(strm_)); + strm_.zalloc = Z_NULL; + strm_.zfree = Z_NULL; + strm_.opaque = Z_NULL; + + is_valid_ = deflateInit2(&strm_, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 31, 8, + Z_DEFAULT_STRATEGY) == Z_OK; +} + +inline gzip_compressor::~gzip_compressor() { deflateEnd(&strm_); } + +inline bool gzip_compressor::compress(const char *data, size_t data_length, + bool last, Callback callback) { + assert(is_valid_); + + do { + constexpr size_t max_avail_in = + std::numeric_limits::max(); + + strm_.avail_in = static_cast( + std::min(data_length, max_avail_in)); + strm_.next_in = const_cast(reinterpret_cast(data)); + + data_length -= strm_.avail_in; + data += strm_.avail_in; + + auto flush = (last && data_length == 0) ? Z_FINISH : Z_NO_FLUSH; + int ret = Z_OK; + + std::array buff{}; + do { + strm_.avail_out = static_cast(buff.size()); + strm_.next_out = reinterpret_cast(buff.data()); + + ret = deflate(&strm_, flush); + if (ret == Z_STREAM_ERROR) { return false; } + + if (!callback(buff.data(), buff.size() - strm_.avail_out)) { + return false; + } + } while (strm_.avail_out == 0); + + assert((flush == Z_FINISH && ret == Z_STREAM_END) || + (flush == Z_NO_FLUSH && ret == Z_OK)); + assert(strm_.avail_in == 0); + + } while (data_length > 0); + + return true; +} + +inline gzip_decompressor::gzip_decompressor() { + std::memset(&strm_, 0, sizeof(strm_)); + strm_.zalloc = Z_NULL; + strm_.zfree = Z_NULL; + strm_.opaque = Z_NULL; + + // 15 is the value of wbits, which should be at the maximum possible value + // to ensure that any gzip stream can be decoded. The offset of 32 specifies + // that the stream type should be automatically detected either gzip or + // deflate. + is_valid_ = inflateInit2(&strm_, 32 + 15) == Z_OK; +} + +inline gzip_decompressor::~gzip_decompressor() { inflateEnd(&strm_); } + +inline bool gzip_decompressor::is_valid() const { return is_valid_; } + +inline bool gzip_decompressor::decompress(const char *data, size_t data_length, + Callback callback) { + assert(is_valid_); + + int ret = Z_OK; + + do { + constexpr size_t max_avail_in = + std::numeric_limits::max(); + + strm_.avail_in = static_cast( + std::min(data_length, max_avail_in)); + strm_.next_in = const_cast(reinterpret_cast(data)); + + data_length -= strm_.avail_in; + data += strm_.avail_in; + + std::array buff{}; + while (strm_.avail_in > 0) { + strm_.avail_out = static_cast(buff.size()); + strm_.next_out = reinterpret_cast(buff.data()); + + ret = inflate(&strm_, Z_NO_FLUSH); + assert(ret != Z_STREAM_ERROR); + switch (ret) { + case Z_NEED_DICT: + case Z_DATA_ERROR: + case Z_MEM_ERROR: inflateEnd(&strm_); return false; + } + + if (!callback(buff.data(), buff.size() - strm_.avail_out)) { + return false; + } + } + + if (ret != Z_OK && ret != Z_STREAM_END) return false; + + } while (data_length > 0); + + return true; +} +#endif + +#ifdef CPPHTTPLIB_BROTLI_SUPPORT +inline brotli_compressor::brotli_compressor() { + state_ = BrotliEncoderCreateInstance(nullptr, nullptr, nullptr); +} + +inline brotli_compressor::~brotli_compressor() { + BrotliEncoderDestroyInstance(state_); +} + +inline bool brotli_compressor::compress(const char *data, size_t data_length, + bool last, Callback callback) { + std::array buff{}; + + auto operation = last ? BROTLI_OPERATION_FINISH : BROTLI_OPERATION_PROCESS; + auto available_in = data_length; + auto next_in = reinterpret_cast(data); + + for (;;) { + if (last) { + if (BrotliEncoderIsFinished(state_)) { break; } + } else { + if (!available_in) { break; } + } + + auto available_out = buff.size(); + auto next_out = buff.data(); + + if (!BrotliEncoderCompressStream(state_, operation, &available_in, &next_in, + &available_out, &next_out, nullptr)) { + return false; + } + + auto output_bytes = buff.size() - available_out; + if (output_bytes) { + callback(reinterpret_cast(buff.data()), output_bytes); + } + } + + return true; +} + +inline brotli_decompressor::brotli_decompressor() { + decoder_s = BrotliDecoderCreateInstance(0, 0, 0); + decoder_r = decoder_s ? BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT + : BROTLI_DECODER_RESULT_ERROR; +} + +inline brotli_decompressor::~brotli_decompressor() { + if (decoder_s) { BrotliDecoderDestroyInstance(decoder_s); } +} + +inline bool brotli_decompressor::is_valid() const { return decoder_s; } + +inline bool brotli_decompressor::decompress(const char *data, + size_t data_length, + Callback callback) { + if (decoder_r == BROTLI_DECODER_RESULT_SUCCESS || + decoder_r == BROTLI_DECODER_RESULT_ERROR) { + return 0; + } + + const uint8_t *next_in = (const uint8_t *)data; + size_t avail_in = data_length; + size_t total_out; + + decoder_r = BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT; + + std::array buff{}; + while (decoder_r == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) { + char *next_out = buff.data(); + size_t avail_out = buff.size(); + + decoder_r = BrotliDecoderDecompressStream( + decoder_s, &avail_in, &next_in, &avail_out, + reinterpret_cast(&next_out), &total_out); + + if (decoder_r == BROTLI_DECODER_RESULT_ERROR) { return false; } + + if (!callback(buff.data(), buff.size() - avail_out)) { return false; } + } + + return decoder_r == BROTLI_DECODER_RESULT_SUCCESS || + decoder_r == BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT; +} +#endif + +inline bool has_header(const Headers &headers, const char *key) { + return headers.find(key) != headers.end(); +} + +inline const char *get_header_value(const Headers &headers, const char *key, + size_t id, const char *def) { + auto rng = headers.equal_range(key); + auto it = rng.first; + std::advance(it, static_cast(id)); + if (it != rng.second) { return it->second.c_str(); } + return def; +} + +template +inline bool parse_header(const char *beg, const char *end, T fn) { + // Skip trailing spaces and tabs. + while (beg < end && is_space_or_tab(end[-1])) { + end--; + } + + auto p = beg; + while (p < end && *p != ':') { + p++; + } + + if (p == end) { return false; } + + auto key_end = p; + + if (*p++ != ':') { return false; } + + while (p < end && is_space_or_tab(*p)) { + p++; + } + + if (p < end) { + fn(std::string(beg, key_end), decode_url(std::string(p, end), false)); + return true; + } + + return false; +} + +inline bool read_headers(Stream &strm, Headers &headers) { + const auto bufsiz = 2048; + char buf[bufsiz]; + stream_line_reader line_reader(strm, buf, bufsiz); + + for (;;) { + if (!line_reader.getline()) { return false; } + + // Check if the line ends with CRLF. + if (line_reader.end_with_crlf()) { + // Blank line indicates end of headers. + if (line_reader.size() == 2) { break; } + } else { + continue; // Skip invalid line. + } + + // Exclude CRLF + auto end = line_reader.ptr() + line_reader.size() - 2; + + parse_header(line_reader.ptr(), end, + [&](std::string &&key, std::string &&val) { + headers.emplace(std::move(key), std::move(val)); + }); + } + + return true; +} + +inline bool read_content_with_length(Stream &strm, uint64_t len, + Progress progress, + ContentReceiverWithProgress out) { + char buf[CPPHTTPLIB_RECV_BUFSIZ]; + + uint64_t r = 0; + while (r < len) { + auto read_len = static_cast(len - r); + auto n = strm.read(buf, (std::min)(read_len, CPPHTTPLIB_RECV_BUFSIZ)); + if (n <= 0) { return false; } + + if (!out(buf, static_cast(n), r, len)) { return false; } + r += static_cast(n); + + if (progress) { + if (!progress(r, len)) { return false; } + } + } + + return true; +} + +inline void skip_content_with_length(Stream &strm, uint64_t len) { + char buf[CPPHTTPLIB_RECV_BUFSIZ]; + uint64_t r = 0; + while (r < len) { + auto read_len = static_cast(len - r); + auto n = strm.read(buf, (std::min)(read_len, CPPHTTPLIB_RECV_BUFSIZ)); + if (n <= 0) { return; } + r += static_cast(n); + } +} + +inline bool read_content_without_length(Stream &strm, + ContentReceiverWithProgress out) { + char buf[CPPHTTPLIB_RECV_BUFSIZ]; + uint64_t r = 0; + for (;;) { + auto n = strm.read(buf, CPPHTTPLIB_RECV_BUFSIZ); + if (n < 0) { + return false; + } else if (n == 0) { + return true; + } + + if (!out(buf, static_cast(n), r, 0)) { return false; } + r += static_cast(n); + } + + return true; +} + +inline bool read_content_chunked(Stream &strm, + ContentReceiverWithProgress out) { + const auto bufsiz = 16; + char buf[bufsiz]; + + stream_line_reader line_reader(strm, buf, bufsiz); + + if (!line_reader.getline()) { return false; } + + unsigned long chunk_len; + while (true) { + char *end_ptr; + + chunk_len = std::strtoul(line_reader.ptr(), &end_ptr, 16); + + if (end_ptr == line_reader.ptr()) { return false; } + if (chunk_len == ULONG_MAX) { return false; } + + if (chunk_len == 0) { break; } + + if (!read_content_with_length(strm, chunk_len, nullptr, out)) { + return false; + } + + if (!line_reader.getline()) { return false; } + + if (strcmp(line_reader.ptr(), "\r\n")) { break; } + + if (!line_reader.getline()) { return false; } + } + + if (chunk_len == 0) { + // Reader terminator after chunks + if (!line_reader.getline() || strcmp(line_reader.ptr(), "\r\n")) + return false; + } + + return true; +} + +inline bool is_chunked_transfer_encoding(const Headers &headers) { + return !strcasecmp(get_header_value(headers, "Transfer-Encoding", 0, ""), + "chunked"); +} + +template +bool prepare_content_receiver(T &x, int &status, + ContentReceiverWithProgress receiver, + bool decompress, U callback) { + if (decompress) { + std::string encoding = x.get_header_value("Content-Encoding"); + std::unique_ptr decompressor; + + if (encoding.find("gzip") != std::string::npos || + encoding.find("deflate") != std::string::npos) { +#ifdef CPPHTTPLIB_ZLIB_SUPPORT + decompressor = detail::make_unique(); +#else + status = 415; + return false; +#endif + } else if (encoding.find("br") != std::string::npos) { +#ifdef CPPHTTPLIB_BROTLI_SUPPORT + decompressor = detail::make_unique(); +#else + status = 415; + return false; +#endif + } + + if (decompressor) { + if (decompressor->is_valid()) { + ContentReceiverWithProgress out = [&](const char *buf, size_t n, + uint64_t off, uint64_t len) { + return decompressor->decompress(buf, n, + [&](const char *buf2, size_t n2) { + return receiver(buf2, n2, off, len); + }); + }; + return callback(std::move(out)); + } else { + status = 500; + return false; + } + } + } + + ContentReceiverWithProgress out = [&](const char *buf, size_t n, uint64_t off, + uint64_t len) { + return receiver(buf, n, off, len); + }; + return callback(std::move(out)); +} + +template +bool read_content(Stream &strm, T &x, size_t payload_max_length, int &status, + Progress progress, ContentReceiverWithProgress receiver, + bool decompress) { + return prepare_content_receiver( + x, status, std::move(receiver), decompress, + [&](const ContentReceiverWithProgress &out) { + auto ret = true; + auto exceed_payload_max_length = false; + + if (is_chunked_transfer_encoding(x.headers)) { + ret = read_content_chunked(strm, out); + } else if (!has_header(x.headers, "Content-Length")) { + ret = read_content_without_length(strm, out); + } else { + auto len = get_header_value(x.headers, "Content-Length"); + if (len > payload_max_length) { + exceed_payload_max_length = true; + skip_content_with_length(strm, len); + ret = false; + } else if (len > 0) { + ret = read_content_with_length(strm, len, std::move(progress), out); + } + } + + if (!ret) { status = exceed_payload_max_length ? 413 : 400; } + return ret; + }); +} + +inline ssize_t write_headers(Stream &strm, const Headers &headers) { + ssize_t write_len = 0; + for (const auto &x : headers) { + auto len = + strm.write_format("%s: %s\r\n", x.first.c_str(), x.second.c_str()); + if (len < 0) { return len; } + write_len += len; + } + auto len = strm.write("\r\n"); + if (len < 0) { return len; } + write_len += len; + return write_len; +} + +inline bool write_data(Stream &strm, const char *d, size_t l) { + size_t offset = 0; + while (offset < l) { + auto length = strm.write(d + offset, l - offset); + if (length < 0) { return false; } + offset += static_cast(length); + } + return true; +} + +template +inline bool write_content(Stream &strm, const ContentProvider &content_provider, + size_t offset, size_t length, T is_shutting_down, + Error &error) { + size_t end_offset = offset + length; + auto ok = true; + DataSink data_sink; + + data_sink.write = [&](const char *d, size_t l) -> bool { + if (ok) { + if (write_data(strm, d, l)) { + offset += l; + } else { + ok = false; + } + } + return ok; + }; + + data_sink.is_writable = [&](void) { return ok && strm.is_writable(); }; + + while (offset < end_offset && !is_shutting_down()) { + if (!content_provider(offset, end_offset - offset, data_sink)) { + error = Error::Canceled; + return false; + } + if (!ok) { + error = Error::Write; + return false; + } + } + + error = Error::Success; + return true; +} + +template +inline bool write_content(Stream &strm, const ContentProvider &content_provider, + size_t offset, size_t length, + const T &is_shutting_down) { + auto error = Error::Success; + return write_content(strm, content_provider, offset, length, is_shutting_down, + error); +} + +template +inline bool +write_content_without_length(Stream &strm, + const ContentProvider &content_provider, + const T &is_shutting_down) { + size_t offset = 0; + auto data_available = true; + auto ok = true; + DataSink data_sink; + + data_sink.write = [&](const char *d, size_t l) -> bool { + if (ok) { + offset += l; + if (!write_data(strm, d, l)) { ok = false; } + } + return ok; + }; + + data_sink.done = [&](void) { data_available = false; }; + + data_sink.is_writable = [&](void) { return ok && strm.is_writable(); }; + + while (data_available && !is_shutting_down()) { + if (!content_provider(offset, 0, data_sink)) { return false; } + if (!ok) { return false; } + } + return true; +} + +template +inline bool +write_content_chunked(Stream &strm, const ContentProvider &content_provider, + const T &is_shutting_down, U &compressor, Error &error) { + size_t offset = 0; + auto data_available = true; + auto ok = true; + DataSink data_sink; + + data_sink.write = [&](const char *d, size_t l) -> bool { + if (ok) { + data_available = l > 0; + offset += l; + + std::string payload; + if (compressor.compress(d, l, false, + [&](const char *data, size_t data_len) { + payload.append(data, data_len); + return true; + })) { + if (!payload.empty()) { + // Emit chunked response header and footer for each chunk + auto chunk = + from_i_to_hex(payload.size()) + "\r\n" + payload + "\r\n"; + if (!write_data(strm, chunk.data(), chunk.size())) { ok = false; } + } + } else { + ok = false; + } + } + return ok; + }; + + data_sink.done = [&](void) { + if (!ok) { return; } + + data_available = false; + + std::string payload; + if (!compressor.compress(nullptr, 0, true, + [&](const char *data, size_t data_len) { + payload.append(data, data_len); + return true; + })) { + ok = false; + return; + } + + if (!payload.empty()) { + // Emit chunked response header and footer for each chunk + auto chunk = from_i_to_hex(payload.size()) + "\r\n" + payload + "\r\n"; + if (!write_data(strm, chunk.data(), chunk.size())) { + ok = false; + return; + } + } + + static const std::string done_marker("0\r\n\r\n"); + if (!write_data(strm, done_marker.data(), done_marker.size())) { + ok = false; + } + }; + + data_sink.is_writable = [&](void) { return ok && strm.is_writable(); }; + + while (data_available && !is_shutting_down()) { + if (!content_provider(offset, 0, data_sink)) { + error = Error::Canceled; + return false; + } + if (!ok) { + error = Error::Write; + return false; + } + } + + error = Error::Success; + return true; +} + +template +inline bool write_content_chunked(Stream &strm, + const ContentProvider &content_provider, + const T &is_shutting_down, U &compressor) { + auto error = Error::Success; + return write_content_chunked(strm, content_provider, is_shutting_down, + compressor, error); +} + +template +inline bool redirect(T &cli, Request &req, Response &res, + const std::string &path, const std::string &location, + Error &error) { + Request new_req = req; + new_req.path = path; + new_req.redirect_count_ -= 1; + + if (res.status == 303 && (req.method != "GET" && req.method != "HEAD")) { + new_req.method = "GET"; + new_req.body.clear(); + new_req.headers.clear(); + } + + Response new_res; + + auto ret = cli.send(new_req, new_res, error); + if (ret) { + req = new_req; + res = new_res; + res.location = location; + } + return ret; +} + +inline std::string params_to_query_str(const Params ¶ms) { + std::string query; + + for (auto it = params.begin(); it != params.end(); ++it) { + if (it != params.begin()) { query += "&"; } + query += it->first; + query += "="; + query += encode_query_param(it->second); + } + return query; +} + +inline std::string append_query_params(const char *path, const Params ¶ms) { + std::string path_with_query = path; + const static std::regex re("[^?]+\\?.*"); + auto delm = std::regex_match(path, re) ? '&' : '?'; + path_with_query += delm + params_to_query_str(params); + return path_with_query; +} + +inline void parse_query_text(const std::string &s, Params ¶ms) { + std::set cache; + split(s.data(), s.data() + s.size(), '&', [&](const char *b, const char *e) { + std::string kv(b, e); + if (cache.find(kv) != cache.end()) { return; } + cache.insert(kv); + + std::string key; + std::string val; + split(b, e, '=', [&](const char *b2, const char *e2) { + if (key.empty()) { + key.assign(b2, e2); + } else { + val.assign(b2, e2); + } + }); + + if (!key.empty()) { + params.emplace(decode_url(key, true), decode_url(val, true)); + } + }); +} + +inline bool parse_multipart_boundary(const std::string &content_type, + std::string &boundary) { + auto pos = content_type.find("boundary="); + if (pos == std::string::npos) { return false; } + boundary = content_type.substr(pos + 9); + if (boundary.length() >= 2 && boundary.front() == '"' && + boundary.back() == '"') { + boundary = boundary.substr(1, boundary.size() - 2); + } + return !boundary.empty(); +} + +inline bool parse_range_header(const std::string &s, Ranges &ranges) try { + static auto re_first_range = std::regex(R"(bytes=(\d*-\d*(?:,\s*\d*-\d*)*))"); + std::smatch m; + if (std::regex_match(s, m, re_first_range)) { + auto pos = static_cast(m.position(1)); + auto len = static_cast(m.length(1)); + bool all_valid_ranges = true; + split(&s[pos], &s[pos + len], ',', [&](const char *b, const char *e) { + if (!all_valid_ranges) return; + static auto re_another_range = std::regex(R"(\s*(\d*)-(\d*))"); + std::cmatch cm; + if (std::regex_match(b, e, cm, re_another_range)) { + ssize_t first = -1; + if (!cm.str(1).empty()) { + first = static_cast(std::stoll(cm.str(1))); + } + + ssize_t last = -1; + if (!cm.str(2).empty()) { + last = static_cast(std::stoll(cm.str(2))); + } + + if (first != -1 && last != -1 && first > last) { + all_valid_ranges = false; + return; + } + ranges.emplace_back(std::make_pair(first, last)); + } + }); + return all_valid_ranges; + } + return false; +} catch (...) { return false; } + +class MultipartFormDataParser { +public: + MultipartFormDataParser() = default; + + void set_boundary(std::string &&boundary) { boundary_ = boundary; } + + bool is_valid() const { return is_valid_; } + + bool parse(const char *buf, size_t n, const ContentReceiver &content_callback, + const MultipartContentHeader &header_callback) { + + static const std::regex re_content_disposition( + "^Content-Disposition:\\s*form-data;\\s*name=\"(.*?)\"(?:;\\s*filename=" + "\"(.*?)\")?\\s*$", + std::regex_constants::icase); + static const std::string dash_ = "--"; + static const std::string crlf_ = "\r\n"; + + buf_.append(buf, n); // TODO: performance improvement + + while (!buf_.empty()) { + switch (state_) { + case 0: { // Initial boundary + auto pattern = dash_ + boundary_ + crlf_; + if (pattern.size() > buf_.size()) { return true; } + auto pos = buf_.find(pattern); + if (pos != 0) { return false; } + buf_.erase(0, pattern.size()); + off_ += pattern.size(); + state_ = 1; + break; + } + case 1: { // New entry + clear_file_info(); + state_ = 2; + break; + } + case 2: { // Headers + auto pos = buf_.find(crlf_); + while (pos != std::string::npos) { + // Empty line + if (pos == 0) { + if (!header_callback(file_)) { + is_valid_ = false; + return false; + } + buf_.erase(0, crlf_.size()); + off_ += crlf_.size(); + state_ = 3; + break; + } + + static const std::string header_name = "content-type:"; + const auto header = buf_.substr(0, pos); + if (start_with_case_ignore(header, header_name)) { + file_.content_type = trim_copy(header.substr(header_name.size())); + } else { + std::smatch m; + if (std::regex_match(header, m, re_content_disposition)) { + file_.name = m[1]; + file_.filename = m[2]; + } + } + + buf_.erase(0, pos + crlf_.size()); + off_ += pos + crlf_.size(); + pos = buf_.find(crlf_); + } + if (state_ != 3) { return true; } + break; + } + case 3: { // Body + { + auto pattern = crlf_ + dash_; + if (pattern.size() > buf_.size()) { return true; } + + auto pos = find_string(buf_, pattern); + + if (!content_callback(buf_.data(), pos)) { + is_valid_ = false; + return false; + } + + off_ += pos; + buf_.erase(0, pos); + } + { + auto pattern = crlf_ + dash_ + boundary_; + if (pattern.size() > buf_.size()) { return true; } + + auto pos = buf_.find(pattern); + if (pos != std::string::npos) { + if (!content_callback(buf_.data(), pos)) { + is_valid_ = false; + return false; + } + + off_ += pos + pattern.size(); + buf_.erase(0, pos + pattern.size()); + state_ = 4; + } else { + if (!content_callback(buf_.data(), pattern.size())) { + is_valid_ = false; + return false; + } + + off_ += pattern.size(); + buf_.erase(0, pattern.size()); + } + } + break; + } + case 4: { // Boundary + if (crlf_.size() > buf_.size()) { return true; } + if (buf_.compare(0, crlf_.size(), crlf_) == 0) { + buf_.erase(0, crlf_.size()); + off_ += crlf_.size(); + state_ = 1; + } else { + auto pattern = dash_ + crlf_; + if (pattern.size() > buf_.size()) { return true; } + if (buf_.compare(0, pattern.size(), pattern) == 0) { + buf_.erase(0, pattern.size()); + off_ += pattern.size(); + is_valid_ = true; + state_ = 5; + } else { + return true; + } + } + break; + } + case 5: { // Done + is_valid_ = false; + return false; + } + } + } + + return true; + } + +private: + void clear_file_info() { + file_.name.clear(); + file_.filename.clear(); + file_.content_type.clear(); + } + + bool start_with_case_ignore(const std::string &a, + const std::string &b) const { + if (a.size() < b.size()) { return false; } + for (size_t i = 0; i < b.size(); i++) { + if (::tolower(a[i]) != ::tolower(b[i])) { return false; } + } + return true; + } + + bool start_with(const std::string &a, size_t off, + const std::string &b) const { + if (a.size() - off < b.size()) { return false; } + for (size_t i = 0; i < b.size(); i++) { + if (a[i + off] != b[i]) { return false; } + } + return true; + } + + size_t find_string(const std::string &s, const std::string &pattern) const { + auto c = pattern.front(); + + size_t off = 0; + while (off < s.size()) { + auto pos = s.find(c, off); + if (pos == std::string::npos) { return s.size(); } + + auto rem = s.size() - pos; + if (pattern.size() > rem) { return pos; } + + if (start_with(s, pos, pattern)) { return pos; } + + off = pos + 1; + } + + return s.size(); + } + + std::string boundary_; + + std::string buf_; + size_t state_ = 0; + bool is_valid_ = false; + size_t off_ = 0; + MultipartFormData file_; +}; + +inline std::string to_lower(const char *beg, const char *end) { + std::string out; + auto it = beg; + while (it != end) { + out += static_cast(::tolower(*it)); + it++; + } + return out; +} + +inline std::string make_multipart_data_boundary() { + static const char data[] = + "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + + // std::random_device might actually be deterministic on some + // platforms, but due to lack of support in the c++ standard library, + // doing better requires either some ugly hacks or breaking portability. + std::random_device seed_gen; + // Request 128 bits of entropy for initialization + std::seed_seq seed_sequence{seed_gen(), seed_gen(), seed_gen(), seed_gen()}; + std::mt19937 engine(seed_sequence); + + std::string result = "--cpp-httplib-multipart-data-"; + + for (auto i = 0; i < 16; i++) { + result += data[engine() % (sizeof(data) - 1)]; + } + + return result; +} + +inline std::pair +get_range_offset_and_length(const Request &req, size_t content_length, + size_t index) { + auto r = req.ranges[index]; + + if (r.first == -1 && r.second == -1) { + return std::make_pair(0, content_length); + } + + auto slen = static_cast(content_length); + + if (r.first == -1) { + r.first = (std::max)(static_cast(0), slen - r.second); + r.second = slen - 1; + } + + if (r.second == -1) { r.second = slen - 1; } + return std::make_pair(r.first, static_cast(r.second - r.first) + 1); +} + +inline std::string make_content_range_header_field(size_t offset, size_t length, + size_t content_length) { + std::string field = "bytes "; + field += std::to_string(offset); + field += "-"; + field += std::to_string(offset + length - 1); + field += "/"; + field += std::to_string(content_length); + return field; +} + +template +bool process_multipart_ranges_data(const Request &req, Response &res, + const std::string &boundary, + const std::string &content_type, + SToken stoken, CToken ctoken, + Content content) { + for (size_t i = 0; i < req.ranges.size(); i++) { + ctoken("--"); + stoken(boundary); + ctoken("\r\n"); + if (!content_type.empty()) { + ctoken("Content-Type: "); + stoken(content_type); + ctoken("\r\n"); + } + + auto offsets = get_range_offset_and_length(req, res.body.size(), i); + auto offset = offsets.first; + auto length = offsets.second; + + ctoken("Content-Range: "); + stoken(make_content_range_header_field(offset, length, res.body.size())); + ctoken("\r\n"); + ctoken("\r\n"); + if (!content(offset, length)) { return false; } + ctoken("\r\n"); + } + + ctoken("--"); + stoken(boundary); + ctoken("--\r\n"); + + return true; +} + +inline bool make_multipart_ranges_data(const Request &req, Response &res, + const std::string &boundary, + const std::string &content_type, + std::string &data) { + return process_multipart_ranges_data( + req, res, boundary, content_type, + [&](const std::string &token) { data += token; }, + [&](const char *token) { data += token; }, + [&](size_t offset, size_t length) { + if (offset < res.body.size()) { + data += res.body.substr(offset, length); + return true; + } + return false; + }); +} + +inline size_t +get_multipart_ranges_data_length(const Request &req, Response &res, + const std::string &boundary, + const std::string &content_type) { + size_t data_length = 0; + + process_multipart_ranges_data( + req, res, boundary, content_type, + [&](const std::string &token) { data_length += token.size(); }, + [&](const char *token) { data_length += strlen(token); }, + [&](size_t /*offset*/, size_t length) { + data_length += length; + return true; + }); + + return data_length; +} + +template +inline bool write_multipart_ranges_data(Stream &strm, const Request &req, + Response &res, + const std::string &boundary, + const std::string &content_type, + const T &is_shutting_down) { + return process_multipart_ranges_data( + req, res, boundary, content_type, + [&](const std::string &token) { strm.write(token); }, + [&](const char *token) { strm.write(token); }, + [&](size_t offset, size_t length) { + return write_content(strm, res.content_provider_, offset, length, + is_shutting_down); + }); +} + +inline std::pair +get_range_offset_and_length(const Request &req, const Response &res, + size_t index) { + auto r = req.ranges[index]; + + if (r.second == -1) { + r.second = static_cast(res.content_length_) - 1; + } + + return std::make_pair(r.first, r.second - r.first + 1); +} + +inline bool expect_content(const Request &req) { + if (req.method == "POST" || req.method == "PUT" || req.method == "PATCH" || + req.method == "PRI" || req.method == "DELETE") { + return true; + } + // TODO: check if Content-Length is set + return false; +} + +inline bool has_crlf(const char *s) { + auto p = s; + while (*p) { + if (*p == '\r' || *p == '\n') { return true; } + p++; + } + return false; +} + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +template +inline std::string message_digest(const std::string &s, Init init, + Update update, Final final, + size_t digest_length) { + using namespace std; + + std::vector md(digest_length, 0); + CTX ctx; + init(&ctx); + update(&ctx, s.data(), s.size()); + final(md.data(), &ctx); + + stringstream ss; + for (auto c : md) { + ss << setfill('0') << setw(2) << hex << (unsigned int)c; + } + return ss.str(); +} + +inline std::string MD5(const std::string &s) { + return message_digest(s, MD5_Init, MD5_Update, MD5_Final, + MD5_DIGEST_LENGTH); +} + +inline std::string SHA_256(const std::string &s) { + return message_digest(s, SHA256_Init, SHA256_Update, SHA256_Final, + SHA256_DIGEST_LENGTH); +} + +inline std::string SHA_512(const std::string &s) { + return message_digest(s, SHA512_Init, SHA512_Update, SHA512_Final, + SHA512_DIGEST_LENGTH); +} +#endif + +#ifdef _WIN32 +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +// NOTE: This code came up with the following stackoverflow post: +// https://stackoverflow.com/questions/9507184/can-openssl-on-windows-use-the-system-certificate-store +inline bool load_system_certs_on_windows(X509_STORE *store) { + auto hStore = CertOpenSystemStoreW((HCRYPTPROV_LEGACY)NULL, L"ROOT"); + + if (!hStore) { return false; } + + PCCERT_CONTEXT pContext = NULL; + while ((pContext = CertEnumCertificatesInStore(hStore, pContext)) != + nullptr) { + auto encoded_cert = + static_cast(pContext->pbCertEncoded); + + auto x509 = d2i_X509(NULL, &encoded_cert, pContext->cbCertEncoded); + if (x509) { + X509_STORE_add_cert(store, x509); + X509_free(x509); + } + } + + CertFreeCertificateContext(pContext); + CertCloseStore(hStore, 0); + + return true; +} +#endif + +class WSInit { +public: + WSInit() { + WSADATA wsaData; + WSAStartup(0x0002, &wsaData); + } + + ~WSInit() { WSACleanup(); } +}; + +static WSInit wsinit_; +#endif + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +inline std::pair make_digest_authentication_header( + const Request &req, const std::map &auth, + size_t cnonce_count, const std::string &cnonce, const std::string &username, + const std::string &password, bool is_proxy = false) { + using namespace std; + + string nc; + { + stringstream ss; + ss << setfill('0') << setw(8) << hex << cnonce_count; + nc = ss.str(); + } + + auto qop = auth.at("qop"); + if (qop.find("auth-int") != std::string::npos) { + qop = "auth-int"; + } else { + qop = "auth"; + } + + std::string algo = "MD5"; + if (auth.find("algorithm") != auth.end()) { algo = auth.at("algorithm"); } + + string response; + { + auto H = algo == "SHA-256" + ? detail::SHA_256 + : algo == "SHA-512" ? detail::SHA_512 : detail::MD5; + + auto A1 = username + ":" + auth.at("realm") + ":" + password; + + auto A2 = req.method + ":" + req.path; + if (qop == "auth-int") { A2 += ":" + H(req.body); } + + response = H(H(A1) + ":" + auth.at("nonce") + ":" + nc + ":" + cnonce + + ":" + qop + ":" + H(A2)); + } + + auto field = "Digest username=\"" + username + "\", realm=\"" + + auth.at("realm") + "\", nonce=\"" + auth.at("nonce") + + "\", uri=\"" + req.path + "\", algorithm=" + algo + + ", qop=" + qop + ", nc=\"" + nc + "\", cnonce=\"" + cnonce + + "\", response=\"" + response + "\""; + + auto key = is_proxy ? "Proxy-Authorization" : "Authorization"; + return std::make_pair(key, field); +} +#endif + +inline bool parse_www_authenticate(const Response &res, + std::map &auth, + bool is_proxy) { + auto auth_key = is_proxy ? "Proxy-Authenticate" : "WWW-Authenticate"; + if (res.has_header(auth_key)) { + static auto re = std::regex(R"~((?:(?:,\s*)?(.+?)=(?:"(.*?)"|([^,]*))))~"); + auto s = res.get_header_value(auth_key); + auto pos = s.find(' '); + if (pos != std::string::npos) { + auto type = s.substr(0, pos); + if (type == "Basic") { + return false; + } else if (type == "Digest") { + s = s.substr(pos + 1); + auto beg = std::sregex_iterator(s.begin(), s.end(), re); + for (auto i = beg; i != std::sregex_iterator(); ++i) { + auto m = *i; + auto key = s.substr(static_cast(m.position(1)), + static_cast(m.length(1))); + auto val = m.length(2) > 0 + ? s.substr(static_cast(m.position(2)), + static_cast(m.length(2))) + : s.substr(static_cast(m.position(3)), + static_cast(m.length(3))); + auth[key] = val; + } + return true; + } + } + } + return false; +} + +// https://stackoverflow.com/questions/440133/how-do-i-create-a-random-alpha-numeric-string-in-c/440240#answer-440240 +inline std::string random_string(size_t length) { + auto randchar = []() -> char { + const char charset[] = "0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz"; + const size_t max_index = (sizeof(charset) - 1); + return charset[static_cast(std::rand()) % max_index]; + }; + std::string str(length, 0); + std::generate_n(str.begin(), length, randchar); + return str; +} + +class ContentProviderAdapter { +public: + explicit ContentProviderAdapter( + ContentProviderWithoutLength &&content_provider) + : content_provider_(content_provider) {} + + bool operator()(size_t offset, size_t, DataSink &sink) { + return content_provider_(offset, sink); + } + +private: + ContentProviderWithoutLength content_provider_; +}; + +} // namespace detail + +// Header utilities +inline std::pair make_range_header(Ranges ranges) { + std::string field = "bytes="; + auto i = 0; + for (auto r : ranges) { + if (i != 0) { field += ", "; } + if (r.first != -1) { field += std::to_string(r.first); } + field += '-'; + if (r.second != -1) { field += std::to_string(r.second); } + i++; + } + return std::make_pair("Range", std::move(field)); +} + +inline std::pair +make_basic_authentication_header(const std::string &username, + const std::string &password, bool is_proxy) { + auto field = "Basic " + detail::base64_encode(username + ":" + password); + auto key = is_proxy ? "Proxy-Authorization" : "Authorization"; + return std::make_pair(key, std::move(field)); +} + +inline std::pair +make_bearer_token_authentication_header(const std::string &token, + bool is_proxy = false) { + auto field = "Bearer " + token; + auto key = is_proxy ? "Proxy-Authorization" : "Authorization"; + return std::make_pair(key, std::move(field)); +} + +// Request implementation +inline bool Request::has_header(const char *key) const { + return detail::has_header(headers, key); +} + +inline std::string Request::get_header_value(const char *key, size_t id) const { + return detail::get_header_value(headers, key, id, ""); +} + +inline size_t Request::get_header_value_count(const char *key) const { + auto r = headers.equal_range(key); + return static_cast(std::distance(r.first, r.second)); +} + +inline void Request::set_header(const char *key, const char *val) { + if (!detail::has_crlf(key) && !detail::has_crlf(val)) { + headers.emplace(key, val); + } +} + +inline void Request::set_header(const char *key, const std::string &val) { + if (!detail::has_crlf(key) && !detail::has_crlf(val.c_str())) { + headers.emplace(key, val); + } +} + +inline bool Request::has_param(const char *key) const { + return params.find(key) != params.end(); +} + +inline std::string Request::get_param_value(const char *key, size_t id) const { + auto rng = params.equal_range(key); + auto it = rng.first; + std::advance(it, static_cast(id)); + if (it != rng.second) { return it->second; } + return std::string(); +} + +inline size_t Request::get_param_value_count(const char *key) const { + auto r = params.equal_range(key); + return static_cast(std::distance(r.first, r.second)); +} + +inline bool Request::is_multipart_form_data() const { + const auto &content_type = get_header_value("Content-Type"); + return !content_type.find("multipart/form-data"); +} + +inline bool Request::has_file(const char *key) const { + return files.find(key) != files.end(); +} + +inline MultipartFormData Request::get_file_value(const char *key) const { + auto it = files.find(key); + if (it != files.end()) { return it->second; } + return MultipartFormData(); +} + +// Response implementation +inline bool Response::has_header(const char *key) const { + return headers.find(key) != headers.end(); +} + +inline std::string Response::get_header_value(const char *key, + size_t id) const { + return detail::get_header_value(headers, key, id, ""); +} + +inline size_t Response::get_header_value_count(const char *key) const { + auto r = headers.equal_range(key); + return static_cast(std::distance(r.first, r.second)); +} + +inline void Response::set_header(const char *key, const char *val) { + if (!detail::has_crlf(key) && !detail::has_crlf(val)) { + headers.emplace(key, val); + } +} + +inline void Response::set_header(const char *key, const std::string &val) { + if (!detail::has_crlf(key) && !detail::has_crlf(val.c_str())) { + headers.emplace(key, val); + } +} + +inline void Response::set_redirect(const char *url, int stat) { + if (!detail::has_crlf(url)) { + set_header("Location", url); + if (300 <= stat && stat < 400) { + this->status = stat; + } else { + this->status = 302; + } + } +} + +inline void Response::set_redirect(const std::string &url, int stat) { + set_redirect(url.c_str(), stat); +} + +inline void Response::set_content(const char *s, size_t n, + const char *content_type) { + body.assign(s, n); + + auto rng = headers.equal_range("Content-Type"); + headers.erase(rng.first, rng.second); + set_header("Content-Type", content_type); +} + +inline void Response::set_content(const std::string &s, + const char *content_type) { + set_content(s.data(), s.size(), content_type); +} + +inline void Response::set_content_provider( + size_t in_length, const char *content_type, ContentProvider provider, + ContentProviderResourceReleaser resource_releaser) { + assert(in_length > 0); + set_header("Content-Type", content_type); + content_length_ = in_length; + content_provider_ = std::move(provider); + content_provider_resource_releaser_ = resource_releaser; + is_chunked_content_provider_ = false; +} + +inline void Response::set_content_provider( + const char *content_type, ContentProviderWithoutLength provider, + ContentProviderResourceReleaser resource_releaser) { + set_header("Content-Type", content_type); + content_length_ = 0; + content_provider_ = detail::ContentProviderAdapter(std::move(provider)); + content_provider_resource_releaser_ = resource_releaser; + is_chunked_content_provider_ = false; +} + +inline void Response::set_chunked_content_provider( + const char *content_type, ContentProviderWithoutLength provider, + ContentProviderResourceReleaser resource_releaser) { + set_header("Content-Type", content_type); + content_length_ = 0; + content_provider_ = detail::ContentProviderAdapter(std::move(provider)); + content_provider_resource_releaser_ = resource_releaser; + is_chunked_content_provider_ = true; +} + +// Result implementation +inline bool Result::has_request_header(const char *key) const { + return request_headers_.find(key) != request_headers_.end(); +} + +inline std::string Result::get_request_header_value(const char *key, + size_t id) const { + return detail::get_header_value(request_headers_, key, id, ""); +} + +inline size_t Result::get_request_header_value_count(const char *key) const { + auto r = request_headers_.equal_range(key); + return static_cast(std::distance(r.first, r.second)); +} + +// Stream implementation +inline ssize_t Stream::write(const char *ptr) { + return write(ptr, strlen(ptr)); +} + +inline ssize_t Stream::write(const std::string &s) { + return write(s.data(), s.size()); +} + +namespace detail { + +// Socket stream implementation +inline SocketStream::SocketStream(socket_t sock, time_t read_timeout_sec, + time_t read_timeout_usec, + time_t write_timeout_sec, + time_t write_timeout_usec) + : sock_(sock), read_timeout_sec_(read_timeout_sec), + read_timeout_usec_(read_timeout_usec), + write_timeout_sec_(write_timeout_sec), + write_timeout_usec_(write_timeout_usec) {} + +inline SocketStream::~SocketStream() {} + +inline bool SocketStream::is_readable() const { + return select_read(sock_, read_timeout_sec_, read_timeout_usec_) > 0; +} + +inline bool SocketStream::is_writable() const { + return select_write(sock_, write_timeout_sec_, write_timeout_usec_) > 0; +} + +inline ssize_t SocketStream::read(char *ptr, size_t size) { + if (!is_readable()) { return -1; } + +#ifdef _WIN32 + if (size > static_cast((std::numeric_limits::max)())) { + return -1; + } + return recv(sock_, ptr, static_cast(size), CPPHTTPLIB_RECV_FLAGS); +#else + return handle_EINTR( + [&]() { return recv(sock_, ptr, size, CPPHTTPLIB_RECV_FLAGS); }); +#endif +} + +inline ssize_t SocketStream::write(const char *ptr, size_t size) { + if (!is_writable()) { return -1; } + +#ifdef _WIN32 + if (size > static_cast((std::numeric_limits::max)())) { + return -1; + } + return send(sock_, ptr, static_cast(size), CPPHTTPLIB_SEND_FLAGS); +#else + return handle_EINTR( + [&]() { return send(sock_, ptr, size, CPPHTTPLIB_SEND_FLAGS); }); +#endif +} + +inline void SocketStream::get_remote_ip_and_port(std::string &ip, + int &port) const { + return detail::get_remote_ip_and_port(sock_, ip, port); +} + +inline socket_t SocketStream::socket() const { return sock_; } + +// Buffer stream implementation +inline bool BufferStream::is_readable() const { return true; } + +inline bool BufferStream::is_writable() const { return true; } + +inline ssize_t BufferStream::read(char *ptr, size_t size) { +#if defined(_MSC_VER) && _MSC_VER <= 1900 + auto len_read = buffer._Copy_s(ptr, size, size, position); +#else + auto len_read = buffer.copy(ptr, size, position); +#endif + position += static_cast(len_read); + return static_cast(len_read); +} + +inline ssize_t BufferStream::write(const char *ptr, size_t size) { + buffer.append(ptr, size); + return static_cast(size); +} + +inline void BufferStream::get_remote_ip_and_port(std::string & /*ip*/, + int & /*port*/) const {} + +inline socket_t BufferStream::socket() const { return 0; } + +inline const std::string &BufferStream::get_buffer() const { return buffer; } + +} // namespace detail + +// HTTP server implementation +inline Server::Server() + : new_task_queue( + [] { return new ThreadPool(CPPHTTPLIB_THREAD_POOL_COUNT); }), + svr_sock_(INVALID_SOCKET), is_running_(false) { +#ifndef _WIN32 + signal(SIGPIPE, SIG_IGN); +#endif +} + +inline Server::~Server() {} + +inline Server &Server::Get(const std::string &pattern, Handler handler) { + get_handlers_.push_back( + std::make_pair(std::regex(pattern), std::move(handler))); + return *this; +} + +inline Server &Server::Post(const std::string &pattern, Handler handler) { + post_handlers_.push_back( + std::make_pair(std::regex(pattern), std::move(handler))); + return *this; +} + +inline Server &Server::Post(const std::string &pattern, + HandlerWithContentReader handler) { + post_handlers_for_content_reader_.push_back( + std::make_pair(std::regex(pattern), std::move(handler))); + return *this; +} + +inline Server &Server::Put(const std::string &pattern, Handler handler) { + put_handlers_.push_back( + std::make_pair(std::regex(pattern), std::move(handler))); + return *this; +} + +inline Server &Server::Put(const std::string &pattern, + HandlerWithContentReader handler) { + put_handlers_for_content_reader_.push_back( + std::make_pair(std::regex(pattern), std::move(handler))); + return *this; +} + +inline Server &Server::Patch(const std::string &pattern, Handler handler) { + patch_handlers_.push_back( + std::make_pair(std::regex(pattern), std::move(handler))); + return *this; +} + +inline Server &Server::Patch(const std::string &pattern, + HandlerWithContentReader handler) { + patch_handlers_for_content_reader_.push_back( + std::make_pair(std::regex(pattern), std::move(handler))); + return *this; +} + +inline Server &Server::Delete(const std::string &pattern, Handler handler) { + delete_handlers_.push_back( + std::make_pair(std::regex(pattern), std::move(handler))); + return *this; +} + +inline Server &Server::Delete(const std::string &pattern, + HandlerWithContentReader handler) { + delete_handlers_for_content_reader_.push_back( + std::make_pair(std::regex(pattern), std::move(handler))); + return *this; +} + +inline Server &Server::Options(const std::string &pattern, Handler handler) { + options_handlers_.push_back( + std::make_pair(std::regex(pattern), std::move(handler))); + return *this; +} + +inline bool Server::set_base_dir(const std::string &dir, + const std::string &mount_point) { + return set_mount_point(mount_point, dir); +} + +inline bool Server::set_mount_point(const std::string &mount_point, + const std::string &dir, Headers headers) { + if (detail::is_dir(dir)) { + std::string mnt = !mount_point.empty() ? mount_point : "/"; + if (!mnt.empty() && mnt[0] == '/') { + base_dirs_.push_back({mnt, dir, std::move(headers)}); + return true; + } + } + return false; +} + +inline bool Server::remove_mount_point(const std::string &mount_point) { + for (auto it = base_dirs_.begin(); it != base_dirs_.end(); ++it) { + if (it->mount_point == mount_point) { + base_dirs_.erase(it); + return true; + } + } + return false; +} + +inline Server & +Server::set_file_extension_and_mimetype_mapping(const char *ext, + const char *mime) { + file_extension_and_mimetype_map_[ext] = mime; + return *this; +} + +inline Server &Server::set_file_request_handler(Handler handler) { + file_request_handler_ = std::move(handler); + return *this; +} + +inline Server &Server::set_error_handler(HandlerWithResponse handler) { + error_handler_ = std::move(handler); + return *this; +} + +inline Server &Server::set_error_handler(Handler handler) { + error_handler_ = [handler](const Request &req, Response &res) { + handler(req, res); + return HandlerResponse::Handled; + }; + return *this; +} + +inline Server &Server::set_exception_handler(ExceptionHandler handler) { + exception_handler_ = std::move(handler); + return *this; +} + +inline Server &Server::set_pre_routing_handler(HandlerWithResponse handler) { + pre_routing_handler_ = std::move(handler); + return *this; +} + +inline Server &Server::set_post_routing_handler(Handler handler) { + post_routing_handler_ = std::move(handler); + return *this; +} + +inline Server &Server::set_logger(Logger logger) { + logger_ = std::move(logger); + return *this; +} + +inline Server & +Server::set_expect_100_continue_handler(Expect100ContinueHandler handler) { + expect_100_continue_handler_ = std::move(handler); + + return *this; +} + +inline Server &Server::set_address_family(int family) { + address_family_ = family; + return *this; +} + +inline Server &Server::set_tcp_nodelay(bool on) { + tcp_nodelay_ = on; + return *this; +} + +inline Server &Server::set_socket_options(SocketOptions socket_options) { + socket_options_ = std::move(socket_options); + return *this; +} + +inline Server &Server::set_default_headers(Headers headers) { + default_headers_ = std::move(headers); + return *this; +} + +inline Server &Server::set_keep_alive_max_count(size_t count) { + keep_alive_max_count_ = count; + return *this; +} + +inline Server &Server::set_keep_alive_timeout(time_t sec) { + keep_alive_timeout_sec_ = sec; + return *this; +} + +inline Server &Server::set_read_timeout(time_t sec, time_t usec) { + read_timeout_sec_ = sec; + read_timeout_usec_ = usec; + return *this; +} + +inline Server &Server::set_write_timeout(time_t sec, time_t usec) { + write_timeout_sec_ = sec; + write_timeout_usec_ = usec; + return *this; +} + +inline Server &Server::set_idle_interval(time_t sec, time_t usec) { + idle_interval_sec_ = sec; + idle_interval_usec_ = usec; + return *this; +} + +inline Server &Server::set_payload_max_length(size_t length) { + payload_max_length_ = length; + return *this; +} + +inline bool Server::bind_to_port(const char *host, int port, int socket_flags) { + if (bind_internal(host, port, socket_flags) < 0) return false; + return true; +} +inline int Server::bind_to_any_port(const char *host, int socket_flags) { + return bind_internal(host, 0, socket_flags); +} + +inline bool Server::listen_after_bind() { return listen_internal(); } + +inline bool Server::listen(const char *host, int port, int socket_flags) { + return bind_to_port(host, port, socket_flags) && listen_internal(); +} + +inline bool Server::is_running() const { return is_running_; } + +inline void Server::stop() { + if (is_running_) { + assert(svr_sock_ != INVALID_SOCKET); + std::atomic sock(svr_sock_.exchange(INVALID_SOCKET)); + detail::shutdown_socket(sock); + detail::close_socket(sock); + } +} + +inline bool Server::parse_request_line(const char *s, Request &req) { + auto len = strlen(s); + if (len < 2 || s[len - 2] != '\r' || s[len - 1] != '\n') { return false; } + len -= 2; + + { + size_t count = 0; + + detail::split(s, s + len, ' ', [&](const char *b, const char *e) { + switch (count) { + case 0: req.method = std::string(b, e); break; + case 1: req.target = std::string(b, e); break; + case 2: req.version = std::string(b, e); break; + default: break; + } + count++; + }); + + if (count != 3) { return false; } + } + + static const std::set methods{ + "GET", "HEAD", "POST", "PUT", "DELETE", + "CONNECT", "OPTIONS", "TRACE", "PATCH", "PRI"}; + + if (methods.find(req.method) == methods.end()) { return false; } + + if (req.version != "HTTP/1.1" && req.version != "HTTP/1.0") { return false; } + + { + size_t count = 0; + + detail::split(req.target.data(), req.target.data() + req.target.size(), '?', + [&](const char *b, const char *e) { + switch (count) { + case 0: + req.path = detail::decode_url(std::string(b, e), false); + break; + case 1: { + if (e - b > 0) { + detail::parse_query_text(std::string(b, e), req.params); + } + break; + } + default: break; + } + count++; + }); + + if (count > 2) { return false; } + } + + return true; +} + +inline bool Server::write_response(Stream &strm, bool close_connection, + const Request &req, Response &res) { + return write_response_core(strm, close_connection, req, res, false); +} + +inline bool Server::write_response_with_content(Stream &strm, + bool close_connection, + const Request &req, + Response &res) { + return write_response_core(strm, close_connection, req, res, true); +} + +inline bool Server::write_response_core(Stream &strm, bool close_connection, + const Request &req, Response &res, + bool need_apply_ranges) { + assert(res.status != -1); + + if (400 <= res.status && error_handler_ && + error_handler_(req, res) == HandlerResponse::Handled) { + need_apply_ranges = true; + } + + std::string content_type; + std::string boundary; + if (need_apply_ranges) { apply_ranges(req, res, content_type, boundary); } + + // Prepare additional headers + if (close_connection || req.get_header_value("Connection") == "close") { + res.set_header("Connection", "close"); + } else { + std::stringstream ss; + ss << "timeout=" << keep_alive_timeout_sec_ + << ", max=" << keep_alive_max_count_; + res.set_header("Keep-Alive", ss.str()); + } + + if (!res.has_header("Content-Type") && + (!res.body.empty() || res.content_length_ > 0 || res.content_provider_)) { + res.set_header("Content-Type", "text/plain"); + } + + if (!res.has_header("Content-Length") && res.body.empty() && + !res.content_length_ && !res.content_provider_) { + res.set_header("Content-Length", "0"); + } + + if (!res.has_header("Accept-Ranges") && req.method == "HEAD") { + res.set_header("Accept-Ranges", "bytes"); + } + + if (post_routing_handler_) { post_routing_handler_(req, res); } + + // Response line and headers + { + detail::BufferStream bstrm; + + if (!bstrm.write_format("HTTP/1.1 %d %s\r\n", res.status, + detail::status_message(res.status))) { + return false; + } + + if (!detail::write_headers(bstrm, res.headers)) { return false; } + + // Flush buffer + auto &data = bstrm.get_buffer(); + strm.write(data.data(), data.size()); + } + + // Body + auto ret = true; + if (req.method != "HEAD") { + if (!res.body.empty()) { + if (!strm.write(res.body)) { ret = false; } + } else if (res.content_provider_) { + if (write_content_with_provider(strm, req, res, boundary, content_type)) { + res.content_provider_success_ = true; + } else { + res.content_provider_success_ = false; + ret = false; + } + } + } + + // Log + if (logger_) { logger_(req, res); } + + return ret; +} + +inline bool +Server::write_content_with_provider(Stream &strm, const Request &req, + Response &res, const std::string &boundary, + const std::string &content_type) { + auto is_shutting_down = [this]() { + return this->svr_sock_ == INVALID_SOCKET; + }; + + if (res.content_length_ > 0) { + if (req.ranges.empty()) { + return detail::write_content(strm, res.content_provider_, 0, + res.content_length_, is_shutting_down); + } else if (req.ranges.size() == 1) { + auto offsets = + detail::get_range_offset_and_length(req, res.content_length_, 0); + auto offset = offsets.first; + auto length = offsets.second; + return detail::write_content(strm, res.content_provider_, offset, length, + is_shutting_down); + } else { + return detail::write_multipart_ranges_data( + strm, req, res, boundary, content_type, is_shutting_down); + } + } else { + if (res.is_chunked_content_provider_) { + auto type = detail::encoding_type(req, res); + + std::unique_ptr compressor; + if (type == detail::EncodingType::Gzip) { +#ifdef CPPHTTPLIB_ZLIB_SUPPORT + compressor = detail::make_unique(); +#endif + } else if (type == detail::EncodingType::Brotli) { +#ifdef CPPHTTPLIB_BROTLI_SUPPORT + compressor = detail::make_unique(); +#endif + } else { + compressor = detail::make_unique(); + } + assert(compressor != nullptr); + + return detail::write_content_chunked(strm, res.content_provider_, + is_shutting_down, *compressor); + } else { + return detail::write_content_without_length(strm, res.content_provider_, + is_shutting_down); + } + } +} + +inline bool Server::read_content(Stream &strm, Request &req, Response &res) { + MultipartFormDataMap::iterator cur; + if (read_content_core( + strm, req, res, + // Regular + [&](const char *buf, size_t n) { + if (req.body.size() + n > req.body.max_size()) { return false; } + req.body.append(buf, n); + return true; + }, + // Multipart + [&](const MultipartFormData &file) { + cur = req.files.emplace(file.name, file); + return true; + }, + [&](const char *buf, size_t n) { + auto &content = cur->second.content; + if (content.size() + n > content.max_size()) { return false; } + content.append(buf, n); + return true; + })) { + const auto &content_type = req.get_header_value("Content-Type"); + if (!content_type.find("application/x-www-form-urlencoded")) { + detail::parse_query_text(req.body, req.params); + } + return true; + } + return false; +} + +inline bool Server::read_content_with_content_receiver( + Stream &strm, Request &req, Response &res, ContentReceiver receiver, + MultipartContentHeader multipart_header, + ContentReceiver multipart_receiver) { + return read_content_core(strm, req, res, std::move(receiver), + std::move(multipart_header), + std::move(multipart_receiver)); +} + +inline bool Server::read_content_core(Stream &strm, Request &req, Response &res, + ContentReceiver receiver, + MultipartContentHeader mulitpart_header, + ContentReceiver multipart_receiver) { + detail::MultipartFormDataParser multipart_form_data_parser; + ContentReceiverWithProgress out; + + if (req.is_multipart_form_data()) { + const auto &content_type = req.get_header_value("Content-Type"); + std::string boundary; + if (!detail::parse_multipart_boundary(content_type, boundary)) { + res.status = 400; + return false; + } + + multipart_form_data_parser.set_boundary(std::move(boundary)); + out = [&](const char *buf, size_t n, uint64_t /*off*/, uint64_t /*len*/) { + /* For debug + size_t pos = 0; + while (pos < n) { + auto read_size = std::min(1, n - pos); + auto ret = multipart_form_data_parser.parse( + buf + pos, read_size, multipart_receiver, mulitpart_header); + if (!ret) { return false; } + pos += read_size; + } + return true; + */ + return multipart_form_data_parser.parse(buf, n, multipart_receiver, + mulitpart_header); + }; + } else { + out = [receiver](const char *buf, size_t n, uint64_t /*off*/, + uint64_t /*len*/) { return receiver(buf, n); }; + } + + if (req.method == "DELETE" && !req.has_header("Content-Length")) { + return true; + } + + if (!detail::read_content(strm, req, payload_max_length_, res.status, nullptr, + out, true)) { + return false; + } + + if (req.is_multipart_form_data()) { + if (!multipart_form_data_parser.is_valid()) { + res.status = 400; + return false; + } + } + + return true; +} + +inline bool Server::handle_file_request(const Request &req, Response &res, + bool head) { + for (const auto &entry : base_dirs_) { + // Prefix match + if (!req.path.compare(0, entry.mount_point.size(), entry.mount_point)) { + std::string sub_path = "/" + req.path.substr(entry.mount_point.size()); + if (detail::is_valid_path(sub_path)) { + auto path = entry.base_dir + sub_path; + if (path.back() == '/') { path += "index.html"; } + + if (detail::is_file(path)) { + detail::read_file(path, res.body); + auto type = + detail::find_content_type(path, file_extension_and_mimetype_map_); + if (type) { res.set_header("Content-Type", type); } + for (const auto &kv : entry.headers) { + res.set_header(kv.first.c_str(), kv.second); + } + res.status = req.has_header("Range") ? 206 : 200; + if (!head && file_request_handler_) { + file_request_handler_(req, res); + } + return true; + } + } + } + } + return false; +} + +inline socket_t +Server::create_server_socket(const char *host, int port, int socket_flags, + SocketOptions socket_options) const { + return detail::create_socket( + host, port, address_family_, socket_flags, tcp_nodelay_, + std::move(socket_options), + [](socket_t sock, struct addrinfo &ai) -> bool { + if (::bind(sock, ai.ai_addr, static_cast(ai.ai_addrlen))) { + return false; + } + if (::listen(sock, 5)) { // Listen through 5 channels + return false; + } + return true; + }); +} + +inline int Server::bind_internal(const char *host, int port, int socket_flags) { + if (!is_valid()) { return -1; } + + svr_sock_ = create_server_socket(host, port, socket_flags, socket_options_); + if (svr_sock_ == INVALID_SOCKET) { return -1; } + + if (port == 0) { + struct sockaddr_storage addr; + socklen_t addr_len = sizeof(addr); + if (getsockname(svr_sock_, reinterpret_cast(&addr), + &addr_len) == -1) { + return -1; + } + if (addr.ss_family == AF_INET) { + return ntohs(reinterpret_cast(&addr)->sin_port); + } else if (addr.ss_family == AF_INET6) { + return ntohs(reinterpret_cast(&addr)->sin6_port); + } else { + return -1; + } + } else { + return port; + } +} + +inline bool Server::listen_internal() { + auto ret = true; + is_running_ = true; + + { + std::unique_ptr task_queue(new_task_queue()); + + while (svr_sock_ != INVALID_SOCKET) { +#ifndef _WIN32 + if (idle_interval_sec_ > 0 || idle_interval_usec_ > 0) { +#endif + auto val = detail::select_read(svr_sock_, idle_interval_sec_, + idle_interval_usec_); + if (val == 0) { // Timeout + task_queue->on_idle(); + continue; + } +#ifndef _WIN32 + } +#endif + socket_t sock = accept(svr_sock_, nullptr, nullptr); + + if (sock == INVALID_SOCKET) { + if (errno == EMFILE) { + // The per-process limit of open file descriptors has been reached. + // Try to accept new connections after a short sleep. + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + continue; + } + if (svr_sock_ != INVALID_SOCKET) { + detail::close_socket(svr_sock_); + ret = false; + } else { + ; // The server socket was closed by user. + } + break; + } + + { + timeval tv; + tv.tv_sec = static_cast(read_timeout_sec_); + tv.tv_usec = static_cast(read_timeout_usec_); + setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv)); + } + { + timeval tv; + tv.tv_sec = static_cast(write_timeout_sec_); + tv.tv_usec = static_cast(write_timeout_usec_); + setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv, sizeof(tv)); + } + +#if __cplusplus > 201703L + task_queue->enqueue([=, this]() { process_and_close_socket(sock); }); +#else + task_queue->enqueue([=]() { process_and_close_socket(sock); }); +#endif + } + + task_queue->shutdown(); + } + + is_running_ = false; + return ret; +} + +inline bool Server::routing(Request &req, Response &res, Stream &strm) { + if (pre_routing_handler_ && + pre_routing_handler_(req, res) == HandlerResponse::Handled) { + return true; + } + + // File handler + bool is_head_request = req.method == "HEAD"; + if ((req.method == "GET" || is_head_request) && + handle_file_request(req, res, is_head_request)) { + return true; + } + + if (detail::expect_content(req)) { + // Content reader handler + { + ContentReader reader( + [&](ContentReceiver receiver) { + return read_content_with_content_receiver( + strm, req, res, std::move(receiver), nullptr, nullptr); + }, + [&](MultipartContentHeader header, ContentReceiver receiver) { + return read_content_with_content_receiver(strm, req, res, nullptr, + std::move(header), + std::move(receiver)); + }); + + if (req.method == "POST") { + if (dispatch_request_for_content_reader( + req, res, std::move(reader), + post_handlers_for_content_reader_)) { + return true; + } + } else if (req.method == "PUT") { + if (dispatch_request_for_content_reader( + req, res, std::move(reader), + put_handlers_for_content_reader_)) { + return true; + } + } else if (req.method == "PATCH") { + if (dispatch_request_for_content_reader( + req, res, std::move(reader), + patch_handlers_for_content_reader_)) { + return true; + } + } else if (req.method == "DELETE") { + if (dispatch_request_for_content_reader( + req, res, std::move(reader), + delete_handlers_for_content_reader_)) { + return true; + } + } + } + + // Read content into `req.body` + if (!read_content(strm, req, res)) { return false; } + } + + // Regular handler + if (req.method == "GET" || req.method == "HEAD") { + return dispatch_request(req, res, get_handlers_); + } else if (req.method == "POST") { + return dispatch_request(req, res, post_handlers_); + } else if (req.method == "PUT") { + return dispatch_request(req, res, put_handlers_); + } else if (req.method == "DELETE") { + return dispatch_request(req, res, delete_handlers_); + } else if (req.method == "OPTIONS") { + return dispatch_request(req, res, options_handlers_); + } else if (req.method == "PATCH") { + return dispatch_request(req, res, patch_handlers_); + } + + res.status = 400; + return false; +} + +inline bool Server::dispatch_request(Request &req, Response &res, + const Handlers &handlers) { + for (const auto &x : handlers) { + const auto &pattern = x.first; + const auto &handler = x.second; + + if (std::regex_match(req.path, req.matches, pattern)) { + handler(req, res); + return true; + } + } + return false; +} + +inline void Server::apply_ranges(const Request &req, Response &res, + std::string &content_type, + std::string &boundary) { + if (req.ranges.size() > 1) { + boundary = detail::make_multipart_data_boundary(); + + auto it = res.headers.find("Content-Type"); + if (it != res.headers.end()) { + content_type = it->second; + res.headers.erase(it); + } + + res.headers.emplace("Content-Type", + "multipart/byteranges; boundary=" + boundary); + } + + auto type = detail::encoding_type(req, res); + + if (res.body.empty()) { + if (res.content_length_ > 0) { + size_t length = 0; + if (req.ranges.empty()) { + length = res.content_length_; + } else if (req.ranges.size() == 1) { + auto offsets = + detail::get_range_offset_and_length(req, res.content_length_, 0); + auto offset = offsets.first; + length = offsets.second; + auto content_range = detail::make_content_range_header_field( + offset, length, res.content_length_); + res.set_header("Content-Range", content_range); + } else { + length = detail::get_multipart_ranges_data_length(req, res, boundary, + content_type); + } + res.set_header("Content-Length", std::to_string(length)); + } else { + if (res.content_provider_) { + if (res.is_chunked_content_provider_) { + res.set_header("Transfer-Encoding", "chunked"); + if (type == detail::EncodingType::Gzip) { + res.set_header("Content-Encoding", "gzip"); + } else if (type == detail::EncodingType::Brotli) { + res.set_header("Content-Encoding", "br"); + } + } + } + } + } else { + if (req.ranges.empty()) { + ; + } else if (req.ranges.size() == 1) { + auto offsets = + detail::get_range_offset_and_length(req, res.body.size(), 0); + auto offset = offsets.first; + auto length = offsets.second; + auto content_range = detail::make_content_range_header_field( + offset, length, res.body.size()); + res.set_header("Content-Range", content_range); + if (offset < res.body.size()) { + res.body = res.body.substr(offset, length); + } else { + res.body.clear(); + res.status = 416; + } + } else { + std::string data; + if (detail::make_multipart_ranges_data(req, res, boundary, content_type, + data)) { + res.body.swap(data); + } else { + res.body.clear(); + res.status = 416; + } + } + + if (type != detail::EncodingType::None) { + std::unique_ptr compressor; + std::string content_encoding; + + if (type == detail::EncodingType::Gzip) { +#ifdef CPPHTTPLIB_ZLIB_SUPPORT + compressor = detail::make_unique(); + content_encoding = "gzip"; +#endif + } else if (type == detail::EncodingType::Brotli) { +#ifdef CPPHTTPLIB_BROTLI_SUPPORT + compressor = detail::make_unique(); + content_encoding = "br"; +#endif + } + + if (compressor) { + std::string compressed; + if (compressor->compress(res.body.data(), res.body.size(), true, + [&](const char *data, size_t data_len) { + compressed.append(data, data_len); + return true; + })) { + res.body.swap(compressed); + res.set_header("Content-Encoding", content_encoding); + } + } + } + + auto length = std::to_string(res.body.size()); + res.set_header("Content-Length", length); + } +} + +inline bool Server::dispatch_request_for_content_reader( + Request &req, Response &res, ContentReader content_reader, + const HandlersForContentReader &handlers) { + for (const auto &x : handlers) { + const auto &pattern = x.first; + const auto &handler = x.second; + + if (std::regex_match(req.path, req.matches, pattern)) { + handler(req, res, content_reader); + return true; + } + } + return false; +} + +inline bool +Server::process_request(Stream &strm, bool close_connection, + bool &connection_closed, + const std::function &setup_request) { + std::array buf{}; + + detail::stream_line_reader line_reader(strm, buf.data(), buf.size()); + + // Connection has been closed on client + if (!line_reader.getline()) { return false; } + + Request req; + Response res; + + res.version = "HTTP/1.1"; + + for (const auto &header : default_headers_) { + if (res.headers.find(header.first) == res.headers.end()) { + res.headers.insert(header); + } + } + +#ifdef _WIN32 + // TODO: Increase FD_SETSIZE statically (libzmq), dynamically (MySQL). +#else +#ifndef CPPHTTPLIB_USE_POLL + // Socket file descriptor exceeded FD_SETSIZE... + if (strm.socket() >= FD_SETSIZE) { + Headers dummy; + detail::read_headers(strm, dummy); + res.status = 500; + return write_response(strm, close_connection, req, res); + } +#endif +#endif + + // Check if the request URI doesn't exceed the limit + if (line_reader.size() > CPPHTTPLIB_REQUEST_URI_MAX_LENGTH) { + Headers dummy; + detail::read_headers(strm, dummy); + res.status = 414; + return write_response(strm, close_connection, req, res); + } + + // Request line and headers + if (!parse_request_line(line_reader.ptr(), req) || + !detail::read_headers(strm, req.headers)) { + res.status = 400; + return write_response(strm, close_connection, req, res); + } + + if (req.get_header_value("Connection") == "close") { + connection_closed = true; + } + + if (req.version == "HTTP/1.0" && + req.get_header_value("Connection") != "Keep-Alive") { + connection_closed = true; + } + + strm.get_remote_ip_and_port(req.remote_addr, req.remote_port); + req.set_header("REMOTE_ADDR", req.remote_addr); + req.set_header("REMOTE_PORT", std::to_string(req.remote_port)); + + if (req.has_header("Range")) { + const auto &range_header_value = req.get_header_value("Range"); + if (!detail::parse_range_header(range_header_value, req.ranges)) { + res.status = 416; + return write_response(strm, close_connection, req, res); + } + } + + if (setup_request) { setup_request(req); } + + if (req.get_header_value("Expect") == "100-continue") { + auto status = 100; + if (expect_100_continue_handler_) { + status = expect_100_continue_handler_(req, res); + } + switch (status) { + case 100: + case 417: + strm.write_format("HTTP/1.1 %d %s\r\n\r\n", status, + detail::status_message(status)); + break; + default: return write_response(strm, close_connection, req, res); + } + } + + // Rounting + bool routed = false; + try { + routed = routing(req, res, strm); + } catch (std::exception &e) { + if (exception_handler_) { + exception_handler_(req, res, e); + routed = true; + } else { + res.status = 500; + res.set_header("EXCEPTION_WHAT", e.what()); + } + } catch (...) { + res.status = 500; + res.set_header("EXCEPTION_WHAT", "UNKNOWN"); + } + + if (routed) { + if (res.status == -1) { res.status = req.ranges.empty() ? 200 : 206; } + return write_response_with_content(strm, close_connection, req, res); + } else { + if (res.status == -1) { res.status = 404; } + return write_response(strm, close_connection, req, res); + } +} + +inline bool Server::is_valid() const { return true; } + +inline bool Server::process_and_close_socket(socket_t sock) { + auto ret = detail::process_server_socket( + sock, keep_alive_max_count_, keep_alive_timeout_sec_, read_timeout_sec_, + read_timeout_usec_, write_timeout_sec_, write_timeout_usec_, + [this](Stream &strm, bool close_connection, bool &connection_closed) { + return process_request(strm, close_connection, connection_closed, + nullptr); + }); + + detail::shutdown_socket(sock); + detail::close_socket(sock); + return ret; +} + +// HTTP client implementation +inline ClientImpl::ClientImpl(const std::string &host) + : ClientImpl(host, 80, std::string(), std::string()) {} + +inline ClientImpl::ClientImpl(const std::string &host, int port) + : ClientImpl(host, port, std::string(), std::string()) {} + +inline ClientImpl::ClientImpl(const std::string &host, int port, + const std::string &client_cert_path, + const std::string &client_key_path) + : host_(host), port_(port), + host_and_port_(adjust_host_string(host) + ":" + std::to_string(port)), + client_cert_path_(client_cert_path), client_key_path_(client_key_path) {} + +inline ClientImpl::~ClientImpl() { + std::lock_guard guard(socket_mutex_); + shutdown_socket(socket_); + close_socket(socket_); +} + +inline bool ClientImpl::is_valid() const { return true; } + +inline void ClientImpl::copy_settings(const ClientImpl &rhs) { + client_cert_path_ = rhs.client_cert_path_; + client_key_path_ = rhs.client_key_path_; + connection_timeout_sec_ = rhs.connection_timeout_sec_; + read_timeout_sec_ = rhs.read_timeout_sec_; + read_timeout_usec_ = rhs.read_timeout_usec_; + write_timeout_sec_ = rhs.write_timeout_sec_; + write_timeout_usec_ = rhs.write_timeout_usec_; + basic_auth_username_ = rhs.basic_auth_username_; + basic_auth_password_ = rhs.basic_auth_password_; + bearer_token_auth_token_ = rhs.bearer_token_auth_token_; +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + digest_auth_username_ = rhs.digest_auth_username_; + digest_auth_password_ = rhs.digest_auth_password_; +#endif + keep_alive_ = rhs.keep_alive_; + follow_location_ = rhs.follow_location_; + url_encode_ = rhs.url_encode_; + address_family_ = rhs.address_family_; + tcp_nodelay_ = rhs.tcp_nodelay_; + socket_options_ = rhs.socket_options_; + compress_ = rhs.compress_; + decompress_ = rhs.decompress_; + interface_ = rhs.interface_; + proxy_host_ = rhs.proxy_host_; + proxy_port_ = rhs.proxy_port_; + proxy_basic_auth_username_ = rhs.proxy_basic_auth_username_; + proxy_basic_auth_password_ = rhs.proxy_basic_auth_password_; + proxy_bearer_token_auth_token_ = rhs.proxy_bearer_token_auth_token_; +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + proxy_digest_auth_username_ = rhs.proxy_digest_auth_username_; + proxy_digest_auth_password_ = rhs.proxy_digest_auth_password_; +#endif +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + ca_cert_file_path_ = rhs.ca_cert_file_path_; + ca_cert_dir_path_ = rhs.ca_cert_dir_path_; + ca_cert_store_ = rhs.ca_cert_store_; +#endif +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + server_certificate_verification_ = rhs.server_certificate_verification_; +#endif + logger_ = rhs.logger_; +} + +inline socket_t ClientImpl::create_client_socket(Error &error) const { + if (!proxy_host_.empty() && proxy_port_ != -1) { + return detail::create_client_socket( + proxy_host_.c_str(), proxy_port_, address_family_, tcp_nodelay_, + socket_options_, connection_timeout_sec_, connection_timeout_usec_, + read_timeout_sec_, read_timeout_usec_, write_timeout_sec_, + write_timeout_usec_, interface_, error); + } + return detail::create_client_socket( + host_.c_str(), port_, address_family_, tcp_nodelay_, socket_options_, + connection_timeout_sec_, connection_timeout_usec_, read_timeout_sec_, + read_timeout_usec_, write_timeout_sec_, write_timeout_usec_, interface_, + error); +} + +inline bool ClientImpl::create_and_connect_socket(Socket &socket, + Error &error) { + auto sock = create_client_socket(error); + if (sock == INVALID_SOCKET) { return false; } + socket.sock = sock; + return true; +} + +inline void ClientImpl::shutdown_ssl(Socket & /*socket*/, + bool /*shutdown_gracefully*/) { + // If there are any requests in flight from threads other than us, then it's + // a thread-unsafe race because individual ssl* objects are not thread-safe. + assert(socket_requests_in_flight_ == 0 || + socket_requests_are_from_thread_ == std::this_thread::get_id()); +} + +inline void ClientImpl::shutdown_socket(Socket &socket) { + if (socket.sock == INVALID_SOCKET) { return; } + detail::shutdown_socket(socket.sock); +} + +inline void ClientImpl::close_socket(Socket &socket) { + // If there are requests in flight in another thread, usually closing + // the socket will be fine and they will simply receive an error when + // using the closed socket, but it is still a bug since rarely the OS + // may reassign the socket id to be used for a new socket, and then + // suddenly they will be operating on a live socket that is different + // than the one they intended! + assert(socket_requests_in_flight_ == 0 || + socket_requests_are_from_thread_ == std::this_thread::get_id()); + + // It is also a bug if this happens while SSL is still active +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + assert(socket.ssl == nullptr); +#endif + if (socket.sock == INVALID_SOCKET) { return; } + detail::close_socket(socket.sock); + socket.sock = INVALID_SOCKET; +} + +inline bool ClientImpl::read_response_line(Stream &strm, const Request &req, + Response &res) { + std::array buf; + + detail::stream_line_reader line_reader(strm, buf.data(), buf.size()); + + if (!line_reader.getline()) { return false; } + + const static std::regex re("(HTTP/1\\.[01]) (\\d{3})(?: (.*?))?\r\n"); + + std::cmatch m; + if (!std::regex_match(line_reader.ptr(), m, re)) { + return req.method == "CONNECT"; + } + res.version = std::string(m[1]); + res.status = std::stoi(std::string(m[2])); + res.reason = std::string(m[3]); + + // Ignore '100 Continue' + while (res.status == 100) { + if (!line_reader.getline()) { return false; } // CRLF + if (!line_reader.getline()) { return false; } // next response line + + if (!std::regex_match(line_reader.ptr(), m, re)) { return false; } + res.version = std::string(m[1]); + res.status = std::stoi(std::string(m[2])); + res.reason = std::string(m[3]); + } + + return true; +} + +inline bool ClientImpl::send(Request &req, Response &res, Error &error) { + std::lock_guard request_mutex_guard(request_mutex_); + + { + std::lock_guard guard(socket_mutex_); + // Set this to false immediately - if it ever gets set to true by the end of + // the request, we know another thread instructed us to close the socket. + socket_should_be_closed_when_request_is_done_ = false; + + auto is_alive = false; + if (socket_.is_open()) { + is_alive = detail::select_write(socket_.sock, 0, 0) > 0; + if (!is_alive) { + // Attempt to avoid sigpipe by shutting down nongracefully if it seems + // like the other side has already closed the connection Also, there + // cannot be any requests in flight from other threads since we locked + // request_mutex_, so safe to close everything immediately + const bool shutdown_gracefully = false; + shutdown_ssl(socket_, shutdown_gracefully); + shutdown_socket(socket_); + close_socket(socket_); + } + } + + if (!is_alive) { + if (!create_and_connect_socket(socket_, error)) { return false; } + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + // TODO: refactoring + if (is_ssl()) { + auto &scli = static_cast(*this); + if (!proxy_host_.empty() && proxy_port_ != -1) { + bool success = false; + if (!scli.connect_with_proxy(socket_, res, success, error)) { + return success; + } + } + + if (!scli.initialize_ssl(socket_, error)) { return false; } + } +#endif + } + + // Mark the current socket as being in use so that it cannot be closed by + // anyone else while this request is ongoing, even though we will be + // releasing the mutex. + if (socket_requests_in_flight_ > 1) { + assert(socket_requests_are_from_thread_ == std::this_thread::get_id()); + } + socket_requests_in_flight_ += 1; + socket_requests_are_from_thread_ = std::this_thread::get_id(); + } + + for (const auto &header : default_headers_) { + if (req.headers.find(header.first) == req.headers.end()) { + req.headers.insert(header); + } + } + + auto close_connection = !keep_alive_; + auto ret = process_socket(socket_, [&](Stream &strm) { + return handle_request(strm, req, res, close_connection, error); + }); + + // Briefly lock mutex in order to mark that a request is no longer ongoing + { + std::lock_guard guard(socket_mutex_); + socket_requests_in_flight_ -= 1; + if (socket_requests_in_flight_ <= 0) { + assert(socket_requests_in_flight_ == 0); + socket_requests_are_from_thread_ = std::thread::id(); + } + + if (socket_should_be_closed_when_request_is_done_ || close_connection || + !ret) { + shutdown_ssl(socket_, true); + shutdown_socket(socket_); + close_socket(socket_); + } + } + + if (!ret) { + if (error == Error::Success) { error = Error::Unknown; } + } + + return ret; +} + +inline Result ClientImpl::send(const Request &req) { + auto req2 = req; + return send_(std::move(req2)); +} + +inline Result ClientImpl::send_(Request &&req) { + auto res = detail::make_unique(); + auto error = Error::Success; + auto ret = send(req, *res, error); + return Result{ret ? std::move(res) : nullptr, error, std::move(req.headers)}; +} + +inline bool ClientImpl::handle_request(Stream &strm, Request &req, + Response &res, bool close_connection, + Error &error) { + if (req.path.empty()) { + error = Error::Connection; + return false; + } + + auto req_save = req; + + bool ret; + + if (!is_ssl() && !proxy_host_.empty() && proxy_port_ != -1) { + auto req2 = req; + req2.path = "http://" + host_and_port_ + req.path; + ret = process_request(strm, req2, res, close_connection, error); + req = req2; + req.path = req_save.path; + } else { + ret = process_request(strm, req, res, close_connection, error); + } + + if (!ret) { return false; } + + if (300 < res.status && res.status < 400 && follow_location_) { + req = req_save; + ret = redirect(req, res, error); + } + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + if ((res.status == 401 || res.status == 407) && + req.authorization_count_ < 5) { + auto is_proxy = res.status == 407; + const auto &username = + is_proxy ? proxy_digest_auth_username_ : digest_auth_username_; + const auto &password = + is_proxy ? proxy_digest_auth_password_ : digest_auth_password_; + + if (!username.empty() && !password.empty()) { + std::map auth; + if (detail::parse_www_authenticate(res, auth, is_proxy)) { + Request new_req = req; + new_req.authorization_count_ += 1; + new_req.headers.erase(is_proxy ? "Proxy-Authorization" + : "Authorization"); + new_req.headers.insert(detail::make_digest_authentication_header( + req, auth, new_req.authorization_count_, detail::random_string(10), + username, password, is_proxy)); + + Response new_res; + + ret = send(new_req, new_res, error); + if (ret) { res = new_res; } + } + } + } +#endif + + return ret; +} + +inline bool ClientImpl::redirect(Request &req, Response &res, Error &error) { + if (req.redirect_count_ == 0) { + error = Error::ExceedRedirectCount; + return false; + } + + auto location = detail::decode_url(res.get_header_value("location"), true); + if (location.empty()) { return false; } + + const static std::regex re( + R"((?:(https?):)?(?://(?:\[([\d:]+)\]|([^:/?#]+))(?::(\d+))?)?([^?#]*(?:\?[^#]*)?)(?:#.*)?)"); + + std::smatch m; + if (!std::regex_match(location, m, re)) { return false; } + + auto scheme = is_ssl() ? "https" : "http"; + + auto next_scheme = m[1].str(); + auto next_host = m[2].str(); + if (next_host.empty()) { next_host = m[3].str(); } + auto port_str = m[4].str(); + auto next_path = m[5].str(); + + auto next_port = port_; + if (!port_str.empty()) { + next_port = std::stoi(port_str); + } else if (!next_scheme.empty()) { + next_port = next_scheme == "https" ? 443 : 80; + } + + if (next_scheme.empty()) { next_scheme = scheme; } + if (next_host.empty()) { next_host = host_; } + if (next_path.empty()) { next_path = "/"; } + + if (next_scheme == scheme && next_host == host_ && next_port == port_) { + return detail::redirect(*this, req, res, next_path, location, error); + } else { + if (next_scheme == "https") { +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + SSLClient cli(next_host.c_str(), next_port); + cli.copy_settings(*this); + if (ca_cert_store_) { cli.set_ca_cert_store(ca_cert_store_); } + return detail::redirect(cli, req, res, next_path, location, error); +#else + return false; +#endif + } else { + ClientImpl cli(next_host.c_str(), next_port); + cli.copy_settings(*this); + return detail::redirect(cli, req, res, next_path, location, error); + } + } +} + +inline bool ClientImpl::write_content_with_provider(Stream &strm, + const Request &req, + Error &error) { + auto is_shutting_down = []() { return false; }; + + if (req.is_chunked_content_provider_) { + // TODO: Brotli suport + std::unique_ptr compressor; +#ifdef CPPHTTPLIB_ZLIB_SUPPORT + if (compress_) { + compressor = detail::make_unique(); + } else +#endif + { + compressor = detail::make_unique(); + } + + return detail::write_content_chunked(strm, req.content_provider_, + is_shutting_down, *compressor, error); + } else { + return detail::write_content(strm, req.content_provider_, 0, + req.content_length_, is_shutting_down, error); + } +} // namespace httplib + +inline bool ClientImpl::write_request(Stream &strm, Request &req, + bool close_connection, Error &error) { + // Prepare additional headers + if (close_connection) { + if (!req.has_header("Connection")) { + req.headers.emplace("Connection", "close"); + } + } + + if (!req.has_header("Host")) { + if (is_ssl()) { + if (port_ == 443) { + req.headers.emplace("Host", host_); + } else { + req.headers.emplace("Host", host_and_port_); + } + } else { + if (port_ == 80) { + req.headers.emplace("Host", host_); + } else { + req.headers.emplace("Host", host_and_port_); + } + } + } + + if (!req.has_header("Accept")) { req.headers.emplace("Accept", "*/*"); } + + if (!req.has_header("User-Agent")) { + req.headers.emplace("User-Agent", "cpp-httplib/0.9"); + } + + if (req.body.empty()) { + if (req.content_provider_) { + if (!req.is_chunked_content_provider_) { + if (!req.has_header("Content-Length")) { + auto length = std::to_string(req.content_length_); + req.headers.emplace("Content-Length", length); + } + } + } else { + if (req.method == "POST" || req.method == "PUT" || + req.method == "PATCH") { + req.headers.emplace("Content-Length", "0"); + } + } + } else { + if (!req.has_header("Content-Type")) { + req.headers.emplace("Content-Type", "text/plain"); + } + + if (!req.has_header("Content-Length")) { + auto length = std::to_string(req.body.size()); + req.headers.emplace("Content-Length", length); + } + } + + if (!basic_auth_password_.empty() || !basic_auth_username_.empty()) { + if (!req.has_header("Authorization")) { + req.headers.insert(make_basic_authentication_header( + basic_auth_username_, basic_auth_password_, false)); + } + } + + if (!proxy_basic_auth_username_.empty() && + !proxy_basic_auth_password_.empty()) { + if (!req.has_header("Proxy-Authorization")) { + req.headers.insert(make_basic_authentication_header( + proxy_basic_auth_username_, proxy_basic_auth_password_, true)); + } + } + + if (!bearer_token_auth_token_.empty()) { + if (!req.has_header("Authorization")) { + req.headers.insert(make_bearer_token_authentication_header( + bearer_token_auth_token_, false)); + } + } + + if (!proxy_bearer_token_auth_token_.empty()) { + if (!req.has_header("Proxy-Authorization")) { + req.headers.insert(make_bearer_token_authentication_header( + proxy_bearer_token_auth_token_, true)); + } + } + + // Request line and headers + { + detail::BufferStream bstrm; + + const auto &path = url_encode_ ? detail::encode_url(req.path) : req.path; + bstrm.write_format("%s %s HTTP/1.1\r\n", req.method.c_str(), path.c_str()); + + detail::write_headers(bstrm, req.headers); + + // Flush buffer + auto &data = bstrm.get_buffer(); + if (!detail::write_data(strm, data.data(), data.size())) { + error = Error::Write; + return false; + } + } + + // Body + if (req.body.empty()) { + return write_content_with_provider(strm, req, error); + } + + return detail::write_data(strm, req.body.data(), req.body.size()); +} + +inline std::unique_ptr ClientImpl::send_with_content_provider( + Request &req, + // const char *method, const char *path, const Headers &headers, + const char *body, size_t content_length, ContentProvider content_provider, + ContentProviderWithoutLength content_provider_without_length, + const char *content_type, Error &error) { + + // Request req; + // req.method = method; + // req.headers = headers; + // req.path = path; + + if (content_type) { req.headers.emplace("Content-Type", content_type); } + +#ifdef CPPHTTPLIB_ZLIB_SUPPORT + if (compress_) { req.headers.emplace("Content-Encoding", "gzip"); } +#endif + +#ifdef CPPHTTPLIB_ZLIB_SUPPORT + if (compress_ && !content_provider_without_length) { + // TODO: Brotli support + detail::gzip_compressor compressor; + + if (content_provider) { + auto ok = true; + size_t offset = 0; + DataSink data_sink; + + data_sink.write = [&](const char *data, size_t data_len) -> bool { + if (ok) { + auto last = offset + data_len == content_length; + + auto ret = compressor.compress( + data, data_len, last, [&](const char *data, size_t data_len) { + req.body.append(data, data_len); + return true; + }); + + if (ret) { + offset += data_len; + } else { + ok = false; + } + } + return ok; + }; + + data_sink.is_writable = [&](void) { return ok && true; }; + + while (ok && offset < content_length) { + if (!content_provider(offset, content_length - offset, data_sink)) { + error = Error::Canceled; + return nullptr; + } + } + } else { + if (!compressor.compress(body, content_length, true, + [&](const char *data, size_t data_len) { + req.body.append(data, data_len); + return true; + })) { + error = Error::Compression; + return nullptr; + } + } + } else +#endif + { + if (content_provider) { + req.content_length_ = content_length; + req.content_provider_ = std::move(content_provider); + req.is_chunked_content_provider_ = false; + } else if (content_provider_without_length) { + req.content_length_ = 0; + req.content_provider_ = detail::ContentProviderAdapter( + std::move(content_provider_without_length)); + req.is_chunked_content_provider_ = true; + req.headers.emplace("Transfer-Encoding", "chunked"); + } else { + req.body.assign(body, content_length); + ; + } + } + + auto res = detail::make_unique(); + return send(req, *res, error) ? std::move(res) : nullptr; +} + +inline Result ClientImpl::send_with_content_provider( + const char *method, const char *path, const Headers &headers, + const char *body, size_t content_length, ContentProvider content_provider, + ContentProviderWithoutLength content_provider_without_length, + const char *content_type) { + Request req; + req.method = method; + req.headers = headers; + req.path = path; + + auto error = Error::Success; + + auto res = send_with_content_provider( + req, + // method, path, headers, + body, content_length, std::move(content_provider), + std::move(content_provider_without_length), content_type, error); + + return Result{std::move(res), error, std::move(req.headers)}; +} + +inline std::string +ClientImpl::adjust_host_string(const std::string &host) const { + if (host.find(':') != std::string::npos) { return "[" + host + "]"; } + return host; +} + +inline bool ClientImpl::process_request(Stream &strm, Request &req, + Response &res, bool close_connection, + Error &error) { + // Send request + if (!write_request(strm, req, close_connection, error)) { return false; } + + // Receive response and headers + if (!read_response_line(strm, req, res) || + !detail::read_headers(strm, res.headers)) { + error = Error::Read; + return false; + } + + // Body + if ((res.status != 204) && req.method != "HEAD" && req.method != "CONNECT") { + auto redirect = 300 < res.status && res.status < 400 && follow_location_; + + if (req.response_handler && !redirect) { + if (!req.response_handler(res)) { + error = Error::Canceled; + return false; + } + } + + auto out = + req.content_receiver + ? static_cast( + [&](const char *buf, size_t n, uint64_t off, uint64_t len) { + if (redirect) { return true; } + auto ret = req.content_receiver(buf, n, off, len); + if (!ret) { error = Error::Canceled; } + return ret; + }) + : static_cast( + [&](const char *buf, size_t n, uint64_t /*off*/, + uint64_t /*len*/) { + if (res.body.size() + n > res.body.max_size()) { + return false; + } + res.body.append(buf, n); + return true; + }); + + auto progress = [&](uint64_t current, uint64_t total) { + if (!req.progress || redirect) { return true; } + auto ret = req.progress(current, total); + if (!ret) { error = Error::Canceled; } + return ret; + }; + + int dummy_status; + if (!detail::read_content(strm, res, (std::numeric_limits::max)(), + dummy_status, std::move(progress), std::move(out), + decompress_)) { + if (error != Error::Canceled) { error = Error::Read; } + return false; + } + } + + if (res.get_header_value("Connection") == "close" || + (res.version == "HTTP/1.0" && res.reason != "Connection established")) { + // TODO this requires a not-entirely-obvious chain of calls to be correct + // for this to be safe. Maybe a code refactor (such as moving this out to + // the send function and getting rid of the recursiveness of the mutex) + // could make this more obvious. + + // This is safe to call because process_request is only called by + // handle_request which is only called by send, which locks the request + // mutex during the process. It would be a bug to call it from a different + // thread since it's a thread-safety issue to do these things to the socket + // if another thread is using the socket. + std::lock_guard guard(socket_mutex_); + shutdown_ssl(socket_, true); + shutdown_socket(socket_); + close_socket(socket_); + } + + // Log + if (logger_) { logger_(req, res); } + + return true; +} + +inline bool +ClientImpl::process_socket(const Socket &socket, + std::function callback) { + return detail::process_client_socket( + socket.sock, read_timeout_sec_, read_timeout_usec_, write_timeout_sec_, + write_timeout_usec_, std::move(callback)); +} + +inline bool ClientImpl::is_ssl() const { return false; } + +inline Result ClientImpl::Get(const char *path) { + return Get(path, Headers(), Progress()); +} + +inline Result ClientImpl::Get(const char *path, Progress progress) { + return Get(path, Headers(), std::move(progress)); +} + +inline Result ClientImpl::Get(const char *path, const Headers &headers) { + return Get(path, headers, Progress()); +} + +inline Result ClientImpl::Get(const char *path, const Headers &headers, + Progress progress) { + Request req; + req.method = "GET"; + req.path = path; + req.headers = headers; + req.progress = std::move(progress); + + return send_(std::move(req)); +} + +inline Result ClientImpl::Get(const char *path, + ContentReceiver content_receiver) { + return Get(path, Headers(), nullptr, std::move(content_receiver), nullptr); +} + +inline Result ClientImpl::Get(const char *path, + ContentReceiver content_receiver, + Progress progress) { + return Get(path, Headers(), nullptr, std::move(content_receiver), + std::move(progress)); +} + +inline Result ClientImpl::Get(const char *path, const Headers &headers, + ContentReceiver content_receiver) { + return Get(path, headers, nullptr, std::move(content_receiver), nullptr); +} + +inline Result ClientImpl::Get(const char *path, const Headers &headers, + ContentReceiver content_receiver, + Progress progress) { + return Get(path, headers, nullptr, std::move(content_receiver), + std::move(progress)); +} + +inline Result ClientImpl::Get(const char *path, + ResponseHandler response_handler, + ContentReceiver content_receiver) { + return Get(path, Headers(), std::move(response_handler), + std::move(content_receiver), nullptr); +} + +inline Result ClientImpl::Get(const char *path, const Headers &headers, + ResponseHandler response_handler, + ContentReceiver content_receiver) { + return Get(path, headers, std::move(response_handler), + std::move(content_receiver), nullptr); +} + +inline Result ClientImpl::Get(const char *path, + ResponseHandler response_handler, + ContentReceiver content_receiver, + Progress progress) { + return Get(path, Headers(), std::move(response_handler), + std::move(content_receiver), std::move(progress)); +} + +inline Result ClientImpl::Get(const char *path, const Headers &headers, + ResponseHandler response_handler, + ContentReceiver content_receiver, + Progress progress) { + Request req; + req.method = "GET"; + req.path = path; + req.headers = headers; + req.response_handler = std::move(response_handler); + req.content_receiver = + [content_receiver](const char *data, size_t data_length, + uint64_t /*offset*/, uint64_t /*total_length*/) { + return content_receiver(data, data_length); + }; + req.progress = std::move(progress); + + return send_(std::move(req)); +} + +inline Result ClientImpl::Get(const char *path, const Params ¶ms, + const Headers &headers, Progress progress) { + if (params.empty()) { return Get(path, headers); } + + std::string path_with_query = detail::append_query_params(path, params); + return Get(path_with_query.c_str(), headers, progress); +} + +inline Result ClientImpl::Get(const char *path, const Params ¶ms, + const Headers &headers, + ContentReceiver content_receiver, + Progress progress) { + return Get(path, params, headers, nullptr, content_receiver, progress); +} + +inline Result ClientImpl::Get(const char *path, const Params ¶ms, + const Headers &headers, + ResponseHandler response_handler, + ContentReceiver content_receiver, + Progress progress) { + if (params.empty()) { + return Get(path, headers, response_handler, content_receiver, progress); + } + + std::string path_with_query = detail::append_query_params(path, params); + return Get(path_with_query.c_str(), headers, response_handler, + content_receiver, progress); +} + +inline Result ClientImpl::Head(const char *path) { + return Head(path, Headers()); +} + +inline Result ClientImpl::Head(const char *path, const Headers &headers) { + Request req; + req.method = "HEAD"; + req.headers = headers; + req.path = path; + + return send_(std::move(req)); +} + +inline Result ClientImpl::Post(const char *path) { + return Post(path, std::string(), nullptr); +} + +inline Result ClientImpl::Post(const char *path, const char *body, + size_t content_length, + const char *content_type) { + return Post(path, Headers(), body, content_length, content_type); +} + +inline Result ClientImpl::Post(const char *path, const Headers &headers, + const char *body, size_t content_length, + const char *content_type) { + return send_with_content_provider("POST", path, headers, body, content_length, + nullptr, nullptr, content_type); +} + +inline Result ClientImpl::Post(const char *path, const std::string &body, + const char *content_type) { + return Post(path, Headers(), body, content_type); +} + +inline Result ClientImpl::Post(const char *path, const Headers &headers, + const std::string &body, + const char *content_type) { + return send_with_content_provider("POST", path, headers, body.data(), + body.size(), nullptr, nullptr, + content_type); +} + +inline Result ClientImpl::Post(const char *path, const Params ¶ms) { + return Post(path, Headers(), params); +} + +inline Result ClientImpl::Post(const char *path, size_t content_length, + ContentProvider content_provider, + const char *content_type) { + return Post(path, Headers(), content_length, std::move(content_provider), + content_type); +} + +inline Result ClientImpl::Post(const char *path, + ContentProviderWithoutLength content_provider, + const char *content_type) { + return Post(path, Headers(), std::move(content_provider), content_type); +} + +inline Result ClientImpl::Post(const char *path, const Headers &headers, + size_t content_length, + ContentProvider content_provider, + const char *content_type) { + return send_with_content_provider("POST", path, headers, nullptr, + content_length, std::move(content_provider), + nullptr, content_type); +} + +inline Result ClientImpl::Post(const char *path, const Headers &headers, + ContentProviderWithoutLength content_provider, + const char *content_type) { + return send_with_content_provider("POST", path, headers, nullptr, 0, nullptr, + std::move(content_provider), content_type); +} + +inline Result ClientImpl::Post(const char *path, const Headers &headers, + const Params ¶ms) { + auto query = detail::params_to_query_str(params); + return Post(path, headers, query, "application/x-www-form-urlencoded"); +} + +inline Result ClientImpl::Post(const char *path, + const MultipartFormDataItems &items) { + return Post(path, Headers(), items); +} + +inline Result ClientImpl::Post(const char *path, const Headers &headers, + const MultipartFormDataItems &items) { + return Post(path, headers, items, detail::make_multipart_data_boundary()); +} +inline Result ClientImpl::Post(const char *path, const Headers &headers, + const MultipartFormDataItems &items, + const std::string &boundary) { + for (size_t i = 0; i < boundary.size(); i++) { + char c = boundary[i]; + if (!std::isalnum(c) && c != '-' && c != '_') { + return Result{nullptr, Error::UnsupportedMultipartBoundaryChars}; + } + } + + std::string body; + + for (const auto &item : items) { + body += "--" + boundary + "\r\n"; + body += "Content-Disposition: form-data; name=\"" + item.name + "\""; + if (!item.filename.empty()) { + body += "; filename=\"" + item.filename + "\""; + } + body += "\r\n"; + if (!item.content_type.empty()) { + body += "Content-Type: " + item.content_type + "\r\n"; + } + body += "\r\n"; + body += item.content + "\r\n"; + } + + body += "--" + boundary + "--\r\n"; + + std::string content_type = "multipart/form-data; boundary=" + boundary; + return Post(path, headers, body, content_type.c_str()); +} + +inline Result ClientImpl::Put(const char *path) { + return Put(path, std::string(), nullptr); +} + +inline Result ClientImpl::Put(const char *path, const char *body, + size_t content_length, const char *content_type) { + return Put(path, Headers(), body, content_length, content_type); +} + +inline Result ClientImpl::Put(const char *path, const Headers &headers, + const char *body, size_t content_length, + const char *content_type) { + return send_with_content_provider("PUT", path, headers, body, content_length, + nullptr, nullptr, content_type); +} + +inline Result ClientImpl::Put(const char *path, const std::string &body, + const char *content_type) { + return Put(path, Headers(), body, content_type); +} + +inline Result ClientImpl::Put(const char *path, const Headers &headers, + const std::string &body, + const char *content_type) { + return send_with_content_provider("PUT", path, headers, body.data(), + body.size(), nullptr, nullptr, + content_type); +} + +inline Result ClientImpl::Put(const char *path, size_t content_length, + ContentProvider content_provider, + const char *content_type) { + return Put(path, Headers(), content_length, std::move(content_provider), + content_type); +} + +inline Result ClientImpl::Put(const char *path, + ContentProviderWithoutLength content_provider, + const char *content_type) { + return Put(path, Headers(), std::move(content_provider), content_type); +} + +inline Result ClientImpl::Put(const char *path, const Headers &headers, + size_t content_length, + ContentProvider content_provider, + const char *content_type) { + return send_with_content_provider("PUT", path, headers, nullptr, + content_length, std::move(content_provider), + nullptr, content_type); +} + +inline Result ClientImpl::Put(const char *path, const Headers &headers, + ContentProviderWithoutLength content_provider, + const char *content_type) { + return send_with_content_provider("PUT", path, headers, nullptr, 0, nullptr, + std::move(content_provider), content_type); +} + +inline Result ClientImpl::Put(const char *path, const Params ¶ms) { + return Put(path, Headers(), params); +} + +inline Result ClientImpl::Put(const char *path, const Headers &headers, + const Params ¶ms) { + auto query = detail::params_to_query_str(params); + return Put(path, headers, query, "application/x-www-form-urlencoded"); +} + +inline Result ClientImpl::Patch(const char *path) { + return Patch(path, std::string(), nullptr); +} + +inline Result ClientImpl::Patch(const char *path, const char *body, + size_t content_length, + const char *content_type) { + return Patch(path, Headers(), body, content_length, content_type); +} + +inline Result ClientImpl::Patch(const char *path, const Headers &headers, + const char *body, size_t content_length, + const char *content_type) { + return send_with_content_provider("PATCH", path, headers, body, + content_length, nullptr, nullptr, + content_type); +} + +inline Result ClientImpl::Patch(const char *path, const std::string &body, + const char *content_type) { + return Patch(path, Headers(), body, content_type); +} + +inline Result ClientImpl::Patch(const char *path, const Headers &headers, + const std::string &body, + const char *content_type) { + return send_with_content_provider("PATCH", path, headers, body.data(), + body.size(), nullptr, nullptr, + content_type); +} + +inline Result ClientImpl::Patch(const char *path, size_t content_length, + ContentProvider content_provider, + const char *content_type) { + return Patch(path, Headers(), content_length, std::move(content_provider), + content_type); +} + +inline Result ClientImpl::Patch(const char *path, + ContentProviderWithoutLength content_provider, + const char *content_type) { + return Patch(path, Headers(), std::move(content_provider), content_type); +} + +inline Result ClientImpl::Patch(const char *path, const Headers &headers, + size_t content_length, + ContentProvider content_provider, + const char *content_type) { + return send_with_content_provider("PATCH", path, headers, nullptr, + content_length, std::move(content_provider), + nullptr, content_type); +} + +inline Result ClientImpl::Patch(const char *path, const Headers &headers, + ContentProviderWithoutLength content_provider, + const char *content_type) { + return send_with_content_provider("PATCH", path, headers, nullptr, 0, nullptr, + std::move(content_provider), content_type); +} + +inline Result ClientImpl::Delete(const char *path) { + return Delete(path, Headers(), std::string(), nullptr); +} + +inline Result ClientImpl::Delete(const char *path, const Headers &headers) { + return Delete(path, headers, std::string(), nullptr); +} + +inline Result ClientImpl::Delete(const char *path, const char *body, + size_t content_length, + const char *content_type) { + return Delete(path, Headers(), body, content_length, content_type); +} + +inline Result ClientImpl::Delete(const char *path, const Headers &headers, + const char *body, size_t content_length, + const char *content_type) { + Request req; + req.method = "DELETE"; + req.headers = headers; + req.path = path; + + if (content_type) { req.headers.emplace("Content-Type", content_type); } + req.body.assign(body, content_length); + + return send_(std::move(req)); +} + +inline Result ClientImpl::Delete(const char *path, const std::string &body, + const char *content_type) { + return Delete(path, Headers(), body.data(), body.size(), content_type); +} + +inline Result ClientImpl::Delete(const char *path, const Headers &headers, + const std::string &body, + const char *content_type) { + return Delete(path, headers, body.data(), body.size(), content_type); +} + +inline Result ClientImpl::Options(const char *path) { + return Options(path, Headers()); +} + +inline Result ClientImpl::Options(const char *path, const Headers &headers) { + Request req; + req.method = "OPTIONS"; + req.headers = headers; + req.path = path; + + return send_(std::move(req)); +} + +inline size_t ClientImpl::is_socket_open() const { + std::lock_guard guard(socket_mutex_); + return socket_.is_open(); +} + +inline void ClientImpl::stop() { + std::lock_guard guard(socket_mutex_); + + // If there is anything ongoing right now, the ONLY thread-safe thing we can + // do is to shutdown_socket, so that threads using this socket suddenly + // discover they can't read/write any more and error out. Everything else + // (closing the socket, shutting ssl down) is unsafe because these actions are + // not thread-safe. + if (socket_requests_in_flight_ > 0) { + shutdown_socket(socket_); + + // Aside from that, we set a flag for the socket to be closed when we're + // done. + socket_should_be_closed_when_request_is_done_ = true; + return; + } + + // Otherwise, sitll holding the mutex, we can shut everything down ourselves + shutdown_ssl(socket_, true); + shutdown_socket(socket_); + close_socket(socket_); +} + +inline void ClientImpl::set_connection_timeout(time_t sec, time_t usec) { + connection_timeout_sec_ = sec; + connection_timeout_usec_ = usec; +} + +inline void ClientImpl::set_read_timeout(time_t sec, time_t usec) { + read_timeout_sec_ = sec; + read_timeout_usec_ = usec; +} + +inline void ClientImpl::set_write_timeout(time_t sec, time_t usec) { + write_timeout_sec_ = sec; + write_timeout_usec_ = usec; +} + +inline void ClientImpl::set_basic_auth(const char *username, + const char *password) { + basic_auth_username_ = username; + basic_auth_password_ = password; +} + +inline void ClientImpl::set_bearer_token_auth(const char *token) { + bearer_token_auth_token_ = token; +} + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +inline void ClientImpl::set_digest_auth(const char *username, + const char *password) { + digest_auth_username_ = username; + digest_auth_password_ = password; +} +#endif + +inline void ClientImpl::set_keep_alive(bool on) { keep_alive_ = on; } + +inline void ClientImpl::set_follow_location(bool on) { follow_location_ = on; } + +inline void ClientImpl::set_url_encode(bool on) { url_encode_ = on; } + +inline void ClientImpl::set_default_headers(Headers headers) { + default_headers_ = std::move(headers); +} + +inline void ClientImpl::set_address_family(int family) { + address_family_ = family; +} + +inline void ClientImpl::set_tcp_nodelay(bool on) { tcp_nodelay_ = on; } + +inline void ClientImpl::set_socket_options(SocketOptions socket_options) { + socket_options_ = std::move(socket_options); +} + +inline void ClientImpl::set_compress(bool on) { compress_ = on; } + +inline void ClientImpl::set_decompress(bool on) { decompress_ = on; } + +inline void ClientImpl::set_interface(const char *intf) { interface_ = intf; } + +inline void ClientImpl::set_proxy(const char *host, int port) { + proxy_host_ = host; + proxy_port_ = port; +} + +inline void ClientImpl::set_proxy_basic_auth(const char *username, + const char *password) { + proxy_basic_auth_username_ = username; + proxy_basic_auth_password_ = password; +} + +inline void ClientImpl::set_proxy_bearer_token_auth(const char *token) { + proxy_bearer_token_auth_token_ = token; +} + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +inline void ClientImpl::set_proxy_digest_auth(const char *username, + const char *password) { + proxy_digest_auth_username_ = username; + proxy_digest_auth_password_ = password; +} +#endif + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +inline void ClientImpl::set_ca_cert_path(const char *ca_cert_file_path, + const char *ca_cert_dir_path) { + if (ca_cert_file_path) { ca_cert_file_path_ = ca_cert_file_path; } + if (ca_cert_dir_path) { ca_cert_dir_path_ = ca_cert_dir_path; } +} + +inline void ClientImpl::set_ca_cert_store(X509_STORE *ca_cert_store) { + if (ca_cert_store && ca_cert_store != ca_cert_store_) { + ca_cert_store_ = ca_cert_store; + } +} +#endif + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +inline void ClientImpl::enable_server_certificate_verification(bool enabled) { + server_certificate_verification_ = enabled; +} +#endif + +inline void ClientImpl::set_logger(Logger logger) { + logger_ = std::move(logger); +} + +/* + * SSL Implementation + */ +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +namespace detail { + +template +inline SSL *ssl_new(socket_t sock, SSL_CTX *ctx, std::mutex &ctx_mutex, + U SSL_connect_or_accept, V setup) { + SSL *ssl = nullptr; + { + std::lock_guard guard(ctx_mutex); + ssl = SSL_new(ctx); + } + + if (ssl) { + set_nonblocking(sock, true); + auto bio = BIO_new_socket(static_cast(sock), BIO_NOCLOSE); + BIO_set_nbio(bio, 1); + SSL_set_bio(ssl, bio, bio); + + if (!setup(ssl) || SSL_connect_or_accept(ssl) != 1) { + SSL_shutdown(ssl); + { + std::lock_guard guard(ctx_mutex); + SSL_free(ssl); + } + set_nonblocking(sock, false); + return nullptr; + } + BIO_set_nbio(bio, 0); + set_nonblocking(sock, false); + } + + return ssl; +} + +inline void ssl_delete(std::mutex &ctx_mutex, SSL *ssl, + bool shutdown_gracefully) { + // sometimes we may want to skip this to try to avoid SIGPIPE if we know + // the remote has closed the network connection + // Note that it is not always possible to avoid SIGPIPE, this is merely a + // best-efforts. + if (shutdown_gracefully) { SSL_shutdown(ssl); } + + std::lock_guard guard(ctx_mutex); + SSL_free(ssl); +} + +template +bool ssl_connect_or_accept_nonblocking(socket_t sock, SSL *ssl, + U ssl_connect_or_accept, + time_t timeout_sec, + time_t timeout_usec) { + int res = 0; + while ((res = ssl_connect_or_accept(ssl)) != 1) { + auto err = SSL_get_error(ssl, res); + switch (err) { + case SSL_ERROR_WANT_READ: + if (select_read(sock, timeout_sec, timeout_usec) > 0) { continue; } + break; + case SSL_ERROR_WANT_WRITE: + if (select_write(sock, timeout_sec, timeout_usec) > 0) { continue; } + break; + default: break; + } + return false; + } + return true; +} + +template +inline bool +process_server_socket_ssl(SSL *ssl, socket_t sock, size_t keep_alive_max_count, + time_t keep_alive_timeout_sec, + time_t read_timeout_sec, time_t read_timeout_usec, + time_t write_timeout_sec, time_t write_timeout_usec, + T callback) { + return process_server_socket_core( + sock, keep_alive_max_count, keep_alive_timeout_sec, + [&](bool close_connection, bool &connection_closed) { + SSLSocketStream strm(sock, ssl, read_timeout_sec, read_timeout_usec, + write_timeout_sec, write_timeout_usec); + return callback(strm, close_connection, connection_closed); + }); +} + +template +inline bool +process_client_socket_ssl(SSL *ssl, socket_t sock, time_t read_timeout_sec, + time_t read_timeout_usec, time_t write_timeout_sec, + time_t write_timeout_usec, T callback) { + SSLSocketStream strm(sock, ssl, read_timeout_sec, read_timeout_usec, + write_timeout_sec, write_timeout_usec); + return callback(strm); +} + +#if OPENSSL_VERSION_NUMBER < 0x10100000L +static std::shared_ptr> openSSL_locks_; + +class SSLThreadLocks { +public: + SSLThreadLocks() { + openSSL_locks_ = + std::make_shared>(CRYPTO_num_locks()); + CRYPTO_set_locking_callback(locking_callback); + } + + ~SSLThreadLocks() { CRYPTO_set_locking_callback(nullptr); } + +private: + static void locking_callback(int mode, int type, const char * /*file*/, + int /*line*/) { + auto &lk = (*openSSL_locks_)[static_cast(type)]; + if (mode & CRYPTO_LOCK) { + lk.lock(); + } else { + lk.unlock(); + } + } +}; + +#endif + +class SSLInit { +public: + SSLInit() { +#if OPENSSL_VERSION_NUMBER < 0x1010001fL + SSL_load_error_strings(); + SSL_library_init(); +#else + OPENSSL_init_ssl( + OPENSSL_INIT_LOAD_SSL_STRINGS | OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL); +#endif + } + + ~SSLInit() { +#if OPENSSL_VERSION_NUMBER < 0x1010001fL + ERR_free_strings(); +#endif + } + +private: +#if OPENSSL_VERSION_NUMBER < 0x10100000L + SSLThreadLocks thread_init_; +#endif +}; + +// SSL socket stream implementation +inline SSLSocketStream::SSLSocketStream(socket_t sock, SSL *ssl, + time_t read_timeout_sec, + time_t read_timeout_usec, + time_t write_timeout_sec, + time_t write_timeout_usec) + : sock_(sock), ssl_(ssl), read_timeout_sec_(read_timeout_sec), + read_timeout_usec_(read_timeout_usec), + write_timeout_sec_(write_timeout_sec), + write_timeout_usec_(write_timeout_usec) { + SSL_clear_mode(ssl, SSL_MODE_AUTO_RETRY); +} + +inline SSLSocketStream::~SSLSocketStream() {} + +inline bool SSLSocketStream::is_readable() const { + return detail::select_read(sock_, read_timeout_sec_, read_timeout_usec_) > 0; +} + +inline bool SSLSocketStream::is_writable() const { + return detail::select_write(sock_, write_timeout_sec_, write_timeout_usec_) > + 0; +} + +inline ssize_t SSLSocketStream::read(char *ptr, size_t size) { + if (SSL_pending(ssl_) > 0) { + return SSL_read(ssl_, ptr, static_cast(size)); + } else if (is_readable()) { + auto ret = SSL_read(ssl_, ptr, static_cast(size)); + if (ret < 0) { + auto err = SSL_get_error(ssl_, ret); + int n = 1000; +#ifdef _WIN32 + while (--n >= 0 && + (err == SSL_ERROR_WANT_READ || + err == SSL_ERROR_SYSCALL && WSAGetLastError() == WSAETIMEDOUT)) { +#else + while (--n >= 0 && err == SSL_ERROR_WANT_READ) { +#endif + if (SSL_pending(ssl_) > 0) { + return SSL_read(ssl_, ptr, static_cast(size)); + } else if (is_readable()) { + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + ret = SSL_read(ssl_, ptr, static_cast(size)); + if (ret >= 0) { return ret; } + err = SSL_get_error(ssl_, ret); + } else { + return -1; + } + } + } + return ret; + } + return -1; +} + +inline ssize_t SSLSocketStream::write(const char *ptr, size_t size) { + if (is_writable()) { return SSL_write(ssl_, ptr, static_cast(size)); } + return -1; +} + +inline void SSLSocketStream::get_remote_ip_and_port(std::string &ip, + int &port) const { + detail::get_remote_ip_and_port(sock_, ip, port); +} + +inline socket_t SSLSocketStream::socket() const { return sock_; } + +static SSLInit sslinit_; + +} // namespace detail + +// SSL HTTP server implementation +inline SSLServer::SSLServer(const char *cert_path, const char *private_key_path, + const char *client_ca_cert_file_path, + const char *client_ca_cert_dir_path) { + ctx_ = SSL_CTX_new(TLS_method()); + + if (ctx_) { + SSL_CTX_set_options(ctx_, + SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | + SSL_OP_NO_COMPRESSION | + SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION); + + // auto ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); + // SSL_CTX_set_tmp_ecdh(ctx_, ecdh); + // EC_KEY_free(ecdh); + + if (SSL_CTX_use_certificate_chain_file(ctx_, cert_path) != 1 || + SSL_CTX_use_PrivateKey_file(ctx_, private_key_path, SSL_FILETYPE_PEM) != + 1) { + SSL_CTX_free(ctx_); + ctx_ = nullptr; + } else if (client_ca_cert_file_path || client_ca_cert_dir_path) { + // if (client_ca_cert_file_path) { + // auto list = SSL_load_client_CA_file(client_ca_cert_file_path); + // SSL_CTX_set_client_CA_list(ctx_, list); + // } + + SSL_CTX_load_verify_locations(ctx_, client_ca_cert_file_path, + client_ca_cert_dir_path); + + SSL_CTX_set_verify( + ctx_, + SSL_VERIFY_PEER | + SSL_VERIFY_FAIL_IF_NO_PEER_CERT, // SSL_VERIFY_CLIENT_ONCE, + nullptr); + } + } +} + +inline SSLServer::SSLServer(X509 *cert, EVP_PKEY *private_key, + X509_STORE *client_ca_cert_store) { + ctx_ = SSL_CTX_new(SSLv23_server_method()); + + if (ctx_) { + SSL_CTX_set_options(ctx_, + SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | + SSL_OP_NO_COMPRESSION | + SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION); + + if (SSL_CTX_use_certificate(ctx_, cert) != 1 || + SSL_CTX_use_PrivateKey(ctx_, private_key) != 1) { + SSL_CTX_free(ctx_); + ctx_ = nullptr; + } else if (client_ca_cert_store) { + + SSL_CTX_set_cert_store(ctx_, client_ca_cert_store); + + SSL_CTX_set_verify( + ctx_, + SSL_VERIFY_PEER | + SSL_VERIFY_FAIL_IF_NO_PEER_CERT, // SSL_VERIFY_CLIENT_ONCE, + nullptr); + } + } +} + +inline SSLServer::~SSLServer() { + if (ctx_) { SSL_CTX_free(ctx_); } +} + +inline bool SSLServer::is_valid() const { return ctx_; } + +inline bool SSLServer::process_and_close_socket(socket_t sock) { + auto ssl = detail::ssl_new( + sock, ctx_, ctx_mutex_, + [&](SSL *ssl) { + return detail::ssl_connect_or_accept_nonblocking( + sock, ssl, SSL_accept, read_timeout_sec_, read_timeout_usec_); + }, + [](SSL * /*ssl*/) { return true; }); + + bool ret = false; + if (ssl) { + ret = detail::process_server_socket_ssl( + ssl, sock, keep_alive_max_count_, keep_alive_timeout_sec_, + read_timeout_sec_, read_timeout_usec_, write_timeout_sec_, + write_timeout_usec_, + [this, ssl](Stream &strm, bool close_connection, + bool &connection_closed) { + return process_request(strm, close_connection, connection_closed, + [&](Request &req) { req.ssl = ssl; }); + }); + + // Shutdown gracefully if the result seemed successful, non-gracefully if + // the connection appeared to be closed. + const bool shutdown_gracefully = ret; + detail::ssl_delete(ctx_mutex_, ssl, shutdown_gracefully); + } + + detail::shutdown_socket(sock); + detail::close_socket(sock); + return ret; +} + +// SSL HTTP client implementation +inline SSLClient::SSLClient(const std::string &host) + : SSLClient(host, 443, std::string(), std::string()) {} + +inline SSLClient::SSLClient(const std::string &host, int port) + : SSLClient(host, port, std::string(), std::string()) {} + +inline SSLClient::SSLClient(const std::string &host, int port, + const std::string &client_cert_path, + const std::string &client_key_path) + : ClientImpl(host, port, client_cert_path, client_key_path) { + ctx_ = SSL_CTX_new(SSLv23_client_method()); + + detail::split(&host_[0], &host_[host_.size()], '.', + [&](const char *b, const char *e) { + host_components_.emplace_back(std::string(b, e)); + }); + if (!client_cert_path.empty() && !client_key_path.empty()) { + if (SSL_CTX_use_certificate_file(ctx_, client_cert_path.c_str(), + SSL_FILETYPE_PEM) != 1 || + SSL_CTX_use_PrivateKey_file(ctx_, client_key_path.c_str(), + SSL_FILETYPE_PEM) != 1) { + SSL_CTX_free(ctx_); + ctx_ = nullptr; + } + } +} + +inline SSLClient::SSLClient(const std::string &host, int port, + X509 *client_cert, EVP_PKEY *client_key) + : ClientImpl(host, port) { + ctx_ = SSL_CTX_new(SSLv23_client_method()); + + detail::split(&host_[0], &host_[host_.size()], '.', + [&](const char *b, const char *e) { + host_components_.emplace_back(std::string(b, e)); + }); + if (client_cert != nullptr && client_key != nullptr) { + if (SSL_CTX_use_certificate(ctx_, client_cert) != 1 || + SSL_CTX_use_PrivateKey(ctx_, client_key) != 1) { + SSL_CTX_free(ctx_); + ctx_ = nullptr; + } + } +} + +inline SSLClient::~SSLClient() { + if (ctx_) { SSL_CTX_free(ctx_); } + // Make sure to shut down SSL since shutdown_ssl will resolve to the + // base function rather than the derived function once we get to the + // base class destructor, and won't free the SSL (causing a leak). + shutdown_ssl_impl(socket_, true); +} + +inline bool SSLClient::is_valid() const { return ctx_; } + +inline void SSLClient::set_ca_cert_store(X509_STORE *ca_cert_store) { + if (ca_cert_store) { + if (ctx_) { + if (SSL_CTX_get_cert_store(ctx_) != ca_cert_store) { + // Free memory allocated for old cert and use new store `ca_cert_store` + SSL_CTX_set_cert_store(ctx_, ca_cert_store); + } + } else { + X509_STORE_free(ca_cert_store); + } + } +} + +inline long SSLClient::get_openssl_verify_result() const { + return verify_result_; +} + +inline SSL_CTX *SSLClient::ssl_context() const { return ctx_; } + +inline bool SSLClient::create_and_connect_socket(Socket &socket, Error &error) { + return is_valid() && ClientImpl::create_and_connect_socket(socket, error); +} + +// Assumes that socket_mutex_ is locked and that there are no requests in flight +inline bool SSLClient::connect_with_proxy(Socket &socket, Response &res, + bool &success, Error &error) { + success = true; + Response res2; + if (!detail::process_client_socket( + socket.sock, read_timeout_sec_, read_timeout_usec_, + write_timeout_sec_, write_timeout_usec_, [&](Stream &strm) { + Request req2; + req2.method = "CONNECT"; + req2.path = host_and_port_; + return process_request(strm, req2, res2, false, error); + })) { + // Thread-safe to close everything because we are assuming there are no + // requests in flight + shutdown_ssl(socket, true); + shutdown_socket(socket); + close_socket(socket); + success = false; + return false; + } + + if (res2.status == 407) { + if (!proxy_digest_auth_username_.empty() && + !proxy_digest_auth_password_.empty()) { + std::map auth; + if (detail::parse_www_authenticate(res2, auth, true)) { + Response res3; + if (!detail::process_client_socket( + socket.sock, read_timeout_sec_, read_timeout_usec_, + write_timeout_sec_, write_timeout_usec_, [&](Stream &strm) { + Request req3; + req3.method = "CONNECT"; + req3.path = host_and_port_; + req3.headers.insert(detail::make_digest_authentication_header( + req3, auth, 1, detail::random_string(10), + proxy_digest_auth_username_, proxy_digest_auth_password_, + true)); + return process_request(strm, req3, res3, false, error); + })) { + // Thread-safe to close everything because we are assuming there are + // no requests in flight + shutdown_ssl(socket, true); + shutdown_socket(socket); + close_socket(socket); + success = false; + return false; + } + } + } else { + res = res2; + return false; + } + } + + return true; +} + +inline bool SSLClient::load_certs() { + bool ret = true; + + std::call_once(initialize_cert_, [&]() { + std::lock_guard guard(ctx_mutex_); + if (!ca_cert_file_path_.empty()) { + if (!SSL_CTX_load_verify_locations(ctx_, ca_cert_file_path_.c_str(), + nullptr)) { + ret = false; + } + } else if (!ca_cert_dir_path_.empty()) { + if (!SSL_CTX_load_verify_locations(ctx_, nullptr, + ca_cert_dir_path_.c_str())) { + ret = false; + } + } else { +#ifdef _WIN32 + detail::load_system_certs_on_windows(SSL_CTX_get_cert_store(ctx_)); +#else + SSL_CTX_set_default_verify_paths(ctx_); +#endif + } + }); + + return ret; +} + +inline bool SSLClient::initialize_ssl(Socket &socket, Error &error) { + auto ssl = detail::ssl_new( + socket.sock, ctx_, ctx_mutex_, + [&](SSL *ssl) { + if (server_certificate_verification_) { + if (!load_certs()) { + error = Error::SSLLoadingCerts; + return false; + } + SSL_set_verify(ssl, SSL_VERIFY_NONE, nullptr); + } + + if (!detail::ssl_connect_or_accept_nonblocking( + socket.sock, ssl, SSL_connect, connection_timeout_sec_, + connection_timeout_usec_)) { + error = Error::SSLConnection; + return false; + } + + if (server_certificate_verification_) { + verify_result_ = SSL_get_verify_result(ssl); + + if (verify_result_ != X509_V_OK) { + error = Error::SSLServerVerification; + return false; + } + + auto server_cert = SSL_get_peer_certificate(ssl); + + if (server_cert == nullptr) { + error = Error::SSLServerVerification; + return false; + } + + if (!verify_host(server_cert)) { + X509_free(server_cert); + error = Error::SSLServerVerification; + return false; + } + X509_free(server_cert); + } + + return true; + }, + [&](SSL *ssl) { + SSL_set_tlsext_host_name(ssl, host_.c_str()); + return true; + }); + + if (ssl) { + socket.ssl = ssl; + return true; + } + + shutdown_socket(socket); + close_socket(socket); + return false; +} + +inline void SSLClient::shutdown_ssl(Socket &socket, bool shutdown_gracefully) { + shutdown_ssl_impl(socket, shutdown_gracefully); +} + +inline void SSLClient::shutdown_ssl_impl(Socket &socket, + bool shutdown_gracefully) { + if (socket.sock == INVALID_SOCKET) { + assert(socket.ssl == nullptr); + return; + } + if (socket.ssl) { + detail::ssl_delete(ctx_mutex_, socket.ssl, shutdown_gracefully); + socket.ssl = nullptr; + } + assert(socket.ssl == nullptr); +} + +inline bool +SSLClient::process_socket(const Socket &socket, + std::function callback) { + assert(socket.ssl); + return detail::process_client_socket_ssl( + socket.ssl, socket.sock, read_timeout_sec_, read_timeout_usec_, + write_timeout_sec_, write_timeout_usec_, std::move(callback)); +} + +inline bool SSLClient::is_ssl() const { return true; } + +inline bool SSLClient::verify_host(X509 *server_cert) const { + /* Quote from RFC2818 section 3.1 "Server Identity" + + If a subjectAltName extension of type dNSName is present, that MUST + be used as the identity. Otherwise, the (most specific) Common Name + field in the Subject field of the certificate MUST be used. Although + the use of the Common Name is existing practice, it is deprecated and + Certification Authorities are encouraged to use the dNSName instead. + + Matching is performed using the matching rules specified by + [RFC2459]. If more than one identity of a given type is present in + the certificate (e.g., more than one dNSName name, a match in any one + of the set is considered acceptable.) Names may contain the wildcard + character * which is considered to match any single domain name + component or component fragment. E.g., *.a.com matches foo.a.com but + not bar.foo.a.com. f*.com matches foo.com but not bar.com. + + In some cases, the URI is specified as an IP address rather than a + hostname. In this case, the iPAddress subjectAltName must be present + in the certificate and must exactly match the IP in the URI. + + */ + return verify_host_with_subject_alt_name(server_cert) || + verify_host_with_common_name(server_cert); +} + +inline bool +SSLClient::verify_host_with_subject_alt_name(X509 *server_cert) const { + auto ret = false; + + auto type = GEN_DNS; + + struct in6_addr addr6; + struct in_addr addr; + size_t addr_len = 0; + +#ifndef __MINGW32__ + if (inet_pton(AF_INET6, host_.c_str(), &addr6)) { + type = GEN_IPADD; + addr_len = sizeof(struct in6_addr); + } else if (inet_pton(AF_INET, host_.c_str(), &addr)) { + type = GEN_IPADD; + addr_len = sizeof(struct in_addr); + } +#endif + + auto alt_names = static_cast( + X509_get_ext_d2i(server_cert, NID_subject_alt_name, nullptr, nullptr)); + + if (alt_names) { + auto dsn_matched = false; + auto ip_mached = false; + + auto count = sk_GENERAL_NAME_num(alt_names); + + for (decltype(count) i = 0; i < count && !dsn_matched; i++) { + auto val = sk_GENERAL_NAME_value(alt_names, i); + if (val->type == type) { + auto name = (const char *)ASN1_STRING_get0_data(val->d.ia5); + auto name_len = (size_t)ASN1_STRING_length(val->d.ia5); + + switch (type) { + case GEN_DNS: dsn_matched = check_host_name(name, name_len); break; + + case GEN_IPADD: + if (!memcmp(&addr6, name, addr_len) || + !memcmp(&addr, name, addr_len)) { + ip_mached = true; + } + break; + } + } + } + + if (dsn_matched || ip_mached) { ret = true; } + } + + GENERAL_NAMES_free((STACK_OF(GENERAL_NAME) *)alt_names); + return ret; +} + +inline bool SSLClient::verify_host_with_common_name(X509 *server_cert) const { + const auto subject_name = X509_get_subject_name(server_cert); + + if (subject_name != nullptr) { + char name[BUFSIZ]; + auto name_len = X509_NAME_get_text_by_NID(subject_name, NID_commonName, + name, sizeof(name)); + + if (name_len != -1) { + return check_host_name(name, static_cast(name_len)); + } + } + + return false; +} + +inline bool SSLClient::check_host_name(const char *pattern, + size_t pattern_len) const { + if (host_.size() == pattern_len && host_ == pattern) { return true; } + + // Wildcard match + // https://bugs.launchpad.net/ubuntu/+source/firefox-3.0/+bug/376484 + std::vector pattern_components; + detail::split(&pattern[0], &pattern[pattern_len], '.', + [&](const char *b, const char *e) { + pattern_components.emplace_back(std::string(b, e)); + }); + + if (host_components_.size() != pattern_components.size()) { return false; } + + auto itr = pattern_components.begin(); + for (const auto &h : host_components_) { + auto &p = *itr; + if (p != h && p != "*") { + auto partial_match = (p.size() > 0 && p[p.size() - 1] == '*' && + !p.compare(0, p.size() - 1, h)); + if (!partial_match) { return false; } + } + ++itr; + } + + return true; +} +#endif + +// Universal client implementation +inline Client::Client(const std::string &scheme_host_port) + : Client(scheme_host_port, std::string(), std::string()) {} + +inline Client::Client(const std::string &scheme_host_port, + const std::string &client_cert_path, + const std::string &client_key_path) { + const static std::regex re( + R"((?:([a-z]+):\/\/)?(?:\[([\d:]+)\]|([^:/?#]+))(?::(\d+))?)"); + + std::smatch m; + if (std::regex_match(scheme_host_port, m, re)) { + auto scheme = m[1].str(); + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + if (!scheme.empty() && (scheme != "http" && scheme != "https")) { +#else + if (!scheme.empty() && scheme != "http") { +#endif + std::string msg = "'" + scheme + "' scheme is not supported."; + throw std::invalid_argument(msg); + return; + } + + auto is_ssl = scheme == "https"; + + auto host = m[2].str(); + if (host.empty()) { host = m[3].str(); } + + auto port_str = m[4].str(); + auto port = !port_str.empty() ? std::stoi(port_str) : (is_ssl ? 443 : 80); + + if (is_ssl) { +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + cli_ = detail::make_unique(host.c_str(), port, + client_cert_path, client_key_path); + is_ssl_ = is_ssl; +#endif + } else { + cli_ = detail::make_unique(host.c_str(), port, + client_cert_path, client_key_path); + } + } else { + cli_ = detail::make_unique(scheme_host_port, 80, + client_cert_path, client_key_path); + } +} + +inline Client::Client(const std::string &host, int port) + : cli_(detail::make_unique(host, port)) {} + +inline Client::Client(const std::string &host, int port, + const std::string &client_cert_path, + const std::string &client_key_path) + : cli_(detail::make_unique(host, port, client_cert_path, + client_key_path)) {} + +inline Client::~Client() {} + +inline bool Client::is_valid() const { + return cli_ != nullptr && cli_->is_valid(); +} + +inline Result Client::Get(const char *path) { return cli_->Get(path); } +inline Result Client::Get(const char *path, const Headers &headers) { + return cli_->Get(path, headers); +} +inline Result Client::Get(const char *path, Progress progress) { + return cli_->Get(path, std::move(progress)); +} +inline Result Client::Get(const char *path, const Headers &headers, + Progress progress) { + return cli_->Get(path, headers, std::move(progress)); +} +inline Result Client::Get(const char *path, ContentReceiver content_receiver) { + return cli_->Get(path, std::move(content_receiver)); +} +inline Result Client::Get(const char *path, const Headers &headers, + ContentReceiver content_receiver) { + return cli_->Get(path, headers, std::move(content_receiver)); +} +inline Result Client::Get(const char *path, ContentReceiver content_receiver, + Progress progress) { + return cli_->Get(path, std::move(content_receiver), std::move(progress)); +} +inline Result Client::Get(const char *path, const Headers &headers, + ContentReceiver content_receiver, Progress progress) { + return cli_->Get(path, headers, std::move(content_receiver), + std::move(progress)); +} +inline Result Client::Get(const char *path, ResponseHandler response_handler, + ContentReceiver content_receiver) { + return cli_->Get(path, std::move(response_handler), + std::move(content_receiver)); +} +inline Result Client::Get(const char *path, const Headers &headers, + ResponseHandler response_handler, + ContentReceiver content_receiver) { + return cli_->Get(path, headers, std::move(response_handler), + std::move(content_receiver)); +} +inline Result Client::Get(const char *path, ResponseHandler response_handler, + ContentReceiver content_receiver, Progress progress) { + return cli_->Get(path, std::move(response_handler), + std::move(content_receiver), std::move(progress)); +} +inline Result Client::Get(const char *path, const Headers &headers, + ResponseHandler response_handler, + ContentReceiver content_receiver, Progress progress) { + return cli_->Get(path, headers, std::move(response_handler), + std::move(content_receiver), std::move(progress)); +} +inline Result Client::Get(const char *path, const Params ¶ms, + const Headers &headers, Progress progress) { + return cli_->Get(path, params, headers, progress); +} +inline Result Client::Get(const char *path, const Params ¶ms, + const Headers &headers, + ContentReceiver content_receiver, Progress progress) { + return cli_->Get(path, params, headers, content_receiver, progress); +} +inline Result Client::Get(const char *path, const Params ¶ms, + const Headers &headers, + ResponseHandler response_handler, + ContentReceiver content_receiver, Progress progress) { + return cli_->Get(path, params, headers, response_handler, content_receiver, + progress); +} + +inline Result Client::Head(const char *path) { return cli_->Head(path); } +inline Result Client::Head(const char *path, const Headers &headers) { + return cli_->Head(path, headers); +} + +inline Result Client::Post(const char *path) { return cli_->Post(path); } +inline Result Client::Post(const char *path, const char *body, + size_t content_length, const char *content_type) { + return cli_->Post(path, body, content_length, content_type); +} +inline Result Client::Post(const char *path, const Headers &headers, + const char *body, size_t content_length, + const char *content_type) { + return cli_->Post(path, headers, body, content_length, content_type); +} +inline Result Client::Post(const char *path, const std::string &body, + const char *content_type) { + return cli_->Post(path, body, content_type); +} +inline Result Client::Post(const char *path, const Headers &headers, + const std::string &body, const char *content_type) { + return cli_->Post(path, headers, body, content_type); +} +inline Result Client::Post(const char *path, size_t content_length, + ContentProvider content_provider, + const char *content_type) { + return cli_->Post(path, content_length, std::move(content_provider), + content_type); +} +inline Result Client::Post(const char *path, + ContentProviderWithoutLength content_provider, + const char *content_type) { + return cli_->Post(path, std::move(content_provider), content_type); +} +inline Result Client::Post(const char *path, const Headers &headers, + size_t content_length, + ContentProvider content_provider, + const char *content_type) { + return cli_->Post(path, headers, content_length, std::move(content_provider), + content_type); +} +inline Result Client::Post(const char *path, const Headers &headers, + ContentProviderWithoutLength content_provider, + const char *content_type) { + return cli_->Post(path, headers, std::move(content_provider), content_type); +} +inline Result Client::Post(const char *path, const Params ¶ms) { + return cli_->Post(path, params); +} +inline Result Client::Post(const char *path, const Headers &headers, + const Params ¶ms) { + return cli_->Post(path, headers, params); +} +inline Result Client::Post(const char *path, + const MultipartFormDataItems &items) { + return cli_->Post(path, items); +} +inline Result Client::Post(const char *path, const Headers &headers, + const MultipartFormDataItems &items) { + return cli_->Post(path, headers, items); +} +inline Result Client::Post(const char *path, const Headers &headers, + const MultipartFormDataItems &items, + const std::string &boundary) { + return cli_->Post(path, headers, items, boundary); +} +inline Result Client::Put(const char *path) { return cli_->Put(path); } +inline Result Client::Put(const char *path, const char *body, + size_t content_length, const char *content_type) { + return cli_->Put(path, body, content_length, content_type); +} +inline Result Client::Put(const char *path, const Headers &headers, + const char *body, size_t content_length, + const char *content_type) { + return cli_->Put(path, headers, body, content_length, content_type); +} +inline Result Client::Put(const char *path, const std::string &body, + const char *content_type) { + return cli_->Put(path, body, content_type); +} +inline Result Client::Put(const char *path, const Headers &headers, + const std::string &body, const char *content_type) { + return cli_->Put(path, headers, body, content_type); +} +inline Result Client::Put(const char *path, size_t content_length, + ContentProvider content_provider, + const char *content_type) { + return cli_->Put(path, content_length, std::move(content_provider), + content_type); +} +inline Result Client::Put(const char *path, + ContentProviderWithoutLength content_provider, + const char *content_type) { + return cli_->Put(path, std::move(content_provider), content_type); +} +inline Result Client::Put(const char *path, const Headers &headers, + size_t content_length, + ContentProvider content_provider, + const char *content_type) { + return cli_->Put(path, headers, content_length, std::move(content_provider), + content_type); +} +inline Result Client::Put(const char *path, const Headers &headers, + ContentProviderWithoutLength content_provider, + const char *content_type) { + return cli_->Put(path, headers, std::move(content_provider), content_type); +} +inline Result Client::Put(const char *path, const Params ¶ms) { + return cli_->Put(path, params); +} +inline Result Client::Put(const char *path, const Headers &headers, + const Params ¶ms) { + return cli_->Put(path, headers, params); +} +inline Result Client::Patch(const char *path) { return cli_->Patch(path); } +inline Result Client::Patch(const char *path, const char *body, + size_t content_length, const char *content_type) { + return cli_->Patch(path, body, content_length, content_type); +} +inline Result Client::Patch(const char *path, const Headers &headers, + const char *body, size_t content_length, + const char *content_type) { + return cli_->Patch(path, headers, body, content_length, content_type); +} +inline Result Client::Patch(const char *path, const std::string &body, + const char *content_type) { + return cli_->Patch(path, body, content_type); +} +inline Result Client::Patch(const char *path, const Headers &headers, + const std::string &body, const char *content_type) { + return cli_->Patch(path, headers, body, content_type); +} +inline Result Client::Patch(const char *path, size_t content_length, + ContentProvider content_provider, + const char *content_type) { + return cli_->Patch(path, content_length, std::move(content_provider), + content_type); +} +inline Result Client::Patch(const char *path, + ContentProviderWithoutLength content_provider, + const char *content_type) { + return cli_->Patch(path, std::move(content_provider), content_type); +} +inline Result Client::Patch(const char *path, const Headers &headers, + size_t content_length, + ContentProvider content_provider, + const char *content_type) { + return cli_->Patch(path, headers, content_length, std::move(content_provider), + content_type); +} +inline Result Client::Patch(const char *path, const Headers &headers, + ContentProviderWithoutLength content_provider, + const char *content_type) { + return cli_->Patch(path, headers, std::move(content_provider), content_type); +} +inline Result Client::Delete(const char *path) { return cli_->Delete(path); } +inline Result Client::Delete(const char *path, const Headers &headers) { + return cli_->Delete(path, headers); +} +inline Result Client::Delete(const char *path, const char *body, + size_t content_length, const char *content_type) { + return cli_->Delete(path, body, content_length, content_type); +} +inline Result Client::Delete(const char *path, const Headers &headers, + const char *body, size_t content_length, + const char *content_type) { + return cli_->Delete(path, headers, body, content_length, content_type); +} +inline Result Client::Delete(const char *path, const std::string &body, + const char *content_type) { + return cli_->Delete(path, body, content_type); +} +inline Result Client::Delete(const char *path, const Headers &headers, + const std::string &body, + const char *content_type) { + return cli_->Delete(path, headers, body, content_type); +} +inline Result Client::Options(const char *path) { return cli_->Options(path); } +inline Result Client::Options(const char *path, const Headers &headers) { + return cli_->Options(path, headers); +} + +inline bool Client::send(Request &req, Response &res, Error &error) { + return cli_->send(req, res, error); +} + +inline Result Client::send(const Request &req) { return cli_->send(req); } + +inline size_t Client::is_socket_open() const { return cli_->is_socket_open(); } + +inline void Client::stop() { cli_->stop(); } + +inline void Client::set_default_headers(Headers headers) { + cli_->set_default_headers(std::move(headers)); +} + +inline void Client::set_address_family(int family) { + cli_->set_address_family(family); +} + +inline void Client::set_tcp_nodelay(bool on) { cli_->set_tcp_nodelay(on); } + +inline void Client::set_socket_options(SocketOptions socket_options) { + cli_->set_socket_options(std::move(socket_options)); +} + +inline void Client::set_connection_timeout(time_t sec, time_t usec) { + cli_->set_connection_timeout(sec, usec); +} + +inline void Client::set_read_timeout(time_t sec, time_t usec) { + cli_->set_read_timeout(sec, usec); +} + +inline void Client::set_write_timeout(time_t sec, time_t usec) { + cli_->set_write_timeout(sec, usec); +} + +inline void Client::set_basic_auth(const char *username, const char *password) { + cli_->set_basic_auth(username, password); +} +inline void Client::set_bearer_token_auth(const char *token) { + cli_->set_bearer_token_auth(token); +} +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +inline void Client::set_digest_auth(const char *username, + const char *password) { + cli_->set_digest_auth(username, password); +} +#endif + +inline void Client::set_keep_alive(bool on) { cli_->set_keep_alive(on); } +inline void Client::set_follow_location(bool on) { + cli_->set_follow_location(on); +} + +inline void Client::set_url_encode(bool on) { cli_->set_url_encode(on); } + +inline void Client::set_compress(bool on) { cli_->set_compress(on); } + +inline void Client::set_decompress(bool on) { cli_->set_decompress(on); } + +inline void Client::set_interface(const char *intf) { + cli_->set_interface(intf); +} + +inline void Client::set_proxy(const char *host, int port) { + cli_->set_proxy(host, port); +} +inline void Client::set_proxy_basic_auth(const char *username, + const char *password) { + cli_->set_proxy_basic_auth(username, password); +} +inline void Client::set_proxy_bearer_token_auth(const char *token) { + cli_->set_proxy_bearer_token_auth(token); +} +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +inline void Client::set_proxy_digest_auth(const char *username, + const char *password) { + cli_->set_proxy_digest_auth(username, password); +} +#endif + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +inline void Client::enable_server_certificate_verification(bool enabled) { + cli_->enable_server_certificate_verification(enabled); +} +#endif + +inline void Client::set_logger(Logger logger) { cli_->set_logger(logger); } + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +inline void Client::set_ca_cert_path(const char *ca_cert_file_path, + const char *ca_cert_dir_path) { + cli_->set_ca_cert_path(ca_cert_file_path, ca_cert_dir_path); +} + +inline void Client::set_ca_cert_store(X509_STORE *ca_cert_store) { + if (is_ssl_) { + static_cast(*cli_).set_ca_cert_store(ca_cert_store); + } else { + cli_->set_ca_cert_store(ca_cert_store); + } +} + +inline long Client::get_openssl_verify_result() const { + if (is_ssl_) { + return static_cast(*cli_).get_openssl_verify_result(); + } + return -1; // NOTE: -1 doesn't match any of X509_V_ERR_??? +} + +inline SSL_CTX *Client::ssl_context() const { + if (is_ssl_) { return static_cast(*cli_).ssl_context(); } + return nullptr; +} +#endif + +// ---------------------------------------------------------------------------- + +} // namespace httplib + +#endif // CPPHTTPLIB_HTTPLIB_H diff --git a/study_cpp/P2P-Share/makefile b/study_cpp/P2P-Share/makefile new file mode 100644 index 0000000..edd0b4f --- /dev/null +++ b/study_cpp/P2P-Share/makefile @@ -0,0 +1,5 @@ +all:ser cli +cli:p2pclient.cpp + g++ -std=c++0x $^ -o $@ -lpthread -lboost_filesystem -lboost_system -lboost_thread +ser:p2pserver.cpp + g++ -std=c++0x $^ -o $@ -lpthread -lboost_filesystem -lboost_system diff --git a/study_cpp/P2P-Share/p2pclient.cpp b/study_cpp/P2P-Share/p2pclient.cpp new file mode 100644 index 0000000..3875158 --- /dev/null +++ b/study_cpp/P2P-Share/p2pclient.cpp @@ -0,0 +1,280 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "httplib.h" +#include + +#define RANGE_SIZE (1024*1024*10) // 10M +using namespace httplib; +namespace bf = boost::filesystem; + +class P2PClient{ + +private: + uint16_t _srv_port; + int _host_idx; + std::vector _online_list; + std::vector _file_list; +private: + bool GetAllHost(std::vector &list){ + + struct sockaddr_in *ip = NULL; + struct sockaddr_in *mask = NULL; + struct ifaddrs *addrs = NULL; + getifaddrs(&addrs); + for(; addrs != NULL; addrs = addrs->ifa_next){ + ip = (struct sockaddr_in*)addrs->ifa_addr; + mask = (struct sockaddr_in*)addrs->ifa_netmask; + if(ip->sin_family != AF_INET){ + continue; + } + + if(ip->sin_addr.s_addr == inet_addr("127.0.0.1")){ + continue; + } + + uint32_t net, host; + net = ntohl(ip->sin_addr.s_addr & mask->sin_addr.s_addr); + host = ntohl(~mask->sin_addr.s_addr); + for(int i = 2; i < host-1; i++){ + struct in_addr ip; + ip.s_addr = htonl(net+i); + list.push_back(inet_ntoa(ip)); + } + } + freeifaddrs(addrs); + + + return true; + } + + void HostPair(std::string &i){ + Client client(i.c_str(), _srv_port); + auto req = client.Get("/hostpair"); + if(req && req->status == 200){ + std::cerr << "host " << i << " pair success\n"; + _online_list.push_back(i); + } + std::cerr << "host " << i << " pair failed\n"; + + return; + } + + bool GetOnlineHost(std::vector &list){ + _online_list.clear(); + std::vector thr_list(list.size()); + for(int i = 0; i < list.size(); i++){ + std::thread thr(&P2PClient::HostPair, this, std::ref(list[i])); + thr_list[i] = std::move(thr); + } + + for(int i = 0; i < thr_list.size(); i++){ + thr_list[i].join(); + } + return true; + } + + bool ShowOnlineHost(){ + for(int i = 0; i < _online_list.size(); i++){ + std::cout << i << ". " << _online_list[i] << "\n"; + } + std::cout << "please choose:"; + fflush(stdout); + std::cin >> _host_idx; + if(_host_idx < 0 || _host_idx > _online_list.size()){ + std::cerr << "choose error\n"; + return false; + } + return true; + } + + bool GetFileList(){ + Client client(_online_list[_host_idx].c_str(), _srv_port); + auto req = client.Get("/list"); + if(req && req->status == 200){ + //std::vector list; + boost::split(_file_list, req->body, boost::is_any_of("\n")); + } + return true; + } + + bool ShowFileList(std::string &name){ + for(int i = 0; i < _file_list.size(); i++){ + std::cout << i << ". " << _file_list[i] << "\n"; + } + std::cout << "please choose:"; + fflush(stdout); + int file_idx; + std::cin >> file_idx; + if(file_idx < 0 || file_idx > _file_list.size()){ + std::cerr << "choose error\n"; + return false; + } + name = _file_list[file_idx]; + return true; + } + + void RangeDownLoad(std::string host, std::string name, + int64_t start, int64_t end, int *res){ + std::string uri = "/list/" + name; + std::string realpath = "Download/" + name; + std::stringstream range_val; + range_val << "bytes=" << start << "-" << end; + + std::cerr << "download range: " << range_val.str() << "\n"; + *res = 0; + Client client(host.c_str(), _srv_port); + Headers header; + header.insert(std::make_pair("Range", range_val.str().c_str())); + auto req = client.Get(uri.c_str(), header); + if(req && req->status == 206){ + int fd = open(realpath.c_str(), O_CREAT | O_WRONLY, 0664); + if(fd < 0){ + std::cerr << "file " << realpath << " open error\n"; + return; + } + lseek(fd, start, SEEK_SET); + int ret = write(fd, &req->body[0], req->body.size()); + if(ret < 0){ + std::cerr << "file " << realpath << "write error\n"; + close(fd); + return; + } + close(fd); + *res = 1; + std::cerr << "file " << realpath << " download range:"; + std::cerr << range_val.str() << " success\n"; + } + return; + + } + + int64_t GetFileSize(std::string &host, std::string &name){ + int64_t fsize = -1; + std::string path = "/list/" + name; + Client client(host.c_str(), _srv_port); + auto req = client.Head(path.c_str()); + if(req && req->status == 200){ + if(!req->has_header("Content-Length")){ + return -1; + } + std::string len = req->get_header_value("Content-Length"); + std::stringstream tmp; + tmp << len; + tmp >> fsize; + } + return fsize; + } + + bool DownLoadFile(std::string &name){ + // GET /list/filename + std::string host = _online_list[_host_idx]; + int64_t fsize = GetFileSize(host, name); + if(fsize < 0){ + std::cerr << "download file " << name << "failed\n"; + return false; + } + + int count = fsize / RANGE_SIZE; + std::cout << "range count: " << count << "\n"; + std::vector thr_list(count + 1); + std::vector res_list(count + 1); + for(int64_t i = 0; i <= count; i++){ + int64_t start, end, len; + start = i * RANGE_SIZE; + end = (i + 1) * RANGE_SIZE - 1; + if(i == count){ + if(fsize % RANGE_SIZE == 0){ + break; + } + end = fsize - 1; + } + std::cerr << "range: " << start << "-" << end <<"\n"; + len = end - start + 1; + + int *res = &res_list[i]; + boost::thread thr(&P2PClient::RangeDownLoad, this, host, name, start, end, res); + thr_list[i] = std::move(thr); + } + + bool ret = true; + for(int i = 0; i <= count; i++){ + if(i == count && fsize % RANGE_SIZE == 0){ + break; + } + thr_list[i].join(); + if(res_list[i] == 0){ + ret = false; + } + } + + if(ret == true){ + std::cerr << "download file " << name << " success\n"; + } + else{ + std::cerr << "download file " << name << " failed\n"; + return false; + } + return true; + } + + int DoFace(){ + std::cout << "0. 退出\n"; + std::cout << "1. 搜索附近主机\n"; + std::cout << "2. 显示在线主机\n"; + std::cout << "3. 显示文件列表\n"; + int choose = 0; + std::cout << "please choose:"; + fflush(stdout); + std::cin >> choose; + return choose; + } +public: + P2PClient(uint16_t port):_srv_port(port){} + bool Start(){ + while(1){ + int choose = DoFace(); + std::string filename; + std::vector list; + switch(choose){ + case 1: + GetAllHost(list); + GetOnlineHost(list); + break; + case 2: + if(ShowOnlineHost() == false){ + break; + } + GetFileList(); + break; + case 3: + if(ShowFileList(filename) == false){ + break; + } + DownLoadFile(filename); + break; + case 0: + exit(0); + default: + break; + } + } + } + +}; + +int main(){ + + P2PClient cli(9001); + cli.Start(); + return 0; +} diff --git a/study_cpp/P2P-Share/p2pserver.cpp b/study_cpp/P2P-Share/p2pserver.cpp new file mode 100644 index 0000000..81abdee --- /dev/null +++ b/study_cpp/P2P-Share/p2pserver.cpp @@ -0,0 +1,153 @@ +#include +#include +#include +#include +#include "httplib.h" + +#define SHARD_PATH "SHARD" +#define LOG(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__) + +using namespace httplib; +namespace bf = boost::filesystem; + +class P2PServer +{ + private: + Server _server; + private: + static void GetHostPair(const Request& req,Response& rsp) + { + rsp.status =200; + return; + } + static void GetFileList(const Request& req,Response& rsp) + { + bf::directory_iterator it_begin(SHARD_PATH); + bf::directory_iterator it_end; + std::stringstream body; + // body<<""; + for(;it_begin!=it_end;it_begin++){ + if(bf::is_directory(it_begin->status())){ + continue; + } + std::string name = it_begin->path().filename().string(); + rsp.body+=name+"\n"; + // body << "

"; + // body << name; + // body <<"

"; + //rsp.body+=name; + } + // body<<""; + // rsp.body = body.str(); + rsp.set_header("Content-Type","text/html");//渲染 + rsp.status = 200; + } + + static void GetFileData(const Request& req,Response& rsp) + { + //a.txt->Dowanload/a.txt + bf::path path(req.path); //生成一个path对象 + std::stringstream name; + name<< SHARD_PATH << "/" << path.filename().string(); + + if(!bf::exists(name.str())){ + rsp.status = 404; + return; + } + + if(bf::is_directory(name.str())){ + rsp.status = 403; + return; + } + + int64_t fsize = bf::file_size(name.str()); + if(req.method == "HEAD"){ + rsp.status = 200; + std::string len = std::to_string(fsize); + rsp.set_header("Content-Length", len.c_str()); + return; + } + else{ + if(!req.has_header("Range")){ + rsp.status = 400; + return; + } + std::string range_val; + range_val = req.get_header_value("Range"); + int64_t start, rlen; + + bool ret = RangeParse(range_val, start, rlen); + if(ret == false){ + rsp.status = 400; + return; + } + + std::cerr << "body.resize: " << rlen << "\n"; + rsp.body.resize(rlen); + std::ifstream file(name.str(),std::ios::binary); + if(!file.is_open()) + { + std::cerr<<"open file"<> start; + tmp.clear(); + tmp << rend; + tmp >> end; + len = end - start + 1; + return true; + } + + public: + P2PServer(){ + if(!bf::exists(SHARD_PATH)){ + bf::create_directory(SHARD_PATH); + } + } + bool Start(uint16_t port){ + _server.Get("/hostpair",GetHostPair); + _server.Get("/list",GetFileList); + _server.Get("/list/(.*)",GetFileData); + _server.listen("0.0.0.0",port); + } +}; + +int main() +{ + P2PServer srv; + srv.Start(9000); + return 0; +} diff --git a/study_cpp/P2P-Share/ser b/study_cpp/P2P-Share/ser new file mode 100755 index 0000000..3e421db Binary files /dev/null and b/study_cpp/P2P-Share/ser differ diff --git a/study_cpp/P2P-Share/tcp_cubic.cc b/study_cpp/P2P-Share/tcp_cubic.cc new file mode 100644 index 0000000..8f5c20a --- /dev/null +++ b/study_cpp/P2P-Share/tcp_cubic.cc @@ -0,0 +1,498 @@ +/* + * TCP CUBIC: Binary Increase Congestion control for TCP v2.3 + * Home page: + * http://netsrv.csc.ncsu.edu/twiki/bin/view/Main/BIC + * This is from the implementation of CUBIC TCP in + * Sangtae Ha, Injong Rhee and Lisong Xu, + * "CUBIC: A New TCP-Friendly High-Speed TCP Variant" + * in ACM SIGOPS Operating System Review, July 2008. + * Available from: + * http://netsrv.csc.ncsu.edu/export/cubic_a_new_tcp_2008.pdf + * + * CUBIC integrates a new slow start algorithm, called HyStart. + * The details of HyStart are presented in + * Sangtae Ha and Injong Rhee, + * "Taming the Elephants: New TCP Slow Start", NCSU TechReport 2008. + * Available from: + * http://netsrv.csc.ncsu.edu/export/hystart_techreport_2008.pdf + * + * All testing results are available from: + * http://netsrv.csc.ncsu.edu/wiki/index.php/TCP_Testing + * + * Unless CUBIC is enabled and congestion window is large + * this behaves the same as the original Reno. + */ + +#include +#include +#include +#include + +#define BICTCP_BETA_SCALE 1024 /* Scale factor beta calculation + * max_cwnd = snd_cwnd * beta + */ +#define BICTCP_HZ 10 /* BIC HZ 2^10 = 1024 */ + +/* Two methods of hybrid slow start */ +#define HYSTART_ACK_TRAIN 0x1 +#define HYSTART_DELAY 0x2 + +/* Number of delay samples for detecting the increase of delay */ +#define HYSTART_MIN_SAMPLES 8 +#define HYSTART_DELAY_MIN (2U<<3) +#define HYSTART_DELAY_MAX (16U<<3) +#define HYSTART_DELAY_THRESH(x) clamp(x, HYSTART_DELAY_MIN, HYSTART_DELAY_MAX) +static int fast_convergence __read_mostly = 1; +static int beta __read_mostly = 717; /* = 717/1024 (BICTCP_BETA_SCALE) */ +static int initial_ssthresh __read_mostly; +//bic_scale就是paper中三次方系数C的1024倍缩放值 +//MODULE_PARM_DESC(bic_scale, "scale (scaled by 1024) value for bic function (bic_scale/1024)"); +static int bic_scale __read_mostly = 41; +static int tcp_friendliness __read_mostly = 1; +static int hystart __read_mostly = 1; +static int hystart_detect __read_mostly = HYSTART_ACK_TRAIN | HYSTART_DELAY; +static int hystart_low_window __read_mostly = 16; +static u32 cube_rtt_scale __read_mostly; +static u32 beta_scale __read_mostly; +static u64 cube_factor __read_mostly; +/* Note parameters that are used for precomputing scale factors are read-only */ +module_param(fast_convergence, int, 0644); +MODULE_PARM_DESC(fast_convergence, "turn on/off fast convergence"); +module_param(beta, int, 0644); +MODULE_PARM_DESC(beta, "beta for multiplicative increase"); +module_param(initial_ssthresh, int, 0644); +MODULE_PARM_DESC(initial_ssthresh, "initial value of slow start threshold"); +module_param(bic_scale, int, 0444); +MODULE_PARM_DESC(bic_scale, "scale (scaled by 1024) value for bic function (bic_scale/1024)"); +module_param(tcp_friendliness, int, 0644); +MODULE_PARM_DESC(tcp_friendliness, "turn on/off tcp friendliness"); +module_param(hystart, int, 0644); +MODULE_PARM_DESC(hystart, "turn on/off hybrid slow start algorithm"); +module_param(hystart_detect, int, 0644); +MODULE_PARM_DESC(hystart_detect, "hyrbrid slow start detection mechanisms" + " 1: packet-train 2: delay 3: both packet-train and delay"); +module_param(hystart_low_window, int, 0644); +MODULE_PARM_DESC(hystart_low_window, "lower bound cwnd for hybrid slow start"); +/* BIC TCP Parameters */ +struct bictcp { + u32 cnt; /* increase cwnd by 1 after ACKs */ + u32 last_max_cwnd; /* last maximum snd_cwnd */ +//两个重要的count值: +//第一个是tcp_sock->snd_cwnd_cnt,表示在当前的拥塞窗口中已经 +//发送(经过对方ack包确认)的数据段的个数, +//而第二个是bictcp->cnt,它是cubic拥塞算法的核心, +//主要用来控制在拥塞避免状态的时候,什么时候才能增大拥塞窗口, +//具体实现是通过比较cnt和snd_cwnd_cnt,来决定是否增大拥塞窗口, + u32 loss_cwnd; /* congestion window at last loss */ + u32 last_cwnd; /* the last snd_cwnd */ + u32 last_time; /* time when updated last_cwnd */ + u32 bic_origin_point;/* origin point of bic function */ + u32 bic_K; /* time to origin point from the beginning of the current epoch */ + u32 delay_min; /* min delay */ + u32 epoch_start; /* beginning of an epoch */ + u32 ack_cnt; /* number of acks */ + u32 tcp_cwnd; /* estimated tcp cwnd */ +#define ACK_RATIO_SHIFT 4 + u16 delayed_ack; /* estimate the ratio of Packets/ACKs << 4 */ + u8 sample_cnt; /* number of samples to decide curr_rtt */ + u8 found; /* the exit point is found? */ + u32 round_start; /* beginning of each round */ + u32 end_seq; /* end_seq of the round */ + u32 last_jiffies; /* last time when the ACK spacing is close */ + u32 curr_rtt; /* the minimum rtt of current round */ +}; +static inline void bictcp_reset(struct bictcp *ca) +{ + ca->cnt = 0; + ca->last_max_cwnd = 0; + ca->loss_cwnd = 0; + ca->last_cwnd = 0; + ca->last_time = 0; + ca->bic_origin_point = 0; + ca->bic_K = 0; + ca->delay_min = 0; + ca->epoch_start = 0; + ca->delayed_ack = 2 << ACK_RATIO_SHIFT; + ca->ack_cnt = 0; + ca->tcp_cwnd = 0; + ca->found = 0; +} + +static inline void bictcp_hystart_reset(struct sock *sk) +{ + struct tcp_sock *tp = tcp_sk(sk); + struct bictcp *ca = inet_csk_ca(sk); + + ca->round_start = ca->last_jiffies = jiffies; + ca->end_seq = tp->snd_nxt; + ca->curr_rtt = 0; + ca->sample_cnt = 0; +} + +static void bictcp_init(struct sock *sk) +{ + bictcp_reset(inet_csk_ca(sk)); + + if (hystart) + bictcp_hystart_reset(sk); + + if (!hystart && initial_ssthresh) + tcp_sk(sk)->snd_ssthresh = initial_ssthresh; +} + +/* calculate the cubic root of x using a table lookup followed by one + * Newton-Raphson iteration. + * Avg err ~= 0.195% + */ +static u32 cubic_root(u64 a) +{ + u32 x, b, shift; + /* + * cbrt(x) MSB values for x MSB values in [0..63]. + * Precomputed then refined by hand - Willy Tarreau + * + * For x in [0..63], + * v = cbrt(x << 18) - 1 + * cbrt(x) = (v[x] + 10) >> 6 + */ + static const u8 v[] = { + /* 0x00 */ 0, 54, 54, 54, 118, 118, 118, 118, + /* 0x08 */ 123, 129, 134, 138, 143, 147, 151, 156, + /* 0x10 */ 157, 161, 164, 168, 170, 173, 176, 179, + /* 0x18 */ 181, 185, 187, 190, 192, 194, 197, 199, + /* 0x20 */ 200, 202, 204, 206, 209, 211, 213, 215, + /* 0x28 */ 217, 219, 221, 222, 224, 225, 227, 229, + /* 0x30 */ 231, 232, 234, 236, 237, 239, 240, 242, + /* 0x38 */ 244, 245, 246, 248, 250, 251, 252, 254, + }; + + b = fls64(a); + if (b < 7) { + /* a in [0..63] */ + return ((u32)v[(u32)a] + 35) >> 6; + } + + b = ((b * 84) >> 8) - 1; + shift = (a >> (b * 3)); + + x = ((u32)(((u32)v[shift] + 10) << b)) >> 6; + + /* + * Newton-Raphson iteration + * 2 + * x = ( 2 * x + a / x ) / 3 + * k+1 k k + */ + x = (2 * x + (u32)div64_u64(a, (u64)x * (u64)(x - 1))); + x = ((x * 341) >> 10); + return x; +} +/* +函数关键点 +1. 我们最终要得到的是ca->cnt,用来控制snd_cwnd的增长。 +2. ca->cnt的值,是根据cwnd和w( t + after ) 的大小来判断的。w( t + after )即bic_target,它表示我们预期的 +在经过after时间后的snd_cwnd。如果此时cwnd < w( t + after ),那么我们就快速增加窗口,达到预期目标。 +如果cwnd > w( t + after ),那说明我们已经增加过快了,需要降速了,这样才能达到预期目标。 + cwnd / (bic_target - cwnd ) // bic_target > cwnd +cnt = + 100 * cwnd // bic_target < cwnd +3. cwnd是传入的参数,已知。现在我们只需要计算bic_target。 +而根据Cubic的窗口增长函数:W(t) = C(t - K)^3 + Wmax, +我们要计算时间( 当前 + after ),以及时间K。时间K即bic_K,表示函数值为Wmax所对应的时间。 +通过代码可以发现,after为min RTT,即连接的传播时延。 +*/ +/* + * Compute congestion window to use. + */ +static inline void bictcp_update(struct bictcp *ca, u32 cwnd) +{ + u64 offs;/* 时间差,| t - K | */ + u32 delta, t, bic_target, max_cnt;/* delta是cwnd差,bic_target是预测值,t为预测时间 */ + ca->ack_cnt++; /* count the number of ACKs */ + + if (ca->last_cwnd == cwnd && + (s32)(tcp_time_stamp - ca->last_time) <= HZ / 32) + return; + + ca->last_cwnd = cwnd; + ca->last_time = tcp_time_stamp; + + if (ca->epoch_start == 0) { + ca->epoch_start = tcp_time_stamp; /* record the beginning of an epoch */ + ca->ack_cnt = 1; /* start counting */ + ca->tcp_cwnd = cwnd; /* syn with cubic */ + /* 取max(last_max_cwnd , cwnd)作为当前Wmax */ + if (ca->last_max_cwnd <= cwnd) { + ca->bic_K = 0; + ca->bic_origin_point = cwnd; + } else { + /* Compute new K based on + * (wmax-cwnd) * (srtt>>3 / HZ) / c * 2^(3*bictcp_HZ) + */ + ca->bic_K = cubic_root(cube_factor + * (ca->last_max_cwnd - cwnd)); + ca->bic_origin_point = ca->last_max_cwnd; + } + } + + /* cubic function - calc*/ + /* calculate c * time^3 / rtt, + * while considering overflow in calculation of time^3 + * (so time^3 is done by using 64 bit) + * and without the support of division of 64bit numbers + * (so all divisions are done by using 32 bit) + * also NOTE the unit of those veriables + * time = (t - K) / 2^bictcp_HZ + * c = bic_scale >> 10 + * rtt = (srtt >> 3) / HZ + * !!! The following code does not have overflow problems, + * if the cwnd < 1 million packets !!! + */ + /* change the unit from HZ to bictcp_HZ */ + t = ((tcp_time_stamp + (ca->delay_min>>3) - ca->epoch_start) + << BICTCP_HZ) / HZ; + /* 求| t - bic_K | */ + if (t < ca->bic_K) /* 还未达到Wmax */ + offs = ca->bic_K - t; + else + offs = t - ca->bic_K; //此时已经超过Wmax + + /* c/rtt * (t-K)^3 */ + /* 计算delta =| W(t) - W(bic_K) | + * cube_rtt_scale = (bic_scale * 10) = c / srtt * 2^10,c/srtt = 0.4 + */ + delta = (cube_rtt_scale * offs * offs * offs) >> (10+3*BICTCP_HZ); + if (t < ca->bic_K) /* below origin*/ + bic_target = ca->bic_origin_point - delta; + else /* above origin*/ + bic_target = ca->bic_origin_point + delta; + + /* cubic function - calc bictcp_cnt /* 计算bic_target,即预测cwnd */ + if (bic_target > cwnd) { + /* 相差越多,增长越快,这就是函数形状由来 */ + ca->cnt = cwnd / (bic_target - cwnd); + } else { + ca->cnt = 100 * cwnd; /* very small increment 目前cwnd已经超出预期了,应该降速*/ + } + + /* TCP Friendly /* TCP Friendly —如果cubic比RENO慢,则提升cwnd增长速度,即减小cnt + * 以上次丢包以后的时间t算起,每次RTT增长 3B / ( 2 - B),那么可以得到 + * 采用RENO算法的cwnd。 + * cwnd (RENO) = cwnd + 3B / (2 - B) * ack_cnt / cwnd + * B为乘性减少因子,在此算法中为0.3 + */ + if (tcp_friendliness) { + u32 scale = beta_scale; + delta = (cwnd * scale) >> 3; + while (ca->ack_cnt > delta) { /* update tcp cwnd */ + ca->ack_cnt -= delta; + ca->tcp_cwnd++; + } + + if (ca->tcp_cwnd > cwnd){ /* if bic is slower than tcp */ + delta = ca->tcp_cwnd - cwnd; + max_cnt = cwnd / delta; + if (ca->cnt > max_cnt) + ca->cnt = max_cnt; + } + } + + ca->cnt = (ca->cnt << ACK_RATIO_SHIFT) / ca->delayed_ack;//做了一个比较直接的delay_ack的控制 + //ratio = (15*ratio + sample) / 16 这里ca-delayed_ack由 + if (ca->cnt == 0) /* cannot be zero */ + ca->cnt = 1;/* 此时代表cwnd远小于bic_target,增长速度最大 */ +} + +static void bictcp_cong_avoid(struct sock *sk, u32 ack, u32 in_flight) +{ + struct tcp_sock *tp = tcp_sk(sk); + struct bictcp *ca = inet_csk_ca(sk); + //判断发送拥塞窗口是否到达限制,如果到达限制则直接返回 + if (!tcp_is_cwnd_limited(sk, in_flight)) + return; + + if (tp->snd_cwnd <= tp->snd_ssthresh) { + if (hystart && after(ack, ca->end_seq)) + bictcp_hystart_reset(sk); + tcp_slow_start(tp);//进入slow start状态 + } else { + bictcp_update(ca, tp->snd_cwnd); + tcp_cong_avoid_ai(tp, ca->cnt);//然后进入拥塞避免,更新tcp_sock->snd_cwnd_cnt + } + +} + +//做了两件事:重赋值last_max_cwnd、返回新的慢启动阈值 +static u32 bictcp_recalc_ssthresh(struct sock *sk) +{ + const struct tcp_sock *tp = tcp_sk(sk); + struct bictcp *ca = inet_csk_ca(sk); + + ca->epoch_start = 0; /* end of epoch */ + + /* Wmax and fast convergence */ + //当一个新的TCP流加入到网络, + //网络中已有TCP流需要放弃自己带宽, + //给新的TCP流提供一定的上升空间。 + //为提高已有TCP流所释放的带宽而引入快速收敛机制。 + if (tp->snd_cwnd < ca->last_max_cwnd && fast_convergence) + //表示已有TCP流所经历的饱和点因为可用带宽改变而正在降低。 + //然后,通过进一步降低Wmax让已有流释放更多带宽。 + //这种行为有效地延长已有流增大其窗口的时间, + //因为降低后的Wmax强制已有流更早进入平稳状态。 + //这允许新流有更多的时间来赶上其窗口尺寸。 + ca->last_max_cwnd = (tp->snd_cwnd * (BICTCP_BETA_SCALE + beta)) + / (2 * BICTCP_BETA_SCALE);//last_max_cwnd = 0.9 * snd_cwnd + else + ca->last_max_cwnd = tp->snd_cwnd; + + ca->loss_cwnd = tp->snd_cwnd; + //修改snd_ssthresh,即max(0.7*snd_cwnd,2) + return max((tp->snd_cwnd * beta) / BICTCP_BETA_SCALE, 2U); +} + +//快速恢复:直接把snd_cwnd更新为max(snd_cwnd,last_max_cwnd),和掉包前相差不大 +static u32 bictcp_undo_cwnd(struct sock *sk) +{ + struct bictcp *ca = inet_csk_ca(sk); + + return max(tcp_sk(sk)->snd_cwnd, ca->last_max_cwnd); +} + +static void bictcp_state(struct sock *sk, u8 new_state) +{ + if (new_state == TCP_CA_Loss) { + bictcp_reset(inet_csk_ca(sk)); + bictcp_hystart_reset(sk); + } +} + +static void hystart_update(struct sock *sk, u32 delay) +{ + struct tcp_sock *tp = tcp_sk(sk); + struct bictcp *ca = inet_csk_ca(sk); + + if (!(ca->found & hystart_detect)) { + u32 curr_jiffies = jiffies; + + /* first detection parameter - ack-train detection */ + if (curr_jiffies - ca->last_jiffies <= msecs_to_jiffies(2)) { + ca->last_jiffies = curr_jiffies; + if (curr_jiffies - ca->round_start >= ca->delay_min>>4) + ca->found |= HYSTART_ACK_TRAIN; + } + + /* obtain the minimum delay of more than sampling packets */ + if (ca->sample_cnt < HYSTART_MIN_SAMPLES) { + if (ca->curr_rtt == 0 || ca->curr_rtt > delay) + ca->curr_rtt = delay; + + ca->sample_cnt++; + } else { + if (ca->curr_rtt > ca->delay_min + + HYSTART_DELAY_THRESH(ca->delay_min>>4)) + ca->found |= HYSTART_DELAY; + } + /* + * Either one of two conditions are met, + * we exit from slow start immediately. + */ + if (ca->found & hystart_detect) + tp->snd_ssthresh = tp->snd_cwnd; + } +} + +/* Track delayed acknowledgment ratio using sliding window + * ratio = (15*ratio + sample) / 16 + */ +//跟踪延迟确认在滑动窗口的比例,主要考虑正常和丢包的时候,是一个参考值 +//根据下面这个函数。化简得 delayed_ack = 15/16*delayed_ack + cnt; +//由于 ratio = delayed_ack/ 16; 16*ration = 15*ration+cnt +//所以 ratio = 15/16 * ratio + cnt / 16; +static void bictcp_acked(struct sock *sk, u32 cnt, s32 rtt_us) +{ + const struct inet_connection_sock *icsk = inet_csk(sk); + const struct tcp_sock *tp = tcp_sk(sk); + struct bictcp *ca = inet_csk_ca(sk); + u32 delay; + + if (icsk->icsk_ca_state == TCP_CA_Open) { + cnt -= ca->delayed_ack >> ACK_RATIO_SHIFT; + ca->delayed_ack += cnt; + } + + /* Some calls are for duplicates without timetamps */ + if (rtt_us < 0) + return; + /* Discard delay samples right after fast recovery */ + if ((s32)(tcp_time_stamp - ca->epoch_start) < HZ) + return; + + delay = usecs_to_jiffies(rtt_us) << 3; + if (delay == 0) + delay = 1; + + /* first time call or link delay decreases */ + if (ca->delay_min == 0 || ca->delay_min > delay) + ca->delay_min = delay; + + /* hystart triggers when cwnd is larger than some threshold */ + if (hystart && tp->snd_cwnd <= tp->snd_ssthresh && + tp->snd_cwnd >= hystart_low_window) + hystart_update(sk, delay); +} + +static struct tcp_congestion_ops cubictcp = { + .init = bictcp_init, + .ssthresh = bictcp_recalc_ssthresh, + .cong_avoid = bictcp_cong_avoid, + .set_state = bictcp_state, + .undo_cwnd = bictcp_undo_cwnd, + .pkts_acked = bictcp_acked, + .owner = THIS_MODULE, + .name = "cubic", +}; + +static int __init cubictcp_register(void) +{ + BUILD_BUG_ON(sizeof(struct bictcp) > ICSK_CA_PRIV_SIZE); + + /* Precompute a bunch of the scaling factors that are used per-packet + * based on SRTT of 100ms + */ + //beta_scale == 8*(1024 + 717) / 3 / (1024 -717 ),大约为15 + beta_scale = 8*(BICTCP_BETA_SCALE+beta)/ 3 / (BICTCP_BETA_SCALE - beta); + //cube_rtt_scale cube_rtt_scale是bic_scale/RTT, 这里rtt=100ms=0.1s + cube_rtt_scale = (bic_scale * 10); /* 1024*c/rtt */ + + /* calculate the "K" for (wmax-cwnd) = c/rtt * K^3 + * so K = cubic_root( (wmax-cwnd)*rtt/c ) + * the unit of K is bictcp_HZ=2^10, not HZ + * + * c = bic_scale >> 10 + * rtt = 100ms + * + * the following code has been designed and tested for + * cwnd < 1 million packets + * RTT < 100 seconds + * HZ < 1,000,00 (corresponding to 10 nano-second) + */ + /* 1/c * 2^2*bictcp_HZ * srtt */ + //通过bic_K和paper中的公式对比,可以知道cube_factor就是1/(C/RTT) + //具体需要参考算法实现,以及这里的30是开根号 + cube_factor = 1ull << (10+3*BICTCP_HZ); /* 2^40 */ + /* divide by bic_scale and by constant Srtt (100ms) */ + do_div(cube_factor, bic_scale * 10); + return tcp_register_congestion_control(&cubictcp); +} +static void __exit cubictcp_unregister(void) +{ + tcp_unregister_congestion_control(&cubictcp); +} +module_init(cubictcp_register); +module_exit(cubictcp_unregister); +MODULE_AUTHOR("Sangtae Ha, Stephen Hemminger"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("CUBIC TCP"); +MODULE_VERSION("2.3"); + \ No newline at end of file diff --git a/study_cpp/cpp_primer_source_code/Appendix E/align.cpp b/study_cpp/cpp_primer_source_code/Appendix E/align.cpp new file mode 100644 index 0000000..fd75823 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Appendix E/align.cpp @@ -0,0 +1,9 @@ +#include +using namespace std; + +int main() +{ + cout << alignof(double) << endl; + cin.get(); + return 0; +} \ No newline at end of file diff --git a/study_cpp/cpp_primer_source_code/Appendix E/memb_pt.cpp b/study_cpp/cpp_primer_source_code/Appendix E/memb_pt.cpp new file mode 100644 index 0000000..33618bd --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Appendix E/memb_pt.cpp @@ -0,0 +1,78 @@ +// memb_pt.cpp -- dereferencing pointers to class members +#include +using namespace std; + +class Example +{ +private: + int feet; + int inches; +public: + Example(); + Example(int ft); + ~Example(); + void show_in() const; + void show_ft() const; + void use_ptr() const; +}; + +Example::Example() +{ + feet = 0; + inches = 0; +} + +Example::Example(int ft) +{ + feet = ft; + inches = 12 * feet; +} + +Example::~Example() +{ +} + +void Example::show_in() const +{ + cout << inches << " inches\n"; +} + +void Example::show_ft() const +{ + cout << feet << " feet\n"; +} + +void Example::use_ptr() const +{ + Example yard(3); + int Example::*pt; + pt = &Example::inches; + cout << "Set pt to &Example::inches:\n"; + cout << "this->pt: " << this->*pt << endl; + cout << "yard.*pt: " << yard.*pt << endl; + pt = &Example::feet; + cout << "Set pt to &Example::feet:\n"; + cout << "this->pt: " << this->*pt << endl; + cout << "yard.*pt: " << yard.*pt << endl; + void (Example::*pf)() const; + pf = &Example::show_in; + cout << "Set pf to &Example::show_in:\n"; + cout << "Using (this->*pf)(): "; + (this->*pf)(); + cout << "Using (yard.*pf)(): "; + (yard.*pf)(); +} + +int main() +{ + Example car(15); + Example van(20); + Example garage; + + cout << "car.use_ptr() output:\n"; + car.use_ptr(); + cout << "\nvan.use_ptr() output:\n"; + van.use_ptr(); + cin.get(); + return 0; +} diff --git a/study_cpp/cpp_primer_source_code/Appendix E/noex.cpp b/study_cpp/cpp_primer_source_code/Appendix E/noex.cpp new file mode 100644 index 0000000..f175e50 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Appendix E/noex.cpp @@ -0,0 +1,40 @@ +#include +#include +#include +#include +#include +#include +#include +using namespace std; +struct S {double a; double b;}; +int main() +{ + S a = {1.1,2.2}; + S b = {2.1,4.2}; + S c = {3.1,5.2}; + + unordered_set us; + us.insert(&a); + us.insert(&b); + us.insert(&c); + for_each(us.begin(),us.end(),[](S* i) {cout << (*i).a << ", ";}); + cout << "\nNext\n"; + + +/* if(pt != vi.end()) + cout << *pt << endl; + else + cout << "not found\n"; + cout << vi.count("cow") << endl; + cout << vi.count("fondu") << endl; + cout << endl; + cout << *vi.lower_bound("cow") << endl; + cout << *vi.upper_bound("hen") << endl; + cout << vi.bucket_count() << endl; + cout << vi.bucket("cow") << endl; + cout << vi.bucket("starkA") << endl; + cout << vi.bucket("stark") << endl;*/ + + cin.get(); + +} \ No newline at end of file diff --git a/study_cpp/cpp_primer_source_code/Appendix G/appg01.cpp b/study_cpp/cpp_primer_source_code/Appendix G/appg01.cpp new file mode 100644 index 0000000..95acb63 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Appendix G/appg01.cpp @@ -0,0 +1,23 @@ +#include +#include +#include +#include +using namespace std; + +int main() +{ +vector input; +string temp; +while (cin >> temp && temp != "quit") + input.push_back(temp); +vector::iterator want= + find(input.begin(), input.end(), string("bonus")); +if (want != input.end()) +{ + vector::reference r = *want; + r = "bogus"; +} +for_each(input.begin(), input.end(), [](string s){cout << s << ", ";}); +cin.get(); +cin.get(); +} diff --git a/study_cpp/cpp_primer_source_code/Appendix G/appg02.cpp b/study_cpp/cpp_primer_source_code/Appendix G/appg02.cpp new file mode 100644 index 0000000..5d10298 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Appendix G/appg02.cpp @@ -0,0 +1,29 @@ +#include +#include +#include +#include +using namespace std; + +template +typename Bag::value_type min(const Bag & b) +{ + typename Bag::const_iterator it; + typename Bag::value_type m = *b.begin(); + for (it = b.begin(); it != b.end(); ++it) + if (*it < m) + m = *it; + return m; +} + +int main() +{ +vector temperatures; +int temp; +while (cin >> temp && temp >-274) + temperatures.push_back(temp); +int coldest = min(temperatures); +for_each(temperatures.begin(), temperatures.end(), [](int s){cout << s << ", ";}); +cout << endl << coldest << endl; +cin.get(); +cin.get(); +} diff --git a/study_cpp/cpp_primer_source_code/Appendix G/appg04.cpp b/study_cpp/cpp_primer_source_code/Appendix G/appg04.cpp new file mode 100644 index 0000000..bf46360 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Appendix G/appg04.cpp @@ -0,0 +1,57 @@ +// setops.cpp -- some set operations +#include +#include +#include +#include +#include + +int main() +{ + using namespace std; + const int N = 6; + string s1[N] = {"buffoon", "thinkers", "for", "heavy", "can", "for"}; + string s2[N] = {"metal", "any", "food", "elegant", "deliver","for"}; + + set A(s1, s1 + N); + set B(s2, s2 + N); + A.insert("buffalo"); + ostream_iterator out(cout, " "); + cout << "Set A: "; + copy(A.begin(), A.end(), out); + cout << endl; + cout << "Set B: "; + copy(B.begin(), B.end(), out); + cout << endl; + + cout << "Union of A and B:\n"; + set_union(A.begin(), A.end(), B.begin(), B.end(), out); + cout << endl; + + cout << "Intersection of A and B:\n"; + set_intersection(A.begin(), A.end(), B.begin(), B.end(), out); + cout << endl; + + cout << "Difference of A and B:\n"; + set_difference(A.begin(), A.end(), B.begin(), B.end(), out); + cout << endl; + + set C; + cout << "Set C:\n"; + set_union(A.begin(), A.end(), B.begin(), B.end(), + insert_iterator >(C, C.begin())); + copy(C.begin(), C.end(), out); + cout << endl; + + string s3("grungy"); + C.insert(s3); + cout << "Set C after insertion:\n"; + copy(C.begin(), C.end(),out); + cout << endl; + + cout << "Showing a range:\n"; + copy(C.lower_bound("ghost"),C.upper_bound("spook"), out); + cout << endl; + cin.get(); + cin.get(); + return 0; +} diff --git a/study_cpp/cpp_primer_source_code/Appendix G/appg3.cpp b/study_cpp/cpp_primer_source_code/Appendix G/appg3.cpp new file mode 100644 index 0000000..28e6de8 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Appendix G/appg3.cpp @@ -0,0 +1,27 @@ +#include +#include +#include +using namespace std; + +class Items +{ + double x; + double y; + int m; +public: + Items() : x(0),y(0), m(0){}; // #1 + Items (double xx, double yy, int mm): x(xx),y(yy), m(mm){}; // #2 + void Show() const { cout << x << ", " << y << ", " << m << endl;} +}; +int main() +{ + vector vt(5); + + for_each( vt.begin(), vt.end(), [](const Items & i){i.Show();}); + + vt.push_back( Items(8.2, 2.8, 3)); // + for_each( vt.begin(), vt.end(), [](const Items & i){i.Show();}); + vt.emplace_back( 8.2, 2.8, 3); // + for_each( vt.begin(), vt.end(), [](const Items & i){i.Show();}); + cin.get(); +} \ No newline at end of file diff --git a/study_cpp/cpp_primer_source_code/Appendix G/perfectf.cpp b/study_cpp/cpp_primer_source_code/Appendix G/perfectf.cpp new file mode 100644 index 0000000..ded0722 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Appendix G/perfectf.cpp @@ -0,0 +1,26 @@ +#include +#include +#include +using namespace std; + +class Items +{ + double x; + double y; + int m; +public: + Items() : x(0),y(0), m(0){}; // #1 + Items (double xx, double yy, int mm): x(xx),y(yy), m(mm){}; // #2 + void Show() const { cout << x << ", " << y << ", " << m << endl;} +}; + +template + void dumb(int i, Args... args) + { + cout << i << endl; + Items(args...).Show(); + } +int main() +{ + dumb(10, 2.2,4.4,1); +} \ No newline at end of file diff --git a/study_cpp/cpp_primer_source_code/Chapter 10/stack.cpp b/study_cpp/cpp_primer_source_code/Chapter 10/stack.cpp new file mode 100644 index 0000000..b555650 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 10/stack.cpp @@ -0,0 +1,38 @@ +// stack.cpp -- Stack member functions +#include "stack.h" +Stack::Stack() // create an empty stack +{ + top = 0; +} + +bool Stack::isempty() const +{ + return top == 0; +} + +bool Stack::isfull() const +{ + return top == MAX; +} + +bool Stack::push(const Item & item) +{ + if (top < MAX) + { + items[top++] = item; + return true; + } + else + return false; +} + +bool Stack::pop(Item & item) +{ + if (top > 0) + { + item = items[--top]; + return true; + } + else + return false; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 10/stack.h b/study_cpp/cpp_primer_source_code/Chapter 10/stack.h new file mode 100644 index 0000000..cb42221 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 10/stack.h @@ -0,0 +1,22 @@ +// stack.h -- class definition for the stack ADT +#ifndef STACK_H_ +#define STACK_H_ + +typedef unsigned long Item; + +class Stack +{ +private: + enum {MAX = 10}; // constant specific to class + Item items[MAX]; // holds stack items + int top; // index for top stack item +public: + Stack(); + bool isempty() const; + bool isfull() const; + // push() returns false if stack already is full, true otherwise + bool push(const Item & item); // add item to stack + // pop() returns false if stack already is empty, true otherwise + bool pop(Item & item); // pop top into item +}; +#endif diff --git a/study_cpp/cpp_primer_source_code/Chapter 10/stacker.cpp b/study_cpp/cpp_primer_source_code/Chapter 10/stacker.cpp new file mode 100644 index 0000000..7d0838e --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 10/stacker.cpp @@ -0,0 +1,46 @@ +// stacker.cpp -- testing the Stack class +#include +#include // or ctype.h +#include "stack.h" +int main() +{ + using namespace std; + Stack st; // create an empty stack + char ch; + unsigned long po; + cout << "Please enter A to add a purchase order,\n" + << "P to process a PO, or Q to quit.\n"; + while (cin >> ch && toupper(ch) != 'Q') + { + while (cin.get() != '\n') + continue; + if (!isalpha(ch)) + { + cout << '\a'; + continue; + } + switch(ch) + { + case 'A': + case 'a': cout << "Enter a PO number to add: "; + cin >> po; + if (st.isfull()) + cout << "stack already full\n"; + else + st.push(po); + break; + case 'P': + case 'p': if (st.isempty()) + cout << "stack already empty\n"; + else { + st.pop(po); + cout << "PO #" << po << " popped\n"; + } + break; + } + cout << "Please enter A to add a purchase order,\n" + << "P to process a PO, or Q to quit.\n"; + } + cout << "Bye\n"; + return 0; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 10/stock00.cpp b/study_cpp/cpp_primer_source_code/Chapter 10/stock00.cpp new file mode 100644 index 0000000..5ba255e --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 10/stock00.cpp @@ -0,0 +1,69 @@ +// stock00.cpp -- implementing the Stock class +// version 00 +#include +#include "stock00.h" + +void Stock::acquire(const std::string & co, long n, double pr) +{ + company = co; + if (n < 0) + { + std::cout << "Number of shares can't be negative; " + << company << " shares set to 0.\n"; + shares = 0; + } + else + shares = n; + share_val = pr; + set_tot(); +} + +void Stock::buy(long num, double price) +{ + if (num < 0) + { + std::cout << "Number of shares purchased can't be negative. " + << "Transaction is aborted.\n"; + } + else + { + shares += num; + share_val = price; + set_tot(); + } +} + +void Stock::sell(long num, double price) +{ + using std::cout; + if (num < 0) + { + cout << "Number of shares sold can't be negative. " + << "Transaction is aborted.\n"; + } + else if (num > shares) + { + cout << "You can't sell more than you have! " + << "Transaction is aborted.\n"; + } + else + { + shares -= num; + share_val = price; + set_tot(); + } +} + +void Stock::update(double price) +{ + share_val = price; + set_tot(); +} + +void Stock::show() +{ + std::cout << "Company: " << company + << " Shares: " << shares << '\n' + << " Share Price: $" << share_val + << " Total Worth: $" << total_val << '\n'; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 10/stock00.h b/study_cpp/cpp_primer_source_code/Chapter 10/stock00.h new file mode 100644 index 0000000..7b5c334 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 10/stock00.h @@ -0,0 +1,24 @@ +// stock00.h -- Stock class interface +// version 00 +#ifndef STOCK00_H_ +#define STOCK00_H_ + +#include + +class Stock // class declaration +{ +private: + std::string company; + long shares; + double share_val; + double total_val; + void set_tot() { total_val = shares * share_val; } +public: + void acquire(const std::string & co, long n, double pr); + void buy(long num, double price); + void sell(long num, double price); + void update(double price); + void show(); +}; // note semicolon at the end + +#endif \ No newline at end of file diff --git a/study_cpp/cpp_primer_source_code/Chapter 10/stock01.cpp b/study_cpp/cpp_primer_source_code/Chapter 10/stock01.cpp new file mode 100644 index 0000000..a8b5b70 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 10/stock01.cpp @@ -0,0 +1,80 @@ +// stock01.cpp -- revised show() method +#include +#include "stock00.h" + +void Stock::acquire(const std::string & co, long n, double pr) +{ + company = co; + if (n < 0) + { + std::cerr << "Number of shares can't be negative; " + << company << " shares set to 0.\n"; + shares = 0; + } + else + shares = n; + share_val = pr; + set_tot(); +} + +void Stock::buy(long num, double price) +{ + if (num < 0) + { + std::cerr << "Number of shares purchased can't be negative. " + << "Transaction is aborted.\n"; + } + else + { + shares += num; + share_val = price; + set_tot(); + } +} + +void Stock::sell(long num, double price) +{ + using std::cerr; + if (num < 0) + { + cerr << "Number of shares sold can't be negative. " + << "Transaction is aborted.\n"; + } + else if (num > shares) + { + cerr << "You can't sell more than you have! " + << "Transaction is aborted.\n"; + } + else + { + shares -= num; + share_val = price; + set_tot(); + } +} + +void Stock::update(double price) +{ + share_val = price; + set_tot(); +} + +void Stock::show() +{ + using std::cout; + using std::ios_base; + // set format to #.### + ios_base::fmtflags orig = cout.setf(ios_base::fixed); + int prec = cout.precision(3); + + cout << "Company: " << company + << " Shares: " << shares << '\n'; + cout << " Share Price: $" << share_val; + // set format to *.** + cout.precision(2); + cout << " Total Worth: $" << total_val << '\n'; + + // restore original format + cout.setf(orig, ios_base::floatfield); + cout.precision(prec); +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 10/stock10.cpp b/study_cpp/cpp_primer_source_code/Chapter 10/stock10.cpp new file mode 100644 index 0000000..66681e8 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 10/stock10.cpp @@ -0,0 +1,99 @@ +// stock1.cpp Stock class implementation with constructors, destructor added +#include +#include "stock10.h" + +// constructors (verbose versions) +Stock::Stock() // default constructor +{ + std::cout << "Default constructor called\n"; + company = "no name"; + shares = 0; + share_val = 0.0; + total_val = 0.0; +} + +Stock::Stock(const std::string & co, long n, double pr) +{ + std::cout << "Constructor using " << co << " called\n"; + company = co; + + if (n < 0) + { + std::cout << "Number of shares can't be negative; " + << company << " shares set to 0.\n"; + shares = 0; + } + else + shares = n; + share_val = pr; + set_tot(); +} +// class destructor +Stock::~Stock() // verbose class destructor +{ + std::cout << "Bye, " << company << "!\n"; +} + +// other methods +void Stock::buy(long num, double price) +{ + if (num < 0) + { + std::cout << "Number of shares purchased can't be negative. " + << "Transaction is aborted.\n"; + } + else + { + shares += num; + share_val = price; + set_tot(); + } +} + +void Stock::sell(long num, double price) +{ + using std::cout; + if (num < 0) + { + cout << "Number of shares sold can't be negative. " + << "Transaction is aborted.\n"; + } + else if (num > shares) + { + cout << "You can't sell more than you have! " + << "Transaction is aborted.\n"; + } + else + { + shares -= num; + share_val = price; + set_tot(); + } +} + +void Stock::update(double price) +{ + share_val = price; + set_tot(); +} + +void Stock::show() +{ + using std::cout; + using std::ios_base; + // set format to #.### + ios_base::fmtflags orig = + cout.setf(ios_base::fixed, ios_base::floatfield); + std::streamsize prec = cout.precision(3); + + cout << "Company: " << company + << " Shares: " << shares << '\n'; + cout << " Share Price: $" << share_val; + // set format to #.## + cout.precision(2); + cout << " Total Worth: $" << total_val << '\n'; + + // restore original format + cout.setf(orig, ios_base::floatfield); + cout.precision(prec); +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 10/stock10.h b/study_cpp/cpp_primer_source_code/Chapter 10/stock10.h new file mode 100644 index 0000000..980a2b2 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 10/stock10.h @@ -0,0 +1,23 @@ +// stock10.h Stock class declaration with constructors, destructor added +#ifndef STOCK1_H_ +#define STOCK1_H_ +#include +class Stock +{ +private: + std::string company; + long shares; + double share_val; + double total_val; + void set_tot() { total_val = shares * share_val; } +public: + Stock(); // default constructor + Stock(const std::string & co, long n = 0, double pr = 0.0); + ~Stock(); // noisy destructor + void buy(long num, double price); + void sell(long num, double price); + void update(double price); + void show(); +}; + +#endif diff --git a/study_cpp/cpp_primer_source_code/Chapter 10/stock20.cpp b/study_cpp/cpp_primer_source_code/Chapter 10/stock20.cpp new file mode 100644 index 0000000..057658e --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 10/stock20.cpp @@ -0,0 +1,103 @@ +// stock20.cpp -- augmented version +#include +#include "stock20.h" +using namespace std; +// constructors +Stock::Stock() // default constructor +{ + shares = 0; + share_val = 0.0; + total_val = 0.0; +} + +Stock::Stock(const std::string & co, long n, double pr) +{ + company = co; + if (n < 0) + { + std::cout << "Number of shares can't be negative; " + << company << " shares set to 0.\n"; + shares = 0; + } + else + shares = n; + share_val = pr; + set_tot(); +} + +// class destructor +Stock::~Stock() // quiet class destructor +{ +} + +// other methods +void Stock::buy(long num, double price) +{ + if (num < 0) + { + std::cout << "Number of shares purchased can't be negative. " + << "Transaction is aborted.\n"; + } + else + { + shares += num; + share_val = price; + set_tot(); + } +} + +void Stock::sell(long num, double price) +{ + using std::cout; + if (num < 0) + { + cout << "Number of shares sold can't be negative. " + << "Transaction is aborted.\n"; + } + else if (num > shares) + { + cout << "You can't sell more than you have! " + << "Transaction is aborted.\n"; + } + else + { + shares -= num; + share_val = price; + set_tot(); + } +} + +void Stock::update(double price) +{ + share_val = price; + set_tot(); +} + +void Stock::show() const +{ + using std::cout; + using std::ios_base; + // set format to #.### + ios_base::fmtflags orig = + cout.setf(ios_base::fixed, ios_base::floatfield); + std::streamsize prec = cout.precision(3); + + cout << "Company: " << company + << " Shares: " << shares << '\n'; + cout << " Share Price: $" << share_val; + // set format to #.## + cout.precision(2); + cout << " Total Worth: $" << total_val << '\n'; + + // restore original format + cout.setf(orig, ios_base::floatfield); + cout.precision(prec); +} + +const Stock & Stock::topval(const Stock & s) const +{ + if (s.total_val > total_val) + return s; + else + return *this; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 10/stock20.h b/study_cpp/cpp_primer_source_code/Chapter 10/stock20.h new file mode 100644 index 0000000..8fbcad1 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 10/stock20.h @@ -0,0 +1,25 @@ +// stock20.h -- augmented version +#ifndef STOCK20_H_ +#define STOCK20_H_ +#include + +class Stock +{ +private: + std::string company; + int shares; + double share_val; + double total_val; + void set_tot() { total_val = shares * share_val; } +public: + // Stock(); // default constructor + Stock(const std::string & co, long n = 0, double pr = 0.0); + ~Stock(); // do-nothing destructor + void buy(long num, double price); + void sell(long num, double price); + void update(double price); + void show()const; + const Stock & topval(const Stock & s) const; +}; + +#endif diff --git a/study_cpp/cpp_primer_source_code/Chapter 10/stocks.cpp b/study_cpp/cpp_primer_source_code/Chapter 10/stocks.cpp new file mode 100644 index 0000000..9866791 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 10/stocks.cpp @@ -0,0 +1,16 @@ +// stocks.cpp -- the whole program +#include +#include "stocks00.h" + +int main() +{ + Stock stock1; + stock1.acquire("NanoSmart", 20, 12.50); + stock1.show(); + stock1.buy(15, 18.25); + stock1.show(); + stock1.sell(400, 20.00); + stock1.show(); + std::cin.get(); + return 0; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 10/temp20.cpp b/study_cpp/cpp_primer_source_code/Chapter 10/temp20.cpp new file mode 100644 index 0000000..19bb507 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 10/temp20.cpp @@ -0,0 +1,110 @@ +// stock20.cpp -- augmented version +#include +#include "stock20.h" +using namespace std; +// constructors +/* +Stock::Stock() // default constructor +{ + std::cout << "Default constructor called\n"; + company = "no name"; + + shares = 0; + share_val = 0.0; + total_val = 0.0; +} +*/ +Stock::Stock(const std::string & co, long n, double pr) +{ + std::cout << "Constructor using " << co << " called\n"; + + company = co; + if (n < 0) + { + std::cout << "Number of shares can't be negative; " + << company << " shares set to 0.\n"; + shares = 0; + } + else + shares = n; + share_val = pr; + set_tot(); +} + +// class destructor +Stock::~Stock() // quiet class destructor +{ + std::cout << "Bye, " << company << "!\n"; +} + +// other methods +void Stock::buy(long num, double price) +{ + if (num < 0) + { + std::cout << "Number of shares purchased can't be negative. " + << "Transaction is aborted.\n"; + } + else + { + shares += num; + share_val = price; + set_tot(); + } +} + +void Stock::sell(long num, double price) +{ + using std::cout; + if (num < 0) + { + cout << "Number of shares sold can't be negative. " + << "Transaction is aborted.\n"; + } + else if (num > shares) + { + cout << "You can't sell more than you have! " + << "Transaction is aborted.\n"; + } + else + { + shares -= num; + share_val = price; + set_tot(); + } +} + +void Stock::update(double price) +{ + share_val = price; + set_tot(); +} + +void Stock::show() const +{ + using std::cout; + using std::ios_base; + // set format to #.### + ios_base::fmtflags orig = + cout.setf(ios_base::fixed, ios_base::floatfield); + std::streamsize prec = cout.precision(3); + + cout << "Company: " << company + << " Shares: " << shares << '\n'; + cout << " Share Price: $" << share_val; + // set format to #.## + cout.precision(2); + cout << " Total Worth: $" << total_val << '\n'; + + // restore original format + cout.setf(orig, ios_base::floatfield); + cout.precision(prec); +} + +const Stock & Stock::topval(const Stock & s) const +{ + if (s.total_val > total_val) + return s; + else + return *this; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 10/usestok0.cpp b/study_cpp/cpp_primer_source_code/Chapter 10/usestok0.cpp new file mode 100644 index 0000000..37a792f --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 10/usestok0.cpp @@ -0,0 +1,21 @@ +// usestok0.cpp -- the client program +// compile with stock.cpp +#include +#include "stock00.h" + +int main() +{ + Stock fluffy_the_cat; + fluffy_the_cat.acquire("NanoSmart", 20, 12.50); + fluffy_the_cat.show(); + fluffy_the_cat.buy(15, 18.125); + fluffy_the_cat.show(); + fluffy_the_cat.sell(400, 20.00); + fluffy_the_cat.show(); + fluffy_the_cat.buy(300000,40.125); + fluffy_the_cat.show(); + fluffy_the_cat.sell(300000,0.125); + fluffy_the_cat.show(); + // std::cin.get(); + return 0; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 10/usestok1.cpp b/study_cpp/cpp_primer_source_code/Chapter 10/usestok1.cpp new file mode 100644 index 0000000..3cbe194 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 10/usestok1.cpp @@ -0,0 +1,30 @@ +// usestok1.cpp -- using the Stock class +// compile with stock10.cpp +#include +#include "stock10.h" + +int main() +{ + { + using std::cout; + cout << "Using constructors to create new objects\n"; + Stock stock1("NanoSmart", 12, 20.0); // syntax 1 + stock1.show(); + Stock stock2 = Stock ("Boffo Objects", 2, 2.0); // syntax 2 + stock2.show(); + + cout << "Assigning stock1 to stock2:\n"; + stock2 = stock1; + cout << "Listing stock1 and stock2:\n"; + stock1.show(); + stock2.show(); + + cout << "Using a constructor to reset an object\n"; + stock1 = Stock("Nifty Foods", 10, 50.0); // temp object + cout << "Revised stock1:\n"; + stock1.show(); + cout << "Done\n"; + } + // std::cin.get(); + return 0; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 10/usestok2.cpp b/study_cpp/cpp_primer_source_code/Chapter 10/usestok2.cpp new file mode 100644 index 0000000..07a8325 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 10/usestok2.cpp @@ -0,0 +1,30 @@ +// usestok2.cpp -- using the Stock class +// compile with stock20.cpp +#include +#include "stock20.h" + +const int STKS = 4; +int main() +{{ +// create an array of initialized objects + Stock stocks[STKS] = { + Stock("NanoSmart", 12, 20.0), + Stock("Boffo Objects", 200, 2.0), + Stock("Monolithic Obelisks", 130, 3.25), + Stock("Fleep Enterprises", 60, 6.5) + }; + + std::cout << "Stock holdings:\n"; + int st; + for (st = 0; st < STKS; st++) + stocks[st].show(); +// set pointer to first element + const Stock * top = &stocks[0]; + for (st = 1; st < STKS; st++) + top = &top->topval(stocks[st]); +// now top points to the most valuable holding + std::cout << "\nMost valuable holding:\n"; + top->show();} + // std::cin.get(); + return 0; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 11/mytime.cpp b/study_cpp/cpp_primer_source_code/Chapter 11/mytime.cpp new file mode 100644 index 0000000..a149082 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 11/mytime.cpp @@ -0,0 +1,46 @@ +// mytime0.cpp -- implementing Time methods +#include +#include "mytime0.h" + +Time::Time() +{ + hours = minutes = 0; +} + +Time::Time(int h, int m ) +{ + hours = h; + minutes = m; +} + +void Time::AddMin(int m) +{ + minutes += m; + hours += minutes / 60; + minutes %= 60; +} + +void Time::AddHr(int h) +{ + hours += h; +} + +void Time::Reset(int h, int m) +{ + hours = h; + minutes = m; +} + +const Time Time::Sum(const Time & t) const +{ + Time sum; + sum.minutes = minutes + t.minutes; + sum.hours = hours + t.hours + sum.minutes / 60; + sum.minutes %= 60; + return sum; +} + +void Time::Show() const +{ + std::cout << hours << " hours, " << minutes << " minutes"; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 11/mytime0.h b/study_cpp/cpp_primer_source_code/Chapter 11/mytime0.h new file mode 100644 index 0000000..2ef5632 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 11/mytime0.h @@ -0,0 +1,19 @@ +// mytime0.h -- Time class before operator overloading +#ifndef MYTIME0_H_ +#define MYTIME0_H_ + +class Time +{ +private: + int hours; + int minutes; +public: + Time(); + Time(int h, int m = 0); + void AddMin(int m); + void AddHr(int h); + void Reset(int h = 0, int m = 0); + const Time Sum(const Time & t) const; + void Show() const; +}; +#endif diff --git a/study_cpp/cpp_primer_source_code/Chapter 11/mytime1.cpp b/study_cpp/cpp_primer_source_code/Chapter 11/mytime1.cpp new file mode 100644 index 0000000..6bb9edb --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 11/mytime1.cpp @@ -0,0 +1,46 @@ +// mytime1.cpp -- implementing Time methods +#include +#include "mytime1.h" + +Time::Time() +{ + hours = minutes = 0; +} + +Time::Time(int h, int m ) +{ + hours = h; + minutes = m; +} + +void Time::AddMin(int m) +{ + minutes += m; + hours += minutes / 60; + minutes %= 60; +} + +void Time::AddHr(int h) +{ + hours += h; +} + +void Time::Reset(int h, int m) +{ + hours = h; + minutes = m; +} + +Time Time::operator+(const Time & t) const +{ + Time sum; + sum.minutes = minutes + t.minutes; + sum.hours = hours + t.hours + sum.minutes / 60; + sum.minutes %= 60; + return sum; +} + +void Time::Show() const +{ + std::cout << hours << " hours, " << minutes << " minutes"; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 11/mytime1.h b/study_cpp/cpp_primer_source_code/Chapter 11/mytime1.h new file mode 100644 index 0000000..019940f --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 11/mytime1.h @@ -0,0 +1,19 @@ +// mytime1.h -- Time class before operator overloading +#ifndef MYTIME1_H_ +#define MYTIME1_H_ + +class Time +{ +private: + int hours; + int minutes; +public: + Time(); + Time(int h, int m = 0); + void AddMin(int m); + void AddHr(int h); + void Reset(int h = 0, int m = 0); + Time operator+(const Time & t) const; + void Show() const; +}; +#endif diff --git a/study_cpp/cpp_primer_source_code/Chapter 11/mytime2.cpp b/study_cpp/cpp_primer_source_code/Chapter 11/mytime2.cpp new file mode 100644 index 0000000..e9237b7 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 11/mytime2.cpp @@ -0,0 +1,65 @@ +// mytime2.cpp -- implementing Time methods +#include +#include "mytime2.h" + +Time::Time() +{ + hours = minutes = 0; +} + +Time::Time(int h, int m ) +{ + hours = h; + minutes = m; +} + +void Time::AddMin(int m) +{ + minutes += m; + hours += minutes / 60; + minutes %= 60; +} +void Time::AddHr(int h) +{ + hours += h; +} + +void Time::Reset(int h, int m) +{ + hours = h; + minutes = m; +} + +Time Time::operator+(const Time & t) const +{ + Time sum; + sum.minutes = minutes + t.minutes; + sum.hours = hours + t.hours + sum.minutes / 60; + sum.minutes %= 60; + return sum; +} + +Time Time::operator-(const Time & t) const +{ + Time diff; + int tot1, tot2; + tot1 = t.minutes + 60 * t.hours; + tot2 = minutes + 60 * hours; + diff.minutes = (tot2 - tot1) % 60; + diff.hours = (tot2 - tot1) / 60; + return diff; +} + +Time Time::operator*(double mult) const +{ + Time result; + long totalminutes = hours * mult * 60 + minutes * mult; + result.hours = totalminutes / 60; + result.minutes = totalminutes % 60; + return result; +} + +void Time::Show() const +{ + std::cout << hours << " hours, " << minutes << " minutes"; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 11/mytime2.h b/study_cpp/cpp_primer_source_code/Chapter 11/mytime2.h new file mode 100644 index 0000000..0d632d3 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 11/mytime2.h @@ -0,0 +1,21 @@ +// mytime2.h -- Time class after operator overloading +#ifndef MYTIME2_H_ +#define MYTIME2_H_ + +class Time +{ +private: + int hours; + int minutes; +public: + Time(); + Time(int h, int m = 0); + void AddMin(int m); + void AddHr(int h); + void Reset(int h = 0, int m = 0); + Time operator+(const Time & t) const; + Time operator-(const Time & t) const; + Time operator*(double n) const; + void Show() const; +}; +#endif diff --git a/study_cpp/cpp_primer_source_code/Chapter 11/mytime3.cpp b/study_cpp/cpp_primer_source_code/Chapter 11/mytime3.cpp new file mode 100644 index 0000000..b3bed07 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 11/mytime3.cpp @@ -0,0 +1,66 @@ +// mytime3.cpp -- implementing Time methods +#include "mytime3.h" + +Time::Time() +{ + hours = minutes = 0; +} + +Time::Time(int h, int m ) +{ + hours = h; + minutes = m; +} + +void Time::AddMin(int m) +{ + minutes += m; + hours += minutes / 60; + minutes %= 60; +} + +void Time::AddHr(int h) +{ + hours += h; +} + +void Time::Reset(int h, int m) +{ + hours = h; + minutes = m; +} + +Time Time::operator+(const Time & t) const +{ + Time sum; + sum.minutes = minutes + t.minutes; + sum.hours = hours + t.hours + sum.minutes / 60; + sum.minutes %= 60; + return sum; +} + +Time Time::operator-(const Time & t) const +{ + Time diff; + int tot1, tot2; + tot1 = t.minutes + 60 * t.hours; + tot2 = minutes + 60 * hours; + diff.minutes = (tot2 - tot1) % 60; + diff.hours = (tot2 - tot1) / 60; + return diff; +} + +Time Time::operator*(double mult) const +{ + Time result; + long totalminutes = hours * mult * 60 + minutes * mult; + result.hours = totalminutes / 60; + result.minutes = totalminutes % 60; + return result; +} + +std::ostream & operator<<(std::ostream & os, const Time & t) +{ + os << t.hours << " hours, " << t.minutes << " minutes"; + return os; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 11/mytime3.h b/study_cpp/cpp_primer_source_code/Chapter 11/mytime3.h new file mode 100644 index 0000000..de8a7e8 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 11/mytime3.h @@ -0,0 +1,25 @@ +// mytime3.h -- Time class with friends +#ifndef MYTIME3_H_ +#define MYTIME3_H_ +#include + +class Time +{ +private: + int hours; + int minutes; +public: + Time(); + Time(int h, int m = 0); + void AddMin(int m); + void AddHr(int h); + void Reset(int h = 0, int m = 0); + Time operator+(const Time & t) const; + Time operator-(const Time & t) const; + Time operator*(double n) const; + friend Time operator*(double m, const Time & t) + { return t * m; } // inline definition + friend std::ostream & operator<<(std::ostream & os, const Time & t); + +}; +#endif diff --git a/study_cpp/cpp_primer_source_code/Chapter 11/randwalk.cpp b/study_cpp/cpp_primer_source_code/Chapter 11/randwalk.cpp new file mode 100644 index 0000000..4019d30 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 11/randwalk.cpp @@ -0,0 +1,51 @@ +// randwalk.cpp -- using the Vector class +// compile with the vect.cpp file +#include +#include // rand(), srand() prototypes +#include // time() prototype +#include "vect.h" +int main() +{ + using namespace std; + using VECTOR::Vector; + srand(time(0)); // seed random-number generator + double direction; + Vector step; + Vector result(0.0, 0.0); + unsigned long steps = 0; + double target; + double dstep; + cout << "Enter target distance (q to quit): "; + while (cin >> target) + { + cout << "Enter step length: "; + if (!(cin >> dstep)) + break; + + while (result.magval() < target) + { + direction = rand() % 360; + step.reset(dstep, direction, POL); + result = result + step; + steps++; + } + cout << "After " << steps << " steps, the subject " + "has the following location:\n"; + cout << result << endl; + result.polar_mode(); + cout << " or\n" << result << endl; + cout << "Average outward distance per step = " + << result.magval()/steps << endl; + steps = 0; + result.reset(0.0, 0.0); + cout << "Enter target distance (q to quit): "; + } + cout << "Bye!\n"; +/* keep window open + cin.clear(); + while (cin.get() != '\n') + continue; + cin.get(); +*/ + return 0; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 11/stone.cpp b/study_cpp/cpp_primer_source_code/Chapter 11/stone.cpp new file mode 100644 index 0000000..57fcb30 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 11/stone.cpp @@ -0,0 +1,40 @@ +// stone.cpp -- user-defined conversions +// compile with stonewt.cpp +#include +using std::cout; +#include "stonewt.h" +void display(const Stonewt & st, int n); +int main() +{ + Stonewt incognito = 275; // uses constructor to initialize + Stonewt wolfe(285.7); // same as Stonewt wolfe = 285.7; + Stonewt taft(21, 8); + + cout << "The celebrity weighed "; + incognito.show_stn(); + cout << "The detective weighed "; + wolfe.show_stn(); + cout << "The President weighed "; + taft.show_lbs(); + incognito = 276.8; // uses constructor for conversion + taft = 325; // same as taft = Stonewt(325); + cout << "After dinner, the celebrity weighed "; + incognito.show_stn(); + cout << "After dinner, the President weighed "; + taft.show_lbs(); + display(taft, 2); + cout << "The wrestler weighed even more.\n"; + display(422, 2); + cout << "No stone left unearned\n"; + // std::cin.get(); + return 0; +} + +void display(const Stonewt & st, int n) +{ + for (int i = 0; i < n; i++) + { + cout << "Wow! "; + st.show_stn(); + } +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 11/stone1.cpp b/study_cpp/cpp_primer_source_code/Chapter 11/stone1.cpp new file mode 100644 index 0000000..414a03f --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 11/stone1.cpp @@ -0,0 +1,17 @@ +// stone1.cpp -- user-defined conversion functions +// compile with stonewt1.cpp +#include +#include "stonewt1.h" + +int main() +{ + using std::cout; + Stonewt poppins(9,2.8); // 9 stone, 2.8 pounds + double p_wt = poppins; // implicit conversion + cout << "Convert to double => "; + cout << "Poppins: " << p_wt << " pounds.\n"; + cout << "Convert to int => "; + cout << "Poppins: " << int (poppins) << " pounds.\n"; + // std::cin.get(); + return 0; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 11/stonewt.cpp b/study_cpp/cpp_primer_source_code/Chapter 11/stonewt.cpp new file mode 100644 index 0000000..cc7e6a4 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 11/stonewt.cpp @@ -0,0 +1,41 @@ +// stonewt.cpp -- Stonewt methods +#include +using std::cout; +#include "stonewt.h" + +// construct Stonewt object from double value +Stonewt::Stonewt(double lbs) +{ + stone = int (lbs) / Lbs_per_stn; // integer division + pds_left = int (lbs) % Lbs_per_stn + lbs - int(lbs); + pounds = lbs; +} + +// construct Stonewt object from stone, double values +Stonewt::Stonewt(int stn, double lbs) +{ + stone = stn; + pds_left = lbs; + pounds = stn * Lbs_per_stn +lbs; +} + +Stonewt::Stonewt() // default constructor, wt = 0 +{ + stone = pounds = pds_left = 0; +} + +Stonewt::~Stonewt() // destructor +{ +} + +// show weight in stones +void Stonewt::show_stn() const +{ + cout << stone << " stone, " << pds_left << " pounds\n"; +} + +// show weight in pounds +void Stonewt::show_lbs() const +{ + cout << pounds << " pounds\n"; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 11/stonewt.h b/study_cpp/cpp_primer_source_code/Chapter 11/stonewt.h new file mode 100644 index 0000000..aa5f428 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 11/stonewt.h @@ -0,0 +1,19 @@ +// stonewt.h -- definition for the Stonewt class +#ifndef STONEWT_H_ +#define STONEWT_H_ +class Stonewt +{ +private: + enum {Lbs_per_stn = 14}; // pounds per stone + int stone; // whole stones + double pds_left; // fractional pounds + double pounds; // entire weight in pounds +public: + Stonewt(double lbs); // constructor for double pounds + Stonewt(int stn, double lbs); // constructor for stone, lbs + Stonewt(); // default constructor + ~Stonewt(); + void show_lbs() const; // show weight in pounds format + void show_stn() const; // show weight in stone format +}; +#endif diff --git a/study_cpp/cpp_primer_source_code/Chapter 11/stonewt1.cpp b/study_cpp/cpp_primer_source_code/Chapter 11/stonewt1.cpp new file mode 100644 index 0000000..4742bbb --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 11/stonewt1.cpp @@ -0,0 +1,54 @@ +// stonewt1.cpp -- Stonewt class methods + conversion functions +#include +using std::cout; +#include "stonewt1.h" + +// construct Stonewt object from double value +Stonewt::Stonewt(double lbs) +{ + stone = int (lbs) / Lbs_per_stn; // integer division + pds_left = int (lbs) % Lbs_per_stn + lbs - int(lbs); + pounds = lbs; +} + +// construct Stonewt object from stone, double values +Stonewt::Stonewt(int stn, double lbs) +{ + stone = stn; + pds_left = lbs; + pounds = stn * Lbs_per_stn +lbs; +} + +Stonewt::Stonewt() // default constructor, wt = 0 +{ + stone = pounds = pds_left = 0; +} + +Stonewt::~Stonewt() // destructor +{ +} + +// show weight in stones +void Stonewt::show_stn() const +{ + cout << stone << " stone, " << pds_left << " pounds\n"; +} + +// show weight in pounds +void Stonewt::show_lbs() const +{ + cout << pounds << " pounds\n"; +} + +// conversion functions +Stonewt::operator int() const +{ + + return int (pounds + 0.5); + +} + +Stonewt::operator double()const +{ + return pounds; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 11/stonewt1.h b/study_cpp/cpp_primer_source_code/Chapter 11/stonewt1.h new file mode 100644 index 0000000..be3181f --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 11/stonewt1.h @@ -0,0 +1,22 @@ +// stonewt1.h -- revised definition for the Stonewt class +#ifndef STONEWT1_H_ +#define STONEWT1_H_ +class Stonewt +{ +private: + enum {Lbs_per_stn = 14}; // pounds per stone + int stone; // whole stones + double pds_left; // fractional pounds + double pounds; // entire weight in pounds +public: + Stonewt(double lbs); // construct from double pounds + Stonewt(int stn, double lbs); // construct from stone, lbs + Stonewt(); // default constructor + ~Stonewt(); + void show_lbs() const; // show weight in pounds format + void show_stn() const; // show weight in stone format +// conversion functions + operator int() const; + operator double() const; +}; +#endif diff --git a/study_cpp/cpp_primer_source_code/Chapter 11/usetime0.cpp b/study_cpp/cpp_primer_source_code/Chapter 11/usetime0.cpp new file mode 100644 index 0000000..008a90d --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 11/usetime0.cpp @@ -0,0 +1,33 @@ +// usetime0.cpp -- using the first draft of the Time class +// compile usetime0.cpp and mytime0.cpp together +#include +#include "mytime0.h" + +int main() +{ + using std::cout; + using std::endl; + Time planning; + Time coding(2, 40); + Time fixing(5, 55); + Time total; + + cout << "planning time = "; + planning.Show(); + cout << endl; + + cout << "coding time = "; + coding.Show(); + cout << endl; + + cout << "fixing time = "; + fixing.Show(); + cout << endl; + + total = coding.Sum(fixing); + cout << "coding.Sum(fixing) = "; + total.Show(); + cout << endl; + // std::cin.get(); + return 0; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 11/usetime1.cpp b/study_cpp/cpp_primer_source_code/Chapter 11/usetime1.cpp new file mode 100644 index 0000000..b6b9771 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 11/usetime1.cpp @@ -0,0 +1,44 @@ +// usetime1.cpp -- using the second draft of the Time class +// compile usetime1.cpp and mytime1.cpp together +#include +#include "mytime1.h" + +int main() +{ + using std::cout; + using std::endl; + Time planning; + Time coding(2, 40); + Time fixing(5, 55); + Time total; + + cout << "planning time = "; + planning.Show(); + cout << endl; + + cout << "coding time = "; + coding.Show(); + cout << endl; + + cout << "fixing time = "; + fixing.Show(); + cout << endl; + + total = coding + fixing; + // operator notation + cout << "coding + fixing = "; + total.Show(); + cout << endl; + + Time morefixing(3, 28); + cout << "more fixing time = "; + morefixing.Show(); + cout << endl; + total = morefixing.operator+(total); + // function notation + cout << "morefixing.operator+(total) = "; + total.Show(); + cout << endl; + // std::cin.get(); + return 0; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 11/usetime2.cpp b/study_cpp/cpp_primer_source_code/Chapter 11/usetime2.cpp new file mode 100644 index 0000000..be3f720 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 11/usetime2.cpp @@ -0,0 +1,40 @@ +// usetime2.cpp -- using the third draft of the Time class +// compile usetime2.cpp and mytime2.cpp together +#include +#include "mytime2.h" + +int main() +{ + using std::cout; + using std::endl; + Time weeding(4, 35); + Time waxing(2, 47); + Time total; + Time diff; + Time adjusted; + + cout << "weeding time = "; + weeding.Show(); + cout << endl; + + cout << "waxing time = "; + waxing.Show(); + cout << endl; + + cout << "total work time = "; + total = weeding + waxing; // use operator+() + total.Show(); + cout << endl; + + diff = weeding - waxing; // use operator-() + cout << "weeding time - waxing time = "; + diff.Show(); + cout << endl; + + adjusted = total * 1.5; // use operator+() + cout << "adjusted work time = "; + adjusted.Show(); + cout << endl; + // std::cin.get(); + return 0; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 11/usetime3.cpp b/study_cpp/cpp_primer_source_code/Chapter 11/usetime3.cpp new file mode 100644 index 0000000..8b5d4e9 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 11/usetime3.cpp @@ -0,0 +1,23 @@ +//usetime3.cpp -- using the fourth draft of the Time class +// compile usetime3.cpp and mytime3.cpp together +#include +#include "mytime3.h" + +int main() +{ + using std::cout; + using std::endl; + Time aida(3, 35); + Time tosca(2, 48); + Time temp; + + cout << "Aida and Tosca:\n"; + cout << aida<<"; " << tosca << endl; + temp = aida + tosca; // operator+() + cout << "Aida + Tosca: " << temp << endl; + temp = aida* 1.17; // member operator*() + cout << "Aida * 1.17: " << temp << endl; + cout << "10.0 * Tosca: " << 10.0 * tosca << endl; + // std::cin.get(); + return 0; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 11/vect.cpp b/study_cpp/cpp_primer_source_code/Chapter 11/vect.cpp new file mode 100644 index 0000000..069e26c --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 11/vect.cpp @@ -0,0 +1,170 @@ +// vect.cpp -- methods for the Vector class +#include +#include "vect.h" // includes +using std::sqrt; +using std::sin; +using std::cos; +using std::atan; +using std::atan2; +using std::cout; + +namespace VECTOR +{ + // compute degrees in one radian + const double Rad_to_deg = 45.0 / atan(1.0); + // should be about 57.2957795130823 + + // private methods + // calculates magnitude from x and y + void Vector::set_mag() + { + mag = sqrt(x * x + y * y); + } + + void Vector::set_ang() + { + if (x == 0.0 && y == 0.0) + ang = 0.0; + else + ang = atan2(y, x); + } + + // set x from polar coordinate + void Vector::set_x() + { + x = mag * cos(ang); + } + + // set y from polar coordinate + void Vector::set_y() + { + y = mag * sin(ang); + } + + // public methods + Vector::Vector() // default constructor + { + x = y = mag = ang = 0.0; + mode = RECT; + } + + // construct vector from rectangular coordinates if form is r + // (the default) or else from polar coordinates if form is p + Vector::Vector(double n1, double n2, Mode form) + { + mode = form; + if (form == RECT) + { + x = n1; + y = n2; + set_mag(); + set_ang(); + } + else if (form == POL) + { + mag = n1; + ang = n2 / Rad_to_deg; + set_x(); + set_y(); + } + else + { + cout << "Incorrect 3rd argument to Vector() -- "; + cout << "vector set to 0\n"; + x = y = mag = ang = 0.0; + mode = RECT; + } + } + + // reset vector from rectangular coordinates if form is + // RECT (the default) or else from polar coordinates if + // form is POL + void Vector:: reset(double n1, double n2, Mode form) + { + mode = form; + if (form == RECT) + { + x = n1; + y = n2; + set_mag(); + set_ang(); + } + else if (form == POL) + { + mag = n1; + ang = n2 / Rad_to_deg; + set_x(); + set_y(); + } + else + { + cout << "Incorrect 3rd argument to Vector() -- "; + cout << "vector set to 0\n"; + x = y = mag = ang = 0.0; + mode = RECT; + } + } + + Vector::~Vector() // destructor + { + } + + void Vector::polar_mode() // set to polar mode + { + mode = POL; + } + + void Vector::rect_mode() // set to rectangular mode + { + mode = RECT; + } + + // operator overloading + // add two Vectors + Vector Vector::operator+(const Vector & b) const + { + return Vector(x + b.x, y + b.y); + } + + // subtract Vector b from a + Vector Vector::operator-(const Vector & b) const + { + return Vector(x - b.x, y - b.y); + } + + // reverse sign of Vector + Vector Vector::operator-() const + { + return Vector(-x, -y); + } + + // multiply vector by n + Vector Vector::operator*(double n) const + { + return Vector(n * x, n * y); + } + + // friend methods + // multiply n by Vector a + Vector operator*(double n, const Vector & a) + { + return a * n; + } + + // display rectangular coordinates if mode is RECT, + // else display polar coordinates if mode is POL + std::ostream & operator<<(std::ostream & os, const Vector & v) + { + if (v.mode == Vector::RECT) + os << "(x,y) = (" << v.x << ", " << v.y << ")"; + else if (v.mode == Vector::POL) + { + os << "(m,a) = (" << v.mag << ", " + << v.ang * Rad_to_deg << ")"; + } + else + os << "Vector object mode is invalid"; + return os; + } + +} // end namespace VECTOR diff --git a/study_cpp/cpp_primer_source_code/Chapter 11/vect.h b/study_cpp/cpp_primer_source_code/Chapter 11/vect.h new file mode 100644 index 0000000..749a59a --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 11/vect.h @@ -0,0 +1,45 @@ +// vect.h -- Vector class with <<, mode state +#ifndef VECTOR_H_ +#define VECTOR_H_ +#include +namespace VECTOR +{ + class Vector + { + public: + enum Mode {RECT, POL}; + // RECT for rectangular, POL for Polar modes + private: + double x; // horizontal value + double y; // vertical value + double mag; // length of vector + double ang; // direction of vector in degrees + Mode mode; // RECT or POL + // private methods for setting values + void set_mag(); + void set_ang(); + void set_x(); + void set_y(); + public: + Vector(); + Vector(double n1, double n2, Mode form = RECT); + void reset(double n1, double n2, Mode form = RECT); + ~Vector(); + double xval() const {return x;} // report x value + double yval() const {return y;} // report y value + double magval() const {return mag;} // report magnitude + double angval() const {return ang;} // report angle + void polar_mode(); // set mode to POL + void rect_mode(); // set mode to RECT + // operator overloading + Vector operator+(const Vector & b) const; + Vector operator-(const Vector & b) const; + Vector operator-() const; + Vector operator*(double n) const; + // friends + friend Vector operator*(double n, const Vector & a); + friend std::ostream & operator<<(std::ostream & os, const Vector & v); + }; + +} // end namespace VECTOR +#endif diff --git a/study_cpp/cpp_primer_source_code/Chapter 12/bank.cpp b/study_cpp/cpp_primer_source_code/Chapter 12/bank.cpp new file mode 100644 index 0000000..bc9c417 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 12/bank.cpp @@ -0,0 +1,99 @@ +// bank.cpp -- using the Queue interface +// compile with queue.cpp +#include +#include // for rand() and srand() +#include // for time() +#include "queue.h" +const int MIN_PER_HR = 60; + +bool newcustomer(double x); // is there a new customer? + +int main() +{ + using std::cin; + using std::cout; + using std::endl; + using std::ios_base; +// setting things up + std::srand(std::time(0)); // random initializing of rand() + + cout << "Case Study: Bank of Heather Automatic Teller\n"; + cout << "Enter maximum size of queue: "; + int qs; + cin >> qs; + Queue line(qs); // line queue holds up to qs people + + cout << "Enter the number of simulation hours: "; + int hours; // hours of simulation + cin >> hours; + // simulation will run 1 cycle per minute + long cyclelimit = MIN_PER_HR * hours; // # of cycles + + cout << "Enter the average number of customers per hour: "; + double perhour; // average # of arrival per hour + cin >> perhour; + double min_per_cust; // average time between arrivals + min_per_cust = MIN_PER_HR / perhour; + + Item temp; // new customer data + long turnaways = 0; // turned away by full queue + long customers = 0; // joined the queue + long served = 0; // served during the simulation + long sum_line = 0; // cumulative line length + int wait_time = 0; // time until autoteller is free + long line_wait = 0; // cumulative time in line + + +// running the simulation + for (int cycle = 0; cycle < cyclelimit; cycle++) + { + if (newcustomer(min_per_cust)) // have newcomer + { + if (line.isfull()) + turnaways++; + else + { + customers++; + temp.set(cycle); // cycle = time of arrival + line.enqueue(temp); // add newcomer to line + } + } + if (wait_time <= 0 && !line.isempty()) + { + line.dequeue (temp); // attend next customer + wait_time = temp.ptime(); // for wait_time minutes + line_wait += cycle - temp.when(); + served++; + } + if (wait_time > 0) + wait_time--; + sum_line += line.queuecount(); + } + +// reporting results + if (customers > 0) + { + cout << "customers accepted: " << customers << endl; + cout << " customers served: " << served << endl; + cout << " turnaways: " << turnaways << endl; + cout << "average queue size: "; + cout.precision(2); + cout.setf(ios_base::fixed, ios_base::floatfield); + cout << (double) sum_line / cyclelimit << endl; + cout << " average wait time: " + << (double) line_wait / served << " minutes\n"; + } + else + cout << "No customers!\n"; + cout << "Done!\n"; + // cin.get(); + // cin.get(); + return 0; +} + +// x = average time, in minutes, between customers +// return value is true if customer shows up this minute +bool newcustomer(double x) +{ + return (std::rand() * x / RAND_MAX < 1); +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 12/placenew1.cpp b/study_cpp/cpp_primer_source_code/Chapter 12/placenew1.cpp new file mode 100644 index 0000000..a2cf7bf --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 12/placenew1.cpp @@ -0,0 +1,51 @@ +// placenew1.cpp -- new, placement new, no delete +#include +#include +#include +using namespace std; +const int BUF = 512; + +class JustTesting +{ +private: + string words; + int number; +public: + JustTesting(const string & s = "Just Testing", int n = 0) + {words = s; number = n; cout << words << " constructed\n"; } + ~JustTesting() { cout << words << " destroyed\n";} + void Show() const { cout << words << ", " << number << endl;} +}; +int main() +{ + char * buffer = new char[BUF]; // get a block of memory + + JustTesting *pc1, *pc2; + + pc1 = new (buffer) JustTesting; // place object in buffer + pc2 = new JustTesting("Heap1", 20); // place object on heap + + cout << "Memory block addresses:\n" << "buffer: " + << (void *) buffer << " heap: " << pc2 <Show(); + cout << pc2 << ": "; + pc2->Show(); + + JustTesting *pc3, *pc4; + pc3 = new (buffer) JustTesting("Bad Idea", 6); + pc4 = new JustTesting("Heap2", 10); + cout << "Memory contents:\n"; + cout << pc3 << ": "; + pc3->Show(); + cout << pc4 << ": "; + pc4->Show(); + + delete pc2; // free Heap1 + delete pc4; // free Heap2 + delete [] buffer; // free buffer + cout << "Done\n"; + // std::cin.get(); + return 0; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 12/placenew2.cpp b/study_cpp/cpp_primer_source_code/Chapter 12/placenew2.cpp new file mode 100644 index 0000000..6b77498 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 12/placenew2.cpp @@ -0,0 +1,56 @@ +// placenew2.cpp -- new, placement new, no delete +#include +#include +#include +using namespace std; +const int BUF = 512; + +class JustTesting +{ +private: + string words; + int number; +public: + JustTesting(const string & s = "Just Testing", int n = 0) + {words = s; number = n; cout << words << " constructed\n"; } + ~JustTesting() { cout << words << " destroyed\n";} + void Show() const { cout << words << ", " << number << endl;} +}; +int main() +{ + char * buffer = new char[BUF]; // get a block of memory + + JustTesting *pc1, *pc2; + + pc1 = new (buffer) JustTesting; // place object in buffer + pc2 = new JustTesting("Heap1", 20); // place object on heap + + cout << "Memory block addresses:\n" << "buffer: " + << (void *) buffer << " heap: " << pc2 <Show(); + cout << pc2 << ": "; + pc2->Show(); + + JustTesting *pc3, *pc4; +// fix placement new location + pc3 = new (buffer + sizeof (JustTesting)) + JustTesting("Better Idea", 6); + pc4 = new JustTesting("Heap2", 10); + + cout << "Memory contents:\n"; + cout << pc3 << ": "; + pc3->Show(); + cout << pc4 << ": "; + pc4->Show(); + + delete pc2; // free Heap1 + delete pc4; // free Heap2 +// explicitly destroy placement new objects + pc3->~JustTesting(); // destroy object pointed to by pc3 + pc1->~JustTesting(); // destroy object pointed to by pc1 + delete [] buffer; // free buffer + // std::cin.get(); + return 0; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 12/queue.cpp b/study_cpp/cpp_primer_source_code/Chapter 12/queue.cpp new file mode 100644 index 0000000..423229b --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 12/queue.cpp @@ -0,0 +1,80 @@ +// queue.cpp -- Queue and Customer methods +#include "queue.h" +#include // (or stdlib.h) for rand() + +// Queue methods +Queue::Queue(int qs) : qsize(qs) +{ + front = rear = NULL; // or nullptr + items = 0; +} + +Queue::~Queue() +{ + Node * temp; + while (front != NULL) // while queue is not yet empty + { + temp = front; // save address of front item + front = front->next;// reset pointer to next item + delete temp; // delete former front + } +} + +bool Queue::isempty() const +{ + return items == 0; +} + +bool Queue::isfull() const +{ + return items == qsize; +} + +int Queue::queuecount() const +{ + return items; +} + +// Add item to queue +bool Queue::enqueue(const Item & item) +{ + if (isfull()) + return false; + Node * add = new Node; // create node +// on failure, new throws std::bad_alloc exception + add->item = item; // set node pointers + add->next = NULL; // or nullptr; + items++; + if (front == NULL) // if queue is empty, + front = add; // place item at front + else + rear->next = add; // else place at rear + rear = add; // have rear point to new node + return true; +} + +// Place front item into item variable and remove from queue +bool Queue::dequeue(Item & item) +{ + if (front == NULL) + return false; + item = front->item; // set item to first item in queue + items--; + Node * temp = front; // save location of first item + front = front->next; // reset front to next item + delete temp; // delete former first item + if (items == 0) + rear = NULL; + return true; +} + +// customer method + +// when is the time at which the customer arrives +// the arrival time is set to when and the processing +// time set to a random value in the range 1 - 3 +void Customer::set(long when) +{ + processtime = std::rand() % 3 + 1; + arrive = when; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 12/queue.h b/study_cpp/cpp_primer_source_code/Chapter 12/queue.h new file mode 100644 index 0000000..1001f62 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 12/queue.h @@ -0,0 +1,43 @@ +// queue.h -- interface for a queue +#ifndef QUEUE_H_ +#define QUEUE_H_ +// This queue will contain Customer items +class Customer +{ +private: + long arrive; // arrival time for customer + int processtime; // processing time for customer +public: + Customer() : arrive(0), processtime (0){} + void set(long when); + long when() const { return arrive; } + int ptime() const { return processtime; } +}; + +typedef Customer Item; + +class Queue +{ +private: +// class scope definitions + // Node is a nested structure definition local to this class + struct Node { Item item; struct Node * next;}; + enum {Q_SIZE = 10}; +// private class members + Node * front; // pointer to front of Queue + Node * rear; // pointer to rear of Queue + int items; // current number of items in Queue + const int qsize; // maximum number of items in Queue + // preemptive definitions to prevent public copying + Queue(const Queue & q) : qsize(0) { } + Queue & operator=(const Queue & q) { return *this;} +public: + Queue(int qs = Q_SIZE); // create queue with a qs limit + ~Queue(); + bool isempty() const; + bool isfull() const; + int queuecount() const; + bool enqueue(const Item &item); // add item to end + bool dequeue(Item &item); // remove item from front +}; +#endif diff --git a/study_cpp/cpp_primer_source_code/Chapter 12/sayings1.cpp b/study_cpp/cpp_primer_source_code/Chapter 12/sayings1.cpp new file mode 100644 index 0000000..9f4773b --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 12/sayings1.cpp @@ -0,0 +1,62 @@ +// sayings1.cpp -- using expanded String class +// compile with string1.cpp +#include +#include "string1.h" +const int ArSize = 10; +const int MaxLen =81; +int main() +{ + using std::cout; + using std::cin; + using std::endl; + String name; + cout <<"Hi, what's your name?\n>> "; + cin >> name; + + cout << name << ", please enter up to " << ArSize + << " short sayings :\n"; + String sayings[ArSize]; // array of objects + char temp[MaxLen]; // temporary string storage + int i; + for (i = 0; i < ArSize; i++) + { + cout << i+1 << ": "; + cin.get(temp, MaxLen); + while (cin && cin.get() != '\n') + continue; + if (!cin || temp[0] == '\0') // empty line? + break; // i not incremented + else + sayings[i] = temp; // overloaded assignment + } + int total = i; // total # of lines read + + if ( total > 0) + { + cout << "Here are your sayings:\n"; + for (i = 0; i < total; i++) + cout << sayings[i][0] << ": " << sayings[i] << endl; + + int shortest = 0; + int first = 0; + for (i = 1; i < total; i++) + { + if (sayings[i].length() < sayings[shortest].length()) + shortest = i; + if (sayings[i] < sayings[first]) + first = i; + } + cout << "Shortest saying:\n" << sayings[shortest] << endl;; + cout << "First alphabetically:\n" << sayings[first] << endl; + cout << "This program used "<< String::HowMany() + << " String objects. Bye.\n"; + } + else + cout << "No input! Bye.\n"; +// keep window open +/* if (!cin) + cin.clear(); + while (cin.get() != '\n') + continue; */ + return 0; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 12/sayings2.cpp b/study_cpp/cpp_primer_source_code/Chapter 12/sayings2.cpp new file mode 100644 index 0000000..e7630db --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 12/sayings2.cpp @@ -0,0 +1,71 @@ +// sayings2.cpp -- using pointers to objects +// compile with string1.cpp +#include +#include // (or stdlib.h) for rand(), srand() +#include // (or time.h) for time() +#include "string1.h" +const int ArSize = 10; +const int MaxLen = 81; +int main() +{ + using namespace std; + String name; + cout <<"Hi, what's your name?\n>> "; + cin >> name; + + cout << name << ", please enter up to " << ArSize + << " short sayings :\n"; + String sayings[ArSize]; + char temp[MaxLen]; // temporary string storage + int i; + for (i = 0; i < ArSize; i++) + { + cout << i+1 << ": "; + cin.get(temp, MaxLen); + while (cin && cin.get() != '\n') + continue; + if (!cin || temp[0] == '\0') // empty line? + break; // i not incremented + else + sayings[i] = temp; // overloaded assignment + } + int total = i; // total # of lines read + + if (total > 0) + { + cout << "Here are your sayings:\n"; + for (i = 0; i < total; i++) + cout << sayings[i] << "\n"; + + // use pointers to keep track of shortest, first strings + String * shortest = &sayings[0]; // initialize to first object + String * first = &sayings[0]; + for (i = 1; i < total; i++) + { + if (sayings[i].length() < shortest->length()) + shortest = &sayings[i]; + if (sayings[i] < *first) // compare values + first = &sayings[i]; // assign address + } + cout << "Shortest saying:\n" << * shortest << endl; + cout << "First alphabetically:\n" << * first << endl; + + srand(time(0)); + int choice = rand() % total; // pick index at random + // use new to create, initialize new String object + String * favorite = new String(sayings[choice]); + cout << "My favorite saying:\n" << *favorite << endl; + delete favorite; + } + else + cout << "Not much to say, eh?\n"; + cout << "Bye.\n"; +// keep window open +/* if (!cin) + cin.clear(); + while (cin.get() != '\n') + continue; + cin.get(); +*/ + return 0; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 12/string1.cpp b/study_cpp/cpp_primer_source_code/Chapter 12/string1.cpp new file mode 100644 index 0000000..d69e3d8 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 12/string1.cpp @@ -0,0 +1,118 @@ +// string1.cpp -- String class methods +#include // string.h for some +#include "string1.h" // includes +using std::cin; +using std::cout; + +// initializing static class member + +int String::num_strings = 0; + +// static method +int String::HowMany() +{ + return num_strings; +} + +// class methods +String::String(const char * s) // construct String from C string +{ + len = std::strlen(s); // set size + str = new char[len + 1]; // allot storage + std::strcpy(str, s); // initialize pointer + num_strings++; // set object count +} + +String::String() // default constructor +{ + len = 4; + str = new char[1]; + str[0] = '\0'; // default string + num_strings++; +} + +String::String(const String & st) +{ + num_strings++; // handle static member update + len = st.len; // same length + str = new char [len + 1]; // allot space + std::strcpy(str, st.str); // copy string to new location +} + +String::~String() // necessary destructor +{ + --num_strings; // required + delete [] str; // required +} + +// overloaded operator methods + + // assign a String to a String +String & String::operator=(const String & st) +{ + if (this == &st) + return *this; + delete [] str; + len = st.len; + str = new char[len + 1]; + std::strcpy(str, st.str); + return *this; +} + + // assign a C string to a String +String & String::operator=(const char * s) +{ + delete [] str; + len = std::strlen(s); + str = new char[len + 1]; + std::strcpy(str, s); + return *this; +} + + // read-write char access for non-const String +char & String::operator[](int i) +{ + return str[i]; +} + + // read-only char access for const String +const char & String::operator[](int i) const +{ + return str[i]; +} + +// overloaded operator friends + +bool operator<(const String &st1, const String &st2) +{ + return (std::strcmp(st1.str, st2.str) < 0); +} + +bool operator>(const String &st1, const String &st2) +{ + return st2 < st1; +} + +bool operator==(const String &st1, const String &st2) +{ + return (std::strcmp(st1.str, st2.str) == 0); +} + + // simple String output +ostream & operator<<(ostream & os, const String & st) +{ + os << st.str; + return os; +} + + // quick and dirty String input +istream & operator>>(istream & is, String & st) +{ + char temp[String::CINLIM]; + is.get(temp, String::CINLIM); + if (is) + st = temp; + while (is && is.get() != '\n') + continue; + return is; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 12/string1.h b/study_cpp/cpp_primer_source_code/Chapter 12/string1.h new file mode 100644 index 0000000..b3ab5f5 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 12/string1.h @@ -0,0 +1,37 @@ +// string1.h -- fixed and augmented string class definition + +#ifndef STRING1_H_ +#define STRING1_H_ +#include +using std::ostream; +using std::istream; + +class String +{ +private: + char * str; // pointer to string + int len; // length of string + static int num_strings; // number of objects + static const int CINLIM = 80; // cin input limit +public: +// constructors and other methods + String(const char * s); // constructor + String(); // default constructor + String(const String &); // copy constructor + ~String(); // destructor + int length () const { return len; } +// overloaded operator methods + String & operator=(const String &); + String & operator=(const char *); + char & operator[](int i); + const char & operator[](int i) const; +// overloaded operator friends + friend bool operator<(const String &st, const String &st2); + friend bool operator>(const String &st1, const String &st2); + friend bool operator==(const String &st, const String &st2); + friend ostream & operator<<(ostream & os, const String & st); + friend istream & operator>>(istream & is, String & st); +// static function + static int HowMany(); +}; +#endif diff --git a/study_cpp/cpp_primer_source_code/Chapter 12/strngbad.cpp b/study_cpp/cpp_primer_source_code/Chapter 12/strngbad.cpp new file mode 100644 index 0000000..1d4db9c --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 12/strngbad.cpp @@ -0,0 +1,44 @@ +// strngbad.cpp -- StringBad class methods +#include // string.h for some +#include "strngbad.h" +using std::cout; + +// initializing static class member +int StringBad::num_strings = 0; + +// class methods + +// construct StringBad from C string +StringBad::StringBad(const char * s) +{ + len = std::strlen(s); // set size + str = new char[len + 1]; // allot storage + std::strcpy(str, s); // initialize pointer + num_strings++; // set object count + cout << num_strings << ": \"" << str + << "\" object created\n"; // For Your Information +} + +StringBad::StringBad() // default constructor +{ + len = 4; + str = new char[4]; + std::strcpy(str, "C++"); // default string + num_strings++; + cout << num_strings << ": \"" << str + << "\" default object created\n"; // FYI +} + +StringBad::~StringBad() // necessary destructor +{ + cout << "\"" << str << "\" object deleted, "; // FYI + --num_strings; // required + cout << num_strings << " left\n"; // FYI + delete [] str; // required +} + +std::ostream & operator<<(std::ostream & os, const StringBad & st) +{ + os << st.str; + return os; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 12/strngbad.h b/study_cpp/cpp_primer_source_code/Chapter 12/strngbad.h new file mode 100644 index 0000000..b3124fb --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 12/strngbad.h @@ -0,0 +1,19 @@ +// strngbad.h -- flawed string class definition +#include +#ifndef STRNGBAD_H_ +#define STRNGBAD_H_ +class StringBad +{ +private: + char * str; // pointer to string + int len; // length of string + static int num_strings; // number of objects +public: + StringBad(const char * s); // constructor + StringBad(); // default constructor + ~StringBad(); // destructor +// friend function + friend std::ostream & operator<<(std::ostream & os, + const StringBad & st); +}; +#endif diff --git a/study_cpp/cpp_primer_source_code/Chapter 12/vegnews.cpp b/study_cpp/cpp_primer_source_code/Chapter 12/vegnews.cpp new file mode 100644 index 0000000..bb306d9 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 12/vegnews.cpp @@ -0,0 +1,49 @@ +// vegnews.cpp -- using new and delete with classes +// compile with strngbad.cpp +#include +using std::cout; +#include "strngbad.h" + +void callme1(StringBad &); // pass by reference +void callme2(StringBad); // pass by value + +int main() +{ + using std::endl; + { + cout << "Starting an inner block.\n"; + StringBad headline1("Celery Stalks at Midnight"); + StringBad headline2("Lettuce Prey"); + StringBad sports("Spinach Leaves Bowl for Dollars"); + cout << "headline1: " << headline1 << endl; + cout << "headline2: " << headline2 << endl; + cout << "sports: " << sports << endl; + callme1(headline1); + cout << "headline1: " << headline1 << endl; + callme2(headline2); + cout << "headline2: " << headline2 << endl; + cout << "Initialize one object to another:\n"; + StringBad sailor = sports; + cout << "sailor: " << sailor << endl; + cout << "Assign one object to another:\n"; + StringBad knot; + knot = headline1; + cout << "knot: " << knot << endl; + cout << "Exiting the block.\n"; + } + cout << "End of main()\n"; + // std::cin.get(); + return 0; +} + +void callme1(StringBad & rsb) +{ + cout << "String passed by reference:\n"; + cout << " \"" << rsb << "\"\n"; +} + +void callme2(StringBad sb) +{ + cout << "String passed by value:\n"; + cout << " \"" << sb << "\"\n"; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 13/acctabc.cpp b/study_cpp/cpp_primer_source_code/Chapter 13/acctabc.cpp new file mode 100644 index 0000000..fe80462 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 13/acctabc.cpp @@ -0,0 +1,122 @@ +// acctabc.cpp -- bank account class methods +#include +#include "acctabc.h" +using std::cout; +using std::ios_base; +using std::endl; +using std::string; + +// Abstract Base Class +AcctABC::AcctABC(const string & s, long an, double bal) +{ + fullName = s; + acctNum = an; + balance = bal; +} + +void AcctABC::Deposit(double amt) +{ + if (amt < 0) + cout << "Negative deposit not allowed; " + << "deposit is cancelled.\n"; + else + balance += amt; +} + +void AcctABC::Withdraw(double amt) +{ + balance -= amt; +} + +// protected methods for formatting +AcctABC::Formatting AcctABC::SetFormat() const +{ + // set up ###.## format + Formatting f; + f.flag = + cout.setf(ios_base::fixed, ios_base::floatfield); + f.pr = cout.precision(2); + return f; +} + +void AcctABC::Restore(Formatting & f) const +{ + cout.setf(f.flag, ios_base::floatfield); + cout.precision(f.pr); +} + +// Brass methods +void Brass::Withdraw(double amt) +{ + if (amt < 0) + cout << "Withdrawal amount must be positive; " + << "withdrawal canceled.\n"; + else if (amt <= Balance()) + AcctABC::Withdraw(amt); + else + cout << "Withdrawal amount of $" << amt + << " exceeds your balance.\n" + << "Withdrawal canceled.\n"; +} + +void Brass::ViewAcct() const +{ + + Formatting f = SetFormat(); + cout << "Brass Client: " << FullName() << endl; + cout << "Account Number: " << AcctNum() << endl; + cout << "Balance: $" << Balance() << endl; + Restore(f); +} + +// BrassPlus Methods +BrassPlus::BrassPlus(const string & s, long an, double bal, + double ml, double r) : AcctABC(s, an, bal) +{ + maxLoan = ml; + owesBank = 0.0; + rate = r; +} + +BrassPlus::BrassPlus(const Brass & ba, double ml, double r) + : AcctABC(ba) // uses implicit copy constructor +{ + maxLoan = ml; + owesBank = 0.0; + rate = r; +} + +void BrassPlus::ViewAcct() const +{ + Formatting f = SetFormat(); + + cout << "BrassPlus Client: " << FullName() << endl; + cout << "Account Number: " << AcctNum() << endl; + cout << "Balance: $" << Balance() << endl; + cout << "Maximum loan: $" << maxLoan << endl; + cout << "Owed to bank: $" << owesBank << endl; + cout.precision(3); + cout << "Loan Rate: " << 100 * rate << "%\n"; + Restore(f); +} + +void BrassPlus::Withdraw(double amt) +{ + Formatting f = SetFormat(); + + double bal = Balance(); + if (amt <= bal) + AcctABC::Withdraw(amt); + else if ( amt <= bal + maxLoan - owesBank) + { + double advance = amt - bal; + owesBank += advance * (1.0 + rate); + cout << "Bank advance: $" << advance << endl; + cout << "Finance charge: $" << advance * rate << endl; + Deposit(advance); + AcctABC::Withdraw(amt); + } + else + cout << "Credit limit exceeded. Transaction cancelled.\n"; + Restore(f); +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 13/acctabc.h b/study_cpp/cpp_primer_source_code/Chapter 13/acctabc.h new file mode 100644 index 0000000..d462266 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 13/acctabc.h @@ -0,0 +1,64 @@ +// acctabc.h -- bank account classes +#ifndef ACCTABC_H_ +#define ACCTABC_H_ +#include +#include + +// Abstract Base Class +class AcctABC +{ +private: + std::string fullName; + long acctNum; + double balance; +protected: + struct Formatting + { + std::ios_base::fmtflags flag; + std::streamsize pr; + }; + const std::string & FullName() const {return fullName;} + long AcctNum() const {return acctNum;} + Formatting SetFormat() const; + void Restore(Formatting & f) const; +public: + AcctABC(const std::string & s = "Nullbody", long an = -1, + double bal = 0.0); + void Deposit(double amt) ; + virtual void Withdraw(double amt) = 0; // pure virtual function + double Balance() const {return balance;}; + virtual void ViewAcct() const = 0; // pure virtual function + virtual ~AcctABC() {} +}; + +// Brass Account Class +class Brass :public AcctABC +{ +public: + Brass(const std::string & s = "Nullbody", long an = -1, + double bal = 0.0) : AcctABC(s, an, bal) { } + virtual void Withdraw(double amt); + virtual void ViewAcct() const; + virtual ~Brass() {} +}; + +//Brass Plus Account Class +class BrassPlus : public AcctABC +{ +private: + double maxLoan; + double rate; + double owesBank; +public: + BrassPlus(const std::string & s = "Nullbody", long an = -1, + double bal = 0.0, double ml = 500, + double r = 0.10); + BrassPlus(const Brass & ba, double ml = 500, double r = 0.1); + virtual void ViewAcct()const; + virtual void Withdraw(double amt); + void ResetMax(double m) { maxLoan = m; } + void ResetRate(double r) { rate = r; }; + void ResetOwes() { owesBank = 0; } +}; + +#endif diff --git a/study_cpp/cpp_primer_source_code/Chapter 13/brass.cpp b/study_cpp/cpp_primer_source_code/Chapter 13/brass.cpp new file mode 100644 index 0000000..4b6f2ed --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 13/brass.cpp @@ -0,0 +1,133 @@ +// brass.cpp -- bank account class methods +#include +#include "brass.h" +using std::cout; +using std::endl; +using std::string; + +// formatting stuff +typedef std::ios_base::fmtflags format; +typedef std::streamsize precis; +format setFormat(); +void restore(format f, precis p); + +// Brass methods + +Brass::Brass(const string & s, long an, double bal) +{ + fullName = s; + acctNum = an; + balance = bal; +} + +void Brass::Deposit(double amt) +{ + if (amt < 0) + cout << "Negative deposit not allowed; " + << "deposit is cancelled.\n"; + else + balance += amt; +} + +void Brass::Withdraw(double amt) +{ + // set up ###.## format + format initialState = setFormat(); + precis prec = cout.precision(2); + + if (amt < 0) + cout << "Withdrawal amount must be positive; " + + << "withdrawal canceled.\n"; + else if (amt <= balance) + balance -= amt; + else + cout << "Withdrawal amount of $" << amt + << " exceeds your balance.\n" + << "Withdrawal canceled.\n"; + restore(initialState, prec); +} +double Brass::Balance() const +{ + return balance; +} + +void Brass::ViewAcct() const +{ + // set up ###.## format + format initialState = setFormat(); + precis prec = cout.precision(2); + cout << "Client: " << fullName << endl; + cout << "Account Number: " << acctNum << endl; + cout << "Balance: $" << balance << endl; + restore(initialState, prec); // Restore original format +} + +// BrassPlus Methods +BrassPlus::BrassPlus(const string & s, long an, double bal, + double ml, double r) : Brass(s, an, bal) +{ + maxLoan = ml; + owesBank = 0.0; + rate = r; +} + +BrassPlus::BrassPlus(const Brass & ba, double ml, double r) + : Brass(ba) // uses implicit copy constructor +{ + maxLoan = ml; + owesBank = 0.0; + rate = r; +} + +// redefine how ViewAcct() works +void BrassPlus::ViewAcct() const +{ + // set up ###.## format + format initialState = setFormat(); + precis prec = cout.precision(2); + + Brass::ViewAcct(); // display base portion + cout << "Maximum loan: $" << maxLoan << endl; + cout << "Owed to bank: $" << owesBank << endl; + cout.precision(3); // ###.### format + cout << "Loan Rate: " << 100 * rate << "%\n"; + restore(initialState, prec); +} + +// redefine how Withdraw() works +void BrassPlus::Withdraw(double amt) +{ + // set up ###.## format + format initialState = setFormat(); + precis prec = cout.precision(2); + + double bal = Balance(); + if (amt <= bal) + Brass::Withdraw(amt); + else if ( amt <= bal + maxLoan - owesBank) + { + double advance = amt - bal; + owesBank += advance * (1.0 + rate); + cout << "Bank advance: $" << advance << endl; + cout << "Finance charge: $" << advance * rate << endl; + Deposit(advance); + Brass::Withdraw(amt); + } + else + cout << "Credit limit exceeded. Transaction cancelled.\n"; + restore(initialState, prec); +} + +format setFormat() +{ + // set up ###.## format + return cout.setf(std::ios_base::fixed, + std::ios_base::floatfield); +} + +void restore(format f, precis p) +{ + cout.setf(f, std::ios_base::floatfield); + cout.precision(p); +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 13/brass.h b/study_cpp/cpp_primer_source_code/Chapter 13/brass.h new file mode 100644 index 0000000..4d23e18 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 13/brass.h @@ -0,0 +1,42 @@ +// brass.h -- bank account classes +#ifndef BRASS_H_ +#define BRASS_H_ +#include +// Brass Account Class +class Brass +{ +private: + std::string fullName; + long acctNum; + double balance; +public: + Brass(const std::string & s = "Nullbody", long an = -1, + double bal = 0.0); + void Deposit(double amt); + virtual void Withdraw(double amt); + double Balance() const; + virtual void ViewAcct() const; + virtual ~Brass() {} +}; + +//Brass Plus Account Class +class BrassPlus : public Brass +{ +private: + double maxLoan; + double rate; + double owesBank; +public: + BrassPlus(const std::string & s = "Nullbody", long an = -1, + double bal = 0.0, double ml = 500, + double r = 0.11125); + BrassPlus(const Brass & ba, double ml = 500, + double r = 0.11125); + virtual void ViewAcct()const; + virtual void Withdraw(double amt); + void ResetMax(double m) { maxLoan = m; } + void ResetRate(double r) { rate = r; }; + void ResetOwes() { owesBank = 0; } +}; + +#endif diff --git a/study_cpp/cpp_primer_source_code/Chapter 13/dma.cpp b/study_cpp/cpp_primer_source_code/Chapter 13/dma.cpp new file mode 100644 index 0000000..474cffb --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 13/dma.cpp @@ -0,0 +1,109 @@ +// dma.cpp --dma class methods + +#include "dma.h" +#include + +// baseDMA methods +baseDMA::baseDMA(const char * l, int r) +{ + label = new char[std::strlen(l) + 1]; + std::strcpy(label, l); + rating = r; +} + +baseDMA::baseDMA(const baseDMA & rs) +{ + label = new char[std::strlen(rs.label) + 1]; + std::strcpy(label, rs.label); + rating = rs.rating; +} + +baseDMA::~baseDMA() +{ + delete [] label; +} + +baseDMA & baseDMA::operator=(const baseDMA & rs) +{ + if (this == &rs) + return *this; + delete [] label; + label = new char[std::strlen(rs.label) + 1]; + std::strcpy(label, rs.label); + rating = rs.rating; + return *this; +} + +std::ostream & operator<<(std::ostream & os, const baseDMA & rs) +{ + os << "Label: " << rs.label << std::endl; + os << "Rating: " << rs.rating << std::endl; + return os; +} + +// lacksDMA methods +lacksDMA::lacksDMA(const char * c, const char * l, int r) + : baseDMA(l, r) +{ + std::strncpy(color, c, 39); + color[39] = '\0'; +} + +lacksDMA::lacksDMA(const char * c, const baseDMA & rs) + : baseDMA(rs) +{ + std::strncpy(color, c, COL_LEN - 1); + color[COL_LEN - 1] = '\0'; +} + +std::ostream & operator<<(std::ostream & os, const lacksDMA & ls) +{ + os << (const baseDMA &) ls; + os << "Color: " << ls.color << std::endl; + return os; +} + +// hasDMA methods +hasDMA::hasDMA(const char * s, const char * l, int r) + : baseDMA(l, r) +{ + style = new char[std::strlen(s) + 1]; + std::strcpy(style, s); +} + +hasDMA::hasDMA(const char * s, const baseDMA & rs) + : baseDMA(rs) +{ + style = new char[std::strlen(s) + 1]; + std::strcpy(style, s); +} + +hasDMA::hasDMA(const hasDMA & hs) + : baseDMA(hs) // invoke base class copy constructor +{ + style = new char[std::strlen(hs.style) + 1]; + std::strcpy(style, hs.style); +} + +hasDMA::~hasDMA() +{ + delete [] style; +} + +hasDMA & hasDMA::operator=(const hasDMA & hs) +{ + if (this == &hs) + return *this; + baseDMA::operator=(hs); // copy base portion + delete [] style; // prepare for new style + style = new char[std::strlen(hs.style) + 1]; + std::strcpy(style, hs.style); + return *this; +} + +std::ostream & operator<<(std::ostream & os, const hasDMA & hs) +{ + os << (const baseDMA &) hs; + os << "Style: " << hs.style << std::endl; + return os; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 13/dma.h b/study_cpp/cpp_primer_source_code/Chapter 13/dma.h new file mode 100644 index 0000000..a4b1b84 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 13/dma.h @@ -0,0 +1,55 @@ +// dma.h -- inheritance and dynamic memory allocation +#ifndef DMA_H_ +#define DMA_H_ +#include + +// Base Class Using DMA +class baseDMA +{ +private: + char * label; + int rating; + +public: + baseDMA(const char * l = "null", int r = 0); + baseDMA(const baseDMA & rs); + virtual ~baseDMA(); + baseDMA & operator=(const baseDMA & rs); + friend std::ostream & operator<<(std::ostream & os, + const baseDMA & rs); +}; + +// derived class without DMA +// no destructor needed +// uses implicit copy constructor +// uses implicit assignment operator +class lacksDMA :public baseDMA +{ +private: + enum { COL_LEN = 40}; + char color[COL_LEN]; +public: + lacksDMA(const char * c = "blank", const char * l = "null", + int r = 0); + lacksDMA(const char * c, const baseDMA & rs); + friend std::ostream & operator<<(std::ostream & os, + const lacksDMA & rs); +}; + +// derived class with DMA +class hasDMA :public baseDMA +{ +private: + char * style; +public: + hasDMA(const char * s = "none", const char * l = "null", + int r = 0); + hasDMA(const char * s, const baseDMA & rs); + hasDMA(const hasDMA & hs); + ~hasDMA(); + hasDMA & operator=(const hasDMA & rs); + friend std::ostream & operator<<(std::ostream & os, + const hasDMA & rs); +}; + +#endif diff --git a/study_cpp/cpp_primer_source_code/Chapter 13/tabtenn0.cpp b/study_cpp/cpp_primer_source_code/Chapter 13/tabtenn0.cpp new file mode 100644 index 0000000..b38b276 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 13/tabtenn0.cpp @@ -0,0 +1,12 @@ +//tabtenn0.cpp -- simple base-class methods +#include "tabtenn0.h" +#include + +TableTennisPlayer::TableTennisPlayer (const string & fn, + const string & ln, bool ht) : firstname(fn), + lastname(ln), hasTable(ht) {} + +void TableTennisPlayer::Name() const +{ + std::cout << lastname << ", " << firstname; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 13/tabtenn0.h b/study_cpp/cpp_primer_source_code/Chapter 13/tabtenn0.h new file mode 100644 index 0000000..03627f0 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 13/tabtenn0.h @@ -0,0 +1,20 @@ +// tabtenn0.h -- a table-tennis base class +#ifndef TABTENN0_H_ +#define TABTENN0_H_ +#include +using std::string; +// simple base class +class TableTennisPlayer +{ +private: + string firstname; + string lastname; + bool hasTable; +public: + TableTennisPlayer (const string & fn = "none", + const string & ln = "none", bool ht = false); + void Name() const; + bool HasTable() const { return hasTable; }; + void ResetTable(bool v) { hasTable = v; }; +}; +#endif diff --git a/study_cpp/cpp_primer_source_code/Chapter 13/tabtenn1.cpp b/study_cpp/cpp_primer_source_code/Chapter 13/tabtenn1.cpp new file mode 100644 index 0000000..16facab --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 13/tabtenn1.cpp @@ -0,0 +1,24 @@ +//tabtenn1.cpp -- simple base-class methods +#include "tabtenn1.h" +#include + +TableTennisPlayer::TableTennisPlayer (const string & fn, + const string & ln, bool ht) : firstname(fn), + lastname(ln), hasTable(ht) {} + +void TableTennisPlayer::Name() const +{ + std::cout << lastname << ", " << firstname; +} + +// RatedPlayer methods +RatedPlayer::RatedPlayer(unsigned int r, const string & fn, + const string & ln, bool ht) : TableTennisPlayer(fn, ln, ht) +{ + rating = r; +} + +RatedPlayer::RatedPlayer(unsigned int r, const TableTennisPlayer & tp) + : TableTennisPlayer(tp), rating(r) +{ +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 13/tabtenn1.h b/study_cpp/cpp_primer_source_code/Chapter 13/tabtenn1.h new file mode 100644 index 0000000..e7ad932 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 13/tabtenn1.h @@ -0,0 +1,34 @@ +// tabtenn1.h -- a table-tennis base class +#ifndef TABTENN1_H_ +#define TABTENN1_H_ +#include +using std::string; +// simple base class +class TableTennisPlayer +{ +private: + string firstname; + string lastname; + bool hasTable; +public: + TableTennisPlayer (const string & fn = "none", + const string & ln = "none", bool ht = false); + void Name() const; + bool HasTable() const { return hasTable; }; + void ResetTable(bool v) { hasTable = v; }; +}; + +// simple derived class +class RatedPlayer : public TableTennisPlayer +{ +private: + unsigned int rating; +public: + RatedPlayer (unsigned int r = 0, const string & fn = "none", + const string & ln = "none", bool ht = false); + RatedPlayer(unsigned int r, const TableTennisPlayer & tp); + unsigned int Rating() const { return rating; } + void ResetRating (unsigned int r) {rating = r;} +}; + +#endif diff --git a/study_cpp/cpp_primer_source_code/Chapter 13/usebrass1.cpp b/study_cpp/cpp_primer_source_code/Chapter 13/usebrass1.cpp new file mode 100644 index 0000000..d5df72f --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 13/usebrass1.cpp @@ -0,0 +1,28 @@ +// usebrass1.cpp -- testing bank account classes +// compile with brass.cpp +#include +#include "brass.h" + +int main() +{ + using std::cout; + using std::endl; + + Brass Piggy("Porcelot Pigg", 381299, 4000.00); + BrassPlus Hoggy("Horatio Hogg", 382288, 3000.00); + Piggy.ViewAcct(); + cout << endl; + Hoggy.ViewAcct(); + cout << endl; + cout << "Depositing $1000 into the Hogg Account:\n"; + Hoggy.Deposit(1000.00); + cout << "New balance: $" << Hoggy.Balance() << endl; + cout << "Withdrawing $4200 from the Pigg Account:\n"; + Piggy.Withdraw(4200.00); + cout << "Pigg account balance: $" << Piggy.Balance() << endl; + cout << "Withdrawing $4200 from the Hogg Account:\n"; + Hoggy.Withdraw(4200.00); + Hoggy.ViewAcct(); + // std::cin.get(); + return 0; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 13/usebrass2.cpp b/study_cpp/cpp_primer_source_code/Chapter 13/usebrass2.cpp new file mode 100644 index 0000000..9ca6dc2 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 13/usebrass2.cpp @@ -0,0 +1,67 @@ +// usebrass2.cpp -- polymorphic example +// compile with brass.cpp +#include +#include +#include "brass.h" +const int CLIENTS = 4; + +int main() +{ + using std::cin; + using std::cout; + using std::endl; + + Brass * p_clients[CLIENTS]; + std::string temp; + long tempnum; + double tempbal; + char kind; + + for (int i = 0; i < CLIENTS; i++) + { + cout << "Enter client's name: "; + getline(cin,temp); + cout << "Enter client's account number: "; + cin >> tempnum; + cout << "Enter opening balance: $"; + cin >> tempbal; + cout << "Enter 1 for Brass Account or " + << "2 for BrassPlus Account: "; + while (cin >> kind && (kind != '1' && kind != '2')) + cout <<"Enter either 1 or 2: "; + if (kind == '1') + p_clients[i] = new Brass(temp, tempnum, tempbal); + else + { + double tmax, trate; + cout << "Enter the overdraft limit: $"; + cin >> tmax; + cout << "Enter the interest rate " + << "as a decimal fraction: "; + cin >> trate; + p_clients[i] = new BrassPlus(temp, tempnum, tempbal, + tmax, trate); + } + while (cin.get() != '\n') + continue; + } + cout << endl; + for (int i = 0; i < CLIENTS; i++) + { + p_clients[i]->ViewAcct(); + cout << endl; + } + + for (int i = 0; i < CLIENTS; i++) + { + delete p_clients[i]; // free memory + } + cout << "Done.\n"; + /* code to keep window open + if (!cin) + cin.clear(); + while (cin.get() != '\n') + continue; +*/ + return 0; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 13/usebrass3.cpp b/study_cpp/cpp_primer_source_code/Chapter 13/usebrass3.cpp new file mode 100644 index 0000000..03c8523 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 13/usebrass3.cpp @@ -0,0 +1,62 @@ +// usebrass3.cpp -- polymorphic example +// compile with acctacb.cpp +#include +#include +#include "acctabc.h" +const int CLIENTS = 4; + +int main() +{ + using std::cin; + using std::cout; + using std::endl; + + AcctABC * p_clients[CLIENTS]; + std::string temp; + long tempnum; + double tempbal; + char kind; + + for (int i = 0; i < CLIENTS; i++) + { + cout << "Enter client's name: "; + getline(cin,temp); + cout << "Enter client's account number: "; + cin >> tempnum; + cout << "Enter opening balance: $"; + cin >> tempbal; + cout << "Enter 1 for Brass Account or " + << "2 for BrassPlus Account: "; + while (cin >> kind && (kind != '1' && kind != '2')) + cout <<"Enter either 1 or 2: "; + if (kind == '1') + p_clients[i] = new Brass(temp, tempnum, tempbal); + else + { + double tmax, trate; + cout << "Enter the overdraft limit: $"; + cin >> tmax; + cout << "Enter the interest rate " + << "as a decimal fraction: "; + cin >> trate; + p_clients[i] = new BrassPlus(temp, tempnum, tempbal, + tmax, trate); + } + while (cin.get() != '\n') + continue; + } + cout << endl; + for (int i = 0; i < CLIENTS; i++) + { + p_clients[i]->ViewAcct(); + cout << endl; + } + + for (int i = 0; i < CLIENTS; i++) + { + delete p_clients[i]; // free memory + } + cout << "Done.\n"; + // cin.get(); + return 0; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 13/usedma.cpp b/study_cpp/cpp_primer_source_code/Chapter 13/usedma.cpp new file mode 100644 index 0000000..0d29f48 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 13/usedma.cpp @@ -0,0 +1,28 @@ +// usedma.cpp -- inheritance, friends, and DMA +// compile with dma.cpp +#include +#include "dma.h" +int main() +{ + using std::cout; + using std::endl; + + baseDMA shirt("Portabelly", 8); + lacksDMA balloon("red", "Blimpo", 4); + hasDMA map("Mercator", "Buffalo Keys", 5); + cout << "Displaying baseDMA object:\n"; + cout << shirt << endl; + cout << "Displaying lacksDMA object:\n"; + cout << balloon << endl; + cout << "Displaying hasDMA object:\n"; + cout << map << endl; + lacksDMA balloon2(balloon); + cout << "Result of lacksDMA copy:\n"; + cout << balloon2 << endl; + hasDMA map2; + map2 = map; + cout << "Result of hasDMA assignment:\n"; + cout << map2 << endl; + // std::cin.get(); + return 0; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 13/usett0.cpp b/study_cpp/cpp_primer_source_code/Chapter 13/usett0.cpp new file mode 100644 index 0000000..ea53692 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 13/usett0.cpp @@ -0,0 +1,22 @@ +// usett0.cpp -- using a base class +#include +#include "tabtenn0.h" + +int main ( void ) +{ + using std::cout; + TableTennisPlayer player1("Chuck", "Blizzard", true); + TableTennisPlayer player2("Tara", "Boomdea", false); + player1.Name(); + if (player1.HasTable()) + cout << ": has a table.\n"; + else + cout << ": hasn't a table.\n"; + player2.Name(); + if (player2.HasTable()) + cout << ": has a table"; + else + cout << ": hasn't a table.\n"; + // std::cin.get(); + return 0; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 13/usett1.cpp b/study_cpp/cpp_primer_source_code/Chapter 13/usett1.cpp new file mode 100644 index 0000000..9ff8c98 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 13/usett1.cpp @@ -0,0 +1,31 @@ +// usett1.cpp -- using base class and derived class +#include +#include "tabtenn1.h" + +int main ( void ) +{ + using std::cout; + using std::endl; + TableTennisPlayer player1("Tara", "Boomdea", false); + RatedPlayer rplayer1(1140, "Mallory", "Duck", true); + rplayer1.Name(); // derived object uses base method + if (rplayer1.HasTable()) + cout << ": has a table.\n"; + else + cout << ": hasn't a table.\n"; + player1.Name(); // base object uses base method + if (player1.HasTable()) + cout << ": has a table"; + else + cout << ": hasn't a table.\n"; + cout << "Name: "; + rplayer1.Name(); + cout << "; Rating: " << rplayer1.Rating() << endl; +// initialize RatedPlayer using TableTennisPlayer object + RatedPlayer rplayer2(1212, player1); + cout << "Name: "; + rplayer2.Name(); + cout << "; Rating: " << rplayer2.Rating() << endl; + // std::cin.get(); + return 0; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 14/arraytp.h b/study_cpp/cpp_primer_source_code/Chapter 14/arraytp.h new file mode 100644 index 0000000..fafd699 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 14/arraytp.h @@ -0,0 +1,51 @@ +//arraytp.h -- Array Template +#ifndef ARRAYTP_H_ +#define ARRAYTP_H_ + +#include +#include + +template +class ArrayTP +{ +private: + T ar[n]; +public: + ArrayTP() {}; + explicit ArrayTP(const T & v); + virtual T & operator[](int i); + virtual T operator[](int i) const; +}; + +template +ArrayTP::ArrayTP(const T & v) +{ + for (int i = 0; i < n; i++) + ar[i] = v; +} + +template +T & ArrayTP::operator[](int i) +{ + if (i < 0 || i >= n) + { + std::cerr << "Error in array limits: " << i + << " is out of range\n"; + std::exit(EXIT_FAILURE); + } + return ar[i]; +} + +template +T ArrayTP::operator[](int i) const +{ + if (i < 0 || i >= n) + { + std::cerr << "Error in array limits: " << i + << " is out of range\n"; + std::exit(EXIT_FAILURE); + } + return ar[i]; +} + +#endif diff --git a/study_cpp/cpp_primer_source_code/Chapter 14/frnd2tmp.cpp b/study_cpp/cpp_primer_source_code/Chapter 14/frnd2tmp.cpp new file mode 100644 index 0000000..59e0129 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 14/frnd2tmp.cpp @@ -0,0 +1,60 @@ +// frnd2tmp.cpp -- template class with non-template friends +#include +using std::cout; +using std::endl; + +template +class HasFriend +{ +private: + T item; + static int ct; +public: + HasFriend(const T & i) : item(i) {ct++;} + ~HasFriend() {ct--; } + friend void counts(); + friend void reports(HasFriend &); // template parameter +}; + +// each specialization has its own static data member +template +int HasFriend::ct = 0; + +// non-template friend to all HasFriend classes +void counts() +{ + cout << "int count: " << HasFriend::ct << "; "; + cout << "double count: " << HasFriend::ct << endl; +} + +// non-template friend to the HasFriend class +void reports(HasFriend & hf) +{ + cout <<"HasFriend: " << hf.item << endl; +} + +// non-template friend to the HasFriend class +void reports(HasFriend & hf) +{ + cout <<"HasFriend: " << hf.item << endl; +} + +int main() +{ + cout << "No objects declared: "; + counts(); + HasFriend hfi1(10); + cout << "After hfi1 declared: "; + counts(); + HasFriend hfi2(20); + cout << "After hfi2 declared: "; + counts(); + HasFriend hfdb(10.5); + cout << "After hfdb declared: "; + counts(); + reports(hfi1); + reports(hfi2); + reports(hfdb); + // std::cin.get(); + return 0; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 14/manyfrnd.cpp b/study_cpp/cpp_primer_source_code/Chapter 14/manyfrnd.cpp new file mode 100644 index 0000000..def53b8 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 14/manyfrnd.cpp @@ -0,0 +1,32 @@ +// manyfrnd.cpp -- unbound template friend to a template class +#include +using std::cout; +using std::endl; + +template +class ManyFriend +{ +private: + T item; +public: + ManyFriend(const T & i) : item(i) {} + template friend void show2(C &, D &); +}; + +template void show2(C & c, D & d) +{ + cout << c.item << ", " << d.item << endl; +} + +int main() +{ + ManyFriend hfi1(10); + ManyFriend hfi2(20); + ManyFriend hfdb(10.5); + cout << "hfi1, hfi2: "; + show2(hfi1, hfi2); + cout << "hfdb, hfi2: "; + show2(hfdb, hfi2); + // std::cin.get(); + return 0; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 14/pairs.cpp b/study_cpp/cpp_primer_source_code/Chapter 14/pairs.cpp new file mode 100644 index 0000000..50eb2d8 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 14/pairs.cpp @@ -0,0 +1,55 @@ +// pairs.cpp -- defining and using a Pair template +#include +#include +template +class Pair +{ +private: + T1 a; + T2 b; +public: + T1 & first(); + T2 & second(); + T1 first() const { return a; } + T2 second() const { return b; } + Pair(const T1 & aval, const T2 & bval) : a(aval), b(bval) { } + Pair() {} +}; + +template +T1 & Pair::first() +{ + return a; +} +template +T2 & Pair::second() +{ + return b; +} + +int main() +{ + using std::cout; + using std::endl; + using std::string; + Pair ratings[4] = + { + Pair("The Purpled Duck", 5), + Pair("Jaquie's Frisco Al Fresco", 4), + Pair("Cafe Souffle", 5), + Pair("Bertie's Eats", 3) + }; + + int joints = sizeof(ratings) / sizeof (Pair); + cout << "Rating:\t Eatery\n"; + for (int i = 0; i < joints; i++) + cout << ratings[i].second() << ":\t " + << ratings[i].first() << endl; + cout << "Oops! Revised rating:\n"; + ratings[3].first() = "Bertie's Fab Eats"; + ratings[3].second() = 6; + cout << ratings[3].second() << ":\t " + << ratings[3].first() << endl; + // std::cin.get(); + return 0; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 14/stacktem.cpp b/study_cpp/cpp_primer_source_code/Chapter 14/stacktem.cpp new file mode 100644 index 0000000..a9ceea6 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 14/stacktem.cpp @@ -0,0 +1,51 @@ +// stacktem.cpp -- testing the template stack class +#include +#include +#include +#include "stacktp.h" +using std::cin; +using std::cout; + +int main() +{ + Stack st; // create an empty stack + char ch; + std::string po; + cout << "Please enter A to add a purchase order,\n" + << "P to process a PO, or Q to quit.\n"; + while (cin >> ch && std::toupper(ch) != 'Q') + { + while (cin.get() != '\n') + continue; + if (!std::isalpha(ch)) + { + cout << '\a'; + continue; + } + switch(ch) + { + case 'A': + case 'a': cout << "Enter a PO number to add: "; + cin >> po; + if (st.isfull()) + cout << "stack already full\n"; + else + st.push(po); + break; + case 'P': + case 'p': if (st.isempty()) + cout << "stack already empty\n"; + else { + st.pop(po); + cout << "PO #" << po << " popped\n"; + break; + } + } + cout << "Please enter A to add a purchase order,\n" + << "P to process a PO, or Q to quit.\n"; + } + cout << "Bye\n"; + // cin.get(); + // cin.get(); + return 0; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 14/stacktp.h b/study_cpp/cpp_primer_source_code/Chapter 14/stacktp.h new file mode 100644 index 0000000..6ce5c2f --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 14/stacktp.h @@ -0,0 +1,61 @@ +// stacktp.h -- a stack template +#ifndef STACKTP_H_ +#define STACKTP_H_ +template +class Stack +{ +private: + enum {MAX = 10}; // constant specific to class + Type items[MAX]; // holds stack items + int top; // index for top stack item +public: + Stack(); + bool isempty(); + bool isfull(); + bool push(const Type & item); // add item to stack + bool pop(Type & item); // pop top into item +}; + +template +Stack::Stack() +{ + top = 0; +} + +template +bool Stack::isempty() +{ + return top == 0; +} + +template +bool Stack::isfull() +{ + return top == MAX; +} + +template +bool Stack::push(const Type & item) +{ + if (top < MAX) + { + items[top++] = item; + return true; + } + else + return false; +} + +template +bool Stack::pop(Type & item) +{ + if (top > 0) + { + item = items[--top]; + return true; + } + else + return false; +} + +#endif diff --git a/study_cpp/cpp_primer_source_code/Chapter 14/stckoptr1.cpp b/study_cpp/cpp_primer_source_code/Chapter 14/stckoptr1.cpp new file mode 100644 index 0000000..6b07193 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 14/stckoptr1.cpp @@ -0,0 +1,47 @@ +// stkoptr1.cpp -- testing stack of pointers +#include +#include // for rand(), srand() +#include // for time() +#include "stcktp1.h" +const int Num = 10; +int main() +{ + std::srand(std::time(0)); // randomize rand() + std::cout << "Please enter stack size: "; + int stacksize; + std::cin >> stacksize; +// create an empty stack with stacksize slots + Stack st(stacksize); + +// in basket + const char * in[Num] = { + " 1: Hank Gilgamesh", " 2: Kiki Ishtar", + " 3: Betty Rocker", " 4: Ian Flagranti", + " 5: Wolfgang Kibble", " 6: Portia Koop", + " 7: Joy Almondo", " 8: Xaverie Paprika", + " 9: Juan Moore", "10: Misha Mache" + }; + // out basket + const char * out[Num]; + + int processed = 0; + int nextin = 0; + while (processed < Num) + { + if (st.isempty()) + st.push(in[nextin++]); + else if (st.isfull()) + st.pop(out[processed++]); + else if (std::rand() % 2 && nextin < Num) // 50-50 chance + st.push(in[nextin++]); + else + st.pop(out[processed++]); + } + for (int i = 0; i < Num; i++) + std::cout << out[i] << std::endl; + + std::cout << "Bye\n"; + // std::cin.get(); + // std::cin.get(); + return 0; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 14/stcktp1.h b/study_cpp/cpp_primer_source_code/Chapter 14/stcktp1.h new file mode 100644 index 0000000..f3f5983 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 14/stcktp1.h @@ -0,0 +1,78 @@ +// stcktp1.h -- modified Stack template +#ifndef STCKTP1_H_ +#define STCKTP1_H_ + +template +class Stack +{ +private: + enum {SIZE = 10}; // default size + int stacksize; + Type * items; // holds stack items + int top; // index for top stack item +public: + explicit Stack(int ss = SIZE); + Stack(const Stack & st); + ~Stack() { delete [] items; } + bool isempty() { return top == 0; } + bool isfull() { return top == stacksize; } + bool push(const Type & item); // add item to stack + bool pop(Type & item); // pop top into item + Stack & operator=(const Stack & st); +}; + +template +Stack::Stack(int ss) : stacksize(ss), top(0) +{ + items = new Type [stacksize]; +} + +template +Stack::Stack(const Stack & st) +{ + stacksize = st.stacksize; + top = st.top; + items = new Type [stacksize]; + for (int i = 0; i < top; i++) + items[i] = st.items[i]; +} + +template +bool Stack::push(const Type & item) +{ + if (top < stacksize) + { + items[top++] = item; + return true; + } + else + return false; +} + +template +bool Stack::pop(Type & item) +{ + if (top > 0) + { + item = items[--top]; + return true; + } + else + return false; +} + +template +Stack & Stack::operator=(const Stack & st) +{ + if (this == &st) + return *this; + delete [] items; + stacksize = st.stacksize; + top = st.top; + items = new Type [stacksize]; + for (int i = 0; i < top; i++) + items[i] = st.items[i]; + return *this; +} + +#endif diff --git a/study_cpp/cpp_primer_source_code/Chapter 14/studentc.cpp b/study_cpp/cpp_primer_source_code/Chapter 14/studentc.cpp new file mode 100644 index 0000000..412934a --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 14/studentc.cpp @@ -0,0 +1,75 @@ +// studentc.cpp -- Student class using containment +#include "studentc.h" +using std::ostream; +using std::endl; +using std::istream; +using std::string; + +//public methods +double Student::Average() const +{ + if (scores.size() > 0) + return scores.sum()/scores.size(); + else + return 0; +} + +const string & Student::Name() const +{ + return name; +} + +double & Student::operator[](int i) +{ + return scores[i]; // use valarray::operator[]() +} + +double Student::operator[](int i) const +{ + return scores[i]; +} + +// private method +ostream & Student::arr_out(ostream & os) const +{ + int i; + int lim = scores.size(); + if (lim > 0) + { + for (i = 0; i < lim; i++) + { + os << scores[i] << " "; + if (i % 5 == 4) + os << endl; + } + if (i % 5 != 0) + os << endl; + } + else + os << " empty array "; + return os; +} + +// friends + +// use string version of operator>>() +istream & operator>>(istream & is, Student & stu) +{ + is >> stu.name; + return is; +} + +// use string friend getline(ostream &, const string &) +istream & getline(istream & is, Student & stu) +{ + getline(is, stu.name); + return is; +} + +// use string version of operator<<() +ostream & operator<<(ostream & os, const Student & stu) +{ + os << "Scores for " << stu.name << ":\n"; + stu.arr_out(os); // use private method for scores + return os; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 14/studentc.h b/study_cpp/cpp_primer_source_code/Chapter 14/studentc.h new file mode 100644 index 0000000..5a12544 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 14/studentc.h @@ -0,0 +1,43 @@ +// studentc.h -- defining a Student class using containment +#ifndef STUDENTC_H_ +#define STUDENTC_H_ + +#include +#include +#include +class Student +{ +private: + typedef std::valarray ArrayDb; + std::string name; // contained object + ArrayDb scores; // contained object + // private method for scores output + std::ostream & arr_out(std::ostream & os) const; +public: + Student() : name("Null Student"), scores() {} + explicit Student(const std::string & s) + : name(s), scores() {} + explicit Student(int n) : name("Nully"), scores(n) {} + Student(const std::string & s, int n) + : name(s), scores(n) {} + Student(const std::string & s, const ArrayDb & a) + : name(s), scores(a) {} + Student(const char * str, const double * pd, int n) + : name(str), scores(pd, n) {} + ~Student() {} + double Average() const; + const std::string & Name() const; + double & operator[](int i); + double operator[](int i) const; +// friends + // input + friend std::istream & operator>>(std::istream & is, + Student & stu); // 1 word + friend std::istream & getline(std::istream & is, + Student & stu); // 1 line + // output + friend std::ostream & operator<<(std::ostream & os, + const Student & stu); +}; + +#endif diff --git a/study_cpp/cpp_primer_source_code/Chapter 14/studenti.cpp b/study_cpp/cpp_primer_source_code/Chapter 14/studenti.cpp new file mode 100644 index 0000000..37bae08 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 14/studenti.cpp @@ -0,0 +1,74 @@ +// studenti.cpp -- Student class using private inheritance +#include "studenti.h" +using std::ostream; +using std::endl; +using std::istream; +using std::string; + +// public methods +double Student::Average() const +{ + if (ArrayDb::size() > 0) + return ArrayDb::sum()/ArrayDb::size(); + else + return 0; +} + +const string & Student::Name() const +{ + return (const string &) *this; +} + +double & Student::operator[](int i) +{ + return ArrayDb::operator[](i); // use ArrayDb::operator[]() +} + +double Student::operator[](int i) const +{ + return ArrayDb::operator[](i); +} + +// private method +ostream & Student::arr_out(ostream & os) const +{ + int i; + int lim = ArrayDb::size(); + if (lim > 0) + { + for (i = 0; i < lim; i++) + { + os << ArrayDb::operator[](i) << " "; + if (i % 5 == 4) + os << endl; + } + if (i % 5 != 0) + os << endl; + } + else + os << " empty array "; + return os; +} + +// friends +// use String version of operator>>() +istream & operator>>(istream & is, Student & stu) +{ + is >> (string &)stu; + return is; +} + +// use string friend getline(ostream &, const string &) +istream & getline(istream & is, Student & stu) +{ + getline(is, (string &)stu); + return is; +} + +// use string version of operator<<() +ostream & operator<<(ostream & os, const Student & stu) +{ + os << "Scores for " << (const string &) stu << ":\n"; + stu.arr_out(os); // use private method for scores + return os; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 14/studenti.h b/study_cpp/cpp_primer_source_code/Chapter 14/studenti.h new file mode 100644 index 0000000..947237c --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 14/studenti.h @@ -0,0 +1,41 @@ +// studenti.h -- defining a Student class using private inheritance +#ifndef STUDENTC_H_ +#define STUDENTC_H_ + +#include +#include +#include +class Student : private std::string, private std::valarray +{ +private: + typedef std::valarray ArrayDb; + // private method for scores output + std::ostream & arr_out(std::ostream & os) const; +public: + Student() : std::string("Null Student"), ArrayDb() {} + explicit Student(const std::string & s) + : std::string(s), ArrayDb() {} + explicit Student(int n) : std::string("Nully"), ArrayDb(n) {} + Student(const std::string & s, int n) + : std::string(s), ArrayDb(n) {} + Student(const std::string & s, const ArrayDb & a) + : std::string(s), ArrayDb(a) {} + Student(const char * str, const double * pd, int n) + : std::string(str), ArrayDb(pd, n) {} + ~Student() {} + double Average() const; + double & operator[](int i); + double operator[](int i) const; + const std::string & Name() const; +// friends + // input + friend std::istream & operator>>(std::istream & is, + Student & stu); // 1 word + friend std::istream & getline(std::istream & is, + Student & stu); // 1 line + // output + friend std::ostream & operator<<(std::ostream & os, + const Student & stu); +}; + +#endif diff --git a/study_cpp/cpp_primer_source_code/Chapter 14/tempmemb.cpp b/study_cpp/cpp_primer_source_code/Chapter 14/tempmemb.cpp new file mode 100644 index 0000000..d71a72c --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 14/tempmemb.cpp @@ -0,0 +1,42 @@ +// tempmemb.cpp -- template members +#include +using std::cout; +using std::endl; + +template +class beta +{ +private: + template // nested template class member + class hold + { + private: + V val; + public: + hold(V v = 0) : val(v) {} + void show() const { cout << val << endl; } + V Value() const { return val; } + }; + hold q; // template object + hold n; // template object +public: + beta( T t, int i) : q(t), n(i) {} + template // template method + U blab(U u, T t) { return (n.Value() + q.Value()) * u / t; } + void Show() const { q.show(); n.show();} +}; + +int main() +{ + beta guy(3.5, 3); + cout << "T was set to double\n"; + guy.Show(); + cout << "V was set to T, which is double, then V was set to int\n"; + cout << guy.blab(10, 2.3) << endl; + cout << "U was set to int\n"; + cout << guy.blab(10.0, 2.3) << endl; + cout << "U was set to double\n"; + cout << "Done\n"; + // std::cin.get(); + return 0; +} diff --git a/study_cpp/cpp_primer_source_code/Chapter 14/tempparm.cpp b/study_cpp/cpp_primer_source_code/Chapter 14/tempparm.cpp new file mode 100644 index 0000000..b2e4d96 --- /dev/null +++ b/study_cpp/cpp_primer_source_code/Chapter 14/tempparm.cpp @@ -0,0 +1,40 @@ +// tempparm.cpp templates as parameters +#include +#include "stacktp.h" + +template