exp.cpp
Go to the documentation of this file.
1 #include "exp.h"
3 #include <sstream>
4 
5 namespace YAML_PM
6 {
7  namespace Exp
8  {
9  unsigned ParseHex(const std::string& str, const Mark& mark)
10  {
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
23 
24  value = (value << 4) + digit;
25  }
26 
27  return value;
28  }
29 
30  std::string Str(unsigned ch)
31  {
32  return std::string(1, static_cast<char>(ch));
33  }
34 
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)
39  {
40  // grab string
41  std::string str;
42  for(int i=0;i<codeLength;i++)
43  str += in.get();
44 
45  // get the value
46  unsigned value = ParseHex(str, in.mark());
47 
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());
53  }
54 
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));
65  }
66 
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.
72  {
73  // eat slash
74  char escape = in.get();
75 
76  // switch on escape character
77  char ch = in.get();
78 
79  // first do single quote, since it's easier
80  if(escape == '\'' && ch == '\'')
81  return "\'";
82 
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);
107  }
108 
109  std::stringstream msg;
111  }
112  }
113 }
YAML_PM::Exp::Str
std::string Str(unsigned ch)
Definition: exp.cpp:30
exceptions.h
YAML_PM::ErrorMsg::INVALID_HEX
const char *const INVALID_HEX
Definition: exceptions.h:37
YAML_PM
Definition: aliasmanager.h:11
YAML_PM::ErrorMsg::INVALID_ESCAPE
const char *const INVALID_ESCAPE
Definition: exceptions.h:39
exp.h
YAML_PM::Stream::get
char get()
Definition: stream.cpp:245
YAML_PM::ErrorMsg::INVALID_UNICODE
const char *const INVALID_UNICODE
Definition: exceptions.h:38
testing::internal::string
::std::string string
Definition: gtest.h:1979
YAML_PM::ParserException
Definition: exceptions.h:110
YAML_PM::Exp::Escape
std::string Escape(Stream &in, int codeLength)
Definition: exp.cpp:38
YAML_PM::Mark
Definition: mark.h:13
YAML_PM::Stream
Definition: stream.h:20
YAML_PM::Exp::ParseHex
unsigned ParseHex(const std::string &str, const Mark &mark)
Definition: exp.cpp:9
YAML_PM::Stream::mark
const Mark mark() const
Definition: stream.h:38


mp2p_icp
Author(s):
autogenerated on Fri Dec 20 2024 03:45:57