source: box/trunk/lib/common/StreamableMemBlock.cpp @ 2493

Revision 2493, 9.0 KB checked in by chris, 3 years ago (diff)

gcc 4.3 and 4.4 compile fixes, thanks to Reinhard Tartler and the Debian
project. See also:

 http://patch-tracking.debian.net/package/boxbackup/0.11~rc2+r2072-1
 http://lists.warhead.org.uk/pipermail/boxbackup/2009-April/005159.html

  • Property svn:eol-style set to native
Line 
1// --------------------------------------------------------------------------
2//
3// File
4//              Name:    StreamableMemBlock.cpp
5//              Purpose: Memory blocks which can be loaded and saved from streams
6//              Created: 2003/09/05
7//
8// --------------------------------------------------------------------------
9
10#include "Box.h"
11
12#include <new>
13#include <cstdlib>
14#include <string.h>
15
16#include "StreamableMemBlock.h"
17#include "IOStream.h"
18
19#include "MemLeakFindOn.h"
20
21// --------------------------------------------------------------------------
22//
23// Function
24//              Name:    StreamableMemBlock::StreamableMemBlock()
25//              Purpose: Constructor, making empty block
26//              Created: 2003/09/05
27//
28// --------------------------------------------------------------------------
29StreamableMemBlock::StreamableMemBlock()
30        : mpBuffer(0),
31          mSize(0)
32{
33}
34
35// --------------------------------------------------------------------------
36//
37// Function
38//              Name:    StreamableMemBlock::StreamableMemBlock(void *, int)
39//              Purpose: Create block, copying data from another bit of memory
40//              Created: 2003/09/05
41//
42// --------------------------------------------------------------------------
43StreamableMemBlock::StreamableMemBlock(void *pBuffer, int Size)
44        : mpBuffer(0),
45          mSize(0)
46{
47        AllocateBlock(Size);
48        ::memcpy(mpBuffer, pBuffer, Size);
49}
50
51// --------------------------------------------------------------------------
52//
53// Function
54//              Name:    StreamableMemBlock::StreamableMemBlock(int)
55//              Purpose: Create block, initialising it to all zeros
56//              Created: 2003/09/05
57//
58// --------------------------------------------------------------------------
59StreamableMemBlock::StreamableMemBlock(int Size)
60        : mpBuffer(0),
61          mSize(0)
62{
63        AllocateBlock(Size);
64        ::memset(mpBuffer, 0, Size);
65}
66
67// --------------------------------------------------------------------------
68//
69// Function
70//              Name:    StreamableMemBlock::StreamableMemBlock(const StreamableMemBlock &)
71//              Purpose: Copy constructor
72//              Created: 2003/09/05
73//
74// --------------------------------------------------------------------------
75StreamableMemBlock::StreamableMemBlock(const StreamableMemBlock &rToCopy)
76        : mpBuffer(0),
77          mSize(0)
78{
79        AllocateBlock(rToCopy.mSize);
80        ::memcpy(mpBuffer, rToCopy.mpBuffer, mSize);
81}
82
83
84// --------------------------------------------------------------------------
85//
86// Function
87//              Name:    StreamableMemBlock::Set(void *, int)
88//              Purpose: Set the contents of the block
89//              Created: 2003/09/05
90//
91// --------------------------------------------------------------------------
92void StreamableMemBlock::Set(void *pBuffer, int Size)
93{
94        FreeBlock();
95        AllocateBlock(Size);
96        ::memcpy(mpBuffer, pBuffer, Size);
97}
98
99
100// --------------------------------------------------------------------------
101//
102// Function
103//              Name:    StreamableMemBlock::Set(IOStream &)
104//              Purpose: Set from stream. Stream must support BytesLeftToRead()
105//              Created: 2003/09/05
106//
107// --------------------------------------------------------------------------
108void StreamableMemBlock::Set(IOStream &rStream, int Timeout)
109{
110        // Get size
111        IOStream::pos_type size = rStream.BytesLeftToRead();
112        if(size == IOStream::SizeOfStreamUnknown)
113        {
114                THROW_EXCEPTION(CommonException, StreamDoesntHaveRequiredProperty)
115        }
116       
117        // Allocate a new block (this way to be exception safe)
118        char *pblock = (char*)malloc(size);
119        if(pblock == 0)
120        {
121                throw std::bad_alloc();
122        }
123       
124        try
125        {
126                // Read in
127                if(!rStream.ReadFullBuffer(pblock, size, 0 /* not interested in bytes read if this fails */))
128                {
129                        THROW_EXCEPTION(CommonException, StreamableMemBlockIncompleteRead)
130                }
131       
132                // Free the block ready for replacement
133                FreeBlock();
134        }
135        catch(...)
136        {
137                ::free(pblock);
138                throw;
139        }
140       
141        // store...
142        ASSERT(mpBuffer == 0);
143        mpBuffer = pblock;
144        mSize = size;
145}
146
147
148// --------------------------------------------------------------------------
149//
150// Function
151//              Name:    StreamableMemBlock::Set(const StreamableMemBlock &)
152//              Purpose: Set from other block.
153//              Created: 2003/09/06
154//
155// --------------------------------------------------------------------------
156void StreamableMemBlock::Set(const StreamableMemBlock &rBlock)
157{
158        Set(rBlock.mpBuffer, rBlock.mSize);
159}
160
161
162// --------------------------------------------------------------------------
163//
164// Function
165//              Name:    StreamableMemBlock::~StreamableMemBlock()
166//              Purpose: Destructor
167//              Created: 2003/09/05
168//
169// --------------------------------------------------------------------------
170StreamableMemBlock::~StreamableMemBlock()
171{
172        FreeBlock();
173}
174
175
176// --------------------------------------------------------------------------
177//
178// Function
179//              Name:    StreamableMemBlock::FreeBlock()
180//              Purpose: Protected. Frees block of memory
181//              Created: 2003/09/05
182//
183// --------------------------------------------------------------------------
184void StreamableMemBlock::FreeBlock()
185{
186        if(mpBuffer != 0)
187        {
188                ::free(mpBuffer);
189        }
190        mpBuffer = 0;
191        mSize = 0;
192}
193
194
195// --------------------------------------------------------------------------
196//
197// Function
198//              Name:    StreamableMemBlock::AllocateBlock(int)
199//              Purpose: Protected. Allocate the block of memory
200//              Created: 2003/09/05
201//
202// --------------------------------------------------------------------------
203void StreamableMemBlock::AllocateBlock(int Size)
204{
205        ASSERT(mpBuffer == 0);
206        if(Size > 0)
207        {
208                mpBuffer = ::malloc(Size);
209                if(mpBuffer == 0)
210                {
211                        throw std::bad_alloc();
212                }
213        }
214        mSize = Size;
215}
216
217
218// --------------------------------------------------------------------------
219//
220// Function
221//              Name:    StreamableMemBlock::ResizeBlock(int)
222//              Purpose: Protected. Resizes the allocated block.
223//              Created: 3/12/03
224//
225// --------------------------------------------------------------------------
226void StreamableMemBlock::ResizeBlock(int Size)
227{
228        ASSERT(Size > 0);
229        if(Size > 0)
230        {
231                void *pnewBuffer = ::realloc(mpBuffer, Size);
232                if(pnewBuffer == 0)
233                {
234                        throw std::bad_alloc();
235                }
236                mpBuffer = pnewBuffer;
237        }
238        mSize = Size;
239}
240
241
242// --------------------------------------------------------------------------
243//
244// Function
245//              Name:    StreamableMemBlock::ReadFromStream(IOStream &, int)
246//              Purpose: Read the block in from a stream
247//              Created: 2003/09/05
248//
249// --------------------------------------------------------------------------
250void StreamableMemBlock::ReadFromStream(IOStream &rStream, int Timeout)
251{
252        // Get the size of the block
253        int32_t size_s;
254        if(!rStream.ReadFullBuffer(&size_s, sizeof(size_s), 0 /* not interested in bytes read if this fails */))
255        {
256                THROW_EXCEPTION(CommonException, StreamableMemBlockIncompleteRead)
257        }
258       
259        int size = ntohl(size_s);
260       
261       
262        // Allocate a new block (this way to be exception safe)
263        char *pblock = (char*)malloc(size);
264        if(pblock == 0)
265        {
266                throw std::bad_alloc();
267        }
268       
269        try
270        {
271                // Read in
272                if(!rStream.ReadFullBuffer(pblock, size, 0 /* not interested in bytes read if this fails */))
273                {
274                        THROW_EXCEPTION(CommonException, StreamableMemBlockIncompleteRead)
275                }
276       
277                // Free the block ready for replacement
278                FreeBlock();
279        }
280        catch(...)
281        {
282                ::free(pblock);
283                throw;
284        }
285       
286        // store...
287        ASSERT(mpBuffer == 0);
288        mpBuffer = pblock;
289        mSize = size;
290}
291
292// --------------------------------------------------------------------------
293//
294// Function
295//              Name:    StreamableMemBlock::WriteToStream(IOStream &)
296//              Purpose: Write the block to a stream
297//              Created: 2003/09/05
298//
299// --------------------------------------------------------------------------
300void StreamableMemBlock::WriteToStream(IOStream &rStream) const
301{
302        int32_t sizenbo = htonl(mSize);
303        // Size
304        rStream.Write(&sizenbo, sizeof(sizenbo));
305        // Buffer
306        if(mSize > 0)
307        {
308                rStream.Write(mpBuffer, mSize);
309        }
310}
311
312// --------------------------------------------------------------------------
313//
314// Function
315//              Name:    StreamableMemBlock::WriteEmptyBlockToStream(IOStream &)
316//              Purpose: Writes an empty block to a stream.
317//              Created: 2003/09/05
318//
319// --------------------------------------------------------------------------
320void StreamableMemBlock::WriteEmptyBlockToStream(IOStream &rStream)
321{
322        int32_t sizenbo = htonl(0);
323        rStream.Write(&sizenbo, sizeof(sizenbo));
324}
325
326
327// --------------------------------------------------------------------------
328//
329// Function
330//              Name:    StreamableMemBlock::GetBuffer()
331//              Purpose: Get pointer to buffer
332//              Created: 2003/09/05
333//
334// --------------------------------------------------------------------------
335void *StreamableMemBlock::GetBuffer() const
336{
337        if(mSize == 0)
338        {
339                // Return something which isn't a null pointer
340                static const int validptr = 0;
341                return (void*)&validptr;
342        }
343       
344        // return the buffer
345        ASSERT(mpBuffer != 0);
346        return mpBuffer;
347}
348
349// --------------------------------------------------------------------------
350//
351// Function
352//              Name:    StreamableMemBlock::operator==(const StreamableMemBlock &)
353//              Purpose: Test for equality of memory blocks
354//              Created: 2003/09/06
355//
356// --------------------------------------------------------------------------
357bool StreamableMemBlock::operator==(const StreamableMemBlock &rCompare) const
358{
359        if(mSize != rCompare.mSize) return false;
360        if(mSize == 0 && rCompare.mSize == 0) return true;      // without memory comparison!
361        return ::memcmp(mpBuffer, rCompare.mpBuffer, mSize) == 0;
362}
363
364
Note: See TracBrowser for help on using the repository browser.