I am trying to create a class which I can use to safely allocate a block
of bytes. One purpose is to allow me to easily fill in a variable with N
bytes from the block. For example the code below would attempt to fill a
variable (e.g. boost::uint32_t val ).
template <typename Value_Type>
void read (Value_Type* value)
{
m_file_img->read (reinterpret_cast(value),
sizeof(Value_Type));
}
The second purpose is to create a block of bytes which I can write bytes
to at particular offsets from the beginning. For example if I created a
block of 50 bytes I may want to fill in bytes 5 through 8 with 4 bytes
of data.
My present method is create a block via 'new char[size]' and store this
pointer in a class. This works for reading by when later in my program
when I create a instance to write data to it I get a segfault.
I was wondering if there was a boost method for creating an array of
bytes? My code is below. I would greatly appreciate comments on how to
utilize more of boost's functionality.
Stephen
-----------------------
#ifndef MEMORY_MAP_H_
#define MEMORY_MAP_H_
#include
#include
#include
#include
#include <iostream>
#include <iomanip>
#include "io/exceptions/IO_Exception.hpp"
namespace libreverse { namespace data_types {
class Memory_Map
{
public:
typedef char data_type;
typedef char const* const_iterator;
typedef data_type* iterator;
typedef boost::shared_ptr ptr;
Memory_Map ( boost::uint32_t const& size );
Memory_Map ( boost::uint64_t const& size );
Memory_Map ( Memory_Map const& rhs );
virtual ~Memory_Map();
template <typename Offset_Type>
void seek ( Offset_Type offset )
{
if (offset > m_size)
{
std::cerr << "The offset given, " << offset
<< " is invalid. Its pointing to a "
<< std::endl
<< "memory location outside of space "
<< "allocated to"
<< std::endl
<< "this Memory Map. ("
<< m_size << ")"
<< std::endl;
throw errors::IO_Exception
( errors::IO_Exception::OUT_OF_RANGE );
}
m_present_pos = m_base_addr + offset;
std::cout
<< boost::format ("Memory_Map::seek - new present pos = %1p") %
*m_present_pos
<< std::endl;
}
void read ( iterator dest_addr_ptr, boost::uint32_t const& len);
void copy ( const_iterator src_addr_ptr, boost::uint32_t const& len );
iterator begin();
const_iterator begin() const;
const_iterator end() const;
iterator get_Present_Position (void);
const_iterator get_Present_Position (void) const;
boost::uint32_t const& size (void) const;
private:
char* m_base_addr;
boost::uint32_t m_size; // Size of memory
iterator m_present_pos;
iterator m_end_addr;
};
#endif /* MEMORY_MAP_H_ */
----------------
#include "Memory_Map.hpp"
namespace libreverse { namespace data_types {
Memory_Map::Memory_Map ( boost::uint32_t const& size )
: m_size ( size )
{
m_base_addr = new char[size];
m_present_pos = m_base_addr;
/*
std::cout
<< boost::format ("Memory_Map::constructor - start present pos = %1%") %
boost::io::group ( std::hex,
m_present_pos )
<< std::endl;
*/
m_end_addr = m_base_addr + size;
}
Memory_Map::Memory_Map ( boost::uint64_t const& size )
: m_size ( size )
{
m_base_addr = new char[size];
m_present_pos = m_base_addr;
m_end_addr = m_base_addr + size;
}
Memory_Map::Memory_Map ( Memory_Map const& rhs )
: m_base_addr (rhs.m_base_addr),
m_size (rhs.m_size),
m_present_pos ( rhs.m_present_pos ),
m_end_addr ( rhs.m_end_addr )
{
/*
std::cout
<< "Memory_Map::copy_constructor - start present pos = "
<< m_present_pos
<< std::endl;
*/
#warning We do not deep copy the data here
}
Memory_Map::~Memory_Map ()
{
delete[] m_base_addr;
}
void
Memory_Map::read ( iterator dest_addr_ptr,
boost::uint32_t const& length )
{
if ( m_present_pos > m_end_addr )
{
std::cerr << "The present position pointer is invalid. "
<< "Its pointing"
<< std::endl
<< "to a memory location out side of space "
<< "allocated to"
<< std::endl
<< "this Memory Map."
<< std::endl;
throw errors::IO_Exception
( errors::IO_Exception::INVALID_INDEX );
}
memcpy ( dest_addr_ptr, m_present_pos, length );
m_present_pos += length;
}
Memory_Map::iterator
Memory_Map::begin()
{
return m_base_addr;
}
Memory_Map::const_iterator
Memory_Map::begin() const
{
return m_base_addr;
}
Memory_Map::const_iterator
Memory_Map::end() const
{
return m_end_addr;
}
Memory_Map::iterator
Memory_Map::get_Present_Position (void)
{
return m_present_pos;
}
Memory_Map::const_iterator
Memory_Map::get_Present_Position (void) const
{
return m_present_pos;
}
boost::uint32_t const&
Memory_Map::size (void) const
{
return m_size;
}
void
Memory_Map::copy ( const_iterator src_addr_ptr, boost::uint32_t const& length )
{
// If m_present_pos + length > m_end_addr ERROR
if ( m_present_pos + length > m_end_addr )
{
std::cerr << "The present position pointer will be"
<< " invalid if we write from the present"
<< std::endl
<< "position with the given length. It will"
<< " cause an segfault. Recheck the value"
<< std::endl
<< "given for length (" << length << ") or check"
<< " the setting of the present position."
<< std::endl;
throw errors::IO_Exception
( errors::IO_Exception::OUT_OF_RANGE );
}
memcpy ( m_present_pos, src_addr_ptr, length );
m_present_pos += length;
}