/** * Reads content of binary file * @param pathToFile to read * @return Result<std::vector<uint8_t>> all the content of the file, and/or an error string * if something went wrong */ Result<std::vector<uint8_t>> ReadBinaryFileContent(const std::string& pathToFile) { std::ifstream in(pathToFile, std::ifstream::binary); if (!in) { std::string error{"Cannot read-open file: "}; error.append(pathToFile); return Result<std::vector<uint8_t>>{{}, error}; } std::shared_ptr<void> fileCloser(nullptr, [&](void *) { // RAII file close if (in) { in.close(); } }); //fileCloser RAII std::vector<char> contents; in.seekg(0, std::ios::end); auto end = in.tellg(); // Attempt to read it the fastest way possible. if (-1 != end) { // tellg() --> pos_type{-1} if reading the end failed. contents.resize(end); in.seekg(0, std::ios::beg); in.read(&contents[0], contents.size()); } else { // Could not calculate with ifstream::tellg(). Is it a RAM file? // Fallback solution to slower iteratator approach contents.assign((std::istreambuf_iterator<char>(in)), (std::istreambuf_iterator<char>())); } // return copy of the read result. return Result<std::vector<uint8_t>>{{contents.begin(), contents.end()}}; }
/** * Write the serialized date to the given filename * @param filename * @param content * @return whether or not the write was successful */ Result<bool> WriteAppendBinaryFileContent(const std::string & filename, const std::vector<uint8_t>& content) { static_assert(sizeof(char) == sizeof(uint8_t), "File writing assumes equal size for uint8_t and char"); std::fstream outputFile; outputFile.open(filename.c_str(), std::fstream::out | std::fstream::binary | std::fstream::app); const bool openStatus = outputFile.is_open(); std::shared_ptr<void> fileCloser(nullptr, [&](void *) { // RAII file close if (openStatus) { outputFile.close(); } }); //fileCloser RAII std::string error = {"Unable to write test data to file: "}; error.append(filename); if (!openStatus) { return Result<bool> {false, error}; } // FYI: thread_local must be trivial to initialize: // http://coliru.stacked-crooked.com/view?id=6717cbf5974c0e5c const static int kOneMbBuffer = 1024 * 1024; thread_local char buffer[kOneMbBuffer]; outputFile.rdbuf()->pubsetbuf(buffer, kOneMbBuffer); outputFile.exceptions(std::ios::failbit | std::ios::badbit); // trigger exception if error happens try { outputFile.write(reinterpret_cast<const char*>(&content[0]), content.size()); } catch(const std::exception& e) { error.append(". Writing triggered exception: ").append(e.what()); return Result<bool>{false, error}; } return Result<bool>{true}; }
/** * A generic write function that supports a variety of modes * @param pathToFile * @param content * @param mode, std::ios::app or std::ios::trunc * @return */ Result<bool> WriteFileContentInternal(const std::string& pathToFile, const std::string& content, std::ios_base::openmode mode) { std::ofstream out(pathToFile, std::ios::out | mode); if (!out) { std::string error{"Cannot write-open file: "}; error.append(pathToFile); return Result<bool>{false, error}; } std::shared_ptr<void> fileCloser(nullptr, [&](void *) { // RAII file close if (out) { out.close(); } }); //fileCloser RAII out << content; return Result<bool>{true}; }
//------------------------------------------------------------------------------- ColumnItem::Ptr getMinMaxFromThesaurus( size_t tableID, size_t colIdx, size_t partIdx, bool min, Base& BaseDesc, Settings& Settings ) { ColumnItem::Ptr minMax = NULL; size_t tableIdx = 0; for (tableIdx = 0; tableIdx < BaseDesc.getTables().size(); ++tableIdx) { if (BaseDesc.getTables()[tableIdx]->ID == tableID) break; } std::string fileName = getThesaurusFileName( Settings.dataPath.c_str(), tableIdx + 1, colIdx + 1, partIdx ); FILE* pFIn = fopen( fileName.c_str(), "rb" ); if ( pFIn == NULL ) return minMax; FileCloser fileCloser(pFIn); Column::Ptr column = BaseDesc.getTable(static_cast<unsigned int>(tableID))->Columns[colIdx]; size_t binItemSize = 0; size_t tmpBufSize = 1000; switch( column->Type ) { case COL_TYPE_INT: binItemSize = 4; break; case COL_TYPE_BIG_INT: case COL_TYPE_DATE: case COL_TYPE_DOUBLE: binItemSize = 8; break; case COL_TYPE_VARCHAR: binItemSize = column->Size; tmpBufSize = column->Size + 1000; break; default: throw generic_error(generic_error::NOT_IMPLEMENTED, "type not supported"); } unsigned char *pTmpBuf = new unsigned char[tmpBufSize]; boost::scoped_array<unsigned char> pTmpBufDel( pTmpBuf ); if( !min ) { //get the file size if( fseek( pFIn, 0, SEEK_END ) != 0 ) assert( 0 ); long fileSize = ftell( pFIn ); if( fileSize == -1 ) assert( 0 ); if( fseek( pFIn, fileSize - static_cast<long>(binItemSize), SEEK_SET ) != 0 ) assert( 0 ); } if( fread( pTmpBuf, 1, binItemSize, pFIn ) != binItemSize ) throw generic_error(generic_error::INVALID_FILE, "invalid thesaurus file [%s]", fileName.c_str()); switch( column->Type ) { case COL_TYPE_INT: { int *pItemData = (int*)( pTmpBuf ); minMax = new ColumnItem( *pItemData ); } break; case COL_TYPE_BIG_INT: case COL_TYPE_DATE: { llong *pItemData = (llong*)( pTmpBuf ); minMax = new ColumnItem( (double) *pItemData ); } break; case COL_TYPE_DOUBLE: { double *pItemData = (double*)( pTmpBuf ); minMax = new ColumnItem( *pItemData ); } break; case COL_TYPE_VARCHAR: pTmpBuf[column->Size] = '\0'; minMax = new ColumnItem( (char*) pTmpBuf ); break; } return minMax; }
nsresult mozJSComponentLoader::GlobalForLocation(nsILocalFile *aComponent, JSObject **aGlobal, char **aLocation) { nsresult rv; JSPrincipals* jsPrincipals = nsnull; JSCLContextHelper cx(mContext); #ifndef XPCONNECT_STANDALONE rv = mSystemPrincipal->GetJSPrincipals(cx, &jsPrincipals); NS_ENSURE_SUCCESS(rv, rv); JSPrincipalsHolder princHolder(mContext, jsPrincipals); #endif nsCOMPtr<nsIXPCScriptable> backstagePass; rv = mRuntimeService->GetBackstagePass(getter_AddRefs(backstagePass)); NS_ENSURE_SUCCESS(rv, rv); JSCLAutoErrorReporterSetter aers(cx, mozJSLoaderErrorReporter); nsCOMPtr<nsIXPConnect> xpc = do_GetService(kXPConnectServiceContractID, &rv); NS_ENSURE_SUCCESS(rv, rv); // Make sure InitClassesWithNewWrappedGlobal() installs the // backstage pass as the global in our compilation context. JS_SetGlobalObject(cx, nsnull); nsCOMPtr<nsIXPConnectJSObjectHolder> holder; rv = xpc->InitClassesWithNewWrappedGlobal(cx, backstagePass, NS_GET_IID(nsISupports), nsIXPConnect:: FLAG_SYSTEM_GLOBAL_OBJECT, getter_AddRefs(holder)); NS_ENSURE_SUCCESS(rv, rv); JSObject *global; rv = holder->GetJSObject(&global); NS_ENSURE_SUCCESS(rv, rv); if (!JS_DefineFunctions(cx, global, gGlobalFun)) { return NS_ERROR_FAILURE; } nsCOMPtr<nsIXPConnectJSObjectHolder> locationHolder; rv = xpc->WrapNative(cx, global, aComponent, NS_GET_IID(nsILocalFile), getter_AddRefs(locationHolder)); NS_ENSURE_SUCCESS(rv, rv); JSObject *locationObj; rv = locationHolder->GetJSObject(&locationObj); NS_ENSURE_SUCCESS(rv, rv); if (!JS_DefineProperty(cx, global, "__LOCATION__", OBJECT_TO_JSVAL(locationObj), nsnull, nsnull, 0)) { return NS_ERROR_FAILURE; } nsCAutoString nativePath; // Quick hack to unbust XPCONNECT_STANDALONE. // This leaves the jsdebugger with a non-URL pathname in the // XPCONNECT_STANDALONE case - but at least it builds and runs otherwise. // See: http://bugzilla.mozilla.org/show_bug.cgi?id=121438 #ifdef XPCONNECT_STANDALONE localFile->GetNativePath(nativePath); #else NS_GetURLSpecFromFile(aComponent, nativePath); #endif // Before compiling the script, first check to see if we have it in // the fastload file. Note: as a rule, fastload errors are not fatal // to loading the script, since we can always slow-load. nsCOMPtr<nsIFastLoadService> flSvc = do_GetFastLoadService(&rv); // Save the old state and restore it upon return FastLoadStateHolder flState(flSvc); PRBool fastLoading = PR_FALSE; if (NS_SUCCEEDED(rv)) { rv = StartFastLoad(flSvc); if (NS_SUCCEEDED(rv)) { fastLoading = PR_TRUE; } } nsCOMPtr<nsIURI> uri; rv = NS_NewURI(getter_AddRefs(uri), nativePath); NS_ENSURE_SUCCESS(rv, rv); JSScript *script = nsnull; if (fastLoading) { rv = ReadScript(flSvc, nativePath.get(), uri, cx, &script); if (NS_SUCCEEDED(rv)) { LOG(("Successfully loaded %s from fastload\n", nativePath.get())); fastLoading = PR_FALSE; // no need to write out the script } else if (rv == NS_ERROR_NOT_AVAILABLE) { // This is ok, it just means the script is not yet in the // fastload file. rv = NS_OK; } else { LOG(("Failed to deserialize %s\n", nativePath.get())); // Remove the fastload file, it may be corrupted. LOG(("Invalid fastload file detected, removing it\n")); nsCOMPtr<nsIObjectOutputStream> objectOutput; flSvc->GetOutputStream(getter_AddRefs(objectOutput)); if (objectOutput) { flSvc->SetOutputStream(nsnull); objectOutput->Close(); } nsCOMPtr<nsIObjectInputStream> objectInput; flSvc->GetInputStream(getter_AddRefs(objectInput)); if (objectInput) { flSvc->SetInputStream(nsnull); objectInput->Close(); } if (mFastLoadFile) { mFastLoadFile->Remove(PR_FALSE); } fastLoading = PR_FALSE; } } if (!script || NS_FAILED(rv)) { // The script wasn't in the fastload cache, so compile it now. LOG(("Slow loading %s\n", nativePath.get())); #ifdef HAVE_PR_MEMMAP PRInt64 fileSize; rv = aComponent->GetFileSize(&fileSize); if (NS_FAILED(rv)) return rv; PRInt64 maxSize; LL_UI2L(maxSize, PR_UINT32_MAX); if (LL_CMP(fileSize, >, maxSize)) { NS_ERROR("file too large"); return NS_ERROR_FAILURE; } PRFileDesc *fileHandle; rv = aComponent->OpenNSPRFileDesc(PR_RDONLY, 0, &fileHandle); NS_ENSURE_SUCCESS(rv, rv); // Make sure the file is closed, no matter how we return. FileAutoCloser fileCloser(fileHandle); PRFileMap *map = PR_CreateFileMap(fileHandle, fileSize, PR_PROT_READONLY); if (!map) { NS_ERROR("Failed to create file map"); return NS_ERROR_FAILURE; } // Make sure the file map is closed, no matter how we return. FileMapAutoCloser mapCloser(map); PRUint32 fileSize32; LL_L2UI(fileSize32, fileSize); char *buf = static_cast<char*>(PR_MemMap(map, 0, fileSize32)); if (!buf) { NS_WARNING("Failed to map file"); return NS_ERROR_FAILURE; } script = JS_CompileScriptForPrincipals(cx, global, jsPrincipals, buf, fileSize32, nativePath.get(), 1); PR_MemUnmap(buf, fileSize32); #else /* HAVE_PR_MEMMAP */ /** * No memmap implementation, so fall back to using * JS_CompileFileHandleForPrincipals(). */ FILE *fileHandle; rv = aComponent->OpenANSIFileDesc("r", &fileHandle); NS_ENSURE_SUCCESS(rv, rv); script = JS_CompileFileHandleForPrincipals(cx, global, nativePath.get(), fileHandle, jsPrincipals); /* JS will close the filehandle after compilation is complete. */ #endif /* HAVE_PR_MEMMAP */ }