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:
00034 int getFormatVersion() const;
00035
00036 bool hasKey(const std::string& key) const;
00037 const std::string& get(const std::string& key) const;
00038
00039 void set(const std::string& key, const std::string& value);
00040 void add(const std::string& key, const std::string& value);
00041 void removeAll(const std::string& key);
00042
00043 const std::vector< std::pair<std::string, std::string> >& getMap() const
00044 {
00045 return kv_;
00046 }
00047
00048 private:
00049 std::vector< std::pair<std::string, std::string> > kv_;
00050 };
00051
00052 std::ostream& operator<< (std::ostream& out, const DelimitedFileMetadata& meta);
00053
00065 class DelimitedFile : boost::noncopyable
00066 {
00067 public:
00068 typedef DelimitedFileMetadata Metadata;
00069 typedef DelimitedLineParser::EmptyFieldHandling EmptyFieldHandling;
00070
00071 explicit DelimitedFile(std::istream& in,
00072 char delimiter = '\t',
00073 EmptyFieldHandling emptyHandling = DelimitedLineParser::PROCESS_EMPTY_FIELDS);
00074
00075 enum FieldParserType
00076 {
00077 REQUIRED = 0,
00078 OPTIONAL = 1
00079 };
00080 template <class Field>
00081 void addField(const Field& parser, FieldParserType ft = REQUIRED)
00082 {
00083 int count = 0;
00084 for(size_t ii=0; ii<columnHeaders_.size(); ii++)
00085 {
00086 if (columnHeadersEqual(columnHeaders_[ii], parser.getName()))
00087 {
00088 lp_.setField(ii, parser);
00089 count++;
00090 }
00091 }
00092 if (0 == count && OPTIONAL != ft)
00093 throw Exception("missing required field: "+parser.getName());
00094 if (count > 1)
00095 throw Exception("multiple fields with same name: "+parser.getName());
00096 }
00097
00098 void addAllFields(std::vector<std::string>& fields);
00099
00100 bool next();
00101
00102 const Metadata& getMetadata() const
00103 {
00104 return metadata_;
00105 }
00106
00107 const std::vector<std::string>& getColumnHeaders() const
00108 {
00109 return columnHeaders_;
00110 }
00111
00112 size_t getFieldOffset(const std::string& fieldName) const;
00113
00114 bool hasField(const std::string& fieldName) const;
00115
00116 DelimitedLineParser& getDelimitedLineParser()
00117 {
00118 return lp_;
00119 }
00120
00121 const std::string& getLine() const
00122 {
00123 return line_;
00124 }
00125
00126 private:
00127 void readHeader();
00128 bool columnHeadersEqual(const std::string& h1, const std::string& h2) const;
00129
00130 std::istream& in_;
00131 Metadata metadata_;
00132 std::vector<std::string> columnHeaders_;
00133 DelimitedLineParser lp_;
00134 std::string line_;
00135 char delimiter_;
00136 EmptyFieldHandling emptyHandling_;
00137 };
00138
00139 } }
00140
00141 #endif // CGATOOLS_UTIL_DELIMITEDFILE_HPP_