2 ** Copyright 2011 Double Precision, Inc.
3 ** See COPYING for distribution information.
7 #include "unicode_config.h"
12 static int iconv_trampoline(const char *str, size_t cnt, void *arg)
14 return reinterpret_cast<mail::iconvert *>(arg)
15 ->converted(str, cnt);
18 int mail::linebreak_trampoline(int value, void *ptr)
20 return (*reinterpret_cast<mail::linebreak_callback_base *>
24 int mail::linebreakc_trampoline(int value, unicode_char ch, void *ptr)
26 return (*reinterpret_cast<mail::linebreakc_callback_base *>
30 int mail::wordbreak_trampoline(int value, void *ptr)
32 return (*reinterpret_cast<mail::wordbreak_callback_base *>
38 size_t unicode_wcwidth(const std::vector<unicode_char> &uc)
42 for (std::vector<unicode_char>::const_iterator
43 b(uc.begin()), e(uc.end()); b != e; ++b)
44 w += unicode_wcwidth(*b);
48 mail::iconvert::iconvert() : handle(NULL)
52 mail::iconvert::~iconvert()
57 int mail::iconvert::converted(const char *, size_t)
62 bool mail::iconvert::begin(const std::string &src_chset,
63 const std::string &dst_chset)
67 if ((handle=libmail_u_convert_init(src_chset.c_str(),
75 bool mail::iconvert::end(bool *errflag)
84 rc=libmail_u_convert_deinit(handle, &errptr);
92 bool mail::iconvert::operator()(const char *str, size_t cnt)
97 return (libmail_u_convert(handle, str, cnt) == 0);
100 bool mail::iconvert::operator()(const unicode_char *str, size_t cnt)
105 return (libmail_u_convert_uc(handle, str, cnt) == 0);
108 std::string mail::iconvert::convert(const std::string &text,
109 const std::string &charset,
110 const std::string &dstcharset,
116 char *p=libmail_u_convert_tobuf(text.c_str(),
121 errflag= errptr != 0;
135 std::string mail::iconvert::convert(const std::vector<unicode_char> &uc,
136 const std::string &dstcharset,
145 if (libmail_u_convert_fromu_tobuf(&uc[0], uc.size(),
146 dstcharset.c_str(), &c, &csize,
154 --csize; // Trailing NULL
156 buf.append(c, c+csize);
170 bool mail::iconvert::convert(const std::string &text,
171 const std::string &charset,
172 std::vector<unicode_char> &uc)
179 if (libmail_u_convert_tou_tobuf(text.c_str(),
190 uc.insert(uc.end(), ucbuf, ucbuf+ucsize);
201 int mail::iconvert::tou::converted(const unicode_char *, size_t)
206 bool mail::iconvert::tou::begin(const std::string &chset)
208 return iconvert::begin(chset, libmail_u_ucs4_native);
211 int mail::iconvert::tou::converted(const char *ptr, size_t cnt)
213 return converted(reinterpret_cast<const unicode_char *>(ptr),
214 cnt/sizeof(unicode_char));
217 void mail::iconvert::tou::convert(const std::string &str,
218 const std::string &chset,
219 std::vector<unicode_char> &out_buf)
221 convert(str.begin(), str.end(), chset, out_buf);
224 bool mail::iconvert::fromu::begin(const std::string &chset)
226 return iconvert::begin(libmail_u_ucs4_native, chset);
229 std::string mail::iconvert::fromu::convert(const std::vector<unicode_char>
231 const std::string &chset)
235 convert(ubuf, chset, s);
239 void mail::iconvert::fromu::convert(const std::vector<unicode_char> &ubuf,
240 const std::string &chset,
241 std::string &out_buf)
243 convert(ubuf.begin(), ubuf.end(), chset, out_buf);
246 std::string mail::iconvert::convert_tocase(const std::string &text,
247 const std::string &charset,
249 unicode_char (*first_char_func)(unicode_char),
250 unicode_char (*char_func)(unicode_char))
255 char *p=libmail_u_convert_tocase(text.c_str(),
276 mail::linebreak_callback_base::linebreak_callback_base()
277 : handle(NULL), opts(0)
282 void mail::linebreak_callback_base::set_opts(int optsArg)
287 unicode_lb_set_opts(handle, opts);
290 mail::linebreak_callback_base::~linebreak_callback_base()
295 int mail::linebreak_callback_base::operator()(int)
300 mail::linebreak_callback_base
301 &mail::linebreak_callback_base::operator<<(unicode_char uc)
305 handle=unicode_lb_init(linebreak_trampoline,
306 reinterpret_cast<void *>
307 (static_cast<linebreak_callback_base *>
313 if (unicode_lb_next(handle, uc))
318 void mail::linebreak_callback_base::finish()
321 unicode_lb_end(handle);
326 mail::linebreak_callback_save_buf::linebreak_callback_save_buf()
330 mail::linebreak_callback_save_buf::~linebreak_callback_save_buf()
334 int mail::linebreak_callback_save_buf::operator()(int value)
336 lb_buf.push_back(value);
340 mail::linebreakc_callback_base::linebreakc_callback_base()
341 : handle(NULL), opts(0)
345 mail::linebreakc_callback_base::~linebreakc_callback_base()
350 int mail::linebreakc_callback_base::operator()(int, unicode_char)
355 void mail::linebreakc_callback_base::set_opts(int optsArg)
360 unicode_lbc_set_opts(handle, opts);
363 mail::linebreakc_callback_base
364 &mail::linebreakc_callback_base::operator<<(unicode_char uc)
368 handle=unicode_lbc_init(linebreakc_trampoline,
369 reinterpret_cast<void *>
370 (static_cast<linebreakc_callback_base *>
376 if (unicode_lbc_next(handle, uc))
381 void mail::linebreakc_callback_base::finish()
384 unicode_lbc_end(handle);
389 mail::linebreakc_callback_save_buf::linebreakc_callback_save_buf()
393 mail::linebreakc_callback_save_buf::~linebreakc_callback_save_buf()
397 int mail::linebreakc_callback_save_buf::operator()(int c, unicode_char ch)
399 lb_buf.push_back(std::make_pair(c, ch));
403 mail::wordbreak_callback_base::wordbreak_callback_base()
408 mail::wordbreak_callback_base::~wordbreak_callback_base()
413 int mail::wordbreak_callback_base::operator()(bool)
418 mail::wordbreak_callback_base
419 &mail::wordbreak_callback_base::operator<<(unicode_char uc)
423 handle=unicode_wb_init(wordbreak_trampoline,
424 reinterpret_cast<void *>
425 (static_cast<wordbreak_callback_base *>
430 if (unicode_wb_next(handle, uc))
435 void mail::wordbreak_callback_base::finish()
438 unicode_wb_end(handle);
442 /* -------------------------------------------- */
444 mail::wordbreakscan::wordbreakscan() : handle(NULL)
448 mail::wordbreakscan::~wordbreakscan()
453 bool mail::wordbreakscan::operator<<(unicode_char uc)
456 handle=unicode_wbscan_init();
459 return unicode_wbscan_next(handle, uc) != 0;
464 size_t mail::wordbreakscan::finish()
470 n=unicode_wbscan_end(handle);