示例#1
0
void
Decoder::decodeTextSection(MoveNode* node, ByteStream& text)
{
	for ( ; node; node = node->next())
	{
		if (node->hasSupplement())
		{
			if (uint8_t flag = node->commentFlag())
			{
				mstl::string	buf;
				Comment			comment;

				if (flag & comm::Ante)
				{
					text.get(buf);
					comment.swap(buf, bool(flag & comm::Ante_Eng), bool(flag & comm::Ante_Oth));
					node->setComment(comment, move::Ante);
				}

				if (flag & comm::Post)
				{
					text.get(buf);
					comment.swap(buf,  bool(flag & comm::Post_Eng), bool(flag & comm::Post_Oth));
					node->setComment(comment, move::Post);
				}
			}

			for (unsigned i = 0; i < node->variationCount(); ++i)
				decodeTextSection(node->variation(i), text);
		}
	}
}
示例#2
0
void
Decoder::decodeVariation(Consumer& consumer, util::ByteStream& data, ByteStream& text)
{
	MarkSet			marks;
	MoveInfoSet		moveInfo;
	Annotation		annotation;
	mstl::string	buf;
	Comment			comment;
	Comment			preComment;
	bool				hasNote(false);	// satisfies the compiler
	unsigned			pieceNum(0);		// satisfies the compiler
	Move				move;
	Move				lastMove;

	while (true)
	{
		Byte b = m_strm.get();

		if (__builtin_expect(b > token::Last, 1))
		{
			if (move)
			{
				if (hasNote)
				{
					consumer.putMove(move, annotation, preComment, comment, marks);
					if (!moveInfo.isEmpty())
					{
						consumer.putMoveInfo(moveInfo);
						moveInfo.clear();
					}
					marks.clear();
					annotation.clear();
					comment.clear();
					preComment.clear();
					hasNote = false;
				}
				else
				{
					consumer.putMove(move);
				}

				m_position.doMove(move, pieceNum);
			}
			else
			{
				if (lastMove)
				{
					m_position.doMove(lastMove, pieceNum);
					lastMove.clear();
				}

				if (hasNote)
				{
					consumer.putPrecedingComment(comment, annotation, marks);
					marks.clear();
					annotation.clear();
					comment.clear();
					hasNote = false;
				}
			}

			pieceNum = decodeMove(b, move);
		}
		else
		{
			switch (b)
			{
				case token::End_Marker:
					if (move)
					{
						if (hasNote)
						{
							consumer.putMove(move, annotation, preComment, comment, marks);
							if (!moveInfo.isEmpty())
								consumer.putMoveInfo(moveInfo);
						}
						else
						{
							consumer.putMove(move);
						}
					}
					else if (hasNote)
					{
						consumer.putPrecedingComment(comment, annotation, marks);
						hasNote = false;
					}
					switch (m_strm.get())
					{
						case token::Comment:
							{
								uint8_t flag = data.get();

								buf.clear();
								text.get(buf);
								comment.swap(buf, bool(flag & comm::Ante_Eng), bool(flag & comm::Ante_Oth));
								consumer.putTrailingComment(comment);
								break;
							}

						case token::End_Marker: break;
						default: return; //IO_RAISE(Game, Corrupted, "unexpected token");
					}
					return;

				case token::Start_Marker:
					if (move)
					{
						if (hasNote)
						{
							consumer.putMove(move, annotation, preComment, comment, marks);
							if (!moveInfo.isEmpty())
							{
								consumer.putMoveInfo(moveInfo);
								moveInfo.clear();
							}
							marks.clear();
							annotation.clear();
							comment.clear();
							preComment.clear();
							hasNote = false;
						}
						else
						{
							consumer.putMove(move);
						}

						lastMove = move;
						move.clear();
					}

					//M_ASSERT(!hasNote);

					m_position.push();
					m_position.board().undoMove(lastMove);
					consumer.startVariation();
					decodeVariation(consumer, data, text);
					consumer.finishVariation();
					m_position.pop();
					break;

				case token::Nag:
					{
						nag::ID nag = nag::ID(m_strm.get());

						if (nag == 0)
						{
							move.setLegalMove(false);
						}
						else
						{
							annotation.add(nag);
							hasNote = true;
						}
					}
					break;

				case token::Mark:
					if (data.peek() & 0x80)
						moveInfo.add().decode(data);
					else
						marks.add().decode(data);
					hasNote = true;
					break;

				case token::Comment:
					{
						uint8_t flag = data.get();

						if (flag & comm::Ante)
						{
							buf.clear();
							text.get(buf);
							preComment.swap(buf, bool(flag & comm::Ante_Eng), bool(flag & comm::Ante_Oth));
						}

						if (flag & comm::Post)
						{
							buf.clear();
							text.get(buf);
							comment.swap(buf, bool(flag & comm::Post_Eng), bool(flag & comm::Post_Oth));
						}

						hasNote = true;
					}
					break;
			}
		}
	}
}