/* * Miranda-IM Vypress Chat/quickChat plugins * Copyright (C) Saulius Menkevicius * * 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; either version 2 of the License, or * (at your option) any later version. * * 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, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: util.c,v 1.7 2005/04/11 21:44:16 bobas Exp $ */ #include #include #include "main.h" #include "util.h" /* exported routines */ /* ip/ipx address funcs */ char * util_vqpaddr2str(vqp_addr_t addr) { char * str = malloc(32); if(addr.conn == VQP_PROTOCOL_CONN_UDP) { sprintf(str, "%u.%u.%u.%u", (unsigned)(addr.node.ip >> 24) & 0xff, (unsigned)(addr.node.ip >> 16) & 0xff, (unsigned)(addr.node.ip >> 8) & 0xff, (unsigned)addr.node.ip & 0xff); } else { sprintf(str, "%02X:%02X:%02X:%02X:%02X:%02X", addr.node.ipx[5], addr.node.ipx[4], addr.node.ipx[3], addr.node.ipx[2], addr.node.ipx[1], addr.node.ipx[0]); } return str; } /* utf8/locale/unicode conversion */ char * util_loc2utf(const char * loc_str) { wchar_t * uni_str = util_loc2uni(loc_str); char * utf_str = util_uni2utf(uni_str); free(uni_str); return utf_str; } char * util_utf2loc(const char * utf_str) { wchar_t * uni_str = util_utf2uni(utf_str); char * loc_str = util_uni2loc(uni_str); free(uni_str); return loc_str; } wchar_t * util_loc2uni(const char * loc_str) { int loc_len, uni_len; wchar_t * uni_str; loc_len = lstrlenA(loc_str) + 1; uni_len = MultiByteToWideChar(CP_ACP, 0, loc_str, loc_len, NULL, 0); uni_str = malloc(sizeof(wchar_t) * uni_len); MultiByteToWideChar(CP_ACP, 0, loc_str, loc_len, uni_str, uni_len); return uni_str; } char * util_uni2loc(const wchar_t * uni_str) { int uni_len, loc_len; char * loc_str; uni_len = lstrlenW(uni_str) + 1; loc_len = WideCharToMultiByte(CP_ACP, 0, uni_str, uni_len, NULL, 0, NULL, NULL); loc_str = malloc(loc_len); WideCharToMultiByte(CP_ACP, 0, uni_str, uni_len, loc_str, loc_len, NULL, NULL); return loc_str; } wchar_t * util_utf2uni(const char * utf_str) { int utf_len, uni_len; wchar_t * uni_str; utf_len = lstrlenA(utf_str) + 1; uni_len = MultiByteToWideChar(CP_UTF8, 0, utf_str, utf_len, NULL, 0); uni_str = malloc(sizeof(wchar_t) * uni_len); MultiByteToWideChar(CP_UTF8, 0, utf_str, utf_len, uni_str, uni_len); return uni_str; } char * util_uni2utf(const wchar_t * uni_str) { int uni_len, utf_len; char * utf_str; uni_len = lstrlenW(uni_str) + 1; utf_len = WideCharToMultiByte(CP_UTF8, 0, uni_str, uni_len, NULL, 0, NULL, NULL); utf_str = malloc(utf_len); WideCharToMultiByte(CP_UTF8, 0, uni_str, uni_len, utf_str, utf_len, NULL, NULL); return utf_str; } /* string functions */ char * util_vqp2utf(enum vqp_codepage codepage, const char * vqp_text) { return codepage == VQP_CODEPAGE_UTF8 ? strdup(vqp_text): util_loc2utf(vqp_text); } char * util_utf2vqp(enum vqp_codepage codepage, const char * utf_text) { return codepage == VQP_CODEPAGE_UTF8 ? strdup(utf_text): util_utf2loc(utf_text); } /* util_split_multiline: * splits a multiline string into it's lines, * optionally emitting the empty ones * returns: * an array of (char*), with the last being NULL */ char ** util_split_multiline(const char * text, int include_empty) { int n_lines, i; const char * line, * next; char ** array, * str; ASSERT_RETURNVALIFFAIL(VALIDPTR(text), NULL); /* get the number of lines */ n_lines = 1; line = text; while((line = strchr(line, '\n')) != NULL) { n_lines ++; line ++; /* skip the '\n' we've found */ } /* alloc the array */ array = malloc(sizeof(void *) * (n_lines + 1)); /* split the strings */ line = text; i = 0; do { int line_len; /* get the end of this line */ next = strchr(line, '\n'); if(next) { /* get the length of the line */ line_len = next - line; /* skip the '\r' at the end of the line, if exists */ if(line[line_len - 1] == '\r') line_len --; } else { line_len = strlen(line); } /* alloc and copy the string */ if(include_empty || (!include_empty && line_len!=0)) { str = malloc(line_len + 1); memcpy(str, line, line_len); str[line_len] = '\0'; array[i ++] = str; } /* advance to the next line */ if(next) { /* skip pas the \n char onto the next line */ line = next + 1; } } while(next); /* end up the array */ array[i] = NULL; /* return all we got here */ return array; } /* util_free_str_list: * frees a (char*) list, like the one alloced * by util_split_multiline() */ void util_free_str_list(char ** str_list) { char ** pstr; ASSERT_RETURNIFFAIL(VALIDPTR(str_list)); /* free each of the strings in the list */ for(pstr = str_list; *pstr; pstr ++) free(*pstr); free(str_list); } /* windows unicode functions */ void util_SetWindowTextUtf(HWND hwnd, const char * utf_str) { wchar_t * unistr; ASSERT_RETURNIFFAIL(utf_str); unistr = util_utf2uni(utf_str); SetWindowTextW(hwnd, unistr); free(unistr); } char * util_GetWindowTextUtf(HWND hwnd) { int len; wchar_t * uni_str; char * utf_str; len = GetWindowTextLengthW(hwnd) + 1; uni_str = malloc(sizeof(wchar_t) * len); GetWindowTextW(hwnd, uni_str, len); utf_str = util_uni2utf(uni_str); free(uni_str); return utf_str; } void util_SetDlgItemTextUtf(HWND hDialog, int nDlgItemN, const char * utf_str) { util_SetWindowTextUtf(GetDlgItem(hDialog, nDlgItemN), utf_str); } char * util_GetDlgItemTextUtf(HWND hDialog, int nDlgItemN) { return util_GetWindowTextUtf(GetDlgItem(hDialog, nDlgItemN)); } /* db module extension routines */ int db_blob_set( HANDLE hContact, const char * szModule, const char * szSetting, void * pBlob, size_t cpBlob) { DBCONTACTWRITESETTING cws; cws.szModule = szModule; cws.szSetting = szSetting; cws.value.type = DBVT_BLOB; cws.value.cpbVal = cpBlob; cws.value.pbVal = pBlob; return CallService(MS_DB_CONTACT_WRITESETTING, (WPARAM)hContact, (LPARAM)&cws); } BOOL db_dword_list_add( HANDLE hContact, const char * szModule, const char * szSetting, DWORD dw, BOOL unique) { DWORD * list, * new_list; size_t list_sz; if(unique && db_dword_list_contains(hContact, szModule, szSetting, dw)) return FALSE; /* append dword and write the new list */ list = db_dword_list(hContact, szModule, szSetting, &list_sz); if(list) { new_list = malloc(sizeof(DWORD) * (list_sz + 1)); if(!new_list) { free(list); return FALSE; } memcpy(new_list, list, sizeof(DWORD) * list_sz); new_list[list_sz] = dw; db_blob_set(hContact, szModule, szSetting, new_list, sizeof(DWORD) * (list_sz + 1)); free(new_list); free(list); } else { db_blob_set(hContact, szModule, szSetting, &dw, sizeof(DWORD)); } return TRUE; } void db_dword_list_remove( HANDLE hContact, const char * szModule, const char * szSetting, DWORD dw) { DWORD * list; size_t list_sz; list = db_dword_list(hContact, szModule, szSetting, &list_sz); if(list) { size_t i; for(i = 0; i < list_sz; i++) if(list[i] == dw) { if(list_sz != 1) { char * new_list = malloc(sizeof(DWORD) * (list_sz - 1)); if(!new_list) break; memcpy(new_list, list, sizeof(DWORD) * i); memcpy(new_list + i, list + i + 1, sizeof(DWORD) * (list_sz - i - 1)); db_blob_set(hContact, szModule, szSetting, new_list, sizeof(DWORD) * (list_sz - 1)); } else { db_unset(hContact, szModule, szSetting); } break; } } free(list); } DWORD * db_dword_list( HANDLE hContact, const char * szModule, const char * szSetting, size_t * pCount) { DBVARIANT dbv; DWORD * list = NULL; ASSERT_RETURNVALIFFAIL(szModule!=NULL && szSetting!=NULL && pCount!=NULL, NULL); *pCount = 0; if(!db_get(hContact, szModule, szSetting, &dbv)) { if(dbv.type == DBVT_BLOB && (dbv.cpbVal % sizeof(DWORD))==0 && dbv.cpbVal!=0) { list = malloc(dbv.cpbVal); if(list) { memcpy(list, dbv.pbVal, dbv.cpbVal); *pCount = dbv.cpbVal / sizeof(DWORD); } } } DBFreeVariant(&dbv); return list; } BOOL db_dword_list_contains( HANDLE hContact, const char * szModule, const char * szSetting, DWORD dw) { DWORD * list; size_t list_sz, i; list = db_dword_list(hContact, szModule, szSetting, &list_sz); if(list) { for(i = 0; i < list_sz; i++) if(list[i]==dw) return TRUE; } return FALSE; }