Esempio n. 1
0
void Gobby::OperationOpen::on_stream_read(
	const Glib::RefPtr<Gio::AsyncResult>& result)
{
	try
	{
		gssize size = m_stream->read_finish(result);

		// Close stream after reading, this signals the idle handler
		// that all data has been read from the file.
		if(size <= 0)
		{
			m_stream->close();
			m_stream.reset();
			m_buffer.reset(NULL);

			// If the idle handler is not connected, then we have
			// already processed all the data.
			if(!m_idle_connection.connected())
				read_finish();
		}
		else
		{
			m_raw_content.insert(m_raw_content.end(),
			                     m_buffer->buf,
			                     m_buffer->buf + size);

			// Process read data in an idle handler
			if(!m_idle_connection.connected())
			{
				m_idle_connection =
					Glib::signal_idle().connect(
						sigc::mem_fun(*this,
							&OperationOpen::
								on_idle));
			}

			m_stream->read_async(
				m_buffer->buf, buffer::SIZE,
			        sigc::mem_fun(
					*this,
					&OperationOpen::on_stream_read));
		}
	}
	catch(const Glib::Exception& ex)
	{
		error(ex.what());
	}
}
Esempio n. 2
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;
}
Esempio n. 3
0
void USBTester::epbulk_out_callback()
{
    read_finish(bulk_out);
    read_start(bulk_out, bulk_buf, sizeof(bulk_buf));
}
Esempio n. 4
0
void USBTester::epint_out_callback()
{
    read_finish(int_out);
    read_start(int_out, int_buf, sizeof(int_buf));
}
Esempio n. 5
0
const wchar_t *
el_wgets(EditLine *el, int *nread)
{
	int retval;
	el_action_t cmdnum = 0;
	int num;		/* how many chars we have read at NL */
	wchar_t ch;
	int nrb;

	if (nread == NULL)
		nread = &nrb;
	*nread = 0;
	el->el_read->read_errno = 0;

	if (el->el_flags & NO_TTY) {
		el->el_line.lastchar = el->el_line.buffer;
		return noedit_wgets(el, nread);
	}

#ifdef FIONREAD
	if (el->el_tty.t_mode == EX_IO && el->el_read->macros.level < 0) {
		int chrs = 0;

		(void) ioctl(el->el_infd, FIONREAD, &chrs);
		if (chrs == 0) {
			if (tty_rawmode(el) < 0) {
				errno = 0;
				*nread = 0;
				return NULL;
			}
		}
	}
#endif /* FIONREAD */

	if ((el->el_flags & UNBUFFERED) == 0)
		read_prepare(el);

	if (el->el_flags & EDIT_DISABLED) {
		if ((el->el_flags & UNBUFFERED) == 0)
			el->el_line.lastchar = el->el_line.buffer;
		terminal__flush(el);
		return noedit_wgets(el, nread);
	}

	for (num = -1; num == -1;) {  /* while still editing this line */
		/* if EOF or error */
		if (read_getcmd(el, &cmdnum, &ch) == -1)
			break;
		if ((size_t)cmdnum >= el->el_map.nfunc) /* BUG CHECK command */
			continue;	/* try again */
		/* now do the real command */
		/* vi redo needs these way down the levels... */
		el->el_state.thiscmd = cmdnum;
		el->el_state.thisch = ch;
		if (el->el_map.type == MAP_VI &&
		    el->el_map.current == el->el_map.key &&
		    el->el_chared.c_redo.pos < el->el_chared.c_redo.lim) {
			if (cmdnum == VI_DELETE_PREV_CHAR &&
			    el->el_chared.c_redo.pos != el->el_chared.c_redo.buf
			    && iswprint(el->el_chared.c_redo.pos[-1]))
				el->el_chared.c_redo.pos--;
			else
				*el->el_chared.c_redo.pos++ = ch;
		}
		retval = (*el->el_map.func[cmdnum]) (el, ch);

		/* save the last command here */
		el->el_state.lastcmd = cmdnum;

		/* use any return value */
		switch (retval) {
		case CC_CURSOR:
			re_refresh_cursor(el);
			break;

		case CC_REDISPLAY:
			re_clear_lines(el);
			re_clear_display(el);
			/* FALLTHROUGH */

		case CC_REFRESH:
			re_refresh(el);
			break;

		case CC_REFRESH_BEEP:
			re_refresh(el);
			terminal_beep(el);
			break;

		case CC_NORM:	/* normal char */
			break;

		case CC_ARGHACK:	/* Suggested by Rich Salz */
			/* <*****@*****.**> */
			continue;	/* keep going... */

		case CC_EOF:	/* end of file typed */
			if ((el->el_flags & UNBUFFERED) == 0)
				num = 0;
			else if (num == -1) {
				*el->el_line.lastchar++ = CONTROL('d');
				el->el_line.cursor = el->el_line.lastchar;
				num = 1;
			}
			break;

		case CC_NEWLINE:	/* normal end of line */
			num = (int)(el->el_line.lastchar - el->el_line.buffer);
			break;

		case CC_FATAL:	/* fatal error, reset to known state */
			/* put (real) cursor in a known place */
			re_clear_display(el);	/* reset the display stuff */
			ch_reset(el);	/* reset the input pointers */
			read_clearmacros(&el->el_read->macros);
			re_refresh(el); /* print the prompt again */
			break;

		case CC_ERROR:
		default:	/* functions we don't know about */
			terminal_beep(el);
			terminal__flush(el);
			break;
		}
		el->el_state.argument = 1;
		el->el_state.doingarg = 0;
		el->el_chared.c_vcmd.action = NOP;
		if (el->el_flags & UNBUFFERED)
			break;
	}

	terminal__flush(el);		/* flush any buffered output */
	/* make sure the tty is set up correctly */
	if ((el->el_flags & UNBUFFERED) == 0) {
		read_finish(el);
		*nread = num != -1 ? num : 0;
	} else
		*nread = (int)(el->el_line.lastchar - el->el_line.buffer);

	if (*nread == 0) {
		if (num == -1) {
			*nread = -1;
			if (el->el_read->read_errno)
				errno = el->el_read->read_errno;
		}
		return NULL;
	} else
		return el->el_line.buffer;
}
Esempio n. 6
0
const wchar_t *
el_wgets(EditLine *el, int *nread)
{
	int retval;
	el_action_t cmdnum = 0;
	int num;		/* how many chars we have read at NL */
	wchar_t wc;
	wchar_t ch, *cp;
	int crlf = 0;
	int nrb;

	if (nread == NULL)
		nread = &nrb;
	*nread = 0;

	if (el->el_flags & NO_TTY) {
		size_t idx;

		cp = el->el_line.buffer;
		while ((num = (*el->el_read->read_char)(el, &wc)) == 1) {
			*cp = wc;
			/* make sure there is space for next character */
			if (cp + 1 >= el->el_line.limit) {
				idx = (size_t)(cp - el->el_line.buffer);
				if (!ch_enlargebufs(el, (size_t)2))
					break;
				cp = &el->el_line.buffer[idx];
			}
			cp++;
			if (el->el_flags & UNBUFFERED)
				break;
			if (cp[-1] == '\r' || cp[-1] == '\n')
				break;
		}
		if (num == -1) {
			if (errno == EINTR)
				cp = el->el_line.buffer;
			el->el_errno = errno;
		}

		goto noedit;
	}


#ifdef FIONREAD
	if (el->el_tty.t_mode == EX_IO && el->el_chared.c_macro.level < 0) {
		int chrs = 0;

		(void) ioctl(el->el_infd, FIONREAD, &chrs);
		if (chrs == 0) {
			if (tty_rawmode(el) < 0) {
				errno = 0;
				*nread = 0;
				return NULL;
			}
		}
	}
#endif /* FIONREAD */

	if ((el->el_flags & UNBUFFERED) == 0)
		read_prepare(el);

	if (el->el_flags & EDIT_DISABLED) {
		size_t idx;

		if ((el->el_flags & UNBUFFERED) == 0)
			cp = el->el_line.buffer;
		else
			cp = el->el_line.lastchar;

		terminal__flush(el);

		while ((num = (*el->el_read->read_char)(el, &wc)) == 1) {
			*cp = wc;
			/* make sure there is space next character */
			if (cp + 1 >= el->el_line.limit) {
				idx = (size_t)(cp - el->el_line.buffer);
				if (!ch_enlargebufs(el, (size_t)2))
					break;
				cp = &el->el_line.buffer[idx];
			}
			cp++;
			crlf = cp[-1] == '\r' || cp[-1] == '\n';
			if (el->el_flags & UNBUFFERED)
				break;
			if (crlf)
				break;
		}

		if (num == -1) {
			if (errno == EINTR)
				cp = el->el_line.buffer;
			el->el_errno = errno;
		}

		goto noedit;
	}

	for (num = -1; num == -1;) {  /* while still editing this line */
#ifdef DEBUG_EDIT
		read_debug(el);
#endif /* DEBUG_EDIT */
		/* if EOF or error */
		if (read_getcmd(el, &cmdnum, &ch) == -1) {
#ifdef DEBUG_READ
			(void) fprintf(el->el_errfile,
			    "Returning from el_gets\n");
#endif /* DEBUG_READ */
			break;
		}
		if (el->el_errno == EINTR) {
			el->el_line.buffer[0] = '\0';
			el->el_line.lastchar =
			    el->el_line.cursor = el->el_line.buffer;
			break;
		}
		if ((size_t)cmdnum >= el->el_map.nfunc) {	/* BUG CHECK command */
#ifdef DEBUG_EDIT
			(void) fprintf(el->el_errfile,
			    "ERROR: illegal command from key 0%o\r\n", ch);
#endif /* DEBUG_EDIT */
			continue;	/* try again */
		}
		/* now do the real command */
#ifdef DEBUG_READ
		{
			el_bindings_t *b;
			for (b = el->el_map.help; b->name; b++)
				if (b->func == cmdnum)
					break;
			if (b->name)
				(void) fprintf(el->el_errfile,
				    "Executing %ls\n", b->name);
			else
				(void) fprintf(el->el_errfile,
				    "Error command = %d\n", cmdnum);
		}
#endif /* DEBUG_READ */
		/* vi redo needs these way down the levels... */
		el->el_state.thiscmd = cmdnum;
		el->el_state.thisch = ch;
		if (el->el_map.type == MAP_VI &&
		    el->el_map.current == el->el_map.key &&
		    el->el_chared.c_redo.pos < el->el_chared.c_redo.lim) {
			if (cmdnum == VI_DELETE_PREV_CHAR &&
			    el->el_chared.c_redo.pos != el->el_chared.c_redo.buf
			    && iswprint(el->el_chared.c_redo.pos[-1]))
				el->el_chared.c_redo.pos--;
			else
				*el->el_chared.c_redo.pos++ = ch;
		}
		retval = (*el->el_map.func[cmdnum]) (el, ch);
#ifdef DEBUG_READ
		(void) fprintf(el->el_errfile,
			"Returned state %d\n", retval );
#endif /* DEBUG_READ */

		/* save the last command here */
		el->el_state.lastcmd = cmdnum;

		/* use any return value */
		switch (retval) {
		case CC_CURSOR:
			re_refresh_cursor(el);
			break;

		case CC_REDISPLAY:
			re_clear_lines(el);
			re_clear_display(el);
			/* FALLTHROUGH */

		case CC_REFRESH:
			re_refresh(el);
			break;

		case CC_REFRESH_BEEP:
			re_refresh(el);
			terminal_beep(el);
			break;

		case CC_NORM:	/* normal char */
			break;

		case CC_ARGHACK:	/* Suggested by Rich Salz */
			/* <*****@*****.**> */
			continue;	/* keep going... */

		case CC_EOF:	/* end of file typed */
			if ((el->el_flags & UNBUFFERED) == 0)
				num = 0;
			else if (num == -1) {
				*el->el_line.lastchar++ = CONTROL('d');
				el->el_line.cursor = el->el_line.lastchar;
				num = 1;
			}
			break;

		case CC_NEWLINE:	/* normal end of line */
			num = (int)(el->el_line.lastchar - el->el_line.buffer);
			break;

		case CC_FATAL:	/* fatal error, reset to known state */
#ifdef DEBUG_READ
			(void) fprintf(el->el_errfile,
			    "*** editor fatal ERROR ***\r\n\n");
#endif /* DEBUG_READ */
			/* put (real) cursor in a known place */
			re_clear_display(el);	/* reset the display stuff */
			ch_reset(el, 1);	/* reset the input pointers */
			re_refresh(el); /* print the prompt again */
			break;

		case CC_ERROR:
		default:	/* functions we don't know about */
#ifdef DEBUG_READ
			(void) fprintf(el->el_errfile,
			    "*** editor ERROR ***\r\n\n");
#endif /* DEBUG_READ */
			terminal_beep(el);
			terminal__flush(el);
			break;
		}
		el->el_state.argument = 1;
		el->el_state.doingarg = 0;
		el->el_chared.c_vcmd.action = NOP;
		if (el->el_flags & UNBUFFERED)
			break;
	}

	terminal__flush(el);		/* flush any buffered output */
	/* make sure the tty is set up correctly */
	if ((el->el_flags & UNBUFFERED) == 0) {
		read_finish(el);
		*nread = num != -1 ? num : 0;
	} else {
		*nread = (int)(el->el_line.lastchar - el->el_line.buffer);
	}
	goto done;
noedit:
	el->el_line.cursor = el->el_line.lastchar = cp;
	*cp = '\0';
	*nread = (int)(el->el_line.cursor - el->el_line.buffer);
done:
	if (*nread == 0) {
		if (num == -1) {
			*nread = -1;
			errno = el->el_errno;
		}
		return NULL;
	} else
		return el->el_line.buffer;
}