导航:[首页]->[cpp]->[基于文件接口的内存流]

支持托管,所有写进去的内存会重组,以便让其连续排列

    #ifndef MEMCACHE__H_
    #define MEMCACHE__H_

    #include <cstddef>
    #include <cassert>
    #include <cstring>

    template<bool HOSTING>
    class MemFileT{
    public:
        MemFileT():
            m_ptr_(NULL),
            m_max_(0),
            m_cur_(0){}
        ~MemFileT(){
            fclose();
        }

        void        fclose()
        {
            if(m_ptr_){
                if(!HOSTING)
                    free(m_ptr_);
                m_ptr_ = NULL;
                m_max_ = 0;
                m_cur_ = 0;
            }
        }

        void        attach(char* ptr,size_t size)
        {
            if(HOSTING)
            {
                assert(ptr);
                assert(size);
                m_ptr_ = ptr;
                m_max_ = size;
                m_cur_ = 0;
            }
        }


        bool        fread(char*ptr,size_t size,size_t* readed)
        {
            assert(ptr);
            assert(size);

            size_t rest_ = m_max_ - m_cur_;
            if(readed){
                *readed = std::min(size,rest_);
                if(*readed > 0){
                    memcpy(ptr,m_ptr_ + m_cur_,*readed);
                    m_cur_ += *readed;
                }
            }else{
                if(rest_ < size)
                    return false;   
                if(size > 0){
                    memcpy(ptr,m_ptr_ + m_cur_,size);
                    m_cur_ += size;
                }
            }
            return true;
        }


        bool        fwrite(char*ptr,size_t size){
            assert(ptr);
            assert(size);

            if(m_max_ - m_cur_ < size)
            {
                if(HOSTING)
                    return false;
                resize(size + m_cur_);
            }

            memcpy(m_ptr_ + m_cur_ ,ptr,size);
            m_cur_ += size;
            return true;
        }

        bool        fseek(long int offset, int origin )
        {
            switch(origin){
            case SEEK_SET:
            {
                if(offset <= (long int)m_max_ && offset >= 0){
                    m_cur_ = offset;
                    return true;
                }
                break;
            }
            case SEEK_END:
            {
                offset = - offset;
                if(offset <= (long int)m_max_ && offset >= 0)
                {
                    m_cur_ = m_max_ - offset;
                    return true;
                }
                break;
            }
            case SEEK_CUR:
            {
                if(offset >= 0)
                {
                    if(m_cur_ + (size_t)offset <= m_max_)
                    {
                        m_cur_ += (size_t)offset;
                        return true;
                    }
                }else{
                    if(offset + (long int)m_cur_ >= 0)
                    {
                        m_cur_ += offset;
                        return true;
                    }
                }
                break;
            }
            };
            return false;
        }

        size_t      ftell() const{
            return m_cur_;
        }

    private:

        void        resize(size_t size)
        {
            char* oldptr = m_ptr_;
            char* newptr = static_cast<char*>(malloc(size));
            assert(newptr);
            if(oldptr){
                if(m_cur_)
                    memcpy(newptr,oldptr,m_cur_);
                free(oldptr);
            }
            m_ptr_ = newptr;
            m_max_ = size;
        }

    private:
        char*       m_ptr_;
        size_t      m_max_;
        size_t      m_cur_;
    };

    typedef MemFileT<true>      MemFileHandle;
    typedef MemFileT<false>     MemFile;

    #endif