/* librock/allocof.h NOTE: This file is intended to be included from librock/mstruct.h See http://www.mibsoftware.com/librock/ for documentation and original copies of this software. This software shall be distributed with the implementation source code according to the license terms of the source code. License text in librock_LIDESC_HC=12440211096131f5976d36be0cddca4cd9152e45 */ /* $Log: allocof.h,v $ Revision 1.2 2002/02/10 03:06:08 forrest@mibsoftware.com rights=#1 Fixed EXPERIMENTAL bracketing. Standardized chg log Revision 1.1 2002/01/29 04:40:02 forrest@mibsoftware.com rights=#1 Prep for publish. API clean up, TAB, space at eol removal rights#1 Copyright (c) Forrest J Cavalier III d-b-a Mib Software rights#1 License text in librock_LIDESC_HC=12440211096131f5976d36be0cddca4cd9152e45 */ #ifndef librock_INCLUDE_ALLOCOF_H #define librock_INCLUDE_ALLOCOF_H #ifdef librock_EXPERIMENTAL_ALLOCOF_x001 #define librock_CAllocOffsetFILE librock_CAllocOffsetFILE_x001 #ifndef librock_ISOLATED #include #endif #ifdef __cplusplus class librock_CAllocOffsetFILE : public librock_CAllocOffset32 { protected: FILE *m_f; long m_bias; librock_uint32_t m_length; int m_bFcloseOnDestruct; /* Allocate and store blocks which are referenced by offset */ public: /* Primitives */ virtual librock_uint32_t ReadAt(librock_uint32_t offset,char *pBuf,librock_uint32_t cbBuf) { fseek(m_f,offset+m_bias,SEEK_SET); return fread(pBuf,1,cbBuf,m_f); }; virtual librock_uint32_t WriteAt(librock_uint32_t offset,const char *pBuf,librock_uint32_t cbBuf) { /* printf("write(%08lx,%d)\n",offset,cbBuf); */ fseek(m_f,offset+m_bias,SEEK_SET); long ret = fwrite(pBuf,1,cbBuf,m_f); if (offset+cbBuf > m_length) { m_length = Length(); } fflush(m_f); return ret; }; librock_uint32_t Length() { fseek(m_f,0,SEEK_END); long l = ftell(m_f); if (l < m_bias) { return 0; } return l - m_bias; }; virtual librock_uint32_t NextBlock(librock_uint32_t offset,librock_uint32_t cb) { if (offset+cb < m_length) { return offset+cb; } return 0; } virtual librock_uint32_t Extend(librock_uint32_t cb) { librock_uint32_t l = Length(); if (l == 0) { l = sizeof(l); } struct freelist_s e; e.offset = l; e.cb = cb; WriteCtl(l,&e); /* Seek and write, in order to expand the file */ WriteAt(l+cb-sizeof(long),(char *) &cb,sizeof(long)); return l; }; public: librock_CAllocOffsetFILE() { m_f = 0; m_bFcloseOnDestruct = 0; m_length = 0; }; virtual ~librock_CAllocOffsetFILE() { if (m_bFcloseOnDestruct) { fclose(m_f); } }; const char *Open(const char *fpathname) { m_f = fopen(fpathname,"r+b"); if (!m_f) { m_f = fopen(fpathname,"w+b"); } if (!m_f) { return "E-1-Could not Open()"; } m_bias = 0; m_bFcloseOnDestruct = 1; /* Allocate a free list */ if (Length() < sizeof(m_freelist)) { m_oFreeList = Extend(sizeof(m_freelist)+sizeof(librock_uint32_t)); WriteAt(m_oFreeList,(char *) m_freelist,sizeof(m_freelist)); } else { m_oFreeList = sizeof(librock_uint32_t); m_bFreeListLoaded = 0; } m_oFreeScan = m_oFreeList; /* First allocation */ m_length = Length(); return 0; } const char *SetF(FILE *f,long bias) { m_f = f; m_bias = bias; /* Allocate a free list */ if (Length() < sizeof(m_freelist)) { m_oFreeList = Extend(sizeof(m_freelist)+sizeof(librock_uint32_t)); WriteAt(m_oFreeList,(char *) m_freelist,sizeof(m_freelist)); } else { m_oFreeList = sizeof(librock_uint32_t); m_bFreeListLoaded = 0; } m_oFreeScan = m_oFreeList; /* First allocation */ m_length = Length(); return 0; } }; /**************************************************************/ #endif /* __cplusplus */ #undef librock_CAllocOffsetFILE #endif #endif