< prev index next >

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

Print this page




 472   this->mode = HB_MEMORY_MODE_WRITABLE;
 473   this->data = new_data;
 474   this->user_data = new_data;
 475   this->destroy = free;
 476 
 477   return true;
 478 }
 479 
 480 /*
 481  * Mmap
 482  */
 483 
 484 #ifdef HAVE_MMAP
 485 # include <sys/types.h>
 486 # include <sys/stat.h>
 487 # include <fcntl.h>
 488 #endif
 489 
 490 #if defined(_WIN32) || defined(__CYGWIN__)
 491 # include <windows.h>
 492 #endif
 493 
 494 #ifndef _O_BINARY
 495 # define _O_BINARY 0

 496 #endif
 497 
 498 #ifndef MAP_NORESERVE
 499 # define MAP_NORESERVE 0
 500 #endif
 501 
 502 struct hb_mapped_file_t
 503 {
 504   char *contents;
 505   unsigned long length;
 506 #if defined(_WIN32) || defined(__CYGWIN__)
 507   HANDLE mapping;
 508 #endif
 509 };
 510 
 511 static void
 512 _hb_mapped_file_destroy (hb_mapped_file_t *file)
 513 {
 514 #ifdef HAVE_MMAP
 515   munmap (file->contents, file->length);
 516 #elif defined(_WIN32) || defined(__CYGWIN__)
 517   UnmapViewOfFile (file->contents);
 518   CloseHandle (file->mapping);
 519 #else
 520   free (file->contents);
 521 #endif
 522 
 523   free (file);
 524 }
 525 
 526 /**
 527  * hb_blob_create_from_file:
 528  * @file_name: font filename.
 529  *
 530  * Returns: A hb_blob_t pointer with the content of the file
 531  *
 532  * Since: 1.7.7
 533  **/
 534 hb_blob_t *
 535 hb_blob_create_from_file (const char *file_name)
 536 {
 537   // Adopted from glib's gmappedfile.c with Matthias Clasen and
 538   // Allison Lortie permission but changed a lot to suit our need.
 539   bool writable = false;
 540   hb_memory_mode_t mm = HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE;
 541   hb_mapped_file_t *file = (hb_mapped_file_t *) calloc (1, sizeof (hb_mapped_file_t));
 542   if (unlikely (!file)) return hb_blob_get_empty ();
 543 
 544 #ifdef HAVE_MMAP
 545   int fd = open (file_name, (writable ? O_RDWR : O_RDONLY) | _O_BINARY, 0);
 546 # define CLOSE close
 547   if (unlikely (fd == -1)) goto fail_without_close;
 548 
 549   struct stat st;
 550   if (unlikely (fstat (fd, &st) == -1)) goto fail;
 551 
 552   // See https://github.com/GNOME/glib/blob/f9faac7/glib/gmappedfile.c#L139-L142
 553   if (unlikely (st.st_size == 0 && S_ISREG (st.st_mode))) goto fail;
 554 
 555   file->length = (unsigned long) st.st_size;
 556   file->contents = (char *) mmap (nullptr, file->length,
 557                                   writable ? PROT_READ|PROT_WRITE : PROT_READ,
 558                                   MAP_PRIVATE | MAP_NORESERVE, fd, 0);
 559 
 560   if (unlikely (file->contents == MAP_FAILED)) goto fail;
 561 
 562 #elif defined(_WIN32) || defined(__CYGWIN__)
 563   HANDLE fd = CreateFile (file_name,
 564                           writable ? GENERIC_READ|GENERIC_WRITE : GENERIC_READ,
 565                           FILE_SHARE_READ, nullptr, OPEN_EXISTING,
 566                           FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, nullptr);
 567 # define CLOSE CloseHandle
 568 
 569   if (unlikely (fd == INVALID_HANDLE_VALUE)) goto fail_without_close;
 570 
 571   file->length = (unsigned long) GetFileSize (fd, nullptr);
 572   file->mapping = CreateFileMapping (fd, nullptr,
 573                                      writable ? PAGE_WRITECOPY : PAGE_READONLY,
 574                                      0, 0, nullptr);
 575   if (unlikely (file->mapping == nullptr)) goto fail;
 576 
 577   file->contents = (char *) MapViewOfFile (file->mapping,
 578                                            writable ? FILE_MAP_COPY : FILE_MAP_READ,
 579                                            0, 0, 0);
 580   if (unlikely (file->contents == nullptr)) goto fail;
 581 
 582 #else
 583   mm = HB_MEMORY_MODE_WRITABLE;

 584 
 585   FILE *fd = fopen (file_name, "rb");
 586 # define CLOSE fclose
 587   if (unlikely (!fd)) goto fail_without_close;
 588 
 589   fseek (fd, 0, SEEK_END);
 590   file->length = ftell (fd);
 591   rewind (fd);
 592   file->contents = (char *) malloc (file->length);
 593   if (unlikely (!file->contents)) goto fail;
 594 
 595   if (unlikely (fread (file->contents, 1, file->length, fd) != file->length))
 596     goto fail;

 597 
 598 #endif

 599 
 600   CLOSE (fd);
 601   return hb_blob_create (file->contents, file->length, mm, (void *) file,

 602                          (hb_destroy_func_t) _hb_mapped_file_destroy);
 603 
 604 fail:
 605   CLOSE (fd);
 606 #undef CLOSE
 607 fail_without_close:
 608   free (file);











































 609   return hb_blob_get_empty ();
 610 }


 472   this->mode = HB_MEMORY_MODE_WRITABLE;
 473   this->data = new_data;
 474   this->user_data = new_data;
 475   this->destroy = free;
 476 
 477   return true;
 478 }
 479 
 480 /*
 481  * Mmap
 482  */
 483 
 484 #ifdef HAVE_MMAP
 485 # include <sys/types.h>
 486 # include <sys/stat.h>
 487 # include <fcntl.h>
 488 #endif
 489 
 490 #if defined(_WIN32) || defined(__CYGWIN__)
 491 # include <windows.h>
 492 #else
 493 # ifndef _O_BINARY

 494 #  define _O_BINARY 0
 495 # endif
 496 #endif
 497 
 498 #ifndef MAP_NORESERVE
 499 # define MAP_NORESERVE 0
 500 #endif
 501 
 502 struct hb_mapped_file_t
 503 {
 504   char *contents;
 505   unsigned long length;
 506 #if defined(_WIN32) || defined(__CYGWIN__)
 507   HANDLE mapping;
 508 #endif
 509 };
 510 
 511 static void
 512 _hb_mapped_file_destroy (hb_mapped_file_t *file)
 513 {
 514 #ifdef HAVE_MMAP
 515   munmap (file->contents, file->length);
 516 #elif defined(_WIN32) || defined(__CYGWIN__)
 517   UnmapViewOfFile (file->contents);
 518   CloseHandle (file->mapping);
 519 #else
 520   assert (0); // If we don't have mmap we shouldn't reach here
 521 #endif
 522 
 523   free (file);
 524 }
 525 
 526 /**
 527  * hb_blob_create_from_file:
 528  * @file_name: font filename.
 529  *
 530  * Returns: A hb_blob_t pointer with the content of the file
 531  *
 532  * Since: 1.7.7
 533  **/
 534 hb_blob_t *
 535 hb_blob_create_from_file (const char *file_name)
 536 {
 537   /* Adopted from glib's gmappedfile.c with Matthias Clasen and
 538      Allison Lortie permission but changed a lot to suit our need. */
 539 #if defined(HAVE_MMAP) && !defined(HB_NO_MMAP)

 540   hb_mapped_file_t *file = (hb_mapped_file_t *) calloc (1, sizeof (hb_mapped_file_t));
 541   if (unlikely (!file)) return hb_blob_get_empty ();
 542 
 543   int fd = open (file_name, O_RDONLY | _O_BINARY, 0);


 544   if (unlikely (fd == -1)) goto fail_without_close;
 545 
 546   struct stat st;
 547   if (unlikely (fstat (fd, &st) == -1)) goto fail;
 548 



 549   file->length = (unsigned long) st.st_size;
 550   file->contents = (char *) mmap (nullptr, file->length, PROT_READ,

 551                                   MAP_PRIVATE | MAP_NORESERVE, fd, 0);
 552 
 553   if (unlikely (file->contents == MAP_FAILED)) goto fail;
 554 
 555   close (fd);





 556 
 557   return hb_blob_create (file->contents, file->length,
 558                          HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE, (void *) file,
 559                          (hb_destroy_func_t) _hb_mapped_file_destroy);




 560 
 561 fail:
 562   close (fd);
 563 fail_without_close:
 564   free (file);
 565 
 566 #elif (defined(_WIN32) || defined(__CYGWIN__)) && !defined(HB_NO_MMAP)
 567   hb_mapped_file_t *file = (hb_mapped_file_t *) calloc (1, sizeof (hb_mapped_file_t));
 568   if (unlikely (!file)) return hb_blob_get_empty ();
 569 
 570   HANDLE fd = CreateFile (file_name, GENERIC_READ, FILE_SHARE_READ, nullptr,
 571                           OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,
 572                           nullptr);
 573 
 574   if (unlikely (fd == INVALID_HANDLE_VALUE)) goto fail_without_close;




 575 
 576   file->length = (unsigned long) GetFileSize (fd, nullptr);
 577   file->mapping = CreateFileMapping (fd, nullptr, PAGE_READONLY, 0, 0, nullptr);
 578   if (unlikely (file->mapping == nullptr)) goto fail;
 579 
 580   file->contents = (char *) MapViewOfFile (file->mapping, FILE_MAP_READ, 0, 0, 0);
 581   if (unlikely (file->contents == nullptr)) goto fail;
 582 
 583   CloseHandle (fd);
 584   return hb_blob_create (file->contents, file->length,
 585                          HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE, (void *) file,
 586                          (hb_destroy_func_t) _hb_mapped_file_destroy);
 587 
 588 fail:
 589   CloseHandle (fd);

 590 fail_without_close:
 591   free (file);
 592 
 593 #endif
 594 
 595   /* The following tries to read a file without knowing its size beforehand
 596      It's used as a fallback for systems without mmap or to read from pipes */
 597   unsigned long len = 0, allocated = BUFSIZ * 16;
 598   char *data = (char *) malloc (allocated);
 599   if (unlikely (data == nullptr)) return hb_blob_get_empty ();
 600 
 601   FILE *fp = fopen (file_name, "rb");
 602   if (unlikely (fp == nullptr)) goto fread_fail_without_close;
 603 
 604   while (!feof (fp))
 605   {
 606     if (allocated - len < BUFSIZ)
 607     {
 608       allocated *= 2;
 609       /* Don't allocate and go more than ~536MB, our mmap reader still
 610          can cover files like that but lets limit our fallback reader */
 611       if (unlikely (allocated > (2 << 28))) goto fread_fail;
 612       char *new_data = (char *) realloc (data, allocated);
 613       if (unlikely (new_data == nullptr)) goto fread_fail;
 614       data = new_data;
 615     }
 616 
 617     unsigned long addition = fread (data + len, 1, allocated - len, fp);
 618 
 619     int err = ferror (fp);
 620 #ifdef EINTR // armcc doesn't have it
 621     if (unlikely (err == EINTR)) continue;
 622 #endif
 623     if (unlikely (err)) goto fread_fail;
 624 
 625     len += addition;
 626   }
 627 
 628   return hb_blob_create (data, len, HB_MEMORY_MODE_WRITABLE, data,
 629                          (hb_destroy_func_t) free);
 630 
 631 fread_fail:
 632   fclose (fp);
 633 fread_fail_without_close:
 634   free (data);
 635   return hb_blob_get_empty ();
 636 }
< prev index next >