Ejemplo n.º 1
0
	bool parser::parse_string(context& ctx, string_type& value, IteratorType& ch, IteratorType end)
	{
		ctx.clear();

		if (!check_char(ctx, '"', ch, end))
		{
			return false;
		}

		while (ch != end)
		{
			if (std::iscntrl(*ch))
			{
				return false;
			}

			switch (*ch)
			{
				case '"':
					{
						// The string ends.
						++ch;

						value = ctx.str();

						return true;
					}

				case '\\':
					{
						// An escape character was provided.
						++ch;

						if (ch == end)
						{
							return false;
						}

						switch (*ch)
						{
							case '"':
								ctx.push_char('"');
								++ch;
								break;

							case '\\':
								ctx.push_char('\\');
								++ch;
								break;

							case '/':
								ctx.push_char('/');
								++ch;
								break;

							case 'b':
								ctx.push_char('\b');
								++ch;
								break;

							case 'n':
								ctx.push_char('\n');
								++ch;
								break;

							case 'f':
								ctx.push_char('\f');
								++ch;
								break;

							case 'r':
								ctx.push_char('\r');
								++ch;
								break;

							case 't':
								ctx.push_char('\t');
								++ch;
								break;

							case 'u':
								{
									++ch;

									uint16_t codepoint = 0x0000;

									for (size_t i = 0; i < 4; ++i)
									{
										if (ch == end)
										{
											return false;
										}

										if (!std::isxdigit(*ch))
										{
											return false;
										}

										codepoint *= 16;
										codepoint += xdigit_to_int(*ch);

										++ch;
									}

									ctx.push_codepoint(codepoint);

									break;
								}

							default:
								return false;
						}

						break;
					}

				default:
					{
						ctx.push_char(*ch);

						++ch;
					}
			}
		}

		return false;
	}