static InfTextDeleteOperation* inf_text_default_delete_operation_transform_overlap( InfTextDeleteOperation* operation, InfTextDeleteOperation* other, guint position, guint begin, guint other_begin, guint length) { InfTextDefaultDeleteOperationPrivate* priv; InfTextChunk* chunk; GObject* result; priv = INF_TEXT_DEFAULT_DELETE_OPERATION_PRIVATE(operation); chunk = inf_text_chunk_copy(priv->chunk); inf_text_chunk_erase(chunk, begin, length); result = g_object_new( INF_TEXT_TYPE_DEFAULT_DELETE_OPERATION, "position", position, "chunk", chunk, NULL ); inf_text_chunk_free(chunk); return INF_TEXT_DELETE_OPERATION(result); }
/* 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 GSList* inf_text_remote_delete_operation_recon_copy(GSList* recon_list) { GSList* item; InfTextRemoteDeleteOperationRecon* recon; GSList* new_list; GSList* last; InfTextRemoteDeleteOperationRecon* new_recon; new_list = NULL; for(item = recon_list; item != NULL; item = g_slist_next(item)) { recon = (InfTextRemoteDeleteOperationRecon*)item->data; 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); } return new_list; }
static InfAdoptedSplitOperation* inf_text_remote_delete_operation_transform_split( InfTextDeleteOperation* operation, guint split_pos, guint split_len) { /* Need to split the delete operation and the recon list */ InfTextRemoteDeleteOperationPrivate* priv; InfAdoptedSplitOperation* result; GObject* first_operation; GObject* second_operation; InfTextRemoteDeleteOperationPrivate* result_priv; InfTextRemoteDeleteOperationRecon* recon; InfTextRemoteDeleteOperationRecon* new_recon; GSList* first_recon; GSList* second_recon; guint recon_cur_len; GSList* item; priv = INF_TEXT_REMOTE_DELETE_OPERATION_PRIVATE(operation); first_recon = NULL; second_recon = NULL; recon_cur_len = 0; for(item = priv->recon; item != NULL; item = g_slist_next(item)) { recon = (InfTextRemoteDeleteOperationRecon*)item->data; g_assert(recon->position >= recon_cur_len); if(recon->position - recon_cur_len <= split_pos) { new_recon = g_slice_new(InfTextRemoteDeleteOperationRecon); new_recon->position = recon->position; new_recon->chunk = inf_text_chunk_copy(recon->chunk); first_recon = g_slist_prepend(first_recon, new_recon); recon_cur_len += inf_text_chunk_get_length(recon->chunk); } else { new_recon = g_slice_new(InfTextRemoteDeleteOperationRecon); new_recon->position = recon->position - (split_pos + recon_cur_len); new_recon->chunk = inf_text_chunk_copy(recon->chunk); second_recon = g_slist_prepend(second_recon, new_recon); } } first_operation = g_object_new( INF_TEXT_TYPE_REMOTE_DELETE_OPERATION, "position", priv->position, "length", split_pos, NULL ); second_operation = g_object_new( INF_TEXT_TYPE_REMOTE_DELETE_OPERATION, "position", priv->position + split_len, "length", priv->length - split_pos, NULL ); result_priv = INF_TEXT_REMOTE_DELETE_OPERATION_PRIVATE(first_operation); result_priv->recon = g_slist_reverse(first_recon); result_priv->recon_offset = priv->recon_offset; result_priv = INF_TEXT_REMOTE_DELETE_OPERATION_PRIVATE(second_operation); result_priv->recon = g_slist_reverse(second_recon); result_priv->recon_offset = priv->recon_offset + split_pos + recon_cur_len; result = inf_adopted_split_operation_new( INF_ADOPTED_OPERATION(first_operation), INF_ADOPTED_OPERATION(second_operation) ); g_object_unref(G_OBJECT(second_operation)); g_object_unref(G_OBJECT(first_operation)); return result; }