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