/* * This file is a part of Winix * and is not publicly distributed * * Copyright (c) 2008-2012, Tomasz Sowa * All rights reserved. * */ #include #include #include #include "misc.h" #include "log.h" #include "templates/templates.h" #include "utf8/utf8.h" namespace misc_private { std::ifstream get_file_content; std::string get_file_content_ansi; } int Toi(const std::string & str, int base) { return Toi(str.c_str(), base); } int Toi(const std::wstring & str, int base) { return Toi(str.c_str(), base); } int Toi(const char * str, int base) { return static_cast(strtol(str, 0, base)); } int Toi(const wchar_t * str, int base) { return static_cast(wcstol(str, 0, base)); } long Tol(const std::string & str, int base) { return Tol(str.c_str(), base); } long Tol(const std::wstring & str, int base) { return Tol(str.c_str(), base); } long Tol(const char * str, int base) { return strtol(str, 0, base); } long Tol(const wchar_t * str, int base) { return wcstol(str, 0, base); } const wchar_t * Toa(unsigned int value, int base) { return Toa(static_cast(value), base); } const wchar_t * Toa(unsigned long value, int base) { static wchar_t buffer[50]; size_t len = sizeof(buffer) / sizeof(wchar_t); Toa(value, buffer, len, base); return buffer; } const wchar_t * Toa(int value, int base) { return Toa(static_cast(value), base); } const wchar_t * Toa(long value, int base) { static wchar_t buffer[50]; size_t len = sizeof(buffer) / sizeof(wchar_t); Toa(value, buffer, len, base); return buffer; } void Toa(int value, std::string & res, int base, bool clear) { static char buffer[50]; size_t len = sizeof(buffer) / sizeof(char); if( clear ) res.clear(); Toa(value, buffer, len, base); res += buffer; } void Toa(long value, std::string & res, int base, bool clear) { static char buffer[50]; size_t len = sizeof(buffer) / sizeof(char); if( clear ) res.clear(); Toa(value, buffer, len, base); res += buffer; } void Toa(int value, std::wstring & res, int base, bool clear) { static wchar_t buffer[50]; size_t len = sizeof(buffer) / sizeof(wchar_t); if( clear ) res.clear(); Toa(value, buffer, len, base); res += buffer; } void Toa(long value, std::wstring & res, int base, bool clear) { static wchar_t buffer[50]; size_t len = sizeof(buffer) / sizeof(wchar_t); if( clear ) res.clear(); Toa(value, buffer, len, base); res += buffer; } void AssignString(const char * src, size_t len, std::wstring & dst, bool clear) { if( clear ) dst.clear(); if( dst.capacity() < dst.size() + len ) dst.reserve(dst.size() + len + 128); for(size_t i=0 ; i(src[i]); } void AssignString(const char * src, std::wstring & dst, bool clear) { size_t len; for(len=0 ; src[len] ; ++len){} AssignString(src, len, dst, clear); } void AssignString(const std::string & src, std::wstring & dst, bool clear) { AssignString(src.c_str(), src.size(), dst, clear); } void AssignString(const wchar_t * src, size_t len, std::string & dst, bool clear) { if( clear ) dst.clear(); if( dst.capacity() < dst.size() + len ) dst.reserve(dst.size() + len + 128); for(size_t i=0 ; i(src[i]); } void AssignString(const wchar_t * src, std::string & dst, bool clear) { size_t len; for(len=0 ; src[len] ; ++len){} AssignString(src, len, dst, clear); } void AssignString(const std::wstring & src, std::string & dst, bool clear) { AssignString(src.c_str(), src.size(), dst, clear); } void AssignString(const char * src, size_t len, std::string & dst, bool clear) { if( clear ) dst.clear(); // we suppose that append is smart enough and we don't have to use reserve() dst.append(src, len); } void AssignString(const char * src, std::string & dst, bool clear) { size_t len; for(len=0 ; src[len] ; ++len){} AssignString(src, len, dst, clear); } void AssignString(const std::string & src, std::string & dst, bool clear) { if( clear ) dst.clear(); dst.append(src); } void AssignString(const wchar_t * src, size_t len, std::wstring & dst, bool clear) { if( clear ) dst.clear(); // we suppose that append is smart enough and we don't have to use reserve() dst.append(src, len); } void AssignString(const wchar_t * src, std::wstring & dst, bool clear) { size_t len; for(len=0 ; src[len] ; ++len){} AssignString(src, len, dst, clear); } void AssignString(const std::wstring & src, std::wstring & dst, bool clear) { if( clear ) dst.clear(); dst.append(src); } bool CorrectUrlChar(wchar_t c) { return (c >= 'a' && c <='z') || (c >= 'A' && c <='Z') || (c >= '0' && c <='9') || c == '(' || c == ')' || c == '.' || c == ',' || c == '_' || c == '-'; } // this function checks how many dots there are in the url // if there are more than one (last) dot then the first dots will be changed into '_' void CorrectUrlDots(std::wstring & url) { size_t i = url.size(); bool was_dot = false; while( i-- > 0 ) { if( url[i] == '.' ) { if( was_dot ) // only one dot is allowed url[i] = '_'; // !! do konfiga was_dot = true; } } } // !! pomyslec o lepszej nazwie void CorrectUrlChars(std::wstring & url) { std::wstring::iterator i; for(i=url.begin(); i != url.end() ; ++i) { if( !CorrectUrlChar(*i) ) { wchar_t c = TemplatesFunctions::locale.UrlSubst(*i); if( CorrectUrlChar(c) ) *i = c; else *i = '_'; // !! dodac do konfiga } } } // !! pomyslec o lepszej nazwie // przerzucic do funkcji - tam gdzie jest PrepareUrl() // bo tutaj nie mamy wskaznika na config void CorrectUrlOnlyAllowedChar(std::wstring & url) { CorrectUrlDots(url); CorrectUrlChars(url); ToSmall(url); Trim(url, '_'); if( url.empty() || url == L"." ) { // !! brakuje config-> //if( config->item_url_empty.empty() ) url = L"unnamed"; //else //{ // url = config->item_url_empty; // CorrectUrlDots(url); // CorrectUrlChars(url); // ToSmall(url); // we don't trim here and the string will not be empty //} } if( url[0] >= '0' && url[0] <= '9' ) // url must begin with a letter url.insert(url.begin(), '_'); } const wchar_t * DateToStr(int year, int month, int day) { static const wchar_t * month_letter[] = { L"I", L"II", L"III", L"IV", L"V", L"VI", L"VII", L"VIII", L"IX", L"X", L"XI", L"XII" }; static wchar_t buffer[100]; --month; if( month < 0 ) month = 0; if( month > 11 ) month = 11; if( year == 0 ) swprintf(buffer, sizeof(buffer)/sizeof(wchar_t), L"%ls %02d", month_letter[month], day); else swprintf(buffer, sizeof(buffer)/sizeof(wchar_t), L"%02d %ls %02d", year, month_letter[month], day); // warning: not thread safe (we do not use threads) return buffer; } const wchar_t * DateToStr(int year, int month, int day, int hour, int min, int sec) { static const wchar_t * month_letter[] = { L"I", L"II", L"III", L"IV", L"V", L"VI", L"VII", L"VIII", L"IX", L"X", L"XI", L"XII" }; static wchar_t buffer[100]; --month; if( month < 0 ) month = 0; if( month > 11 ) month = 11; if( year == 0 ) swprintf(buffer, sizeof(buffer)/sizeof(wchar_t), L"%ls %02d %02d:%02d:%02d", month_letter[month], day, hour, min, sec); else swprintf(buffer, sizeof(buffer)/sizeof(wchar_t), L"%02d %ls %02d %02d:%02d:%02d", year, month_letter[month], day, hour, min, sec); // warning: not thread safe (we do not use threads) return buffer; } const wchar_t * DateToStr(const tm * ptm) { return DateToStr(ptm->tm_year + 1900, ptm->tm_mon+1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec); } const wchar_t * DateToStr(const tm & rtm) { return DateToStr(rtm.tm_year + 1900, rtm.tm_mon+1, rtm.tm_mday, rtm.tm_hour, rtm.tm_min, rtm.tm_sec); } const wchar_t * DateToStr(time_t t) { tm rtm = Time(t); return DateToStr(rtm); } const wchar_t * DateToStrWithoutHours(const tm * ptm) { return DateToStr(ptm->tm_year + 1900, ptm->tm_mon+1, ptm->tm_mday); } const wchar_t * DateToStrWithoutHours(const tm & rtm) { return DateToStr(rtm.tm_year + 1900, rtm.tm_mon+1, rtm.tm_mday); } const wchar_t * DateToStrWithoutHours(time_t t) { tm rtm = Time(t); return DateToStrWithoutHours(rtm); } // this format is used with cookies const char * DateToStrCookie(int year, int month, int day, int hour, int min, int sec) { static const char * month_str[]={ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; static char buffer[100]; --month; if( month < 0 ) month = 0; if( month > 11 ) month = 11; sprintf(buffer, "%02d-%s-%04d %02d:%02d:%02d", day, month_str[month], year, hour, min, sec); return buffer; } const char * DateToStrCookie(const tm * ptm) { return DateToStrCookie(ptm->tm_year + 1900, ptm->tm_mon+1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec); } const char * DateToStrCookie(const tm & rtm) { return DateToStrCookie(rtm.tm_year + 1900, rtm.tm_mon+1, rtm.tm_mday, rtm.tm_hour, rtm.tm_min, rtm.tm_sec); } const char * DateToStrCookie(time_t t) { tm rtm = Time(t); return DateToStrCookie(rtm); } const wchar_t * IpToStr(unsigned int ip_) { static wchar_t buffer[100]; union { unsigned int ip; unsigned char c[4]; } ip; ip.ip = ip_; swprintf(buffer, sizeof(buffer)/sizeof(wchar_t), L"%u.%u.%u.%u", (int)ip.c[0], (int)ip.c[1], (int)ip.c[2], (int)ip.c[3]); return buffer; } bool IsWhite(wchar_t s) { if( s==' ' || s=='\t' || s==13 || s==160 ) return true; return false; } bool IsLastSlash(const std::wstring & path) { if( path.empty() ) return false; return path[path.size()-1] == '/'; } const char * SkipWhite(const char * s) { while( IsWhite(*s) ) ++s; return s; } const wchar_t * SkipWhite(const wchar_t * s) { while( IsWhite(*s) ) ++s; return s; } wchar_t ToSmall(wchar_t c) { if( c>='A' && c<='Z' ) c = c - 'A' + 'a'; return c; } void ToSmall(std::wstring & s) { std::wstring::size_type i; for(i=0 ; i= 'A' && email[i]<='Z') || (email[i] >= 'a' && email[i]<='z') || (email[i] >= '0' && email[i]<='9') ) { correct = true; } else { for(size_t a=0 ; a < sizeof(allowed_chars)-1 ; ++a) { if( email[i] == allowed_chars[a] ) { correct = true; break; } } } if( email[i] == '@' ) ++at; } if( at != 1 ) return false; return correct; } bool IsFile(const wchar_t * file) { struct stat sb; static std::string afile; PT::WideToUTF8(file, afile); return (stat(afile.c_str(), &sb) == 0); } bool IsFile(const std::wstring & file) { return IsFile(file.c_str()); } bool CreateDir(const wchar_t * dir, int priv) { static std::string adir; if( !IsFile(dir) ) { PT::WideToUTF8(dir, adir); if( mkdir(adir.c_str(), priv) < 0 ) { log << log1 << "Can't create a directory on fs: " << adir << logend; return false; } } return true; } bool CreateDir(const std::wstring & dir, int priv) { return CreateDir(dir.c_str(), priv); } // creating directories (can be more than one) // 'dirs' can begin with a slash (will be skipped) bool CreateDirs(const wchar_t * base_dir, const wchar_t * dirs, int priv, bool skip_last) { static std::wstring temp; const wchar_t * p = dirs; temp = base_dir; // we start creating from 'base_dir' if( temp.empty() ) return false; if( temp[temp.size()-1] != '/' ) temp += '/'; while( true ) { // skipping slashes for( ; *p=='/' ; ++p ); if( *p == 0 ) break; // taking the name for( ; *p!=0 && *p!='/' ; ++p ) temp += *p; if( !skip_last || *p!=0 ) if( !CreateDir(temp.c_str(), priv) ) return false; temp += '/'; } return true; } bool CreateDirs(const std::wstring & base_dir, const std::wstring & dirs, int priv, bool skip_last) { return CreateDirs(base_dir.c_str(), dirs.c_str(), priv, skip_last); } bool CopyFile(FILE * in, FILE * out) { char buf[1024]; size_t buflen = sizeof(buf)/sizeof(char); size_t len; do { len = fread(buf, 1, buflen, in); if( len > 0 ) fwrite(buf, 1, len, out); if( ferror(in) || ferror(out) ) return false; } while( !feof(in) ); return true; } bool CopyFile(const wchar_t * src, const wchar_t * dst) { static std::string asrc, adst; FILE * in, * out; PT::WideToUTF8(src, asrc); PT::WideToUTF8(dst, adst); in = fopen(asrc.c_str(), "rb"); if( !in ) return false; out = fopen(adst.c_str(), "wb"); if( !out ) { fclose(in); return false; } bool res = CopyFile(in, out); fclose(in); fclose(out); if( res && ferror(out) ) res = false; if( !res ) remove(adst.c_str()); return res; } bool CopyFile(const std::wstring & src, const std::wstring & dst) { return CopyFile(src.c_str(), dst.c_str()); } bool RemoveFile(const wchar_t * file) { static std::string afile; PT::WideToUTF8(file, afile); return unlink(afile.c_str()) == 0; } bool RemoveFile(const std::wstring & file) { return RemoveFile(file.c_str()); } bool RenameFile(const wchar_t * from, const wchar_t * to) { static std::string afrom, ato; PT::WideToUTF8(from, afrom); PT::WideToUTF8(to, ato); return rename(afrom.c_str(), ato.c_str()) == 0; } bool RenameFile(const std::wstring & from, const std::wstring & to) { return RenameFile(from.c_str(), to.c_str()); } bool GetUTF8File(const char * file_path, std::wstring & content, bool clear_content) { using namespace misc_private; if( clear_content ) content.clear(); get_file_content.clear(); get_file_content.open(file_path, std::ios_base::in | std::ios_base::binary); if( !get_file_content ) return false; PT::UTF8ToWide(get_file_content, content); get_file_content.close(); return true; } bool GetUTF8File(const wchar_t * file_path, std::wstring & content, bool clear_content) { using namespace misc_private; PT::WideToUTF8(file_path, get_file_content_ansi); return GetUTF8File(get_file_content_ansi.c_str(), content, clear_content); } bool GetUTF8File(const std::string & file_path, std::wstring & content, bool clear_content) { return GetUTF8File(file_path.c_str(), content, clear_content); } bool GetUTF8File(const std::wstring & file_path, std::wstring & content, bool clear_content) { return GetUTF8File(file_path.c_str(), content, clear_content); } // if there is not an extension it returns a pointer to the last '\0' character const wchar_t * GetFileExt(const wchar_t * name) { size_t i, ilast; // looking for the end of the name for(i=0 ; name[i] != 0 ; ++i); if( i == 0 ) return name; // ops, the name is empty // remember the end of the string ilast = i; // looking for the last dot for(--i ; i>0 && name[i] != '.' ; --i); if( name[i] != '.' ) return name + ilast; // ops, there is not a dot // the extensions starts from i+1 // and can be empty (if the last character is a dot) return name + i + 1; } int SelectFileType(const wchar_t * file_name) { const wchar_t * ext = GetFileExt(file_name); // as an image we're using only those types which can be rendered // by a web browser if( EqualNoCase(ext, L"jpg") || EqualNoCase(ext, L"jpeg") || EqualNoCase(ext, L"jpe") || EqualNoCase(ext, L"pic") || EqualNoCase(ext, L"tga") || EqualNoCase(ext, L"gif") || EqualNoCase(ext, L"bmp") || EqualNoCase(ext, L"png") ) return WINIX_ITEM_FILETYPE_IMAGE; if( EqualNoCase(ext, L"pdf") || EqualNoCase(ext, L"doc") || EqualNoCase(ext, L"xls") || EqualNoCase(ext, L"txt") || EqualNoCase(ext, L"ods") || EqualNoCase(ext, L"odt") ) return WINIX_ITEM_FILETYPE_DOCUMENT; if( EqualNoCase(ext, L"avi") || EqualNoCase(ext, L"mp4") || EqualNoCase(ext, L"flv") || EqualNoCase(ext, L"mpg") || EqualNoCase(ext, L"mpeg") || EqualNoCase(ext, L"mkv") || EqualNoCase(ext, L"wmv") ) return WINIX_ITEM_FILETYPE_VIDEO; return WINIX_ITEM_FILETYPE_UNKNOWN; } int SelectFileType(const std::wstring & file_name) { return SelectFileType(file_name.c_str()); } time_t Time(const tm & par) { tm t; memset(&t, 0, sizeof(t)); t.tm_year = par.tm_year; t.tm_mon = par.tm_mon; t.tm_mday = par.tm_mday; t.tm_hour = par.tm_hour; t.tm_min = par.tm_min; t.tm_sec = par.tm_sec; return timegm(&t); } time_t Time(const tm * par) { return Time(*par); } tm Time(time_t par) { tm * ptm = gmtime(&par); tm res; memset(&res, 0, sizeof(res)); if( ptm ) { res.tm_year = ptm->tm_year; res.tm_mon = ptm->tm_mon; res.tm_mday = ptm->tm_mday; res.tm_hour = ptm->tm_hour; res.tm_min = ptm->tm_min; res.tm_sec = ptm->tm_sec; res.tm_wday = ptm->tm_wday; res.tm_yday = ptm->tm_yday; } return res; } void UrlEncode(const std::string & in, std::string & out, bool clear_out) { char buffer[10]; if( clear_out ) out.clear(); // !! we should not use such characters here: '/' '#' for(size_t i=0 ; i= 'a' && in[i] <= 'z') || (in[i] >= 'A' && in[i] <= 'Z') || (in[i] >= '0' && in[i] <= '9') || in[i] == '.' || in[i] == ',' || in[i] == '/' || in[i] == ':' || in[i] == '#' || in[i] == '-' || in[i] == '_' || in[i] == '(' || in[i] == ')' ) { out += in[i]; } else { Toa(static_cast(in[i]), buffer, 10, 16); out += '%'; if( buffer[1] == 0 ) out += '0'; // there is only one character in the buffer out += buffer; } } } void UrlEncode(const std::wstring & in, std::string & out, bool clear_out) { static std::string ain; PT::WideToUTF8(in, ain); UrlEncode(ain, out, clear_out); } void QEncodeAddChar(wchar_t c, std::string & out) { if( (c>='A' && c<='Z') || (c>='a' && c<='z') || (c>='0' && c<='9') ) { out += char(c); } else { char buf1[10]; char buf2[10]; size_t len1 = sizeof(buf1) / sizeof(char); size_t len2 = sizeof(buf2) / sizeof(char); size_t len = PT::IntToUTF8(int(c), buf1, len1); for(size_t i=0 ; isecond.tmp_filename; if( !tmp_filename.empty() && RemoveFile(tmp_filename) ) log << log3 << "Deleted tmp file: " << tmp_filename << logend; } }