1 /*
2  *
3  * Copyright (c) 1998-2002
4  * John Maddock
5  *
6  * Use, modification and distribution are subject to the
7  * Boost Software License, Version 1.0. (See accompanying file
8  * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9  *
10  */
11 
12  /*
13   *   LOCATION:    see http://www.boost.org for most recent version.
14   *   FILE         regex_raw_buffer.hpp
15   *   VERSION      see <boost/version.hpp>
16   *   DESCRIPTION: Raw character buffer for regex code.
17   *                Note this is an internal header file included
18   *                by regex.hpp, do not include on its own.
19   */
20 
21 #ifndef BOOST_REGEX_RAW_BUFFER_HPP
22 #define BOOST_REGEX_RAW_BUFFER_HPP
23 
24 #ifndef BOOST_REGEX_CONFIG_HPP
25 #include <boost/regex/config.hpp>
26 #endif
27 
28 #include <algorithm>
29 #include <cstddef>
30 
31 namespace boost{
32    namespace BOOST_REGEX_DETAIL_NS{
33 
34 struct empty_padding{};
35 
36 union padding
37 {
38    void* p;
39    unsigned int i;
40 };
41 
42 template <int N>
43 struct padding3
44 {
45    enum{
46       padding_size = 8,
47       padding_mask = 7
48    };
49 };
50 
51 template<>
52 struct padding3<2>
53 {
54    enum{
55       padding_size = 2,
56       padding_mask = 1
57    };
58 };
59 
60 template<>
61 struct padding3<4>
62 {
63    enum{
64       padding_size = 4,
65       padding_mask = 3
66    };
67 };
68 
69 template<>
70 struct padding3<8>
71 {
72    enum{
73       padding_size = 8,
74       padding_mask = 7
75    };
76 };
77 
78 template<>
79 struct padding3<16>
80 {
81    enum{
82       padding_size = 16,
83       padding_mask = 15
84    };
85 };
86 
87 enum{
88    padding_size = padding3<sizeof(padding)>::padding_size,
89    padding_mask = padding3<sizeof(padding)>::padding_mask
90 };
91 
92 //
93 // class raw_storage
94 // basically this is a simplified vector<unsigned char>
95 // this is used by basic_regex for expression storage
96 //
97 
98 class raw_storage
99 {
100 public:
101    typedef std::size_t           size_type;
102    typedef unsigned char*        pointer;
103 private:
104    pointer last, start, end;
105 public:
106 
107    raw_storage();
108    raw_storage(size_type n);
109 
~raw_storage()110    ~raw_storage()
111    {
112       ::operator delete(start);
113    }
114 
resize(size_type n)115    void  resize(size_type n)
116    {
117       size_type newsize = start ? last - start : 1024;
118       while (newsize < n)
119          newsize *= 2;
120       size_type datasize = end - start;
121       // extend newsize to WORD/DWORD boundary:
122       newsize = (newsize + padding_mask) & ~(padding_mask);
123 
124       // allocate and copy data:
125       pointer ptr = static_cast<pointer>(::operator new(newsize));
126       BOOST_REGEX_NOEH_ASSERT(ptr)
127          if (start)
128             std::memcpy(ptr, start, datasize);
129 
130       // get rid of old buffer:
131       ::operator delete(start);
132 
133       // and set up pointers:
134       start = ptr;
135       end = ptr + datasize;
136       last = ptr + newsize;
137    }
138 
extend(size_type n)139    void*  extend(size_type n)
140    {
141       if(size_type(last - end) < n)
142          resize(n + (end - start));
143       pointer result = end;
144       end += n;
145       return result;
146    }
147 
insert(size_type pos,size_type n)148    void*  insert(size_type pos, size_type n)
149    {
150       BOOST_REGEX_ASSERT(pos <= size_type(end - start));
151       if (size_type(last - end) < n)
152          resize(n + (end - start));
153       void* result = start + pos;
154       std::memmove(start + pos + n, start + pos, (end - start) - pos);
155       end += n;
156       return result;
157    }
158 
size()159    size_type  size()
160    {
161       return size_type(end - start);
162    }
163 
capacity()164    size_type  capacity()
165    {
166       return size_type(last - start);
167    }
168 
data() const169    void*  data()const
170    {
171       return start;
172    }
173 
index(void * ptr)174    size_type  index(void* ptr)
175    {
176       return size_type(static_cast<pointer>(ptr) - static_cast<pointer>(data()));
177    }
178 
clear()179    void  clear()
180    {
181       end = start;
182    }
183 
align()184    void  align()
185    {
186       // move end up to a boundary:
187       end = start + (((end - start) + padding_mask) & ~padding_mask);
188    }
swap(raw_storage & that)189    void swap(raw_storage& that)
190    {
191       std::swap(start, that.start);
192       std::swap(end, that.end);
193       std::swap(last, that.last);
194   }
195 };
196 
raw_storage()197 inline raw_storage::raw_storage()
198 {
199    last = start = end = 0;
200 }
201 
raw_storage(size_type n)202 inline raw_storage::raw_storage(size_type n)
203 {
204    start = end = static_cast<pointer>(::operator new(n));
205    BOOST_REGEX_NOEH_ASSERT(start)
206    last = start + n;
207 }
208 
209 } // namespace BOOST_REGEX_DETAIL_NS
210 } // namespace boost
211 
212 #endif
213 
214