jsbigstring.cpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /*
  2. * Copyright (c) Facebook, Inc. and its affiliates.
  3. *
  4. * This source code is licensed under the MIT license found in the
  5. * LICENSE file in the root directory of this source tree.
  6. */
  7. #include <fcntl.h>
  8. #include <sys/mman.h>
  9. #include <cxxreact/JSBigString.h>
  10. #include <folly/File.h>
  11. #include <gtest/gtest.h>
  12. using namespace facebook;
  13. using namespace facebook::react;
  14. namespace {
  15. int tempFileFromString(std::string contents) {
  16. const char *tmpDir = getenv("TMPDIR");
  17. if (tmpDir == nullptr)
  18. tmpDir = "/tmp";
  19. std::string tmp{tmpDir};
  20. tmp += "/temp.XXXXXX";
  21. std::vector<char> tmpBuf{tmp.begin(), tmp.end()};
  22. tmpBuf.push_back('\0');
  23. const int fd = mkstemp(tmpBuf.data());
  24. write(fd, contents.c_str(), contents.size() + 1);
  25. return fd;
  26. }
  27. }; // namespace
  28. TEST(JSBigFileString, MapWholeFileTest) {
  29. std::string data{"Hello, world"};
  30. const auto size = data.length() + 1;
  31. // Initialise Big String
  32. int fd = tempFileFromString("Hello, world");
  33. JSBigFileString bigStr{fd, size};
  34. // Test
  35. ASSERT_STREQ(data.c_str(), bigStr.c_str());
  36. }
  37. TEST(JSBigFileString, MapPartTest) {
  38. std::string data{"Hello, world"};
  39. // Sub-string to actually map
  40. std::string needle{"or"};
  41. off_t offset = data.find(needle);
  42. // Initialise Big String
  43. int fd = tempFileFromString(data);
  44. JSBigFileString bigStr{fd, needle.size(), offset};
  45. // Test
  46. EXPECT_EQ(needle.length(), bigStr.size());
  47. for (unsigned int i = 0; i < needle.length(); ++i) {
  48. EXPECT_EQ(needle[i], bigStr.c_str()[i]);
  49. }
  50. }
  51. TEST(JSBigFileString, RemapTest) {
  52. static const uint8_t kRemapMagic[] = {
  53. 0xc6, 0x1f, 0xbc, 0x03, 0xc1, 0x03, 0x19, 0x1f, 0xa1, 0xd0, 0xeb, 0x73};
  54. std::string data(std::begin(kRemapMagic), std::end(kRemapMagic));
  55. auto app = [&data](uint16_t v) {
  56. data.append(reinterpret_cast<char *>(&v), sizeof(v));
  57. };
  58. size_t pageSizeLog2 = 16;
  59. app(pageSizeLog2);
  60. size_t pageSize = 1 << pageSizeLog2;
  61. app(1); // header pages
  62. app(2); // num mappings
  63. // file page 0 -> memory page 1
  64. app(1); // memory page
  65. app(1); // num pages
  66. // file page 1 -> memory page 0
  67. app(0); // memory page
  68. app(1); // num pages
  69. while (data.size() < pageSize) {
  70. app(0);
  71. }
  72. while (data.size() < pageSize * 2) {
  73. app(0x1111);
  74. }
  75. while (data.size() < pageSize * 3) {
  76. app(0x2222);
  77. }
  78. int fd = tempFileFromString(data);
  79. JSBigFileString bigStr{fd, data.size()};
  80. EXPECT_EQ(pageSize * 2, bigStr.size());
  81. auto remapped = bigStr.c_str();
  82. size_t i = 0;
  83. for (; i < pageSize; ++i) {
  84. EXPECT_EQ(0x22, remapped[i]);
  85. }
  86. for (; i < pageSize * 2; ++i) {
  87. EXPECT_EQ(0x11, remapped[i]);
  88. }
  89. }