comparison libfdproto/dictionary_functions.c @ 1035:2f989d1a21e9

Improve dumper for time, and print longer UTF8 strings.
author Thomas Klausner <tk@giga.or.at>
date Tue, 16 Apr 2013 18:51:25 +0200
parents 000e1904074c
children b3d623f04b6d
comparison
equal deleted inserted replaced
1033:000e1904074c 1035:2f989d1a21e9
216 /*******************************/ 216 /*******************************/
217 217
218 /* Dump the AVP in a natural human-readable format */ 218 /* Dump the AVP in a natural human-readable format */
219 char * fd_dictfct_UTF8String_dump(union avp_value * avp_value) 219 char * fd_dictfct_UTF8String_dump(union avp_value * avp_value)
220 { 220 {
221 #define TRUNC_LEN 42 /* avoid very long strings */ 221 #define TRUNC_LEN 1024 /* avoid very long strings */
222 char * ret = strndup((char *)avp_value->os.data, TRUNC_LEN); 222 char * ret;
223 if (ret && (*ret != '\0')) { 223 CHECK_MALLOC_DO( ret = malloc(TRUNC_LEN+2+3+1), return NULL );
224 *ret = '"';
225 strncpy(ret+1, (char *)avp_value->os.data, TRUNC_LEN);
226 /* be sure to have a nul-terminated string */
227 ret[TRUNC_LEN+1] = '\0';
228 if (ret[1] != '\0') {
224 /* We sanitize the returned string to avoid UTF8 boundary problem. 229 /* We sanitize the returned string to avoid UTF8 boundary problem.
225 We do this whether the string is trucated at TRUNC_LEN or not, to avoid potential problem 230 We do this whether the string is trucated at TRUNC_LEN or not, to avoid potential problem
226 with malformed AVP */ 231 with malformed AVP */
227 232
228 char * end = strchr(ret, '\0'); 233 char * end = strchr(ret, '\0');
229 234 char * oldend = end;
230 while (end > ret) { 235 while (end > ret) {
231 end--; 236 end--;
232 char b = *end; 237 char b = *end;
233 /* after the position pointed by end, we have only \0s */ 238 /* after the position pointed by end, we have only \0s */
234 if ((b & 0x80) == 0) { 239 if ((b & 0x80) == 0) {
238 *end = '\0'; 243 *end = '\0';
239 if (b & 0x40) 244 if (b & 0x40)
240 break; /* This was a start byte, we can stop the loop */ 245 break; /* This was a start byte, we can stop the loop */
241 } 246 }
242 } 247 }
243 } 248 if (strlen((char *)avp_value->os.data) > strlen(ret+1))
249 strcat(end, "...");
250 strcat(end, "\"");
251 } else {
252 *ret = '\0';
253 }
244 return ret; 254 return ret;
245 } 255 }
246 256
247 257
248 /*******************************/ 258 /*******************************/
317 } 327 }
318 328
319 char * fd_dictfct_Time_dump(union avp_value * avp_value) 329 char * fd_dictfct_Time_dump(union avp_value * avp_value)
320 { 330 {
321 char * ret; 331 char * ret;
332 time_t val;
333 struct tm conv;
322 CHECK_MALLOC_DO( ret = malloc(STR_LEN), return NULL ); 334 CHECK_MALLOC_DO( ret = malloc(STR_LEN), return NULL );
323 if (avp_value->os.len != 4) { 335 if (avp_value->os.len != 4) {
324 snprintf(ret, STR_LEN, "[invalid length: %zd]", avp_value->os.len); 336 snprintf(ret, STR_LEN, "[invalid length: %zd]", avp_value->os.len);
325 return ret; 337 return ret;
326 } 338 }
327 /* TODO: display the time as human-readable */ 339 if (diameter_string_to_time_t(avp_value->os.data, avp_value->os.len, &val) != 0) {
328 snprintf(ret, STR_LEN, "[TODO Time dump: 0x%02hhx%02hhx%02hhx%02hhx]", avp_value->os.data[0], avp_value->os.data[1], avp_value->os.data[2], avp_value->os.data[3]); 340 snprintf(ret, STR_LEN, "[time conversion error]");
341 return ret;
342 }
343 gmtime_r(&val, &conv);
344 snprintf(ret, STR_LEN, "%d%02d%02dT%02d%02d%02d+00", conv.tm_year+1900, conv.tm_mon+1, conv.tm_mday, conv.tm_hour, conv.tm_min, conv.tm_sec);
329 return ret; 345 return ret;
330 } 346 }
331 347
"Welcome to our mercurial repository"