]> git.tdb.fi Git - libs/core.git/commitdiff
Add documentation for all functions in utils
authorMikko Rasa <tdb@tdb.fi>
Tue, 7 Aug 2007 17:17:24 +0000 (17:17 +0000)
committerMikko Rasa <tdb@tdb.fi>
Tue, 7 Aug 2007 17:17:24 +0000 (17:17 +0000)
Add c_escape and c_unescape functions

source/utils.cpp
source/utils.h

index 244055b232cb81df6347f9200d315683d372aff3..9898a07dca5fe52d8511ad71da78c4f5e8b864cb 100644 (file)
@@ -6,6 +6,7 @@ Distributed under the LGPL
 */
 
 #include <list>
+#include <msp/core/error.h>
 #include "utils.h"
 
 using namespace std;
@@ -48,14 +49,6 @@ vector<string> do_split(const string &str, const string &sep, int max_split)
 
 namespace Msp {
 
-/**
-Compares two strings, ignoring case.
-
-@param   s1  First string
-@param   s2  Second string
-
-@return  -1 if s1<s2, 0 if s1==s2, 1 if s1>s2
-*/
 int strcasecmp(const string &s1, const string &s2)
 {
        string::const_iterator i1=s1.begin();
@@ -71,9 +64,6 @@ int strcasecmp(const string &s1, const string &s2)
        return 0;
 }
 
-/**
-Returns a lowercase copy of the given string.
-*/
 string tolower(const string &str)
 {
        string result(str);
@@ -81,9 +71,6 @@ string tolower(const string &str)
        return result;
 }
 
-/**
-Returns an uppercase copy of the given string.
-*/
 string toupper(const string &str)
 {
        string result(str);
@@ -91,14 +78,14 @@ string toupper(const string &str)
        return result;
 }
 
-vector<string> split_fields(const string &str, const string &sep, int max_split)
+vector<string> split(const string &str, const string &sep, int max_split)
 {
-       return do_split<true, true>(str, sep, max_split);
+       return do_split<false, false>(str, sep, max_split);
 }
 
-vector<string> split_fields(const string &str, char sep, int max_split)
+vector<string> split(const string &str, char sep, int max_split)
 {
-       return split_fields(str, string(1, sep), max_split);
+       return split(str, string(1, sep), max_split);
 }
 
 vector<string> split_long(const string &str, const string &sep, int max_split)
@@ -106,14 +93,14 @@ vector<string> split_long(const string &str, const string &sep, int max_split)
        return do_split<true, false>(str, sep, max_split);
 }
 
-vector<string> split(const string &str, const string &sep, int max_split)
+vector<string> split_fields(const string &str, const string &sep, int max_split)
 {
-       return do_split<false, false>(str, sep, max_split);
+       return do_split<true, true>(str, sep, max_split);
 }
 
-vector<string> split(const string &str, char sep, int max_split)
+vector<string> split_fields(const string &str, char sep, int max_split)
 {
-       return split(str, string(1, sep), max_split);
+       return split_fields(str, string(1, sep), max_split);
 }
 
 /**
@@ -158,38 +145,142 @@ vector<string> split(const string &str, char sep, bool allow_empty)
        return split(str, string(1, sep), allow_empty);
 }
 
-/**
-Builds a single string from the strings in the given sequence by concatenating
-them.
+string strip(const string &s)
+{
+       string result=s;
+       if(!result.erase(0, result.find_first_not_of(" \t\r\n")).empty())
+               result.erase(result.find_last_not_of(" \t\r\n")+1);
+       return result;
+}
 
-@param  seq  A sequence of strings
-@param  sep  Separator to be inserted between strings
-*/
-template<typename T>
-string join(const T &seq, const string &sep)
+string c_unescape(const std::string &str)
 {
+       bool escape=false;
+       unsigned numeric_type=0;
+       unsigned numeric_pos=0;
+       unsigned numeric_value=0;
        string result;
-       for(typename T::const_iterator i=seq.begin(); i!=seq.end(); ++i)
+       for(string::const_iterator i=str.begin(); i!=str.end(); ++i)
        {
-               if(i!=seq.begin())
-                       result+=sep;
-               result+=*i;
+               if(numeric_type==1)
+               {
+                       unsigned digit=0;
+                       if(*i>='0' && *i<='9')
+                               digit=*i-'0';
+                       else if(*i>='a' && *i<='f')
+                               digit=*i-'a'+10;
+                       else if(*i>='A' && *i<='F')
+                               digit=*i-'A'+10;
+                       else
+                               throw InvalidParameterValue("Invalid hexadecimal digit");
+
+                       numeric_value=(numeric_value<<4 | digit);
+                       ++numeric_pos;
+                       if(numeric_pos==2)
+                       {
+                               result+=numeric_value;
+                               numeric_type=0;
+                       }
+               }
+               else if(numeric_type==2)
+               {
+                       unsigned digit=0;
+                       if(*i>='0' && *i<='7')
+                               digit=*i-'0';
+                       else
+                               throw InvalidParameterValue("Invalid octal digit");
+
+                       if(numeric_pos==0 && digit>3)
+                               throw InvalidParameterValue("Octal escape sequence must start with [0-3]");
+
+                       numeric_value=(numeric_value<<3 | digit);
+                       ++numeric_pos;
+                       if(numeric_pos==2)
+                       {
+                               result+=numeric_value;
+                               numeric_type=0;
+                       }
+               }
+               else if(escape)
+               {
+                       if(*i=='x' || (*i>='0' && *i<='7'))
+                       {
+                               numeric_type=(*i=='x' ? 1 : 2);
+                               numeric_pos=0;
+                               numeric_value=0;
+                       }
+                       else if(*i=='n')
+                               result+='\n';
+                       else if(*i=='t')
+                               result+='\t';
+                       else if(*i=='r')
+                               result+='\r';
+                       else if(*i=='b')
+                               result+='\b';
+                       else if(*i=='v')
+                               result+='\v';
+                       else if(*i=='a')
+                               result+='\a';
+                       else if(*i=='f')
+                               result+='\f';
+                       else if(*i=='\"')
+                               result+='\"';
+                       else if(*i=='\'')
+                               result+='\'';
+                       else if(*i=='\\')
+                               result+='\\';
+                       else
+                               throw InvalidParameterValue("Invalid escape sequence");
+
+                       escape=false;
+               }
+               else if(*i=='\\')
+                       escape=true;
+               else
+                       result+=*i;
        }
 
+       if(escape)      
+               throw InvalidParameterValue("Stray backslash at end of string");
+
        return result;
 }
-template string join<list<string> >(const list<string> &, const string &);
-template string join<vector<string> >(const vector<string> &, const string &);
 
-/**
-Returns a copy of the given string with leading and trailing whitespace
-removed.
-*/
-string strip(const string &s)
+string c_escape(const string &str, bool escape_8bit)
 {
-       string result=s;
-       if(!result.erase(0, result.find_first_not_of(" \t\r\n")).empty())
-               result.erase(result.find_last_not_of(" \t\r\n")+1);
+       string result;
+
+       for(string::const_iterator i=str.begin(); i!=str.end(); ++i)
+       {
+               if(*i=='\n')
+                       result+="\\n";
+               else if(*i=='\t')
+                       result+="\\t";
+               else if(*i=='\r')
+                       result+="\\r";
+               else if(*i=='\b')
+                       result+="\\b";
+               else if(*i=='\v')
+                       result+="\\v";
+               else if(*i=='\a')
+                       result+="\\a";
+               else if(*i=='\f')
+                       result+="\\f";
+               else if(*i=='\"')
+                       result+="\\\"";
+               else if(*i=='\'')
+                       result+="\\\'";
+               else if(*i=='\\')
+                       result+="\\\\";
+               else if(*i<' ' || (escape_8bit && (*i&0x80)))
+               {
+                       char buf[4]={'\\', (*i>>6)&7, (*i>>3)&7, *i&7};
+                       result.append(buf, 4);
+               }
+               else
+                       result+=*i;
+       }
+
        return result;
 }
 
index d0d8a171ba29740ecc406bc5b96f2889c45f5056..5492f9558ea4b22a36fcee2a4bcc437c4cfd4b88 100644 (file)
@@ -13,20 +13,102 @@ Distributed under the LGPL
 
 namespace Msp {
 
-int strcasecmp(const std::string &, const std::string &);
+/**
+Compares two strings, ignoring upper/lower case.
+
+@param   s1  First string
+@param   s2  Second string
+
+@return  -1 if s1<s2, 0 if s1==s2, 1 if s1>s2
+*/
+int strcasecmp(const std::string &s1, const std::string &s2);
+
+/**
+Converts a string to lower case.
+*/
 std::string tolower(const std::string &);
+
+/**
+Converts a string to upper case.
+*/
 std::string toupper(const std::string &);
 
-std::vector<std::string> split_fields(const std::string &, const std::string &, int =-1);
-std::vector<std::string> split_fields(const std::string &, char, int =-1);
-std::vector<std::string> split_long(const std::string &, const std::string &, int =-1);
-std::vector<std::string> split(const std::string &, const std::string & =" \t\r\n", int =-1);
-std::vector<std::string> split(const std::string &, char, int =-1);
+/**
+Splits a string at occurrences of any of the characters in sep.  If max_split
+is non-negative, at most that many split will be performed, i.e. the resulting
+vector will contain at most max_split+1 elements.  Two or more consecutive
+separator characters will be treated as a single separator.
+
+@param   str        A string
+@param   sep        Separator characters
+@param   max_split  Maximum number of splits to perform
+*/
+std::vector<std::string> split(const std::string &str, const std::string &sep=" \t\r\n", int max_split=-1);
+
+/**
+Splits a string on occurrences of a single character.
+*/
+std::vector<std::string> split(const std::string &str, char sep, int max_split=-1);
+
+/**
+Splits a string on occurrences of another string.
+*/
+std::vector<std::string> split_long(const std::string &str, const std::string &sep, int max_split=-1);
+
+/**
+Splits a string on occurrences of another string.  Two consecutive separators
+will cause an empty string to be placed in the result.
+*/
+std::vector<std::string> split_fields(const std::string &str, const std::string &sep, int max_split=-1);
+
+/**
+Splits a string on occurrences of a single character.  Two consecutive
+separators will cause an empty string to be placed in the result.
+*/
+std::vector<std::string> split_fields(const std::string &str, char sep, int max_split=-1);
+
+/**
+Concatenates strings from an iterator range.
+
+@param  begin  First iterator
+@param  end    Last iterator
+@param  sep    Separator to be inserted between strings
+*/
+template<typename Iter>
+std::string join(Iter begin, Iter end, const std::string &sep=" ")
+{
+       std::string result;
+       for(Iter i=begin; i!=end; ++i)
+       {
+               if(i!=begin)
+                       result+=sep;
+               result+=*i;
+       }
+
+       return result;
+}
 
-template<typename T>
-std::string join(const T &, const std::string & =" ");
+/**
+Strips leading and trailing whitespace from a string.
+*/
 std::string strip(const std::string &);
 
+/**
+Unescapes a string with C escape sequences.
+*/
+std::string c_unescape(const std::string &str);
+
+/**
+Escapes any non-printable characters in a string with C escape sequences.
+
+@param   str          A string
+@param   escape_8bit  If true, consider characters with high bit set as
+                      non-printable
+
+@return  An escaped version of the string
+*/
+std::string c_escape(const std::string &str, bool escape_8bit=true);
+
 } // namespace Msp
 
 #endif