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 */ 00027 class SgGameReader 00028 { 00029 public: 00030 /** Warning conditions that occurred during reading. 00031 @todo Some of these warnings should be errors. 00032 */ 00033 enum WarningFlags { 00034 /** Invalid board size. 00035 The file contained a size property with a value not in 00036 [SG_MIN_SIZE..SG_MAX_SIZE]. 00037 */ 00038 INVALID_BOARDSIZE, 00039 00040 PROPERTY_WITHOUT_VALUE, 00041 00042 /** Number of WarningFlags. */ 00043 NU_WARNING_FLAGS 00044 }; 00045 00046 /** Warnings that occurred during reading. */ 00047 typedef std::bitset<NU_WARNING_FLAGS> Warnings; 00048 00049 /** Create reader from an input stream. 00050 @param in The input stream. 00051 @param defaultSize The (game-dependent) default board size, if file 00052 contains no SZ property. 00053 no SZ property. 00054 */ 00055 SgGameReader(std::istream& in, int defaultSize = 19); 00056 00057 /** Get warnings of last ReadGame or ReadGames. */ 00058 Warnings GetWarnings() const; 00059 00060 /** Print warnings of last ReadGame or ReadGames to stream. 00061 Prints the warnings as human readable text. 00062 */ 00063 void PrintWarnings(std::ostream& out) const; 00064 00065 /** Read next game tree from file. 00066 @return Root node or 0 if there is no next game. 00067 */ 00068 SgNode* ReadGame(); 00069 00070 /** Read all game trees from this file. 00071 Return a list with the root of each game tree. 00072 */ 00073 void ReadGames(SgVectorOf<SgNode>* rootList); 00074 00075 private: 00076 /** Map label to values (unparsed) */ 00077 typedef std::map<std::string, std::vector<std::string> > RawProperties; 00078 00079 std::istream& m_in; 00080 00081 const int m_defaultSize; 00082 00083 /** The file format read in. */ 00084 int m_fileFormat; 00085 00086 Warnings m_warnings; 00087 00088 /** Not implemented. */ 00089 SgGameReader(const SgGameReader&); 00090 00091 /** Not implemented. */ 00092 SgGameReader& operator=(const SgGameReader&); 00093 00094 static bool GetIntProp(const RawProperties& properties, 00095 const std::string& label, int& value); 00096 00097 void HandleProperties(SgNode* node, const RawProperties& properties, 00098 int& boardSize, SgPropPointFmt& fmt); 00099 00100 SgNode* ReadGame(bool resetWarnings); 00101 00102 std::string ReadLabel(int c); 00103 00104 SgNode* ReadSubtree(SgNode* node, int boardSize, SgPropPointFmt fmt); 00105 00106 bool ReadValue(std::string& value); 00107 }; 00108 00109 inline SgGameReader::Warnings SgGameReader::GetWarnings() const 00110 { 00111 return m_warnings; 00112 } 00113 00114 inline SgNode* SgGameReader::ReadGame() 00115 { 00116 return ReadGame(true); 00117 } 00118 00119 //---------------------------------------------------------------------------- 00120 00121 #endif // SG_GAMEREADER_H