Пример #1
0
String Utf8Codec::decode(const char* data, unsigned size)
{
    Utf8Codec codec;

    Char to[64];
    MBState state;
    String ret;
    const char* from = data;

    result r;
    do
    {
        Char* to_next = to;

        const char* from_next = from;
        r = codec.in(state, from, from + size, from_next, to, to + sizeof(to), to_next);

        if (r == error)
            throw ConversionError("character conversion failed");

        if (r == partial && from_next == from)
            throw ConversionError("character conversion failed - unexpected end of utf8 sequence");

        ret.append(to, to_next);

        size -= (from_next - from);
        from = from_next;

    } while (r == partial);

    return ret;
}
Пример #2
0
				void _allow_value_only(const std::string& type_name) const {

					if (m_type == Type::SECTION) {
						throw ConversionError("Can't convert section to " + type_name + ".");
					}

					if (m_type == Type::LIST) {
						throw ConversionError("Can't convert list to " + type_name + ".");
					}

				}
Пример #3
0
std::string Utf8Codec::encode(const Char* data, unsigned size)
{
    Utf8Codec codec;
    char to[64];
    MBState state;
    
    result r;
    const Char* from = data;
    std::string ret;

    do{
        const Char* from_next;

        char* to_next = to;
        r = codec.out(state, from, from + size, from_next, to, to + sizeof(to), to_next);

        if (r == error)
            throw ConversionError("character conversion failed");

        ret.append(to, to_next);

        size -= (from_next - from);
        from = from_next;

    } while (r == partial);

    return ret;
}
Пример #4
0
void convert(Date& date, const std::string& s)
{
    if (s.size() < 10 || s.at(4) != '-' || s.at(7) != '-')
    {
        throw ConversionError("Illegal date format");
    }

    const char* d = s.data();
    date = Date(getNumber4(d), getNumber2(d + 5), getNumber2(d + 8));
}
Пример #5
0
    static wxPoint StringToPoint(const wxString & str)
    {
        wxArrayString tokens = wxStringTokenize(str, _T(", "), wxTOKEN_STRTOK);
        long x, y;
        if (tokens.size() != 2 ||
            ! (tokens[0].ToLong(&x) && tokens[1].ToLong(&y)) )
        {
            throw ConversionError();
        }

        return wxPoint(x, y);
    }
Пример #6
0
	String::operator bool() const throw(X::ConversionErrorBase)
	{
		if (*this == u"true")
			return true;
		else if (*this == u"false")
			return false;
		else if (*this == u"1")
			return true;
		else if (*this == u"0")
			return false;
		else
			throw ConversionError(typeOf<String>::type, typeOf<bool>::type);
	}
Пример #7
0
UniChar::UniChar(const char * utf8) :
	priv(NULL)
{
	UChar32 cp = 0;

	/* If it happen to find a zero, terminating character, non of the if branches
	 * will apply, because each requires some non-null value. */

	/* http://en.wikipedia.ptrrg/wiki/UTF-8#Description */
		if(0x00 == (utf8[0] & 0x80)){ /* 7 bit -> 1 byte to use (ascii code) */
			cp = utf8[0];
	} else	if(0xc0 == (utf8[0] & 0xe0)){ /* 11 bit -> 2 byte to use */
			if(!(0x80 == (utf8[1] & 0xc0)))
				throw ConversionError("Invalid second byte in utf8 sequence: "
						"%", utf8[1]);
			cp = utf8[0] & 0x1f; cp <<= 6;
			cp |= utf8[1] & 0x3f;
	} else	if(0xe0 == (utf8[0] & 0xf0)) { /* 16 bit -> 3 byte to use */
			if(!(0x80 == (utf8[1] & 0xc0)))
				throw ConversionError("Invalid second byte in utf8 sequence: "
						"%", utf8[1]);
			if(!(0x80 == (utf8[2] & 0xc0)))
				throw ConversionError("Invalid third byte in utf8 sequence: "
						"%", utf8[2]);
			cp = utf8[0] & 0x0f; cp <<= 6;
			cp |= utf8[1] & 0x3f; cp <<= 6;
			cp |= utf8[2] & 0x3f;
	} else	if(0xf0 == (utf8[0] & 0xf8)) { /* 21 bit -> 4 byte to use */
			if(!(0x80 == (utf8[1] & 0xc0)))
				throw ConversionError("Invalid second byte in utf8 sequence: "
						"%", utf8[1]);
			if(!(0x80 == (utf8[2] & 0xc0)))
				throw ConversionError("Invalid third byte in utf8 sequence: "
						"%", utf8[2]);
			if(!(0x80 == (utf8[3] & 0xc0)))
				throw ConversionError("Invalid fourth byte in utf8 sequence: "
						"%", utf8[3]);
			cp = utf8[0] & 0x07; cp <<= 6;
			cp |= utf8[1] & 0x3f; cp <<= 6;
			cp |= utf8[2] & 0x3f; cp <<= 6;
			cp |= utf8[3] & 0x3f;
	} else
		throw ConversionError("Invalid first byte in utf8 sequence: %", utf8[0]);

	if(!unicodePointValidity(cp))
		throw InvalidArgument("The value '%' (converted from utf8 sequence "
				"'%%%%'), is not a valid unicode point.",
				(long unsigned int)cp, utf8[0], utf8[1], utf8[2], utf8[3]);

	priv = new UniCharPrivate();
	priv->val = cp;
	priv->dirtyUtf8 = true;
}
Пример #8
0
                /** Converts this node to true/false, only if it has a single value of 'true' or 'false'. */
                bool to_boolean() const {

					_allow_value_only("boolean");

                    std::string value = m_content.front();

                    if (value == "true") {
                        return true;
                    } else if (value == "false") {
                        return false;
                    } else {
                        throw ConversionError("Can't convert this string to boolean, it's neither 'true' nor 'false'.");
                    }

                }
Пример #9
0
                /**
                 * Converts this node to string if it's not a section.
                 * List values are converted to multi-line text.
                 */
                std::string to_string() const {

                    if (m_type == Type::SECTION) {
                        throw ConversionError("Can't convert section to string.");
                    }

                    if (m_type == Type::VALUE) {
                        return m_content.front();
                    } else {

                        std::stringstream buffer;

                        for (const std::string& line : m_content) {
                            buffer << line << " \n";
                        }

                        return buffer.str();

                    }

                }
Пример #10
0
void ConversionError::doThrow(const std::string& argname, unsigned argnum, const char* typeto, const std::string& value)
{
    std::ostringstream msg;

    msg << "Cannot convert \"'" << value << '"';

    if (typeto)
        msg << " to <" << typeto << '>';

    if (!argname.empty())
    {
        msg << " for argument \"" << argname;
        if (argnum > 0)
            msg << '[' << argnum << ']';
        msg << '"';
    }
    else if (argnum > 0)
    {
        msg << " for argument " << argnum;
    }

    throw ConversionError(msg.str());
}
Пример #11
0
//-----------------------------------------------------------------------------
// SaveXPF
//-----------------------------------------------------------------------------
void SaveXPF(Puzzle * puz, const std::string & filename, void * /* dummy */)
{
    const Grid & grid = puz->GetGrid();

    if (grid.IsScrambled())
        throw ConversionError("XPF does not support scrambled puzzles");
    if (! grid.HasSolution())
        throw ConversionError("XPF does not support puzzles without a solution");
    for (const Square * square = puz->GetGrid().First();
         square != NULL;
         square = square->Next())
    {
        if (square->HasImage())
            throw ConversionError("XPF does not support puzzles with background images.");
    }

    xml::document doc;
    xml::node puzzles = doc.append_child("Puzzles");
    puzzles.append_attribute("Version") = "1.0";
    xml::node puzzle = puzzles.append_child("Puzzle");
    // Metadata
    puz::Puzzle::metamap_t & meta = puz->GetMetadata();
    puz::Puzzle::metamap_t::iterator it;
    for (it = meta.begin(); it != meta.end(); ++it)
    {
        if (it->first == puzT("notes")) // "notes" -> "Notepad"
            xml::Append(puzzle, "Notepad", it->second);
        else
            xml::Append(puzzle, xml::CamelCase(it->first).c_str(), it->second);
    }

    // Grid
    if (grid.GetType() == TYPE_DIAGRAMLESS)
        xml::Append(puzzle, "Type", "diagramless");

    // Grid Size
    xml::node size = puzzle.append_child("Size");
    xml::Append(size, "Rows", puz::ToString(grid.GetHeight()));
    xml::Append(size, "Cols", puz::ToString(grid.GetWidth()));

    // Answers
    {
        xml::node grid_node = puzzle.append_child("Grid");
        xml::node row;
        std::string row_text;
        row_text.reserve(grid.GetWidth());
        const Square * square;
        for (square = grid.First(); square; square = square->Next())
        {
            if (square->IsFirst(ACROSS))
                row = grid_node.append_child("Row");
            if (square->IsMissing())
                row_text.append(1, '~');
            else if (square->IsBlack())
                row_text.append(1, char(Square::Black[0]));
            else if (square->IsSolutionBlank())
                row_text.append(1, ' ');
            else
                row_text.append(1, square->GetPlainSolution());
            if (square->IsLast(ACROSS))
            {
                xml::SetText(row, row_text.c_str());
                row_text.clear();
            }
        }
    }

    // Circles
    {
        xml::node circles = puzzle.append_child("Circles");
        const Square * square;
        for (square = grid.First(); square; square = square->Next())
        {
            if (square->HasCircle())
            {
                xml::node circle = circles.append_child("Circle");
                circle.append_attribute("Row") = square->GetRow() + 1;
                circle.append_attribute("Col") = square->GetCol() + 1;
            }
        }
        if (circles.empty())
            puzzle.remove_child(circles);
    }

    // Rebus
    {
        xml::node rebus = puzzle.append_child("RebusEntries");
        const Square * square;
        for (square = grid.First(); square; square = square->Next())
        {
            if (square->HasSolutionRebus())
            {
                xml::node entry = rebus.append_child("Rebus");
                entry.append_attribute("Row") = square->GetRow() + 1;
                entry.append_attribute("Col") = square->GetCol() + 1;
                entry.append_attribute("Short") =
                    std::string(1, square->GetPlainSolution()).c_str();
                xml::SetText(entry, square->GetSolution());
            }
        }
        if (rebus.empty())
            puzzle.remove_child(rebus);
    }

    // Shades
    {
        xml::node shades = puzzle.append_child("Shades");
        const Square * square;
        for (square = grid.First(); square; square = square->Next())
        {
            if (square->HasColor())
            {
                xml::node shade = shades.append_child("Shade");
                shade.append_attribute("Row") = square->GetRow() + 1;
                shade.append_attribute("Col") = square->GetCol() + 1;
                if (square->HasHighlight())
                    xml::SetText(shade, "gray");
                else
                    xml::SetText(shade, square->GetHtmlColor());
            }
        }
        if (shades.empty())
            puzzle.remove_child(shades);
    }

    // Clues
    {
        xml::node clues_node = puzzle.append_child("Clues");
        Clues & clues = puz->GetClues();
        Clues::iterator clues_it;
        for (clues_it = clues.begin(); clues_it != clues.end(); ++clues_it)
        {
            ClueList & cluelist = clues_it->second;
            ClueList::iterator it;
            for (it = cluelist.begin(); it != cluelist.end(); ++it)
            {
                xml::node clue = clues_node.append_child("Clue");
                // Find the clue direction
                if (! puz->IsDiagramless())
                {
                    const Word & word = it->GetWord();
                    switch (word.GetDirection())
                    {
                    case ACROSS:
                        clue.append_attribute("Dir") = "Across";
                        break;
                    case DOWN:
                        clue.append_attribute("Dir") = "Down";
                        break;
                    case DIAGONAL_SW:
                        clue.append_attribute("Dir") = "Diagonal";
                        break;
                    default:
                        throw ConversionError("XPF clues must be Across, Down, or Diagonal");
                        break;
                    }
                    clue.append_attribute("Row") = word.front()->GetRow() + 1;
                    clue.append_attribute("Col") = word.front()->GetCol() + 1;
                }
                else // diagramless
                {
                    puz::string_t title = cluelist.GetTitle();
                    if (title == puzT("Across"))
                        clue.append_attribute("Dir") = "Across";
                    else if (title == puzT("Down"))
                        clue.append_attribute("Dir") = "Down";
                    else if (title == puzT("Diagonal"))
                        clue.append_attribute("Dir") = "Diagonal";
                    else
                        throw ConversionError("XPF clues must be Across, Down, or Diagonal");
                }
                clue.append_attribute("Num") = encode_utf8(it->GetNumber()).c_str();
                // Clue formatting needs to be escaped if it is XHTML.
                // xml::SetInnerXML(clue, it->GetText());
                xml::SetText(clue, it->GetText());
            }
        }
    }

    // User Grid
    {
        xml::node usergrid = puzzle.append_child("UserGrid");
        xml::node row;
        std::string row_text;
        row_text.reserve(grid.GetWidth());
        const Square * square;
        for (square = grid.First(); square; square = square->Next())
        {
            if (square->IsFirst(ACROSS))
                row = usergrid.append_child("Row");
            if (square->IsMissing())
                row_text.append(1, '~');
            else if (square->IsBlack())
                row_text.append(1, char(Square::Black[0]));
            else if (square->IsBlank())
                row_text.append(1, ' ');
            else
                row_text.append(1, square->GetPlainText());
            if (square->IsLast(ACROSS))
            {
                xml::SetText(row, row_text.c_str());
                row_text.clear();
            }
        }
        if (usergrid.empty())
            puzzle.remove_child(usergrid);
    }

    // User Rebus
    {
        xml::node rebus = puzzle.append_child("UserRebusEntries");
        const Square * square;
        for (square = grid.First(); square; square = square->Next())
        {
            if (square->HasTextRebus())
            {
                xml::node entry = rebus.append_child("Rebus");
                entry.append_attribute("Row") = square->GetRow() + 1;
                entry.append_attribute("Col") = square->GetCol() + 1;
                entry.append_attribute("Short") =
                    std::string(1, square->GetPlainText()).c_str();
                xml::SetText(entry, square->GetText());
            }
        }
        if (rebus.empty())
            puzzle.remove_child(rebus);
    }

    // Square Flags
    {
        xml::node flags = puzzle.append_child("SquareFlags");
        const Square * square;
        for (square = grid.First(); square; square = square->Next())
        {
            if (square->GetFlag() != 0)
            {
                xml::node entry = flags.append_child("Flag");
                entry.append_attribute("Row") = square->GetRow() + 1;
                entry.append_attribute("Col") = square->GetCol() + 1;
                if (square->HasFlag(FLAG_PENCIL))
                    entry.append_attribute("Pencil") = "true";
                if (square->HasFlag(FLAG_BLACK))
                    entry.append_attribute("Checked") = "true";
                if (square->HasFlag(FLAG_REVEALED))
                    entry.append_attribute("Revealed") = "true";
                if (square->HasFlag(FLAG_X))
                    entry.append_attribute("Incorrect") = "true";
                if (square->HasFlag(FLAG_CORRECT))
                    entry.append_attribute("Correct") = "true";
            }
        }
        if (flags.empty())
            puzzle.remove_child(flags);
    }

    // Timer
    {
        if (puz->GetTime() != 0)
        {
            xml::node timer = puzzle.append_child("Timer");
            timer.append_attribute("Seconds") = puz->GetTime();
            if (puz->IsTimerRunning())
                timer.append_attribute("Running") = "true";
        }
    }

    doc.save_file(filename.c_str());
}