1f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org/* 2f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * Copyright 2004 The WebRTC Project Authors. All rights reserved. 3f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * 4f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * Use of this source code is governed by a BSD-style license 5f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * that can be found in the LICENSE file in the root of the source 6f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * tree. An additional intellectual property rights grant can be found 7f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * in the file PATENTS. All contributing project authors may 8f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org */ 10f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 11f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/stringencode.h" 12f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 13f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include <stdio.h> 14f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include <stdlib.h> 15f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 16f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/basictypes.h" 176ae5a6d7fefff6759d338b5a3e3613e050ebaa62andrew@webrtc.org#include "webrtc/base/checks.h" 18f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/stringutils.h" 19f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 20f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgnamespace rtc { 21f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 22f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org///////////////////////////////////////////////////////////////////////////// 23f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// String Encoding Utilities 24f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org///////////////////////////////////////////////////////////////////////////// 25f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 26f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgsize_t escape(char * buffer, size_t buflen, 27f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const char * source, size_t srclen, 28f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const char * illegal, char escape) { 2991d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(buffer); // TODO(grunell): estimate output size 30f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (buflen <= 0) 31f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 32f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 33f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org size_t srcpos = 0, bufpos = 0; 34f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org while ((srcpos < srclen) && (bufpos + 1 < buflen)) { 35f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org char ch = source[srcpos++]; 36f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if ((ch == escape) || ::strchr(illegal, ch)) { 37f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (bufpos + 2 >= buflen) 38f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org break; 39f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[bufpos++] = escape; 40f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 41f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[bufpos++] = ch; 42f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 43f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 44f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[bufpos] = '\0'; 45f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return bufpos; 46f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 47f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 48f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgsize_t unescape(char * buffer, size_t buflen, 49f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const char * source, size_t srclen, 50f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org char escape) { 5191d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(buffer); // TODO(grunell): estimate output size 52f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (buflen <= 0) 53f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 54f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 55f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org size_t srcpos = 0, bufpos = 0; 56f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org while ((srcpos < srclen) && (bufpos + 1 < buflen)) { 57f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org char ch = source[srcpos++]; 58f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if ((ch == escape) && (srcpos < srclen)) { 59f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ch = source[srcpos++]; 60f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 61f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[bufpos++] = ch; 62f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 63f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[bufpos] = '\0'; 64f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return bufpos; 65f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 66f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 67f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgsize_t encode(char * buffer, size_t buflen, 68f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const char * source, size_t srclen, 69f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const char * illegal, char escape) { 7091d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(buffer); // TODO(grunell): estimate output size 71f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (buflen <= 0) 72f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 73f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 74f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org size_t srcpos = 0, bufpos = 0; 75f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org while ((srcpos < srclen) && (bufpos + 1 < buflen)) { 76f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org char ch = source[srcpos++]; 77f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if ((ch != escape) && !::strchr(illegal, ch)) { 78f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[bufpos++] = ch; 79f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else if (bufpos + 3 >= buflen) { 80f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org break; 81f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 82f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[bufpos+0] = escape; 83f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[bufpos+1] = hex_encode((static_cast<unsigned char>(ch) >> 4) & 0xF); 84f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[bufpos+2] = hex_encode((static_cast<unsigned char>(ch) ) & 0xF); 85f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org bufpos += 3; 86f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 87f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 88f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[bufpos] = '\0'; 89f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return bufpos; 90f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 91f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 92f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgsize_t decode(char * buffer, size_t buflen, 93f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const char * source, size_t srclen, 94f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org char escape) { 95f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (buflen <= 0) 96f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 97f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 98f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org unsigned char h1, h2; 99f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org size_t srcpos = 0, bufpos = 0; 100f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org while ((srcpos < srclen) && (bufpos + 1 < buflen)) { 101f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org char ch = source[srcpos++]; 102f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if ((ch == escape) 103f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org && (srcpos + 1 < srclen) 104f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org && hex_decode(source[srcpos], &h1) 105f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org && hex_decode(source[srcpos+1], &h2)) { 106f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[bufpos++] = (h1 << 4) | h2; 107f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org srcpos += 2; 108f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 109f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[bufpos++] = ch; 110f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 111f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 112f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[bufpos] = '\0'; 113f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return bufpos; 114f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 115f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 116f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgconst char* unsafe_filename_characters() { 117f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // It might be better to have a single specification which is the union of 118f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // all operating systems, unless one system is overly restrictive. 119f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#if defined(WEBRTC_WIN) 120f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return "\\/:*?\"<>|"; 1216ae5a6d7fefff6759d338b5a3e3613e050ebaa62andrew@webrtc.org#else // !WEBRTC_WIN 12291d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg // TODO(grunell): Should this never be reached? 12391d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(false); 124f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return ""; 125f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif // !WEBRTC_WIN 126f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 127f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 128f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgconst unsigned char URL_UNSAFE = 0x1; // 0-33 "#$%&+,/:;<=>?@[\]^`{|} 127 129f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgconst unsigned char XML_UNSAFE = 0x2; // "&'<> 130f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgconst unsigned char HTML_UNSAFE = 0x2; // "&'<> 131f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 132f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 6 5 7 8 9 : ; < = > ? 133f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//@ 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 [ \ ] ^ _ 134f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//` 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 { | } ~ 135f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 136f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgconst unsigned char ASCII_CLASS[128] = { 137f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 138f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 1,0,3,1,1,1,3,2,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,3,1,3,1, 139f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0, 140f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1, 141f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}; 142f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 143f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgsize_t url_encode(char * buffer, size_t buflen, 144f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const char * source, size_t srclen) { 145f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (NULL == buffer) 146f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return srclen * 3 + 1; 147f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (buflen <= 0) 148f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 149f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 150f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org size_t srcpos = 0, bufpos = 0; 151f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org while ((srcpos < srclen) && (bufpos + 1 < buflen)) { 152f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org unsigned char ch = source[srcpos++]; 153f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if ((ch < 128) && (ASCII_CLASS[ch] & URL_UNSAFE)) { 154f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (bufpos + 3 >= buflen) { 155f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org break; 156f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 157f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[bufpos+0] = '%'; 158f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[bufpos+1] = hex_encode((ch >> 4) & 0xF); 159f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[bufpos+2] = hex_encode((ch ) & 0xF); 160f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org bufpos += 3; 161f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 162f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[bufpos++] = ch; 163f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 164f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 165f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[bufpos] = '\0'; 166f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return bufpos; 167f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 168f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 169f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgsize_t url_decode(char * buffer, size_t buflen, 170f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const char * source, size_t srclen) { 171f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (NULL == buffer) 172f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return srclen + 1; 173f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (buflen <= 0) 174f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 175f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 176f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org unsigned char h1, h2; 177f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org size_t srcpos = 0, bufpos = 0; 178f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org while ((srcpos < srclen) && (bufpos + 1 < buflen)) { 179f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org unsigned char ch = source[srcpos++]; 180f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (ch == '+') { 181f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[bufpos++] = ' '; 182f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else if ((ch == '%') 183f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org && (srcpos + 1 < srclen) 184f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org && hex_decode(source[srcpos], &h1) 185f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org && hex_decode(source[srcpos+1], &h2)) 186f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org { 187f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[bufpos++] = (h1 << 4) | h2; 188f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org srcpos += 2; 189f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 190f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[bufpos++] = ch; 191f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 192f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 193f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[bufpos] = '\0'; 194f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return bufpos; 195f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 196f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 197f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgsize_t utf8_decode(const char* source, size_t srclen, unsigned long* value) { 198f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const unsigned char* s = reinterpret_cast<const unsigned char*>(source); 199f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if ((s[0] & 0x80) == 0x00) { // Check s[0] == 0xxxxxxx 200f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *value = s[0]; 201f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 1; 202f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 203f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if ((srclen < 2) || ((s[1] & 0xC0) != 0x80)) { // Check s[1] != 10xxxxxx 204f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 205f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 206f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Accumulate the trailer byte values in value16, and combine it with the 207f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // relevant bits from s[0], once we've determined the sequence length. 208f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org unsigned long value16 = (s[1] & 0x3F); 209f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if ((s[0] & 0xE0) == 0xC0) { // Check s[0] == 110xxxxx 210f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *value = ((s[0] & 0x1F) << 6) | value16; 211f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 2; 212f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 213f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if ((srclen < 3) || ((s[2] & 0xC0) != 0x80)) { // Check s[2] != 10xxxxxx 214f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 215f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 216f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org value16 = (value16 << 6) | (s[2] & 0x3F); 217f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if ((s[0] & 0xF0) == 0xE0) { // Check s[0] == 1110xxxx 218f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *value = ((s[0] & 0x0F) << 12) | value16; 219f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 3; 220f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 221f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if ((srclen < 4) || ((s[3] & 0xC0) != 0x80)) { // Check s[3] != 10xxxxxx 222f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 223f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 224f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org value16 = (value16 << 6) | (s[3] & 0x3F); 225f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if ((s[0] & 0xF8) == 0xF0) { // Check s[0] == 11110xxx 226f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *value = ((s[0] & 0x07) << 18) | value16; 227f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 4; 228f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 229f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 230f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 231f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 232f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgsize_t utf8_encode(char* buffer, size_t buflen, unsigned long value) { 233f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if ((value <= 0x7F) && (buflen >= 1)) { 234f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[0] = static_cast<unsigned char>(value); 235f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 1; 236f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 237f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if ((value <= 0x7FF) && (buflen >= 2)) { 238f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[0] = 0xC0 | static_cast<unsigned char>(value >> 6); 239f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[1] = 0x80 | static_cast<unsigned char>(value & 0x3F); 240f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 2; 241f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 242f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if ((value <= 0xFFFF) && (buflen >= 3)) { 243f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[0] = 0xE0 | static_cast<unsigned char>(value >> 12); 244f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[1] = 0x80 | static_cast<unsigned char>((value >> 6) & 0x3F); 245f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[2] = 0x80 | static_cast<unsigned char>(value & 0x3F); 246f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 3; 247f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 248f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if ((value <= 0x1FFFFF) && (buflen >= 4)) { 249f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[0] = 0xF0 | static_cast<unsigned char>(value >> 18); 250f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[1] = 0x80 | static_cast<unsigned char>((value >> 12) & 0x3F); 251f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[2] = 0x80 | static_cast<unsigned char>((value >> 6) & 0x3F); 252f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[3] = 0x80 | static_cast<unsigned char>(value & 0x3F); 253f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 4; 254f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 255f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 256f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 257f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 258f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgsize_t html_encode(char * buffer, size_t buflen, 259f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const char * source, size_t srclen) { 26091d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(buffer); // TODO(grunell): estimate output size 261f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (buflen <= 0) 262f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 263f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 264f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org size_t srcpos = 0, bufpos = 0; 265f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org while ((srcpos < srclen) && (bufpos + 1 < buflen)) { 266f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org unsigned char ch = source[srcpos]; 267f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (ch < 128) { 268f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org srcpos += 1; 269f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (ASCII_CLASS[ch] & HTML_UNSAFE) { 270f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const char * escseq = 0; 271f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org size_t esclen = 0; 272f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org switch (ch) { 273f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case '<': escseq = "<"; esclen = 4; break; 274f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case '>': escseq = ">"; esclen = 4; break; 275f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case '\'': escseq = "'"; esclen = 5; break; 276f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case '\"': escseq = """; esclen = 6; break; 277f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case '&': escseq = "&"; esclen = 5; break; 27891d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg default: RTC_DCHECK(false); 279f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 280f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (bufpos + esclen >= buflen) { 281f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org break; 282f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 283f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org memcpy(buffer + bufpos, escseq, esclen); 284f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org bufpos += esclen; 285f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 286f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[bufpos++] = ch; 287f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 288f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 289f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Largest value is 0x1FFFFF => � (10 characters) 2906ae5a6d7fefff6759d338b5a3e3613e050ebaa62andrew@webrtc.org const size_t kEscseqSize = 11; 2916ae5a6d7fefff6759d338b5a3e3613e050ebaa62andrew@webrtc.org char escseq[kEscseqSize]; 292f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org unsigned long val; 293f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (size_t vallen = utf8_decode(&source[srcpos], srclen - srcpos, &val)) { 294f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org srcpos += vallen; 295f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 296f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Not a valid utf8 sequence, just use the raw character. 297f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org val = static_cast<unsigned char>(source[srcpos++]); 298f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 2996ae5a6d7fefff6759d338b5a3e3613e050ebaa62andrew@webrtc.org size_t esclen = sprintfn(escseq, kEscseqSize, "&#%lu;", val); 300f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (bufpos + esclen >= buflen) { 301f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org break; 302f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 303f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org memcpy(buffer + bufpos, escseq, esclen); 304f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org bufpos += esclen; 305f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 306f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 307f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[bufpos] = '\0'; 308f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return bufpos; 309f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 310f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 311f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgsize_t html_decode(char * buffer, size_t buflen, 312f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const char * source, size_t srclen) { 31391d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(buffer); // TODO(grunell): estimate output size 314f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return xml_decode(buffer, buflen, source, srclen); 315f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 316f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 317f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgsize_t xml_encode(char * buffer, size_t buflen, 318f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const char * source, size_t srclen) { 31991d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(buffer); // TODO(grunell): estimate output size 320f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (buflen <= 0) 321f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 322f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 323f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org size_t srcpos = 0, bufpos = 0; 324f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org while ((srcpos < srclen) && (bufpos + 1 < buflen)) { 325f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org unsigned char ch = source[srcpos++]; 326f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if ((ch < 128) && (ASCII_CLASS[ch] & XML_UNSAFE)) { 327f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const char * escseq = 0; 328f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org size_t esclen = 0; 329f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org switch (ch) { 330f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case '<': escseq = "<"; esclen = 4; break; 331f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case '>': escseq = ">"; esclen = 4; break; 332f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case '\'': escseq = "'"; esclen = 6; break; 333f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case '\"': escseq = """; esclen = 6; break; 334f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case '&': escseq = "&"; esclen = 5; break; 33591d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg default: RTC_DCHECK(false); 336f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 337f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (bufpos + esclen >= buflen) { 338f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org break; 339f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 340f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org memcpy(buffer + bufpos, escseq, esclen); 341f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org bufpos += esclen; 342f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 343f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[bufpos++] = ch; 344f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 345f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 346f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[bufpos] = '\0'; 347f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return bufpos; 348f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 349f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 350f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgsize_t xml_decode(char * buffer, size_t buflen, 351f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const char * source, size_t srclen) { 35291d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(buffer); // TODO(grunell): estimate output size 353f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (buflen <= 0) 354f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 355f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 356f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org size_t srcpos = 0, bufpos = 0; 357f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org while ((srcpos < srclen) && (bufpos + 1 < buflen)) { 358f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org unsigned char ch = source[srcpos++]; 359f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (ch != '&') { 360f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[bufpos++] = ch; 361f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else if ((srcpos + 2 < srclen) 362f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org && (memcmp(source + srcpos, "lt;", 3) == 0)) { 363f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[bufpos++] = '<'; 364f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org srcpos += 3; 365f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else if ((srcpos + 2 < srclen) 366f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org && (memcmp(source + srcpos, "gt;", 3) == 0)) { 367f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[bufpos++] = '>'; 368f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org srcpos += 3; 369f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else if ((srcpos + 4 < srclen) 370f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org && (memcmp(source + srcpos, "apos;", 5) == 0)) { 371f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[bufpos++] = '\''; 372f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org srcpos += 5; 373f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else if ((srcpos + 4 < srclen) 374f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org && (memcmp(source + srcpos, "quot;", 5) == 0)) { 375f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[bufpos++] = '\"'; 376f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org srcpos += 5; 377f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else if ((srcpos + 3 < srclen) 378f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org && (memcmp(source + srcpos, "amp;", 4) == 0)) { 379f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[bufpos++] = '&'; 380f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org srcpos += 4; 381f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else if ((srcpos < srclen) && (source[srcpos] == '#')) { 382f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int int_base = 10; 383f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if ((srcpos + 1 < srclen) && (source[srcpos+1] == 'x')) { 384f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int_base = 16; 385f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org srcpos += 1; 386f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 387f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org char * ptr; 38891d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg // TODO(grunell): Fix hack (ptr may go past end of data) 389f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org unsigned long val = strtoul(source + srcpos + 1, &ptr, int_base); 390f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if ((static_cast<size_t>(ptr - source) < srclen) && (*ptr == ';')) { 391f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org srcpos = ptr - source + 1; 392f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 393f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Not a valid escape sequence. 394f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org break; 395f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 396f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (size_t esclen = utf8_encode(buffer + bufpos, buflen - bufpos, val)) { 397f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org bufpos += esclen; 398f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 399f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Not enough room to encode the character, or illegal character 400f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org break; 401f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 402f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 403f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Unrecognized escape sequence. 404f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org break; 405f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 406f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 407f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[bufpos] = '\0'; 408f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return bufpos; 409f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 410f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 411f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstatic const char HEX[] = "0123456789abcdef"; 412f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 413f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgchar hex_encode(unsigned char val) { 41491d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK_LT(val, 16); 415f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return (val < 16) ? HEX[val] : '!'; 416f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 417f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 418f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgbool hex_decode(char ch, unsigned char* val) { 419f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if ((ch >= '0') && (ch <= '9')) { 420f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *val = ch - '0'; 421f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else if ((ch >= 'A') && (ch <= 'Z')) { 422f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *val = (ch - 'A') + 10; 423f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else if ((ch >= 'a') && (ch <= 'z')) { 424f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *val = (ch - 'a') + 10; 425f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 426f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return false; 427f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 428f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return true; 429f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 430f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 431f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgsize_t hex_encode(char* buffer, size_t buflen, 432f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const char* csource, size_t srclen) { 433f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return hex_encode_with_delimiter(buffer, buflen, csource, srclen, 0); 434f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 435f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 436f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgsize_t hex_encode_with_delimiter(char* buffer, size_t buflen, 437f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const char* csource, size_t srclen, 438f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org char delimiter) { 43991d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(buffer); // TODO(grunell): estimate output size 440f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (buflen == 0) 441f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 442f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 443f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Init and check bounds. 444f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const unsigned char* bsource = 445f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org reinterpret_cast<const unsigned char*>(csource); 446f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org size_t srcpos = 0, bufpos = 0; 447f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org size_t needed = delimiter ? (srclen * 3) : (srclen * 2 + 1); 448f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (buflen < needed) 449f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 450f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 451f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org while (srcpos < srclen) { 452f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org unsigned char ch = bsource[srcpos++]; 453f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[bufpos ] = hex_encode((ch >> 4) & 0xF); 454f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[bufpos+1] = hex_encode((ch ) & 0xF); 455f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org bufpos += 2; 456f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 457f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Don't write a delimiter after the last byte. 458f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (delimiter && (srcpos < srclen)) { 459f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[bufpos] = delimiter; 460f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ++bufpos; 461f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 462f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 463f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 464f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Null terminate. 465f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer[bufpos] = '\0'; 466f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return bufpos; 467f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 468f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 4691cf6f8101ae9db517332783e99c98e14ff4c47e1Peter Thatcherstd::string hex_encode(const std::string& str) { 4701cf6f8101ae9db517332783e99c98e14ff4c47e1Peter Thatcher return hex_encode(str.c_str(), str.size()); 4711cf6f8101ae9db517332783e99c98e14ff4c47e1Peter Thatcher} 4721cf6f8101ae9db517332783e99c98e14ff4c47e1Peter Thatcher 473f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstd::string hex_encode(const char* source, size_t srclen) { 474f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return hex_encode_with_delimiter(source, srclen, 0); 475f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 476f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 477f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstd::string hex_encode_with_delimiter(const char* source, size_t srclen, 478f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org char delimiter) { 479f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const size_t kBufferSize = srclen * 3; 480f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org char* buffer = STACK_ARRAY(char, kBufferSize); 481f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org size_t length = hex_encode_with_delimiter(buffer, kBufferSize, 482f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org source, srclen, delimiter); 48391d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(srclen == 0 || length > 0); 484f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return std::string(buffer, length); 485f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 486f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 487f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgsize_t hex_decode(char * cbuffer, size_t buflen, 488f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const char * source, size_t srclen) { 489f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return hex_decode_with_delimiter(cbuffer, buflen, source, srclen, 0); 490f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 491f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 492f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgsize_t hex_decode_with_delimiter(char* cbuffer, size_t buflen, 493f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const char* source, size_t srclen, 494f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org char delimiter) { 49591d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(cbuffer); // TODO(grunell): estimate output size 496f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (buflen == 0) 497f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 498f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 499f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Init and bounds check. 500f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org unsigned char* bbuffer = reinterpret_cast<unsigned char*>(cbuffer); 501f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org size_t srcpos = 0, bufpos = 0; 502f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org size_t needed = (delimiter) ? (srclen + 1) / 3 : srclen / 2; 503f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (buflen < needed) 504f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 505f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 506f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org while (srcpos < srclen) { 507f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if ((srclen - srcpos) < 2) { 508f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // This means we have an odd number of bytes. 509f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 510f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 511f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 512f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org unsigned char h1, h2; 513f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (!hex_decode(source[srcpos], &h1) || 514f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org !hex_decode(source[srcpos + 1], &h2)) 515f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 516f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 517f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org bbuffer[bufpos++] = (h1 << 4) | h2; 518f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org srcpos += 2; 519f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 520f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Remove the delimiter if needed. 521f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (delimiter && (srclen - srcpos) > 1) { 522f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (source[srcpos] != delimiter) 523f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 524f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ++srcpos; 525f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 526f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 527f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 528f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return bufpos; 529f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 530f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 531f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgsize_t hex_decode(char* buffer, size_t buflen, const std::string& source) { 532f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return hex_decode_with_delimiter(buffer, buflen, source, 0); 533f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 534f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgsize_t hex_decode_with_delimiter(char* buffer, size_t buflen, 535f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const std::string& source, char delimiter) { 536f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return hex_decode_with_delimiter(buffer, buflen, 537f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org source.c_str(), source.length(), delimiter); 538f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 539f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 540f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgsize_t transform(std::string& value, size_t maxlen, const std::string& source, 541f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Transform t) { 542f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org char* buffer = STACK_ARRAY(char, maxlen + 1); 543f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org size_t length = t(buffer, maxlen + 1, source.data(), source.length()); 544f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org value.assign(buffer, length); 545f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return length; 546f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 547f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 548f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstd::string s_transform(const std::string& source, Transform t) { 549f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Ask transformation function to approximate the destination size (returns upper bound) 550f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org size_t maxlen = t(NULL, 0, source.data(), source.length()); 551f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org char * buffer = STACK_ARRAY(char, maxlen); 552f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org size_t len = t(buffer, maxlen, source.data(), source.length()); 553f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org std::string result(buffer, len); 554f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return result; 555f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 556f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 557f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgsize_t tokenize(const std::string& source, char delimiter, 558f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org std::vector<std::string>* fields) { 559f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org fields->clear(); 560f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org size_t last = 0; 561f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org for (size_t i = 0; i < source.length(); ++i) { 562f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (source[i] == delimiter) { 563f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (i != last) { 564f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org fields->push_back(source.substr(last, i - last)); 565f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 566f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org last = i + 1; 567f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 568f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 569f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (last != source.length()) { 570f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org fields->push_back(source.substr(last, source.length() - last)); 571f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 572f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return fields->size(); 573f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 574f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 5750a6c4ca942f3a25c15c7af64a9515d381c34cd9cdeadbeefsize_t tokenize_with_empty_tokens(const std::string& source, 5760a6c4ca942f3a25c15c7af64a9515d381c34cd9cdeadbeef char delimiter, 5770a6c4ca942f3a25c15c7af64a9515d381c34cd9cdeadbeef std::vector<std::string>* fields) { 5780a6c4ca942f3a25c15c7af64a9515d381c34cd9cdeadbeef fields->clear(); 5790a6c4ca942f3a25c15c7af64a9515d381c34cd9cdeadbeef size_t last = 0; 5800a6c4ca942f3a25c15c7af64a9515d381c34cd9cdeadbeef for (size_t i = 0; i < source.length(); ++i) { 5810a6c4ca942f3a25c15c7af64a9515d381c34cd9cdeadbeef if (source[i] == delimiter) { 5820a6c4ca942f3a25c15c7af64a9515d381c34cd9cdeadbeef fields->push_back(source.substr(last, i - last)); 5830a6c4ca942f3a25c15c7af64a9515d381c34cd9cdeadbeef last = i + 1; 5840a6c4ca942f3a25c15c7af64a9515d381c34cd9cdeadbeef } 5850a6c4ca942f3a25c15c7af64a9515d381c34cd9cdeadbeef } 5860a6c4ca942f3a25c15c7af64a9515d381c34cd9cdeadbeef fields->push_back(source.substr(last, source.length() - last)); 5870a6c4ca942f3a25c15c7af64a9515d381c34cd9cdeadbeef return fields->size(); 5880a6c4ca942f3a25c15c7af64a9515d381c34cd9cdeadbeef} 5890a6c4ca942f3a25c15c7af64a9515d381c34cd9cdeadbeef 590f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgsize_t tokenize_append(const std::string& source, char delimiter, 591f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org std::vector<std::string>* fields) { 592f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (!fields) return 0; 593f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 594f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org std::vector<std::string> new_fields; 595f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org tokenize(source, delimiter, &new_fields); 596f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org fields->insert(fields->end(), new_fields.begin(), new_fields.end()); 597f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return fields->size(); 598f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 599f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 600f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgsize_t tokenize(const std::string& source, char delimiter, char start_mark, 601f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org char end_mark, std::vector<std::string>* fields) { 602f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (!fields) return 0; 603f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org fields->clear(); 604f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 605f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org std::string remain_source = source; 606f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org while (!remain_source.empty()) { 607f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org size_t start_pos = remain_source.find(start_mark); 608f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (std::string::npos == start_pos) break; 609f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org std::string pre_mark; 610f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (start_pos > 0) { 611f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org pre_mark = remain_source.substr(0, start_pos - 1); 612f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 613f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 614f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ++start_pos; 615f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org size_t end_pos = remain_source.find(end_mark, start_pos); 616f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (std::string::npos == end_pos) break; 617f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 618f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // We have found the matching marks. First tokenize the pre-mask. Then add 619f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // the marked part as a single field. Finally, loop back for the post-mark. 620f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org tokenize_append(pre_mark, delimiter, fields); 621f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org fields->push_back(remain_source.substr(start_pos, end_pos - start_pos)); 622f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org remain_source = remain_source.substr(end_pos + 1); 623f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 624f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 625f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return tokenize_append(remain_source, delimiter, fields); 626f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 627f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 628144d01850bd3e07222d3f8696debec689dcdccf5Donald Curtisbool tokenize_first(const std::string& source, 629144d01850bd3e07222d3f8696debec689dcdccf5Donald Curtis const char delimiter, 630144d01850bd3e07222d3f8696debec689dcdccf5Donald Curtis std::string* token, 631144d01850bd3e07222d3f8696debec689dcdccf5Donald Curtis std::string* rest) { 6320e07f92043b333acfdaed8f22da5df903a70e0e9Donald Curtis // Find the first delimiter 6330e07f92043b333acfdaed8f22da5df903a70e0e9Donald Curtis size_t left_pos = source.find(delimiter); 6340e07f92043b333acfdaed8f22da5df903a70e0e9Donald Curtis if (left_pos == std::string::npos) { 6350e07f92043b333acfdaed8f22da5df903a70e0e9Donald Curtis return false; 6360e07f92043b333acfdaed8f22da5df903a70e0e9Donald Curtis } 6370e07f92043b333acfdaed8f22da5df903a70e0e9Donald Curtis 6380e07f92043b333acfdaed8f22da5df903a70e0e9Donald Curtis // Look for additional occurrances of delimiter. 6390e07f92043b333acfdaed8f22da5df903a70e0e9Donald Curtis size_t right_pos = left_pos + 1; 640144d01850bd3e07222d3f8696debec689dcdccf5Donald Curtis while (source[right_pos] == delimiter) { 6410e07f92043b333acfdaed8f22da5df903a70e0e9Donald Curtis right_pos++; 6420e07f92043b333acfdaed8f22da5df903a70e0e9Donald Curtis } 6430e07f92043b333acfdaed8f22da5df903a70e0e9Donald Curtis 6440e07f92043b333acfdaed8f22da5df903a70e0e9Donald Curtis *token = source.substr(0, left_pos); 6450e07f92043b333acfdaed8f22da5df903a70e0e9Donald Curtis *rest = source.substr(right_pos); 6460e07f92043b333acfdaed8f22da5df903a70e0e9Donald Curtis return true; 6470e07f92043b333acfdaed8f22da5df903a70e0e9Donald Curtis} 6480e07f92043b333acfdaed8f22da5df903a70e0e9Donald Curtis 649f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgsize_t split(const std::string& source, char delimiter, 650f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org std::vector<std::string>* fields) { 65191d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(fields); 652f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org fields->clear(); 653f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org size_t last = 0; 654f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org for (size_t i = 0; i < source.length(); ++i) { 655f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (source[i] == delimiter) { 656f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org fields->push_back(source.substr(last, i - last)); 657f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org last = i + 1; 658f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 659f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 660f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org fields->push_back(source.substr(last, source.length() - last)); 661f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return fields->size(); 662f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 663f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 664f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgchar make_char_safe_for_filename(char c) { 665f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (c < 32) 666f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return '_'; 667f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 668f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org switch (c) { 669f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case '<': 670f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case '>': 671f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case ':': 672f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case '"': 673f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case '/': 674f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case '\\': 675f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case '|': 676f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case '*': 677f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case '?': 678f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return '_'; 679f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 680f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org default: 681f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return c; 682f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 683f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 684f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 685f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org/* 686f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid sprintf(std::string& value, size_t maxlen, const char * format, ...) { 687f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org char * buffer = STACK_ARRAY(char, maxlen + 1); 688f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org va_list args; 689f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org va_start(args, format); 690f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org value.assign(buffer, vsprintfn(buffer, maxlen + 1, format, args)); 691f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org va_end(args); 692f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 693f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org*/ 694f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 695f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org///////////////////////////////////////////////////////////////////////////// 696f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 697f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} // namespace rtc 698