00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef OST_IO_STAR_PARSER_HH
00020 #define OST_IO_STAR_PARSER_HH
00021
00022
00023
00024
00025
00026 #include <iostream>
00027 #include <vector>
00028 #include <map>
00029 #include <ost/string_ref.hh>
00030 #include <ost/io/module_config.hh>
00031
00032 namespace ost { namespace io {
00033
00034 class DLLEXPORT_OST_IO StarDataItem {
00035 public:
00036 StarDataItem(const StringRef& category, const StringRef& name,
00037 const StringRef& value):
00038 category_(category), name_(name), value_(value)
00039 { }
00040 const StringRef& GetCategory() const { return category_; }
00041 const StringRef& GetName() const { return name_; }
00042 const StringRef& GetValue() const { return value_; }
00043 private:
00044 StringRef category_;
00045 StringRef name_;
00046 StringRef value_;
00047 };
00048
00049 class DLLEXPORT_OST_IO StarLoopDesc {
00050 public:
00051 StarLoopDesc():
00052 category_("")
00053 { }
00054
00055 int GetIndex(const String& name) const
00056 {
00057 std::map<String, int>::const_iterator i=index_map_.find(name);
00058 return i==index_map_.end() ? -1 : i->second;
00059 }
00060
00061 void SetCategory(const StringRef& category)
00062 {
00063 category_=category.str();
00064 }
00065
00066 void Add(const StringRef& name)
00067 {
00068 index_map_.insert(std::make_pair(name.str(), index_map_.size()));
00069 }
00070 size_t GetSize() const
00071 {
00072 return index_map_.size();
00073 }
00074 const String& GetCategory() const { return category_; }
00075 private:
00076 String category_;
00077 std::map<String, int> index_map_;
00078 };
00079
00096 class DLLEXPORT_OST_IO StarParser {
00097 public:
00098 StarParser(std::istream& istream);
00099
00100 virtual ~StarParser() { }
00101
00102 public:
00107 virtual bool OnBeginLoop(const StarLoopDesc& header) { return true; }
00111 virtual void OnEndLoop() { }
00115 virtual void OnDataRow(const StarLoopDesc& header,
00116 const std::vector<StringRef>& columns)
00117 {
00118 }
00120 virtual void OnDataItem(const StarDataItem& item) { }
00121
00125 virtual bool OnBeginData(const StringRef& data_name) { return true; }
00126
00129 virtual void OnEndData() { }
00130 public:
00131 void Parse();
00132
00133 public:
00134 static bool SplitLine(const StringRef& line,
00135 std::vector<StringRef>& parts, bool clear=true);
00136 private:
00137 void ParseLoop();
00138 private:
00140 bool NextLine(StringRef& str)
00141 {
00142 if (std::getline(stream_, current_line_)) {
00143 str=StringRef(current_line_.data(), current_line_.length());
00144 ++line_num_;
00145 has_current_line_=true;
00146 return true;
00147 }
00148 return false;
00149 }
00151 bool GetLine(StringRef& ref)
00152 {
00153 if (has_current_line_) {
00154 ref=StringRef(current_line_.data(), current_line_.size());
00155 return true;
00156 }
00157 return this->NextLine(ref);
00158 }
00159
00160 void ConsumeLine()
00161 {
00162 assert(has_current_line_);
00163 has_current_line_=false;
00164 }
00165 void ParseGlobal();
00166 void ParseData();
00167 void ParseDataItem();
00168 void DiagnoseUnknown();
00169 bool ParseMultilineValue(String& value, bool skip=false);
00170 std::istream& stream_;
00171 int line_num_;
00172 bool has_current_line_;
00173 String current_line_;
00174 };
00175
00176 }}
00177
00178 #endif