static void ParseCommandLine(WCHAR *cmdLine) { WStrVec argList; ParseCmdLine(cmdLine, argList); #define is_arg(param) str::EqI(arg + 1, TEXT(param)) #define is_arg_with_param(param) (is_arg(param) && i < argList.Count() - 1) // skip the first arg (exe path) for (size_t i = 1; i < argList.Count(); i++) { WCHAR *arg = argList.At(i); if ('-' != *arg && '/' != *arg) continue; if (is_arg("s")) gGlobalData.silent = true; else if (is_arg_with_param("d")) str::ReplacePtr(&gGlobalData.installDir, argList.At(++i)); #ifndef BUILD_UNINSTALLER else if (is_arg("register")) gGlobalData.registerAsDefault = true; else if (is_arg_with_param("opt")) { WCHAR *opts = argList.At(++i); str::ToLower(opts); str::TransChars(opts, L" ;", L",,"); WStrVec optlist; optlist.Split(opts, L",", true); if (optlist.Contains(L"pdffilter")) gGlobalData.installPdfFilter = true; if (optlist.Contains(L"pdfpreviewer")) gGlobalData.installPdfPreviewer = true; // uninstall the deprecated browser plugin if it's not // explicitly listed (only applies if the /opt flag is used) if (!optlist.Contains(L"plugin")) gGlobalData.keepBrowserPlugin = false; } else if (is_arg("x")) { gGlobalData.justExtractFiles = true; // silently extract files to the current directory (if /d isn't used) gGlobalData.silent = true; if (!gGlobalData.installDir) str::ReplacePtr(&gGlobalData.installDir, L"."); } else if (is_arg("autoupdate")) { gGlobalData.autoUpdate = true; } #endif else if (is_arg("h") || is_arg("help") || is_arg("?")) gGlobalData.showUsageAndQuit = true; #ifdef ENABLE_CRASH_TESTING else if (is_arg("crash")) { // will induce crash when 'Install' button is pressed // for testing crash handling gForceCrash = true; } #endif } }
int TesterMain() { RedirectIOToConsole(); WCHAR *cmdLine = GetCommandLine(); WStrVec argv; ParseCmdLine(cmdLine, argv); InitAllCommonControls(); ScopedGdiPlus gdi; mui::Initialize(); WCHAR *dirOrFile = NULL; bool mobiTest = false; size_t i = 2; // skip program name and "/tester" while (i < argv.Count()) { if (str::Eq(argv[i], L"-mobi")) { ++i; if (i == argv.Count()) return Usage(); mobiTest = true; dirOrFile = argv[i]; ++i; } else if (str::Eq(argv[i], L"-layout")) { gLayout = true; ++i; } else if (str::Eq(argv[i], L"-save-html")) { gSaveHtml = true; ++i; } else if (str::Eq(argv[i], L"-save-images")) { gSaveImages = true; ++i; } else if (str::Eq(argv[i], L"-zip-create")) { ZipCreateTest(); ++i; } else if (str::Eq(argv[i], L"-bench-md5")) { BenchMD5(); ++i; } else { // unknown argument return Usage(); } } if (2 == i) { // no arguments return Usage(); } if (mobiTest) { MobiTest(dirOrFile); } mui::Destroy(); system("pause"); return 0; }
/* Make a string safe to be displayed as a menu item (preserving all & so that they don't get swallowed) Caller needs to free() the result. */ WCHAR *ToSafeString(const WCHAR *str) { if (!str::FindChar(str, '&')) return str::Dup(str); WStrVec ampSplitter; ampSplitter.Split(str, L"&"); return ampSplitter.Join(L"&&"); }
void CopySelectionToClipboard(WindowInfo* win) { if (!win->currentTab || !win->currentTab->selectionOnPage) return; CrashIf(win->currentTab->selectionOnPage->size() == 0 && win->mouseAction != MouseAction::SelectingText); if (win->currentTab->selectionOnPage->size() == 0) return; CrashIf(!win->AsFixed()); if (!win->AsFixed()) return; if (!OpenClipboard(nullptr)) return; EmptyClipboard(); DisplayModel* dm = win->AsFixed(); #ifndef DISABLE_DOCUMENT_RESTRICTIONS if (!dm->GetEngine()->AllowsCopyingText()) win->ShowNotification(_TR("Copying text was denied (copying as image only)")); else #endif if (!dm->GetEngine()->IsImageCollection()) { AutoFreeW selText; bool isTextSelection = dm->textSelection->result.len > 0; if (isTextSelection) { selText.Set(dm->textSelection->ExtractText(L"\r\n")); } else { WStrVec selections; for (SelectionOnPage& sel : *win->currentTab->selectionOnPage) { WCHAR* text = dm->GetTextInRegion(sel.pageNo, sel.rect); if (text) selections.Push(text); } selText.Set(selections.Join()); } // don't copy empty text if (!str::IsEmpty(selText.Get())) CopyTextToClipboard(selText, true); if (isTextSelection) { // don't also copy the first line of a text selection as an image CloseClipboard(); return; } } /* also copy a screenshot of the current selection to the clipboard */ SelectionOnPage* selOnPage = &win->currentTab->selectionOnPage->at(0); RenderedBitmap* bmp = dm->GetEngine()->RenderBitmap(selOnPage->pageNo, dm->GetZoomReal(), dm->GetRotation(), &selOnPage->rect, RenderTarget::Export); if (bmp) CopyImageToClipboard(bmp->GetBitmap(), true); delete bmp; CloseClipboard(); }
void DumpProperties(BaseEngine *engine, bool fullDump) { Out("\t<Properties\n"); ScopedMem<char> str; str.Set(Escape(str::Dup(engine->FileName()))); Out("\t\tFilePath=\"%s\"\n", str.Get()); str.Set(Escape(engine->GetProperty(Prop_Title))); if (str) Out("\t\tTitle=\"%s\"\n", str.Get()); str.Set(Escape(engine->GetProperty(Prop_Subject))); if (str) Out("\t\tSubject=\"%s\"\n", str.Get()); str.Set(Escape(engine->GetProperty(Prop_Author))); if (str) Out("\t\tAuthor=\"%s\"\n", str.Get()); str.Set(Escape(engine->GetProperty(Prop_Copyright))); if (str) Out("\t\tCopyright=\"%s\"\n", str.Get()); str.Set(Escape(engine->GetProperty(Prop_CreationDate))); if (str) Out("\t\tCreationDate=\"%s\"\n", str.Get()); str.Set(Escape(engine->GetProperty(Prop_ModificationDate))); if (str) Out("\t\tModDate=\"%s\"\n", str.Get()); str.Set(Escape(engine->GetProperty(Prop_CreatorApp))); if (str) Out("\t\tCreator=\"%s\"\n", str.Get()); str.Set(Escape(engine->GetProperty(Prop_PdfProducer))); if (str) Out("\t\tPdfProducer=\"%s\"\n", str.Get()); str.Set(Escape(engine->GetProperty(Prop_PdfVersion))); if (str) Out("\t\tPdfVersion=\"%s\"\n", str.Get()); str.Set(Escape(engine->GetProperty(Prop_PdfFileStructure))); if (str) Out("\t\tPdfFileStructure=\"%s\"\n", str.Get()); if (!engine->AllowsPrinting()) Out("\t\tPrintingAllowed=\"no\"\n"); if (!engine->AllowsCopyingText()) Out("\t\tCopyingTextAllowed=\"no\"\n"); if (engine->IsImageCollection()) Out("\t\tImageCollection=\"yes\"\n"); if (engine->PreferredLayout()) Out("\t\tPreferredLayout=\"%d\"\n", engine->PreferredLayout()); Out("\t/>\n"); if (fullDump) { ScopedMem<WCHAR> fontlist(engine->GetProperty(Prop_FontList)); if (fontlist) { WStrVec fonts; fonts.Split(fontlist, L"\n"); str.Set(Escape(fonts.Join(L"\n\t\t"))); Out("\t<FontList>\n\t\t%s\n\t</FontList>\n", str.Get()); } } }
static void CALLBACK ReadDirectoryChangesNotification(DWORD errCode, DWORD bytesTransfered, LPOVERLAPPED overlapped) { ScopedCritSec cs(&g_threadCritSec); OverlappedEx *over = (OverlappedEx*)overlapped; WatchedDir* wd = (WatchedDir*)over->data; lf(L"ReadDirectoryChangesNotification() dir: %s, numBytes: %d", wd->dirPath, (int)bytesTransfered); CrashIf(wd != wd->overlapped.data); if (errCode == ERROR_OPERATION_ABORTED) { lf(" ERROR_OPERATION_ABORTED"); DeleteWatchedDir(wd); InterlockedDecrement(&gRemovalsPending); return; } // This might mean overflow? Not sure. if (!bytesTransfered) return; FILE_NOTIFY_INFORMATION *notify = (FILE_NOTIFY_INFORMATION*)wd->buf; // collect files that changed, removing duplicates WStrVec changedFiles; for (;;) { ScopedMem<WCHAR> fileName(str::DupN(notify->FileName, notify->FileNameLength / sizeof(WCHAR))); // files can get updated either by writing to them directly or // by writing to a .tmp file first and then moving that file in place // (the latter only yields a RENAMED action with the expected file name) if (notify->Action == FILE_ACTION_MODIFIED || notify->Action == FILE_ACTION_RENAMED_NEW_NAME) { if (!changedFiles.Contains(fileName)) { lf(L"ReadDirectoryChangesNotification() FILE_ACTION_MODIFIED, for '%s'", fileName); changedFiles.Append(fileName.StealData()); } else { lf(L"ReadDirectoryChangesNotification() eliminating duplicate notification for '%s'", fileName); } } else { lf(L"ReadDirectoryChangesNotification() action=%d, for '%s'", (int)notify->Action, fileName); } // step to the next entry if there is one DWORD nextOff = notify->NextEntryOffset; if (!nextOff) break; notify = (FILE_NOTIFY_INFORMATION *)((char*)notify + nextOff); } StartMonitoringDirForChanges(wd); for (const WCHAR *f : changedFiles) { NotifyAboutFile(wd, f); } }
bool DirFileProvider::OpenDir(const WCHAR* dirPath) { AssertCrash(filesToOpen.size() == 0); bool hasFiles = CollectStressTestSupportedFilesFromDirectory(dirPath, fileFilter, filesToOpen); filesToOpen.SortNatural(); AutoFreeW pattern(str::Format(L"%s\\*", dirPath)); bool hasSubDirs = CollectPathsFromDirectory(pattern, dirsToVisit, true); return hasFiles || hasSubDirs; }
virtual void Execute() { for (size_t i = 0; i < paths.Count(); i++) { gFileHistory.MarkFileInexistent(paths.At(i), true); } // update the Frequently Read page in case it's been displayed already if (paths.Count() > 0 && gWindows.Count() > 0 && gWindows.At(0)->IsAboutWindow()) gWindows.At(0)->RedrawAll(true); // prepare for clean-up (Join() just to be safe) gFileExistenceChecker = NULL; Join(); }
void CopySelectionToClipboard(WindowInfo *win) { if (!win->selectionOnPage) return; CrashIf(win->selectionOnPage->Count() == 0); if (win->selectionOnPage->Count() == 0) return; CrashIf(!win->dm || !win->dm->engine); if (!win->dm || !win->dm->engine) return; if (!OpenClipboard(NULL)) return; EmptyClipboard(); #ifndef DISABLE_DOCUMENT_RESTRICTIONS if (!win->dm->engine->AllowsCopyingText()) ShowNotification(win, _TR("Copying text was denied (copying as image only)")); else #endif if (!win->dm->engine->IsImageCollection()) { ScopedMem<WCHAR> selText; bool isTextSelection = win->dm->textSelection->result.len > 0; if (isTextSelection) { selText.Set(win->dm->textSelection->ExtractText(L"\r\n")); } else { WStrVec selections; for (size_t i = 0; i < win->selectionOnPage->Count(); i++) { SelectionOnPage *selOnPage = &win->selectionOnPage->At(i); WCHAR *text = win->dm->GetTextInRegion(selOnPage->pageNo, selOnPage->rect); if (text) selections.Push(text); } selText.Set(selections.Join()); } // don't copy empty text if (!str::IsEmpty(selText.Get())) CopyTextToClipboard(selText, true); if (isTextSelection) { // don't also copy the first line of a text selection as an image CloseClipboard(); return; } } /* also copy a screenshot of the current selection to the clipboard */ SelectionOnPage *selOnPage = &win->selectionOnPage->At(0); RenderedBitmap * bmp = win->dm->engine->RenderBitmap(selOnPage->pageNo, win->dm->ZoomReal(), win->dm->Rotation(), &selOnPage->rect, Target_Export); if (bmp) CopyImageToClipboard(bmp->GetBitmap(), true); delete bmp; CloseClipboard(); }
static void CALLBACK ReadDirectoryChangesNotification(DWORD errCode, DWORD bytesTransfered, LPOVERLAPPED overlapped) { ScopedCritSec cs(&g_threadCritSec); OverlappedEx *over = (OverlappedEx*)overlapped; WatchedDir* wd = (WatchedDir*)over->data; lf(L"ReadDirectoryChangesNotification() dir: %s, numBytes: %d", wd->dirPath, (int)bytesTransfered); CrashIf(wd != wd->overlapped.data); if (errCode == ERROR_OPERATION_ABORTED) { lf(" ERROR_OPERATION_ABORTED"); DeleteWatchedDir(wd); return; } // This might mean overflow? Not sure. if (!bytesTransfered) return; FILE_NOTIFY_INFORMATION *notify = (FILE_NOTIFY_INFORMATION*)wd->buf; // collect files that changed, removing duplicates WStrVec changedFiles; for (;;) { WCHAR *fileName = str::DupN(notify->FileName, notify->FileNameLength / sizeof(WCHAR)); if (notify->Action == FILE_ACTION_MODIFIED) { if (!changedFiles.Contains(fileName)) { lf(L"ReadDirectoryChangesNotification() FILE_ACTION_MODIFIED, for '%s'", fileName); changedFiles.Append(fileName); fileName = NULL; } else { lf(L"ReadDirectoryChangesNotification() eliminating duplicate notification for '%s'", fileName); } } else { lf(L"ReadDirectoryChangesNotification() action=%d, for '%s'", (int)notify->Action, fileName); } free(fileName); // step to the next entry if there is one DWORD nextOff = notify->NextEntryOffset; if (!nextOff) break; notify = (FILE_NOTIFY_INFORMATION *)((char*)notify + nextOff); } StartMonitoringDirForChanges(wd); for (WCHAR **f = changedFiles.IterStart(); f; f = changedFiles.IterNext()) { NotifyAboutFile(wd, *f); } }
static bool SetupPluginMode(CommandLineInfo& i) { if (!IsWindow(i.hwndPluginParent) || i.fileNames.Count() == 0) return false; gPluginURL = i.pluginURL; if (!gPluginURL) gPluginURL = i.fileNames.At(0); assert(i.fileNames.Count() == 1); while (i.fileNames.Count() > 1) { free(i.fileNames.Pop()); } i.reuseInstance = i.exitWhenDone = false; gGlobalPrefs->reuseInstance = false; // always display the toolbar when embedded (as there's no menubar in that case) gGlobalPrefs->showToolbar = true; // never allow esc as a shortcut to quit gGlobalPrefs->escToExit = false; // never show the sidebar by default gGlobalPrefs->showToc = false; if (DM_AUTOMATIC == gGlobalPrefs->defaultDisplayModeEnum) { // if the user hasn't changed the default display mode, // display documents as single page/continuous/fit width // (similar to Adobe Reader, Google Chrome and how browsers display HTML) gGlobalPrefs->defaultDisplayModeEnum = DM_CONTINUOUS; gGlobalPrefs->defaultZoomFloat = ZOOM_FIT_WIDTH; } // use fixed page UI for all document types (so that the context menu always // contains all plugin specific entries and the main window is never closed) gGlobalPrefs->ebookUI.useFixedPageUI = gGlobalPrefs->chmUI.useFixedPageUI = true; // extract some command line arguments from the URL's hash fragment where available // see http://www.adobe.com/devnet/acrobat/pdfs/pdf_open_parameters.pdf#nameddest=G4.1501531 if (i.pluginURL && str::FindChar(i.pluginURL, '#')) { ScopedMem<WCHAR> args(str::Dup(str::FindChar(i.pluginURL, '#') + 1)); str::TransChars(args, L"#", L"&"); WStrVec parts; parts.Split(args, L"&", true); for (size_t k = 0; k < parts.Count(); k++) { WCHAR *part = parts.At(k); int pageNo; if (str::StartsWithI(part, L"page=") && str::Parse(part + 4, L"=%d%$", &pageNo)) i.pageNumber = pageNo; else if (str::StartsWithI(part, L"nameddest=") && part[10]) str::ReplacePtr(&i.destName, part + 10); else if (!str::FindChar(part, '=') && part[0]) str::ReplacePtr(&i.destName, part); } } return true; }
static void SetCloseProcessMsg() { AutoFreeW procNames(str::Dup(ReadableProcName(gProcessesToClose.at(0)))); for (size_t i = 1; i < gProcessesToClose.size(); i++) { const WCHAR* name = ReadableProcName(gProcessesToClose.at(i)); if (i < gProcessesToClose.size() - 1) procNames.Set(str::Join(procNames, L", ", name)); else procNames.Set(str::Join(procNames, L" and ", name)); } AutoFreeW s(str::Format(_TR("Please close %s to proceed!"), procNames)); SetMsg(s, COLOR_MSG_FAILED); }
int ImageDirEngineImpl::GetPageByLabel(const WCHAR *label) { for (size_t i = 0; i < pageFileNames.Count(); i++) { const WCHAR *fileName = path::GetBaseName(pageFileNames.At(i)); const WCHAR *fileExt = path::GetExt(fileName); if (str::StartsWithI(fileName, label) && (fileName + str::Len(label) == fileExt || fileName[str::Len(label)] == '\0')) return (int)i + 1; } return BaseEngine::GetPageByLabel(label); }
bool DirFileProvider::OpenDir(const WCHAR *dirPath) { assert(filesToOpen.Count() == 0); bool hasFiles = CollectStressTestSupportedFilesFromDirectory(dirPath, fileFilter, filesToOpen); filesToOpen.SortNatural(); ScopedMem<WCHAR> pattern(str::Format(L"%s\\*", dirPath)); bool hasSubDirs = CollectPathsFromDirectory(pattern, dirsToVisit, true); return hasFiles || hasSubDirs; }
// Find a record corresponding to the given source file, line number and optionally column number. // (at the moment the column parameter is ignored) // // If there are several *consecutively declared* records for the same line then they are all returned. // The list of records is added to the vector 'records' // // If there is no record for that line, the record corresponding to the nearest line is selected // (within a range of EPSILON_LINE) // // The function returns PDFSYNCERR_SUCCESS if a matching record was found. UINT Pdfsync::SourceToRecord(const WCHAR* srcfilename, UINT line, UINT col, Vec<size_t> &records) { if (!srcfilename) return PDFSYNCERR_INVALID_ARGUMENT; ScopedMem<WCHAR> srcfilepath; // convert the source file to an absolute path if (PathIsRelative(srcfilename)) srcfilepath.Set(PrependDir(srcfilename)); else srcfilepath.Set(str::Dup(srcfilename)); if (!srcfilepath) return PDFSYNCERR_OUTOFMEMORY; // find the source file entry size_t isrc; for (isrc = 0; isrc < srcfiles.Count(); isrc++) if (path::IsSame(srcfilepath, srcfiles.At(isrc))) break; if (isrc == srcfiles.Count()) return PDFSYNCERR_UNKNOWN_SOURCEFILE; if (fileIndex.At(isrc).start == fileIndex.At(isrc).end) return PDFSYNCERR_NORECORD_IN_SOURCEFILE; // there is not any record declaration for that particular source file // look for sections belonging to the specified file // starting with the first section that is declared within the scope of the file. UINT min_distance = EPSILON_LINE; // distance to the closest record size_t lineIx = (size_t)-1; // closest record-line index for (size_t isec = fileIndex.At(isrc).start; isec < fileIndex.At(isrc).end; isec++) { // does this section belong to the desired file? if (lines.At(isec).file != isrc) continue; UINT d = abs((int)lines.At(isec).line - (int)line); if (d < min_distance) { min_distance = d; lineIx = isec; if (0 == d) break; // We have found a record for the requested line! } } if (lineIx == (size_t)-1) return PDFSYNCERR_NORECORD_FOR_THATLINE; // we read all the consecutive records until we reach a record belonging to another line for (size_t i = lineIx; i < lines.Count() && lines.At(i).line == lines.At(lineIx).line; i++) records.Push(lines.At(i).record); return PDFSYNCERR_SUCCESS; }
static void SetCloseProcessMsg() { ScopedMem<WCHAR> procNames(str::Dup(ReadableProcName(gProcessesToClose.At(0)))); for (size_t i = 1; i < gProcessesToClose.Count(); i++) { const WCHAR *name = ReadableProcName(gProcessesToClose.At(i)); if (i < gProcessesToClose.Count() - 1) procNames.Set(str::Join(procNames, L", ", name)); else procNames.Set(str::Join(procNames, L" and ", name)); } ScopedMem<WCHAR> s(str::Format(L"Please close %s to proceed!", procNames)); SetMsg(s, COLOR_MSG_FAILED); }
virtual void Run() { // filters all file paths on network drives, removable drives and // all paths which still exist from the list (remaining paths will // be marked as inexistent in gFileHistory) for (size_t i = 0; i < paths.Count() && !WasCancelRequested(); i++) { WCHAR *path = paths.At(i); if (!path || !path::IsOnFixedDrive(path) || DocumentPathExists(path)) { free(paths.PopAt(i--)); } } if (!WasCancelRequested()) uitask::Post(this); }
bool ImageDirEngineImpl::SaveFileAs(const WCHAR *copyFileName) { // only copy the files if the target directory doesn't exist yet if (!CreateDirectory(copyFileName, NULL)) return false; bool ok = true; for (size_t i = 0; i < pageFileNames.Count(); i++) { const WCHAR *filePathOld = pageFileNames.At(i); ScopedMem<WCHAR> filePathNew(path::Join(copyFileName, path::GetBaseName(filePathOld))); ok = ok && CopyFile(filePathOld, filePathNew, TRUE); } return ok; }
WCHAR* DirFileProvider::NextFile() { if (filesToOpen.size() > 0) { return filesToOpen.PopAt(0); } if (dirsToVisit.size() > 0) { // test next directory AutoFreeW path(dirsToVisit.PopAt(0)); OpenDir(path); return NextFile(); } return nullptr; }
// returns a list of permissions denied by this document // Caller needs to free the result static WCHAR *FormatPermissions(Doc doc) { if (!doc.IsEngine()) return NULL; WStrVec denials; if (!doc.AsEngine()->AllowsPrinting()) denials.Push(str::Dup(_TR("printing document"))); if (!doc.AsEngine()->AllowsCopyingText()) denials.Push(str::Dup(_TR("copying text"))); return denials.Join(L", "); }
// returns a list of permissions denied by this document // Caller needs to free the result static WCHAR *FormatPermissions(Controller *ctrl) { if (!ctrl->AsFixed()) return nullptr; WStrVec denials; BaseEngine *engine = ctrl->AsFixed()->GetEngine(); if (!engine->AllowsPrinting()) denials.Push(str::Dup(_TR("printing document"))); if (!engine->AllowsCopyingText()) denials.Push(str::Dup(_TR("copying text"))); return denials.Join(L", "); }
FileExistenceChecker() { DisplayState *state; for (size_t i = 0; i < 2 * FILE_HISTORY_MAX_RECENT && (state = gFileHistory.Get(i)) != NULL; i++) { if (!state->isMissing) paths.Append(str::Dup(state->filePath)); } // add missing paths from the list of most frequently opened documents Vec<DisplayState *> frequencyList; gFileHistory.GetFrequencyOrder(frequencyList); for (size_t i = 0; i < 2 * FILE_HISTORY_MAX_FREQUENT && i < frequencyList.Count(); i++) { state = frequencyList.At(i); if (!paths.Contains(state->filePath)) paths.Append(str::Dup(state->filePath)); } }
WCHAR *DirFileProvider::NextFile() { if (filesToOpen.Count() > 0) { return filesToOpen.PopAt(0); } if (dirsToVisit.Count() > 0) { // test next directory ScopedMem<WCHAR> path(dirsToVisit.PopAt(0)); OpenDir(path); return NextFile(); } return nullptr; }
// creates an archive from files (starting at index skipFiles); // file paths may be relative to the current directory or absolute and // may end in a colon followed by the desired path in the archive // (this is required for absolute paths) bool CreateArchive(const WCHAR *archivePath, WStrVec& files, size_t skipFiles=0) { size_t prevDataLen = 0; ScopedMem<char> prevData(file::ReadAll(archivePath, &prevDataLen)); lzma::SimpleArchive prevArchive; if (!lzma::ParseSimpleArchive(prevData, prevDataLen, &prevArchive)) prevArchive.filesCount = 0; str::Str<char> data; str::Str<char> content; ByteWriterLE lzsaHeader(data.AppendBlanks(8), 8); lzsaHeader.Write32(LZMA_MAGIC_ID); lzsaHeader.Write32((uint32_t)(files.Count() - skipFiles)); for (size_t i = skipFiles; i < files.Count(); i++) { ScopedMem<WCHAR> filePath(str::Dup(files.At(i))); WCHAR *sep = str::FindCharLast(filePath, ':'); ScopedMem<char> utf8Name; if (sep) { utf8Name.Set(str::conv::ToUtf8(sep + 1)); *sep = '\0'; } else { utf8Name.Set(str::conv::ToUtf8(filePath)); } str::TransChars(utf8Name, "/", "\\"); if ('/' == *utf8Name || str::Find(utf8Name, "../")) { fprintf(stderr, "In-archive name must not be an absolute path: %s\n", utf8Name); return false; } int idx = GetIdxFromName(&prevArchive, utf8Name); lzma::FileInfo *fi = NULL; if (idx != -1) fi = &prevArchive.files[idx]; if (!AppendEntry(data, content, filePath, utf8Name, fi)) return false; } uint32_t headerCrc32 = crc32(0, (const uint8_t *)data.Get(), (uint32_t)data.Size()); ByteWriterLE(data.AppendBlanks(4), 4).Write32(headerCrc32); if (!data.AppendChecked(content.Get(), content.Size())) return false; return file::WriteAll(archivePath, data.Get(), data.Size()); }
bool CheckInstallUninstallPossible(bool silent) { gProcessesToClose.Reset(); ProcessesUsingInstallation(gProcessesToClose); bool possible = gProcessesToClose.size() == 0; if (possible) { SetDefaultMsg(); } else { SetCloseProcessMsg(); if (!silent) MessageBeep(MB_ICONEXCLAMATION); } InvalidateFrame(); return possible; }
int Pdfsync::DocToSource(UINT pageNo, PointI pt, ScopedMem<WCHAR>& filename, UINT *line, UINT *col) { if (IsIndexDiscarded()) if (RebuildIndex() != PDFSYNCERR_SUCCESS) return PDFSYNCERR_SYNCFILE_CANNOT_BE_OPENED; // find the entry in the index corresponding to this page if (pageNo <= 0 || pageNo >= sheetIndex.Count() || pageNo > (UINT)engine->PageCount()) return PDFSYNCERR_INVALID_PAGE_NUMBER; // PdfSync coordinates are y-inversed RectI mbox = engine->PageMediabox(pageNo).Round(); pt.y = mbox.dy - pt.y; // distance to the closest pdf location (in the range <PDFSYNC_EPSILON_SQUARE) UINT closest_xydist = UINT_MAX; UINT selected_record = UINT_MAX; // If no record is found within a distance^2 of PDFSYNC_EPSILON_SQUARE // (selected_record == -1) then we pick up the record that is closest // vertically to the hit-point. UINT closest_ydist = UINT_MAX; // vertical distance between the hit point and the vertically-closest record UINT closest_xdist = UINT_MAX; // horizontal distance between the hit point and the vertically-closest record UINT closest_ydist_record = UINT_MAX; // vertically-closest record // read all the sections of 'p' declarations for this pdf sheet for (size_t i = sheetIndex.At(pageNo); i < points.Count() && points.At(i).page == pageNo; i++) { // check whether it is closer than the closest point found so far UINT dx = abs(pt.x - (int)SYNC_TO_PDF_COORDINATE(points.At(i).x)); UINT dy = abs(pt.y - (int)SYNC_TO_PDF_COORDINATE(points.At(i).y)); UINT dist = dx * dx + dy * dy; if (dist < PDFSYNC_EPSILON_SQUARE && dist < closest_xydist) { selected_record = points.At(i).record; closest_xydist = dist; } else if ((closest_xydist == UINT_MAX) && dy < PDFSYNC_EPSILON_Y && (dy < closest_ydist || (dy == closest_ydist && dx < closest_xdist))) { closest_ydist_record = points.At(i).record; closest_ydist = dy; closest_xdist = dx; } } if (selected_record == UINT_MAX) selected_record = closest_ydist_record; if (selected_record == UINT_MAX) return PDFSYNCERR_NO_SYNC_AT_LOCATION; // no record was found close enough to the hit point // We have a record number, we need to find its declaration ('l ...') in the syncfile PdfsyncLine cmp; cmp.record = selected_record; PdfsyncLine *found = (PdfsyncLine *)bsearch(&cmp, lines.LendData(), lines.Count(), sizeof(PdfsyncLine), cmpLineRecords); assert(found); if (!found) return PDFSYNCERR_NO_SYNC_AT_LOCATION; filename.Set(str::Dup(srcfiles.At(found->file))); *line = found->line; *col = found->column; return PDFSYNCERR_SUCCESS; }
void BenchFileOrDir(WStrVec& pathsToBench) { gLog = new slog::StderrLogger(); size_t n = pathsToBench.size() / 2; for (size_t i = 0; i < n; i++) { WCHAR* path = pathsToBench.at(2 * i); if (file::Exists(path)) BenchFile(path, pathsToBench.at(2 * i + 1)); else if (dir::Exists(path)) BenchDir(path); else logbench(L"Error: file or dir %s doesn't exist", path); } delete gLog; }
bool Set(int index, const WCHAR *t) { if (index < Count()) { str::ReplacePtr(&text.At(index), t); return true; } return false; }
bool Delete(int index) { if (index < Count()) { free(text.PopAt(index)); return true; } return false; }
WCHAR *ImageDirEngineImpl::GetPageLabel(int pageNo) { if (pageNo < 1 || PageCount() < pageNo) return BaseEngine::GetPageLabel(pageNo); const WCHAR *fileName = path::GetBaseName(pageFileNames.At(pageNo - 1)); return str::DupN(fileName, path::GetExt(fileName) - fileName); }