/**
 * @file trace_interpreter.h
 *
 * TraceInterpreter - Class for interpreting a CAPI trace file.
 *
 * Copyright: 2002-2003 Thomas Wintergerst. All rights reserved.
 *
 * $FreeBSD$
 * $Id: trace_interpreter.h,v 1.1.2.1 2006/02/28 21:35:42 thomas Exp $
 * Project  CAPI for BSD
 * Target   capitrace - Tracing CAPI calls and messages
 * @date    21.09.2002
 * @author  "Thomas Wintergerst" <twinterg@gmx.de>
 * <p>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * </p>
 */

#ifndef __TRACE_INTERPRETER_H
#define __TRACE_INTERPRETER_H

#include <stddef.h> // size_t
#include <sys/types.h> // u_int8_t, etc.
#include <string>

#ifndef __CONFIG_H
#  include "config.h"
#endif
#ifndef __FORM_OUT_STREAM_H
#  include "form_out_stream.h"
#endif
#ifndef __TRACE_MESSAGE_PRINT_H
#  include "trace_message_print.h"
#endif





// === Public declarations ===============================================





// === Class declarations ================================================





/**
 * Class for CAPI trace interpretation.
 */
class CTraceInterpreter
{
   public:
      /**
       * Constructor.
       */
      CTraceInterpreter (void);
      
      /**
       * Destructor.
       */
      ~CTraceInterpreter (void);
      
      /**
       * Set the input file name for the next interpretation run.
       */
      void SetInputFile
         (const std::string &strFileName);
      
      /**
       * Set the output file name for the next interpretation run.
       */
      void SetOutputFile
         (const std::string &strFileName);
      
      /**
       * Set configuration for handling Data-B3 messages.
       */
      void SetDataB3MsgOutput
         (bool   fDataB3MsgOutput,
          bool   fDataB3BlockOutput,
          size_t nDataB3MaxBlockLen);
      
      /**
       * Set flag for optional hexadecimal output of the message.
       */
      void SetHexOutput
         (bool f);
      
      /**
       * Perform interpretation of the current input file.
       */
      void Run (void);



   protected:



   private:
      /// The file name for the CAPI trace input.
      std::string m_strInputFileName;
      
      /// This stream object will be opened if the input is a regular file.
      std::ifstream m_isInFile;
      
      /// This field points to the real input stream, either cin or m_isInFile.
      std::istream *m_pisIn;
      
      /// The count of the total number of bytes read from the input stream.
      size_t m_nTotalBytesRead;
      
      /// The file name for the interpreted output, if empty standard output is
      /// used
      std::string m_strOutputFileName;
      
      /// The stream object for formatted output
      CFormOutStream m_osOut;
      
      /// Flag for opened output stream
      bool m_fOutStreamOpened;
      
      /// Flag if Data-B3 messages should be written or suppressed.
      bool m_fIncludeDataB3Msgs;
      
      /// Flag if Data-B3 data blocks should be written or suppressed.
      bool m_fIncludeDataB3Blocks;
      
      /// The maximum length of Data-B3 data blocks to write if they shall be
      /// included.
      size_t m_nDataB3MaxBlockLen;
      
      /// Flag if additional hexadecimal output shall be written.
      bool m_fHexOutput;
      
      /// The buffer for the current message read from the input stream.
      u_int8_t *m_pacMsgBuf;
      
      /// The reserved length of the message buffer at m_pacMsgBuf.
      size_t m_nLenMsgBuf;
      
      /// The buffer for the data block attached to the current message read
      /// from the input stream.
      u_int8_t *m_paucDataBuf;
      
      /// The reserved length of the data buffer at m_pacDataBuf.
      size_t m_nLenDataBuf;
      
      /// The object to perform the real translation of trace messages to a
      /// textual representation.
      CTraceMessagePrint m_oTraceMsgPrint;
      
      
      
      /**
       * Open the source file.
       */
      void OpenSourceFile
         (CConfig::TracerConfig_t &traceConfig,
          struct timeval          &tvStartTime);
      
      /**
       * Close the source file.
       */
      void CloseSourceFile (void);
      
      /**
       * Open the destination file.
       */
      void OpenDestinationFile
         (CConfig::TracerConfig_t &traceConfig,
          struct timeval          &tvStartTime);
      
      /**
       * Close the destination file.
       */
      void CloseDestinationFile (void);
      
      /**
       * Read a complete message and possible data block from the source.
       */
      bool ReadTraceBlock (void);
      
      /**
       * Write a complete message and possible data block to the destination.
       */
      void WriteTraceBlock (void);
      
      /**
       * Ensure the buffer specified is large enough to hold a given number of
       * bytes.
       *
       * If the buffer specified through the first two arguments of this
       * function is already large enough to hold the number of bytes specified
       * through the third parameter, nothing is done and the function simply
       * returns at once.
       *
       * Else a new buffer is allocated. The number of bytes specified in the
       * fourth parameter is copied from the old buffer to the new one. Then the
       * old buffer is released and the new buffer is returned in place of the
       * old one.
       *
       * @param rpacBuf         I/O: The reference of the pointer to the
       *                           original buffer space. The pointer value may
       *                           be NULL when entering this function.
       * @param rnCurrLenBuf    I/O: The reference to the current length of the
       *                           original buffer at rpacBuf.
       * @param nNewLen         I: The required new length of the buffer.
       * @param nPreserve       I: The number of bytes in the original buffer to
       *                           preserve, i.e. to copy to the new one.
       *
       * @return Nothing.
       */
      void Reserve
         (u_int8_t *&rpacBuf,
          size_t    &rnCurrLenBuf,
          size_t     nNewLen,
          size_t     nPreserve = 0);



}; // CTraceInterpreter





// === Prototypes of interface functions =================================





#endif // __TRACE_INTERPRETER_H
