diff --git a/HISTORY b/HISTORY index 5571151..9775e46 100644 --- a/HISTORY +++ b/HISTORY @@ -1,5 +1,5 @@ -Version 1.44 2020-03-03 +Version 1.44 2020-03-04 * add test file src/tests/test_pthread_lock.c * add uniq_skiplist.[hc] * add function split_string_ex @@ -13,7 +13,8 @@ Version 1.44 2020-03-03 * shared_func.[hc]: add functions fc_floor_prime and fc_ceil_prime * fast_mpool.[hc]: change function fast_mpool_strdup * fast_allocator.[hc]: add function fast_allocator_strdup - * shared_func.[hc]: add functions getFileSize + * shared_func.[hc]: add function getFileSize + * char_converter.[hc]: add function fast_char_unescape Version 1.43 2019-12-25 * replace function call system to getExecResult, diff --git a/src/char_converter.c b/src/char_converter.c index c1c6ecd..6cd0b0b 100644 --- a/src/char_converter.c +++ b/src/char_converter.c @@ -20,7 +20,8 @@ int char_converter_init_ex(FastCharConverter *pCharConverter, const unsigned op) { int i; - unsigned char src; + unsigned char from; + unsigned char to; if (count > FAST_MAX_CHAR_COUNT) { logError("file: "__FILE__", line: %d, " @@ -33,10 +34,15 @@ int char_converter_init_ex(FastCharConverter *pCharConverter, pCharConverter->count = count; for (i=0; ichar_table[src].op = op; - pCharConverter->char_table[src].dest = charPairs[i].dest; + from = charPairs[i].src; + to = charPairs[i].dest; + pCharConverter->char_table[from].op = op; + pCharConverter->char_table[from].dest = to; + + pCharConverter->unescape_chars[to].op = op; + pCharConverter->unescape_chars[to].dest = from; } + return 0; } @@ -67,14 +73,14 @@ int std_spaces_add_backslash_converter_init(FastCharConverter *pCharConverter) #define SPACE_CHAR_PAIR_COUNT2 8 FastCharPair pairs[SPACE_CHAR_PAIR_COUNT2]; - pairs[0].src = '\0'; pairs[0].dest = '0'; - pairs[1].src = '\t'; pairs[1].dest = 't'; - pairs[2].src = '\n'; pairs[2].dest = 'n'; - pairs[3].src = '\v'; pairs[3].dest = 'v'; - pairs[4].src = '\f'; pairs[4].dest = 'f'; - pairs[5].src = '\r'; pairs[5].dest = 'r'; - pairs[6].src = ' '; pairs[6].dest = '-'; - pairs[7].src = '\\'; pairs[7].dest = '\\'; + FAST_CHAR_MAKE_PAIR(pairs[0], '\0', '0'); + FAST_CHAR_MAKE_PAIR(pairs[1], '\t', 't'); + FAST_CHAR_MAKE_PAIR(pairs[2], '\n', 'n'); + FAST_CHAR_MAKE_PAIR(pairs[3], '\v', 'v'); + FAST_CHAR_MAKE_PAIR(pairs[4], '\f', 'f'); + FAST_CHAR_MAKE_PAIR(pairs[5], '\r', 'r'); + FAST_CHAR_MAKE_PAIR(pairs[6], ' ', 's'); + FAST_CHAR_MAKE_PAIR(pairs[7], '\\', '\\'); return char_converter_init_ex(pCharConverter, pairs, SPACE_CHAR_PAIR_COUNT2, FAST_CHAR_OP_ADD_BACKSLASH); @@ -142,7 +148,7 @@ int fast_char_convert(FastCharConverter *pCharConverter, out_size_sub1 = out_size - 1; for (; pi= out_size_sub1) { - logDebug("file: "__FILE__", line: %d, " + logWarning("file: "__FILE__", line: %d, " "exceeds max size: %d", __LINE__, out_size); break; } @@ -162,3 +168,47 @@ int fast_char_convert(FastCharConverter *pCharConverter, return count; } +int fast_char_unescape(FastCharConverter *pCharConverter, char *str, int *len) +{ + int count; + unsigned char *backslash; + unsigned char *p; + unsigned char *end; + unsigned char *dest; + + backslash = (unsigned char *)memchr(str, '\\', *len); + if (backslash == NULL) { + return 0; + } + + count = 0; + end = (unsigned char *)str + *len; + p = dest = backslash; + while (p < end) { + if (*p == '\\') { + if (p + 1 < end) { + if (pCharConverter->unescape_chars[p[1]].op == + FAST_CHAR_OP_ADD_BACKSLASH) + { + *dest++ = pCharConverter->unescape_chars[p[1]].dest; + p += 2; + ++count; + } else { + *dest++ = *p++; + } + } else { + *dest++ = *p++; + } + } else if (pCharConverter->unescape_chars[*p].op == + FAST_CHAR_OP_NO_BACKSLASH) + { + *dest++ = pCharConverter->unescape_chars[*p++].dest; + ++count; + } else { + *dest++ = *p++; + } + } + + *len = dest - (unsigned char *)str; + return count; +} diff --git a/src/char_converter.h b/src/char_converter.h index 4e51b98..a85af84 100644 --- a/src/char_converter.h +++ b/src/char_converter.h @@ -24,6 +24,9 @@ extern "C" { #define FAST_CHAR_OP_ADD_BACKSLASH 1 #define FAST_CHAR_OP_NO_BACKSLASH 2 +#define FAST_CHAR_MAKE_PAIR(pair, from, to) \ + pair.src = from; pair.dest = to + typedef struct fast_char_pair { unsigned char src; @@ -47,6 +50,11 @@ typedef struct fast_char_converter * char table to convert * */ FastCharTarget char_table[FAST_MAX_CHAR_COUNT]; + + /* + * char table to unescape + * */ + FastCharTarget unescape_chars[FAST_MAX_CHAR_COUNT]; } FastCharConverter; /** @@ -133,6 +141,21 @@ int fast_char_convert(FastCharConverter *pCharConverter, const char *input, const int input_len, char *output, int *out_len, const int out_size); +#define fast_char_escape(pCharConverter, input, input_len, \ + output, out_len, out_size) \ + fast_char_convert(pCharConverter, input, input_len, \ + output, out_len, out_size) + +/** + * char unescape function + * parameters: + * pCharConverter: the char converter + * str: the string to unescape + * len: the input string length and store the unscaped string length + * return: converted char count +*/ +int fast_char_unescape(FastCharConverter *pCharConverter, char *str, int *len); + #ifdef __cplusplus } #endif diff --git a/src/tests/Makefile b/src/tests/Makefile index 4243bdb..a2e621d 100644 --- a/src/tests/Makefile +++ b/src/tests/Makefile @@ -8,7 +8,7 @@ ALL_PRGS = test_allocator test_skiplist test_multi_skiplist test_mblock test_blo test_id_generator test_ini_parser test_char_convert test_char_convert_loader \ test_logger test_skiplist_set test_crc32 test_thourands_seperator test_sched_thread \ test_json_parser test_pthread_lock test_uniq_skiplist test_split_string \ - test_server_id_func + test_server_id_func test_pipe all: $(ALL_PRGS) .c: diff --git a/src/tests/test_pipe.c b/src/tests/test_pipe.c new file mode 100644 index 0000000..b6a7fc7 --- /dev/null +++ b/src/tests/test_pipe.c @@ -0,0 +1,76 @@ +#include +#include +#include +#include +#include +#include +#include +#include "fastcommon/logger.h" +#include "fastcommon/shared_func.h" + +#define LOOP (200 * 1000) + +int main(int argc, char *argv[]) +{ + int result; + int pipe_fds[2]; + int i; + long n; + pid_t pid; + int64_t start_time; + + log_init(); + + if (pipe(pipe_fds) != 0) { + result = errno != 0 ? errno : EPERM; + logError("file: "__FILE__", line: %d, " + "call pipe fail, " + "errno: %d, error info: %s", + __LINE__, result, strerror(result)); + return result; + } + + pid = fork(); + if (pid < 0) { + result = errno != 0 ? errno : EPERM; + logError("file: "__FILE__", line: %d, " + "call fork fail, " + "errno: %d, error info: %s", + __LINE__, result, strerror(result)); + return result; + } + if (pid == 0) { + printf("i am the child proccess: %d\n", getpid()); + start_time = get_current_time_ms(); + for (i=0;i