1 // Copyright (c) 2012, Robert Escriva
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met:
6 //
7 //     * Redistributions of source code must retain the above copyright notice,
8 //       this list of conditions and the following disclaimer.
9 //     * Redistributions in binary form must reproduce the above copyright
10 //       notice, this list of conditions and the following disclaimer in the
11 //       documentation and/or other materials provided with the distribution.
12 //     * Neither the name of this project nor the names of its contributors may
13 //       be used to endorse or promote products derived from this software
14 //       without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 // POSSIBILITY OF SUCH DAMAGE.
27 
28 // C
29 #include <stddef.h>
30 
31 // STL
32 #include <memory>
33 
34 // e
35 #include "e/buffer.h"
36 
37 using e::buffer;
38 
39 void*
operator new(size_t,size_t num)40 buffer :: operator new (size_t, size_t num)
41 {
42     return new char[offsetof(buffer, m_data) + num];
43 }
44 
45 void
operator delete(void * mem)46 buffer :: operator delete (void* mem)
47 {
48     delete[] static_cast<char*>(mem);
49 }
50 
buffer(size_t sz)51 buffer :: buffer(size_t sz)
52     : m_cap(sz)
53     , m_size(0)
54     , m_data()
55 {
56 }
57 
buffer(const char * buf,size_t sz)58 buffer :: buffer(const char* buf, size_t sz)
59     : m_cap(sz)
60     , m_size(sz)
61     , m_data()
62 {
63     memmove(m_data, buf, sz);
64 }
65 
~buffer()66 buffer :: ~buffer() throw ()
67 {
68 }
69 
70 bool
cmp(const char * buf,size_t sz) const71 buffer :: cmp(const char* buf, size_t sz) const
72 {
73     if (m_size == sz)
74     {
75         return memcmp(m_data, buf, sz) == 0;
76     }
77 
78     return false;
79 }
80 
81 buffer*
copy() const82 buffer :: copy() const
83 {
84     std::auto_ptr<buffer> ret(create(m_cap));
85     ret->m_cap = m_cap;
86     ret->m_size = m_size;
87     memmove(ret->m_data, m_data, m_cap);
88     return ret.release();
89 }
90 
91 void
resize(size_t sz)92 buffer :: resize(size_t sz)
93 {
94     assert(sz <= m_cap);
95     m_size = sz;
96 }
97 
98 e::packer
pack()99 buffer :: pack()
100 {
101     return pack_at(0);
102 }
103 
104 e::packer
pack_at(size_t off)105 buffer :: pack_at(size_t off)
106 {
107     return packer(this, off);
108 }
109 
110 e::unpacker
unpack()111 buffer :: unpack()
112 {
113     return unpack_from(0);
114 }
115 
116 e::unpacker
unpack_from(size_t off)117 buffer :: unpack_from(size_t off)
118 {
119     if (off > m_size)
120     {
121         return e::unpacker::error_out();
122     }
123 
124     return e::unpacker(m_data + off, m_size - off);
125 }
126