/* TODO: Merge adjacent text chunks */
static GSList*
inf_text_remote_delete_operation_recon_feed(GSList* recon_list,
                                            guint position,
                                            InfTextChunk* chunk)
{
  GSList* item;
  InfTextRemoteDeleteOperationRecon* recon;
  GSList* new_list;
  GSList* last;
  InfTextRemoteDeleteOperationRecon* new_recon;

  guint text_pos;
  guint cur_len;
  guint text_len;

  new_list = NULL;
  text_pos = 0;
  cur_len = 0;

  for(item = recon_list; item != NULL; item = g_slist_next(item))
  {
    recon = (InfTextRemoteDeleteOperationRecon*)item->data;
    if(position + text_pos + cur_len < recon->position &&
       text_pos < inf_text_chunk_get_length(chunk))
    {
      text_len = recon->position - position - text_pos - cur_len;
      if(text_len > inf_text_chunk_get_length(chunk) - text_pos)
        text_len = inf_text_chunk_get_length(chunk) - text_pos;

      new_recon = g_slice_new(InfTextRemoteDeleteOperationRecon);
      new_recon->position = position + text_pos + cur_len;
      new_recon->chunk = inf_text_chunk_substring(chunk, text_pos, text_len);
      new_list = g_slist_append_fast(new_list, &last, new_recon);
      text_pos += text_len;
    }

    cur_len += inf_text_chunk_get_length(recon->chunk);
    new_recon = g_slice_new(InfTextRemoteDeleteOperationRecon);
    new_recon->position = recon->position;
    new_recon->chunk = inf_text_chunk_copy(recon->chunk);
    new_list = g_slist_append_fast(new_list, &last, new_recon);
  }

  if(text_pos < inf_text_chunk_get_length(chunk))
  {
    new_recon = g_slice_new(InfTextRemoteDeleteOperationRecon);
    new_recon->position = position + text_pos + cur_len;
    new_recon->chunk = inf_text_chunk_substring(
      chunk,
      text_pos,
      inf_text_chunk_get_length(chunk) - text_pos
    );

    new_list = g_slist_append_fast(new_list, &last, new_recon);
  }

  return new_list;
}
static InfAdoptedSplitOperation*
inf_text_default_delete_operation_transform_split(
  InfTextDeleteOperation* operation,
  guint split_pos,
  guint split_len)
{
  InfTextDefaultDeleteOperationPrivate* priv;
  InfTextChunk* first_chunk;
  InfTextChunk* second_chunk;
  GObject* first;
  GObject* second;
  InfAdoptedSplitOperation* result;

  priv = INF_TEXT_DEFAULT_DELETE_OPERATION_PRIVATE(operation);

  first_chunk = inf_text_chunk_substring(priv->chunk, 0, split_pos);
  second_chunk = inf_text_chunk_substring(
    priv->chunk,
    split_pos,
    inf_text_chunk_get_length(priv->chunk) - split_pos
  );

  first = g_object_new(
    INF_TEXT_TYPE_DEFAULT_DELETE_OPERATION,
    "position", priv->position,
    "chunk", first_chunk,
    NULL
  );

  second = g_object_new(
    INF_TEXT_TYPE_DEFAULT_DELETE_OPERATION,
    "position", priv->position + split_pos + split_len,
    "chunk", second_chunk,
    NULL
  );

  inf_text_chunk_free(first_chunk);
  inf_text_chunk_free(second_chunk);

  result = inf_adopted_split_operation_new(
    INF_ADOPTED_OPERATION(first),
    INF_ADOPTED_OPERATION(second)
  );

  g_object_unref(first);
  g_object_unref(second);
  return result;
}
static InfTextDeleteOperation*
inf_text_remote_delete_operation_transform_overlap(
  InfTextDeleteOperation* operation,
  InfTextDeleteOperation* other,
  guint position,
  guint begin,
  guint other_begin,
  guint length)
{
  InfTextRemoteDeleteOperationPrivate* priv;
  InfTextChunk* chunk;
  GObject* result;
  InfTextRemoteDeleteOperationPrivate* result_priv;


  /* It is actually possible that two remote delete operations are
   * transformed against each other (actually the parts of a splitted
   * remote delete operation). However, they must not overlap. */
  g_assert(INF_TEXT_IS_DEFAULT_DELETE_OPERATION(other));

  priv = INF_TEXT_REMOTE_DELETE_OPERATION_PRIVATE(operation);

  chunk = inf_text_chunk_substring(
    inf_text_default_delete_operation_get_chunk(
      INF_TEXT_DEFAULT_DELETE_OPERATION(other)
    ),
    other_begin,
    length
  );

  result = g_object_new(
    INF_TEXT_TYPE_REMOTE_DELETE_OPERATION,
    "position", position,
    "length", priv->length - length,
    NULL
  );

  result_priv = INF_TEXT_REMOTE_DELETE_OPERATION_PRIVATE(result);

  result_priv->recon = inf_text_remote_delete_operation_recon_feed(
    priv->recon,
    begin,
    chunk
  );

  inf_text_chunk_free(chunk);

  result_priv->recon_offset = priv->recon_offset;
  return INF_TEXT_DELETE_OPERATION(result);
}
Пример #4
0
int main()
{
  InfTextChunk* chunk;
  InfTextChunk* chunk2;

  chunk2 = inf_text_chunk_new("UTF-8");

  inf_text_chunk_insert_text(chunk2, 0, "a", 1, 1, 500);
  inf_text_chunk_insert_text(chunk2, 0, "b", 1, 1, 501);
  inf_text_chunk_insert_text(chunk2, 0, "c", 1, 1, 502);
  inf_text_chunk_insert_text(chunk2, 3, "ü", 2, 1, 503);
  chunk = inf_text_chunk_substring(chunk2, 0, 3);

  inf_text_chunk_free(chunk);
  inf_text_chunk_free(chunk2);

  return 0;
}