////////////////////////////////////////////////////////////////////// // String Utilities // Written by Jonathan A. Foster // Started April 23rd, 2021 // Copyright JF Possibilities, Inc. All rights reserved. // // This is useful for breaking a text file line into fields. // // 2021-05-14 // Restructure: broke out of monolithic iptraffic.cpp and made its // own module. ////////////////////////////////////////////////////////////////////// #ifndef __JFP_STRUTIL_H__ #define __JFP_STRUTIL_H__ #include #include #include #include ////////////////////////////////////////////////////////////////////// // Useful typedefs ////////////////////////////////////////////////////////////////////// typedef std::vector StringList; typedef std::map NameVal; ////////////////////////////////////////////////////////////////////// // Splits: a util class to divide a line into space sep pieces ////////////////////////////////////////////////////////////////////// // TODO: implement begin() + end() to make "for( : )" work // TODO: implement field enclosing & escaping chars struct Splits { /// CONFIG /// enum { FieldMax=256, LineMax=1024 }; /// properties /// char line[LineMax]; // Line buffer int len; // Length of line (after split()) char sep; // Separator character. bool combine; // Treat multiple consecutive seps as one (combine) char *fields[FieldMax]; // pointers to fields in line int count; // How many fields there were // construct Splits(): count(0), len(0), sep(' '), combine(true) { line[LineMax-1] = 0; } Splits(const std::string &_line) { *this=_line; } // Assign from string inline Splits &operator=(const std::string &_line) { return *this=_line.c_str(); } Splits &operator=(const char *_line); // Convert field[] to string inline std::string operator[](int i) const { std::string s(fields[i]); return s; } // split line. Returns count. int split(); }; // istream >> operator: getline() + .split() std::istream &operator>>(std::istream &in, Splits &sp); ////////////////////////////////////////////////////////////////////// // TSV version of Splits ////////////////////////////////////////////////////////////////////// struct TSV: public Splits { TSV() { sep='\t'; combine=false; } // Need some weird casties to make C++ remember its base class TSV(const std::string &_line): Splits(_line) {} inline TSV &operator=(const std::string &_line) { return *this=_line.c_str(); } inline TSV &operator=(const char *_line) { *((Splits *)this)=_line; return *this; } }; ////////////////////////////////////////////////////////////////////// // Function to match a list of prefixes against a string // // Since C++ < 11 doesn't support constant vector initialization we'll // do this the old fashioned way with a null terminated char*[]. ////////////////////////////////////////////////////////////////////// bool pre_match(const char **list, const std::string &s); // And if vectors can be used... bool pre_match(const StringList &list, const std::string &s); ////////////////////////////////////////////////////////////////////// // Strip leading and trailing space from a string ////////////////////////////////////////////////////////////////////// std::string strip(const std::string &s); #endif