| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 #include "webrtc/base/stringencode.h" | 11 #include "webrtc/base/stringencode.h" |
| 12 | 12 |
| 13 #include <stdio.h> | 13 #include <stdio.h> |
| 14 #include <stdlib.h> | 14 #include <stdlib.h> |
| 15 | 15 |
| 16 #include "webrtc/base/basictypes.h" | 16 #include "webrtc/base/basictypes.h" |
| 17 #include "webrtc/base/checks.h" | 17 #include "webrtc/base/checks.h" |
| 18 #include "webrtc/base/stringutils.h" | 18 #include "webrtc/base/stringutils.h" |
| 19 | 19 |
| 20 namespace rtc { | 20 namespace rtc { |
| 21 | 21 |
| 22 ///////////////////////////////////////////////////////////////////////////// | 22 ///////////////////////////////////////////////////////////////////////////// |
| 23 // String Encoding Utilities | 23 // String Encoding Utilities |
| 24 ///////////////////////////////////////////////////////////////////////////// | 24 ///////////////////////////////////////////////////////////////////////////// |
| 25 | 25 |
| 26 size_t escape(char * buffer, size_t buflen, | 26 size_t escape(char * buffer, size_t buflen, |
| 27 const char * source, size_t srclen, | 27 const char * source, size_t srclen, |
| 28 const char * illegal, char escape) { | 28 const char * illegal, char escape) { |
| 29 DCHECK(buffer); // TODO: estimate output size | 29 RTC_DCHECK(buffer); // TODO(grunell): estimate output size |
| 30 if (buflen <= 0) | 30 if (buflen <= 0) |
| 31 return 0; | 31 return 0; |
| 32 | 32 |
| 33 size_t srcpos = 0, bufpos = 0; | 33 size_t srcpos = 0, bufpos = 0; |
| 34 while ((srcpos < srclen) && (bufpos + 1 < buflen)) { | 34 while ((srcpos < srclen) && (bufpos + 1 < buflen)) { |
| 35 char ch = source[srcpos++]; | 35 char ch = source[srcpos++]; |
| 36 if ((ch == escape) || ::strchr(illegal, ch)) { | 36 if ((ch == escape) || ::strchr(illegal, ch)) { |
| 37 if (bufpos + 2 >= buflen) | 37 if (bufpos + 2 >= buflen) |
| 38 break; | 38 break; |
| 39 buffer[bufpos++] = escape; | 39 buffer[bufpos++] = escape; |
| 40 } | 40 } |
| 41 buffer[bufpos++] = ch; | 41 buffer[bufpos++] = ch; |
| 42 } | 42 } |
| 43 | 43 |
| 44 buffer[bufpos] = '\0'; | 44 buffer[bufpos] = '\0'; |
| 45 return bufpos; | 45 return bufpos; |
| 46 } | 46 } |
| 47 | 47 |
| 48 size_t unescape(char * buffer, size_t buflen, | 48 size_t unescape(char * buffer, size_t buflen, |
| 49 const char * source, size_t srclen, | 49 const char * source, size_t srclen, |
| 50 char escape) { | 50 char escape) { |
| 51 DCHECK(buffer); // TODO: estimate output size | 51 RTC_DCHECK(buffer); // TODO(grunell): estimate output size |
| 52 if (buflen <= 0) | 52 if (buflen <= 0) |
| 53 return 0; | 53 return 0; |
| 54 | 54 |
| 55 size_t srcpos = 0, bufpos = 0; | 55 size_t srcpos = 0, bufpos = 0; |
| 56 while ((srcpos < srclen) && (bufpos + 1 < buflen)) { | 56 while ((srcpos < srclen) && (bufpos + 1 < buflen)) { |
| 57 char ch = source[srcpos++]; | 57 char ch = source[srcpos++]; |
| 58 if ((ch == escape) && (srcpos < srclen)) { | 58 if ((ch == escape) && (srcpos < srclen)) { |
| 59 ch = source[srcpos++]; | 59 ch = source[srcpos++]; |
| 60 } | 60 } |
| 61 buffer[bufpos++] = ch; | 61 buffer[bufpos++] = ch; |
| 62 } | 62 } |
| 63 buffer[bufpos] = '\0'; | 63 buffer[bufpos] = '\0'; |
| 64 return bufpos; | 64 return bufpos; |
| 65 } | 65 } |
| 66 | 66 |
| 67 size_t encode(char * buffer, size_t buflen, | 67 size_t encode(char * buffer, size_t buflen, |
| 68 const char * source, size_t srclen, | 68 const char * source, size_t srclen, |
| 69 const char * illegal, char escape) { | 69 const char * illegal, char escape) { |
| 70 DCHECK(buffer); // TODO: estimate output size | 70 RTC_DCHECK(buffer); // TODO(grunell): estimate output size |
| 71 if (buflen <= 0) | 71 if (buflen <= 0) |
| 72 return 0; | 72 return 0; |
| 73 | 73 |
| 74 size_t srcpos = 0, bufpos = 0; | 74 size_t srcpos = 0, bufpos = 0; |
| 75 while ((srcpos < srclen) && (bufpos + 1 < buflen)) { | 75 while ((srcpos < srclen) && (bufpos + 1 < buflen)) { |
| 76 char ch = source[srcpos++]; | 76 char ch = source[srcpos++]; |
| 77 if ((ch != escape) && !::strchr(illegal, ch)) { | 77 if ((ch != escape) && !::strchr(illegal, ch)) { |
| 78 buffer[bufpos++] = ch; | 78 buffer[bufpos++] = ch; |
| 79 } else if (bufpos + 3 >= buflen) { | 79 } else if (bufpos + 3 >= buflen) { |
| 80 break; | 80 break; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 112 buffer[bufpos] = '\0'; | 112 buffer[bufpos] = '\0'; |
| 113 return bufpos; | 113 return bufpos; |
| 114 } | 114 } |
| 115 | 115 |
| 116 const char* unsafe_filename_characters() { | 116 const char* unsafe_filename_characters() { |
| 117 // It might be better to have a single specification which is the union of | 117 // It might be better to have a single specification which is the union of |
| 118 // all operating systems, unless one system is overly restrictive. | 118 // all operating systems, unless one system is overly restrictive. |
| 119 #if defined(WEBRTC_WIN) | 119 #if defined(WEBRTC_WIN) |
| 120 return "\\/:*?\"<>|"; | 120 return "\\/:*?\"<>|"; |
| 121 #else // !WEBRTC_WIN | 121 #else // !WEBRTC_WIN |
| 122 // TODO | 122 // TODO(grunell): Should this never be reached? |
| 123 DCHECK(false); | 123 RTC_DCHECK(false); |
| 124 return ""; | 124 return ""; |
| 125 #endif // !WEBRTC_WIN | 125 #endif // !WEBRTC_WIN |
| 126 } | 126 } |
| 127 | 127 |
| 128 const unsigned char URL_UNSAFE = 0x1; // 0-33 "#$%&+,/:;<=>?@[\]^`{|} 127 | 128 const unsigned char URL_UNSAFE = 0x1; // 0-33 "#$%&+,/:;<=>?@[\]^`{|} 127 |
| 129 const unsigned char XML_UNSAFE = 0x2; // "&'<> | 129 const unsigned char XML_UNSAFE = 0x2; // "&'<> |
| 130 const unsigned char HTML_UNSAFE = 0x2; // "&'<> | 130 const unsigned char HTML_UNSAFE = 0x2; // "&'<> |
| 131 | 131 |
| 132 // ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 6 5 7 8 9 : ; < = > ? | 132 // ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 6 5 7 8 9 : ; < = > ? |
| 133 //@ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ | 133 //@ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 250 buffer[1] = 0x80 | static_cast<unsigned char>((value >> 12) & 0x3F); | 250 buffer[1] = 0x80 | static_cast<unsigned char>((value >> 12) & 0x3F); |
| 251 buffer[2] = 0x80 | static_cast<unsigned char>((value >> 6) & 0x3F); | 251 buffer[2] = 0x80 | static_cast<unsigned char>((value >> 6) & 0x3F); |
| 252 buffer[3] = 0x80 | static_cast<unsigned char>(value & 0x3F); | 252 buffer[3] = 0x80 | static_cast<unsigned char>(value & 0x3F); |
| 253 return 4; | 253 return 4; |
| 254 } | 254 } |
| 255 return 0; | 255 return 0; |
| 256 } | 256 } |
| 257 | 257 |
| 258 size_t html_encode(char * buffer, size_t buflen, | 258 size_t html_encode(char * buffer, size_t buflen, |
| 259 const char * source, size_t srclen) { | 259 const char * source, size_t srclen) { |
| 260 DCHECK(buffer); // TODO: estimate output size | 260 RTC_DCHECK(buffer); // TODO(grunell): estimate output size |
| 261 if (buflen <= 0) | 261 if (buflen <= 0) |
| 262 return 0; | 262 return 0; |
| 263 | 263 |
| 264 size_t srcpos = 0, bufpos = 0; | 264 size_t srcpos = 0, bufpos = 0; |
| 265 while ((srcpos < srclen) && (bufpos + 1 < buflen)) { | 265 while ((srcpos < srclen) && (bufpos + 1 < buflen)) { |
| 266 unsigned char ch = source[srcpos]; | 266 unsigned char ch = source[srcpos]; |
| 267 if (ch < 128) { | 267 if (ch < 128) { |
| 268 srcpos += 1; | 268 srcpos += 1; |
| 269 if (ASCII_CLASS[ch] & HTML_UNSAFE) { | 269 if (ASCII_CLASS[ch] & HTML_UNSAFE) { |
| 270 const char * escseq = 0; | 270 const char * escseq = 0; |
| 271 size_t esclen = 0; | 271 size_t esclen = 0; |
| 272 switch (ch) { | 272 switch (ch) { |
| 273 case '<': escseq = "<"; esclen = 4; break; | 273 case '<': escseq = "<"; esclen = 4; break; |
| 274 case '>': escseq = ">"; esclen = 4; break; | 274 case '>': escseq = ">"; esclen = 4; break; |
| 275 case '\'': escseq = "'"; esclen = 5; break; | 275 case '\'': escseq = "'"; esclen = 5; break; |
| 276 case '\"': escseq = """; esclen = 6; break; | 276 case '\"': escseq = """; esclen = 6; break; |
| 277 case '&': escseq = "&"; esclen = 5; break; | 277 case '&': escseq = "&"; esclen = 5; break; |
| 278 default: DCHECK(false); | 278 default: RTC_DCHECK(false); |
| 279 } | 279 } |
| 280 if (bufpos + esclen >= buflen) { | 280 if (bufpos + esclen >= buflen) { |
| 281 break; | 281 break; |
| 282 } | 282 } |
| 283 memcpy(buffer + bufpos, escseq, esclen); | 283 memcpy(buffer + bufpos, escseq, esclen); |
| 284 bufpos += esclen; | 284 bufpos += esclen; |
| 285 } else { | 285 } else { |
| 286 buffer[bufpos++] = ch; | 286 buffer[bufpos++] = ch; |
| 287 } | 287 } |
| 288 } else { | 288 } else { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 303 memcpy(buffer + bufpos, escseq, esclen); | 303 memcpy(buffer + bufpos, escseq, esclen); |
| 304 bufpos += esclen; | 304 bufpos += esclen; |
| 305 } | 305 } |
| 306 } | 306 } |
| 307 buffer[bufpos] = '\0'; | 307 buffer[bufpos] = '\0'; |
| 308 return bufpos; | 308 return bufpos; |
| 309 } | 309 } |
| 310 | 310 |
| 311 size_t html_decode(char * buffer, size_t buflen, | 311 size_t html_decode(char * buffer, size_t buflen, |
| 312 const char * source, size_t srclen) { | 312 const char * source, size_t srclen) { |
| 313 DCHECK(buffer); // TODO: estimate output size | 313 RTC_DCHECK(buffer); // TODO(grunell): estimate output size |
| 314 return xml_decode(buffer, buflen, source, srclen); | 314 return xml_decode(buffer, buflen, source, srclen); |
| 315 } | 315 } |
| 316 | 316 |
| 317 size_t xml_encode(char * buffer, size_t buflen, | 317 size_t xml_encode(char * buffer, size_t buflen, |
| 318 const char * source, size_t srclen) { | 318 const char * source, size_t srclen) { |
| 319 DCHECK(buffer); // TODO: estimate output size | 319 RTC_DCHECK(buffer); // TODO(grunell): estimate output size |
| 320 if (buflen <= 0) | 320 if (buflen <= 0) |
| 321 return 0; | 321 return 0; |
| 322 | 322 |
| 323 size_t srcpos = 0, bufpos = 0; | 323 size_t srcpos = 0, bufpos = 0; |
| 324 while ((srcpos < srclen) && (bufpos + 1 < buflen)) { | 324 while ((srcpos < srclen) && (bufpos + 1 < buflen)) { |
| 325 unsigned char ch = source[srcpos++]; | 325 unsigned char ch = source[srcpos++]; |
| 326 if ((ch < 128) && (ASCII_CLASS[ch] & XML_UNSAFE)) { | 326 if ((ch < 128) && (ASCII_CLASS[ch] & XML_UNSAFE)) { |
| 327 const char * escseq = 0; | 327 const char * escseq = 0; |
| 328 size_t esclen = 0; | 328 size_t esclen = 0; |
| 329 switch (ch) { | 329 switch (ch) { |
| 330 case '<': escseq = "<"; esclen = 4; break; | 330 case '<': escseq = "<"; esclen = 4; break; |
| 331 case '>': escseq = ">"; esclen = 4; break; | 331 case '>': escseq = ">"; esclen = 4; break; |
| 332 case '\'': escseq = "'"; esclen = 6; break; | 332 case '\'': escseq = "'"; esclen = 6; break; |
| 333 case '\"': escseq = """; esclen = 6; break; | 333 case '\"': escseq = """; esclen = 6; break; |
| 334 case '&': escseq = "&"; esclen = 5; break; | 334 case '&': escseq = "&"; esclen = 5; break; |
| 335 default: DCHECK(false); | 335 default: RTC_DCHECK(false); |
| 336 } | 336 } |
| 337 if (bufpos + esclen >= buflen) { | 337 if (bufpos + esclen >= buflen) { |
| 338 break; | 338 break; |
| 339 } | 339 } |
| 340 memcpy(buffer + bufpos, escseq, esclen); | 340 memcpy(buffer + bufpos, escseq, esclen); |
| 341 bufpos += esclen; | 341 bufpos += esclen; |
| 342 } else { | 342 } else { |
| 343 buffer[bufpos++] = ch; | 343 buffer[bufpos++] = ch; |
| 344 } | 344 } |
| 345 } | 345 } |
| 346 buffer[bufpos] = '\0'; | 346 buffer[bufpos] = '\0'; |
| 347 return bufpos; | 347 return bufpos; |
| 348 } | 348 } |
| 349 | 349 |
| 350 size_t xml_decode(char * buffer, size_t buflen, | 350 size_t xml_decode(char * buffer, size_t buflen, |
| 351 const char * source, size_t srclen) { | 351 const char * source, size_t srclen) { |
| 352 DCHECK(buffer); // TODO: estimate output size | 352 RTC_DCHECK(buffer); // TODO(grunell): estimate output size |
| 353 if (buflen <= 0) | 353 if (buflen <= 0) |
| 354 return 0; | 354 return 0; |
| 355 | 355 |
| 356 size_t srcpos = 0, bufpos = 0; | 356 size_t srcpos = 0, bufpos = 0; |
| 357 while ((srcpos < srclen) && (bufpos + 1 < buflen)) { | 357 while ((srcpos < srclen) && (bufpos + 1 < buflen)) { |
| 358 unsigned char ch = source[srcpos++]; | 358 unsigned char ch = source[srcpos++]; |
| 359 if (ch != '&') { | 359 if (ch != '&') { |
| 360 buffer[bufpos++] = ch; | 360 buffer[bufpos++] = ch; |
| 361 } else if ((srcpos + 2 < srclen) | 361 } else if ((srcpos + 2 < srclen) |
| 362 && (memcmp(source + srcpos, "lt;", 3) == 0)) { | 362 && (memcmp(source + srcpos, "lt;", 3) == 0)) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 378 && (memcmp(source + srcpos, "amp;", 4) == 0)) { | 378 && (memcmp(source + srcpos, "amp;", 4) == 0)) { |
| 379 buffer[bufpos++] = '&'; | 379 buffer[bufpos++] = '&'; |
| 380 srcpos += 4; | 380 srcpos += 4; |
| 381 } else if ((srcpos < srclen) && (source[srcpos] == '#')) { | 381 } else if ((srcpos < srclen) && (source[srcpos] == '#')) { |
| 382 int int_base = 10; | 382 int int_base = 10; |
| 383 if ((srcpos + 1 < srclen) && (source[srcpos+1] == 'x')) { | 383 if ((srcpos + 1 < srclen) && (source[srcpos+1] == 'x')) { |
| 384 int_base = 16; | 384 int_base = 16; |
| 385 srcpos += 1; | 385 srcpos += 1; |
| 386 } | 386 } |
| 387 char * ptr; | 387 char * ptr; |
| 388 // TODO: Fix hack (ptr may go past end of data) | 388 // TODO(grunell): Fix hack (ptr may go past end of data) |
| 389 unsigned long val = strtoul(source + srcpos + 1, &ptr, int_base); | 389 unsigned long val = strtoul(source + srcpos + 1, &ptr, int_base); |
| 390 if ((static_cast<size_t>(ptr - source) < srclen) && (*ptr == ';')) { | 390 if ((static_cast<size_t>(ptr - source) < srclen) && (*ptr == ';')) { |
| 391 srcpos = ptr - source + 1; | 391 srcpos = ptr - source + 1; |
| 392 } else { | 392 } else { |
| 393 // Not a valid escape sequence. | 393 // Not a valid escape sequence. |
| 394 break; | 394 break; |
| 395 } | 395 } |
| 396 if (size_t esclen = utf8_encode(buffer + bufpos, buflen - bufpos, val)) { | 396 if (size_t esclen = utf8_encode(buffer + bufpos, buflen - bufpos, val)) { |
| 397 bufpos += esclen; | 397 bufpos += esclen; |
| 398 } else { | 398 } else { |
| 399 // Not enough room to encode the character, or illegal character | 399 // Not enough room to encode the character, or illegal character |
| 400 break; | 400 break; |
| 401 } | 401 } |
| 402 } else { | 402 } else { |
| 403 // Unrecognized escape sequence. | 403 // Unrecognized escape sequence. |
| 404 break; | 404 break; |
| 405 } | 405 } |
| 406 } | 406 } |
| 407 buffer[bufpos] = '\0'; | 407 buffer[bufpos] = '\0'; |
| 408 return bufpos; | 408 return bufpos; |
| 409 } | 409 } |
| 410 | 410 |
| 411 static const char HEX[] = "0123456789abcdef"; | 411 static const char HEX[] = "0123456789abcdef"; |
| 412 | 412 |
| 413 char hex_encode(unsigned char val) { | 413 char hex_encode(unsigned char val) { |
| 414 DCHECK_LT(val, 16); | 414 RTC_DCHECK_LT(val, 16); |
| 415 return (val < 16) ? HEX[val] : '!'; | 415 return (val < 16) ? HEX[val] : '!'; |
| 416 } | 416 } |
| 417 | 417 |
| 418 bool hex_decode(char ch, unsigned char* val) { | 418 bool hex_decode(char ch, unsigned char* val) { |
| 419 if ((ch >= '0') && (ch <= '9')) { | 419 if ((ch >= '0') && (ch <= '9')) { |
| 420 *val = ch - '0'; | 420 *val = ch - '0'; |
| 421 } else if ((ch >= 'A') && (ch <= 'Z')) { | 421 } else if ((ch >= 'A') && (ch <= 'Z')) { |
| 422 *val = (ch - 'A') + 10; | 422 *val = (ch - 'A') + 10; |
| 423 } else if ((ch >= 'a') && (ch <= 'z')) { | 423 } else if ((ch >= 'a') && (ch <= 'z')) { |
| 424 *val = (ch - 'a') + 10; | 424 *val = (ch - 'a') + 10; |
| 425 } else { | 425 } else { |
| 426 return false; | 426 return false; |
| 427 } | 427 } |
| 428 return true; | 428 return true; |
| 429 } | 429 } |
| 430 | 430 |
| 431 size_t hex_encode(char* buffer, size_t buflen, | 431 size_t hex_encode(char* buffer, size_t buflen, |
| 432 const char* csource, size_t srclen) { | 432 const char* csource, size_t srclen) { |
| 433 return hex_encode_with_delimiter(buffer, buflen, csource, srclen, 0); | 433 return hex_encode_with_delimiter(buffer, buflen, csource, srclen, 0); |
| 434 } | 434 } |
| 435 | 435 |
| 436 size_t hex_encode_with_delimiter(char* buffer, size_t buflen, | 436 size_t hex_encode_with_delimiter(char* buffer, size_t buflen, |
| 437 const char* csource, size_t srclen, | 437 const char* csource, size_t srclen, |
| 438 char delimiter) { | 438 char delimiter) { |
| 439 DCHECK(buffer); // TODO: estimate output size | 439 RTC_DCHECK(buffer); // TODO(grunell): estimate output size |
| 440 if (buflen == 0) | 440 if (buflen == 0) |
| 441 return 0; | 441 return 0; |
| 442 | 442 |
| 443 // Init and check bounds. | 443 // Init and check bounds. |
| 444 const unsigned char* bsource = | 444 const unsigned char* bsource = |
| 445 reinterpret_cast<const unsigned char*>(csource); | 445 reinterpret_cast<const unsigned char*>(csource); |
| 446 size_t srcpos = 0, bufpos = 0; | 446 size_t srcpos = 0, bufpos = 0; |
| 447 size_t needed = delimiter ? (srclen * 3) : (srclen * 2 + 1); | 447 size_t needed = delimiter ? (srclen * 3) : (srclen * 2 + 1); |
| 448 if (buflen < needed) | 448 if (buflen < needed) |
| 449 return 0; | 449 return 0; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 473 std::string hex_encode(const char* source, size_t srclen) { | 473 std::string hex_encode(const char* source, size_t srclen) { |
| 474 return hex_encode_with_delimiter(source, srclen, 0); | 474 return hex_encode_with_delimiter(source, srclen, 0); |
| 475 } | 475 } |
| 476 | 476 |
| 477 std::string hex_encode_with_delimiter(const char* source, size_t srclen, | 477 std::string hex_encode_with_delimiter(const char* source, size_t srclen, |
| 478 char delimiter) { | 478 char delimiter) { |
| 479 const size_t kBufferSize = srclen * 3; | 479 const size_t kBufferSize = srclen * 3; |
| 480 char* buffer = STACK_ARRAY(char, kBufferSize); | 480 char* buffer = STACK_ARRAY(char, kBufferSize); |
| 481 size_t length = hex_encode_with_delimiter(buffer, kBufferSize, | 481 size_t length = hex_encode_with_delimiter(buffer, kBufferSize, |
| 482 source, srclen, delimiter); | 482 source, srclen, delimiter); |
| 483 DCHECK(srclen == 0 || length > 0); | 483 RTC_DCHECK(srclen == 0 || length > 0); |
| 484 return std::string(buffer, length); | 484 return std::string(buffer, length); |
| 485 } | 485 } |
| 486 | 486 |
| 487 size_t hex_decode(char * cbuffer, size_t buflen, | 487 size_t hex_decode(char * cbuffer, size_t buflen, |
| 488 const char * source, size_t srclen) { | 488 const char * source, size_t srclen) { |
| 489 return hex_decode_with_delimiter(cbuffer, buflen, source, srclen, 0); | 489 return hex_decode_with_delimiter(cbuffer, buflen, source, srclen, 0); |
| 490 } | 490 } |
| 491 | 491 |
| 492 size_t hex_decode_with_delimiter(char* cbuffer, size_t buflen, | 492 size_t hex_decode_with_delimiter(char* cbuffer, size_t buflen, |
| 493 const char* source, size_t srclen, | 493 const char* source, size_t srclen, |
| 494 char delimiter) { | 494 char delimiter) { |
| 495 DCHECK(cbuffer); // TODO: estimate output size | 495 RTC_DCHECK(cbuffer); // TODO(grunell): estimate output size |
| 496 if (buflen == 0) | 496 if (buflen == 0) |
| 497 return 0; | 497 return 0; |
| 498 | 498 |
| 499 // Init and bounds check. | 499 // Init and bounds check. |
| 500 unsigned char* bbuffer = reinterpret_cast<unsigned char*>(cbuffer); | 500 unsigned char* bbuffer = reinterpret_cast<unsigned char*>(cbuffer); |
| 501 size_t srcpos = 0, bufpos = 0; | 501 size_t srcpos = 0, bufpos = 0; |
| 502 size_t needed = (delimiter) ? (srclen + 1) / 3 : srclen / 2; | 502 size_t needed = (delimiter) ? (srclen + 1) / 3 : srclen / 2; |
| 503 if (buflen < needed) | 503 if (buflen < needed) |
| 504 return 0; | 504 return 0; |
| 505 | 505 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 549 // Ask transformation function to approximate the destination size (returns up
per bound) | 549 // Ask transformation function to approximate the destination size (returns up
per bound) |
| 550 size_t maxlen = t(NULL, 0, source.data(), source.length()); | 550 size_t maxlen = t(NULL, 0, source.data(), source.length()); |
| 551 char * buffer = STACK_ARRAY(char, maxlen); | 551 char * buffer = STACK_ARRAY(char, maxlen); |
| 552 size_t len = t(buffer, maxlen, source.data(), source.length()); | 552 size_t len = t(buffer, maxlen, source.data(), source.length()); |
| 553 std::string result(buffer, len); | 553 std::string result(buffer, len); |
| 554 return result; | 554 return result; |
| 555 } | 555 } |
| 556 | 556 |
| 557 size_t tokenize(const std::string& source, char delimiter, | 557 size_t tokenize(const std::string& source, char delimiter, |
| 558 std::vector<std::string>* fields) { | 558 std::vector<std::string>* fields) { |
| 559 DCHECK(fields); | 559 RTC_DCHECK(fields); |
| 560 fields->clear(); | 560 fields->clear(); |
| 561 size_t last = 0; | 561 size_t last = 0; |
| 562 for (size_t i = 0; i < source.length(); ++i) { | 562 for (size_t i = 0; i < source.length(); ++i) { |
| 563 if (source[i] == delimiter) { | 563 if (source[i] == delimiter) { |
| 564 if (i != last) { | 564 if (i != last) { |
| 565 fields->push_back(source.substr(last, i - last)); | 565 fields->push_back(source.substr(last, i - last)); |
| 566 } | 566 } |
| 567 last = i + 1; | 567 last = i + 1; |
| 568 } | 568 } |
| 569 } | 569 } |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 627 right_pos++; | 627 right_pos++; |
| 628 } | 628 } |
| 629 | 629 |
| 630 *token = source.substr(0, left_pos); | 630 *token = source.substr(0, left_pos); |
| 631 *rest = source.substr(right_pos); | 631 *rest = source.substr(right_pos); |
| 632 return true; | 632 return true; |
| 633 } | 633 } |
| 634 | 634 |
| 635 size_t split(const std::string& source, char delimiter, | 635 size_t split(const std::string& source, char delimiter, |
| 636 std::vector<std::string>* fields) { | 636 std::vector<std::string>* fields) { |
| 637 DCHECK(fields); | 637 RTC_DCHECK(fields); |
| 638 fields->clear(); | 638 fields->clear(); |
| 639 size_t last = 0; | 639 size_t last = 0; |
| 640 for (size_t i = 0; i < source.length(); ++i) { | 640 for (size_t i = 0; i < source.length(); ++i) { |
| 641 if (source[i] == delimiter) { | 641 if (source[i] == delimiter) { |
| 642 fields->push_back(source.substr(last, i - last)); | 642 fields->push_back(source.substr(last, i - last)); |
| 643 last = i + 1; | 643 last = i + 1; |
| 644 } | 644 } |
| 645 } | 645 } |
| 646 fields->push_back(source.substr(last, source.length() - last)); | 646 fields->push_back(source.substr(last, source.length() - last)); |
| 647 return fields->size(); | 647 return fields->size(); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 674 va_list args; | 674 va_list args; |
| 675 va_start(args, format); | 675 va_start(args, format); |
| 676 value.assign(buffer, vsprintfn(buffer, maxlen + 1, format, args)); | 676 value.assign(buffer, vsprintfn(buffer, maxlen + 1, format, args)); |
| 677 va_end(args); | 677 va_end(args); |
| 678 } | 678 } |
| 679 */ | 679 */ |
| 680 | 680 |
| 681 ///////////////////////////////////////////////////////////////////////////// | 681 ///////////////////////////////////////////////////////////////////////////// |
| 682 | 682 |
| 683 } // namespace rtc | 683 } // namespace rtc |
| OLD | NEW |