src/cmd/fsexam/src/encoding.c
changeset 147 8c4ef02c14b8
parent 146 841e634f8d60
child 148 91c620d9e52f
equal deleted inserted replaced
146:841e634f8d60 147:8c4ef02c14b8
     1 /*
       
     2  * CDDL HEADER START
       
     3  *
       
     4  * The contents of this file are subject to the terms of the
       
     5  * Common Development and Distribution License (the "License").
       
     6  * You may not use this file except in compliance with the License.
       
     7  *
       
     8  * You can obtain a copy of the license at src/OPENSOLARIS.LICENSE
       
     9  * or http://www.opensolaris.org/os/licensing.
       
    10  * See the License for the specific language governing permissions
       
    11  * and limitations under the License.
       
    12  *
       
    13  * When distributing Covered Code, include this CDDL HEADER in each
       
    14  * file and include the License file at src/OPENSOLARIS.LICENSE.
       
    15  * If applicable, add the following below this CDDL HEADER, with the
       
    16  * fields enclosed by brackets "[]" replaced with your own identifying
       
    17  * information: Portions Copyright [yyyy] [name of copyright owner]
       
    18  *
       
    19  * CDDL HEADER END
       
    20  */
       
    21 
       
    22 /*
       
    23  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
       
    24  * Use is subject to license terms.
       
    25  */
       
    26 
       
    27 
       
    28 #include <glib.h>
       
    29 #include <stdio.h>
       
    30 #include <sys/types.h>
       
    31 #include <string.h>
       
    32 #include <dirent.h>
       
    33 #include "encode.h"
       
    34 
       
    35 GList *
       
    36 init_encode (GSList *list)
       
    37 {
       
    38   int      n = 0;
       
    39   GList    *encode_list = NULL;
       
    40 
       
    41   while (list)
       
    42     {
       
    43       GIConv icd;
       
    44       Encoding *encode;
       
    45       GSList *tmp_list = list;
       
    46 
       
    47       list = g_slist_next (list);
       
    48 
       
    49       if ((icd = g_iconv_open ("UTF-8", (char *)tmp_list->data)) == (GIConv)-1)
       
    50 	continue;
       
    51 
       
    52       encode = g_new0 (Encoding, 1);
       
    53       encode->icd = icd;
       
    54       strcpy (encode->codename, (char *)tmp_list->data);
       
    55       encode->score = FAIL;
       
    56       encode->convtype = ConvName;
       
    57 
       
    58       encode_list = g_list_insert (encode_list, encode, n);
       
    59 
       
    60       ++n;
       
    61     }
       
    62 
       
    63   return encode_list;
       
    64 }
       
    65 
       
    66 void
       
    67 destroy_encode (GList *encode_list)
       
    68 {
       
    69   while (encode_list)
       
    70     {
       
    71       Encoding *encode = (Encoding *)encode_list->data;
       
    72 
       
    73       if (encode->convtype == ConvContent && encode->u.contents)
       
    74 	g_free (encode->u.contents);
       
    75 	
       
    76       g_iconv_close (encode->icd);
       
    77       g_free (encode);
       
    78 
       
    79       encode_list = g_list_next (encode_list);
       
    80     }
       
    81 
       
    82   g_list_free (encode_list);
       
    83 }
       
    84 
       
    85 /*
       
    86  * Only work for ConvName and ConvContent
       
    87  */
       
    88 Score
       
    89 decode_analyzer (GList *encode_list,
       
    90 		 ConvType convtype,
       
    91 		 gchar *text, 
       
    92 		 size_t textlen)
       
    93 {
       
    94   gboolean success = FAIL;
       
    95 
       
    96   if (g_utf8_validate (text, textlen, NULL)) return ORIGINAL;
       
    97 
       
    98   while (encode_list)
       
    99     {
       
   100       Encoding *encode = (Encoding *)encode_list->data;
       
   101       gchar    *inbuf = text;
       
   102       size_t   inbytes_left = textlen;
       
   103       gchar    *outbuf;
       
   104       size_t   outbytes_left;
       
   105       size_t   num_uconv = 0;
       
   106 
       
   107       encode->convtype = convtype;
       
   108       if (convtype == ConvName)
       
   109 	{
       
   110 	  outbuf = encode->u.converted_text;
       
   111 	  outbytes_left = 256;
       
   112 	}
       
   113       else /* ConvContent */
       
   114 	{
       
   115 	  outbytes_left = 3 * inbytes_left;
       
   116 	  outbuf = encode->u.contents = g_new0 (char, outbytes_left);
       
   117 	}
       
   118 
       
   119       memset (outbuf, 0, outbytes_left);
       
   120       num_uconv = g_iconv (encode->icd, &inbuf, &inbytes_left,
       
   121 			   &outbuf, &outbytes_left);
       
   122       switch (num_uconv)
       
   123 	{
       
   124 	case 0:
       
   125 	  encode->score = HIGH;
       
   126 	  success = TRUE;
       
   127 	  break;
       
   128 	case (size_t)-1:
       
   129 	  encode->score = FAIL;
       
   130 	  break;
       
   131 	default:
       
   132 	  encode->score = LOW;
       
   133 	  success = TRUE;
       
   134 	  break;
       
   135 	}
       
   136 
       
   137       encode_list = g_list_next (encode_list);
       
   138     }
       
   139 
       
   140   if (success) return HIGH;
       
   141   else return FAIL;
       
   142 }
       
   143 
       
   144 gboolean
       
   145 get_encode_elements (Encoding *encode,
       
   146 		     gint index,
       
   147 		     va_list args)
       
   148 {
       
   149   gint *n_elements;
       
   150 
       
   151   n_elements = va_arg (args, int *);
       
   152   (*n_elements)++;
       
   153 
       
   154   return TRUE;
       
   155 }
       
   156 
       
   157 void
       
   158 iterate_encode_with_func (GList *encode_list,
       
   159 			  EncodeFunc func, ...)
       
   160 {
       
   161   va_list args;
       
   162 
       
   163   va_start (args, func);
       
   164 
       
   165   int encode_idx = -1;
       
   166   while (encode_list)
       
   167     {
       
   168       Encoding *encode = (Encoding *)encode_list->data;
       
   169 
       
   170       encode_list = g_list_next (encode_list);
       
   171       ++encode_idx;
       
   172 
       
   173       if (encode->score == FAIL) continue;
       
   174 
       
   175       if (!(*func)(encode, encode_idx, args))
       
   176 	break;
       
   177     }
       
   178 
       
   179   va_end (args);
       
   180 }
       
   181 
       
   182 gboolean
       
   183 translate_encode_index (Encoding *encode, 
       
   184 			gint index,
       
   185 			va_list args)
       
   186 {
       
   187   gint *old_index = va_arg (args, int *);
       
   188   gint *new_index = va_arg (args, int *);
       
   189 
       
   190   if (*old_index)
       
   191     {
       
   192       --*old_index;
       
   193       return TRUE;
       
   194     }
       
   195   else
       
   196     {
       
   197       *new_index = index;
       
   198       return FALSE;
       
   199     }
       
   200 }
       
   201 
       
   202 int
       
   203 get_first_encode_index (GList *encode_list)
       
   204 {
       
   205   int encode_idx = -1, best_idx = -1;
       
   206 
       
   207   while (encode_list)
       
   208     {
       
   209       Encoding *encode = (Encoding *)encode_list->data;
       
   210 
       
   211       encode_list = g_list_next (encode_list);
       
   212       ++encode_idx;
       
   213 
       
   214       if (encode->score == HIGH) 
       
   215 	{
       
   216 	  // found it, the first encoding with score as HIGH
       
   217 	  best_idx = encode_idx;
       
   218 	  break;
       
   219 	}
       
   220       else if (encode->score == LOW)
       
   221 	{
       
   222 	  // record the first encoding with score as LOW
       
   223 	  if (best_idx == -1) 
       
   224 	    best_idx = encode_idx;
       
   225 	}
       
   226     }
       
   227 
       
   228   return best_idx;
       
   229 }
       
   230 
       
   231 void
       
   232 cleanup_encode (GList *encode_list)
       
   233 {
       
   234   while (encode_list)
       
   235     {
       
   236       Encoding *encode = (Encoding *)encode_list->data;
       
   237 
       
   238       if (encode->convtype == ConvContent)
       
   239 	{
       
   240 	  encode->convtype = ConvName;
       
   241 	  if (encode->u.contents)
       
   242 	    g_free (encode->u.contents);
       
   243 	}
       
   244 
       
   245       encode_list = g_list_next (encode_list);
       
   246     }
       
   247 }