/* 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); }
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; }