comparison src/protocols/qq/utils.c @ 14021:ef8490f9e823

[gaim-migrate @ 16618] Replaced all C++-style comments with C-style ones. Cleaned up some comments and implemented a more consistent formatting scheme. committer: Tailor Script <tailor@pidgin.im>
author Mark Huetsch <markhuetsch>
date Wed, 02 Aug 2006 15:35:36 +0000
parents 39d6d4128599
children 8294485b79db
comparison
equal deleted inserted replaced
14020:13e7ba964993 14021:ef8490f9e823
18 * You should have received a copy of the GNU General Public License 18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software 19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */ 21 */
22 22
23 #include "stdlib.h" // strtol 23 #include "stdlib.h"
24 #include "limits.h" 24 #include "limits.h"
25 #include "string.h" // strlen 25 #include "string.h"
26 26
27 #ifdef _WIN32 27 #ifdef _WIN32
28 #include "win32dep.h" 28 #include "win32dep.h"
29 #endif 29 #endif
30 30
31 #include "debug.h" // gaim_debug 31 #include "char_conv.h"
32 #include "debug.h"
33 #include "prefs.h"
32 #include "utils.h" 34 #include "utils.h"
33 #include "char_conv.h" // qq_to_utf8
34 #include "prefs.h" // gaim_prefs_get_string
35 35
36 #define QQ_NAME_FORMAT "qq-%d" 36 #define QQ_NAME_FORMAT "qq-%d"
37 37
38 #ifndef g_str_has_prefix 38 #ifndef g_str_has_prefix
39 gint g_str_has_prefix(const gchar *str, const gchar *prefix) 39 gint g_str_has_prefix(const gchar *str, const gchar *prefix)
41 gint len = strlen(prefix); 41 gint len = strlen(prefix);
42 return !strncmp(str, prefix, len); 42 return !strncmp(str, prefix, len);
43 } 43 }
44 #endif 44 #endif
45 45
46 /*****************************************************************************/ 46 gchar *get_name_by_index_str(gchar **array, const gchar *index_str, gint amount)
47 gchar *get_name_by_index_str(gchar **array, const gchar *index_str, gint amount) { 47 {
48 gint index; 48 gint index;
49 49
50 index = atoi(index_str); 50 index = atoi(index_str);
51 if (index < 0 || index >= amount) 51 if (index < 0 || index >= amount)
52 index = 0; 52 index = 0;
53 53
54 return array[index]; 54 return array[index];
55 } // get_name_by_index_str 55 }
56 56
57 /*****************************************************************************/ 57 gchar *get_index_str_by_name(gchar **array, const gchar *name, gint amount)
58 gchar *get_index_str_by_name(gchar **array, const gchar *name, gint amount) { 58 {
59 gint index; 59 gint index;
60 60
61 for (index = 0; index <= amount; index++) 61 for (index = 0; index <= amount; index++)
62 if (g_ascii_strcasecmp(array[index], name) == 0) 62 if (g_ascii_strcasecmp(array[index], name) == 0)
63 break; 63 break;
64 64
65 if (index >= amount) 65 if (index >= amount)
66 index = 0; // meaning no match 66 index = 0; /* meaning no match */
67 return g_strdup_printf("%d", index); 67 return g_strdup_printf("%d", index);
68 } // get_index_str_by_name 68 }
69 69
70 /*****************************************************************************/
71 gint qq_string_to_dec_value(const gchar *str) 70 gint qq_string_to_dec_value(const gchar *str)
72 { 71 {
73 g_return_val_if_fail(str != NULL, 0); 72 g_return_val_if_fail(str != NULL, 0);
74 return strtol(str, NULL, 10); 73 return strtol(str, NULL, 10);
75 } // _qq_string_to_dec_value 74 }
76 75
77 /*****************************************************************************/ 76 /* split the given data(len) with delimit,
78 // split the given data(len) with delimit, 77 * check the number of field matches the expected_fields (<=0 means all)
79 // check the number of field matches the expected_fields (<=0 means all) 78 * return gchar* array (needs to be freed by g_strfreev later), or NULL */
80 // return gchar* array (needs to be freed by g_strfreev later), or NULL 79 gchar **split_data(guint8 *data, gint len, const gchar *delimit, gint expected_fields)
81 gchar **split_data(guint8 *data, gint len, const gchar *delimit, gint expected_fields) { 80 {
82
83 guint8 *input; 81 guint8 *input;
84 gchar **segments; 82 gchar **segments;
85 gint i, j; 83 gint i, j;
86 84
87 g_return_val_if_fail(data != NULL && len != 0 && delimit != 0, NULL); 85 g_return_val_if_fail(data != NULL && len != 0 && delimit != 0, NULL);
88 86
89 // as the last field would be string, but data is not ended with 0x00 87 /* as the last field would be string, but data is not ended with 0x00
90 // we have to duplicate the data and append a 0x00 at the end 88 * we have to duplicate the data and append a 0x00 at the end */
91 input = g_newa(guint8, len + 1); 89 input = g_newa(guint8, len + 1);
92 g_memmove(input, data, len); 90 g_memmove(input, data, len);
93 input[len] = 0x00; 91 input[len] = 0x00;
94 92
95 segments = g_strsplit((gchar *) input, delimit, 0); 93 segments = g_strsplit((gchar *) input, delimit, 0);
96 if (expected_fields <= 0) 94 if (expected_fields <= 0)
97 return segments; 95 return segments;
98 96
99 for (i = 0; segments[i] != NULL; i++) {; 97 for (i = 0; segments[i] != NULL; i++) {;
100 } 98 }
101 if (i < expected_fields) { // not enough fields 99 if (i < expected_fields) { /* not enough fields */
102 gaim_debug(GAIM_DEBUG_ERROR, "QQ", 100 gaim_debug(GAIM_DEBUG_ERROR, "QQ",
103 "Invalid data, expect %d fields, found only %d, discard\n", expected_fields, i); 101 "Invalid data, expect %d fields, found only %d, discard\n", expected_fields, i);
104 g_strfreev(segments); 102 g_strfreev(segments);
105 return NULL; 103 return NULL;
106 } else if (i > expected_fields) { // more fields, OK 104 } else if (i > expected_fields) { /* more fields, OK */
107 gaim_debug(GAIM_DEBUG_WARNING, "QQ", 105 gaim_debug(GAIM_DEBUG_WARNING, "QQ",
108 "Dangerous data, expect %d fields, found %d, return all\n", expected_fields, i); 106 "Dangerous data, expect %d fields, found %d, return all\n", expected_fields, i);
109 // free up those not used 107 /* free up those not used */
110 for (j = expected_fields; j < i; j++) { 108 for (j = expected_fields; j < i; j++) {
111 gaim_debug(GAIM_DEBUG_WARNING, "QQ", "field[%d] is %s\n", j, segments[j]); 109 gaim_debug(GAIM_DEBUG_WARNING, "QQ", "field[%d] is %s\n", j, segments[j]);
112 g_free(segments[j]); 110 g_free(segments[j]);
113 } 111 }
114 112
116 } 114 }
117 115
118 return segments; 116 return segments;
119 } 117 }
120 118
121 /*****************************************************************************/ 119 /* given a four-byte ip data, convert it into a human readable ip string
122 // given a four-byte ip data, convert it into a human readable ip string 120 * the return needs to be freed */
123 // the return needs to be freed
124 gchar *gen_ip_str(guint8 *ip) 121 gchar *gen_ip_str(guint8 *ip)
125 { 122 {
126 gchar *ret; 123 gchar *ret;
127 if (ip == NULL || ip[0] == 0) { 124 if (ip == NULL || ip[0] == 0) {
128 ret = g_new(gchar, 1); 125 ret = g_new(gchar, 1);
129 *ret = '\0'; 126 *ret = '\0';
130 return ret; 127 return ret;
131 } else 128 } else {
132 return g_strdup_printf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]); 129 return g_strdup_printf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
130 }
133 } 131 }
134 132
135 guint8 *str_ip_gen(gchar *str) { 133 guint8 *str_ip_gen(gchar *str) {
136 guint8 *ip = g_new(guint8, 4); 134 guint8 *ip = g_new(guint8, 4);
137 int a, b, c, d; 135 int a, b, c, d;
141 ip[2] = c; 139 ip[2] = c;
142 ip[3] = d; 140 ip[3] = d;
143 return ip; 141 return ip;
144 } 142 }
145 143
146 /*****************************************************************************/ 144 /* return the QQ icon file name
147 // return the QQ icon file name 145 * the return needs to be freed */
148 // the return needs to be freed
149 gchar *get_icon_name(gint set, gint suffix) 146 gchar *get_icon_name(gint set, gint suffix)
150 { 147 {
151 return g_strdup_printf("qq_%d-%d", set, suffix); 148 return g_strdup_printf("qq_%d-%d", set, suffix);
152 } // get_icon_name 149 }
153 150
154 /*****************************************************************************/ 151 /* convert a QQ UID to a unique name of GAIM
155 // convert a QQ UID to a unique name of GAIM 152 * the return needs to be freed */
156 // the return needs to be freed
157 gchar *uid_to_gaim_name(guint32 uid) 153 gchar *uid_to_gaim_name(guint32 uid)
158 { 154 {
159 return g_strdup_printf(QQ_NAME_FORMAT, uid); 155 return g_strdup_printf(QQ_NAME_FORMAT, uid);
160 } // uid_to_gaim_name 156 }
161 157
162 /*****************************************************************************/ 158 /* convert GAIM name to original QQ UID */
163 // convert GAIM name to original QQ UID
164 guint32 gaim_name_to_uid(const gchar *name) 159 guint32 gaim_name_to_uid(const gchar *name)
165 { 160 {
166 gchar *p; 161 gchar *p;
167 162
168 g_return_val_if_fail(g_str_has_prefix(name, QQ_NAME_PREFIX), 0); 163 g_return_val_if_fail(g_str_has_prefix(name, QQ_NAME_PREFIX), 0);
169 164
170 p = g_strrstr(name, QQ_NAME_PREFIX); 165 p = g_strrstr(name, QQ_NAME_PREFIX);
171 // atoi is not thread-safe and also not async-cancel safe
172 // atoi is deprecated by strtol() and should not be used in new code
173 return (p == NULL) ? 0 : strtol(p + strlen(QQ_NAME_PREFIX), NULL, 10); 166 return (p == NULL) ? 0 : strtol(p + strlen(QQ_NAME_PREFIX), NULL, 10);
174 } 167 }
175 168
176 /*****************************************************************************/ 169 /* try to dump the data as GBK */
177 // try to dump the data as GBK
178 void try_dump_as_gbk(guint8 *data, gint len) 170 void try_dump_as_gbk(guint8 *data, gint len)
179 { 171 {
180 gint i; 172 gint i;
181 guint8 *incoming; 173 guint8 *incoming;
182 gchar *msg_utf8; 174 gchar *msg_utf8;
183 175
184 incoming = g_newa(guint8, len + 1); 176 incoming = g_newa(guint8, len + 1);
185 g_memmove(incoming, data, len); 177 g_memmove(incoming, data, len);
186 incoming[len] = 0x00; 178 incoming[len] = 0x00;
187 // GBK code: 179 /* GBK code:
188 // Single-byte ASCII: 0x21-0x7E 180 * Single-byte ASCII: 0x21-0x7E
189 // GBK first byte range: 0x81-0xFE 181 * GBK first byte range: 0x81-0xFE
190 // GBK second byte range: 0x40-0x7E and 0x80-0xFE 182 * GBK second byte range: 0x40-0x7E and 0x80-0xFE */
191 for (i = 0; i < len; i++) 183 for (i = 0; i < len; i++)
192 if (incoming[i] >= 0x81) 184 if (incoming[i] >= 0x81)
193 break; 185 break;
194 186
195 msg_utf8 = i < len ? qq_to_utf8((gchar *) &incoming[i], QQ_CHARSET_DEFAULT) : NULL; 187 msg_utf8 = i < len ? qq_to_utf8((gchar *) &incoming[i], QQ_CHARSET_DEFAULT) : NULL;
196 188
197 if (msg_utf8 != NULL) { 189 if (msg_utf8 != NULL) {
198 gaim_debug(GAIM_DEBUG_WARNING, "QQ", "Try extract GB msg: %s\n", msg_utf8); 190 gaim_debug(GAIM_DEBUG_WARNING, "QQ", "Try extract GB msg: %s\n", msg_utf8);
199 g_free(msg_utf8); 191 g_free(msg_utf8);
200 } // msg_utf8 != NULL 192 }
201 } // try_dump_gbk 193 }
202 194
203 /*****************************************************************************/ 195 /* strips whitespace */
204 // strips whitespace
205 static gchar *strstrip(const gchar *buffer) 196 static gchar *strstrip(const gchar *buffer)
206 { 197 {
207 GString *stripped; 198 GString *stripped;
208 gchar *ret; 199 gchar *ret;
209 int i; 200 int i;
218 g_string_free(stripped, FALSE); 209 g_string_free(stripped, FALSE);
219 210
220 return ret; 211 return ret;
221 } 212 }
222 213
223 /*****************************************************************************/ 214 /* Dumps an ASCII hex string to a string of bytes. The return should be freed later.
224 // Dumps an ASCII hex string to a string of bytes. The return should be freed later. 215 * Returns NULL if a string with an odd number of nibbles is passed in or if buffer
225 // Returns NULL if a string with an odd number of nibbles is passed in or if buffer 216 * isn't a valid hex string */
226 // isn't a valid hex string
227 guint8 *hex_str_to_bytes(const gchar *buffer) 217 guint8 *hex_str_to_bytes(const gchar *buffer)
228 { 218 {
229 gchar *hex_str, *hex_buffer, *cursor, tmp; 219 gchar *hex_str, *hex_buffer, *cursor, tmp;
230 guint8 *bytes, nibble1, nibble2; 220 guint8 *bytes, nibble1, nibble2;
231 gint index, len; 221 gint index, len;
266 len = strlen(hex_str) / 2; 256 len = strlen(hex_str) / 2;
267 g_free(hex_str); 257 g_free(hex_str);
268 return g_memdup(bytes, len); 258 return g_memdup(bytes, len);
269 } 259 }
270 260
271 // Dumps a chunk of raw data into an ASCII hex string. The return should be freed later. 261 /* Dumps a chunk of raw data into an ASCII hex string. The return should be freed later. */
272 gchar *hex_dump_to_str(const guint8 *buffer, gint bytes) 262 gchar *hex_dump_to_str(const guint8 *buffer, gint bytes)
273 { 263 {
274 GString *str; 264 GString *str;
275 gchar *ret; 265 gchar *ret;
276 gint i, j, ch; 266 gint i, j, ch;
277 267
278 str = g_string_new(""); 268 str = g_string_new("");
279 for (i = 0; i < bytes; i += 16) { 269 for (i = 0; i < bytes; i += 16) {
280 // length label 270 /* length label */
281 g_string_append_printf(str, "%04d: ", i); 271 g_string_append_printf(str, "%04d: ", i);
282 272
283 // dump hex value 273 /* dump hex value */
284 for (j = 0; j < 16; j++) 274 for (j = 0; j < 16; j++)
285 if ((i + j) < bytes) 275 if ((i + j) < bytes)
286 g_string_append_printf(str, " %02X", buffer[i + j]); 276 g_string_append_printf(str, " %02X", buffer[i + j]);
287 else 277 else
288 g_string_append(str, " "); 278 g_string_append(str, " ");
289 g_string_append(str, " "); 279 g_string_append(str, " ");
290 280
291 // dump ascii value 281 /* dump ascii value */
292 for (j = 0; j < 16 && (i + j) < bytes; j++) { 282 for (j = 0; j < 16 && (i + j) < bytes; j++) {
293 ch = buffer[i + j] & 127; 283 ch = buffer[i + j] & 127;
294 if (ch < ' ' || ch == 127) 284 if (ch < ' ' || ch == 127)
295 g_string_append_c(str, '.'); 285 g_string_append_c(str, '.');
296 else 286 else
298 } 288 }
299 g_string_append_c(str, '\n'); 289 g_string_append_c(str, '\n');
300 } 290 }
301 291
302 ret = str->str; 292 ret = str->str;
303 // GString can be freed without freeing it character data 293 /* GString can be freed without freeing it character data */
304 g_string_free(str, FALSE); 294 g_string_free(str, FALSE);
305 295
306 return ret; 296 return ret;
307 } 297 }