unsigned int Transcoder::decode()

in src/main/cpp/transcoder.cpp [207:303]


unsigned int Transcoder::decode(const std::string& src,
	std::string::const_iterator& iter)
{
	std::string::const_iterator start(iter);
	unsigned char ch1 = *(iter++);

	if (ch1 <= 0x7F)
	{
		return ch1;
	}

	//
	//   should not have continuation character here
	//
	if ((ch1 & 0xC0) != 0x80 && iter != src.end())
	{
		unsigned char ch2 = *(iter++);

		//
		//   should be continuation
		if ((ch2 & 0xC0) != 0x80)
		{
			iter = start;
			return 0xFFFF;
		}

		if ((ch1 & 0xE0) == 0xC0)
		{
			if ((ch2 & 0xC0) == 0x80)
			{
				unsigned int rv = ((ch1 & 0x1F) << 6) + (ch2 & 0x3F);

				if (rv >= 0x80)
				{
					return rv;
				}
			}

			iter = start;
			return 0xFFFF;
		}

		if (iter != src.end())
		{
			unsigned char ch3 = *(iter++);

			//
			//   should be continuation
			//
			if ((ch3 & 0xC0) != 0x80)
			{
				iter = start;
				return 0xFFFF;
			}

			if ((ch1 & 0xF0) == 0xE0)
			{
				unsigned rv = ((ch1 & 0x0F) << 12)
					+ ((ch2 & 0x3F) << 6)
					+ (ch3 & 0x3F);

				if (rv <= 0x800)
				{
					iter = start;
					return 0xFFFF;
				}

				return rv;
			}

			if (iter != src.end())
			{
				unsigned char ch4 = *(iter++);

				if ((ch4 & 0xC0) != 0x80)
				{
					iter = start;
					return 0xFFFF;
				}

				unsigned int rv = ((ch1 & 0x07) << 18)
					+ ((ch2 & 0x3F) << 12)
					+ ((ch3 & 0x3F) << 6)
					+ (ch4 & 0x3F);

				if (rv > 0xFFFF)
				{
					return rv;
				}

			}
		}
	}

	iter = start;
	return 0xFFFF;
}