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