/* * This file is a part of Winix * and is not publicly distributed * * Copyright (c) 2008-2011, Tomasz Sowa * All rights reserved. * */ #ifndef headerfile_winix_core_misc #define headerfile_winix_core_misc #include #include #include #include #include "item.h" #include "requesttypes.h" /* conversions between text and numbers */ int Toi(const std::string & str, int base = 10); int Toi(const std::wstring & str, int base = 10); int Toi(const char * str, int base = 10); int Toi(const wchar_t * str, int base = 10); long Tol(const std::string & str, int base = 10); long Tol(const std::wstring & str, int base = 10); long Tol(const char * str, int base = 10); long Tol(const wchar_t * str, int base = 10); // if the buffer is too small it will be terminated at the beginning (empty string) // and the function returns false template bool Toa(unsigned long value, CharType * buffer, size_t buf_len, int base = 10) { size_t i1, i2; long rest; if( buf_len == 0 ) return false; i1 = i2 = 0; if( base < 2 ) base = 2; if( base > 16 ) base = 16; do { rest = value % base; value = value / base; buffer[i2++] = (rest < 10) ? char(rest) + '0' : char(rest) - 10 + 'A'; } while(value != 0 && i2 < buf_len); if( i2 >= buf_len ) { buffer[0] = 0; // ops, the buffer was too small return false; } buffer[i2--] = 0; for( ; i1 < i2 ; ++i1, --i2) { CharType temp = buffer[i1]; buffer[i1] = buffer[i2]; buffer[i2] = temp; } return true; } // if the buffer is too small it will be terminated at the beginning (empty string) // and the function returns false template bool Toa(long value, CharType * buffer, size_t buf_len, int base = 10) { if( buf_len == 0 ) return false; CharType * buf = buffer; if( value < 0 ) { buffer[0] = '-'; buf += 1; buf_len -= 1; value = -value; } bool res = Toa(static_cast(value), buf, buf_len, base); if( !res ) buffer[0] = 0; return res; } template bool Toa(unsigned int value, CharType * buffer, size_t buf_len, int base = 10) { return Toa(static_cast(value), buffer, buf_len, base); } template bool Toa(int value, CharType * buffer, size_t buf_len, int base = 10) { return Toa(static_cast(value), buffer, buf_len, base); } // warning: it uses its own static buffer // one buffer for both these functions const wchar_t * Toa(unsigned int value, int base = 10); const wchar_t * Toa(unsigned long value, int base = 10); const wchar_t * Toa(int value, int base = 10); const wchar_t * Toa(long value, int base = 10); void Toa(int value, std::string & res, int base = 10, bool clear = true); void Toa(long value, std::string & res, int base = 10, bool clear = true); void Toa(int value, std::wstring & res, int base = 10, bool clear = true); void Toa(long value, std::wstring & res, int base = 10, bool clear = true); /* conversions between ascii text and wide characters (destination is always std::string or std::wstring) characters are copied as they are without any locales checking */ void AssignString(const char * src, size_t len, std::wstring & dst, bool clear = true); void AssignString(const char * src, std::wstring & dst, bool clear = true); void AssignString(const std::string & src, std::wstring & dst, bool clear = true); void AssignString(const wchar_t * src, size_t len, std::string & dst, bool clear = true); void AssignString(const wchar_t * src, std::string & dst, bool clear = true); void AssignString(const std::wstring & src, std::string & dst, bool clear = true); void AssignString(const char * src, size_t len, std::string & dst, bool clear = true); void AssignString(const char * src, std::string & dst, bool clear = true); void AssignString(const std::string & src, std::string & dst, bool clear = true); void AssignString(const wchar_t * src, size_t len, std::wstring & dst, bool clear = true); void AssignString(const wchar_t * src, std::wstring & dst, bool clear = true); void AssignString(const std::wstring & src, std::wstring & dst, bool clear = true); bool CorrectUrlChar(wchar_t c); void CorrectUrlDots(std::wstring & url); void CorrectUrlChars(std::wstring & url); void CorrectUrlOnlyAllowedChar(std::wstring & url); const wchar_t * DateToStr(int year, int month, int day); const wchar_t * DateToStr(int year, int month, int day, int hour, int min, int sec); const wchar_t * DateToStr(const tm * ptm); const wchar_t * DateToStr(const tm & rtm); const wchar_t * DateToStr(time_t t); const wchar_t * DateToStrWithoutHours(const tm * ptm); const wchar_t * DateToStrWithoutHours(const tm & rtm); const wchar_t * DateToStrWithoutHours(time_t t); const char * DateToStrCookie(int year, int month, int day, int hour, int min, int sec); const char * DateToStrCookie(const tm * ptm); const char * DateToStrCookie(const tm & rtm); const char * DateToStrCookie(time_t t); const wchar_t * IpToStr(unsigned int ip_); bool IsWhite(wchar_t s); template void TrimWhite(StringType & s) { typename StringType::size_type i; if( s.empty() ) return; // looking for white characters at the end for(i=s.size()-1 ; i>0 && IsWhite(s[i]) ; --i); if( i==0 && IsWhite(s[i]) ) { // the whole string has white characters s.clear(); return; } // deleting white characters at the end if( i != s.size() - 1 ) s.erase(i+1, StringType::npos); // looking for white characters at the beginning for(i=0 ; i void Trim(StringType & s, wchar_t c) { typename StringType::size_type i; if( s.empty() ) return; // looking for the 'c' characters at the end for(i=s.size()-1 ; i>0 && s[i]==c ; --i); if( i==0 && s[i]==c ) { // the whole string has the 'c' characters s.clear(); return; } // deleting 'c' characters at the end if( i != s.size() - 1 ) s.erase(i+1, StringType::npos); // looking for the 'c' characters at the beginning for(i=0 ; i bool IsSubString(const StringType1 * short_str, const StringType2 * long_str) { while( *short_str && *long_str && wchar_t(*short_str) == wchar_t(*long_str) ) { ++short_str; ++long_str; } if( *short_str == 0 ) return true; return false; } template bool IsSubString(const StringType1 & short_str, const StringType2 & long_str) { return IsSubString(short_str.c_str(), long_str.c_str()); } template bool IsSubStringNoCase(const StringType1 * short_str, const StringType2 * long_str) { while( *short_str && *long_str && ToSmall(*short_str) == ToSmall(*long_str) ) { ++short_str; ++long_str; } if( *short_str == 0 ) return true; return false; } template bool IsSubStringNoCase(const StringType1 & short_str, const StringType2 & long_str) { return IsSubStringNoCase(short_str.c_str(), long_str.c_str()); } template bool Equal(const StringType1 * str1, const StringType2 * str2) { while( *str1 && *str2 && wchar_t(*str1) == wchar_t(*str2) ) { ++str1; ++str2; } if( *str1 == 0 && *str2 == 0 ) return true; return false; } template bool Equal(const StringType1 & str1, const StringType2 & str2) { return Equal(str1.c_str(), str2.c_str()); } template bool EqualNoCase(const StringType1 * str1, const StringType2 * str2) { while( *str1 && *str2 && ToSmall(*str1) == ToSmall(*str2) ) { ++str1; ++str2; } if( *str1 == 0 && *str2 == 0 ) return true; return false; } template bool EqualNoCase(const StringType1 & str1, const StringType2 & str2) { return EqualNoCase(str1.c_str(), str2.c_str()); } template void NoLastSlash(StringType & s) { if( s.empty() ) return; size_t i = s.size(); for( ; i>0 && s[i-1]=='/' ; --i); if( i < s.size() ) s.erase(i); } template void NoFirstHttp(StringType & s) { if( s.empty() ) return; const char http[] = "http://"; const char https[] = "https://"; if( IsSubStringNoCase(http, s.c_str()) ) { s.erase(0, sizeof(http)/sizeof(char)); } else if( IsSubStringNoCase(https, s.c_str()) ) { s.erase(0, sizeof(https)/sizeof(char)); } } /* this method returns true if there are two dots meaning 'go up' somewhere in the path for example such paths return true: ".." "test/../path" "test/where/../" "test/where/.." "../abc" */ template bool PathHasUpDir(const StringType * str) { size_t i = 0; while( str[i] ) { if( str[i]=='.' && str[i+1]=='.' ) { i += 2; if( str[i]=='/' || str[i]==0 ) return true; } // skipping until to next slash while( str[i] && str[i]!='/' ) i += 1; // skipping the slash (or slashes) while( str[i]=='/' ) i += 1; } return false; } template bool PathHasUpDir(const StringType & str) { return PathHasUpDir(str.c_str()); } /* this method calculates how many directories there are in the given path input: str - path last_is_dir - true if the last part of the path should be treated as a directory too samples: HowManyDirs("", false) -> 0 HowManyDirs("", true) -> 0 HowManyDirs("abc", false) -> 0 HowManyDirs("abc", true) -> 1 HowManyDirs("/abc/", true) -> 1 HowManyDirs("////", false) -> 0 HowManyDirs("////", true) -> 0 HowManyDirs("////abc", false) -> 0 HowManyDirs("////abc", true) -> 1 HowManyDirs("/var/static", false) -> 1 HowManyDirs("/var/static", true) -> 2 HowManyDirs("/var/static/", false) -> 2 HowManyDirs("/var/static/", true) -> 2 */ template size_t HowManyDirs(const StringType * str, bool is_last_dir = false) { size_t res = 0; size_t i = 0; // first slash (root dir) is not calculated while( str[i]=='/' ) i += 1; while( str[i] ) { if( str[i]=='/' ) { res += 1; while( str[i]=='/' ) i += 1; } else { i += 1; } } if( is_last_dir && i>0 && str[i-1]!='/' ) res += 1; return res; } template size_t HowManyDirs(const StringType & str, bool is_last_dir = false) { return HowManyDirs(str.c_str(), is_last_dir); } /* this method skips some first directories from given path samples: SkipDirs("/var/test", 1) -> "test" SkipDirs("/var/test/somewhere", 1) -> "test/somewhere" SkipDirs("/var/test/somewhere", 2) -> "somewhere" SkipDirs("/var/test/somewhere", 10) -> "" */ template const StringType * SkipDirs(const StringType * str, size_t how_many_skip) { size_t i = 0; size_t skipped = 0; if( how_many_skip == 0 ) return str; // first slash (root dir) is not calculated while( str[i]=='/' ) i += 1; while( str[i] ) { if( str[i]=='/' ) { skipped += 1; while( str[i]=='/' ) i += 1; if( skipped == how_many_skip ) return str+i; } else { i += 1; } } return str + i; } bool ValidateEmail(const std::wstring & email); bool IsFile(const wchar_t * file); bool IsFile(const std::wstring & file); bool CreateDir(const wchar_t * dir, int priv); bool CreateDir(const std::wstring & dir, int priv); // creating directories (dirs) under base_dir (base_dir must exist) // if skip_last == true then last part from dir is treated as a file (the last directory is not created) bool CreateDirs(const wchar_t * base_dir, const wchar_t * dirs, int priv = 0755, bool skip_last = false); bool CreateDirs(const std::wstring & base_dir, const std::wstring & dirs, int priv = 0755, bool skip_last = false); bool CopyFile(FILE * in, FILE * out); bool CopyFile(const wchar_t * src, const wchar_t * dst); bool CopyFile(const std::wstring & src, const std::wstring & dst); bool RemoveFile(const wchar_t * file); bool RemoveFile(const std::wstring & file); bool RenameFile(const wchar_t * from, const wchar_t * to); bool RenameFile(const std::wstring & from, const std::wstring & to); bool GetUTF8File(const char * file_path, std::wstring & content, bool clear_content = true); bool GetUTF8File(const wchar_t * file_path, std::wstring & content, bool clear_content = true); bool GetUTF8File(const std::string & file_path, std::wstring & content, bool clear_content = true); bool GetUTF8File(const std::wstring & file_path, std::wstring & content, bool clear_content = true); const wchar_t * GetFileExt(const wchar_t * name); int SelectFileType(const wchar_t * file_name); int SelectFileType(const std::wstring & file_name); time_t Time(const tm & par); time_t Time(const tm * par); tm Time(time_t par); void UrlEncode(const std::string & in, std::string & out, bool clear_out = true); void UrlEncode(const std::wstring & in, std::string & out, bool clear_out = true); void QEncode(const std::wstring & in, std::string & out, bool clear = true); void RemovePostFileTmp(PostFileTab & post_file_tab); #endif