summaryrefslogtreecommitdiff
path: root/protocols/Weather/src/weather_conv.cpp
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2019-03-02 12:32:44 +0300
committerGeorge Hazan <ghazan@miranda.im>2019-03-02 12:32:55 +0300
commit931a7dc1ac0dbc7e6c1083583ced915e572f5b47 (patch)
tree9fe9a6448d44030e26aa7107ce16044ed413e0d0 /protocols/Weather/src/weather_conv.cpp
parentdd7d9954042254e66e3bbbec7195c6be8b1a0663 (diff)
all protocols (even virtual ones) moved to the Protocols folder
Diffstat (limited to 'protocols/Weather/src/weather_conv.cpp')
-rw-r--r--protocols/Weather/src/weather_conv.cpp637
1 files changed, 637 insertions, 0 deletions
diff --git a/protocols/Weather/src/weather_conv.cpp b/protocols/Weather/src/weather_conv.cpp
new file mode 100644
index 0000000000..c46b079531
--- /dev/null
+++ b/protocols/Weather/src/weather_conv.cpp
@@ -0,0 +1,637 @@
+/*
+Weather Protocol plugin for Miranda IM
+Copyright (c) 2012 Miranda NG team
+Copyright (c) 2005-2011 Boris Krasnovskiy All Rights Reserved
+Copyright (c) 2002-2005 Calvin Che
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; version 2
+of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+This file contain the source related unit conversion, icon assignment,
+string conversions, display text parsing, etc
+*/
+
+#include "stdafx.h"
+
+//============ SOME HELPER FUNCTIONS ============
+
+// see if a string is a number
+// s = the string to be determined
+// return value = true if the string is a number, false if it isn't
+BOOL is_number(wchar_t *s)
+{
+ BOOL tag = FALSE;
+ // looking character by character
+ // for a number: numerous spaces in front, then optional +/-, then the number
+ // don't care anything that comes after it
+ while (*s != '\0') {
+ if (*s >= '0' && *s <= '9') return TRUE;
+ else if (*s == ' ');
+ else if (*s != '+' && *s != '-') return FALSE;
+ else if ((*s == '+' || *s == '-') && !tag) tag = TRUE;
+ else return FALSE;
+ s++;
+ }
+ return FALSE;
+}
+
+static void numToStr(double num, wchar_t *str, size_t strSize)
+{
+ int i = (int)(num * (opt.NoFrac ? 10 : 100));
+ int u = abs(i);
+
+ int r = u % 10;
+ int w = u / 10 + (r >= 5);
+
+ if (opt.NoFrac)
+ r = 0;
+ else {
+ r = w % 10;
+ w /= 10;
+ }
+
+ if (i < 0 && (w || r)) w = -w;
+ if (r)
+ mir_snwprintf(str, strSize, L"%i.%i", w, r);
+ else
+ mir_snwprintf(str, strSize, L"%i", w);
+}
+
+//============ UNIT CONVERSIONS ============
+
+// temperature conversion
+// tempchar = the string containing the temperature value
+// unit = the unit for temperature
+// return value = the converted temperature with degree sign and unit; if fails, return N/A
+void GetTemp(wchar_t *tempchar, wchar_t *unit, wchar_t* str)
+{
+ // unit can be C, F
+ double temp;
+ wchar_t tstr[20];
+
+ TrimString(tempchar);
+ if (tempchar[0] == '-' && tempchar[1] == ' ')
+ memmove(&tempchar[1], &tempchar[2], sizeof(wchar_t)*(mir_wstrlen(&tempchar[2]) + 1));
+
+ // quit if the value obtained is N/A or not a number
+ if (!mir_wstrcmp(tempchar, NODATA) || !mir_wstrcmp(tempchar, L"N/A")) {
+ mir_wstrcpy(str, tempchar);
+ return;
+ }
+ if (!is_number(tempchar)) {
+ mir_wstrcpy(str, NODATA);
+ return;
+ }
+
+ // convert the string to an integer
+ temp = _wtof(tempchar);
+
+ // convert all to F first
+ if (!mir_wstrcmpi(unit, L"C")) temp = (temp * 9 / 5) + 32;
+ else if (!mir_wstrcmpi(unit, L"K")) temp = ((temp - 273.15) * 9 / 5) + 32;
+
+ // convert to apporiate unit
+ switch (opt.tUnit) {
+ case 1:
+ // rounding
+ numToStr((temp - 32) / 9 * 5, tstr, _countof(tstr));
+ if (opt.DoNotAppendUnit)
+ wcsncpy_s(str, MAX_DATA_LEN, tstr, _TRUNCATE);
+ else
+ mir_snwprintf(str, MAX_DATA_LEN, L"%s%sC", tstr, opt.DegreeSign);
+ break;
+
+ case 2:
+ numToStr(temp, tstr, _countof(tstr));
+ if (opt.DoNotAppendUnit)
+ wcsncpy_s(str, MAX_DATA_LEN, tstr, _TRUNCATE);
+ else
+ mir_snwprintf(str, MAX_DATA_LEN, L"%s%sF", tstr, opt.DegreeSign);
+ break;
+ }
+}
+
+// temperature conversion
+// tempchar = the string containing the pressure value
+// unit = the unit for pressure
+// return value = the converted pressure with unit; if fail, return the original string
+void GetPressure(wchar_t *tempchar, wchar_t *unit, wchar_t* str)
+{
+ // unit can be kPa, hPa, mb, in, mm, torr
+ double tempunit = 0, output;
+ int intunit;
+
+ // convert the string to a floating point number (always positive)
+ // if it end up with 0, then it's not a number, return the original string and quit
+ output = _wtof(tempchar);
+ if (output == 0) {
+ mir_wstrcpy(str, tempchar);
+ return;
+ }
+
+ // convert all to mb first
+ if (!mir_wstrcmpi(unit, L"KPA"))
+ tempunit = (double)output * 10;
+ else if (!mir_wstrcmpi(unit, L"HPA"))
+ tempunit = (double)output;
+ else if (!mir_wstrcmpi(unit, L"MB"))
+ tempunit = (double)output;
+ else if (!mir_wstrcmpi(unit, L"IN"))
+ tempunit = (double)output * 33.86388;
+ else if (!mir_wstrcmpi(unit, L"MM"))
+ tempunit = (double)output * 1.33322;
+ else if (!mir_wstrcmpi(unit, L"TORR"))
+ tempunit = (double)output * 1.33322;
+
+ // convert to apporiate unit
+ switch (opt.pUnit) {
+ case 1:
+ intunit = (int)(tempunit + 0.5);
+ mir_snwprintf(str, MAX_DATA_LEN, L"%i.%i %s", intunit / 10, intunit % 10, opt.DoNotAppendUnit ? L"" : TranslateT("kPa"));
+ break;
+ case 2:
+ intunit = (int)(tempunit + 0.5);
+ mir_snwprintf(str, MAX_DATA_LEN, L"%i %s", intunit, opt.DoNotAppendUnit ? L"" : TranslateT("mb"));
+ break;
+ case 3:
+ intunit = (int)((tempunit * 10 / 33.86388) + 0.5);
+ mir_snwprintf(str, MAX_DATA_LEN, L"%i.%i %s", intunit / 10, intunit % 10, opt.DoNotAppendUnit ? L"" : TranslateT("in"));
+ break;
+ case 4:
+ intunit = (int)((tempunit * 10 / 1.33322) + 0.5);
+ mir_snwprintf(str, MAX_DATA_LEN, L"%i.%i %s", intunit / 10, intunit % 10, opt.DoNotAppendUnit ? L"" : TranslateT("mm"));
+ break;
+ default:
+ mir_wstrcpy(str, tempchar);
+ break;
+
+ }
+}
+
+// speed conversion
+// tempchar = the string containing the speed value
+// unit = the unit for speed
+// return value = the converted speed with unit; if fail, return _T(""
+void GetSpeed(wchar_t *tempchar, wchar_t *unit, wchar_t *str)
+{
+ // unit can be km/h, mph, m/s, knots
+ double tempunit;
+ wchar_t tstr[20];
+
+ str[0] = 0;
+
+ // convert the string into an integer (always positive)
+ // if the result is 0, then the string is not a number, return _T(""
+ tempunit = _wtof(tempchar);
+ if (tempunit == 0 && tempchar[0] != '0')
+ return;
+
+ // convert all to m/s first
+ if (!mir_wstrcmpi(unit, L"KM/H"))
+ tempunit /= 3.6;
+ // else if ( !mir_wstrcmpi(unit, L"M/S")
+ // tempunit = tempunit;
+ else if (!mir_wstrcmpi(unit, L"MPH"))
+ tempunit *= 0.44704;
+ else if (!mir_wstrcmpi(unit, L"KNOTS"))
+ tempunit *= 0.514444;
+
+ // convert to apporiate unit
+ switch (opt.wUnit) {
+ case 1:
+ numToStr(tempunit * 3.6, tstr, _countof(tstr));
+ mir_snwprintf(str, MAX_DATA_LEN, L"%s %s", tstr, opt.DoNotAppendUnit ? L"" : TranslateT("km/h"));
+ break;
+ case 2:
+ numToStr(tempunit, tstr, _countof(tstr));
+ mir_snwprintf(str, MAX_DATA_LEN, L"%s %s", tstr, opt.DoNotAppendUnit ? L"" : TranslateT("m/s"));
+ break;
+ case 3:
+ numToStr(tempunit / 0.44704, tstr, _countof(tstr));
+ mir_snwprintf(str, MAX_DATA_LEN, L"%s %s", tstr, opt.DoNotAppendUnit ? L"" : TranslateT("mph"));
+ break;
+ case 4:
+ numToStr(tempunit / 0.514444, tstr, _countof(tstr));
+ mir_snwprintf(str, MAX_DATA_LEN, L"%s %s", tstr, opt.DoNotAppendUnit ? L"" : TranslateT("knots"));
+ break;
+ }
+}
+
+// distance conversion
+// tempchar = the string containing the distance value
+// unit = the unit for distance
+// return value = the converted distance with unit; if fail, return original string
+void GetDist(wchar_t *tempchar, wchar_t *unit, wchar_t *str)
+{
+ // unit can be km, miles
+ double tempunit = 0, output;
+ int intunit;
+
+ // convert the string to a floating point number (always positive)
+ // if it end up with 0, then it's not a number, return the original string and quit
+ output = _wtof(tempchar);
+ if (output == 0) {
+ mir_wstrcpy(str, tempchar);
+ return;
+ }
+
+ // convert all to km first
+ if (!mir_wstrcmpi(unit, L"KM"))
+ tempunit = (double)output;
+ else if (!mir_wstrcmpi(unit, L"MILES"))
+ tempunit = (double)output * 1.609;
+
+ // convert to apporiate unit
+ switch (opt.vUnit) {
+ case 1:
+ intunit = (int)((tempunit * 10) + 0.5);
+ mir_snwprintf(str, MAX_DATA_LEN, L"%i.%i %s", intunit / 10, intunit % 10, opt.DoNotAppendUnit ? L"" : TranslateT("km"));
+ break;
+ case 2:
+ intunit = (int)((tempunit * 10 / 1.609) + 0.5);
+ mir_snwprintf(str, MAX_DATA_LEN, L"%i.%i %s", intunit / 10, intunit % 10, opt.DoNotAppendUnit ? L"" : TranslateT("miles"));
+ break;
+ default:
+ mir_wstrcpy(str, tempchar);
+ break;
+ }
+}
+
+// elevation conversion
+// tempchar = the string containing the elevation value
+// unit = the unit for elevation
+// return value = the converted elevation with unit; if fail, return original string
+void GetElev(wchar_t *tempchar, wchar_t *unit, wchar_t *str)
+{
+ // unit can be ft, m
+ double tempunit = 0, output;
+ int intunit;
+
+ // convert the string to a floating point number (always positive)
+ // if it end up with 0, then it's not a number, return the original string and quit
+ output = _wtof(tempchar);
+ if (output == 0) {
+ mir_wstrcpy(str, tempchar);
+ return;
+ }
+
+ // convert all to m first
+ if (!mir_wstrcmpi(unit, L"M"))
+ tempunit = (double)output;
+ else if (!mir_wstrcmpi(unit, L"FT"))
+ tempunit = (double)output / 3.28;
+
+ // convert to apporiate unit
+ switch (opt.eUnit) {
+ case 1:
+ intunit = (int)((tempunit * 10 * 3.28) + 0.5);
+ mir_snwprintf(str, MAX_DATA_LEN, L"%i.%i %s", intunit / 10, intunit % 10, opt.DoNotAppendUnit ? L"" : TranslateT("ft"));
+ break;
+ case 2:
+ intunit = (int)((tempunit * 10) + 0.5);
+ mir_snwprintf(str, MAX_DATA_LEN, L"%i.%i %s", intunit / 10, intunit % 10, opt.DoNotAppendUnit ? L"" : TranslateT("m"));
+ break;
+ default:
+ mir_wstrcpy(str, tempchar);
+ break;
+ }
+}
+
+//============ CONDITION ICON ASSIGNMENT ============
+
+// assign the contact icon (status) from the condition string
+// the description may be different between different sources
+// cond = the string for weather condition
+// return value = status for the icon (ONLINE, OFFLINE, etc)
+
+static const wchar_t *statusStr[10] = { L"Lightning", L"Fog", L"Snow Shower", L"Snow", L"Rain Shower", L"Rain", L"Partly Cloudy", L"Cloudy", L"Sunny", L"N/A" };
+static const WORD statusValue[10] = { LIGHT, FOG, SSHOWER, SNOW, RSHOWER, RAIN, PCLOUDY, CLOUDY, SUNNY, NA };
+
+WORD GetIcon(const wchar_t* cond, WIDATA *Data)
+{
+ // set the icon using ini
+ for (int i = 0; i < 10; i++)
+ if (IsContainedInCondList(cond, &Data->CondList[i]))
+ return statusValue[i];
+
+ // internal detection
+ if (
+ wcsstr(cond, L"mainy sunny") != nullptr ||
+ wcsstr(cond, L"mainy clear") != nullptr ||
+ wcsstr(cond, L"partly cloudy") != nullptr ||
+ wcsstr(cond, L"mostly") != nullptr ||
+ wcsstr(cond, L"clouds") != nullptr) {
+ return PCLOUDY;
+ }
+ else if (
+ wcsstr(cond, L"sunny") != nullptr ||
+ wcsstr(cond, L"clear") != nullptr ||
+ wcsstr(cond, L"fair") != nullptr) {
+ return SUNNY;
+ }
+ else if (
+ wcsstr(cond, L"thunder") != nullptr ||
+ wcsstr(cond, L"t-storm") != nullptr) {
+ return LIGHT;
+ }
+ else if (
+ wcsstr(cond, L"cloud") != nullptr ||
+ wcsstr(cond, L"overcast") != nullptr) {
+ return CLOUDY;
+ }
+ else if (
+ wcsstr(cond, L"fog") != nullptr ||
+ wcsstr(cond, L"mist") != nullptr ||
+ wcsstr(cond, L"smoke") != nullptr ||
+ wcsstr(cond, L"sand") != nullptr ||
+ wcsstr(cond, L"dust") != nullptr ||
+ wcsstr(cond, L"haze") != nullptr) {
+ return FOG;
+ }
+ else if (
+ (wcsstr(cond, L"shower") != nullptr && wcsstr(cond, L"snow") != nullptr) ||
+ wcsstr(cond, L"flurries") != nullptr) {
+ return SSHOWER;
+ }
+ else if (
+ wcsstr(cond, L"rain shower") != nullptr ||
+ wcsstr(cond, L"shower") != nullptr) {
+ return RSHOWER;
+ }
+ else if (
+ wcsstr(cond, L"snow") != nullptr ||
+ wcsstr(cond, L"ice") != nullptr ||
+ wcsstr(cond, L"freezing") != nullptr ||
+ wcsstr(cond, L"wintry") != nullptr) {
+ return SNOW;
+ }
+ else if (
+ wcsstr(cond, L"drizzle") != nullptr ||
+ wcsstr(cond, L"rain") != nullptr) {
+ return RAIN;
+ }
+
+ // set the icon using langpack
+ for (int i = 0; i < 9; i++) {
+ wchar_t LangPackStr[64], LangPackStr1[128];
+ int j = 0;
+ do {
+ j++;
+ // using the format _T("# Weather <condition name> <counter> #"
+ mir_snwprintf(LangPackStr, L"# Weather %s %i #", statusStr[i], j);
+ wcsncpy_s(LangPackStr1, TranslateW(LangPackStr), _TRUNCATE);
+ CharLowerBuff(LangPackStr1, (DWORD)mir_wstrlen(LangPackStr1));
+ if (wcsstr(cond, LangPackStr1) != nullptr)
+ return statusValue[i];
+ // loop until the translation string exists (ie, the translated string is differ from original)
+ } while (mir_wstrcmp(TranslateW(LangPackStr), LangPackStr));
+ }
+
+ return NA;
+}
+
+//============ STRING CONVERSIONS ============
+//
+// this function convert the string to the format with 1 upper case followed by lower case char
+void CaseConv(wchar_t *str)
+{
+ bool nextUp = true;
+
+ CharLowerBuffW(str, (DWORD)mir_wstrlen(str));
+ for (wchar_t *pstr = str; *pstr; pstr++) {
+ if (*pstr == ' ' || *pstr == '-')
+ nextUp = true;
+ else if (nextUp) {
+ CharUpperBuffW(pstr, 1);
+ nextUp = false;
+ }
+ }
+}
+
+// the next 2 functions are copied from miranda source
+// str = the string to modify
+//
+void TrimString(char *str)
+{
+ size_t len, start;
+
+ len = mir_strlen(str);
+ while (len && (unsigned char)str[len - 1] <= ' ') str[--len] = 0;
+ for (start = 0; (unsigned char)str[start] <= ' ' && str[start]; start++);
+ memmove(str, str + start, len - start + 1);
+}
+
+void TrimString(WCHAR *str)
+{
+ size_t len, start;
+
+ len = mir_wstrlen(str);
+ while (len && (unsigned char)str[len - 1] <= ' ') str[--len] = 0;
+ for (start = 0; (unsigned char)str[start] <= ' ' && str[start]; start++);
+ memmove(str, str + start, (len - start + 1)*sizeof(WCHAR));
+}
+
+// convert \t to tab and \n to linefeed
+void ConvertBackslashes(char *str)
+{
+ for (char *pstr = str; *pstr; pstr = CharNextA(pstr)) {
+ if (*pstr == '\\') {
+ switch (pstr[1]) {
+ case 'n': *pstr = '\n'; break;
+ case 't': *pstr = '\t'; break;
+ default: *pstr = pstr[1]; break;
+ }
+ memmove(pstr + 1, pstr + 2, mir_strlen(pstr + 2) + 1);
+ }
+ }
+}
+
+// replace spaces with _T("%20"
+// dis = original string
+// return value = the modified string with space -> _T("%20"
+char *GetSearchStr(char *dis)
+{
+ char *pstr = dis;
+ size_t len = mir_strlen(dis);
+ while (*pstr != 0) {
+ if (*pstr == ' ') {
+ memmove(pstr + 3, pstr + 1, len);
+ memcpy(pstr, L"%20", 3);
+ pstr += 2;
+ }
+ pstr++;
+ len--;
+ }
+ return dis;
+}
+
+//============ ICON ASSIGNMENT ============
+//
+// make display and history strings
+// w = WEATHERINFO data to be parsed
+// dis = the string to parse
+// return value = the parsed string
+wchar_t* GetDisplay(WEATHERINFO *w, const wchar_t *dis, wchar_t* str)
+{
+ wchar_t lpzDate[32], chr;
+ char name[256], temp[2];
+ DBVARIANT dbv;
+ size_t i;
+
+ // Clear the string
+ str[0] = 0;
+
+ // looking character by character
+ for (i = 0; i < mir_wstrlen(dis); i++) {
+ // for the escape characters
+ if (dis[i] == '\\') {
+ i++;
+ chr = dis[i];
+ switch (chr) {
+ case '%': mir_wstrcat(str, L"%"); break;
+ case 't': mir_wstrcat(str, L"\t"); break;
+ case 'n': mir_wstrcat(str, L"\r\n"); break;
+ case '\\': mir_wstrcat(str, L"\\"); break;
+ }
+ }
+
+ // for the % varaibles
+ else if (dis[i] == '%') {
+ i++;
+ chr = dis[i];
+ // turn capitalized characters to small case
+ if (chr < 'a' && chr != '[' && chr != '%') chr = (char)((int)chr + 32);
+ switch (chr) {
+ case 'c': mir_wstrcat(str, w->cond); break;
+ case 'd': // get the current date
+ GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, nullptr, nullptr, lpzDate, _countof(lpzDate));
+ mir_wstrcat(str, lpzDate); break;
+ case 'e': mir_wstrcat(str, w->dewpoint); break;
+ case 'f': mir_wstrcat(str, w->feel); break;
+ case 'h': mir_wstrcat(str, w->high); break;
+ case 'i': mir_wstrcat(str, w->winddir); break;
+ case 'l': mir_wstrcat(str, w->low); break;
+ case 'm': mir_wstrcat(str, w->humid); break;
+ case 'n': mir_wstrcat(str, w->city); break;
+ case 'p': mir_wstrcat(str, w->pressure); break;
+ case 'r': mir_wstrcat(str, w->sunrise); break;
+ case 's': mir_wstrcat(str, w->id); break;
+ case 't': mir_wstrcat(str, w->temp); break;
+ case 'u':
+ if (mir_wstrcmp(w->update, NODATA)) mir_wstrcat(str, w->update);
+ else mir_wstrcat(str, TranslateT("<unknown time>"));
+ break;
+ case 'v': mir_wstrcat(str, w->vis); break;
+ case 'w': mir_wstrcat(str, w->wind); break;
+ case 'y': mir_wstrcat(str, w->sunset); break;
+ case '%': mir_wstrcat(str, L"%"); break;
+ case '[': // custom variables
+ i++;
+ name[0] = 0;
+ // read the entire variable name
+ while (dis[i] != ']' && i < mir_wstrlen(dis)) {
+ mir_snprintf(temp, "%c", dis[i++]);
+ mir_strcat(name, temp);
+ }
+ // access the database to get its value
+ if (!db_get_ws(w->hContact, WEATHERCONDITION, name, &dbv)) {
+ if (dbv.pwszVal != TranslateW(NODATA) && dbv.pwszVal != TranslateT("<Error>"))
+ mir_wstrcat(str, dbv.pwszVal);
+ db_free(&dbv);
+ }
+ break;
+ }
+ }
+ // if the character is not a variable, write the original character to the new string
+ else {
+ mir_snwprintf(lpzDate, L"%c", dis[i]);
+ mir_wstrcat(str, lpzDate);
+ }
+ }
+
+ return str;
+}
+
+wchar_t svcReturnText[MAX_TEXT_SIZE];
+INT_PTR GetDisplaySvcFunc(WPARAM wParam, LPARAM lParam)
+{
+ WEATHERINFO winfo = LoadWeatherInfo(wParam);
+ return (INT_PTR)GetDisplay(&winfo, (wchar_t*)lParam, svcReturnText);
+}
+
+//============ ID MANAGEMENT ============
+//
+// get service data module internal name
+// mod/id <- the mod part
+// pszID = original 2-part id, return the service internal name
+void GetSvc(wchar_t *pszID)
+{
+ wchar_t *chop = wcsstr(pszID, L"/");
+ if (chop != nullptr) *chop = '\0';
+ else pszID[0] = 0;
+}
+
+// get the id use for update without the service internal name
+// mod/id <- the id part
+// pszID = original 2-part id, return the single part id
+void GetID(wchar_t *pszID)
+{
+ wchar_t *chop = wcsstr(pszID, L"/");
+ if (chop != nullptr) mir_wstrcpy(pszID, chop + 1);
+ else pszID[0] = 0;
+}
+
+//============ WEATHER ERROR CODE ============
+//
+// Get the text when an error code is specified
+// code = the error code obtained when updating weather
+// str = the string for the error
+//
+wchar_t *GetError(int code)
+{
+ wchar_t *str, str2[100];
+ switch (code) {
+ case 10: str = E10; break;
+ case 11: str = E11; break;
+ case 12: str = E12; break;
+ case 20: str = E20; break;
+ case 30: str = E30; break;
+ case 40: str = E40; break;
+ case 42: str = E42; break;
+ case 43: str = E43; break;
+ case 99: str = E99; break;
+ case 204: str = E204; break;
+ case 301: str = E301; break;
+ case 305: str = E305; break;
+ case 307: str = E307; break;
+ case 400: str = E400; break;
+ case 401: str = E401; break;
+ case 402: str = E402; break;
+ case 403: str = E403; break;
+ case 404: str = E404; break;
+ case 405: str = E405; break;
+ case 407: str = E407; break;
+ case 410: str = E410; break;
+ case 500: str = E500; break;
+ case 502: str = E502; break;
+ case 503: str = E503; break;
+ case 504: str = E504; break;
+ default:
+ mir_snwprintf(str2, TranslateT("HTTP Error %i"), code);
+ str = str2;
+ break;
+ }
+ return mir_wstrdup(str);
+}