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
13Blob::Blob()
14:	m_data(0),
15	m_length(0)
16{
17}
18
19//! Makes a local copy of the \a data argument.
20//!
21Blob::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//!
31Blob::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.
40Blob::~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.
54void 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.
66void 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
98void 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
107void Blob::clear()
108{
109	if (m_data)
110	{
111		free(m_data);
112		m_data = NULL;
113	}
114
115	m_length = 0;
116}
117
118void Blob::relinquish()
119{
120	m_data = NULL;
121	m_length = 0;
122}
123
124