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