1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
// Copyright Ferdinand Majerech 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
module dyaml.escapes;
package:
import std.meta : AliasSeq;
alias escapes = AliasSeq!('0', 'a', 'b', 't', '\t', 'n', 'v', 'f', 'r', 'e', ' ',
'/', '\"', '\\', 'N', '_', 'L', 'P');
/// YAML hex codes specifying the length of the hex number.
alias escapeHexCodeList = AliasSeq!('x', 'u', 'U');
/// Convert a YAML escape to a dchar.
dchar fromEscape(dchar escape) @safe pure nothrow @nogc
{
switch(escape)
{
case '0': return '\0';
case 'a': return '\x07';
case 'b': return '\x08';
case 't': return '\x09';
case '\t': return '\x09';
case 'n': return '\x0A';
case 'v': return '\x0B';
case 'f': return '\x0C';
case 'r': return '\x0D';
case 'e': return '\x1B';
case '/': return '/';
case ' ': return '\x20';
case '\"': return '\"';
case '\\': return '\\';
case 'N': return '\x85'; //'\u0085';
case '_': return '\xA0';
case 'L': return '\u2028';
case 'P': return '\u2029';
default: assert(false, "No such YAML escape");
}
}
/**
* Convert a dchar to a YAML escape.
*
* Params:
* value = The possibly escapable character.
*
* Returns:
* If the character passed as parameter can be escaped, returns the matching
* escape, otherwise returns a null character.
*/
dchar toEscape(dchar value) @safe pure nothrow @nogc
{
switch(value)
{
case '\0': return '0';
case '\x07': return 'a';
case '\x08': return 'b';
case '\x09': return 't';
case '\x0A': return 'n';
case '\x0B': return 'v';
case '\x0C': return 'f';
case '\x0D': return 'r';
case '\x1B': return 'e';
case '\"': return '\"';
case '\\': return '\\';
case '\xA0': return '_';
case '\x85': return 'N';
case '\u2028': return 'L';
case '\u2029': return 'P';
default: return 0;
}
}
/// Get the length of a hexadecimal number determined by its hex code.
///
/// Need a function as associative arrays don't work with @nogc.
/// (And this may be even faster with a function.)
uint escapeHexLength(dchar hexCode) @safe pure nothrow @nogc
{
switch(hexCode)
{
case 'x': return 2;
case 'u': return 4;
case 'U': return 8;
default: assert(false, "No such YAML hex code");
}
}
// Issue #302: Support optional escaping of forward slashes in string
// for JSON compatibility
@safe unittest
{
import dyaml.loader : Loader;
const str = `{
"forward/slashes": "can\/be\/optionally\/escaped"
}`;
auto node = Loader.fromString(str).load();
assert(node["forward/slashes"] == "can/be/optionally/escaped");
}
|