TEST(String, readFile) { const TemporaryFile afileTemp, emptyFileTemp; auto afile = afileTemp.path().string(); auto emptyFile = emptyFileTemp.path().string(); EXPECT_TRUE(writeFile(string(), emptyFile.c_str())); EXPECT_TRUE(writeFile(StringPiece("bar"), afile.c_str())); { string contents; EXPECT_TRUE(readFile(emptyFile.c_str(), contents)); EXPECT_EQ(contents, ""); EXPECT_TRUE(readFile(afile.c_str(), contents, 0)); EXPECT_EQ("", contents); EXPECT_TRUE(readFile(afile.c_str(), contents, 2)); EXPECT_EQ("ba", contents); EXPECT_TRUE(readFile(afile.c_str(), contents)); EXPECT_EQ("bar", contents); } { vector<unsigned char> contents; EXPECT_TRUE(readFile(emptyFile.c_str(), contents)); EXPECT_EQ(vector<unsigned char>(), contents); EXPECT_TRUE(readFile(afile.c_str(), contents, 0)); EXPECT_EQ(vector<unsigned char>(), contents); EXPECT_TRUE(readFile(afile.c_str(), contents, 2)); EXPECT_EQ(vector<unsigned char>({'b', 'a'}), contents); EXPECT_TRUE(readFile(afile.c_str(), contents)); EXPECT_EQ(vector<unsigned char>({'b', 'a', 'r'}), contents); } }
TEST(TemporaryFile, Simple) { int fd = -1; char c = 'x'; { TemporaryFile f; EXPECT_FALSE(f.path().empty()); EXPECT_TRUE(f.path().is_absolute()); fd = f.fd(); EXPECT_LE(0, fd); ssize_t r = write(fd, &c, 1); EXPECT_EQ(1, r); } // The file must have been closed. This assumes that no other thread // has opened another file in the meanwhile, which is a sane assumption // to make in this test. ssize_t r = write(fd, &c, 1); int savedErrno = errno; EXPECT_EQ(-1, r); EXPECT_EQ(EBADF, savedErrno); }
void URIStreamOpenerTest::testStreamOpenerPath() { TemporaryFile tempFile; std::string path = tempFile.path(); std::ofstream ostr(path.c_str()); assert (ostr.good()); ostr << "Hello, world!" << std::endl; ostr.close(); URIStreamOpener opener; std::istream* istr = opener.open(path); assert (istr != 0); assert (istr->good()); delete istr; }
void URIStreamOpenerTest::testStreamOpenerRelative() { TemporaryFile tempFile; std::string path = tempFile.path(); std::ofstream ostr(path.c_str()); assert (ostr.good()); ostr << "Hello, world!" << std::endl; ostr.close(); URI uri(Path(path).toString(Path::PATH_UNIX)); std::string uriString = uri.toString(); URIStreamOpener opener; std::istream* istr = opener.open(uri); assert (istr != 0); assert (istr->good()); delete istr; }
void URIStreamOpenerTest::testStreamOpenerPathResolve() { TemporaryFile tempFile; std::string path = tempFile.path(); std::ofstream ostr(path.c_str()); assert (ostr.good()); ostr << "Hello, world!" << std::endl; ostr.close(); Path p(path); Path parent(p.parent()); std::string base = parent.toString(); URIStreamOpener opener; std::istream* istr = opener.open(base, p.getFileName()); assert (istr != 0); assert (istr->good()); delete istr; }
void URIStreamOpenerTest::testStreamOpenerURIResolve() { TemporaryFile tempFile; std::string path = tempFile.path(); std::ofstream ostr(path.c_str()); assert (ostr.good()); ostr << "Hello, world!" << std::endl; ostr.close(); Path p(path); p.makeAbsolute(); Path parent(p.parent()); URI uri; uri.setScheme("file"); uri.setPath(parent.toString(Path::PATH_UNIX)); std::string uriString = uri.toString(); URIStreamOpener opener; std::istream* istr = opener.open(uriString, p.getFileName()); assert (istr != 0); assert (istr->good()); delete istr; }
TEST(File, Locks) { typedef std::unique_lock<File> Lock; typedef boost::shared_lock<File> SharedLock; // Find out where we are. static constexpr size_t pathLength = 2048; char buf[pathLength + 1]; int r = readlink("/proc/self/exe", buf, pathLength); CHECK_ERR(r); buf[r] = '\0'; fs::path helper(buf); helper.remove_filename(); helper /= "file_test_lock_helper"; TemporaryFile tempFile; File f(tempFile.fd()); enum LockMode { EXCLUSIVE, SHARED }; auto testLock = [&] (LockMode mode, bool expectedSuccess) { auto ret = Subprocess({helper.native(), mode == SHARED ? "-s" : "-x", tempFile.path().native()}).wait(); EXPECT_TRUE(ret.exited()); if (ret.exited()) { EXPECT_EQ(expectedSuccess ? 0 : 42, ret.exitStatus()); } }; // Make sure nothing breaks and things compile. { Lock lock(f); } { SharedLock lock(f); } { Lock lock(f, std::defer_lock); EXPECT_TRUE(lock.try_lock()); } { SharedLock lock(f, boost::defer_lock); EXPECT_TRUE(lock.try_lock()); } // X blocks X { Lock lock(f); testLock(EXCLUSIVE, false); } // X blocks S { Lock lock(f); testLock(SHARED, false); } // S blocks X { SharedLock lock(f); testLock(EXCLUSIVE, false); } // S does not block S { SharedLock lock(f); testLock(SHARED, true); } }
int main(const std::vector<std::string>& args) override { if (args.size() != 2) { logger().fatal("Usage: lokitclient /path/to/lo/installation/program /path/to/document"); return Application::EXIT_USAGE; } LibreOfficeKit *loKit; LibreOfficeKitDocument *loKitDocument; loKit = lok_init(args[0].c_str()); if (!loKit) { logger().fatal("LibreOfficeKit initialisation failed"); return Application::EXIT_UNAVAILABLE; } loKitDocument = loKit->pClass->documentLoad(loKit, args[1].c_str()); if (!loKitDocument) { logger().fatal("Document loading failed: " + std::string(loKit->pClass->getError(loKit))); return Application::EXIT_UNAVAILABLE; } loKitDocument->pClass->registerCallback(loKitDocument, myCallback, nullptr); loKitDocument->pClass->initializeForRendering(loKitDocument, nullptr); if (isatty(0)) { std::cout << "Enter LOKit \"commands\", one per line. 'help' for help. EOF to finish." << std::endl; } while (!std::cin.eof()) { std::string line; std::getline(std::cin, line); StringTokenizer tokens(line, " ", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM); if (tokens.count() == 0) continue; if (tokens[0] == "?" || tokens[0] == "help") { std::cout << "Commands mimic LOOL protocol but we talk directly to LOKit:" << std::endl << " status" << std::endl << " calls LibreOfficeKitDocument::getDocumentType, getParts, getPartName, getDocumentSize" << std::endl << " tile part pixelwidth pixelheight docposx docposy doctilewidth doctileheight" << std::endl << " calls LibreOfficeKitDocument::paintTile" << std::endl; } else if (tokens[0] == "status") { if (tokens.count() != 1) { std::cout << "? syntax" << std::endl; continue; } std::cout << LOKitHelper::documentStatus(loKitDocument) << std::endl; for (int i = 0; i < loKitDocument->pClass->getParts(loKitDocument); i++) { std::cout << " " << i << ": '" << loKitDocument->pClass->getPartName(loKitDocument, i) << "'" << std::endl; } } else if (tokens[0] == "tile") { if (tokens.count() != 8) { std::cout << "? syntax" << std::endl; continue; } int partNumber(std::stoi(tokens[1])); int canvasWidth(std::stoi(tokens[2])); int canvasHeight(std::stoi(tokens[3])); int tilePosX(std::stoi(tokens[4])); int tilePosY(std::stoi(tokens[5])); int tileWidth(std::stoi(tokens[6])); int tileHeight(std::stoi(tokens[7])); std::vector<unsigned char> pixmap(canvasWidth*canvasHeight*4); loKitDocument->pClass->setPart(loKitDocument, partNumber); loKitDocument->pClass->paintTile(loKitDocument, pixmap.data(), canvasWidth, canvasHeight, tilePosX, tilePosY, tileWidth, tileHeight); if (!Util::windowingAvailable()) continue; std::vector<char> png; const auto mode = static_cast<LibreOfficeKitTileMode>(loKitDocument->pClass->getTileMode(loKitDocument)); Png::encodeBufferToPNG(pixmap.data(), canvasWidth, canvasHeight, png, mode); TemporaryFile pngFile; std::ofstream pngStream(pngFile.path(), std::ios::binary); pngStream.write(png.data(), png.size()); pngStream.close(); if (std::system((std::string("display ") + pngFile.path()).c_str()) == -1) { // Not worth it to display a warning, this is just a throwaway test program, and // the developer running it surely notices if nothing shows up... } } else { std::cout << "? unrecognized" << std::endl; } } // Safest to just bluntly exit std::_Exit(Application::EXIT_OK); }
TEST(File, Locks) { typedef std::unique_lock<File> Lock; typedef boost::shared_lock<File> SharedLock; // Find out where we are. static constexpr size_t pathLength = 2048; char buf[pathLength + 1]; int r = readlink("/proc/self/exe", buf, pathLength); CHECK(r != -1); buf[r] = '\0'; fs::path me(buf); auto helper_basename = "file_test_lock_helper"; fs::path helper; if (fs::exists(me.parent_path() / helper_basename)) { helper = me.parent_path() / helper_basename; } else { throw std::runtime_error( folly::to<std::string>("cannot find helper ", helper_basename)); } TemporaryFile tempFile; File f(tempFile.fd()); enum LockMode { EXCLUSIVE, SHARED }; auto testLock = [&](LockMode mode, bool expectedSuccess) { auto ret = Subprocess({helper.native(), mode == SHARED ? "-s" : "-x", tempFile.path().native()}).wait(); EXPECT_TRUE(ret.exited()); if (ret.exited()) { EXPECT_EQ(expectedSuccess ? 0 : 42, ret.exitStatus()); } }; // Make sure nothing breaks and things compile. { Lock lock(f); } { SharedLock lock(f); } { Lock lock(f, std::defer_lock); EXPECT_TRUE(lock.try_lock()); } { SharedLock lock(f, boost::defer_lock); EXPECT_TRUE(lock.try_lock()); } // X blocks X { Lock lock(f); testLock(EXCLUSIVE, false); } // X blocks S { Lock lock(f); testLock(SHARED, false); } // S blocks X { SharedLock lock(f); testLock(EXCLUSIVE, false); } // S does not block S { SharedLock lock(f); testLock(SHARED, true); } }