#pragma once /************************************************************************ MeOS - Orienteering Software Copyright (C) 2009-2022 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Melin Software HB - software@melin.nu - www.melin.nu Eksoppsvägen 16, SE-75646 UPPSALA, Sweden ************************************************************************/ #include #include #include #include #include "oEvent.h" class oWordDatabase; typedef oWordDatabase* pWordDatabase; typedef map MapTable; const wchar_t indexMapStart='a'; const wchar_t indexMapEnd='z'; const int hashSplitSize=16; const int hashTableSize=indexMapEnd-indexMapStart+1; class oFreeImport; class oWordDatabase { public: virtual char getType() const = 0; virtual const char *deserialize(const char *bf, const char *end) = 0; virtual char *serialize(char *bf) const = 0; virtual int serialSize() const = 0; virtual pWordDatabase split() {return this;} virtual void insert(const wchar_t *s) = 0; virtual bool lookup(const wchar_t *s) const = 0; virtual ~oWordDatabase() = 0 {} }; class oWordDB : public oWordDatabase { protected: char getType() const {return 1;} set str; public: const char *deserialize(const char *bf, const char *end); char *serialize(char *bf) const; int serialSize() const; pWordDatabase split(); void insert(const wchar_t *s); bool lookup(const wchar_t *s) const; size_t size(); }; class oWordIndexHash : public oWordDatabase { protected: char getType() const {return 2;} pWordDatabase hashTable[hashTableSize]; MapTable unMapped; bool hashAll; public: const char *deserialize(const char *bf, const char *end); char *serialize(char *bf) const; int serialSize() const; void insert(const wchar_t *s); bool lookup(const wchar_t *s) const; void clear(); ~oWordIndexHash(); oWordIndexHash(bool hashAll_); }; class oWordList { protected: oWordIndexHash wh; public: void serialize(vector &serial) const; void deserialize(const vector &serial); void save(const wstring &file) const; void load(const wstring &file); void insert(const wchar_t *s); bool lookup(const wchar_t *s) const; ~oWordList(); oWordList(); }; struct oEntryPerson { wstring name1; wstring name2; wstring club; int cardNo; void swap(); int nameCount() const; oEntryPerson(const wstring &clb); }; struct oEntryBlock { // Remember clear for additional data vector ePersons; wstring eClub; wstring eClass; bool isClassSet; wstring eStartTime; bool canInsertName; int nClubsSet; const oFreeImport &freeImporter; int nameCount(); void setClub(const wchar_t *s); void setClass(const wchar_t *s); void setCardNo(int c); void setStartTime(const wchar_t *s); void addPerson(const wchar_t *s, bool complete); vector getPersons() const; void clear(const wstring &rulingClub, const wstring &rulingClass); // Return true if more clubs can be accepted bool acceptMoreClubs(int expectedNumRunners) const; bool expectMoreNames(int expectedNumRunners) const; bool needCard() const; bool hasClub() const {return !eClub.empty();} /** Return true if class explicitly set. May have a ruling class anyway*/ bool hasClass() const {return isClassSet;} bool hasStartTime() const {return !eStartTime.empty();} bool hasName() {return !ePersons.empty() && !ePersons.front().name1.empty();} void cleanEntry(); //Remove bad data. oEntryBlock(const oFreeImport &importer); oEntryBlock(const oEntryBlock &eb); void operator=(const oEntryBlock &eb); int getNumPersons() const {return ePersons.size();} wstring getTeamName() const; wstring getName(int k) const; wstring getClub(int k) const; int getCard(int k) const; /** Make name complete */ void completeName(); }; struct MatchPattern { short nName; short singleName; short nClass; short nClub; short nTime; short nCard; bool isClass(int level=2) const {return nClass>(nClub+nTime+nCard)+level;} bool isClub(int level=2) const {return nClub>(nClass+nTime+nCard)+level;} bool isTime(int level=2) const {return nTime>(nClass+nClub+nCard)+level;} bool isCard(int level=2) const {return nCard>(nClass+nTime+nTime)+level;} bool isName(int level=2) const {return nName>(nCard+nClass+nTime+nClub)+level;} bool isCompleteName() const {return singleName separator; oWordList givenDB; oWordList familyDB; oWordList clubDB; oWordList classDB; enum Types { None = -2, Unknown = -1, Club = 0, Class = 1, Time = 2, Card = 3, Name = 4 }; void analyzePart(wchar_t *part, const MatchPattern &ptrn, int nNamesPerPart, oEntryBlock &entry, vector &entries, bool allowNames); //bool analyze(vector &b, int &offset, int &delta) const; wchar_t *extractWord(wchar_t *&str, int &count) const; wchar_t *extractPart(wchar_t *&str, int &wordCount) const; wchar_t *extractLine(wchar_t *&str, int &count) const; bool isNumber(const wchar_t *str, int &number) const; bool isTime(const wstring &m) const; bool isName(const wchar_t *p) const; bool isCard(const wchar_t *p) const; bool isCrap(const wchar_t *p) const; bool loaded; int preAnalyzeRow(vector &p, const vector &ptrn, vector &classified); // Runners per class in defined classes map runnersPerClass; /** Must not return 0 */ int getExpectedNumRunners(const wstring &cls) const; friend struct oEntryBlock; /** Check if a line is a header and remove header words, name: , class: etc. Returns true if the entire line is header (->ignore) */ bool analyzeHeaders(vector &line) const; /** Returns true if the given word is a header word */ bool isHeaderWord(const wstring &word) const; mutable set headerWords; // Expected club for all entries wstring rulingClub; wstring rulingClass; Types lastInsertedType; public: void load(); bool isLoaded() const {return loaded;} void save() const; void init(const oRunnerList &r, const oClubList &clb, const oClassList &cls); void buildDatabases(oEvent &oe); void extractEntries(wchar_t *bf, vector &entries); void showEntries(gdioutput &gdi, const vector &entries); void addEntries(pEvent oe, const vector &entries); void test(const oRunnerList &li); oFreeImport(void); ~oFreeImport(void); friend class oEvent; };