1 /*
2  * File:  Blob.cpp
3  *
4  * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
5  * See included license file for license details.
6  */
7 
8 #include "Blob.h"
9 #include <stdexcept>
10 #include <stdlib.h>
11 #include <string.h>
12 
Blob()13 Blob::Blob()
14 :         m_data(0),
15           m_length(0)
16 {
17 }
18 
19 //! Makes a local copy of the \a data argument.
20 //!
Blob(const uint8_t * data,unsigned length)21 Blob::Blob(const uint8_t * data, unsigned length)
22 :         m_data(0),
23           m_length(length)
24 {
25           m_data = reinterpret_cast<uint8_t*>(malloc(length));
26           memcpy(m_data, data, length);
27 }
28 
29 //! Makes a local copy of the data owned by \a other.
30 //!
Blob(const Blob & other)31 Blob::Blob(const Blob & other)
32 :         m_data(0),
33           m_length(other.m_length)
34 {
35           m_data = reinterpret_cast<uint8_t *>(malloc(m_length));
36           memcpy(m_data, other.m_data, m_length);
37 }
38 
39 //! Disposes of the binary data associated with this object.
~Blob()40 Blob::~Blob()
41 {
42           if (m_data)
43           {
44                     free(m_data);
45           }
46 }
47 
48 //! Copies \a data onto the blob's data. The blob does not assume ownership
49 //! of \a data.
50 //!
51 //! \param data Pointer to a buffer containing the data which will be copied
52 //!                 into the blob.
53 //! \param length Number of bytes pointed to by \a data.
setData(const uint8_t * data,unsigned length)54 void Blob::setData(const uint8_t * data, unsigned length)
55 {
56           setLength(length);
57           memcpy(m_data, data, length);
58 }
59 
60 //! Sets the #m_length member variable to \a length and resizes #m_data to
61 //! the new length. The contents of #m_data past any previous contents are undefined.
62 //! If the new \a length is 0 then the data will be freed and a subsequent call
63 //! to getData() will return NULL.
64 //!
65 //! \param length New length of the blob's data in bytes.
setLength(unsigned length)66 void Blob::setLength(unsigned length)
67 {
68           if (length == 0)
69           {
70                     clear();
71                     return;
72           }
73 
74           // Allocate new block.
75           if (!m_data)
76           {
77                     m_data = reinterpret_cast<uint8_t*>(malloc(length));
78                     if (!m_data)
79                     {
80                               throw std::runtime_error("failed to allocate memory");
81                     }
82           }
83           // Reallocate previous block.
84           else
85           {
86                     void * newBlob = realloc(m_data, length);
87                     if (!newBlob)
88                     {
89                               throw std::runtime_error("failed to reallocate memory");
90                     }
91                     m_data = reinterpret_cast<uint8_t*>(newBlob);
92           }
93 
94           // Set length.
95           m_length = length;
96 }
97 
append(const uint8_t * newData,unsigned newDataLength)98 void Blob::append(const uint8_t * newData, unsigned newDataLength)
99 {
100           unsigned oldLength = m_length;
101 
102           setLength(m_length + newDataLength);
103 
104           memcpy(m_data + oldLength, newData, newDataLength);
105 }
106 
clear()107 void Blob::clear()
108 {
109           if (m_data)
110           {
111                     free(m_data);
112                     m_data = NULL;
113           }
114 
115           m_length = 0;
116 }
117 
relinquish()118 void Blob::relinquish()
119 {
120           m_data = NULL;
121           m_length = 0;
122 }
123 
124