예제 #1
0
    /**
     *  @brief Deserialize the integer value from the specified input stream.
     *  @param __s  Reference to the input stream.
     */
    void
    load(std::basic_istream<CharT, Traits> &__s)
    {
        // We must ensure that subsequent actions will be performed
        // for very likely integer value, otherwise and exception
        // should be raised.
        if (__s.peek() != basic_value_type::integer_token) {
            throw type_error(
                "bencode::integer::load the specified stream does "
                "not contain interpretable bencode integer value\n");
        }

        // Read the leading "i" symbol from the provided stream.
        __s.get();

        // Define the integer symbol representation placeholder.
        std::basic_stringstream<CharT, Traits> __i;

        // Define the input stream iterator of the provided stream to
        // be able to read the integer value symbol by symbol.
        auto __si = std::istream_iterator<CharT, CharT, Traits>(__s);

        // Define the output stream to as a buffer for the integer
        // value, which will be later converted.
        auto __ival = std::ostream_iterator<CharT, CharT, Traits>(__i);

        // Copy the values from the input stream into the integer
        // placeholder string stream.
        auto __result = copy_until(__si, __ival,
            [&__s](const CharT& __ch) {

            // Additionally, check that we did not exceed the
            // length of the stream to prevent hangs.
            return !__s.eof() && __ch != basic_value_type::end_token;
        }, basic_value_type::integer_length);

        // Covert the value from the string into the integer.
        __i >> _M_value;

        // The "e" symbol should be already extracted at this moment,
        // so validate that the iterator pointing right to it.
        if (*__result != basic_value_type::end_token) {
            std::ostringstream __error;

            __error << "bencode::integer::load the end of the integer "
                "`e` expected, but `" << CharT(*__result) << "` found\n";
            throw encoding_error(__error.str());
        }

        // Validate that decoded value is an actual integer.
        if (!_M_value && __i.str() != std::basic_string<
                CharT, Traits>(1, CharT('0'))) {
            std::ostringstream __error;

            __error << "bencode::integer::load the specified "
                "value is not a number\n";
            throw value_error(__error.str());
        }
    }
예제 #2
0
파일: unicode.hpp 프로젝트: Teile/Helper
 inline char decode_raw_byte(codepoint c)
 {
     if (!is_raw_byte(c))
     {
         throw encoding_error("codepoint is not an encoded raw byte");
     }
     return c & 0xFF;
 }
예제 #3
0
파일: unicode.hpp 프로젝트: Teile/Helper
 inline codepoint encode_raw_byte(char byte)
 {
     codepoint c = codepoint(byte) & 0xFF;
     if (c == 0)
     {
         throw encoding_error("null or zero byte cannot be raw-data encoded");
     }
     return c | 0xF800;
 }
예제 #4
0
파일: unicode.hpp 프로젝트: Teile/Helper
 typename boost::enable_if_c<bit_size<typename std::iterator_traits<T>::value_type>::value >= 21, codepoint>::type next(T& it, T const& end)
 {
     codepoint c = codepoint(*it);
     if (!is_valid(c))
     {
         throw encoding_error("invalid codepoint");
     }
     ++it;
     return c;
 }
예제 #5
0
bool Gobby::OperationOpen::on_idle()
{
	static const unsigned int CONVERT_BUFFER_SIZE = 1024;

	const char* inbuffer = &m_raw_content[m_raw_pos];
	char* inbuf = const_cast<char*>(inbuffer);
	gsize inbytes = m_raw_content.size() - m_raw_pos;
	char outbuffer[CONVERT_BUFFER_SIZE];
	gchar* outbuf = outbuffer;
	gsize outbytes = CONVERT_BUFFER_SIZE;

	/* iconv is defined as libiconv on Windows, or at least when using the
	 * binary packages from ftp.gnome.org. Therefore we can't propely
	 * call Glib::IConv::iconv. Therefore, we use the C API here. */
	const std::size_t result = g_iconv(m_iconv->gobj(),
		&inbuf, &inbytes, &outbuf, &outbytes);
	bool more_to_process = (inbytes != 0);

	if(result == static_cast<std::size_t>(-1))
	{
		if(errno == EILSEQ)
		{
			// Invalid text for the current encoding
			encoding_error();
			return false;
		}

		if(errno == EINVAL)
		{
			// If EINVAL is set, this means that an incomplete
			// multibyte sequence was at the end of the input.
			// We might have some more bytes, but those do not
			// make up a whole character, so we need to wait for
			// more input.
			if(!m_stream)
			{
				// However, if we already read all input, then
				// there is no more input to come. We
				// consider this an error since the file
				// should not end with an incomplete multibyte
				// sequence.
				encoding_error();
				return false;
			}
			else
			{
				// Otherwise, we need to wait for more data
				// to process.
				more_to_process = false;
			}
		}
	}

	m_raw_pos += (inbuf - inbuffer);

	// We now have outbuf - outbuffer bytes of valid UTF-8 in outbuffer.
	char* prev = outbuffer;
	char* pos;
	const char to_find[] = { '\r', '\n', '\0' };

	/* TODO: Write directly into the buffer here,
	 * instead of memmoving stuff. */
	while( (pos = std::find_first_of<char*>(prev, outbuf,
		to_find, to_find + sizeof(to_find))) != outbuf)
	{
		if(*pos == '\0')
		{
			// There is a nullbyte in the conversion. As normal
			// text files don't contain nullbytes, this only
			// occurs when converting for example a UTF-16 from
			// ISO-8859-1 to UTF-8 (note that the UTF-16 file is
			// valid ISO-8859-1, it just contains lots of
			// nullbytes). We therefore produce an error here.
			encoding_error();
			return false;
		}
		else
		{
			// We convert everything to '\n' as line separator,
			// but remember the current eol-style to correctly
			// save the document back to disk.
			prev = pos + 1;
			if(*pos == '\r' && prev != outbuf && *prev == '\n')
			{
				// CRLF style line break
				std::memmove(prev, prev + 1,
				             outbuf - prev - 1);
				m_eol_style = DocumentInfoStorage::EOL_CRLF;
				--outbuf;
			}
			else if(*pos == '\r')
			{
				*pos = '\n';
				m_eol_style = DocumentInfoStorage::EOL_CR;
			}
			else
			{
				m_eol_style = DocumentInfoStorage::EOL_LF;
			}
		}
	}

	GtkTextIter insert_iter;
	gtk_text_buffer_get_end_iter(m_content, &insert_iter);
	gtk_text_buffer_insert(m_content, &insert_iter, outbuffer,
	                       outbuf - outbuffer);

	// Done reading and converting the whole file
	if(!more_to_process && !m_stream)
		read_finish();

	return more_to_process;
}
예제 #6
0
    /**
     *  @brief Deserialize the string value from the specified input stream.
     *  @param __s  Reference to the input stream.
     */
    void
    load(std::basic_istream<CharT, Traits>& __s)
    {
        // Define the integer symbol representation placeholder.
        std::basic_stringstream<CharT, Traits> __i;

        // Define the input stream iterator of the provided stream to
        // be able to read the string length value symbol by symbol.
        auto __si = std::istream_iterator<CharT, CharT, Traits>(__s);

        // Define the output stream to as a buffer for the integer
        // value, which will be later converted.
        auto __ival = std::ostream_iterator<CharT, CharT, Traits>(__i);

        // Copy the symbols from the input stream to the integer
        // placeholder until the ":" delimiter value.
        auto __result = copy_until(__si, __ival,
            [&__s](const CharT& __ch) {

            // Additionally, check that we did not exceed the
            // length of the stream to prevent hangs.
            return !__s.eof() && __ch != basic_value_type::delimiter_token;
        }, basic_value_type::integer_length);

        if (*__result != basic_value_type::delimiter_token) {
            std::ostringstream __error;

            __error << "bencode::string::load the delimiter `:` "
                "expected, but `" << CharT(*__result) << "` found\n";
            throw encoding_error(__error.str());
        }

        // Save the length of the string.
        int64_t __count;
        __i >> __count;

        if (!__count && __i.str() != std::basic_string<
                CharT, Traits>(1, CharT('0'))) {
            std::ostringstream __error;

            __error << "bencode::string::load the specified string "
                "length is not a number\n";
            throw value_error(__error.str());
        }

        // Ensure that the string length is a non-negative value.
        if (__count < 0) {
            std::ostringstream __error;

            __error << "bencode::string::load the length of the string "
                "value must be a positive integer: `" << __count << "`\n";
            throw value_error(__error.str());
        }

        // Allocate the list of symbols of the specified string length.
        std::unique_ptr<CharT[]> __str(new CharT[__count+1]);

        // Read the string value into the symbol list.
        __s.get(__str.get(), std::streamsize(__count+1));
        auto __strval = string_type(__str.get());

        // Ensure that valid count of the symbols was extracted from
        // the provided input stream.
        if (int64_t(__strval.length()) != __count) {
            std::ostringstream __error;

            __error << "bencode::string::load the specified string "
                "decoded length is not equal to the real one: `" << __count
                << "` != `" << __strval.length() << "`\n";
            throw value_error(__error.str());
        }

        // Initialize the internal value with a new string.
        _M_value = __strval;
    }