save::State DatabaseCodec::saveMoves(util::ByteStream const& gameData, Provider const& provider) { //M_REQUIRE(isOpen()); //M_REQUIRE(provider.index() >= 0); GameInfo* info = m_db->m_gameInfoList[provider.index()]; if (gameData.size() > maxGameRecordLength()) return save::GameTooLong; if (provider.plyCount() > maxGameLength()) return save::GameTooLong; unsigned gameOffset = putGame(gameData, info->gameOffset(), info->gameRecordLength()); switch (gameOffset) { /*case util::BlockFile::MaxFileSizeExceeded: IO_RAISE(Game, Max_File_Size_Exceeded, "maximal file size (2 GB) exceeded"); case util::BlockFile::SyncFailed: IO_RAISE(Game, Write_Failed, "sync failed"); case util::BlockFile::ReadError: IO_RAISE(Game, Read_Error, "read error"); case util::BlockFile::IllegalOffset: IO_RAISE(Game, Write_Failed, "offset failure (internal error)");*/ } info->setup(gameOffset, gameData.size()); sync(); return save::Ok; }
save::State DatabaseCodec::addGame(ByteStream const& gameData, GameInfo const& info, Allocation allocation) { //M_REQUIRE(isOpen()); if (m_db->size() == maxGameCount()) return save::TooManyGames; if (gameData.size() > maxGameRecordLength() || info.plyCount() > maxGameLength()) return save::GameTooLong; mstl::string whitePlayer; mstl::string blackPlayer; mstl::string event; mstl::string site; mstl::string annotator; if (allocation == Alloc) { namebase(Namebase::Player).copy(whitePlayer, info.playerName(color::White)); namebase(Namebase::Player).copy(blackPlayer, info.playerName(color::Black)); namebase(Namebase::Event).copy(event, info.event()); namebase(Namebase::Site).copy(site, info.site()); namebase(Namebase::Annotator).copy(annotator, info.annotator()); } else { whitePlayer.hook(info.playerName(color::White)); blackPlayer.hook(info.playerName(color::Black)); event.hook(info.event()); site.hook(info.site()); annotator.hook(info.annotator()); } unsigned maxAnnotatorCount = this->maxAnnotatorCount(); NamebasePlayer* whiteEntry; NamebasePlayer* blackEntry; NamebaseSite* siteEntry; NamebaseEvent* eventEntry; NamebaseEntry* annotatorEntry = NamebaseEntry::emptyEntry(); unsigned maxPlayerCount = this->maxPlayerCount(); whiteEntry = namebase(Namebase::Player).insertPlayer( whitePlayer, info.federation(color::White), info.title(color::White), info.playerType(color::White), info.sex(color::White), info.fideID(color::White), maxPlayerCount); blackEntry = namebase(Namebase::Player).insertPlayer( blackPlayer, info.federation(color::Black), info.title(color::Black), info.playerType(color::Black), info.sex(color::Black), info.fideID(color::Black), maxPlayerCount); siteEntry = namebase(Namebase::Site).insertSite( site, info.eventCountry(), maxSiteCount()); eventEntry = namebase(Namebase::Event).insertEvent( event, info.eventDate(), info.eventType(), info.timeMode(), info.eventMode(), maxEventCount(), siteEntry ?siteEntry : NamebaseEvent::emptySite()); if (maxAnnotatorCount) annotatorEntry = namebase(Namebase::Annotator).insert(annotator, maxAnnotatorCount); bool failed = whiteEntry == 0 || blackEntry == 0 || eventEntry == 0 || siteEntry == 0 || annotatorEntry == 0; save::State state = save::Ok; if (!failed && format() != format::Scidb) { } unsigned gameOffset = 0; // shut up compiler if (failed || int(gameOffset = putGame(gameData)) < 0) { namebases().update(); switch (gameOffset) { /*case util::BlockFile::MaxFileSizeExceeded: IO_RAISE(Game, Max_File_Size_Exceeded, "maximal file size (2 GB) exceeded"); case util::BlockFile::SyncFailed: IO_RAISE(Game, Write_Failed, "sync failed"); case util::BlockFile::ReadError: IO_RAISE(Game, Read_Error, "read error"); case util::BlockFile::IllegalOffset: IO_RAISE(Game, Write_Failed, "offset failure (internal error)");*/ } if (!whiteEntry) return save::TooManyPlayerNames; if (!blackEntry) return save::TooManyPlayerNames; if (!eventEntry) return save::TooManyEventNames; if (!siteEntry) return save::TooManySiteNames; return save::TooManyAnnotatorNames; } GameInfo* i = allocGameInfo(); *i = info; i->setup( gameOffset, gameData.size(), whiteEntry, blackEntry, eventEntry, annotatorEntry, m_db->m_namebases); m_db->m_gameInfoList.push_back(i); return state; }
save::State DatabaseCodec::saveGame(ByteStream const& gameData, TagSet const& tags, Provider const& provider) { //M_REQUIRE(isOpen()); typedef Namebase::PlayerEntry* Player; typedef Namebase::EventEntry* Event; typedef Namebase::SiteEntry* Site; typedef Namebase::Entry* Entry; if (gameData.size() > maxGameRecordLength()) return save::GameTooLong; if (provider.plyCount() > maxGameLength()) return save::GameTooLong; GameInfo* info = 0; unsigned index; if (provider.index() >= 0) { index = provider.index(); info = m_db->m_gameInfoList[index]; *m_storedInfo = *info; info->reset(m_db->m_namebases); } else if (m_db->size() == maxGameCount()) { return save::TooManyGames; } else { index = m_db->m_gameInfoList.size(); } unsigned maxAnnotatorCount = this->maxAnnotatorCount(); unsigned maxPlayerCount = this->maxPlayerCount(); InfoData data(tags); Player whiteEntry; Player blackEntry; Site siteEntry; switch (provider.sourceFormat()) { case format::Scid3: case format::Scid4: { mstl::string name; whiteEntry = namebase(Namebase::Player).insertPlayer( ::normalizePlayerName(tags.value(tag::White), name), data.whiteCountry, data.whiteTitle, data.whiteType, data.whiteSex, data.whiteFideID, maxPlayerCount); blackEntry = namebase(Namebase::Player).insertPlayer( ::normalizePlayerName(tags.value(tag::Black), name), data.blackCountry, data.blackTitle, data.blackType, data.blackSex, data.blackFideID, maxPlayerCount); siteEntry = namebase(Namebase::Site).insertSite( ::normalizeSiteName(tags.value(tag::Site), name), data.eventCountry, maxSiteCount()); } break; default: whiteEntry = namebase(Namebase::Player).insertPlayer( tags.value(tag::White), data.whiteCountry, data.whiteTitle, data.whiteType, data.whiteSex, data.whiteFideID, maxPlayerCount); blackEntry = namebase(Namebase::Player).insertPlayer( tags.value(tag::Black), data.blackCountry, data.blackTitle, data.blackType, data.blackSex, data.blackFideID, maxPlayerCount); siteEntry = namebase(Namebase::Site).insertSite( tags.value(tag::Site), data.eventCountry, maxSiteCount()); } Event eventEntry = namebase(Namebase::Event).insertEvent( tags.value(tag::Event), data.eventDate, data.eventType, data.timeMode, data.eventMode, maxEventCount(), siteEntry ? siteEntry : NamebaseEvent::emptySite()); Entry annotatorEntry = NamebaseEntry::emptyEntry(); if (maxAnnotatorCount) { annotatorEntry = namebase(Namebase::Annotator).insert(tags.value(tag::Annotator), maxAnnotatorCount); } save::State state = save::Ok; bool failed = whiteEntry == 0 || blackEntry == 0 || eventEntry == 0 || siteEntry == 0 || annotatorEntry == 0; unsigned gameOffset = 0; // shut up compiler if (!failed) { if (info) gameOffset = putGame(gameData, info->gameOffset(), info->gameRecordLength()); else gameOffset = putGame(gameData); } if (failed || int(gameOffset) < 0) { if (info) info->restore(*m_storedInfo, m_db->m_namebases); namebases().update(); switch (gameOffset) { /*case util::BlockFile::MaxFileSizeExceeded: IO_RAISE(Game, Max_File_Size_Exceeded, "maximal file size (2 GB) exceeded"); case util::BlockFile::SyncFailed: IO_RAISE(Game, Write_Failed, "sync failed"); case util::BlockFile::ReadError: IO_RAISE(Game, Read_Error, "read error"); case util::BlockFile::IllegalOffset: IO_RAISE(Game, Write_Failed, "offset failure (internal error)");*/ } if (!whiteEntry) return save::TooManyPlayerNames; if (!blackEntry) return save::TooManyPlayerNames; if (!eventEntry) return save::TooManyEventNames; if (!siteEntry) return save::TooManySiteNames; return save::TooManyAnnotatorNames; } if (info == 0) { info = allocGameInfo(); m_db->m_gameInfoList.push_back(info); } info->setup(gameOffset, gameData.size(), whiteEntry, blackEntry, eventEntry, annotatorEntry, tags, provider, m_db->m_namebases); return state; }