Boost logo

Boost Users :

From: Stephen Torri (storri_at_[hidden])
Date: 2006-10-30 23:53:15


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<char*>(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 <boost/cstdint.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/format.hpp>
#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<Memory_Map> 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;

    }


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net