/* Network-Integrated Multimedia Middleware (NMM)
 * http://www.motama.com/nmm.html
 *  
 * Copyright (C) 2006-2007
 * Motama GmbH, Saarbruecken, Germany
 * http://www.motama.com
 *  
 * This file is part of NMM. 
 * 
 * NMM is free software; you can redistribute it and/or modify it    
 * under the terms of the GNU General Public License as published by 
 * the Free Software Foundation; only version 2 of the License.      
 * 
 * NMM is distributed in the hope that it will be useful, but WITHOUT 
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 
 * License for more details.  
 * 
 * You should have received a copy of the GNU General Public License 
 * along with NMM; if not, write to the Free Software Foundation,    
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */

#ifndef NMM_IEXTERNALBUFFERMANAGER_HPP
#define NMM_IEXTERNALBUFFERMANAGER_HPP NMM_IEXTERNALBUFFERMANAGER_HPP

#include "nmm/nmm_prefix.hpp"

#include <cstdlib> // for size_t

#include "visibility.hpp"

namespace NMM {
  
  class Buffer;
  class BufferManager;
  
  /** Standardized interface for an external buffer manager.
   *
   * This class implements a standardized interface for an external
   * buffer manager. This interface is meant to be used as a
   * secondary superclass for nodes, especially the generic layer
   * nodes.
   * Using this interface, a leaf node can be passed a specific buffer
   * manager for future use. The leaf node can use the getNewBuffer
   * call to request a buffer from this buffer manager, or a new
   * buffer manager if none has been provided.
   */
  class DLLEXPORT IExternalBufferManager {
  private:
    /**
     * A buffer manager for obtaining new buffers. By letting this base
     * class take care of the buffer manager, a generic method can be
     * set up to force nodes to use specific managers. This allows for
     * upstream buffer manager propagation.
     */
    BufferManager *buffer_manager;

  public:
  
    /**
     * Main constructor.
     */
    IExternalBufferManager();

    /**
     * Main destructor.
     */
    virtual ~IExternalBufferManager();
    
    /** Requests a new buffer.
     *
     * This method asks the buffer manager for a new
     * buffer. If no buffer manager is present, a new Allocator will be
     * instantiated and stored.
     *
     * @param size The requested size of the buffer.
     * @return the requested buffer, or NULL if no buffer was available.
     */
    Buffer *getNewBuffer(const size_t size);

    /** Requests a new buffer.
     *
     * This method does the same as getNewBuffer(const size_t). 
     * But the new buffer's header is
     * initialized with the second argument's header.
     *
     * @param size The requested size of the buffer.
     * @param buffer The buffer which header is copied into the new one.
     * @return The requested buffer, or NULL if no buffer was available.
     */
    Buffer *getNewBuffer(const size_t size, const Buffer *buffer);

    /** Sets BufferManager.
     *
     * Use this buffer manager. The buffer manager passed will be returned
     * in getBufferManager and will be used for all getNewBuffer calls.
     * This method MUST be called before the node's init method if called
     * from the outside. The subclass itself should use this method from
     * within its own setup method to change/set the buffer manager. If
     * no one sets a buffer manager, a basic Allocator will be created on
     * the first call of getNewBuffer.
     *
     * @param manager The new buffer manager to use.
     */
    void setBufferManager(BufferManager *manager);

    /** Gets used BufferManager.
     *
     * Get this node's buffer manager. If possible, a subclass should use
     * this method to check for the presence of a buffer manager before
     * it installs its own.
     *
     * @return The buffer manager currently in use or 0 if non such exists.
     */
    const BufferManager *getBufferManager() const;

    /** Gets used BufferManager and increases reference count.
     *
     * Get this node's buffer manager and increase reference count.
     *
     * @return pointer to buffer manager
     */
    virtual BufferManager* requestBufferManager();

  };

}

#include "nmm/nmm_suffix.hpp"

#endif
