00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef CGATOOLS_UTIL_DELIMITEDLINEPARSER_HPP_
00016 #define CGATOOLS_UTIL_DELIMITEDLINEPARSER_HPP_ 1
00017
00021
00022 #include "cgatools/core.hpp"
00023 #include "cgatools/util/parse.hpp"
00024 #include "cgatools/util/Exception.hpp"
00025
00026 #include <string>
00027 #include <vector>
00028
00029 #include <boost/shared_ptr.hpp>
00030 #include <boost/array.hpp>
00031
00032 #include <cstring>
00033
00034 namespace cgatools { namespace util {
00035
00037 class DelimitedFieldParser
00038 {
00039 public:
00040 DelimitedFieldParser(const std::string& name)
00041 : name_(name)
00042 {
00043 }
00044
00045 virtual ~DelimitedFieldParser()
00046 {
00047 }
00048
00049 const std::string& getName() const
00050 {
00051 return name_;
00052 }
00053
00058 virtual void parse(const char* first, const char* last) = 0;
00059
00060 protected:
00062 std::string name_;
00063 };
00064
00066 class IgnoreField : public DelimitedFieldParser
00067 {
00068 public:
00069 IgnoreField(const std::string& name)
00070 : DelimitedFieldParser(name)
00071 {
00072 }
00073
00074 void parse(const char* first, const char* last)
00075 {
00076 }
00077 };
00078
00081 template <typename Value>
00082 class ValueField : public DelimitedFieldParser
00083 {
00084 public:
00085 ValueField(const std::string& name, Value* val)
00086 : DelimitedFieldParser(name),
00087 val_(val)
00088 {
00089 }
00090
00091 void parse(const char* first, const char* last)
00092 {
00093 for(size_t ii=0; ii<exceptions_.size(); ii++)
00094 {
00095 if (0 == std::strcmp(first, exceptions_[ii].first.c_str()))
00096 {
00097 *val_ = exceptions_[ii].second;
00098 return;
00099 }
00100 }
00101
00102 *val_ = parseValue<Value>(first, last);
00103 }
00104
00107 ValueField<Value>& exception(const std::string& key, const Value& val)
00108 {
00109 exceptions_.push_back(make_pair(key, val));
00110 return *this;
00111 }
00112
00113 private:
00114 Value* val_;
00115 std::vector< std::pair<std::string, Value> > exceptions_;
00116 };
00117
00119 class StringField : public DelimitedFieldParser
00120 {
00121 public:
00122 StringField(const std::string& name, std::string* val)
00123 : DelimitedFieldParser(name),
00124 val_(val)
00125 {
00126 }
00127
00128 void parse(const char* first, const char* last);
00129
00130 private:
00131 std::string* val_;
00132 };
00134 class CharField : public DelimitedFieldParser
00135 {
00136 public:
00137 CharField(const std::string& name, char* val)
00138 : DelimitedFieldParser(name),
00139 val_(val)
00140 {
00141 }
00142
00143 void parse(const char* first, const char* last);
00144
00145 private:
00146 char* val_;
00147 };
00148
00149 class StrandField : public DelimitedFieldParser
00150 {
00151 public:
00152 StrandField(const std::string& name, bool* val)
00153 : DelimitedFieldParser(name),
00154 val_(val)
00155 {
00156 }
00157
00158 void parse(const char* first, const char* last);
00159
00160 private:
00161 bool* val_;
00162 };
00163
00165 class DelimitedLineParser
00166 {
00167 friend class DelimitedFile;
00168 public:
00171 enum EmptyFieldHandling
00172 {
00175 PROCESS_EMPTY_FIELDS = 0,
00178 SKIP_EMPTY_FIELDS = 1
00179 };
00180
00183 enum StrictnessChecking
00184 {
00187 STRICT_CHECKING = 0,
00190 RELAXED_CHECKING = 1
00191 };
00192
00193 typedef std::vector< boost::shared_ptr<DelimitedFieldParser> > Fields;
00194
00196 DelimitedLineParser();
00197
00201 template <class Field>
00202 DelimitedLineParser& addField(const Field& field)
00203 {
00204 boost::shared_ptr<Field> ptr(new Field(field));
00205 fields_.push_back(ptr);
00206 return *this;
00207 }
00208
00210 template <class Field>
00211 DelimitedLineParser& setField(size_t offset, const Field& field)
00212 {
00213 CGA_ASSERT(offset < fields_.size());
00214 boost::shared_ptr<Field> ptr(new Field(field));
00215 fields_[offset] = ptr;
00216 return *this;
00217 }
00218
00222 void parseLine(std::string& line,
00223 char delimiter = '\t',
00224 EmptyFieldHandling emptyHandling = PROCESS_EMPTY_FIELDS,
00225 StrictnessChecking strictnessChecking = RELAXED_CHECKING);
00226
00228 const Fields& getFields() const {return fields_;}
00229
00230 private:
00231 Fields fields_;
00232 };
00233
00234 } }
00235
00236 #endif // CGATOOLS_UTIL_DELIMITEDLINEPARSER_HPP_