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