1 //this file is part of MimeTools (plugin for Notepad++) 2 //Copyright (C)2019 Don HO <don.h@free.fr> 3 // 4 //This program is free software; you can redistribute it and/or 5 //modify it under the terms of the GNU General Public License 6 //as published by the Free Software Foundation; either 7 //version 2 of the License, or (at your option) any later version. 8 // 9 //This program is distributed in the hope that it will be useful, 10 //but WITHOUT ANY WARRANTY; without even the implied warranty of 11 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 //GNU General Public License for more details. 13 // 14 //You should have received a copy of the GNU General Public License 15 //along with this program; if not, write to the Free Software 16 //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17 module npp_mimetools.url; 18 19 20 private static import core.stdc.ctype; 21 private static import core.stdc.string; 22 23 // These characters must be encoded in a URL, as per RFC1738 24 enum gReservedAscii = "<>\"#%{}|\\^~[]`;/?:@=& "; 25 enum gHexChar = "0123456789ABCDEF"; 26 27 pure nothrow @nogc 28 size_t AsciiToUrl(ref char[] dest, const char[] src, bool encodeAll) 29 30 in 31 { 32 assert(dest.length > 2); 33 } 34 35 do 36 { 37 size_t i = 0; 38 size_t k = 0; 39 size_t l = 0; 40 size_t end_length = dest.length - 2; 41 dest[] = '\0'; 42 43 for (; (i < end_length) && ((l < src.length) && (src[l] != '\0')); ++i, ++l) { 44 // Encode source if it is a reserved or non-printable character. 45 if (encodeAll || (core.stdc..string.strchr(&(.gReservedAscii[0]), src[l]) != null) || !core.stdc.ctype.isprint(src[l])) { 46 dest[k++] = '%'; 47 dest[k++] = .gHexChar[((src[l] >> 4) & 0x0F)]; 48 dest[k++] = .gHexChar[(src[l] & 0x0F)]; 49 i += 2; 50 } else { 51 // don't encode character 52 dest[k++] = src[l]; 53 } 54 } 55 56 // return characters stored to destination 57 return i; 58 } 59 60 pure nothrow @safe @nogc 61 size_t UrlToAscii(ref char[] dest, const char[] src) 62 63 do 64 { 65 size_t i = 0; 66 size_t l = 0; 67 dest[] = '\0'; 68 69 for (i = 0; (i < dest.length) && ((l < src.length) && (src[l] != '\0')); ++i) { 70 if (src[l] == '%') { 71 ++l; 72 73 if (l >= (src.length - 1)) { 74 return 0; 75 } 76 77 // Found an encoded triplet. 78 // The next two characters must be hex. 79 if (core.stdc.ctype.isxdigit(src[l]) && core.stdc.ctype.isxdigit(src[l + 1])) { 80 char val = 0; 81 size_t j = 0; 82 83 for (; j < 2; ++j, ++l) { 84 val <<= 4; 85 86 if (l >= src.length) { 87 return 0; 88 } 89 90 if (core.stdc.ctype.isdigit(src[l])) { 91 val += src[l] - '0'; 92 } else if (core.stdc.ctype.isupper(src[l])) { 93 val += src[l] - 'A' + 10; 94 } else { 95 val += src[l] - 'a' + 10; 96 } 97 } 98 99 dest[i] = val; 100 } else { 101 // invalid encoding 102 return 0; 103 } 104 } else { 105 // non-encoded character, so just copy it 106 dest[i] = src[l]; 107 ++l; 108 } 109 } 110 111 return i; 112 }