• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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