utils.cpp

Go to the documentation of this file.
00001 /*
00002  * File Name: utils.cpp
00003  */
00004 
00005 /*
00006  * This file is part of uds-plugin-common.
00007  *
00008  * uds-plugin-common is free software: you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation, either version 2 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * uds-plugin-common is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program. If not, see <http://www.gnu.org/licenses/>.
00020  */
00021 
00022 /**
00023  * Copyright (C) 2008 iRex Technologies B.V.
00024  * All rights reserved.
00025  */
00026 
00027 #include <cassert>
00028 #include <ctype.h>
00029 #include <stdio.h>
00030 #include <string.h>
00031 #include <sys/types.h>
00032 #include <iconv.h>
00033 // #include <sys/sysinfo.h>
00034 
00035 #include "utils.h"
00036 #include "log.h"
00037 
00038 int get_free_memory()
00039 {
00040     /*
00041     struct sysinfo info;
00042     
00043     if (0 == sysinfo(&info))
00044     {
00045         return info.freeram;
00046     }
00047     */
00048     return 0;
00049 }
00050 
00051 // borrow from glib
00052 // TODO test
00053 unsigned int make_hash_code(const char *buffer, unsigned int len)
00054 {
00055     assert(buffer);
00056     assert(len != 0);
00057 
00058     const char *p = buffer;
00059     unsigned int h = 0;
00060 
00061     while (len--)
00062     {
00063         h = (h << 5) - h + *p;
00064         p++;
00065     }
00066 
00067     return h;
00068 }
00069 
00070 const char* utf8_strichr(const char *str, int len, gunichar c)
00071 {
00072     if (g_unichar_isalpha(c))
00073     {
00074         // Only alphabetic character is case related.
00075         c = g_unichar_toupper(c);
00076         for (const char* p=str; (len == -1 && *p != 0) || (p-str<len); p = g_utf8_next_char(p))
00077         {
00078             gunichar i = g_utf8_get_char(p);
00079             if (i == c || i-c == 32)
00080             {
00081                 return p;
00082             }
00083         }
00084         return NULL;
00085     }
00086     else
00087     {
00088         return g_utf8_strchr(str, len, c);
00089     }
00090 }
00091 
00092 const char* utf8_strirchr(const char *str, int len, gunichar c)
00093 {
00094     if (g_unichar_isalpha(c))
00095     {
00096         // Only alphabetic character is case related.
00097         c = g_unichar_toupper(c);
00098         const char *p = str + len;
00099         while (true)
00100         {
00101             // Try previous character.
00102             p = g_utf8_find_prev_char(str, p);
00103             if (p == NULL)
00104             {
00105                 return NULL;
00106             }
00107             
00108             gunichar i = g_utf8_get_char(p);
00109             if (i == c || i-c == 32)
00110             {
00111                 return p;
00112             }
00113         }
00114     }
00115     else
00116     {
00117         return g_utf8_strrchr(str, len, c);
00118     }
00119 }
00120 
00121 const char* utf8_strstr(const char *str, const char *sub, bool case_sensitive)
00122 {
00123     if (case_sensitive)
00124     {
00125         return strstr(str, sub);
00126     }
00127     else
00128     {
00129         // Ignore case.
00130         gunichar first_char = g_utf8_get_char(sub);
00131         size_t sub_len = strlen(sub);
00132 
00133         for (const char *p=str; *p != 0;)
00134         {
00135             const char *find = utf8_strichr(p, -1, first_char);
00136             if (find != NULL)
00137             {
00138 #ifdef WIN32
00139                 if (_strnicmp(find, sub, sub_len) == 0)
00140 #else
00141                 if (strncasecmp(find, sub, sub_len) == 0)
00142 #endif
00143                 {
00144                     return find;
00145                 }
00146                 else
00147                 {
00148                     p = g_utf8_next_char(find);
00149                 }
00150             }
00151             else
00152             {
00153                 return NULL;
00154             }
00155         }
00156 
00157         return NULL;
00158     }
00159 }
00160 
00161 const char* utf8_strrstr(const char *str, int len, const char *sub, bool case_sensitive)
00162 {
00163     gunichar first_char = g_utf8_get_char(sub);
00164     size_t sub_len = strlen(sub);
00165 
00166     while (len > 0)
00167     {
00168         const char *p = NULL;
00169         if (case_sensitive)
00170         {
00171             p = g_utf8_strrchr(str, len, first_char);
00172         }
00173         else
00174         {
00175             // Ignore case.
00176             p = utf8_strirchr(str, len, first_char);
00177         }
00178 
00179         if (p == NULL)
00180         {
00181             return NULL;
00182         }
00183 
00184         // The first char of sub string is found.
00185         int ret;
00186         if (case_sensitive)
00187         {
00188             ret = strncmp(p, sub, sub_len);
00189         }
00190         else
00191         {
00192 #ifdef WIN32
00193             ret = _strnicmp(p, sub, sub_len);
00194 #else
00195             ret = strncasecmp(p, sub, sub_len);
00196 #endif
00197         }
00198         
00199         if (ret == 0)
00200         {
00201             // Pattern found
00202             return p;
00203         }
00204         len = static_cast<int>(p - str);
00205     }
00206 
00207     return NULL;
00208 }
00209 
00210 bool is_whole_word(const char *str, const char *sub, size_t sub_len)
00211 {
00212     // Check the input parameters.
00213     if (   !str
00214         || !sub
00215         || sub_len == 0)
00216     {
00217         return false;
00218     }
00219 
00220     // Check the first char before 'sub'.
00221     const char *p = g_utf8_find_prev_char(str, sub);
00222     if (p)
00223     {
00224         gunichar prev_char = g_utf8_get_char(p);
00225         if (   g_unichar_isalpha(prev_char) 
00226             || g_unichar_isdigit(prev_char) 
00227             || prev_char == '_'   )
00228         {
00229             return false;
00230         }
00231     }
00232 
00233     // Check the first char after 'sub'.
00234     const char *n = sub + sub_len;
00235     if (*n)
00236     {
00237         gunichar next_char = g_utf8_get_char_validated(n, -1);
00238         if (   next_char > 0
00239             && (   g_unichar_isalpha(next_char)
00240                 || g_unichar_isdigit(next_char)
00241                 || next_char == '_'             ) )
00242         {
00243             return false;
00244         }
00245     }
00246 
00247     // Otherwise 'sub' is a whole word.
00248     return true;
00249 }
00250 
00251 bool get_dir_path(const char * filename, char * dir, int dir_len)
00252 {
00253     bool has_dir = false;
00254 
00255     if (filename && dir)
00256     {
00257        char * ptr = g_path_get_dirname(filename);
00258        if (ptr)
00259        {
00260            has_dir = true;
00261            
00262            g_snprintf(dir, dir_len, "%s", ptr);
00263            g_free(ptr);
00264        }
00265     }
00266 
00267     LOGPRINTF("%s %s %d", filename, dir, has_dir);
00268 
00269     return has_dir;
00270 }
00271 
00272 bool get_file_name(const char * filename, char *name, int name_len)
00273 {
00274     bool has_name = false;
00275 
00276     if (filename && name)
00277     {
00278         if (filename[strlen(filename)-1] != G_DIR_SEPARATOR)
00279         {
00280             char * ptr = g_path_get_basename(filename);
00281             if (ptr)
00282             {
00283                 if (strcmp(ptr, G_DIR_SEPARATOR_S)
00284                    && strcmp(ptr, "."))
00285                 {
00286                     has_name = true;
00287                     g_snprintf(name, name_len, "%s", ptr);
00288                 }
00289                 g_free(ptr);
00290             }
00291         }
00292     }
00293 
00294     LOGPRINTF("%s %s %d", filename, name, has_name);
00295 
00296     return has_name;
00297 }
00298 
00299 bool get_ext_name(const char * filename, char * ext, int ext_len)
00300 {
00301     bool has_ext = false;
00302   
00303     if (filename && ext)
00304     {
00305         char name[MAX_PATH_LEN];
00306         
00307         if (get_file_name(filename, name, MAX_PATH_LEN))
00308         {
00309             char * ptr = g_strrstr(name, ".");
00310             if (ptr)
00311             {
00312                 has_ext = true;
00313 
00314                 ptr++;
00315                 g_snprintf(ext, ext_len, "%s", ptr);
00316             }
00317         }
00318     }
00319 
00320     LOGPRINTF("%s %s %d", filename, ext, has_ext);
00321 
00322     return has_ext;
00323 }
00324 
00325 static iconv_t conv = (iconv_t) -1;
00326 bool ucs2utf8(char* ucs_str, size_t input_len, char* utf_str, size_t output_len)
00327 {
00328     if (conv == (iconv_t) -1)
00329     {
00330         conv = iconv_open("UTF-8", "Unicode");
00331     }
00332 
00333     assert(conv != (iconv_t) -1);
00334 
00335     char* in_buf  = ucs_str;
00336     char* out_buf = utf_str;
00337     size_t in_bytes_left  = input_len;
00338     size_t out_bytes_left = output_len;
00339 
00340 #ifdef WIN32
00341     if (-1 == iconv(conv, const_cast<const char **>(&in_buf), &in_bytes_left, &out_buf, &out_bytes_left))
00342 #else
00343     if ((size_t)-1 == iconv(conv, &in_buf, &in_bytes_left, &out_buf, &out_bytes_left))
00344 #endif
00345     {
00346         return false;
00347     }
00348 
00349     if (in_bytes_left != 0)
00350     {
00351         // Either we encountered an error, or the output buffer is too small.
00352         return false;
00353     }
00354 
00355     // Add '\0' terminator.
00356     *out_buf = 0;
00357     return true;
00358 }
00359 
Generated by  doxygen 1.6.2-20100208