athena/src/athena/MemoryWriter.cpp

328 lines
6.9 KiB
C++
Raw Normal View History

2016-03-04 15:00:12 -08:00
#include "athena/MemoryWriter.hpp"
2014-04-20 02:14:15 -07:00
#include <stdio.h>
#include <string.h>
#include <vector>
#include <iostream>
#ifdef HW_RVL
#include <malloc.h>
#endif // HW_RVL
2016-03-04 15:00:12 -08:00
namespace athena
2014-04-20 02:14:15 -07:00
{
namespace io
{
2016-03-19 21:08:23 -07:00
MemoryWriter::MemoryWriter(atUint8* data, atUint64 length, bool takeOwnership)
: m_data((atUint8*)data),
2014-04-20 02:14:15 -07:00
m_length(length),
2016-03-19 21:08:23 -07:00
m_position(0),
m_bufferOwned(takeOwnership)
{
if (!data)
2015-07-21 22:37:22 -07:00
{
atError("data cannot be NULL");
2015-07-22 13:40:22 -07:00
setError();
2015-07-21 22:37:22 -07:00
return;
}
if (length == 0)
2015-07-21 22:37:22 -07:00
{
atError("length cannot be 0");
2015-07-22 13:40:22 -07:00
setError();
2015-07-21 22:37:22 -07:00
return;
}
}
2014-04-20 02:14:15 -07:00
2016-03-19 21:08:23 -07:00
MemoryWriter::~MemoryWriter()
{
if (m_bufferOwned)
delete m_data;
m_data = nullptr;
m_length = 0;
}
MemoryCopyWriter::MemoryCopyWriter(atUint8* data, atUint64 length)
{
2015-07-07 23:34:59 -07:00
m_data = data;
m_length = length;
m_position = 0;
2016-03-19 21:08:23 -07:00
m_bufferOwned = false;
2015-07-07 23:34:59 -07:00
if (length == 0)
2015-07-21 22:37:22 -07:00
{
atError("length cannot be 0");
2015-07-22 13:40:22 -07:00
setError();
2015-07-21 22:37:22 -07:00
return;
}
m_dataCopy.reset(new atUint8[length]);
m_data = m_dataCopy.get();
if (data)
memcpy(m_data, data, length);
}
MemoryCopyWriter::MemoryCopyWriter(const std::string& filename)
2014-04-20 02:14:15 -07:00
{
m_filepath = filename;
2014-04-20 02:14:15 -07:00
m_length = 0x10;
m_position = 0;
m_dataCopy.reset(new atUint8[m_length]);
m_data = m_dataCopy.get();
2016-03-19 21:08:23 -07:00
m_bufferOwned = false;
2014-04-20 02:14:15 -07:00
if (!m_data)
2015-07-21 22:37:22 -07:00
{
atError("Could not allocate memory!");
2015-07-22 13:40:22 -07:00
setError();
2015-07-21 22:37:22 -07:00
return;
}
2014-04-20 02:14:15 -07:00
}
2015-03-01 12:42:39 -08:00
void MemoryWriter::seek(atInt64 position, SeekOrigin origin)
2015-07-07 23:34:59 -07:00
{
switch (origin)
{
2016-03-19 21:08:23 -07:00
case SeekOrigin::Begin:
if (position < 0)
2015-07-21 22:37:22 -07:00
{
atError("Position outside stream bounds");
2015-07-22 13:40:22 -07:00
setError();
2015-07-21 22:37:22 -07:00
return;
}
2015-07-07 23:34:59 -07:00
if ((atUint64)position > m_length)
2015-07-21 22:37:22 -07:00
{
atError("data exceeds available buffer space");
2015-07-22 13:40:22 -07:00
setError();
2015-07-21 22:37:22 -07:00
return;
}
2015-07-07 23:34:59 -07:00
m_position = position;
break;
case SeekOrigin::Current:
if ((((atInt64)m_position + position) < 0))
2015-07-21 22:37:22 -07:00
{
atError("Position outside stream bounds");
2015-07-22 13:40:22 -07:00
setError();
2015-07-21 22:37:22 -07:00
return;
}
2015-07-07 23:34:59 -07:00
if (m_position + position > m_length)
2015-07-21 22:37:22 -07:00
{
atError("data exceeds available buffer space");
2015-07-22 13:40:22 -07:00
setError();
2015-07-21 22:37:22 -07:00
return;
}
2015-07-07 23:34:59 -07:00
m_position += position;
break;
case SeekOrigin::End:
if (((atInt64)m_length - position) < 0)
2015-07-21 22:37:22 -07:00
{
atError("Position outside stream bounds");
2015-07-22 13:40:22 -07:00
setError();
2015-07-21 22:37:22 -07:00
return;
}
2015-07-07 23:34:59 -07:00
if ((atUint64)position > m_length)
2015-07-21 22:37:22 -07:00
{
atError("data exceeds available buffer space");
2015-07-22 13:40:22 -07:00
setError();
2015-07-21 22:37:22 -07:00
return;
}
2015-07-07 23:34:59 -07:00
m_position = m_length - position;
break;
}
}
void MemoryCopyWriter::seek(atInt64 position, SeekOrigin origin)
2014-04-20 02:14:15 -07:00
{
switch (origin)
{
case SeekOrigin::Begin:
if (position < 0)
2015-07-21 22:37:22 -07:00
{
atError("Position outside stream bounds");
2015-07-22 13:40:22 -07:00
setError();
2015-07-21 22:37:22 -07:00
return;
}
2014-04-20 02:14:15 -07:00
if ((atUint64)position > m_length)
2014-04-20 02:14:15 -07:00
resize(position);
2015-05-18 20:24:56 -07:00
2014-04-20 02:14:15 -07:00
m_position = position;
2015-03-11 13:10:18 -07:00
break;
2015-05-18 20:24:56 -07:00
2014-04-20 02:14:15 -07:00
case SeekOrigin::Current:
if ((((atInt64)m_position + position) < 0))
2015-07-21 22:37:22 -07:00
{
atError("Position outside stream bounds");
2015-07-22 13:40:22 -07:00
setError();
2015-07-21 22:37:22 -07:00
return;
}
2014-04-20 02:14:15 -07:00
if (m_position + position > m_length)
resize(m_position + position);
m_position += position;
2015-03-11 13:10:18 -07:00
break;
2015-05-18 20:24:56 -07:00
2014-04-20 02:14:15 -07:00
case SeekOrigin::End:
if (((atInt64)m_length - position) < 0)
2015-07-21 22:37:22 -07:00
{
atError("Position outside stream bounds");
2015-07-22 13:40:22 -07:00
setError();
2015-07-21 22:37:22 -07:00
return;
}
2014-04-20 02:14:15 -07:00
if ((atUint64)position > m_length)
2014-04-20 02:14:15 -07:00
resize(position);
2015-05-18 20:24:56 -07:00
2014-04-20 02:14:15 -07:00
m_position = m_length - position;
2015-03-11 13:10:18 -07:00
break;
2014-04-20 02:14:15 -07:00
}
}
2016-03-19 21:08:23 -07:00
void MemoryWriter::setData(atUint8* data, atUint64 length, bool takeOwnership)
2014-04-20 02:14:15 -07:00
{
2016-03-19 21:08:23 -07:00
if (m_bufferOwned)
delete m_data;
m_data = (atUint8*)data;
2014-04-20 02:14:15 -07:00
m_length = length;
m_position = 0;
2016-03-19 21:08:23 -07:00
m_bufferOwned = takeOwnership;
2014-04-20 02:14:15 -07:00
}
void MemoryCopyWriter::setData(const atUint8* data, atUint64 length)
{
m_dataCopy.reset(new atUint8[length]);
m_data = m_dataCopy.get();
memcpy(m_data, data, length);
m_length = length;
m_position = 0;
2016-03-19 21:08:23 -07:00
m_bufferOwned = false;
}
2015-03-01 12:42:39 -08:00
atUint8* MemoryWriter::data() const
2014-04-20 02:14:15 -07:00
{
atUint8* ret = new atUint8[m_length];
2014-04-20 02:14:15 -07:00
memset(ret, 0, m_length);
memcpy(ret, m_data, m_length);
return ret;
}
2015-03-01 12:42:39 -08:00
void MemoryWriter::save(const std::string& filename)
2014-04-20 02:14:15 -07:00
{
if (filename.empty() && m_filepath.empty())
2015-07-21 22:37:22 -07:00
{
atError("No file specified, cannot save.");
2015-07-22 13:40:22 -07:00
setError();
2015-07-21 22:37:22 -07:00
return;
}
2014-04-20 02:14:15 -07:00
if (!filename.empty())
m_filepath = filename;
FILE* out = fopen(m_filepath.c_str(), "wb");
2015-05-18 20:24:56 -07:00
2014-04-20 02:14:15 -07:00
if (!out)
2015-07-21 22:37:22 -07:00
{
atError("Unable to open file '%s'", m_filepath.c_str());
2015-07-22 13:40:22 -07:00
setError();
2015-07-21 22:37:22 -07:00
return;
}
2014-04-20 02:14:15 -07:00
atUint64 done = 0;
atUint64 blocksize = BLOCKSZ;
2015-05-18 20:24:56 -07:00
2014-04-20 02:14:15 -07:00
do
{
if (blocksize > m_length - done)
blocksize = m_length - done;
atInt64 ret = fwrite(m_data + done, 1, blocksize, out);
2014-04-20 02:14:15 -07:00
if (ret < 0)
2015-07-21 22:37:22 -07:00
{
atError("Error writing data to disk");
2015-07-22 13:40:22 -07:00
setError();
2015-07-21 22:37:22 -07:00
return;
}
2014-04-20 02:14:15 -07:00
else if (ret == 0)
break;
done += blocksize;
2015-05-18 20:24:56 -07:00
}
while (done < m_length);
2014-04-20 02:14:15 -07:00
fclose(out);
}
2015-06-30 20:01:04 -07:00
void MemoryWriter::writeUBytes(const atUint8* data, atUint64 length)
2014-04-20 02:14:15 -07:00
{
2015-07-07 23:34:59 -07:00
if (!data)
2015-07-21 22:37:22 -07:00
{
atError("data cannnot be NULL");
2015-07-22 13:40:22 -07:00
setError();
2015-07-21 22:37:22 -07:00
return;
}
2015-07-07 23:34:59 -07:00
if (m_position + length > m_length)
2015-07-21 22:37:22 -07:00
{
atError("data length exceeds available buffer space");
2015-07-22 13:40:22 -07:00
setError();
2015-07-21 22:37:22 -07:00
return;
}
2015-07-07 23:34:59 -07:00
memcpy(reinterpret_cast<atInt8*>(m_data + m_position), data, length);
2015-07-07 23:34:59 -07:00
m_position += length;
}
2014-04-20 02:14:15 -07:00
2015-07-07 23:34:59 -07:00
void MemoryCopyWriter::writeUBytes(const atUint8* data, atUint64 length)
{
2014-04-20 02:14:15 -07:00
if (!data)
2015-07-21 22:37:22 -07:00
{
atError("data cannnot be NULL");
2015-07-22 13:40:22 -07:00
setError();
2015-07-21 22:37:22 -07:00
return;
}
2015-05-18 20:24:56 -07:00
2014-04-20 02:14:15 -07:00
if (m_position + length > m_length)
resize(m_position + length);
memcpy(reinterpret_cast<atInt8*>(m_data + m_position), data, length);
2014-04-20 02:14:15 -07:00
m_position += length;
}
2015-07-07 23:34:59 -07:00
void MemoryCopyWriter::resize(atUint64 newSize)
2014-04-20 02:14:15 -07:00
{
if (newSize < m_length)
2015-07-21 22:37:22 -07:00
{
atError("New size cannot be less to the old size.");
return;
}
2014-04-20 02:14:15 -07:00
// Allocate and copy new buffer
atUint8* newArray = new atUint8[newSize];
2014-04-20 02:14:15 -07:00
memset(newArray, 0, newSize);
2015-07-07 23:34:59 -07:00
if (m_dataCopy)
memcpy(newArray, m_dataCopy.get(), m_length);
m_dataCopy.reset(newArray);
2014-04-20 02:14:15 -07:00
// Swap the pointer and size out for the new ones.
m_data = newArray;
m_length = newSize;
}
} // io
} // Athena