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