Subversion Repositories DevTools

Rev

Rev 2263 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2263 kivins 1
//## begin module%1.7%.codegen_version preserve=yes
2
//   Read the documentation to learn more about C++ code generator
3
//   versioning.
4
//## end module%1.7%.codegen_version
5
 
6
//## begin module%420720460243.cm preserve=no
7
//## end module%420720460243.cm
8
 
9
//## begin module%420720460243.cp preserve=no
10
//	C O P Y R I G H T   N O T I C E
11
//	This material is confidential to ERG and may not be disclosed in whole
12
//	or in part to any third party nor used in any manner whatsoever other
13
//	than for the purposes expressly consented to by ERG in writing.
14
//
15
//	This material is also copyright and may not be reproduced, stored in a
16
//	retrieval system or transmitted in any form or by any means in whole or
17
//	in part without the express written consent of ERG.
18
//## end module%420720460243.cp
19
 
20
//## Module: TransactionStream%420720460243; Pseudo Package body
21
//## Subsystem: MASS::Dev::Tools::TxnTestManager::src%41F5A79001E4
22
//## Source file: Z:\MASS_Dev\Tools\TxnTestManager\src\TransactionStream.cpp
23
 
24
//## begin module%420720460243.additionalIncludes preserve=no
25
//## end module%420720460243.additionalIncludes
26
 
27
//## begin module%420720460243.includes preserve=yes
28
#pragma warn -com
29
#include <LoggingMacros.h>
30
#pragma warn +com
31
 
32
#include <vcl.h>
33
#pragma hdrstop
34
//## end module%420720460243.includes
35
 
36
// UdFileManifest
37
#include "UdFileManifest.h"
38
// TransactionStream
39
#include "TransactionStream.h"
40
//## begin module%420720460243.additionalDeclarations preserve=yes
41
#if defined( WIN32 ) || defined( __BCPLUSPLUS__ ) || defined( __BORLANDC__ )
42
   const char g_separator = '\\';
43
#else
44
   const char g_separator = '/';
45
#endif
46
 
47
#include <iomanip>
48
#include <fstream>
49
#include <sstream>
50
#include <time.h>
51
#include <sys/stat.h>
52
//## end module%420720460243.additionalDeclarations
53
 
54
 
55
// Class TransactionStream 
56
 
57
//## Operation: TransactionStream%4207228700FB
58
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)
59
  //## begin TransactionStream::TransactionStream%4207228700FB.hasinit preserve=no
60
      : m_batchNumber(1),
61
        m_batchCount(0),
62
        m_batchPrefix(batchPrefix),
63
        m_batchSize(0),
64
        m_batchSuffix(batchSuffix),
65
        m_folder(folder),
66
        m_stream(0),
67
        m_manifest(0)
68
  //## end TransactionStream::TransactionStream%4207228700FB.hasinit
69
  //## begin TransactionStream::TransactionStream%4207228700FB.initialization preserve=yes
70
  //## end TransactionStream::TransactionStream%4207228700FB.initialization
71
{
72
  //## begin TransactionStream::TransactionStream%4207228700FB.body preserve=yes
73
 
74
	if ( buildManifest )
75
	{
76
		m_manifest = new UdFileManifest(
77
			folder,
78
			manifestPrefix,
79
			manifestSuffix,
80
			pathmapTarget );
81
	}
82
 
83
  //## end TransactionStream::TransactionStream%4207228700FB.body
84
}
85
 
86
 
87
TransactionStream::~TransactionStream()
88
{
89
  //## begin TransactionStream::~TransactionStream%420720460243_dest.body preserve=yes
90
 
91
	close();
92
 
93
	if ( m_manifest )
94
	{
95
		delete m_manifest;
96
		m_manifest = 0;
97
	}
98
 
99
 
100
  //## end TransactionStream::~TransactionStream%420720460243_dest.body
101
}
102
 
103
 
104
 
105
//## Other Operations (implementation)
106
//## Operation: buildFileName%420821AD02EF
107
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)
108
{
109
  //## begin TransactionStream::buildFileName%420821AD02EF.body preserve=yes
110
 
111
	static const int	base = 62;
112
	static const char	encoding[ base ] =
113
		"0123456789"
114
		"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
115
		"abcdefghijklmnopqrstuvwxyz";
116
 
117
	/**
118
	 *	TDateTime is in local time, and the DCE currently uses UTC.  Therefore,
119
	 *	we use time() to get seconds since midnight in UTC, and use TDateTime
120
	 *	only to get msec.
121
	 */
122
	unsigned short	hour;
123
	unsigned short	minute;
124
	unsigned short	second;
125
	unsigned short	millisecond;
126
	struct stat		statbuf;
127
	time_t			now;
128
	char			encodingTime[ 9 ];
129
 
130
	/**
131
	 *	Do this until we have a filename, but no more than 10,000 iterations,
132
	 *	which should be a little over 10 seconds.
133
	 */
134
	for ( int safetyLimit = 10000; safetyLimit; --safetyLimit )
135
	{
136
		TDateTime::CurrentDateTime().DecodeTime(
137
			&hour,
138
			&minute,
139
			&second,
140
			&millisecond );
141
 
142
		time( &now );
143
 
144
		encodingTime[ 6 ] = encoding[ millisecond % base ];
145
		millisecond /= base;
146
		encodingTime[ 5 ] = encoding[ millisecond % base ];
147
 
148
		encodingTime[ 4 ] = encoding[ now % base ];
149
		now /= base;
150
		encodingTime[ 3 ] = encoding[ now % base ];
151
		now /= base;
152
		encodingTime[ 2 ] = encoding[ now % base ];
153
		now /= base;
154
		encodingTime[ 1 ] = encoding[ now % base ];
155
		now /= base;
156
		encodingTime[ 0 ] = encoding[ now % base ];
157
 
158
		for ( int counter=0; counter < base; ++counter )
159
		{
160
			encodingTime[ 7 ] = encoding[ counter ];
161
			encodingTime[ 8 ] = 0;
162
 
163
			std::stringstream name;
164
			if ( folder.length() )
165
			{
166
				name << folder;
167
				if ( folder[ folder.length() - 1 ] != g_separator )
168
				{
169
					name << g_separator;
170
				}
171
			}
172
 
173
			if ( prefix.length() )
174
			{
175
				name << prefix;
176
			}
177
 
178
			name << encodingTime;
179
 
180
			if ( batchName.length() )
181
			{
182
				name << '_' << batchName << '_' << std::setw( 4 ) << std::setfill( '0' ) << std::right << batchNumber;
183
			}
184
 
185
			if ( suffix.length() )
186
			{
187
				name << suffix;
188
			}
189
 
190
			filename = name.str();
191
 
192
			if ( stat( filename.c_str(), &statbuf ) == -1 )
193
			{
194
				return ( filename );
195
			}
196
		}
197
 
198
		Sleep( 1 );
199
	}
200
 
201
	MTHROW( std::runtime_error, \
202
		"Cannot build a filename that is not already in use in \"" \
203
		<< folder \
204
		<< "\" with prefix \"" \
205
		<< prefix \
206
		<< "\" and suffix \"" \
207
		<< suffix \
208
		<< "\"." );
209
 
210
  //## end TransactionStream::buildFileName%420821AD02EF.body
211
}
212
 
213
//## Operation: close%420819C203E4
214
void TransactionStream::close ()
215
{
216
  //## begin TransactionStream::close%420819C203E4.body preserve=yes
217
 
218
	if ( m_stream )
219
	{
220
		m_stream->close();
221
 
222
		delete m_stream;
223
		m_stream = 0;
224
	}
225
 
226
  //## end TransactionStream::close%420819C203E4.body
227
}
228
 
229
//## Operation: incrementCount%420723C60224
230
void TransactionStream::incrementCount ()
231
{
232
  //## begin TransactionStream::incrementCount%420723C60224.body preserve=yes
233
 
234
	/**
235
	 *	When we have a batch size (and so we batch), then we may need to
236
	 *	start a new batch.
237
	 */
238
	if ( m_batchSize )
239
	{
2265 kivins 240
		if ( m_batchCount++ >= m_batchSize )
2263 kivins 241
		{
242
			close();
243
			m_batchCount = 0;
244
			++m_batchNumber;
245
			open();
246
		}
247
	}
248
 
249
  //## end TransactionStream::incrementCount%420723C60224.body
250
}
251
 
252
//## Operation: newBatch%420722B50215
253
const bool TransactionStream::newBatch (const unsigned &size, const std::string &name)
254
{
255
  //## begin TransactionStream::newBatch%420722B50215.body preserve=yes
256
 
257
	m_batchSize		= size;
258
	m_batchCount	= 0;
259
	m_batchName		= name;
260
 
261
	return ( open() );
262
 
263
  //## end TransactionStream::newBatch%420722B50215.body
264
}
265
 
266
//## Operation: open%420819AE03C4
267
const bool TransactionStream::open ()
268
{
269
  //## begin TransactionStream::open%420819AE03C4.body preserve=yes
270
 
271
	close();	// Close the stream should it be open.
272
 
273
	std::string filename;
274
	buildFileName( filename, m_folder, m_batchPrefix, m_batchSuffix, m_batchName, m_batchNumber );
275
 
276
	m_stream = new std::ofstream(
277
		filename.c_str(),
278
		std::ios_base::binary | std::ios_base::out );
279
	if ( m_stream->is_open() )
280
	{
281
		if ( m_manifest )
282
		{
283
			m_manifest->addUdFile( filename );
284
		}
285
		return ( true );
286
	}
287
 
288
	// When we can't open the file, then roll back.
289
	delete m_stream;
290
	m_stream = 0;
291
 
292
	MERROR( "Cannot open \"" << filename << "\" for writing." );
293
	return ( false );
294
 
295
  //## end TransactionStream::open%420819AE03C4.body
296
}
297
 
298
//## Operation: write%4207231D014A
299
const bool TransactionStream::write (const void *buffer, const unsigned &length)
300
{
301
  //## begin TransactionStream::write%4207231D014A.body preserve=yes
302
 
303
	if ( m_stream )
304
	{
305
		m_stream->write( reinterpret_cast< const char * >( buffer ), length );
306
 
307
		if ( m_stream->good() )
308
		{
309
			return ( true );
310
		}
311
		else
312
		{
313
			MERROR( "Cannot write " << length << " byte(s) to stream." );
314
		}
315
	}
316
	else
317
	{
318
		MERROR( "Cannot write to stream because it is not open." );
319
	}
320
 
321
	return ( false );
322
 
323
  //## end TransactionStream::write%4207231D014A.body
324
}
325
 
326
// Additional Declarations
327
  //## begin TransactionStream%420720460243.declarations preserve=yes
328
  //## end TransactionStream%420720460243.declarations
329
 
330
const void TransactionStream::logToManifest (const std::string & info, const bool &addTime )
331
{
332
     TDateTime t;
333
     String st = "";
334
     String details;
335
 
336
     if (addTime) 
337
     {
338
        t = Time();
339
        st = TimeToStr(t) + "   ";
340
     }
341
 
342
     details = "# " + st + AnsiString(info.c_str());
343
 
344
     //pass the data on without added value at this stage
345
     if ( m_manifest )
346
     {
347
         m_manifest->addTestDetails(details.c_str());
348
     }
349
}
350
 
351
 
352
//## begin module%420720460243.epilog preserve=yes
353
//## end module%420720460243.epilog