file_mapping_test.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost
  4. // Software License, Version 1.0. (See accompanying file
  5. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // See http://www.boost.org/libs/interprocess for documentation.
  8. //
  9. //////////////////////////////////////////////////////////////////////////////
  10. #include <boost/interprocess/detail/config_begin.hpp>
  11. #include <ios> //std::streamoff
  12. #include <fstream> //std::ofstream, std::ifstream
  13. #include <iostream>
  14. #include <boost/interprocess/file_mapping.hpp>
  15. #include <boost/interprocess/mapped_region.hpp>
  16. #include <boost/container/vector.hpp>
  17. #include <stdexcept> //std::exception
  18. #include <cstddef> //std::size_t
  19. #include "get_process_id_name.hpp"
  20. using namespace boost::interprocess;
  21. inline std::string get_filename()
  22. {
  23. std::string ret (ipcdetail::get_temporary_path());
  24. ret += "/";
  25. ret += test::get_process_id_name();
  26. return ret;
  27. }
  28. file_mapping get_file_mapping()
  29. {
  30. file_mapping f;
  31. return file_mapping(boost::move(f));
  32. }
  33. int main ()
  34. {
  35. try{
  36. const std::size_t FileSize = 99999*2;
  37. {
  38. //Create file with given size
  39. std::ofstream file(get_filename().c_str(), std::ios::binary | std::ios::trunc);
  40. file.seekp(static_cast<std::streamoff>(FileSize-1));
  41. file.write("", 1);
  42. }
  43. {
  44. //Create a file mapping
  45. file_mapping mapping(get_filename().c_str(), read_write);
  46. //Create two mapped regions, one half of the file each
  47. mapped_region region (mapping
  48. ,read_write
  49. ,0
  50. ,FileSize/2
  51. );
  52. mapped_region region2(mapping
  53. ,read_write
  54. ,FileSize/2
  55. ,FileSize - FileSize/2
  56. );
  57. //Fill two regions with a pattern
  58. unsigned char *filler = static_cast<unsigned char*>(region.get_address());
  59. for(std::size_t i = 0
  60. ;i < FileSize/2
  61. ;++i){
  62. *filler++ = static_cast<unsigned char>(i);
  63. }
  64. filler = static_cast<unsigned char*>(region2.get_address());
  65. for(std::size_t i = FileSize/2
  66. ;i < FileSize
  67. ;++i){
  68. *filler++ = static_cast<unsigned char>(i);
  69. }
  70. if(!region.flush(0, 0, false)){
  71. return 1;
  72. }
  73. if(!region2.flush(0, 0, true)){
  74. return 1;
  75. }
  76. }
  77. //See if the pattern is correct in the file
  78. {
  79. //Open the file
  80. std::ifstream file(get_filename().c_str(), std::ios::binary);
  81. //Create a memory buffer
  82. boost::container::vector<unsigned char> memory(FileSize/2 +1);
  83. //Fill buffer
  84. file.read(static_cast<char*>(static_cast<void*>(memory.data()))
  85. , FileSize/2);
  86. unsigned char *checker = memory.data();
  87. //Check pattern
  88. for(std::size_t i = 0
  89. ;i < FileSize/2
  90. ;++i){
  91. if(*checker++ != static_cast<unsigned char>(i)){
  92. return 1;
  93. }
  94. }
  95. //Fill buffer
  96. file.read(static_cast<char*>(static_cast<void*>(memory.data()))
  97. , FileSize - FileSize/2);
  98. checker = memory.data();
  99. //Check pattern
  100. for(std::size_t i = FileSize/2
  101. ;i < FileSize
  102. ;++i){
  103. if(*checker++ != static_cast<unsigned char>(i)){
  104. return 1;
  105. }
  106. }
  107. }
  108. //Now check the pattern mapping a single read only mapped_region
  109. {
  110. //Create a file mapping
  111. file_mapping mapping(get_filename().c_str(), read_only);
  112. //Create a single regions, mapping all the file
  113. mapped_region region (mapping
  114. ,read_only
  115. );
  116. //Check pattern
  117. unsigned char *pattern = static_cast<unsigned char*>(region.get_address());
  118. for(std::size_t i = 0
  119. ;i < FileSize
  120. ;++i, ++pattern){
  121. if(*pattern != static_cast<unsigned char>(i)){
  122. return 1;
  123. }
  124. }
  125. }
  126. {
  127. //Now test move semantics
  128. file_mapping mapping(get_filename().c_str(), read_only);
  129. file_mapping move_ctor(boost::move(mapping));
  130. file_mapping move_assign;
  131. move_assign = boost::move(move_ctor);
  132. mapping.swap(move_assign);
  133. file_mapping ret(get_file_mapping());
  134. }
  135. }
  136. catch(std::exception &exc){
  137. file_mapping::remove(get_filename().c_str());
  138. std::cout << "Unhandled exception: " << exc.what() << std::endl;
  139. throw;
  140. }
  141. file_mapping::remove(get_filename().c_str());
  142. return 0;
  143. }
  144. #include <boost/interprocess/detail/config_end.hpp>