~mshinke/nvdajp/MiscellaneousDependencies

« back to all changes in this revision

Viewing changes to include/jtalk/libopenjtalk/mecab/src/iconv_utils.cpp

  • Committer: Masataka Shinke
  • Date: 2012-01-12 20:01:32 UTC
  • mfrom: (26.1.42 miscdep)
  • Revision ID: mshinke@users.sourceforge.jp-20120112200132-fvksmjulcjdzu5mk
mergedĀ lp:~nishimotz/nvdajp/MiscellaneousDependenciesĀ 68

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// MeCab -- Yet Another Part-of-Speech and Morphological Analyzer
 
2
//
 
3
//
 
4
//  Copyright(C) 2001-2006 Taku Kudo <taku@chasen.org>
 
5
//  Copyright(C) 2004-2006 Nippon Telegraph and Telephone Corporation
 
6
 
 
7
/* ----------------------------------------------------------------- */
 
8
/*           The Japanese TTS System "Open JTalk"                    */
 
9
/*           developed by HTS Working Group                          */
 
10
/*           http://open-jtalk.sourceforge.net/                      */
 
11
/* ----------------------------------------------------------------- */
 
12
/*                                                                   */
 
13
/*  Copyright (c) 2008-2011  Nagoya Institute of Technology          */
 
14
/*                           Department of Computer Science          */
 
15
/*                                                                   */
 
16
/* All rights reserved.                                              */
 
17
/*                                                                   */
 
18
/* Redistribution and use in source and binary forms, with or        */
 
19
/* without modification, are permitted provided that the following   */
 
20
/* conditions are met:                                               */
 
21
/*                                                                   */
 
22
/* - Redistributions of source code must retain the above copyright  */
 
23
/*   notice, this list of conditions and the following disclaimer.   */
 
24
/* - Redistributions in binary form must reproduce the above         */
 
25
/*   copyright notice, this list of conditions and the following     */
 
26
/*   disclaimer in the documentation and/or other materials provided */
 
27
/*   with the distribution.                                          */
 
28
/* - Neither the name of the HTS working group nor the names of its  */
 
29
/*   contributors may be used to endorse or promote products derived */
 
30
/*   from this software without specific prior written permission.   */
 
31
/*                                                                   */
 
32
/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND            */
 
33
/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,       */
 
34
/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF          */
 
35
/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE          */
 
36
/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS */
 
37
/* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,          */
 
38
/* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED   */
 
39
/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     */
 
40
/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */
 
41
/* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,   */
 
42
/* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY    */
 
43
/* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE           */
 
44
/* POSSIBILITY OF SUCH DAMAGE.                                       */
 
45
/* ----------------------------------------------------------------- */
 
46
 
 
47
#include <iostream>
 
48
#include <fstream>
 
49
#include <cstring>
 
50
#include <string>
 
51
#include "common.h"
 
52
#include "utils.h"
 
53
#include "scoped_ptr.h"
 
54
 
 
55
#ifdef HAVE_CONFIG_H
 
56
#include "config.h"
 
57
#endif
 
58
 
 
59
#include "iconv_utils.h"
 
60
#include "char_property.h"
 
61
 
 
62
#ifdef HAVE_WINDOWS_H /* for Open JTalk */
 
63
#include "windows.h"
 
64
#endif
 
65
 
 
66
namespace {
 
67
 
 
68
#ifdef HAVE_ICONV
 
69
const char * decode_charset_iconv(const char *str) {
 
70
  const int charset = MeCab::decode_charset(str);
 
71
  switch (charset) {
 
72
    case MeCab::UTF8:
 
73
      return "UTF-8";
 
74
    case MeCab::EUC_JP:
 
75
      return "EUC-JP";
 
76
    case  MeCab::CP932:
 
77
      return "SHIFT-JIS";
 
78
    case  MeCab::UTF16:
 
79
      return "UTF-16";
 
80
    case  MeCab::UTF16LE:
 
81
      return "UTF-16LE";
 
82
    case  MeCab::UTF16BE:
 
83
      return "UTF-16BE";
 
84
    default:
 
85
      std::cerr << "charset " << str
 
86
                << " is not defined, use " MECAB_DEFAULT_CHARSET;
 
87
      return MECAB_DEFAULT_CHARSET;
 
88
  }
 
89
  return MECAB_DEFAULT_CHARSET;
 
90
}
 
91
#endif
 
92
 
 
93
#ifdef HAVE_WINDOWS_H /* for Open JTalk */
 
94
DWORD decode_charset_win32(const char *str) {
 
95
  const int charset = MeCab::decode_charset(str);
 
96
  switch (charset) {
 
97
    case MeCab::UTF8:
 
98
      return CP_UTF8;
 
99
    case MeCab::UTF16:
 
100
      return 1200;
 
101
    case MeCab::UTF16LE:
 
102
      return 1200;
 
103
    case MeCab::UTF16BE:
 
104
      return 1201;
 
105
    case MeCab::EUC_JP:
 
106
      //      return 51932;
 
107
      return 20932;
 
108
    case MeCab::CP932:
 
109
      return 932;
 
110
    default:
 
111
      std::cerr << "charset " << str
 
112
                << " is not defined, use 'CP_THREAD_ACP'";
 
113
      return CP_THREAD_ACP;
 
114
  }
 
115
  return 0;
 
116
}
 
117
#endif
 
118
}  // namespace
 
119
 
 
120
namespace MeCab {
 
121
bool Iconv::open(const char* from, const char* to) {
 
122
  ic_ = 0;
 
123
#if defined HAVE_ICONV
 
124
  const char *from2 = decode_charset_iconv(from);
 
125
  const char *to2 = decode_charset_iconv(to);
 
126
  if (std::strcmp(from2, to2) == 0) {
 
127
    return true;
 
128
  }
 
129
  ic_ = 0;
 
130
  ic_ = iconv_open(to2, from2);
 
131
  if (ic_ == (iconv_t)(-1)) {
 
132
    ic_ = 0;
 
133
    return false;
 
134
  }
 
135
#else
 
136
#ifdef HAVE_WINDOWS_H /* for Open JTalk */
 
137
  from_cp_ = decode_charset_win32(from);
 
138
  to_cp_ = decode_charset_win32(to);
 
139
  if (from_cp_ == to_cp_) {
 
140
    return true;
 
141
  }
 
142
  ic_ = from_cp_;
 
143
#else
 
144
  std::cerr << "iconv_open is not supported" << std::endl;
 
145
#endif
 
146
#endif
 
147
 
 
148
  return true;
 
149
}
 
150
 
 
151
bool Iconv::convert(std::string *str) {
 
152
  if (str->empty()) {
 
153
    return true;
 
154
  }
 
155
  if (ic_ == 0) {
 
156
    return true;
 
157
  }
 
158
 
 
159
#if defined HAVE_ICONV /* for Open JTalk */
 
160
  size_t ilen = 0;
 
161
  size_t olen = 0;
 
162
  ilen = str->size();
 
163
  olen = ilen * 4;
 
164
  std::string tmp;
 
165
  tmp.reserve(olen);
 
166
  char *ibuf = const_cast<char *>(str->data());
 
167
  char *obuf_org = const_cast<char *>(tmp.data());
 
168
  char *obuf = obuf_org;
 
169
  std::fill(obuf, obuf + olen, 0);
 
170
  size_t olen_org = olen;
 
171
  iconv(ic_, 0, &ilen, 0, &olen);  // reset iconv state
 
172
  while (ilen != 0) {
 
173
    if (iconv(ic_, (ICONV_CONST char **)&ibuf, &ilen, &obuf, &olen)
 
174
        == (size_t) -1) {
 
175
      return false;
 
176
    }
 
177
  }
 
178
  str->assign(obuf_org, olen_org - olen);
 
179
#else
 
180
#ifdef HAVE_WINDOWS_H /* for Open JTalk */
 
181
  // covert it to wide character first
 
182
  const size_t wide_len = ::MultiByteToWideChar(from_cp_, 0,
 
183
                                                str->c_str(),
 
184
                                                -1, NULL, 0);
 
185
  if (wide_len == 0) {
 
186
    return false;
 
187
  }
 
188
 
 
189
  scoped_array<wchar_t> wide_str(new wchar_t[wide_len + 1]);
 
190
 
 
191
  if (!wide_str.get()) {
 
192
    return false;
 
193
  };
 
194
 
 
195
  if (::MultiByteToWideChar(from_cp_, 0, str->c_str(), -1,
 
196
                            wide_str.get(), wide_len + 1) == 0) {
 
197
    return false;
 
198
  }
 
199
 
 
200
  if (to_cp_ == 1200 || to_cp_ == 1201) {
 
201
    str->resize(2 * wide_len);
 
202
    memcpy(const_cast<char *>(str->data()),
 
203
           reinterpret_cast<char *>(wide_str.get()), wide_len * 2);
 
204
    if (to_cp_ == 1201) {
 
205
      char *buf = const_cast<char *>(str->data());
 
206
      for (size_t i = 0; i < 2 * wide_len; i += 2) {
 
207
        std::swap(buf[i], buf[i+1]);
 
208
      }
 
209
    }
 
210
    return true;
 
211
  }
 
212
 
 
213
  const size_t output_len = ::WideCharToMultiByte(to_cp_, 0,
 
214
                                                  wide_str.get(),
 
215
                                                  -1,
 
216
                                                  NULL, 0, NULL, NULL);
 
217
 
 
218
  if (output_len == 0) {
 
219
    return false;
 
220
  }
 
221
 
 
222
  scoped_array<char> encoded(new char[output_len + 1]);
 
223
  if (::WideCharToMultiByte(to_cp_, 0, wide_str.get(), wide_len,
 
224
                            encoded.get(), output_len + 1,
 
225
                            NULL, NULL) == 0) {
 
226
    return false;
 
227
  }
 
228
 
 
229
  str->assign(encoded.get());
 
230
 
 
231
#endif
 
232
#endif
 
233
 
 
234
  return true;
 
235
}
 
236
 
 
237
Iconv::Iconv() : ic_(0)  {}
 
238
 
 
239
Iconv::~Iconv() {
 
240
#if defined HAVE_ICONV
 
241
  if (ic_ != 0) iconv_close(ic_);
 
242
#endif
 
243
}
 
244
}