Index: samples/pdfium_test.cc |
diff --git a/samples/pdfium_test.cc b/samples/pdfium_test.cc |
index 19e8b7ee57a500b7a7fd463be476e20cecf847a7..61732d52b21f730d92584afffdb54f27d318acff 100644 |
--- a/samples/pdfium_test.cc |
+++ b/samples/pdfium_test.cc |
@@ -11,6 +11,7 @@ |
#include <list> |
#include <string> |
#include <utility> |
+#include <vector> |
#include "../fpdfsdk/include/fpdf_dataavail.h" |
#include "../fpdfsdk/include/fpdf_ext.h" |
@@ -21,7 +22,10 @@ |
#include "v8/include/v8.h" |
#ifdef _WIN32 |
- #define snprintf _snprintf |
+#define snprintf _snprintf |
+#define PATH_SEPARATOR '\\' |
+#else |
+#define PATH_SEPARATOR '/' |
#endif |
enum OutputFormat { |
@@ -33,6 +37,80 @@ enum OutputFormat { |
#endif |
}; |
+struct Options { |
+ Options() : output_format(OUTPUT_NONE) { } |
+ |
+ OutputFormat output_format; |
+ std::string exe_path; |
+ std::string bin_directory; |
+}; |
+ |
+// Reads the entire contents of a file into a newly malloc'd buffer. |
+static char* GetFileContents(const char* filename, size_t* retlen) { |
+ 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); |
+ if (!file_length) { |
+ return NULL; |
+ } |
+ (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 |
+// Returns the full path for an external V8 data file based on either |
+// the currect exectuable path or an explicit override. |
+static std::string GetFullPathForSnapshotFile(const Options& options, |
+ const std::string& filename) { |
+ std::string result; |
+ if (!options.bin_directory.empty()) { |
+ result = options.bin_directory; |
+ if (*options.bin_directory.rbegin() != PATH_SEPARATOR) { |
+ result += PATH_SEPARATOR; |
+ } |
+ } else if (!options.exe_path.empty()) { |
+ size_t last_separator = options.exe_path.rfind(PATH_SEPARATOR); |
+ if (last_separator != std::string::npos) { |
+ result = options.exe_path.substr(0, last_separator + 1); |
+ } |
+ } |
+ result += filename; |
+ return result; |
+} |
+ |
+// Reads an extenal V8 data file from the |options|-indicated location, |
+// returing true on success and false on error. |
+static bool GetExternalData(const Options& options, |
+ const std::string& bin_filename, |
+ v8::StartupData* result_data) { |
+ std::string full_path = GetFullPathForSnapshotFile(options, bin_filename); |
+ size_t data_length = 0; |
+ char* data_buffer = GetFileContents(full_path.c_str(), &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,34 +276,57 @@ 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, |
- std::list<const char*>* files) { |
- *output_format = OUTPUT_NONE; |
- files->clear(); |
- |
- int cur_arg = 1; |
- for (; cur_arg < argc; ++cur_arg) { |
- if (strcmp(argv[cur_arg], "--ppm") == 0) |
- *output_format = OUTPUT_PPM; |
+bool ParseCommandLine(const std::vector<std::string>& args, |
+ Options* options, std::list<std::string>* files) { |
+ if (args.empty()) { |
+ return false; |
+ } |
+ options->exe_path = args[0]; |
+ int cur_idx = 1; |
+ for (; cur_idx < args.size(); ++cur_idx) { |
+ const std::string& cur_arg = args[cur_idx]; |
+ if (cur_arg == "--ppm") { |
+ if (options->output_format != OUTPUT_NONE) { |
+ fprintf(stderr, "Duplicate or conflicting --ppm 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 (cur_arg == "--emf") { |
+ if (options->output_format != OUTPUT_NONE) { |
+ fprintf(stderr, "Duplicate or conflicting --emf argument\n"); |
+ return false; |
+ } |
+ options->output_format = OUTPUT_EMF; |
+ } |
+ else if (cur_arg == "--bmp") { |
+ if (options->output_format != OUTPUT_NONE) { |
+ fprintf(stderr, "Duplicate or conflicting --bmp argument\n"); |
+ return false; |
+ } |
+ options->output_format = OUTPUT_BMP; |
+ } |
+#endif // _WIN32 |
+#ifdef V8_USE_EXTERNAL_STARTUP_DATA |
+ else if (cur_arg.size() > 10 && cur_arg.compare(0, 10, "--bin-dir=") == 0) { |
+ if (!options->bin_directory.empty()) { |
+ fprintf(stderr, "Duplicate --bin-dir argument\n"); |
+ return false; |
+ } |
+ options->bin_directory = cur_arg.substr(10); |
+ } |
+#endif // V8_USE_EXTERNAL_STARTUP_DATA |
else |
break; |
} |
- |
- if (cur_arg > 2) // Multiple options. |
+ if (cur_idx >= args.size()) { |
+ fprintf(stderr, "No input files.\n"); |
return false; |
- |
- if (cur_arg >= argc) // No input files. |
- return false; |
- |
- for (int i = cur_arg; i < argc; i++) |
- files->push_back(argv[i]); |
- |
+ } |
+ for (int i = cur_idx; i < args.size(); i++) { |
+ files->push_back(args[i]); |
+ } |
return true; |
} |
@@ -256,9 +357,9 @@ bool Is_Data_Avail(FX_FILEAVAIL* pThis, size_t offset, size_t size) { |
void Add_Segment(FX_DOWNLOADHINTS* pThis, size_t offset, size_t size) { |
} |
-void RenderPdf(const char* name, const char* pBuf, size_t len, |
+void RenderPdf(const std::string& name, const char* pBuf, size_t len, |
OutputFormat format) { |
- printf("Rendering PDF file %s.\n", name); |
+ printf("Rendering PDF file %s.\n", name.c_str()); |
IPDF_JSPLATFORM platform_callbacks; |
memset(&platform_callbacks, '\0', sizeof(platform_callbacks)); |
@@ -350,15 +451,15 @@ void RenderPdf(const char* name, const char* pBuf, size_t len, |
switch (format) { |
#ifdef _WIN32 |
case OUTPUT_BMP: |
- WriteBmp(name, i, buffer, stride, width, height); |
+ WriteBmp(name.c_str(), i, buffer, stride, width, height); |
break; |
case OUTPUT_EMF: |
- WriteEmf(page, name, i); |
+ WriteEmf(page.c_str(), name, i); |
break; |
#endif |
case OUTPUT_PPM: |
- WritePpm(name, i, buffer, stride, width, height); |
+ WritePpm(name.c_str(), i, buffer, stride, width, height); |
break; |
default: |
break; |
@@ -382,19 +483,33 @@ 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; |
- std::list<const char*> files; |
- if (!ParseCommandLine(argc, argv, &format, &files)) { |
+ std::vector<std::string> args(argv, argv + argc); |
+ Options options; |
+ std::list<std::string> files; |
+ if (!ParseCommandLine(args, &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; |
@@ -405,25 +520,14 @@ int main(int argc, const char* argv[]) { |
FSDK_SetUnSpObjProcessHandler(&unsuppored_info); |
while (!files.empty()) { |
- const char* filename = files.front(); |
+ std::string 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.c_str(), &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(); |