diff options
author | Akira Kakuto <kakuto@fuk.kindai.ac.jp> | 2018-07-04 07:14:37 +0000 |
---|---|---|
committer | Akira Kakuto <kakuto@fuk.kindai.ac.jp> | 2018-07-04 07:14:37 +0000 |
commit | 9d5e239b66f12f75c7e0b7c869bbacd18429130d (patch) | |
tree | b6ec3a404dc034983673de93a837ec12650d63b5 /Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc | |
parent | d5588d938102254b0cf8345cdca07b6ca6dabb7d (diff) |
harfbuzz 1.8.2
git-svn-id: svn://tug.org/texlive/trunk@48132 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc')
-rw-r--r-- | Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc | 124 |
1 files changed, 75 insertions, 49 deletions
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc index c138648ca7b..98e9c65c23d 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc @@ -489,10 +489,10 @@ hb_blob_t::try_make_writable (void) #if defined(_WIN32) || defined(__CYGWIN__) # include <windows.h> -#endif - -#ifndef _O_BINARY -# define _O_BINARY 0 +#else +# ifndef _O_BINARY +# define _O_BINARY 0 +# endif #endif #ifndef MAP_NORESERVE @@ -517,7 +517,7 @@ _hb_mapped_file_destroy (hb_mapped_file_t *file) UnmapViewOfFile (file->contents); CloseHandle (file->mapping); #else - free (file->contents); + assert (0); // If we don't have mmap we shouldn't reach here #endif free (file); @@ -534,77 +534,103 @@ _hb_mapped_file_destroy (hb_mapped_file_t *file) hb_blob_t * hb_blob_create_from_file (const char *file_name) { - // Adopted from glib's gmappedfile.c with Matthias Clasen and - // Allison Lortie permission but changed a lot to suit our need. - bool writable = false; - hb_memory_mode_t mm = HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE; + /* Adopted from glib's gmappedfile.c with Matthias Clasen and + Allison Lortie permission but changed a lot to suit our need. */ +#if defined(HAVE_MMAP) && !defined(HB_NO_MMAP) hb_mapped_file_t *file = (hb_mapped_file_t *) calloc (1, sizeof (hb_mapped_file_t)); if (unlikely (!file)) return hb_blob_get_empty (); -#ifdef HAVE_MMAP - int fd = open (file_name, (writable ? O_RDWR : O_RDONLY) | _O_BINARY, 0); -# define CLOSE close + int fd = open (file_name, O_RDONLY | _O_BINARY, 0); if (unlikely (fd == -1)) goto fail_without_close; struct stat st; if (unlikely (fstat (fd, &st) == -1)) goto fail; - // See https://github.com/GNOME/glib/blob/f9faac7/glib/gmappedfile.c#L139-L142 - if (unlikely (st.st_size == 0 && S_ISREG (st.st_mode))) goto fail; - file->length = (unsigned long) st.st_size; - file->contents = (char *) mmap (nullptr, file->length, - writable ? PROT_READ|PROT_WRITE : PROT_READ, + file->contents = (char *) mmap (nullptr, file->length, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, fd, 0); if (unlikely (file->contents == MAP_FAILED)) goto fail; -#elif defined(_WIN32) || defined(__CYGWIN__) - HANDLE fd = CreateFile (file_name, - writable ? GENERIC_READ|GENERIC_WRITE : GENERIC_READ, - FILE_SHARE_READ, nullptr, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, nullptr); -# define CLOSE CloseHandle + close (fd); + + return hb_blob_create (file->contents, file->length, + HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE, (void *) file, + (hb_destroy_func_t) _hb_mapped_file_destroy); + +fail: + close (fd); +fail_without_close: + free (file); + +#elif (defined(_WIN32) || defined(__CYGWIN__)) && !defined(HB_NO_MMAP) + hb_mapped_file_t *file = (hb_mapped_file_t *) calloc (1, sizeof (hb_mapped_file_t)); + if (unlikely (!file)) return hb_blob_get_empty (); + + HANDLE fd = CreateFile (file_name, GENERIC_READ, FILE_SHARE_READ, nullptr, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, + nullptr); if (unlikely (fd == INVALID_HANDLE_VALUE)) goto fail_without_close; file->length = (unsigned long) GetFileSize (fd, nullptr); - file->mapping = CreateFileMapping (fd, nullptr, - writable ? PAGE_WRITECOPY : PAGE_READONLY, - 0, 0, nullptr); + file->mapping = CreateFileMapping (fd, nullptr, PAGE_READONLY, 0, 0, nullptr); if (unlikely (file->mapping == nullptr)) goto fail; - file->contents = (char *) MapViewOfFile (file->mapping, - writable ? FILE_MAP_COPY : FILE_MAP_READ, - 0, 0, 0); + file->contents = (char *) MapViewOfFile (file->mapping, FILE_MAP_READ, 0, 0, 0); if (unlikely (file->contents == nullptr)) goto fail; -#else - mm = HB_MEMORY_MODE_WRITABLE; + CloseHandle (fd); + return hb_blob_create (file->contents, file->length, + HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE, (void *) file, + (hb_destroy_func_t) _hb_mapped_file_destroy); - FILE *fd = fopen (file_name, "rb"); -# define CLOSE fclose - if (unlikely (!fd)) goto fail_without_close; +fail: + CloseHandle (fd); +fail_without_close: + free (file); - fseek (fd, 0, SEEK_END); - file->length = ftell (fd); - rewind (fd); - file->contents = (char *) malloc (file->length); - if (unlikely (!file->contents)) goto fail; +#endif - if (unlikely (fread (file->contents, 1, file->length, fd) != file->length)) - goto fail; + /* The following tries to read a file without knowing its size beforehand + It's used as a fallback for systems without mmap or to read from pipes */ + unsigned long len = 0, allocated = BUFSIZ * 16; + char *data = (char *) malloc (allocated); + if (unlikely (data == nullptr)) return hb_blob_get_empty (); + + FILE *fp = fopen (file_name, "rb"); + if (unlikely (fp == nullptr)) goto fread_fail_without_close; + + while (!feof (fp)) + { + if (allocated - len < BUFSIZ) + { + allocated *= 2; + /* Don't allocate and go more than ~536MB, our mmap reader still + can cover files like that but lets limit our fallback reader */ + if (unlikely (allocated > (2 << 28))) goto fread_fail; + char *new_data = (char *) realloc (data, allocated); + if (unlikely (new_data == nullptr)) goto fread_fail; + data = new_data; + } + unsigned long addition = fread (data + len, 1, allocated - len, fp); + + int err = ferror (fp); +#ifdef EINTR // armcc doesn't have it + if (unlikely (err == EINTR)) continue; #endif + if (unlikely (err)) goto fread_fail; - CLOSE (fd); - return hb_blob_create (file->contents, file->length, mm, (void *) file, - (hb_destroy_func_t) _hb_mapped_file_destroy); + len += addition; + } -fail: - CLOSE (fd); -#undef CLOSE -fail_without_close: - free (file); + return hb_blob_create (data, len, HB_MEMORY_MODE_WRITABLE, data, + (hb_destroy_func_t) free); + +fread_fail: + fclose (fp); +fread_fail_without_close: + free (data); return hb_blob_get_empty (); } |