scide: implement selectionLength for openDocument
[supercollider.git] / external_libraries / yaml-cpp-0.3.0 / src / exp.cpp
blob7bc545466fa6f9b13b895467c50d28f4fddbaf9a
1 #include "exp.h"
2 #include "yaml-cpp/exceptions.h"
3 #include <sstream>
5 namespace YAML
7 namespace Exp
9 unsigned ParseHex(const std::string& str, const Mark& mark)
11 unsigned value = 0;
12 for(std::size_t i=0;i<str.size();i++) {
13 char ch = str[i];
14 int digit = 0;
15 if('a' <= ch && ch <= 'f')
16 digit = ch - 'a' + 10;
17 else if('A' <= ch && ch <= 'F')
18 digit = ch - 'A' + 10;
19 else if('0' <= ch && ch <= '9')
20 digit = ch - '0';
21 else
22 throw ParserException(mark, ErrorMsg::INVALID_HEX);
24 value = (value << 4) + digit;
27 return value;
30 std::string Str(unsigned ch)
32 return std::string(1, static_cast<char>(ch));
35 // Escape
36 // . Translates the next 'codeLength' characters into a hex number and returns the result.
37 // . Throws if it's not actually hex.
38 std::string Escape(Stream& in, int codeLength)
40 // grab string
41 std::string str;
42 for(int i=0;i<codeLength;i++)
43 str += in.get();
45 // get the value
46 unsigned value = ParseHex(str, in.mark());
48 // legal unicode?
49 if((value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF) {
50 std::stringstream msg;
51 msg << ErrorMsg::INVALID_UNICODE << value;
52 throw ParserException(in.mark(), msg.str());
55 // now break it up into chars
56 if(value <= 0x7F)
57 return Str(value);
58 else if(value <= 0x7FF)
59 return Str(0xC0 + (value >> 6)) + Str(0x80 + (value & 0x3F));
60 else if(value <= 0xFFFF)
61 return Str(0xE0 + (value >> 12)) + Str(0x80 + ((value >> 6) & 0x3F)) + Str(0x80 + (value & 0x3F));
62 else
63 return Str(0xF0 + (value >> 18)) + Str(0x80 + ((value >> 12) & 0x3F)) +
64 Str(0x80 + ((value >> 6) & 0x3F)) + Str(0x80 + (value & 0x3F));
67 // Escape
68 // . Escapes the sequence starting 'in' (it must begin with a '\' or single quote)
69 // and returns the result.
70 // . Throws if it's an unknown escape character.
71 std::string Escape(Stream& in)
73 // eat slash
74 char escape = in.get();
76 // switch on escape character
77 char ch = in.get();
79 // first do single quote, since it's easier
80 if(escape == '\'' && ch == '\'')
81 return "\'";
83 // now do the slash (we're not gonna check if it's a slash - you better pass one!)
84 switch(ch) {
85 case '0': return std::string(1, '\x00');
86 case 'a': return "\x07";
87 case 'b': return "\x08";
88 case 't':
89 case '\t': return "\x09";
90 case 'n': return "\x0A";
91 case 'v': return "\x0B";
92 case 'f': return "\x0C";
93 case 'r': return "\x0D";
94 case 'e': return "\x1B";
95 case ' ': return "\x20";
96 case '\"': return "\"";
97 case '\'': return "\'";
98 case '\\': return "\\";
99 case '/': return "/";
100 case 'N': return "\x85";
101 case '_': return "\xA0";
102 case 'L': return "\xE2\x80\xA8"; // LS (#x2028)
103 case 'P': return "\xE2\x80\xA9"; // PS (#x2029)
104 case 'x': return Escape(in, 2);
105 case 'u': return Escape(in, 4);
106 case 'U': return Escape(in, 8);
109 std::stringstream msg;
110 throw ParserException(in.mark(), std::string(ErrorMsg::INVALID_ESCAPE) + ch);