//-< BLOB.H >--------------------------------------------------------*--------*
// GigaBASE                  Version 1.0         (c) 1999  GARRET    *     ?  *
// (Post Relational Database Management System)                      *   /\|  *
//                                                                   *  /  \  *
//                          Created:     04-Jun-2000  K.A. Knizhnik  * / [] \ *
//                          Last update: 27-Jun-2000  K.A. Knizhnik  * GARRET *
//-------------------------------------------------------------------*--------*
// Binary large object
//-------------------------------------------------------------------*--------*

#ifndef __BLOB_H__
#define __BLOB_H__

BEGIN_GIGABASE_NAMESPACE

class GIGABASE_DLL_ENTRY dbBlobIterator {
  protected:
    size_t      size;
    offs_t      pos;
    dbDatabase& db;
    oid_t       oid;
    oid_t       next;
    void*       buf;
    bool        closed;

  public:
    //
    // Get size of sequential BLOB segment
    //
    virtual size_t getAvailableSize() = 0;

    //
    // Get size of available BLOB buffer
    //
    size_t getAvailableBufferSize() {
	size_t rest = dbPageSize - ((int)pos & (dbPageSize-1));
	return rest < size ? rest : size;
    }


    virtual void* mapBuffer() = 0;
    virtual void  unmapBuffer(size_t processed);

    virtual void close();

    dbBlobIterator(dbDatabase& db, oid_t oid);
    virtual ~dbBlobIterator();
};

class GIGABASE_DLL_ENTRY dbBlobReadIterator : public dbBlobIterator {
  public:
    size_t read(void* buf, size_t bufSize);
    dbBlobReadIterator(dbDatabase& db, oid_t oid) : dbBlobIterator(db,oid) {}
    ~dbBlobReadIterator();
    virtual void*  mapBuffer();
    virtual size_t getAvailableSize();
    virtual void   close();
};

class GIGABASE_DLL_ENTRY dbBlobWriteIterator : public dbBlobIterator {
  public:
    void   write(void const* buf, size_t bufSize);

    dbBlobWriteIterator(dbDatabase& db, oid_t oid) : dbBlobIterator(db,oid) {}
    ~dbBlobWriteIterator();
    virtual void*  mapBuffer();
    virtual size_t getAvailableSize();
    virtual void   close();
};

const size_t dbDefaultFirstBlobSegmentSize = 16000;

class GIGABASE_DLL_ENTRY dbBlob : public dbAnyReference {
  public:
    void create(dbDatabase& dbase, size_t size = dbDefaultFirstBlobSegmentSize);

    size_t getSize(dbDatabase& db);

    dbBlobReadIterator  getReadIterator(dbDatabase& db);
    dbBlobWriteIterator getWriteIterator(dbDatabase& db);

    dbBlob& operator = (dbAnyReference const& ref) {
	oid = ref.getOid();
	return *this;
    }

    void free(dbDatabase& db);
};

END_GIGABASE_NAMESPACE

#endif




