예제 #1
0
save::State
Decoder::doDecoding(db::Consumer& consumer, TagSet& tags)
{
	uint16_t flags	= m_strm.uint16();
	uint16_t idn	= flags & 0x0fff;

	if (idn)
	{
		m_position.setup(idn);
	}
	else
	{
		mstl::string fen;
		m_strm.get(fen);
		m_position.setup(fen);
		tags.set(tag::SetUp, "1");	// bad PGN design
		tags.set(tag::Fen, fen);
	}

	if (!consumer.startGame(tags, m_position.board()))
		return save::UnsupportedVariant;

	Byte* dataSection = m_strm.base() + m_strm.uint24();
	ByteStream text, data;

	if (flags & 0x8000)
	{
		unsigned size = ByteStream::uint24(dataSection);

		text.setup(dataSection + 3, size);
		data.setup(text.end(), m_strm.end());
	}
	else
	{
		data.setup(dataSection, m_strm.end());
	}

	if (flags & 0x7000)
	{
		EngineList engines;
		decodeEngines(data, engines);
		consumer.swapEngines(engines);
	}

	consumer.startMoveSection();
	decodeRun(m_strm.uint16(), consumer);
	decodeVariation(consumer, data, text);
	consumer.finishMoveSection(result::fromString(tags.value(tag::Result)));

	if (data.remaining())
		decodeTags(data, tags);

	return consumer.finishGame(tags);
}
예제 #2
0
void
Decoder::decodeTags(ByteStream& strm, TagSet& tags)
{
	//M_ASSERT(strm.remaining());

	mstl::string name;
	mstl::string value;

	for (tag::ID id = tag::ID(strm.get()); id; id = tag::ID(strm.get()))
	{
		if (id == tag::ExtraTag)
		{
			name.clear();
			value.clear();
			strm.get(name);
			strm.get(value);
			tags.setExtra(name, value);
		}
		else
		{
			value.clear();
			strm.get(value);
			tags.set(id, value);

			if (tag::isRatingTag(id))
				tags.setSignificance(id, 0);
		}

#define SCI_TAGS_FIX
#ifdef SCI_TAGS_FIX
		if (strm.remaining() == 0)
			return;
#endif
	}
}
예제 #3
0
save::State
Consumer::endGame(TagSet const& tags)
{
	TagSet const* tagSet = &tags;
	TagSet* myTags = 0;

	if (m_text.tellp() > 0 && m_lastCommentPos == plyCount() && !tags.contains(tag::Termination))
	{
		result::ID result = result::fromString(tags.value(tag::Result));

		if (result == result::White || result == result::Black)
		{
			Byte const* s = m_text.data() + m_text.tellp() - 1;

			while (s > m_text.base() && s[-1])
				--s;

			if (	::strcasecmp(reinterpret_cast<char const*>(s), "time") == 0
				|| ::strcasecmp(reinterpret_cast<char const*>(s), "time/") == 0
				|| ::strcasecmp(reinterpret_cast<char const*>(s), "time!") == 0
				|| ::strcasecmp(reinterpret_cast<char const*>(s), "time forfeit") == 0)
			{
				myTags = new TagSet(tags);
				myTags->set(tag::Termination, termination::toString(termination::TimeForfeit));
				tagSet = myTags;
			}
		}
	}

	unsigned dataOffset = m_strm.tellp();

	encodeTextSection();
	encodeDataSection(engines());
	encodeTags(*tagSet, allowedTags(), allowExtraTags());
	ByteStream::set(m_strm.base() + m_streamPos, uint24_t(dataOffset));

	m_stream.provide();
	save::State state = m_codec.addGame(m_stream, *tagSet, *this);

	if (myTags)
		delete myTags;

	return state;
}