]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | ////////////////////////////////////////////////////////////////////////////// |
2 | // | |
3 | // (C) Copyright Ion Gaztanaga 2006-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 | ////////////////////////////////////////////////////////////////////////////// | |
1e59de90 | 10 | |
7c673cae FG |
11 | #include <boost/interprocess/detail/workaround.hpp> |
12 | //[doc_bufferstream | |
13 | #include <boost/interprocess/managed_shared_memory.hpp> | |
14 | #include <boost/interprocess/streams/bufferstream.hpp> | |
15 | #include <vector> | |
16 | #include <iterator> | |
17 | #include <cstddef> | |
18 | //<- | |
19 | #include "../test/get_process_id_name.hpp" | |
20 | //-> | |
21 | ||
22 | using namespace boost::interprocess; | |
23 | ||
24 | int main () | |
25 | { | |
26 | //Remove shared memory on construction and destruction | |
27 | struct shm_remove | |
28 | { | |
29 | //<- | |
30 | #if 1 | |
31 | shm_remove() { shared_memory_object::remove(test::get_process_id_name()); } | |
32 | ~shm_remove(){ shared_memory_object::remove(test::get_process_id_name()); } | |
33 | #else | |
34 | //-> | |
35 | shm_remove() { shared_memory_object::remove("MySharedMemory"); } | |
36 | ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); } | |
37 | //<- | |
38 | #endif | |
39 | //-> | |
40 | } remover; | |
41 | //<- | |
42 | (void)remover; | |
43 | //-> | |
44 | ||
45 | //Create shared memory | |
46 | //<- | |
47 | #if 1 | |
48 | managed_shared_memory segment(create_only,test::get_process_id_name(), 65536); | |
49 | #else | |
50 | //-> | |
51 | managed_shared_memory segment(create_only, | |
52 | "MySharedMemory", //segment name | |
53 | 65536); | |
54 | //<- | |
55 | #endif | |
56 | //-> | |
57 | ||
58 | //Fill data | |
59 | std::vector<int> data; | |
60 | data.reserve(100); | |
1e59de90 TL |
61 | for(std::size_t i = 0; i < 100; ++i){ |
62 | data.push_back((int)i); | |
7c673cae FG |
63 | } |
64 | const std::size_t BufferSize = 100*5; | |
65 | ||
66 | //Allocate a buffer in shared memory to write data | |
67 | char *my_cstring = | |
1e59de90 | 68 | segment.construct<char>("MyCString")[BufferSize]('\0'); |
7c673cae FG |
69 | bufferstream mybufstream(my_cstring, BufferSize); |
70 | ||
71 | //Now write data to the buffer | |
1e59de90 | 72 | for(std::size_t i = 0; i < 100; ++i){ |
7c673cae FG |
73 | mybufstream << data[i] << std::endl; |
74 | } | |
75 | ||
76 | //Check there was no overflow attempt | |
77 | assert(mybufstream.good()); | |
78 | ||
79 | //Extract all values from the shared memory string | |
80 | //directly to a vector. | |
81 | std::vector<int> data2; | |
82 | std::istream_iterator<int> it(mybufstream), itend; | |
83 | std::copy(it, itend, std::back_inserter(data2)); | |
84 | ||
85 | //This extraction should have ended will fail error since | |
86 | //the numbers formatted in the buffer end before the end | |
87 | //of the buffer. (Otherwise it would trigger eofbit) | |
88 | assert(mybufstream.fail()); | |
89 | ||
90 | //Compare data | |
91 | assert(std::equal(data.begin(), data.end(), data2.begin())); | |
92 | ||
93 | //Clear errors and rewind | |
94 | mybufstream.clear(); | |
95 | mybufstream.seekp(0, std::ios::beg); | |
96 | ||
97 | //Now write again the data trying to do a buffer overflow | |
1e59de90 TL |
98 | for(std::size_t i = 0, m = data.size()*5; i < m; ++i){ |
99 | mybufstream << data[i%5u] << std::endl; | |
7c673cae FG |
100 | } |
101 | ||
102 | //Now make sure badbit is active | |
103 | //which means overflow attempt. | |
104 | assert(!mybufstream.good()); | |
105 | assert(mybufstream.bad()); | |
106 | segment.destroy_ptr(my_cstring); | |
107 | return 0; | |
108 | } | |
109 | //] | |
1e59de90 | 110 |