Chromium Code Reviews| Index: samples/pdfium_test.cc |
| diff --git a/samples/pdfium_test.cc b/samples/pdfium_test.cc |
| index 19e8b7ee57a500b7a7fd463be476e20cecf847a7..122de6a8cd85aa5271e8204c3b7d6c5e0fd96ce5 100644 |
| --- a/samples/pdfium_test.cc |
| +++ b/samples/pdfium_test.cc |
| @@ -21,7 +21,10 @@ |
| #include "v8/include/v8.h" |
| #ifdef _WIN32 |
| - #define snprintf _snprintf |
| +#define snprintf _snprintf |
| +#define SEPARATOR '\\' |
|
Lei Zhang
2014/12/17 22:35:50
Maybe PATH_SEPARATOR?
Tom Sepez
2014/12/17 23:52:59
Done.
|
| +#else |
| +#define SEPARATOR '/' |
| #endif |
| enum OutputFormat { |
| @@ -33,6 +36,104 @@ enum OutputFormat { |
| #endif |
| }; |
| +struct Options { |
| + OutputFormat output_format; |
| + const char* exe_path; |
| + const char* bin_directory; |
| +}; |
| + |
| +static char* GetFileContents(const char* filename, size_t* retlen) { |
|
Lei Zhang
2014/12/17 22:35:51
It would be nice to document the functions.
Tom Sepez
2014/12/17 23:52:59
Done.
|
| + FILE* file = fopen(filename, "rb"); |
| + if (!file) { |
| + fprintf(stderr, "Failed to open: %s\n", filename); |
| + return NULL; |
| + } |
| + (void) fseek(file, 0, SEEK_END); |
| + size_t file_length = ftell(file); |
|
Lei Zhang
2014/12/17 22:35:50
Can we get 0 here? If so, don't bother mallocing?
Tom Sepez
2014/12/17 23:52:59
Done.
|
| + (void) fseek(file, 0, SEEK_SET); |
| + char* buffer = (char*) malloc(file_length); |
| + if (!buffer) { |
| + return NULL; |
| + } |
| + size_t bytes_read = fread(buffer, 1, file_length, file); |
| + (void) fclose(file); |
| + if (bytes_read != file_length) { |
| + fprintf(stderr, "Failed to read: %s\n", filename); |
| + free(buffer); |
| + return NULL; |
| + } |
| + *retlen = bytes_read; |
| + return buffer; |
| +} |
| + |
| +#ifdef V8_USE_EXTERNAL_STARTUP_DATA |
| +static bool GetFullPathForSnapshotFile(const Options& options, |
| + const char* filename, |
| + char* output_buffer, |
|
Lei Zhang
2014/12/17 22:35:51
|output_buffer| and |output_buffer_size| -> a sing
Tom Sepez
2014/12/17 23:52:59
I think I'm going to replace this whole mess with
Lei Zhang
2014/12/18 00:07:01
Oh, so much nicer. :)
|
| + size_t output_buffer_size) { |
| + char* insertion_point = output_buffer; |
| + size_t space_remaining = output_buffer_size; |
| + if (options.bin_directory) { |
| + size_t bin_directory_len = strlen(options.bin_directory); |
| + if (bin_directory_len > space_remaining) { |
| + return false; |
| + } |
| + if (bin_directory_len) { |
| + memcpy(output_buffer, options.bin_directory, bin_directory_len); |
| + insertion_point += bin_directory_len; |
| + space_remaining -= bin_directory_len; |
| + if (*(insertion_point - 1) != SEPARATOR) { |
| + if (space_remaining == 0) { |
| + return false; |
| + } |
| + *insertion_point = SEPARATOR; |
| + insertion_point += 1; |
| + space_remaining -= 1; |
| + } |
| + } |
| + } else if (options.exe_path) { |
| + const char* last_separator = strrchr(options.exe_path, SEPARATOR); |
| + if (last_separator) { |
| + size_t exe_path_len = 1 + last_separator - options.exe_path; |
| + if (exe_path_len > space_remaining) { |
| + return false; |
| + } |
| + memcpy(output_buffer, options.exe_path, exe_path_len); |
| + insertion_point += exe_path_len; |
| + space_remaining -= exe_path_len; |
| + } |
| + } |
| + size_t filename_len = strlen(filename); |
| + if (filename_len + 1 > space_remaining) { |
| + return false; |
| + } |
| + memcpy(insertion_point, filename, filename_len); |
| + insertion_point += filename_len; |
| + space_remaining -= filename_len; |
| + *insertion_point = '\0'; |
| + return true; |
| +} |
| + |
| +static bool GetExternalData(const Options& options, |
| + const char *bin_filename, |
|
Lei Zhang
2014/12/17 22:35:51
nit: char*, ditto below.
|
| + v8::StartupData* result_data) { |
| + char full_path[4096]; |
|
Lei Zhang
2014/12/17 22:35:51
4096 -> PATH_MAX ?
Tom Sepez
2014/12/17 23:52:59
Present on windows?
|
| + if (!GetFullPathForSnapshotFile(options, bin_filename, |
| + full_path, sizeof(full_path))) { |
| + fprintf(stderr, "GetFullPathForSnapshotFile() failed\n"); |
| + return false; |
| + } |
| + size_t data_length = 0; |
| + char *data_buffer = GetFileContents(full_path, &data_length); |
| + if (!data_buffer) { |
| + return false; |
| + } |
| + result_data->data = const_cast<const char*>(data_buffer); |
| + result_data->raw_size = data_length; |
| + return true; |
| +} |
| +#endif // V8_USE_EXTERNAL_STARTUP_DATA |
| + |
| static void WritePpm(const char* pdf_name, int num, const void* buffer_void, |
| int stride, int width, int height) { |
| const char* buffer = reinterpret_cast<const char*>(buffer_void); |
| @@ -198,32 +299,62 @@ void Unsupported_Handler(UNSUPPORT_INFO*, int type) { |
| printf("Unsupported feature: %s.\n", feature.c_str()); |
| } |
| -bool ParseCommandLine(int argc, const char* argv[], OutputFormat* output_format, |
| +bool ParseCommandLine(int argc, const char* argv[], Options* options, |
| std::list<const char*>* files) { |
| - *output_format = OUTPUT_NONE; |
| + options->output_format = OUTPUT_NONE; |
|
Lei Zhang
2014/12/17 22:35:50
Options probably should have a constructor to do t
Tom Sepez
2014/12/17 23:52:59
D'oh. Done.
|
| + options->exe_path = NULL; |
| + options->bin_directory = NULL; |
| files->clear(); |
| - |
| - int cur_arg = 1; |
| - for (; cur_arg < argc; ++cur_arg) { |
| - if (strcmp(argv[cur_arg], "--ppm") == 0) |
| - *output_format = OUTPUT_PPM; |
| + if (!argc) { |
| + return false; |
| + } |
| + options->exe_path = argv[0]; |
| + int cur_idx = 1; |
| + for (; cur_idx < argc; ++cur_idx) { |
| + const char* cur_arg = argv[cur_idx]; |
| + size_t arg_length = strlen(cur_arg); |
| + if (strcmp(cur_arg, "--ppm") == 0) { |
| + if (options->output_format != OUTPUT_NONE) { |
| + fprintf(stderr, "Duplicate format argument\n"); |
| + return false; |
| + } |
| + options->output_format = OUTPUT_PPM; |
| + } |
| #ifdef _WIN32 |
| - else if (strcmp(argv[cur_arg], "--emf") == 0) |
| - *output_format = OUTPUT_EMF; |
| - else if (strcmp(argv[cur_arg], "--bmp") == 0) |
| - *output_format = OUTPUT_BMP; |
| -#endif |
| + else if (strcmp(cur_arg, "--emf") == 0) { |
| + if (options->output_format != OUTPUT_NONE) { |
| + fprintf(stderr, "Duplicate format argument\n"); |
| + return false; |
| + } |
| + options->output_format = OUTPUT_EMF; |
| + } |
| + else if (strcmp(cur_arg, "--bmp") == 0) { |
| + if (options->output_format != OUTPUT_NONE) { |
| + fprintf(stderr, "Duplicate format argument\n"); |
| + return false; |
| + } |
| + options->output_format = OUTPUT_BMP; |
| + } |
| +#endif // _WIN32 |
| +#ifdef V8_USE_EXTERNAL_STARTUP_DATA |
| + else if (arg_length > 10 && memcmp(cur_arg, "--bin-dir=", 10) == 0) { |
| + if (options->bin_directory) { |
| + fprintf(stderr, "Duplicate --bin-dir argument\n"); |
| + return false; |
| + } |
| + options->bin_directory = cur_arg + 10; |
| + } |
| +#endif // V8_USE_EXTERNAL_STARTUP_DATA |
| else |
| break; |
| } |
| - if (cur_arg > 2) // Multiple options. |
| - return false; |
| - |
| - if (cur_arg >= argc) // No input files. |
| + if (cur_idx >= argc) { |
| + fprintf(stderr, "No input files.\n"); |
| return false; |
| + } |
| - for (int i = cur_arg; i < argc; i++) |
| + for (int i = cur_idx; i < argc; i++) |
| files->push_back(argv[i]); |
| return true; |
| @@ -382,19 +513,32 @@ void RenderPdf(const char* name, const char* pBuf, size_t len, |
| } |
| int main(int argc, const char* argv[]) { |
| - v8::V8::InitializeICU(); |
| - OutputFormat format = OUTPUT_NONE; |
| + Options options; |
| std::list<const char*> files; |
| - if (!ParseCommandLine(argc, argv, &format, &files)) { |
| + if (!ParseCommandLine(argc, argv, &options, &files)) { |
| printf("Usage: pdfium_test [OPTION] [FILE]...\n"); |
| - printf("--ppm write page images <pdf-name>.<page-number>.ppm\n"); |
| + printf("--bin-dir=<path> - override path to v8 external data\n"); |
| + printf("--ppm - write page images <pdf-name>.<page-number>.ppm\n"); |
| #ifdef _WIN32 |
| - printf("--bmp write page images <pdf-name>.<page-number>.bmp\n"); |
| - printf("--emf write page meta files <pdf-name>.<page-number>.emf\n"); |
| + printf("--bmp - write page images <pdf-name>.<page-number>.bmp\n"); |
| + printf("--emf - write page meta files <pdf-name>.<page-number>.emf\n"); |
| #endif |
| return 1; |
| } |
| + v8::V8::InitializeICU(); |
| + |
| +#ifdef V8_USE_EXTERNAL_STARTUP_DATA |
| + v8::StartupData natives; |
| + v8::StartupData snapshot; |
| + if (!GetExternalData(options, "natives_blob.bin", &natives) || |
| + !GetExternalData(options, "snapshot_blob.bin", &snapshot)) { |
| + return 1; |
| + } |
| + v8::V8::SetNativesDataBlob(&natives); |
| + v8::V8::SetSnapshotDataBlob(&snapshot); |
| +#endif // V8_USE_EXTERNAL_STARTUP_DATA |
| + |
| FPDF_InitLibrary(); |
| UNSUPPORT_INFO unsuppored_info; |
| @@ -407,23 +551,12 @@ int main(int argc, const char* argv[]) { |
| while (!files.empty()) { |
| const char* filename = files.front(); |
| files.pop_front(); |
| - FILE* file = fopen(filename, "rb"); |
| - if (!file) { |
| - fprintf(stderr, "Failed to open: %s\n", filename); |
| + size_t file_length = 0; |
| + char *file_contents = GetFileContents(filename, &file_length); |
| + if (!file_contents) |
| continue; |
| - } |
| - (void) fseek(file, 0, SEEK_END); |
| - size_t len = ftell(file); |
| - (void) fseek(file, 0, SEEK_SET); |
| - char* pBuf = (char*) malloc(len); |
| - size_t ret = fread(pBuf, 1, len, file); |
| - (void) fclose(file); |
| - if (ret != len) { |
| - fprintf(stderr, "Failed to read: %s\n", filename); |
| - } else { |
| - RenderPdf(filename, pBuf, len, format); |
| - } |
| - free(pBuf); |
| + RenderPdf(filename, file_contents, file_length, options.output_format); |
| + free(file_contents); |
| } |
| FPDF_DestroyLibrary(); |