< prev index next >

src/java.desktop/share/native/libfontmanager/harfbuzz/hb-blob.cc

Print this page

        

*** 487,500 **** # include <fcntl.h> #endif #if defined(_WIN32) || defined(__CYGWIN__) # include <windows.h> ! #endif ! ! #ifndef _O_BINARY # define _O_BINARY 0 #endif #ifndef MAP_NORESERVE # define MAP_NORESERVE 0 #endif --- 487,500 ---- # include <fcntl.h> #endif #if defined(_WIN32) || defined(__CYGWIN__) # include <windows.h> ! #else ! # ifndef _O_BINARY # define _O_BINARY 0 + # endif #endif #ifndef MAP_NORESERVE # define MAP_NORESERVE 0 #endif
*** 515,525 **** munmap (file->contents, file->length); #elif defined(_WIN32) || defined(__CYGWIN__) UnmapViewOfFile (file->contents); CloseHandle (file->mapping); #else ! free (file->contents); #endif free (file); } --- 515,525 ---- munmap (file->contents, file->length); #elif defined(_WIN32) || defined(__CYGWIN__) UnmapViewOfFile (file->contents); CloseHandle (file->mapping); #else ! assert (0); // If we don't have mmap we shouldn't reach here #endif free (file); }
*** 532,610 **** * Since: 1.7.7 **/ 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; 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 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, 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 ! 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); ! if (unlikely (file->mapping == nullptr)) goto fail; ! file->contents = (char *) MapViewOfFile (file->mapping, ! writable ? FILE_MAP_COPY : FILE_MAP_READ, ! 0, 0, 0); ! if (unlikely (file->contents == nullptr)) goto fail; ! #else ! mm = HB_MEMORY_MODE_WRITABLE; ! FILE *fd = fopen (file_name, "rb"); ! # define CLOSE fclose ! if (unlikely (!fd)) goto fail_without_close; ! fseek (fd, 0, SEEK_END); ! file->length = ftell (fd); ! rewind (fd); ! file->contents = (char *) malloc (file->length); ! if (unlikely (!file->contents)) goto fail; ! if (unlikely (fread (file->contents, 1, file->length, fd) != file->length)) ! goto fail; ! #endif ! CLOSE (fd); ! return hb_blob_create (file->contents, file->length, mm, (void *) file, (hb_destroy_func_t) _hb_mapped_file_destroy); fail: ! CLOSE (fd); ! #undef CLOSE fail_without_close: free (file); return hb_blob_get_empty (); } --- 532,636 ---- * Since: 1.7.7 **/ 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. */ ! #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 (); ! 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; file->length = (unsigned long) st.st_size; ! file->contents = (char *) mmap (nullptr, file->length, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, fd, 0); if (unlikely (file->contents == MAP_FAILED)) goto fail; ! 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, PAGE_READONLY, 0, 0, nullptr); ! if (unlikely (file->mapping == nullptr)) goto fail; ! file->contents = (char *) MapViewOfFile (file->mapping, FILE_MAP_READ, 0, 0, 0); ! if (unlikely (file->contents == nullptr)) goto fail; ! 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); fail: ! CloseHandle (fd); fail_without_close: free (file); + + #endif + + /* 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; + + len += addition; + } + + 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 (); }
< prev index next >