Subversion Repositories DevTools

Rev

Rev 2218 | Blame | Compare with Previous | Last modification | View Log | RSS feed

//## begin module%1.7%.codegen_version preserve=yes
//   Read the documentation to learn more about C++ code generator
//   versioning.
//## end module%1.7%.codegen_version

//## begin module%420720460243.cm preserve=no
//## end module%420720460243.cm

//## begin module%420720460243.cp preserve=no
//      C O P Y R I G H T   N O T I C E
//      This material is confidential to ERG and may not be disclosed in whole
//      or in part to any third party nor used in any manner whatsoever other
//      than for the purposes expressly consented to by ERG in writing.
//
//      This material is also copyright and may not be reproduced, stored in a
//      retrieval system or transmitted in any form or by any means in whole or
//      in part without the express written consent of ERG.
//## end module%420720460243.cp

//## Module: TransactionStream%420720460243; Pseudo Package body
//## Subsystem: MASS::Dev::Tools::TxnTestManager::src%41F5A79001E4
//## Source file: Z:\MASS_Dev\Tools\TxnTestManager\src\TransactionStream.cpp

//## begin module%420720460243.additionalIncludes preserve=no
//## end module%420720460243.additionalIncludes

//## begin module%420720460243.includes preserve=yes
#pragma warn -com
#include <LoggingMacros.h>
#pragma warn +com

#include <vcl.h>
#pragma hdrstop
//## end module%420720460243.includes

// UdFileManifest
#include "UdFileManifest.h"
// TransactionStream
#include "TransactionStream.h"
//## begin module%420720460243.additionalDeclarations preserve=yes
#if defined( WIN32 ) || defined( __BCPLUSPLUS__ ) || defined( __BORLANDC__ )
   const char g_separator = '\\';
#else
   const char g_separator = '/';
#endif

#include <iomanip>
#include <fstream>
#include <sstream>
#include <time.h>
#include <sys/stat.h>
//## end module%420720460243.additionalDeclarations


// Class TransactionStream 

//## Operation: TransactionStream%4207228700FB
TransactionStream::TransactionStream (const std::string &folder, const std::string &batchPrefix, const std::string &batchSuffix, const bool &buildManifest, const std::string &manifestPrefix, const std::string &manifestSuffix, const std::string &pathmapTarget)
  //## begin TransactionStream::TransactionStream%4207228700FB.hasinit preserve=no
      : m_batchNumber(1),
        m_batchCount(0),
        m_batchPrefix(batchPrefix),
        m_batchSize(0),
        m_batchSuffix(batchSuffix),
        m_folder(folder),
        m_stream(0),
        m_manifest(0)
  //## end TransactionStream::TransactionStream%4207228700FB.hasinit
  //## begin TransactionStream::TransactionStream%4207228700FB.initialization preserve=yes
  //## end TransactionStream::TransactionStream%4207228700FB.initialization
{
  //## begin TransactionStream::TransactionStream%4207228700FB.body preserve=yes

        if ( buildManifest )
        {
                m_manifest = new UdFileManifest(
                        folder,
                        manifestPrefix,
                        manifestSuffix,
                        pathmapTarget );
        }

  //## end TransactionStream::TransactionStream%4207228700FB.body
}


TransactionStream::~TransactionStream()
{
  //## begin TransactionStream::~TransactionStream%420720460243_dest.body preserve=yes

        close();
        
        if ( m_manifest )
        {
                delete m_manifest;
                m_manifest = 0;
        }


  //## end TransactionStream::~TransactionStream%420720460243_dest.body
}



//## Other Operations (implementation)
//## Operation: buildFileName%420821AD02EF
std::string & TransactionStream::buildFileName (std::string &filename, const std::string &folder, const std::string &prefix, const std::string &suffix, const std::string &batchName, const unsigned &batchNumber)
{
  //## begin TransactionStream::buildFileName%420821AD02EF.body preserve=yes

        static const int        base = 62;
        static const char       encoding[ base ] =
                "0123456789"
                "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                "abcdefghijklmnopqrstuvwxyz";

        /**
         *      TDateTime is in local time, and the DCE currently uses UTC.  Therefore,
         *      we use time() to get seconds since midnight in UTC, and use TDateTime
         *      only to get msec.
         */
        unsigned short  hour;
        unsigned short  minute;
        unsigned short  second;
        unsigned short  millisecond;
        struct stat             statbuf;
        time_t                  now;
        char                    encodingTime[ 9 ];

        /**
         *      Do this until we have a filename, but no more than 10,000 iterations,
         *      which should be a little over 10 seconds.
         */
        for ( int safetyLimit = 10000; safetyLimit; --safetyLimit )
        {
                TDateTime::CurrentDateTime().DecodeTime(
                        &hour,
                        &minute,
                        &second,
                        &millisecond );

                time( &now );

                encodingTime[ 6 ] = encoding[ millisecond % base ];
                millisecond /= base;
                encodingTime[ 5 ] = encoding[ millisecond % base ];

                encodingTime[ 4 ] = encoding[ now % base ];
                now /= base;
                encodingTime[ 3 ] = encoding[ now % base ];
                now /= base;
                encodingTime[ 2 ] = encoding[ now % base ];
                now /= base;
                encodingTime[ 1 ] = encoding[ now % base ];
                now /= base;
                encodingTime[ 0 ] = encoding[ now % base ];

                for ( int counter=0; counter < base; ++counter )
                {
                        encodingTime[ 7 ] = encoding[ counter ];
                        encodingTime[ 8 ] = 0;

                        std::stringstream name;
                        if ( folder.length() )
                        {
                                name << folder;
                                if ( folder[ folder.length() - 1 ] != g_separator )
                                {
                                        name << g_separator;
                                }
                        }

                        if ( prefix.length() )
                        {
                                name << prefix;
                        }

                        name << encodingTime;

                        if ( batchName.length() )
                        {
                                name << '_' << batchName << '_' << std::setw( 4 ) << std::setfill( '0' ) << std::right << batchNumber;
                        }

                        if ( suffix.length() )
                        {
                                name << suffix;
                        }

                        filename = name.str();

                        if ( stat( filename.c_str(), &statbuf ) == -1 )
                        {
                                return ( filename );
                        }
                }

                Sleep( 1 );
        }

        MTHROW( std::runtime_error, \
                "Cannot build a filename that is not already in use in \"" \
                << folder \
                << "\" with prefix \"" \
                << prefix \
                << "\" and suffix \"" \
                << suffix \
                << "\"." );

  //## end TransactionStream::buildFileName%420821AD02EF.body
}

//## Operation: close%420819C203E4
void TransactionStream::close ()
{
  //## begin TransactionStream::close%420819C203E4.body preserve=yes

        if ( m_stream )
        {
                m_stream->close();

                delete m_stream;
                m_stream = 0;
        }

  //## end TransactionStream::close%420819C203E4.body
}

//## Operation: incrementCount%420723C60224
void TransactionStream::incrementCount ()
{
  //## begin TransactionStream::incrementCount%420723C60224.body preserve=yes

        /**
         *      When we have a batch size (and so we batch), then we may need to
         *      start a new batch.
         */
        if ( m_batchSize )
        {
                if ( ++m_batchCount >= m_batchSize )
                {
                        close();
                        m_batchCount = 0;
                        ++m_batchNumber;
                        open();
                }
        }

  //## end TransactionStream::incrementCount%420723C60224.body
}

//## Operation: newBatch%420722B50215
const bool TransactionStream::newBatch (const unsigned &size, const std::string &name)
{
  //## begin TransactionStream::newBatch%420722B50215.body preserve=yes

        m_batchSize             = size;
        m_batchCount    = 0;
        m_batchName             = name;
        
        return ( open() );

  //## end TransactionStream::newBatch%420722B50215.body
}

//## Operation: open%420819AE03C4
const bool TransactionStream::open ()
{
  //## begin TransactionStream::open%420819AE03C4.body preserve=yes

        close();        // Close the stream should it be open.

        std::string filename;
        buildFileName( filename, m_folder, m_batchPrefix, m_batchSuffix, m_batchName, m_batchNumber );

        m_stream = new std::ofstream(
                filename.c_str(),
                std::ios_base::binary | std::ios_base::out );
        if ( m_stream->is_open() )
        {
                if ( m_manifest )
                {
                        m_manifest->addUdFile( filename );
                }
                return ( true );
        }

        // When we can't open the file, then roll back.
        delete m_stream;
        m_stream = 0;

        MERROR( "Cannot open \"" << filename << "\" for writing." );
        return ( false );

  //## end TransactionStream::open%420819AE03C4.body
}

//## Operation: write%4207231D014A
const bool TransactionStream::write (const void *buffer, const unsigned &length)
{
  //## begin TransactionStream::write%4207231D014A.body preserve=yes

        if ( m_stream )
        {
                m_stream->write( reinterpret_cast< const char * >( buffer ), length );

                if ( m_stream->good() )
                {
                        return ( true );
                }
                else
                {
                        MERROR( "Cannot write " << length << " byte(s) to stream." );
                }
        }
        else
        {
                MERROR( "Cannot write to stream because it is not open." );
        }

        return ( false );

  //## end TransactionStream::write%4207231D014A.body
}

// Additional Declarations
  //## begin TransactionStream%420720460243.declarations preserve=yes
  //## end TransactionStream%420720460243.declarations

//## begin module%420720460243.epilog preserve=yes
//## end module%420720460243.epilog