123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- #include "iconv.h"
- #include <iconv.h>
- using namespace NICONVPrivate;
- TDescriptor::TDescriptor(const char* from, const char* to)
- : Descriptor_(iconv_open(to, from))
- , From_(from)
- , To_(to)
- {
- #if defined(USE_ICONV_EXTENSIONS)
- if (!Invalid()) {
- int temp = 1;
- libiconvctl(Descriptor_, ICONV_SET_DISCARD_ILSEQ, &temp);
- }
- #endif
- }
- TDescriptor::~TDescriptor() {
- if (!Invalid()) {
- iconv_close(static_cast<iconv_t>(Descriptor_));
- }
- }
- size_t NICONVPrivate::RecodeImpl(const TDescriptor& descriptor, const char* in, char* out, size_t inSize, size_t outSize, size_t& read, size_t& written) {
- Y_ASSERT(!descriptor.Invalid());
- Y_ASSERT(in);
- Y_ASSERT(out);
- char* inPtr = const_cast<char*>(in);
- char* outPtr = out;
- size_t inSizeMod = inSize;
- size_t outSizeMod = outSize;
- size_t res = iconv(static_cast<iconv_t>(descriptor.Get()), &inPtr, &inSizeMod, &outPtr, &outSizeMod);
- read = inSize - inSizeMod;
- written = outSize - outSizeMod;
- return res;
- }
- void NICONVPrivate::DoRecode(const TDescriptor& descriptor, const char* in, char* out, size_t inSize, size_t outSize, size_t& read, size_t& written) {
- if (descriptor.Invalid()) {
- ythrow yexception() << "Can not convert from " << descriptor.From() << " to " << descriptor.To();
- }
- size_t res = RecodeImpl(descriptor, in, out, inSize, outSize, read, written);
- if (res == static_cast<size_t>(-1)) {
- switch (errno) {
- case EILSEQ:
- read = inSize;
- break;
- case EINVAL:
- read = inSize;
- break;
- case E2BIG:
- ythrow yexception() << "Iconv error: output buffer is too small";
- default:
- ythrow yexception() << "Unknown iconv error";
- }
- }
- }
- RECODE_RESULT NICONVPrivate::DoRecodeNoThrow(const TDescriptor& descriptor, const char* in, char* out, size_t inSize, size_t outSize, size_t& read, size_t& written) {
- if (descriptor.Invalid()) {
- return RECODE_ERROR;
- }
- size_t res = RecodeImpl(descriptor, in, out, inSize, outSize, read, written);
- if (res == static_cast<size_t>(-1)) {
- switch (errno) {
- case EILSEQ:
- read = inSize;
- break;
- case EINVAL:
- read = inSize;
- break;
- case E2BIG:
- return RECODE_EOOUTPUT;
- default:
- return RECODE_ERROR;
- }
- }
- return RECODE_OK;
- }
|