diff --git a/legacy/eina/ChangeLog b/legacy/eina/ChangeLog index 22d070ffd2..db8b643790 100644 --- a/legacy/eina/ChangeLog +++ b/legacy/eina/ChangeLog @@ -303,3 +303,10 @@ passthrough to malloc for debgging purposes and memory footrpint comparisons at runtime. +2012-07-01 Vincent Torri + + * remove --enable-coverage from configure options, + +2012-07-04 Vincent Torri + + * implement eina_file_map_lines() on Windows diff --git a/legacy/eina/NEWS b/legacy/eina/NEWS index f53279e662..a5360b1909 100644 --- a/legacy/eina/NEWS +++ b/legacy/eina/NEWS @@ -15,6 +15,11 @@ Fixes: * Portability issue with Eina_Value test suite when unsigned where not promoted to unsigned long (case on Itanium). * Fix issue in the XML parser when a tag was in a comment or a CDATA. + * Implement eina_file_map_lines() on Windows + +Removal: + * configure options: --disable-posix-threads, --disable-win32-threads, + --enable-coverage Eina 1.2.0 diff --git a/legacy/eina/src/lib/eina_file_win32.c b/legacy/eina/src/lib/eina_file_win32.c index 2baa29fb45..f507bf9467 100644 --- a/legacy/eina/src/lib/eina_file_win32.c +++ b/legacy/eina/src/lib/eina_file_win32.c @@ -91,6 +91,7 @@ void *alloca (size_t); #define MAP_FAILED ((void *)-1) typedef struct _Eina_File_Iterator Eina_File_Iterator; +typedef struct _Eina_Lines_Iterator Eina_Lines_Iterator; typedef struct _Eina_File_Direct_Iterator Eina_File_Direct_Iterator; typedef struct _Eina_File_Map Eina_File_Map; @@ -106,6 +107,19 @@ struct _Eina_File_Iterator char dir[1]; }; +struct _Eina_Lines_Iterator +{ + Eina_Iterator iterator; + + Eina_File *fp; + const char *map; + const char *end; + + int boundary; + + Eina_File_Lines current; +}; + struct _Eina_File_Direct_Iterator { Eina_Iterator iterator; @@ -561,6 +575,90 @@ _eina_file_win32_escape(const char *path, size_t *length) return result; } +/* search '\r' and '\n' by preserving cache locality and page locality + in doing a search inside 4K boundary. + */ +static inline const char * +_eina_fine_eol(const char *start, int boundary, const char *end) +{ + const char *cr; + const char *lf; + unsigned long long chunk; + + while (start < end) + { + chunk = start + boundary < end ? boundary : end - start; + cr = memchr(start, '\r', chunk); + lf = memchr(start, '\n', chunk); + if (cr) + { + if (lf && lf < cr) + return lf + 1; + return cr + 1; + } + else if (lf) + return lf + 1; + + start += chunk; + boundary = 4096; + } + + return end; +} + +static Eina_Bool +_eina_file_map_lines_iterator_next(Eina_Lines_Iterator *it, void **data) +{ + const char *eol; + unsigned char match; + + if (it->current.line.end >= it->end) + return EINA_FALSE; + + match = *it->current.line.end; + while ((*it->current.line.end == '\n' || *it->current.line.end == '\r') + && it->current.line.end < it->end) + { + if (match == *it->current.line.end) + it->current.line.index++; + it->current.line.end++; + } + it->current.line.index++; + + if (it->current.line.end == it->end) + return EINA_FALSE; + + eol = _eina_fine_eol(it->current.line.end, + it->boundary, + it->end); + it->boundary = (uintptr_t) eol & 0x3FF; + if (it->boundary == 0) it->boundary = 4096; + + it->current.line.start = it->current.line.end; + + it->current.line.end = eol; + it->current.length = eol - it->current.line.start - 1; + + *data = &it->current; + return EINA_TRUE; +} + +static Eina_File * +_eina_file_map_lines_iterator_container(Eina_Lines_Iterator *it) +{ + return it->fp; +} + +static void +_eina_file_map_lines_iterator_free(Eina_Lines_Iterator *it) +{ + eina_file_map_free(it->fp, (void*) it->map); + eina_file_close(it->fp); + + EINA_MAGIC_SET(&it->iterator, 0); + free(it); +} + /** * @endcond @@ -1062,6 +1160,47 @@ eina_file_map_all(Eina_File *file, Eina_File_Populate rule __UNUSED__) return NULL; } +EAPI Eina_Iterator * +eina_file_map_lines(Eina_File *file) +{ + Eina_Lines_Iterator *it; + + EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL); + + if (file->length == 0) return NULL; + + it = calloc(1, sizeof (Eina_Lines_Iterator)); + if (!it) return NULL; + + EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); + + it->map = eina_file_map_all(file, EINA_FILE_SEQUENTIAL); + if (!it->map) + { + free(it); + return NULL; + } + + eina_lock_take(&file->lock); + file->refcount++; + eina_lock_release(&file->lock); + + it->fp = file; + it->boundary = 4096; + it->current.line.start = it->map; + it->current.line.end = it->current.line.start; + it->current.line.index = 0; + it->current.length = 0; + it->end = it->map + it->fp->length; + + it->iterator.version = EINA_ITERATOR_VERSION; + it->iterator.next = FUNC_ITERATOR_NEXT(_eina_file_map_lines_iterator_next); + it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_eina_file_map_lines_iterator_container); + it->iterator.free = FUNC_ITERATOR_FREE(_eina_file_map_lines_iterator_free); + + return &it->iterator; +} + EAPI void * eina_file_map_new(Eina_File *file, Eina_File_Populate rule, unsigned long int offset, unsigned long int length)