svvitch
digital signage player
D:/vs_workspace/switch_sf/src/svvitch/Utils.cpp
Go to the documentation of this file.
00001 #include "Utils.h"
00002 
00003 #include <algorithm>
00004 #include <fstream>
00005 #include <iostream>
00006 #include <vector>
00007 #include <set>
00008 #include <Poco/Buffer.h>
00009 #include <Poco/MD5Engine.h>
00010 #include <Poco/DigestStream.h>
00011 #include <Poco/File.h>
00012 #include <Poco/FileStream.h>
00013 #include <Poco/Logger.h>
00014 #include <Poco/format.h>
00015 #include <Poco/string.h>
00016 #include <Poco/StreamCopier.h>
00017 #include <Poco/UnicodeConverter.h>
00018 #include <Poco/RegularExpression.h>
00019 #include <Poco/NumberParser.h>
00020 
00021 using std::copy;
00022 using std::set;
00023 using std::sort;
00024 using std::vector;
00025 using Poco::DigestEngine;
00026 using Poco::File;
00027 using Poco::MD5Engine;
00028 using Poco::DigestOutputStream;
00029 using Poco::StreamCopier;
00030 
00031 
00032 const string svvitch::version() {
00033     return "1.10";
00034 }
00035 
00036 bool svvitch::readFile(const string& fileName, LPVOID* ref) {
00037     Poco::Logger& log(Poco::Logger::get(""));
00038     // dicファイルの読込み
00039     try {
00040         File file(fileName);
00041         if (file.exists()) {
00042             Poco::FileInputStream is(file.path());
00043             if (is.good()) {
00044                 LPBYTE buf = new BYTE[(UINT)file.getSize()];
00045                 ZeroMemory(buf, (UINT)file.getSize());
00046                 #define BUFFER_SIZE (8192)
00047                 Poco::Buffer<char> buffer(BUFFER_SIZE);
00048                 std::streamsize len = 0;
00049                 is.read(buffer.begin(), BUFFER_SIZE);
00050                 std::streamsize n = is.gcount();
00051                 while (n > 0) {
00052                     CopyMemory(&buf[len], buffer.begin(), n);
00053                     len += n;
00054                     if (is) {
00055                         is.read(buffer.begin(), BUFFER_SIZE);
00056                         n = is.gcount();
00057                     }
00058                     else n = 0;
00059                 }
00060                 is.close();
00061                 log.information(Poco::format("load file size: %d", len));
00062                 *ref = (LPVOID)buf;
00063                 return true;
00064             } else {
00065                 log.warning(Poco::format("failed not read file: %s", file.path()));
00066             }
00067         } else {
00068             log.warning(Poco::format("file not found: %s", file.path()));
00069         }
00070     } catch (Poco::IOException& ex) {
00071         log.warning(Poco::format("failed read file: %s", ex.displayText()));
00072     }
00073     return false;
00074 }
00075 
00076 void svvitch::sjis_utf8(const string& in, string& out) {
00077     wstring wstring;
00078     sjis_utf16(in, wstring);
00079     Poco::UnicodeConverter::toUTF8(wstring, out);
00080 }
00081 
00082 void svvitch::sjis_utf16(const string& in, wstring& out) {
00083     int len = ::MultiByteToWideChar(CP_ACP, 0, in.c_str(), -1, NULL, 0);
00084     if (len > 0) { 
00085         vector<wchar_t> utf16(len);
00086         if (::MultiByteToWideChar(CP_ACP, 0, in.c_str(), -1, &utf16[0], len)) {
00087             out = &utf16[0];
00088         }
00089         utf16.clear();
00090     } else {
00091         out = L"";
00092     }
00093 }
00094 
00095 
00096 void svvitch::utf16_sjis(const wstring& wstr, string& out) {
00097     int len = ::WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, NULL, 0, NULL, NULL);
00098     if (len > 0) {
00099         vector<char> sjis(len);
00100         if (::WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, &sjis[0], len, NULL, NULL)) {
00101             out = &sjis[0];
00102         }
00103         sjis.clear();
00104     } else {
00105         out.clear();
00106     }
00107 }
00108 
00109 
00110 void svvitch::utf8_sjis(const string& str, string& out) {
00111     std::wstring wstr;
00112     // UTF-8をUTF-16に変換
00113     Poco::UnicodeConverter::toUTF16(str, wstr);
00114     utf16_sjis(wstr, out); // UTF-16をシフトJISに変換
00115 }
00116 
00117 
00118 int svvitch::fileCount(const Path& path) {
00119     int count = 0;
00120     File dir(path);
00121     if (dir.isDirectory()) {
00122         vector<File> list;
00123         dir.list(list);
00124         for (vector<File>::iterator it = list.begin(); it != list.end(); it++) {
00125             File f = *it;
00126             if (f.isDirectory()) {
00127                 count += fileCount(Path(f.path()));
00128             } else {
00129                 count++;
00130             }
00131         }
00132     } else if (!dir.exists()) {
00133         count++;
00134     }
00135     return count;
00136 }
00137 
00138 string svvitch::md5(const Path& path) {
00139     std::wstring wfile;
00140     Poco::UnicodeConverter::toUTF16(path.toString(), wfile);
00141     std::ifstream is(wfile.c_str(), std::ios::binary);
00142     if (is.good()) {
00143         MD5Engine md5;
00144         DigestOutputStream dos(md5);
00145         StreamCopier::copyStream(is, dos);
00146         dos.close();
00147         return DigestEngine::digestToHex(md5.digest());
00148     }
00149     return string("");
00150 }
00151 
00152 string svvitch::join(const vector<string>& v, const string& c) {
00153     string s;
00154     for (vector<string>::const_iterator p = v.begin(); p != v.end(); p++) {
00155         s += *p;
00156         if (p != v.end() -1) s += c;
00157     }
00158     return s;
00159 }
00160 
00161 void svvitch::split(const string& s, char c, vector<string>& v, int splits) {
00162     string::size_type pos = 0;
00163     string::size_type j = s.find(c);
00164 
00165     int count = 0;
00166     while (j != string::npos) {
00167         if (splits > 0 && (splits - 1) == count) {
00168             v.push_back(s.substr(pos));
00169             break;
00170         }
00171         v.push_back(s.substr(pos, j - pos));
00172         pos = ++j;
00173         j = s.find(c, j);
00174 
00175         if (j == string::npos) v.push_back(s.substr(pos, s.length()));
00176         count++;
00177     }
00178     if (v.empty()) v.push_back(s);
00179 }
00180 
00181 bool svvitch::parseMultiNumbers(const string& s, int min, int max, vector<int>& result) {
00182     Poco::Logger& log(Poco::Logger::get(""));
00183     set<int> num;
00184     vector<string> datas;
00185     split(s, ',', datas); // カンマを区切る
00186     for (vector<string>::const_iterator p = datas.begin(); p != datas.end(); p++) {
00187         string data = Poco::trim(*p);
00188         if (!data.empty()) {
00189             if (data[0] == '-') {
00190                 // 開始省略範囲
00191                 int n;
00192                 if (Poco::NumberParser::tryParse(Poco::trim(data.substr(1)), n)) {
00193                     for (int i = min; i <= n; i++) num.insert(i);
00194                 } else {
00195                     log.warning(Poco::format("parse failed: %s", data));
00196                     return false;
00197                 }
00198 
00199             } else if (data[data.size() - 1] == '-') {
00200                 // 終了省略範囲
00201                 int n;
00202                 if (Poco::NumberParser::tryParse(Poco::trim(data.substr(0, data.size() - 1)), n)) {
00203                     for (int i = n; i <= max; i++) num.insert(i);
00204                 } else {
00205                     log.warning(Poco::format("parse failed: %s", data));
00206                     return false;
00207                 }
00208 
00209             } else if (data.find("-") != string::npos) {
00210                 // 範囲指定
00211                 int i = data.find("-");
00212                 int n1, n2;
00213                 if (!Poco::NumberParser::tryParse(Poco::trim(data.substr(0, i)), n1) || n1 < min) {
00214                     log.warning(Poco::format("parse failed: %s", data));
00215                     return false;
00216                 }
00217                 if (!Poco::NumberParser::tryParse(Poco::trim(data.substr(i + 1)), n2) || n2 > max) {
00218                     log.warning(Poco::format("parse failed: %s", data));
00219                     return false;
00220                 }
00221                 for (int i = n1; i <= n2; i++) num.insert(i);
00222 
00223             } else {
00224                 // 単独数値
00225                 int n = -1;
00226                 if (Poco::NumberParser::tryParse(data, n) && (n >= min && n <= max)) {
00227                     num.insert(n);
00228                 } else {
00229                     log.warning(Poco::format("parse failed: %s", data));
00230                     return false;
00231                 }
00232             }
00233         }
00234     }
00235     for (set<int>::const_iterator p = num.begin(); p != num.end(); p++) result.push_back(*p);
00236     sort(result.begin(), result.end());
00237     return true;
00238 }
00239 
00240 string svvitch::formatJSON(const string& s) {
00241     if (!s.empty()) {
00242         int i = s.length() - 1;
00243         if (s.c_str()[0] == '[' && s.c_str()[i] == ']') {
00244             return s;
00245         } else if (s.c_str()[0] == '{' && s.c_str()[i] == '}') {
00246             return s;
00247         }
00248         string rep;
00249         for (i = 0; i < s.length(); ++i) {
00250             char c = s.at(i);
00251             if (c == '¥"') {
00252                 rep.append("&quot;");
00253             } else if (c == '¥¥') {
00254                 rep.append("¥¥¥¥");
00255             } else {
00256                 rep += c;
00257             }
00258         }
00259         return "¥"" + rep + "¥"";
00260     }
00261     return "¥"¥"";
00262 }
00263 
00264 string svvitch::formatJSON(const map<string, string>& obj) {
00265     vector<string> params;
00266     for (map<string, string>::const_iterator it = obj.begin(); it != obj.end(); it++) {
00267         params.push_back(Poco::format("¥"%s¥":%s", it->first, it->second));
00268     }
00269     return Poco::format("{%s}", svvitch::join(params, ","));
00270 }
00271 
00272 string svvitch::formatJSONArray(const vector<string>& list) {
00273     vector<string> params;
00274     for (vector<string>::const_iterator it = list.begin(); it != list.end(); it++) {
00275         params.push_back(formatJSON(*it));
00276     }
00277     return Poco::format("[%s]", svvitch::join(params, ","));
00278 }
00279 
00280 void svvitch::parseJSON(const string& json, map<string, string>& map) {
00281     string key;
00282     bool inText = false;
00283     int start = -1;
00284     int inArray = 0;
00285     int inMap = 0;
00286     string::size_type pos = 0;
00287     for (; json.length() > pos; pos++) {
00288         char c = json.at(pos);
00289         switch (c) {
00290         case '{':
00291             if (!inText) {
00292                 // Mapブロック開始
00293                 if (inMap == 1 && start == -1) {
00294                     start = pos;
00295                 }
00296                 inMap++;
00297             }
00298             break;
00299         case '}':
00300             if (!inText) {
00301                 // Mapブロック終了
00302                 inMap--;
00303                 if (inMap == 0 && start != -1) {
00304                     if (!key.empty()) {
00305                         string value = json.substr(start, pos - start);
00306                         map[trimQuotationMark(key)] = trimQuotationMark(value);
00307                     }
00308                 }
00309             }
00310             break;
00311         case '[':
00312             if (!inText) {
00313                 // arrayブロック開始
00314                 if (inArray == 0 && start == -1) {
00315                     // Textブロック開始
00316                     start = pos;
00317                 }
00318                 inArray++;
00319             }
00320             break;
00321         case ']':
00322             if (!inText) {
00323                 // arrayブロック終了
00324                 inArray--;
00325             }
00326             break;
00327         case '¥"':
00328             if (inMap <= 1 && inArray == 0) {
00329                 if (start != -1) {
00330                     // Textブロック終了
00331                     inText = false;
00332                 } else {
00333                     // Textブロック開始
00334                     start = pos;
00335                     inText = true;
00336                 }
00337             } else {
00338                 // arrayブロック内はスルー
00339             }
00340             break;
00341         case ':':
00342             if (!inText) {
00343                 // キーブロック終了
00344                 if (inMap <= 1 && inArray == 0) {
00345                     if (start != -1) {
00346                         key = json.substr(start, pos - start);
00347                         start = -1;
00348                     }
00349                 } else {
00350                     // arrayブロック内はスルー
00351                 }
00352             }
00353             break;
00354         case ',':
00355             if (!inText) {
00356                 // 値ブロック終了
00357                 if (inMap <= 1 && inArray == 0) {
00358                     if (inMap > 0 && !key.empty()) {
00359                         string value = json.substr(start, pos - start);
00360                         map[trimQuotationMark(key)] = trimQuotationMark(value);
00361                         key.clear();
00362                     }
00363                     start = -1;
00364                 } else {
00365                     // arrayブロック内はスルー
00366                 }
00367             }
00368             break;
00369         case ' ':
00370             // 空白はスルー
00371             break;
00372         default:
00373             if (start == -1) {
00374                 start = pos;
00375             }
00376         }
00377     }
00378 }
00379 
00380 void svvitch::parseJSONArray(const string& json, vector<string>& v) {
00381     string key;
00382     int start = -1;
00383     int inArray = 0;
00384     string::size_type pos = 0;
00385     for (; json.length() > pos; pos++) {
00386         char c = json.at(pos);
00387         switch (c) {
00388         case '[':
00389             // arrayブロック開始
00390             inArray++;
00391             break;
00392         case ']':
00393             // arrayブロック終了
00394             inArray--;
00395             if (inArray == 0 && start != -1) {
00396                 string value = json.substr(start, pos - start);
00397                 v.push_back(trimQuotationMark(value));
00398             }
00399             break;
00400         case '¥"':
00401             if (start != -1) {
00402                 // Textブロック終了
00403             } else {
00404                 // Textブロック開始
00405                 start = pos;
00406             }
00407             break;
00408         case ',':
00409             // 値ブロック終了
00410             string value = json.substr(start, pos - start);
00411             v.push_back(trimQuotationMark(value));
00412             start = -1;
00413             break;
00414         }
00415     }
00416 }
00417 
00418 string svvitch::trimQuotationMark(const string& s) {
00419     char q = s.at(0);
00420     switch (q) {
00421     case '¥"':
00422     //case '[':
00423     //case '}':
00424         if (s.at(s.length() - 1) == q) {
00425             return s.substr(1, s.length() - 2);
00426         }
00427     }
00428     return s;
00429 }
00430 
00431 string svvitch::findLastOfText(const string& src, const string& find) {
00432     string s;
00433     int i = src.find_last_of(find);
00434     if (i == string::npos) {
00435         s = src;
00436     } else {
00437         s = src.substr(i + 1);
00438     }
00439     return s;
00440 }
00441 
00442 vector<int> svvitch::parseTimes(const string& timeText) {
00443     Poco::RegularExpression re("[¥¥s:/]+");
00444     int pos = 0;
00445     Poco::RegularExpression::Match match;
00446     vector<int> time;
00447     while (re.match(timeText, pos, match) > 0) {
00448         string s = timeText.substr(pos, match.offset - pos);
00449         if (s == "*") {
00450             time.push_back(-1);
00451         } else {
00452             time.push_back(Poco::NumberParser::parse(s));
00453         }
00454         pos = (match.offset + match.length);
00455     }
00456     string s = timeText.substr(pos);
00457     if (s == "*") {
00458         time.push_back(-1);
00459     } else {
00460         time.push_back(Poco::NumberParser::parse(s));
00461     }
00462     return time;
00463 }
00464 
00465 void svvitch::rebootWindows(BOOL shutdown, BOOL force) {
00466     HANDLE hToken;
00467     LUID Luid;
00468     HANDLE hProcess = GetCurrentProcess();
00469     OpenProcessToken(hProcess, TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken);
00470     LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &Luid);
00471     TOKEN_PRIVILEGES tokenNew, tokenPre;
00472     tokenNew.PrivilegeCount = 1;
00473     tokenNew.Privileges[0].Luid = Luid;
00474     tokenNew.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
00475     DWORD ret;
00476     AdjustTokenPrivileges(hToken, FALSE, &tokenNew, sizeof(tokenPre), &tokenPre, &ret);
00477 
00478     //case 1:     uFlag = EWX_LOGOFF;     break;
00479     //case 2:     uFlag = EWX_POWEROFF;   break;
00480     //case 3:     uFlag = EWX_REBOOT;     break;
00481     //case 4:     uFlag = EWX_SHUTDOWN;   break;
00482     UINT flag;
00483     if (shutdown) {
00484         // 電源OFF
00485         flag = EWX_POWEROFF;
00486     } else {
00487         // 再起動(default)
00488         flag = EWX_REBOOT;
00489     }
00490     if (force) {
00491         // プロセス強制終了
00492         flag |= EWX_FORCE;
00493     }
00494     ExitWindowsEx(flag, 0);
00495 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines