1 module html.utils; 2 3 4 import std.ascii; 5 import std.typecons; 6 7 8 bool isAllWhite(Char)(Char[] value) { 9 auto ptr = value.ptr; 10 const end = ptr + value.length; 11 12 while (ptr != end) { 13 if (!isWhite(*ptr++)) 14 return false; 15 } 16 return true; 17 } 18 19 20 bool requiresQuotes(Char)(Char[] value) { 21 auto ptr = value.ptr; 22 const end = ptr + value.length; 23 24 while (ptr != end) { 25 switch (*ptr++) { 26 case 'a': .. case 'z': 27 case 'A': .. case 'Z': 28 case '0': .. case '9': 29 case '-': 30 case '_': 31 case '.': 32 case ':': 33 continue; 34 default: 35 return true; 36 } 37 } 38 return false; 39 } 40 41 42 bool equalsCI(CharA, CharB)(const(CharA)[] a, const(CharB)[] b) { 43 if (a.length == b.length) { 44 for (size_t i; i < a.length; ++i) { 45 if (std.ascii.toLower(a.ptr[i]) != std.ascii.toLower(b.ptr[i])) 46 return false; 47 } 48 return true; 49 } 50 return false; 51 } 52 53 54 enum QuickHash64Seed = 14695981039346656037u; 55 enum QuickHash64Scale = 1099511628211u; 56 57 58 ulong quickHash64(const(char)* p, const(char)* pend, ulong hash = QuickHash64Seed) { 59 while (p != pend) 60 hash = (hash ^ cast(ulong)(*p++)) * QuickHash64Scale; 61 return hash; 62 } 63 64 65 ulong quickHash64i(const(char)* p, const(char)* pend, ulong hash = QuickHash64Seed) { 66 while (p != pend) 67 hash = (hash ^ cast(ulong)(std.ascii.toLower(*p++))) * QuickHash64Scale; 68 return hash; 69 } 70 71 72 hash_t quickHashOf(const(char)[] x) { 73 return cast(hash_t)quickHash64(x.ptr, x.ptr + x.length); 74 } 75 76 77 hash_t tagHashOf(const(char)[] x) { 78 return cast(hash_t)quickHash64i(x.ptr, x.ptr + x.length); 79 } 80 81 82 void writeQuotesEscaped(Appender)(ref Appender app, const(char)[] x) { 83 auto ptr = x.ptr; 84 const end = x.ptr + x.length; 85 86 while (ptr != end) { 87 const ch = *ptr++; 88 if (ch != '"') { 89 app.put(ch); 90 } else { 91 app.put("""); // shorter than " 92 } 93 } 94 } 95 96 97 void writeHTMLEscaped(Flag!q{escapeQuotes} escapeQuotes, Appender)(ref Appender app, const(char)[] x) { 98 auto ptr = x.ptr; 99 const end = x.ptr + x.length; 100 101 while (ptr != end) { 102 const ch = *ptr++; 103 switch (ch) { 104 static if (escapeQuotes) { 105 case '"': 106 app.put("""); // shorter than " 107 break; 108 } 109 case '<': 110 app.put("<"); 111 break; 112 case '>': 113 app.put(">"); 114 break; 115 case '&': 116 app.put("&"); 117 break; 118 default: 119 app.put(ch); 120 break; 121 } 122 } 123 }