Actually use the eina_file memory mapping

Any appended or modified lines need to be stored seperately.
Always check for modified content before using the memory map from the
backing file.
This commit is contained in:
Andy Williams 2014-11-19 22:39:00 +00:00
parent aa5b70972c
commit 65b67ec898
8 changed files with 89 additions and 40 deletions

View File

@ -23,6 +23,14 @@ _elm_code_test_win_del(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, voi
elm_exit();
}
static void _append_line(Elm_Code_File *file, const char *line)
{
int length;
length = strlen(line);
elm_code_file_line_append(file, line, length);
}
static Evas_Object *
_elm_code_test_welcome_setup(Evas_Object *parent)
{
@ -32,12 +40,12 @@ _elm_code_test_welcome_setup(Evas_Object *parent)
code = elm_code_create();
elm_code_file_new(code);
widget = elm_code_widget_add(parent, code);
elm_code_file_line_append(code->file, "Hello World, Elm Code!");
_append_line(code->file, "Hello World, Elm Code!");
elm_code_file_line_token_add(code->file, 1, 14, 21, ELM_CODE_TOKEN_TYPE_COMMENT);
elm_code_file_line_append(code->file, "");
elm_code_file_line_append(code->file, "This is a demo of elm_code's capabilities.");
_append_line(code->file, "");
_append_line(code->file, "This is a demo of elm_code's capabilities.");
elm_code_file_line_append(code->file, "*** Currently experimental ***");
_append_line(code->file, "*** Currently experimental ***");
elm_code_file_line_status_set(code->file, 4, ELM_CODE_STATUS_TYPE_ERROR);
evas_object_size_hint_weight_set(widget, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
@ -65,12 +73,12 @@ _elm_code_test_diff_setup(Evas_Object *parent)
elm_code_file_new(code);
widget = elm_code_widget_add(parent, code);
elm_code_file_line_append(code->file, "Some content to diff");
elm_code_file_line_append(code->file, "");
elm_code_file_line_append(code->file, "more");
elm_code_file_line_append(code->file, "removed");
elm_code_file_line_append(code->file, "will change");
elm_code_file_line_append(code->file, "unchanged");
_append_line(code->file, "Some content to diff");
_append_line(code->file, "");
_append_line(code->file, "more");
_append_line(code->file, "removed");
_append_line(code->file, "will change");
_append_line(code->file, "unchanged");
elm_code_file_line_status_set(code->file, 4, ELM_CODE_STATUS_TYPE_REMOVED);
elm_code_file_line_token_add(code->file, 4, 1, 7, ELM_CODE_TOKEN_TYPE_REMOVED);
@ -87,12 +95,12 @@ _elm_code_test_diff_setup(Evas_Object *parent)
elm_code_file_new(code);
widget = elm_code_widget_add(parent, code);
elm_code_file_line_append(code->file, "Some content to diff");
elm_code_file_line_append(code->file, "added");
elm_code_file_line_append(code->file, "more");
elm_code_file_line_append(code->file, "");
elm_code_file_line_append(code->file, "changed");
elm_code_file_line_append(code->file, "unchanged");
_append_line(code->file, "Some content to diff");
_append_line(code->file, "added");
_append_line(code->file, "more");
_append_line(code->file, "");
_append_line(code->file, "changed");
_append_line(code->file, "unchanged");
elm_code_file_line_status_set(code->file, 2, ELM_CODE_STATUS_TYPE_ADDED);
elm_code_file_line_token_add(code->file, 2, 1, 5, ELM_CODE_TOKEN_TYPE_ADDED);

View File

@ -20,16 +20,25 @@ static Elm_Code_Line *_elm_code_blank_create(int line)
return ecl;
}
static void _elm_code_file_line_append_data(Elm_Code_File *file, const char *content, int length, int row)
static void _elm_code_file_line_append_data(Elm_Code_File *file, const char *content, int length, int row, Eina_Bool mapped)
{
Elm_Code_Line *line;
line = _elm_code_blank_create(row);
if (!line) return;
line->content = malloc(sizeof(char) * (length + 1));
strncpy(line->content, content, length);
line->content[length] = 0;
if (mapped)
{
line->content = content;
line->length = length;
}
else
{
line->modified = malloc(sizeof(char)*(length+1));
strncpy(line->modified, content, length);
line->modified[length] = 0;
line->length = length;
}
file->lines = eina_list_append(file->lines, line);
@ -64,6 +73,7 @@ EAPI Elm_Code_File *elm_code_file_open(Elm_Code *code, const char *path)
ret->file = file;
lastindex = 1;
ret->map = eina_file_map_all(file, EINA_FILE_POPULATE);
it = eina_file_map_lines(file);
EINA_ITERATOR_FOREACH(it, line)
{
@ -78,7 +88,7 @@ EAPI Elm_Code_File *elm_code_file_open(Elm_Code *code, const char *path)
ret->lines = eina_list_append(ret->lines, ecl);
}
_elm_code_file_line_append_data(ret, line->start, line->length, lastindex = line->index);
_elm_code_file_line_append_data(ret, line->start, line->length, lastindex = line->index, EINA_TRUE);
}
eina_iterator_free(it);
@ -96,11 +106,18 @@ EAPI void elm_code_file_free(Elm_Code_File *file)
EINA_LIST_FREE(file->lines, l)
{
if (l->content)
free(l->content);
if (l->modified)
free(l->modified);
free(l);
}
if (file->file)
{
if (file->map)
eina_file_map_free(file->file, file->map);
eina_file_close(file->file);
}
free(file);
}
@ -125,8 +142,9 @@ EAPI void elm_code_file_clear(Elm_Code_File *file)
EINA_LIST_FREE(file->lines, l)
{
if (l->content)
free(l->content);
if (l->modified)
free(l->modified);
free(l);
}
@ -140,12 +158,12 @@ EAPI unsigned int elm_code_file_lines_get(Elm_Code_File *file)
}
EAPI void elm_code_file_line_append(Elm_Code_File *file, const char *line)
EAPI void elm_code_file_line_append(Elm_Code_File *file, const char *line, int length)
{
int row;
row = elm_code_file_lines_get(file);
_elm_code_file_line_append_data(file, line, strlen(line), row+1);
_elm_code_file_line_append_data(file, line, length, row+1, EINA_FALSE);
}
EAPI Elm_Code_Line *elm_code_file_line_get(Elm_Code_File *file, unsigned int number)
@ -153,7 +171,7 @@ EAPI Elm_Code_Line *elm_code_file_line_get(Elm_Code_File *file, unsigned int num
return eina_list_nth(file->lines, number - 1);
}
EAPI char *elm_code_file_line_content_get(Elm_Code_File *file, unsigned int number)
EAPI const char *elm_code_file_line_content_get(Elm_Code_File *file, unsigned int number, int *length)
{
Elm_Code_Line *line;
@ -161,6 +179,11 @@ EAPI char *elm_code_file_line_content_get(Elm_Code_File *file, unsigned int numb
if (!line)
return NULL;
*length = line->length;
if (line->modified)
return line->modified;
return line->content;
}

View File

@ -24,8 +24,10 @@ typedef struct _Elm_Code_Token
typedef struct _Elm_Code_Line
{
char *content;
const char *content;
int length;
unsigned int number;
char *modified;
Elm_Code_Status_Type status;
Eina_List *tokens;
@ -39,6 +41,7 @@ typedef struct _Elm_Code_File
Eina_List *lines;
Eina_File *file;
void *map;
} Elm_Code_File;
@ -80,11 +83,11 @@ EAPI void elm_code_file_clear(Elm_Code_File *file);
EAPI unsigned int elm_code_file_lines_get(Elm_Code_File *file);
EAPI void elm_code_file_line_append(Elm_Code_File *file, const char *line);
EAPI void elm_code_file_line_append(Elm_Code_File *file, const char *line, int length);
EAPI Elm_Code_Line *elm_code_file_line_get(Elm_Code_File *file, unsigned int line);
EAPI char *elm_code_file_line_content_get(Elm_Code_File *file, unsigned int line);
EAPI const char *elm_code_file_line_content_get(Elm_Code_File *file, unsigned int line, int *length);
EAPI void elm_code_file_line_status_set(Elm_Code_File *file, unsigned int line, Elm_Code_Status_Type status);

View File

@ -52,7 +52,7 @@ EAPI void elm_code_widget_fill_line_tokens(Evas_Textgrid_Cell *cells, int count,
int start, length;
start = 1;
length = strlen(line->content);
length = line->length;
EINA_LIST_FOREACH(line->tokens, item, token)
{
@ -77,7 +77,7 @@ static void _elm_code_widget_fill_line(Evas_Object *o, Evas_Textgrid_Cell *cells
if (!_elm_code_widget_resize(o))
return;
length = strlen(line->content);
length = line->length;
evas_object_textgrid_size_get(o, &w, NULL);
cells[0].codepoint = status_icons[line->status];
@ -85,7 +85,10 @@ static void _elm_code_widget_fill_line(Evas_Object *o, Evas_Textgrid_Cell *cells
cells[0].fg = ELM_CODE_TOKEN_TYPE_DEFAULT;
cells[0].bg = line->status;
chr = (char *)line->content;
if (line->modified)
chr = line->modified;
else
chr = (char *)line->content;
for (x = 1; x < (unsigned int) w && x <= length; x++)
{
cells[x].codepoint = *chr;

View File

@ -52,6 +52,18 @@ START_TEST (elm_code_file_load_blank_lines)
}
END_TEST
static void _assert_line_content_eq(const char *content, Elm_Code_Line *line)
{
int length;
int c;
length = strlen(content);
ck_assert_int_eq(length, line->length);
for (c = 0; c < length; c++)
ck_assert_uint_eq(content[c], line->content[c]);
}
START_TEST (elm_code_file_load_content)
{
char *path = "elm_code/tests/testfile.txt";
@ -61,8 +73,8 @@ START_TEST (elm_code_file_load_content)
code = elm_code_create();
file = elm_code_file_open(code, path);
ck_assert_str_eq("line2", elm_code_file_line_content_get(file, 2));
ck_assert_str_eq("another line", elm_code_file_line_content_get(file, 4));
_assert_line_content_eq("line2", elm_code_file_line_get(file, 2));
_assert_line_content_eq("another line", elm_code_file_line_get(file, 4));
elm_code_file_close(file);
elm_code_free(code);
}

View File

@ -13,7 +13,7 @@ START_TEST (elm_code_file_memory_lines)
file = elm_code_file_new(code);
ck_assert_uint_eq(0, elm_code_file_lines_get(file));
elm_code_file_line_append(file, "a line");
elm_code_file_line_append(file, "a line", 6);
ck_assert_uint_eq(1, elm_code_file_lines_get(file));
elm_code_free(code);
@ -29,7 +29,7 @@ START_TEST (elm_code_file_memory_tokens)
code = elm_code_create();
file = elm_code_file_new(code);
elm_code_file_line_append(file, "a line");
elm_code_file_line_append(file, "a line", 6);
elm_code_file_line_token_add(file, 1, 2, 5, ELM_CODE_TOKEN_TYPE_COMMENT);
line = elm_code_file_line_get(file, 1);

View File

@ -29,7 +29,7 @@ START_TEST (elm_code_parse_hook_memory_test)
file = elm_code_file_new(code);
elm_code_parser_add(code, _parser_line_callback, _parser_file_callback);
elm_code_file_line_append(file, "some \"test content\" for parsing");
elm_code_file_line_append(file, "some \"test content\" for parsing", 31);
ck_assert_int_eq(1, line_calls);
ck_assert_int_eq(0, file_calls);

View File

@ -20,7 +20,7 @@ START_TEST (elm_code_widget_token_render_simple_test)
code = elm_code_create();
file = elm_code_file_new(code);
elm_code_file_line_append(file, "some \"test content\", 45");
elm_code_file_line_append(file, "some \"test content\", 45", 23);
line = elm_code_file_line_get(file, 1);
length = strlen(line->content);