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 template <class T>
00039 const T get(const std::string& key) const {
00040 return util::parseValue<T>(get(key));
00041 }
00042
00043 void set(const std::string& key, const std::string& value);
00044 void add(const std::string& key, const std::string& value);
00045 void removeAll(const std::string& key);
00046
00047 const std::vector< std::pair<std::string, std::string> >& getMap() const
00048 {
00049 return kv_;
00050 }
00051
00053 void initDefaults(const char* softwareVersion = 0);
00054
00057 void transfer(const DelimitedFileMetadata& src,
00058 const std::string& keys,
00059 const std::string& prefix = "");
00060
00062 void sort();
00063
00064 void setFileName(const std::string& fn)
00065 {
00066 fileName_ = fn;
00067 }
00068
00069 private:
00070 std::vector< std::pair<std::string, std::string> > kv_;
00071 std::string fileName_;
00072
00073 void reportError(const std::string& error) const;
00074 };
00075
00076 std::ostream& operator<< (std::ostream& out, const DelimitedFileMetadata& meta);
00077
00089 class DelimitedFile : boost::noncopyable
00090 {
00091 public:
00092 typedef DelimitedFileMetadata Metadata;
00093 typedef DelimitedLineParser::EmptyFieldHandling EmptyFieldHandling;
00094 typedef DelimitedLineParser::StrictnessChecking StrictnessChecking;
00095
00096 explicit DelimitedFile(
00097 std::istream& in,
00098 const std::string& fileName ,
00099 char delimiter = '\t',
00100 EmptyFieldHandling emptyHandling = DelimitedLineParser::PROCESS_EMPTY_FIELDS,
00101 StrictnessChecking strictnessChecking = DelimitedLineParser::RELAXED_CHECKING);
00102
00103 enum FieldParserType
00104 {
00105 REQUIRED = 0,
00106 OPTIONAL = 1
00107 };
00108 template <class Field>
00109 void addField(const Field& parser, FieldParserType ft = REQUIRED)
00110 {
00111 int count = 0;
00112 for(size_t ii=0; ii<columnHeaders_.size(); ii++)
00113 {
00114 if (columnHeadersEqual(columnHeaders_[ii], parser.getName()))
00115 {
00116 lp_.setField(ii, parser);
00117 count++;
00118 }
00119 }
00120 if (0 == count && OPTIONAL != ft)
00121 reportError("missing required field: "+parser.getName());
00122 if (count > 1)
00123 reportError("multiple fields with same name: "+parser.getName());
00124 }
00125
00126 void addAllFields(std::vector<std::string>& fields);
00127
00128 bool next();
00129
00130 const Metadata& getMetadata() const
00131 {
00132 return metadata_;
00133 }
00134
00135 const std::vector<std::string>& getColumnHeaders() const
00136 {
00137 return columnHeaders_;
00138 }
00139
00140 size_t getFieldOffset(const std::string& fieldName) const;
00141
00142 bool hasField(const std::string& fieldName) const;
00143
00144 DelimitedLineParser& getDelimitedLineParser()
00145 {
00146 return lp_;
00147 }
00148
00149 const std::string& getLine() const
00150 {
00151 return line_;
00152 }
00153
00154 private:
00155 void readHeader();
00156 void reportError(const std::string& error) const;
00157 bool columnHeadersEqual(const std::string& h1, const std::string& h2) const;
00158
00159 std::istream& in_;
00160 std::string fileName_;
00161 Metadata metadata_;
00162 std::vector<std::string> columnHeaders_;
00163 DelimitedLineParser lp_;
00164 std::string line_;
00165 char delimiter_;
00166 EmptyFieldHandling emptyHandling_;
00167 StrictnessChecking strictnessChecking_;
00168 size_t lineNo_;
00169 std::string activeLineSetId_;
00170 bool withinActiveLineSet_;
00171 };
00172
00173 } }
00174
00175 #endif // CGATOOLS_UTIL_DELIMITEDFILE_HPP_