static void
inf_test_text_recover_text_erased_cb(InfTextBuffer* buffer,
                                     guint pos,
                                     InfTextChunk* chunk,
                                     InfUser* user,
                                     gpointer user_data)
{
  InfAdoptedOperation* operation;
  guint len;

  InfTextChunk* print_chunk;
  gsize print_bytes;
  gpointer print_text;

  /* If the document has substantial content and this deletes most of it,
   * then print out the document here. */
  len = inf_text_chunk_get_length(chunk);
  if(inf_text_buffer_get_length(buffer) + len >= 50)
  {
    if(len >= (inf_text_buffer_get_length(buffer) + len)*75/100)
    {
      if(*(int*)user_data == 0)
      {
        print_chunk = inf_text_buffer_get_slice(
          buffer,
          0,
          inf_text_buffer_get_length(buffer)
        );

        inf_text_chunk_insert_chunk(print_chunk, pos, chunk);
        print_text = inf_text_chunk_get_text(print_chunk, &print_bytes);
        inf_text_chunk_free(print_chunk);

        printf("%.*s\n", (int)print_bytes, (gchar*)print_text);
        g_free(print_text);
      }

      --*(int*)user_data;
    }
  }

  g_object_unref(buffer);
}
static void
infinoted_plugin_linekeeper_run(InfinotedPluginLinekeeperSessionInfo* info)
{
  guint cur_lines;
  guint n;
  gchar* text;

  cur_lines = infinoted_plugin_linekeeper_count_lines(info->buffer);

  if(cur_lines > info->plugin->n_lines)
  {
    n = cur_lines - info->plugin->n_lines;

    inf_text_buffer_erase_text(
      info->buffer,
      inf_text_buffer_get_length(info->buffer) - n,
      n,
      info->user
    );
  }
  else if(cur_lines < info->plugin->n_lines)
  {
    n = info->plugin->n_lines - cur_lines;
    text = g_malloc(n * sizeof(gchar));
    memset(text, '\n', n);

    inf_text_buffer_insert_text(
      info->buffer,
      inf_text_buffer_get_length(info->buffer),
      text,
      n,
      n,
      info->user
    );
  }
}
static void
inf_test_util_print_buffer(InfTextBuffer* buffer)
{
  InfTextChunk* chunk;
  gchar* text;
  gsize bytes;

  chunk = inf_text_buffer_get_slice(
    buffer,
    0,
    inf_text_buffer_get_length(buffer)
  );

  text = inf_text_chunk_get_text(chunk, &bytes);
  inf_text_chunk_free(chunk);

  printf("%.*s\n", (int)bytes, text);
  g_free(text);
}
static void
infinoted_plugin_linekeeper_join_user(
  InfinotedPluginLinekeeperSessionInfo* info)
{
  InfSession* session;
  InfUserTable* user_table;

  g_assert(info->user == NULL);
  g_assert(info->request == NULL);

  g_object_get(G_OBJECT(info->proxy), "session", &session, NULL);
  user_table = inf_session_get_user_table(session);

  /* Prevent double user join attempt by blocking the callback for
   * joining our local user. */
  g_signal_handlers_block_by_func(
    user_table,
    G_CALLBACK(infinoted_plugin_linekeeper_add_available_user_cb),
    info
  );

  info->request = inf_text_session_join_user(
    info->proxy,
    "LineKeeper",
    INF_USER_ACTIVE,
    0.0,
    inf_text_buffer_get_length(info->buffer),
    0,
    infinoted_plugin_linekeeper_user_join_cb,
    info
  );

  g_signal_handlers_unblock_by_func(
    user_table,
    G_CALLBACK(infinoted_plugin_linekeeper_add_available_user_cb),
    info
  );

  g_object_unref(session);
}
static gboolean
inf_text_remote_delete_operation_apply(InfAdoptedOperation* operation,
                                       InfAdoptedUser* by,
                                       InfBuffer* buffer,
                                       GError** error)
{
  InfTextRemoteDeleteOperationPrivate* priv;

  g_assert(INF_TEXT_IS_REMOTE_DELETE_OPERATION(operation));
  g_assert(INF_TEXT_IS_BUFFER(buffer));

  priv = INF_TEXT_REMOTE_DELETE_OPERATION_PRIVATE(operation);

  if(priv->position + priv->length >
     inf_text_buffer_get_length(INF_TEXT_BUFFER(buffer)))
  {
    g_set_error(
      error,
      g_quark_from_static_string("INF_TEXT_OPERATION_ERROR"),
      INF_TEXT_OPERATION_ERROR_INVALID_DELETE,
      "%s",
      _("Attempt to remove text from after the end of the document")
    );

    return FALSE;
  }
  else
  {
    inf_text_buffer_erase_text(
      INF_TEXT_BUFFER(buffer),
      priv->position,
      priv->length,
      INF_USER(by)
    );
    
    return TRUE;
  }
}
static gboolean
check_buffer(InfTextBuffer* buffer,
             const gchar* check_text,
             const gchar* buffer_name)
{
  InfTextChunk* chunk;
  gpointer text;
  gsize len;
  gboolean result;

  chunk = inf_text_buffer_get_slice(
    buffer,
    0,
    inf_text_buffer_get_length(buffer)
  );

  text = inf_text_chunk_get_text(chunk, &len);
  inf_text_chunk_free(chunk);

  if(strlen(check_text) != len || strncmp(check_text, text, len) != 0)
  {
    printf(
      "%s Buffer has text \"%.*s\" but should have \"%s\"\n",
      buffer_name,
      (int)len, (gchar*)text,
      check_text
    );

    result = FALSE;
  }
  else
  {
    result = TRUE;
  }

  g_free(text);
  return result;
}
static void
infinoted_directory_sync_session_save(InfinotedDirectorySync* dsync,
                                      InfinotedDirectorySyncSession* session)
{
  InfdDirectoryIter* iter;
  GError* error;
  InfBuffer* buffer;
  InfTextChunk* chunk;
  gchar* content;
  gsize bytes;

  iter = &session->iter;
  error = NULL;

  if(session->timeout != NULL)
  {
    inf_io_remove_timeout(
      infd_directory_get_io(dsync->directory),
      session->timeout
    );

    session->timeout = NULL;
  }

  buffer = inf_session_get_buffer(
    infd_session_proxy_get_session(session->proxy)
  );

  error = NULL;
  if(!infinoted_util_create_dirname(session->path, &error))
  {
    g_warning(_("Failed to create directory for path \"%s\": %s\n\n"),
              session->path, error->message);
    g_error_free(error);
  }
  else
  {
    /* TODO: Use the iterator API here, which should be less expensive */
    chunk = inf_text_buffer_get_slice(
      INF_TEXT_BUFFER(buffer),
      0,
      inf_text_buffer_get_length(INF_TEXT_BUFFER(buffer))
    );

    content = inf_text_chunk_get_text(chunk, &bytes);
    inf_text_chunk_free(chunk);

    if(!g_file_set_contents(session->path, content, bytes, &error))
    {
      g_warning(
        _("Failed to write session for path \"%s\": %s\n\n"
          "Will retry in %u seconds."),
        session->path, error->message, dsync->sync_interval
      );

      g_error_free(error);

      infinoted_directory_sync_session_start(session->dsync, session);
    }

    g_free(content);
  }
}
Exemple #8
0
unsigned int TextBuffer::length()
{
    return inf_text_buffer_get_length( INF_TEXT_BUFFER(gobject()) );
}
static gboolean
infd_note_plugin_text_read_buffer(InfTextBuffer* buffer,
                                  InfUserTable* user_table,
                                  xmlNodePtr node,
                                  GError** error)
{
  xmlNodePtr child;
  guint author;
  gchar* content;
  gboolean result;
  gboolean res;
  InfUser* user;
  gsize bytes;
  guint chars;


  g_assert(inf_text_buffer_get_length(buffer) == 0);

  for(child = node->children; child != NULL; child = child->next)
  {
    if(child->type != XML_ELEMENT_NODE)
      continue;

    if(strcmp((const gchar*)child->name, "segment") == 0)
    {
      res = inf_xml_util_get_attribute_uint_required(
        child,
        "author",
        &author,
        error
      );

      if(res == FALSE)
      {
        result = FALSE;
        break;
      }

      if(author != 0)
      {
        user = inf_user_table_lookup_user_by_id(user_table, author);

        if(user == NULL)
        {
          g_set_error(
            error,
            g_quark_from_static_string("INF_NOTE_PLUGIN_TEXT_ERROR"),
            INFD_NOTE_PLUGIN_TEXT_ERROR_NO_SUCH_USER,
            "User with ID %u does not exist",
            author
          );

          result = FALSE;
          break;
        }
      }
      else
      {
        user = NULL;
      }

      content = inf_xml_util_get_child_text(child, &bytes, &chars, error);
      if(!content)
      {
        result = FALSE;
        break;
      }

      if(*content != '\0')
      {
        /* TODO: Use inf_text_buffer_append when we have it */
        inf_text_buffer_insert_text(
          buffer,
          inf_text_buffer_get_length(buffer),
          content,
          bytes,
          chars,
          user
        );
      }

      g_free(content);
    }
    else
    {
      infd_note_plugin_text_session_unexpected_node(child, error);
      result = FALSE;
      break;
    }
  }

  if(child == NULL)
    result = TRUE;

  return result;
}