/* * Copyright (c) 2020 YuQing <384681@qq.com> * * This program is free software: you can use, redistribute, and/or modify * it under the terms of the Lesser GNU General Public License, version 3 * or later ("LGPL"), as published by the Free Software Foundation. * * This program 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. * * You should have received a copy of the Lesser GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include #include "logger.h" #include "shared_func.h" #include "char_converter.h" int char_converter_init_ex(FastCharConverter *pCharConverter, const FastCharPair *charPairs, const int count, const unsigned op) { int i; unsigned char from; unsigned char to; if (count > FAST_MAX_CHAR_COUNT) { logError("file: "__FILE__", line: %d, " "count: %d is too large, exceeds %d!", __LINE__, count, FAST_MAX_CHAR_COUNT); return EINVAL; } memset(pCharConverter, 0, sizeof(FastCharConverter)); pCharConverter->count = count; for (i=0; ichar_table[from].op = op; pCharConverter->char_table[from].dest = to; pCharConverter->unescape_chars[to].op = op; pCharConverter->unescape_chars[to].dest = from; } return 0; } int std_space_char_converter_init(FastCharConverter *pCharConverter, const unsigned char dest_base) { #define SPACE_CHAR_PAIR_COUNT1 7 int i; FastCharPair pairs[SPACE_CHAR_PAIR_COUNT1]; pairs[0].src = '\0'; pairs[1].src = '\t'; pairs[2].src = '\n'; pairs[3].src = '\v'; pairs[4].src = '\f'; pairs[5].src = '\r'; pairs[6].src = ' '; for (i=0; ichar_table[src].op != FAST_CHAR_OP_NONE) { --pCharConverter->count; } } else { if (pCharConverter->char_table[src].op == FAST_CHAR_OP_NONE) { ++pCharConverter->count; } } pCharConverter->char_table[src].op = op; pCharConverter->char_table[src].dest = dest; } int fast_char_convert(FastCharConverter *pCharConverter, const char *input, const int input_len, char *output, int *out_len, const int out_size) { int count; unsigned char *pi; unsigned char *po; unsigned char *end; int out_size_sub1; count = 0; po = (unsigned char *)output; if (out_size >= input_len) { end = (unsigned char *)input + input_len; } else { end = (unsigned char *)input + out_size; } for (pi=(unsigned char *)input; pichar_table[*pi].op != FAST_CHAR_OP_NONE) { if (pCharConverter->char_table[*pi].op == FAST_CHAR_OP_ADD_BACKSLASH) { break; } *po++ = pCharConverter->char_table[*pi].dest; ++count; } else { *po++ = *pi; } } if (pi == end) { *out_len = po - (unsigned char *)output; return count; } out_size_sub1 = out_size - 1; for (; pi= out_size_sub1) { logWarning("file: "__FILE__", line: %d, " "exceeds max size: %d", __LINE__, out_size); break; } if (pCharConverter->char_table[*pi].op != FAST_CHAR_OP_NONE) { if (pCharConverter->char_table[*pi].op == FAST_CHAR_OP_ADD_BACKSLASH) { *po++ = '\\'; } *po++ = pCharConverter->char_table[*pi].dest; ++count; } else { *po++ = *pi; } } *out_len = po - (unsigned char *)output; 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; }