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; }