+++ /dev/null
-/*
-** Copyright 2011 Double Precision, Inc.
-** See COPYING for distribution information.
-**
-*/
-
-#include "unicode_config.h"
-#include "unicode.h"
-
-extern "C" {
-
- static int iconv_trampoline(const char *str, size_t cnt, void *arg)
- {
- return reinterpret_cast<mail::iconvert *>(arg)
- ->converted(str, cnt);
- }
-
- int mail::linebreak_trampoline(int value, void *ptr)
- {
- return (*reinterpret_cast<mail::linebreak_callback_base *>
- (ptr))(value);
- }
-
- int mail::linebreakc_trampoline(int value, unicode_char ch, void *ptr)
- {
- return (*reinterpret_cast<mail::linebreakc_callback_base *>
- (ptr))(value, ch);
- }
-
- int mail::wordbreak_trampoline(int value, void *ptr)
- {
- return (*reinterpret_cast<mail::wordbreak_callback_base *>
- (ptr))(value != 0);
- }
-
-}
-
-size_t unicode_wcwidth(const std::vector<unicode_char> &uc)
-{
- size_t w=0;
-
- for (std::vector<unicode_char>::const_iterator
- b(uc.begin()), e(uc.end()); b != e; ++b)
- w += unicode_wcwidth(*b);
- return w;
-}
-
-mail::iconvert::iconvert() : handle(NULL)
-{
-}
-
-mail::iconvert::~iconvert()
-{
- end();
-}
-
-int mail::iconvert::converted(const char *, size_t)
-{
- return 0;
-}
-
-bool mail::iconvert::begin(const std::string &src_chset,
- const std::string &dst_chset)
-{
- end();
-
- if ((handle=libmail_u_convert_init(src_chset.c_str(),
- dst_chset.c_str(),
- &iconv_trampoline,
- this)) == NULL)
- return false;
- return true;
-}
-
-bool mail::iconvert::end(bool *errflag)
-{
- int errptr;
-
- int rc;
-
- if (!handle)
- return true;
-
- rc=libmail_u_convert_deinit(handle, &errptr);
- handle=NULL;
-
- if (errflag)
- *errflag=errptr != 0;
- return rc == 0;
-}
-
-bool mail::iconvert::operator()(const char *str, size_t cnt)
-{
- if (!handle)
- return false;
-
- return (libmail_u_convert(handle, str, cnt) == 0);
-}
-
-bool mail::iconvert::operator()(const unicode_char *str, size_t cnt)
-{
- if (!handle)
- return false;
-
- return (libmail_u_convert_uc(handle, str, cnt) == 0);
-}
-
-std::string mail::iconvert::convert(const std::string &text,
- const std::string &charset,
- const std::string &dstcharset,
- bool &errflag)
-{
- std::string buf;
- int errptr;
-
- char *p=libmail_u_convert_tobuf(text.c_str(),
- charset.c_str(),
- dstcharset.c_str(),
- &errptr);
-
- errflag= errptr != 0;
-
- try {
- buf=p;
- free(p);
- } catch (...) {
- free(p);
- throw;
- }
-
- return buf;
-}
-
-
-std::string mail::iconvert::convert(const std::vector<unicode_char> &uc,
- const std::string &dstcharset,
- bool &errflag)
-{
- std::string buf;
-
- char *c;
- size_t csize;
- int err;
-
- if (libmail_u_convert_fromu_tobuf(&uc[0], uc.size(),
- dstcharset.c_str(), &c, &csize,
- &err))
- {
- err=1;
- }
- else
- {
- if (csize)
- --csize; // Trailing NULL
- try {
- buf.append(c, c+csize);
- free(c);
- } catch (...)
- {
- free(c);
- throw;
- }
- }
-
- errflag= err != 0;
-
- return buf;
-}
-
-bool mail::iconvert::convert(const std::string &text,
- const std::string &charset,
- std::vector<unicode_char> &uc)
-{
- int err;
-
- unicode_char *ucbuf;
- size_t ucsize;
-
- if (libmail_u_convert_tou_tobuf(text.c_str(),
- text.size(),
- charset.c_str(),
- &ucbuf,
- &ucsize,
- &err))
- return false;
-
- try {
- uc.clear();
- uc.reserve(ucsize);
- uc.insert(uc.end(), ucbuf, ucbuf+ucsize);
- free(ucbuf);
- } catch (...)
- {
- free(ucbuf);
- throw;
- }
-
- return err == 0;
-}
-
-int mail::iconvert::tou::converted(const unicode_char *, size_t)
-{
- return 0;
-}
-
-bool mail::iconvert::tou::begin(const std::string &chset)
-{
- return iconvert::begin(chset, libmail_u_ucs4_native);
-}
-
-int mail::iconvert::tou::converted(const char *ptr, size_t cnt)
-{
- return converted(reinterpret_cast<const unicode_char *>(ptr),
- cnt/sizeof(unicode_char));
-}
-
-void mail::iconvert::tou::convert(const std::string &str,
- const std::string &chset,
- std::vector<unicode_char> &out_buf)
-{
- convert(str.begin(), str.end(), chset, out_buf);
-}
-
-bool mail::iconvert::fromu::begin(const std::string &chset)
-{
- return iconvert::begin(libmail_u_ucs4_native, chset);
-}
-
-std::string mail::iconvert::fromu::convert(const std::vector<unicode_char>
- &ubuf,
- const std::string &chset)
-{
- std::string s;
-
- convert(ubuf, chset, s);
- return s;
-}
-
-void mail::iconvert::fromu::convert(const std::vector<unicode_char> &ubuf,
- const std::string &chset,
- std::string &out_buf)
-{
- convert(ubuf.begin(), ubuf.end(), chset, out_buf);
-}
-
-std::string mail::iconvert::convert_tocase(const std::string &text,
- const std::string &charset,
- bool &err,
- unicode_char (*first_char_func)(unicode_char),
- unicode_char (*char_func)(unicode_char))
-{
- err=false;
- std::string s;
-
- char *p=libmail_u_convert_tocase(text.c_str(),
- charset.c_str(),
- first_char_func,
- char_func);
-
- if (!p)
- {
- err=true;
- return s;
- }
-
- try {
- s=p;
- free(p);
- } catch (...) {
- free(p);
- throw;
- }
- return s;
-}
-
-mail::linebreak_callback_base::linebreak_callback_base()
- : handle(NULL), opts(0)
-{
-}
-
-
-void mail::linebreak_callback_base::set_opts(int optsArg)
-{
- opts=optsArg;
-
- if (handle)
- unicode_lb_set_opts(handle, opts);
-}
-
-mail::linebreak_callback_base::~linebreak_callback_base()
-{
- finish();
-}
-
-int mail::linebreak_callback_base::operator()(int)
-{
- return 0;
-}
-
-mail::linebreak_callback_base
-&mail::linebreak_callback_base::operator<<(unicode_char uc)
-{
- if (!handle)
- {
- handle=unicode_lb_init(linebreak_trampoline,
- reinterpret_cast<void *>
- (static_cast<linebreak_callback_base *>
- (this)));
- set_opts(opts);
- }
-
- if (handle)
- if (unicode_lb_next(handle, uc))
- finish();
- return *this;
-}
-
-void mail::linebreak_callback_base::finish()
-{
- if (handle)
- unicode_lb_end(handle);
- handle=NULL;
-}
-
-
-mail::linebreak_callback_save_buf::linebreak_callback_save_buf()
-{
-}
-
-mail::linebreak_callback_save_buf::~linebreak_callback_save_buf()
-{
-}
-
-int mail::linebreak_callback_save_buf::operator()(int value)
-{
- lb_buf.push_back(value);
- return 0;
-}
-
-mail::linebreakc_callback_base::linebreakc_callback_base()
- : handle(NULL), opts(0)
-{
-}
-
-mail::linebreakc_callback_base::~linebreakc_callback_base()
-{
- finish();
-}
-
-int mail::linebreakc_callback_base::operator()(int, unicode_char)
-{
- return 0;
-}
-
-void mail::linebreakc_callback_base::set_opts(int optsArg)
-{
- opts=optsArg;
-
- if (handle)
- unicode_lbc_set_opts(handle, opts);
-}
-
-mail::linebreakc_callback_base
-&mail::linebreakc_callback_base::operator<<(unicode_char uc)
-{
- if (handle == NULL)
- {
- handle=unicode_lbc_init(linebreakc_trampoline,
- reinterpret_cast<void *>
- (static_cast<linebreakc_callback_base *>
- (this)));
- set_opts(opts);
- }
-
- if (handle)
- if (unicode_lbc_next(handle, uc))
- finish();
- return *this;
-}
-
-void mail::linebreakc_callback_base::finish()
-{
- if (handle)
- unicode_lbc_end(handle);
- handle=NULL;
-}
-
-
-mail::linebreakc_callback_save_buf::linebreakc_callback_save_buf()
-{
-}
-
-mail::linebreakc_callback_save_buf::~linebreakc_callback_save_buf()
-{
-}
-
-int mail::linebreakc_callback_save_buf::operator()(int c, unicode_char ch)
-{
- lb_buf.push_back(std::make_pair(c, ch));
- return 0;
-}
-
-mail::wordbreak_callback_base::wordbreak_callback_base()
- : handle(NULL)
-{
-}
-
-mail::wordbreak_callback_base::~wordbreak_callback_base()
-{
- finish();
-}
-
-int mail::wordbreak_callback_base::operator()(bool)
-{
- return 0;
-}
-
-mail::wordbreak_callback_base
-&mail::wordbreak_callback_base::operator<<(unicode_char uc)
-{
- if (!handle)
- {
- handle=unicode_wb_init(wordbreak_trampoline,
- reinterpret_cast<void *>
- (static_cast<wordbreak_callback_base *>
- (this)));
- }
-
- if (handle)
- if (unicode_wb_next(handle, uc))
- finish();
- return *this;
-}
-
-void mail::wordbreak_callback_base::finish()
-{
- if (handle)
- unicode_wb_end(handle);
- handle=NULL;
-}
-
-/* -------------------------------------------- */
-
-mail::wordbreakscan::wordbreakscan() : handle(NULL)
-{
-}
-
-mail::wordbreakscan::~wordbreakscan()
-{
- finish();
-}
-
-bool mail::wordbreakscan::operator<<(unicode_char uc)
-{
- if (!handle)
- handle=unicode_wbscan_init();
-
- if (handle)
- return unicode_wbscan_next(handle, uc) != 0;
-
- return false;
-}
-
-size_t mail::wordbreakscan::finish()
-{
- size_t n=0;
-
- if (handle)
- {
- n=unicode_wbscan_end(handle);
- handle=NULL;
- }
- return n;
-}