+ }
+
+ session->read_buf_len = read_len;
+ }
+
+ data_buf = session->read_data_buf;
+ terminator_len = strlen(session->read_data_terminator);
+
+ if (session->read_buf_len == 0)
+ return TRUE;
+
+ g_byte_array_append(data_buf, session->read_buf_p,
+ session->read_buf_len);
+
+ session->read_buf_len = 0;
+ session->read_buf_p = session->read_buf;
+
+ /* check if data is terminated */
+ if (data_buf->len >= terminator_len) {
+ if (memcmp(data_buf->data, session->read_data_terminator,
+ terminator_len) == 0)
+ complete = TRUE;
+ else if (data_buf->len >= terminator_len + 2 &&
+ memcmp(data_buf->data + data_buf->len -
+ (terminator_len + 2), "\r\n", 2) == 0 &&
+ memcmp(data_buf->data + data_buf->len -
+ terminator_len, session->read_data_terminator,
+ terminator_len) == 0)
+ complete = TRUE;
+ }
+
+ /* incomplete read */
+ if (!complete) {
+ GTimeVal tv_cur;
+
+ g_get_current_time(&tv_cur);
+ if (tv_cur.tv_sec - session->tv_prev.tv_sec > 0 ||
+ tv_cur.tv_usec - session->tv_prev.tv_usec >
+ UI_REFRESH_INTERVAL) {
+ session->recv_data_progressive_notify
+ (session, data_buf->len, 0,
+ session->recv_data_progressive_notify_data);
+ g_get_current_time(&session->tv_prev);
+ }
+ return TRUE;
+ }
+
+ /* complete */
+ if (session->io_tag > 0) {
+ g_source_remove(session->io_tag);
+ session->io_tag = 0;
+ }
+
+ data_len = data_buf->len - terminator_len;
+
+ /* callback */
+ ret = session->recv_data_finished(session, (gchar *)data_buf->data,
+ data_len);
+
+ g_byte_array_set_size(data_buf, 0);
+
+ session->recv_data_notify(session, data_len,
+ session->recv_data_notify_data);
+
+ if (ret < 0)
+ session->state = SESSION_ERROR;
+
+ return FALSE;
+}
+
+static gint session_write_buf(Session *session)
+{
+ gint write_len;
+ gint to_write_len;
+
+ cm_return_val_if_fail(session->write_buf != NULL, -1);
+ cm_return_val_if_fail(session->write_buf_p != NULL, -1);
+ cm_return_val_if_fail(session->write_buf_len > 0, -1);
+
+ to_write_len = session->write_buf_len -
+ (session->write_buf_p - session->write_buf);
+ to_write_len = MIN(to_write_len, SESSION_BUFFSIZE);
+
+ write_len = sock_write(session->sock, session->write_buf_p,
+ to_write_len);
+
+ if (write_len < 0) {
+ switch (errno) {
+ case EAGAIN:
+ write_len = 0;