// **********************************************************************
//
// Copyright (c) 1999
// Object Oriented Concepts, Inc.
// Billerica, MA, USA
//
// All Rights Reserved
//
// **********************************************************************

#ifndef OCI_BUFFER_H
#define OCI_BUFFER_H

//
// The OCI_Buffer class
//
class OCI_Buffer;
typedef OCI_Buffer* OCI_Buffer_ptr;
typedef OCI_Buffer_ptr OCI_BufferRef;
void OBDuplicate(OCI_Buffer_ptr);
void OBRelease(OCI_Buffer_ptr);
typedef OBObjVar< OCI_Buffer > OCI_Buffer_var;

class OCI_Buffer : public OBSimpleRefCount
{
    CORBA_ULong pos_;
    OBBuffer buf_;

public:

    OCI_Buffer() : pos_(0) { }
    OCI_Buffer(CORBA_ULong n) : pos_(0), buf_(n) { }
    virtual ~OCI_Buffer() { }
    
    //
    // Standard IDL to C++ Mapping
    //
    static inline OCI_Buffer_ptr _duplicate(OCI_Buffer_ptr p)
    { if(p) p -> _OB_incRef(); return p; }
    static inline OCI_Buffer_ptr _nil()
    { return 0; }
    
    CORBA_Octet* data() { return buf_.data; }
    CORBA_Octet* rest() { return buf_.data + pos_; }
    
    CORBA_ULong length() { return buf_.len; }
    CORBA_ULong rest_length() { return buf_.len - pos_; }
    
    CORBA_ULong pos() { return pos_; }
    void pos(CORBA_ULong pos) { pos_ = pos; }
    void advance(CORBA_ULong delta) { pos_ += delta; }

    CORBA_Boolean is_full() { return pos_ >= buf_.len; }

    //
    // Additional ORBacus specific functions
    //
    OBBuffer& buf() { return buf_; }
    void alloc(CORBA_ULong n) { buf_.alloc(n); }
    void realloc(CORBA_ULong n) { buf_.realloc(n); }
};

inline void
CORBA_release(OCI_Buffer_ptr p)
{
    if(p)
	p -> _OB_decRef();
}

inline CORBA_Boolean
CORBA_is_nil(OCI_Buffer_ptr p)
{
    return p == 0;
}

typedef OBObjSeq< OCI_Buffer > OCI_BufferSeq;
typedef OBSeqVar< OBVarSeq< OCI_Buffer > > OCI_BufferSeq_var;

#endif
