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
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
21 using namespace boost::interprocess;
22
get_filename()23 inline std::string get_filename()
24 {
25 std::string ret (ipcdetail::get_temporary_path());
26 ret += "/";
27 ret += test::get_process_id_name();
28 return ret;
29 }
30
get_file_mapping()31 file_mapping get_file_mapping()
32 {
33 file_mapping f;
34 return file_mapping(boost::move(f));
35 }
36
main()37 int main ()
38 {
39 try{
40 const std::size_t FileSize = 99999*2;
41 {
42 //Create file with given size
43 std::ofstream file(get_filename().c_str(), std::ios::binary | std::ios::trunc);
44 file.seekp(static_cast<std::streamoff>(FileSize-1));
45 file.write("", 1);
46 }
47
48 {
49 //Create a file mapping
50 file_mapping mapping(get_filename().c_str(), read_write);
51 //Create two mapped regions, one half of the file each
52 mapped_region region (mapping
53 ,read_write
54 ,0
55 ,FileSize/2
56 );
57
58 mapped_region region2(mapping
59 ,read_write
60 ,FileSize/2
61 ,FileSize - FileSize/2
62 );
63
64 //Fill two regions with a pattern
65 unsigned char *filler = static_cast<unsigned char*>(region.get_address());
66 for(std::size_t i = 0
67 ;i < FileSize/2
68 ;++i){
69 *filler++ = static_cast<unsigned char>(i);
70 }
71
72 filler = static_cast<unsigned char*>(region2.get_address());
73 for(std::size_t i = FileSize/2
74 ;i < FileSize
75 ;++i){
76 *filler++ = static_cast<unsigned char>(i);
77 }
78 if(!region.flush(0, 0, false)){
79 return 1;
80 }
81
82 if(!region2.flush(0, 0, true)){
83 return 1;
84 }
85 }
86
87 //See if the pattern is correct in the file
88 {
89 //Open the file
90 std::ifstream file(get_filename().c_str(), std::ios::binary);
91
92 //Create a memory buffer
93 boost::container::vector<unsigned char> memory(FileSize/2 +1);
94
95 //Fill buffer
96 file.read(static_cast<char*>(static_cast<void*>(memory.data()))
97 , FileSize/2);
98
99 unsigned char *checker = memory.data();
100 //Check pattern
101 for(std::size_t i = 0
102 ;i < FileSize/2
103 ;++i){
104 if(*checker++ != static_cast<unsigned char>(i)){
105 return 1;
106 }
107 }
108
109 //Fill buffer
110 file.read(static_cast<char*>(static_cast<void*>(memory.data()))
111 , FileSize - FileSize/2);
112
113 checker = memory.data();
114 //Check pattern
115 for(std::size_t i = FileSize/2
116 ;i < FileSize
117 ;++i){
118 if(*checker++ != static_cast<unsigned char>(i)){
119 return 1;
120 }
121 }
122 }
123
124 //Now check the pattern mapping a single read only mapped_region
125 {
126 //Create a file mapping
127 file_mapping mapping(get_filename().c_str(), read_only);
128
129 //Create a single regions, mapping all the file
130 mapped_region region (mapping
131 ,read_only
132 );
133
134 //Check pattern
135 unsigned char *pattern = static_cast<unsigned char*>(region.get_address());
136 for(std::size_t i = 0
137 ;i < FileSize
138 ;++i, ++pattern){
139 if(*pattern != static_cast<unsigned char>(i)){
140 return 1;
141 }
142 }
143 }
144 {
145 //Now test move semantics
146 file_mapping mapping(get_filename().c_str(), read_only);
147 file_mapping move_ctor(boost::move(mapping));
148 file_mapping move_assign;
149 move_assign = boost::move(move_ctor);
150 mapping.swap(move_assign);
151 file_mapping ret(get_file_mapping());
152 }
153 }
154 catch(std::exception &exc){
155 file_mapping::remove(get_filename().c_str());
156 std::cout << "Unhandled exception: " << exc.what() << std::endl;
157 throw;
158 }
159 file_mapping::remove(get_filename().c_str());
160 return 0;
161 }
162