Logo Search packages:      
Sourcecode: easyh10 version File versions  Download package

ucs2char_iconv.c

/*
 *      UCS-2 implementation with libiconv.
 *
 *      Copyright (c) 2005 Nyaochi
 *
 * 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., 675 Mass Ave, Cambridge, MA 02139, USA, or visit
 * http://www.gnu.org/copyleft/gpl.html .
 *
 */

/* $Id: ucs2char_iconv.c,v 1.25 2005/10/07 00:34:11 nyaochi Exp $ */

#ifdef      HAVE_CONFIG_H
#include <config.h>
#endif/*HAVE_CONFIG_H*/

#include <os.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <ucs2char.h>

#include <iconv.h>

#ifdef  USE_LIBICONV_GNU
#define iconv_open      libiconv_open
#define iconv_convert   libiconv_convert
#define iconv_close     libiconv_close
#endif/*USE_LIBICONV_GNU*/

#define     MBS_CHARSET "UTF-8"

static char g_encoding[128];
static char g_encoding_music[128];
static char g_ucs2encoding[128];

static void print_ucs2(const ucs2_char_t* str)
{
  while (*str) {
    fprintf(stderr, "0x%X %c ", *str);
    str++;
  }
  fprintf(stderr, "\n");
}

static int is_bigendian(void)
{
      ucs2_char_t c = 0x1234;
      uint8_t* p = (uint8_t*)&c;
      return (*p == 0x12);
}

static const char *get_ucs2encoding(void)
{
      static const char *unicode_big = "UNICODEBIG";
      static const char *unicode_little = "UNICODELITTLE";
      return is_bigendian() ? unicode_big : unicode_little;
}

int ucs2init(const char *encoding) 
{
      if (!encoding) {
            encoding = MBS_CHARSET;
      }
      strcpy(g_encoding, encoding);
      strcpy(g_encoding_music, encoding);
}

int ucs2set_encoding(const char *encoding, ucs2conv_t* conv)
{
      strncpy(g_encoding, encoding, sizeof(g_encoding));
      strncpy(g_ucs2encoding, get_ucs2encoding(), sizeof(g_ucs2encoding));
      return ucs2check(conv);
}

int ucs2set_encoding_music(const char *encoding, ucs2conv_t* conv)
{
      strncpy(g_encoding_music, encoding, sizeof(g_encoding_music));
      strncpy(g_ucs2encoding, get_ucs2encoding(), sizeof(g_ucs2encoding));
      return ucs2check(conv);
}


int ucs2check(ucs2conv_t* conv)
{
      int i = 0;
      iconv_t cd;
      const static char *charsets[] = {
            g_encoding, "UNICODE",
            "UNICODE", g_encoding,
            g_encoding_music, "UNICODE",
            "UNICODE", g_encoding_music,
            "UNICODE", "UTF-8",
            NULL, NULL,
      };

      for (i = 0;charsets[i];i += 2) { 
            const char *tocode = charsets[i];
            const char *fromcode = charsets[i+1];
            if (strcmp(tocode, "UNICODE") == 0) {
              tocode = get_ucs2encoding();
            }
            if (strcmp(fromcode, "UNICODE") == 0) {
              fromcode = get_ucs2encoding();
            }
        cd = iconv_open(tocode, fromcode);
            if (cd == (iconv_t)-1) {
              if (conv) {
                conv->from = fromcode;
                conv->to = tocode;
              }
                  return -1;
            }
            iconv_close(cd);
      }
      return 0;
}

void ucs2big2little(ucs2_char_t* value)
{
  if (is_bigendian()) {
      for (;*value;value++) {
            ucs2_char_t val = (*value << 8) | (*value >> 8);
            *value = val;
      }
  }
}

int ucs2toi(const ucs2_char_t* str)
{
      int ret;
      char *mbs = ucs2dupmbs(str);
      ret = atoi(mbs);
      free(mbs);
      return ret;
}

ucs2_char_t* itoucs2(int value, ucs2_char_t *string, int radix)
{
      char buff[1024];
      sprintf(buff, "%d", value);
      mbstoucs2(string, 1024, buff, sizeof(buff));
      return string;
}

size_t iconv_convert(iconv_t cd, char **outbuf, size_t out_size, char **inbuf, size_t in_size)
{
      size_t ret = 0;
      if (*outbuf && out_size) {
            size_t inbytesleft = in_size;
            size_t outbytesleft = out_size;
            iconv(cd, (const char **)inbuf, &inbytesleft, (char **)outbuf, &outbytesleft);
            ret = (out_size - outbytesleft);
      } else {
            size_t inbytesleft = in_size;
            while (inbytesleft > 0) {
                  char buffer[1024];
                  char *p = buffer;
                  size_t outbytesleft = 1024;
                  int iconvret = iconv(cd, (const char **)inbuf, &inbytesleft, &p, &outbytesleft);
                  if (iconvret == -1) {
                        return 0;
                  }
                  ret += (1024 - outbytesleft);
            }
      }
      return ret;
}

size_t ucs2tombs(char *mbstr, size_t mbs_size, const ucs2_char_t *ucs2str, size_t ucs_size)
{
      iconv_t cd = iconv_open(g_encoding, g_ucs2encoding);
      size_t ret = iconv_convert(cd, (char **)&mbstr, mbs_size, (char **)&ucs2str, ucs_size * sizeof(ucs2_char_t));
      iconv_close(cd);
      return ret;
}

size_t mbstoucs2(ucs2_char_t *ucs2str, size_t ucs_size, const char *mbstr, size_t mbs_size)
{
      iconv_t cd = iconv_open(g_ucs2encoding, g_encoding);
      size_t ret = iconv_convert(cd, (char **)&ucs2str, ucs_size * sizeof(ucs2_char_t), (char **)&mbstr, mbs_size);
      iconv_close(cd);
      return ret;
}

size_t mbstoucs2_music(ucs2_char_t *ucs2str, size_t ucs_size, const char *mbstr, size_t mbs_size)
{
      iconv_t cd = iconv_open(g_ucs2encoding, g_encoding_music);
      size_t ret = iconv_convert(cd, (char **)&ucs2str, ucs_size * sizeof(ucs2_char_t), (char **)&mbstr, mbs_size);
      iconv_close(cd);
      return ret;
}

size_t utf8toucs2(ucs2_char_t *ucs2str, size_t ucs_size, const char *mbstr, size_t mbs_size)
{
      iconv_t cd = iconv_open(g_ucs2encoding, "UTF-8");
      size_t ret = iconv_convert(cd, (char **)&ucs2str, ucs_size * sizeof(ucs2_char_t), (char **)&mbstr, mbs_size);
      iconv_close(cd);
      return ret;
}







static void path_decode(char *p)
{
      while (*p) {
            if (*p == 0x005C) {
                  *p = 0x002F;
            }
            p++;
      }
}

FILE *ucs2fopen(const ucs2_char_t *filename, const char *mode)
{
      FILE *fp = NULL;
      char *mbs_filename = ucs2dupmbs(filename);

      if (mbs_filename) {
            /* Convert '\\' to '/'. */
            path_decode(mbs_filename);
            fp = fopen(mbs_filename, mode);
      }
      free(mbs_filename);
      return fp;
}

time_t ucs2stat_mtime(const ucs2_char_t *filename)
{
      int ret = 0;
      struct stat st;
      char *mbs_path = ucs2dupmbs(filename);

      if (mbs_path) {
            path_decode(mbs_path);
            ret = stat(mbs_path, &st);
            free(mbs_path);
            if (ret == 0) {
                  return st.st_mtime;
            }
      }
      return 0;
}

uint32_t ucs2stat_size(const ucs2_char_t *filename)
{
      int ret = 0;
      struct stat st;
      char *mbs_path = ucs2dupmbs(filename);

      if (mbs_path) {
            path_decode(mbs_path);
            ret = stat(mbs_path, &st);
            free(mbs_path);
            if (ret == 0) {
                  return (uint32_t)st.st_size;
            }
      }
      return 0;
}

int ucs2stat_is_dir(const ucs2_char_t *filename)
{
      int ret = 0;
      struct stat st;
      char *mbs_path = ucs2dupmbs(filename);

      if (mbs_path) {
            path_decode(mbs_path);
            ret = stat(mbs_path, &st);
            free(mbs_path);
            if (ret == 0) {
                  return ((st.st_mode & S_IFMT) == S_IFDIR);
            }
      }
      return 0;
}

int ucs2stat_is_exist(const ucs2_char_t *filename)
{
      int ret = 0;
      struct stat st;
      char *mbs_path = ucs2dupmbs(filename);

      if (mbs_path) {
            path_decode(mbs_path);
            ret = open(mbs_path, 0);
            free(mbs_path);
            if (ret != -1) {
                  close(ret);
            }
            return (ret != -1);
      }
      return 0;
}

Generated by  Doxygen 1.6.0   Back to index