/**
 * \file BGDNetBuffer.h
 * \brief Объявление классов Buffer, InputBuffer и OutputBuffer.
 */

#ifndef __BGDNetBuffer_h__
#define __BGDNetBuffer_h__

#include "BGDNetConfig.h"

#include <nwdsbuft.h>
#include "BGDNetException.h"
#include "BGDNetString.h"
#include "BGDNetCollection.h"

namespace BGDNet
{

class Context;

/**
 * \class Buffer
 * \brief Класс "Буфер".
 *
 * Базовый класс буферов, используемых для передачи параметров
 * и получения результатов функций NDS.
 * При использовании различных функций NDS часто возникает необходимость
 * передачи параметров и получения результатов в виде данных сложной структуры.
 * Для этого используются т.н. буфера.
 */
class BGDNET_API Buffer
{
public:

  explicit Buffer( const Context& ctx, size_t sz = DEFAULT_MESSAGE_LEN )
    throw(Exception);
  /**<
   * \brief Конструктор.
   * Инициализирует буфер размером sz байт и ассоциирует его с контекстом,
   * на который ссылается ctx. В случае нехватки памяти возбуждается
   * соответствующее исключение.
   * @param ctx Ссылка на контекст.
   * @param sz Необязательный размер буфера, по умолчанию равен 4096 байт
   */

  ~Buffer( void );
  /**<
   * \brief Деструктор.
   * Автоматически освобождает выделенную память.
   */

  const Context& ctx( void ) const;
  /**<
   * \brief Доступ к контексту, с которым ассоциирован буфер.
   * @return Ссылка на контекст, с которым ассоциирован буфер.
   */

  Buf_T* buf( void );
  /**<
   * \brief Доступ к структуре, реализующей буфер.
   * @return Указатель на структуру Buf_T, которая реализует буфер.
   */

  const Buf_T* buf( void ) const;
  /**<
   * \brief Доступ к структуре, реализующей буфер.
   * @return Указатель на структуру Buf_T, которая реализует буфер.
   */

private:

  Buf_T* m_pBuf;
  /**<
   * \brief Указатель на структуру, реализующую буфер.
   */

  const Context& m_ctx;
  /**<
   * \brief Ссылка на контекст.
   */
};




/**
 * \class InputBuffer
 * \brief Класс "Входной буфер".
 *
 * Выходной буфер предназначен для передачи параметров функциям NDS.
 */
class BGDNET_API InputBuffer : public Buffer
{
public:

  InputBuffer( const Context& ctx, nuint32 op, size_t sz = DEFAULT_MESSAGE_LEN )
    throw(Exception);
  /**<
   * \brief Конструктор
   * @param ctx Ссылка на контекст.
   * @param op Код операции, для которой предназначен буфер.
   * @param sz Необязательный размер буфера, по умолчанию равен 4096 байт.
   */

  void putAttrName( const char* name );
  /**<
   * \brief Добавляет имя атрибута в буфер.
   * @param name Указатель на строку, содержащую имя атрибута.
   */
};




#ifdef _MSC_VER
# pragma warning(disable:4231)
#endif

BGDNET_TEMPLATE(Collection<char>);
BGDNET_TEMPLATE(Collection<Collection<char> >);

#ifdef _MSC_VER
# pragma warning(default:4231)
#endif

typedef Collection<char> NDSAttrVal;
typedef Collection<Collection<char> > NDSAttrValues;




/**
 * \class OutputBuffer
 * \brief Класс "Выходной буфер"
 *
 * Выходной буфер предназначен для получения результатов,
 * возвращаемых функциями NDS.
 */
class BGDNET_API OutputBuffer : public Buffer
{
public:

  explicit OutputBuffer( const Context& ctx, size_t sz = DEFAULT_MESSAGE_LEN )
    throw(Exception);
  /**<
   * \brief Конструктор
   * @param ctx Ссылка на контекст.
   * @param sz Необязательный размер буфера, по умолчанию равен 4096 байт.
   */

  int objCount( void )
    throw(Exception);
  /**<
   * \brief Доступ к количеству объектов в буфере
   * @return Количество объектов в буфере.
   */

  String objName( String* pBaseClass = 0 )
    throw(Exception);
  /**<
   * \brief Получение имени объекта и имени его класса
   * @param pBaseClass Необязательный параметр на строку,
   * в которую помещается имя класса объекта.
   * @return Строка, содержащая имя объекта.
   */

  String objNameAndDSIInfo( char** ppInfo )
    throw(Exception);
  /**<
   * \brief Получение имени объекта и DSI-информации
   * @param ppInfo Указатель на переменную, в которую заносится указатель
   * на DSI-информацию об объекте.
   * @return Строка, содержащая имя объекта.
   */

  int attrCount( void )
    throw(Exception);
  /**<
   * \brief Доступ к количеству атрибутов в буфере
   * @return Количество атрибутов в буфере.
   */

  String getAttr( NDSAttrValues* pValues );
  /**<
   * \brief Получение очередного атрибута из буфера
   * @param pValues Указатель на коллекцию значений атрибутов,
   * заполняемую методом.
   * @return Имя извлеченного атрибута.
   */
};

} // namespace BGDNet

#endif //__BGDNetBuffer_h__
