/** * inf_text_buffer_insert_text: * @buffer: A #InfTextBuffer. * @pos: A character offset into @buffer. * @text (type=guint8*) (array length=bytes) (transfer none): A pointer to * the text to insert. * @len: The length (in characters) of @text. * @bytes: The length (in bytes) of @text. * @user: (allow-none): A #InfUser that has inserted the new text, or %NULL. * * Inserts @text into @buffer as written by @author. @text must be encoded in * the character encoding of the buffer, see inf_text_buffer_get_encoding(). **/ void inf_text_buffer_insert_text(InfTextBuffer* buffer, guint pos, gconstpointer text, gsize bytes, guint len, InfUser* user) { InfTextBufferInterface* iface; InfTextChunk* chunk; g_return_if_fail(INF_TEXT_IS_BUFFER(buffer)); g_return_if_fail(text != NULL); g_return_if_fail(user == NULL || INF_IS_USER(user)); iface = INF_TEXT_BUFFER_GET_IFACE(buffer); g_return_if_fail(iface->insert_text != NULL); chunk = inf_text_chunk_new(inf_text_buffer_get_encoding(buffer)); inf_text_chunk_insert_text( chunk, 0, text, bytes, len, user == NULL ? 0 : inf_user_get_id(user) ); iface->insert_text(buffer, pos, chunk, user); inf_text_chunk_free(chunk); }
static guint infinoted_plugin_linekeeper_count_lines(InfTextBuffer* buffer) { /* Count the number of lines at the end of the document. This assumes the * buffer content is in UTF-8, which is currently hardcoded in infinoted. */ InfTextBufferIter* iter; guint n_lines; gboolean has_iter; guint length; gsize bytes; gchar* text; gchar* pos; gchar* new_pos; gunichar c; g_assert(strcmp(inf_text_buffer_get_encoding(buffer), "UTF-8") == 0); n_lines = 0; iter = inf_text_buffer_create_end_iter(buffer); if(iter == NULL) return 0; do { length = inf_text_buffer_iter_get_length(buffer, iter); bytes = inf_text_buffer_iter_get_bytes(buffer, iter); text = inf_text_buffer_iter_get_text(buffer, iter); pos = text + bytes; while(length > 0) { new_pos = g_utf8_prev_char(pos); g_assert(bytes >= (pos - new_pos)); c = g_utf8_get_char(new_pos); if(c == '\n' || g_unichar_type(c) == G_UNICODE_LINE_SEPARATOR) ++n_lines; else break; --length; bytes -= (pos - new_pos); pos = new_pos; } g_free(text); } while(length == 0 && inf_text_buffer_iter_prev(buffer, iter)); inf_text_buffer_destroy_iter(buffer, iter); return n_lines; }
static InfAdoptedOperation* inf_text_remote_delete_operation_apply_transformed(InfAdoptedOperation* op, InfAdoptedOperation* trans, InfAdoptedUser* by, InfBuffer* buffer, GError** error) { InfTextRemoteDeleteOperationPrivate* priv; InfTextChunk* chunk; InfTextChunk* temp_slice; GSList* list; GSList* item; InfAdoptedOperation* operation; GSList* recon_list; GSList* recon_item; InfTextRemoteDeleteOperationRecon* recon; InfTextDefaultDeleteOperation* result; g_assert(INF_TEXT_IS_REMOTE_DELETE_OPERATION(op)); g_assert(INF_TEXT_IS_BUFFER(buffer)); /* TODO: We can probably optimize this function, but then we should * a) profile it and b) in many cases input parameters to this function * are trivial anyway. */ if(INF_ADOPTED_IS_SPLIT_OPERATION(trans)) { list = inf_adopted_split_operation_unsplit( INF_ADOPTED_SPLIT_OPERATION(trans) ); } else { list = g_slist_prepend(NULL, trans); } chunk = inf_text_chunk_new( inf_text_buffer_get_encoding(INF_TEXT_BUFFER(buffer)) ); /* We assume the list of remote delete operations to be in order */ for(item = list; item != NULL; item = g_slist_next(item)) { g_assert(INF_TEXT_IS_REMOTE_DELETE_OPERATION(item->data)); priv = INF_TEXT_REMOTE_DELETE_OPERATION_PRIVATE(item->data); operation = INF_ADOPTED_OPERATION(item->data); if(priv->length > 0) { temp_slice = inf_text_buffer_get_slice( INF_TEXT_BUFFER(buffer), priv->position, priv->length ); recon_list = inf_text_remote_delete_operation_recon_feed( priv->recon, 0, temp_slice ); inf_text_chunk_free(temp_slice); } else { recon_list = priv->recon; } for(recon_item = recon_list; recon_item != NULL; recon_item = g_slist_next(recon_item)) { recon = (InfTextRemoteDeleteOperationRecon*)recon_item->data; g_assert(priv->recon_offset + recon->position == inf_text_chunk_get_length(chunk)); inf_text_chunk_insert_chunk( chunk, inf_text_chunk_get_length(chunk), recon->chunk ); } /* Free recon list if newly allocated */ if(priv->length > 0) inf_text_remote_delete_operation_recon_free(recon_list); if(!inf_adopted_operation_apply(operation, by, buffer, error)) { g_slist_free(list); inf_text_chunk_free(chunk); return NULL; } } g_slist_free(list); priv = INF_TEXT_REMOTE_DELETE_OPERATION_PRIVATE(op); result = inf_text_default_delete_operation_new(priv->position, chunk); inf_text_chunk_free(chunk); return INF_ADOPTED_OPERATION(result); }
QString TextBuffer::encoding() { return inf_text_buffer_get_encoding( INF_TEXT_BUFFER(gobject()) ); }