File: CharsetConverter.cc

package info (click to toggle)
htmlcxx 0.87-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,412 kB
  • sloc: sh: 4,380; cpp: 4,355; yacc: 526; ansic: 205; lex: 159; makefile: 47; perl: 27
file content (54 lines) | stat: -rw-r--r-- 1,350 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <iconv.h>
#include <cstdio>
#include <cstring>
#include <cerrno>
#include "CharsetConverter.h"

using namespace std;
using namespace htmlcxx;

CharsetConverter::CharsetConverter(const string &from, const string &to)
{
	mIconvDescriptor = iconv_open(to.c_str(), from.c_str());
	if (mIconvDescriptor == (iconv_t)(-1))
	{
		const char *error_str = strerror(errno);
		int size = strlen(error_str) + from.length() + to.length() + 26;
		char error[size];
		snprintf(error, size, "Can't convert from %s to %s: %s", from.c_str(), to.c_str(), error_str);
		throw Exception(error);
	}
}

CharsetConverter::~CharsetConverter()
{
	iconv_close(mIconvDescriptor);
}

string CharsetConverter::convert(const string &input)
{
	const char *inbuf = input.c_str();
	size_t inbytesleft = input.length();

	size_t outbuf_len = 2 * input.length();
	char *outbuf_start = new char[outbuf_len];
	char *outbuf = outbuf_start;
	size_t outbytesleft = outbuf_len;

	size_t ret;
	while (1) {
		ret = iconv(mIconvDescriptor, const_cast<char**>(&inbuf), &inbytesleft, &outbuf, &outbytesleft);
		if (ret == 0) break;
		if (ret == (size_t)-1 && errno == E2BIG) return string();

		//				fprintf(stderr, "invalid byte: %d\n", inbuf - input.c_str());

		inbuf++; inbytesleft--;
	}

	string out(outbuf_start, outbuf_len - outbytesleft);

	delete [] outbuf_start;

	return out;
}