00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef CGATOOLS_UTIL_DELIMITEDFILE_HPP_
00016 #define CGATOOLS_UTIL_DELIMITEDFILE_HPP_ 1
00017
00019
00020 #include "cgatools/core.hpp"
00021 #include "cgatools/util/DelimitedLineParser.hpp"
00022
00023 #include <boost/noncopyable.hpp>
00024
00025 namespace cgatools { namespace util {
00026
00027 class DelimitedFileMetadata
00028 {
00029 public:
00030 bool hasKey(const std::string& key) const;
00031 const std::string& get(const std::string& key) const;
00032
00033 void set(const std::string& key, const std::string& value);
00034 void add(const std::string& key, const std::string& value);
00035 void removeAll(const std::string& key);
00036
00037 const std::vector< std::pair<std::string, std::string> >& getMap() const
00038 {
00039 return kv_;
00040 }
00041
00042 private:
00043 std::vector< std::pair<std::string, std::string> > kv_;
00044 };
00045
00057 class DelimitedFile : boost::noncopyable
00058 {
00059 public:
00060 typedef DelimitedFileMetadata Metadata;
00061 typedef DelimitedLineParser::EmptyFieldHandling EmptyFieldHandling;
00062
00063 explicit DelimitedFile(std::istream& in,
00064 char delimiter = '\t',
00065 EmptyFieldHandling emptyHandling = DelimitedLineParser::PROCESS_EMPTY_FIELDS);
00066
00067 enum FieldParserType
00068 {
00069 REQUIRED = 0,
00070 OPTIONAL = 1
00071 };
00072 template <class Field>
00073 void addField(const Field& parser, FieldParserType ft = REQUIRED)
00074 {
00075 for(size_t ii=0; ii<columnHeaders_.size(); ii++)
00076 {
00077 if (columnHeaders_[ii] == parser.getName())
00078 {
00079 lp_.setField(ii, parser);
00080 return;
00081 }
00082 }
00083 if (OPTIONAL != ft)
00084 throw Exception("missing required field: "+parser.getName());
00085 }
00086
00087 bool next();
00088
00089 const Metadata& getMetadata() const
00090 {
00091 return metadata_;
00092 }
00093
00094 const std::vector<std::string>& getColumnHeaders() const
00095 {
00096 return columnHeaders_;
00097 }
00098
00099 bool hasField(const std::string& fieldName) const;
00100
00101 DelimitedLineParser& getDelimitedLineParser()
00102 {
00103 return lp_;
00104 }
00105
00106 const std::string& getLine() const
00107 {
00108 return line_;
00109 }
00110
00111 private:
00112 void readHeader();
00113
00114 std::istream& in_;
00115 Metadata metadata_;
00116 std::vector<std::string> columnHeaders_;
00117 DelimitedLineParser lp_;
00118 std::string line_;
00119 char delimiter_;
00120 EmptyFieldHandling emptyHandling_;
00121 };
00122
00123 } }
00124
00125 #endif // CGATOOLS_UTIL_DELIMITEDFILE_HPP_