1 /**
2 * Copyright (C) 2008 Happy Fish / YuQing
3 *
4 * FastDFS may be copied only under the terms of the GNU General
5 * Public License V3, which may be found in the FastDFS source kit.
6 * Please visit the FastDFS Home Page http://www.fastken.com/ for more detail.
7 **/
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <unistd.h>
13 #include <errno.h>
14 #include "logger.h"
15 #include "shared_func.h"
16 #include "char_converter.h"
17
char_converter_init_ex(FastCharConverter * pCharConverter,const FastCharPair * charPairs,const int count,const unsigned op)18 int char_converter_init_ex(FastCharConverter *pCharConverter,
19 const FastCharPair *charPairs, const int count,
20 const unsigned op)
21 {
22 int i;
23 unsigned char src;
24 if (count > FAST_MAX_CHAR_COUNT)
25 {
26 logError("file: "__FILE__", line: %d, "
27 "count: %d is too large, exceeds %d!", __LINE__,
28 count, FAST_MAX_CHAR_COUNT);
29 return EINVAL;
30 }
31
32 memset(pCharConverter, 0, sizeof(FastCharConverter));
33 pCharConverter->count = count;
34 for (i=0; i<count; i++)
35 {
36 src = charPairs[i].src;
37 pCharConverter->char_table[src].op = op;
38 pCharConverter->char_table[src].dest = charPairs[i].dest;
39 }
40 return 0;
41 }
42
std_space_char_converter_init(FastCharConverter * pCharConverter,const unsigned char dest_base)43 int std_space_char_converter_init(FastCharConverter *pCharConverter,
44 const unsigned char dest_base)
45 {
46 #define SPACE_CHAR_PAIR_COUNT1 7
47 int i;
48 FastCharPair pairs[SPACE_CHAR_PAIR_COUNT1];
49
50 pairs[0].src = '\0';
51 pairs[1].src = '\t';
52 pairs[2].src = '\n';
53 pairs[3].src = '\v';
54 pairs[4].src = '\f';
55 pairs[5].src = '\r';
56 pairs[6].src = ' ';
57
58 for (i=0; i<SPACE_CHAR_PAIR_COUNT1; i++) {
59 pairs[i].dest = dest_base + i;
60 }
61
62 return char_converter_init(pCharConverter, pairs, SPACE_CHAR_PAIR_COUNT1);
63 }
64
std_spaces_add_backslash_converter_init(FastCharConverter * pCharConverter)65 int std_spaces_add_backslash_converter_init(FastCharConverter *pCharConverter)
66 {
67 #define SPACE_CHAR_PAIR_COUNT2 8
68 FastCharPair pairs[SPACE_CHAR_PAIR_COUNT2];
69
70 pairs[0].src = '\0'; pairs[0].dest = '0';
71 pairs[1].src = '\t'; pairs[1].dest = 't';
72 pairs[2].src = '\n'; pairs[2].dest = 'n';
73 pairs[3].src = '\v'; pairs[3].dest = 'v';
74 pairs[4].src = '\f'; pairs[4].dest = 'f';
75 pairs[5].src = '\r'; pairs[5].dest = 'r';
76 pairs[6].src = ' '; pairs[6].dest = '-';
77 pairs[7].src = '\\'; pairs[7].dest = '\\';
78
79 return char_converter_init_ex(pCharConverter, pairs,
80 SPACE_CHAR_PAIR_COUNT2, FAST_CHAR_OP_ADD_BACKSLASH);
81 }
82
char_converter_set_pair(FastCharConverter * pCharConverter,const unsigned char src,const unsigned char dest)83 void char_converter_set_pair(FastCharConverter *pCharConverter,
84 const unsigned char src, const unsigned char dest)
85 {
86 char_converter_set_pair_ex(pCharConverter, src,
87 FAST_CHAR_OP_NO_BACKSLASH, dest);
88 }
89
char_converter_set_pair_ex(FastCharConverter * pCharConverter,const unsigned char src,const unsigned op,const unsigned char dest)90 void char_converter_set_pair_ex(FastCharConverter *pCharConverter,
91 const unsigned char src, const unsigned op, const unsigned char dest)
92 {
93 if (op == FAST_CHAR_OP_NONE) {
94 if (pCharConverter->char_table[src].op != FAST_CHAR_OP_NONE) {
95 --pCharConverter->count;
96 }
97 } else {
98 if (pCharConverter->char_table[src].op == FAST_CHAR_OP_NONE) {
99 ++pCharConverter->count;
100 }
101 }
102
103 pCharConverter->char_table[src].op = op;
104 pCharConverter->char_table[src].dest = dest;
105 }
106
fast_char_convert(FastCharConverter * pCharConverter,const char * input,const int input_len,char * output,int * out_len,const int out_size)107 int fast_char_convert(FastCharConverter *pCharConverter,
108 const char *input, const int input_len,
109 char *output, int *out_len, const int out_size)
110 {
111 int count;
112 unsigned char *pi;
113 unsigned char *po;
114 unsigned char *end;
115 int out_size_sub1;
116
117 count = 0;
118 po = (unsigned char *)output;
119 if (out_size >= input_len) {
120 end = (unsigned char *)input + input_len;
121 } else {
122 end = (unsigned char *)input + out_size;
123 }
124 for (pi=(unsigned char *)input; pi<end; pi++) {
125 if (pCharConverter->char_table[*pi].op != FAST_CHAR_OP_NONE) {
126 if (pCharConverter->char_table[*pi].op == FAST_CHAR_OP_ADD_BACKSLASH) {
127 break;
128 }
129
130 *po++ = pCharConverter->char_table[*pi].dest;
131 ++count;
132 } else {
133 *po++ = *pi;
134 }
135 }
136
137 if (pi == end) {
138 *out_len = po - (unsigned char *)output;
139 return count;
140 }
141
142 out_size_sub1 = out_size - 1;
143 for (; pi<end; pi++) {
144 if (po - (unsigned char *)output >= out_size_sub1) {
145 logDebug("file: "__FILE__", line: %d, "
146 "exceeds max size: %d", __LINE__, out_size);
147 break;
148 }
149 if (pCharConverter->char_table[*pi].op != FAST_CHAR_OP_NONE) {
150 if (pCharConverter->char_table[*pi].op == FAST_CHAR_OP_ADD_BACKSLASH) {
151 *po++ = '\\';
152 }
153
154 *po++ = pCharConverter->char_table[*pi].dest;
155 ++count;
156 } else {
157 *po++ = *pi;
158 }
159 }
160
161 *out_len = po - (unsigned char *)output;
162 return count;
163 }
164
165