summaryrefslogtreecommitdiffstats
path: root/common/Blob.cpp
blob: 3d025218faee38af5f240d7c47717ee83dc8066d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*
 * File:	Blob.cpp
 *
 * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
 * See included license file for license details.
 */

#include "Blob.h"
#include <stdexcept>
#include <stdlib.h>
#include <string.h>

Blob::Blob()
:	m_data(0),
	m_length(0)
{
}

//! Makes a local copy of the \a data argument.
//!
Blob::Blob(const uint8_t * data, unsigned length)
:	m_data(0),
	m_length(length)
{
	m_data = reinterpret_cast<uint8_t*>(malloc(length));
	memcpy(m_data, data, length);
}

//! Makes a local copy of the data owned by \a other.
//!
Blob::Blob(const Blob & other)
:	m_data(0),
	m_length(other.m_length)
{
	m_data = reinterpret_cast<uint8_t *>(malloc(m_length));
	memcpy(m_data, other.m_data, m_length);
}

//! Disposes of the binary data associated with this object.
Blob::~Blob()
{
	if (m_data)
	{
		free(m_data);
	}
}

//! Copies \a data onto the blob's data. The blob does not assume ownership
//! of \a data.
//!
//! \param data Pointer to a buffer containing the data which will be copied
//!		into the blob.
//! \param length Number of bytes pointed to by \a data.
void Blob::setData(const uint8_t * data, unsigned length)
{
	setLength(length);
	memcpy(m_data, data, length);
}

//! Sets the #m_length member variable to \a length and resizes #m_data to
//! the new length. The contents of #m_data past any previous contents are undefined.
//! If the new \a length is 0 then the data will be freed and a subsequent call
//! to getData() will return NULL.
//!
//! \param length New length of the blob's data in bytes.
void Blob::setLength(unsigned length)
{
	if (length == 0)
	{
		clear();
		return;
	}
	
	// Allocate new block.
	if (!m_data)
	{
		m_data = reinterpret_cast<uint8_t*>(malloc(length));
		if (!m_data)
		{
			throw std::runtime_error("failed to allocate memory");
		}
	}
	// Reallocate previous block.
	else
	{
		void * newBlob = realloc(m_data, length);
		if (!newBlob)
		{
			throw std::runtime_error("failed to reallocate memory");
		}
		m_data = reinterpret_cast<uint8_t*>(newBlob);
	}
	
	// Set length.
	m_length = length;
}

void Blob::append(const uint8_t * newData, unsigned newDataLength)
{
	unsigned oldLength = m_length;
	
	setLength(m_length + newDataLength);
	
	memcpy(m_data + oldLength, newData, newDataLength);
}

void Blob::clear()
{
	if (m_data)
	{
		free(m_data);
		m_data = NULL;
	}
	
	m_length = 0;
}

void Blob::relinquish()
{
	m_data = NULL;
	m_length = 0;
}