00001 //---------------------------------------------------------------------------- 00002 /** @file SgGameReader.h */ 00003 //---------------------------------------------------------------------------- 00004 00005 #ifndef SG_GAMEREADER_H 00006 #define SG_GAMEREADER_H 00007 00008 #include <bitset> 00009 #include <map> 00010 #include <vector> 00011 #include "SgProp.h" 00012 #include "SgVector.h" 00013 00014 class SgNode; 00015 00016 //---------------------------------------------------------------------------- 00017 00018 /** Read file with SGF data. 00019 @bug Properties are read sequentially, therefore GM and SZ properties have 00020 to be before any point value properties, because they are required to 00021 parse the point values. According to the SGF standard, the order or 00022 properties is arbitrary and there exist SGF files, which have the GM and 00023 SZ property after point properties (like AB, AW) in the root node. To fix 00024 this, all properties of a node would have to be read and GM and SZ handled 00025 first before parsing any other property values. */ 00026 class SgGameReader 00027 { 00028 public: 00029 /** Warning conditions that occurred during reading. 00030 @todo Some of these warnings should be errors. */ 00031 enum WarningFlags { 00032 /** Invalid board size. 00033 The file contained a size property with a value not in 00034 [SG_MIN_SIZE..SG_MAX_SIZE]. */ 00035 INVALID_BOARDSIZE, 00036 00037 PROPERTY_WITHOUT_VALUE, 00038 00039 /** Number of WarningFlags. */ 00040 NU_WARNING_FLAGS 00041 }; 00042 00043 /** Warnings that occurred during reading. */ 00044 typedef std::bitset<NU_WARNING_FLAGS> Warnings; 00045 00046 /** Create reader from an input stream. 00047 @param in The input stream. 00048 @param defaultSize The (game-dependent) default board size, if file 00049 contains no SZ property. 00050 no SZ property. */ 00051 SgGameReader(std::istream& in, int defaultSize = 19); 00052 00053 /** Get warnings of last ReadGame or ReadGames. */ 00054 Warnings GetWarnings() const; 00055 00056 /** Print warnings of last ReadGame or ReadGames to stream. 00057 Prints the warnings as human readable text. */ 00058 void PrintWarnings(std::ostream& out) const; 00059 00060 /** Read next game tree from file. 00061 @return Root node or 0 if there is no next game. */ 00062 SgNode* ReadGame(); 00063 00064 /** Read all game trees from this file. 00065 Return a list with the root of each game tree. */ 00066 void ReadGames(SgVectorOf<SgNode>* rootList); 00067 00068 private: 00069 /** Map label to values (unparsed) */ 00070 typedef std::map<std::string, std::vector<std::string> > RawProperties; 00071 00072 std::istream& m_in; 00073 00074 const int m_defaultSize; 00075 00076 /** The file format read in. */ 00077 int m_fileFormat; 00078 00079 Warnings m_warnings; 00080 00081 /** Not implemented. */ 00082 SgGameReader(const SgGameReader&); 00083 00084 /** Not implemented. */ 00085 SgGameReader& operator=(const SgGameReader&); 00086 00087 static bool GetIntProp(const RawProperties& properties, 00088 const std::string& label, int& value); 00089 00090 void HandleProperties(SgNode* node, const RawProperties& properties, 00091 int& boardSize, SgPropPointFmt& fmt); 00092 00093 SgNode* ReadGame(bool resetWarnings); 00094 00095 std::string ReadLabel(int c); 00096 00097 SgNode* ReadSubtree(SgNode* node, int boardSize, SgPropPointFmt fmt); 00098 00099 bool ReadValue(std::string& value); 00100 }; 00101 00102 inline SgGameReader::Warnings SgGameReader::GetWarnings() const 00103 { 00104 return m_warnings; 00105 } 00106 00107 inline SgNode* SgGameReader::ReadGame() 00108 { 00109 return ReadGame(true); 00110 } 00111 00112 //---------------------------------------------------------------------------- 00113 00114 #endif // SG_GAMEREADER_H