Subversion Repositories DevTools

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2218 sbetterm 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
// TransactionStream
37
#include "TransactionStream.h"
38
// UdFileManifest
39
#include "UdFileManifest.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)
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
	}
81
 
82
  //## end TransactionStream::TransactionStream%4207228700FB.body
83
}
84
 
85
 
86
TransactionStream::~TransactionStream()
87
{
88
  //## begin TransactionStream::~TransactionStream%420720460243_dest.body preserve=yes
89
 
90
	close();
91
 
92
	if ( m_manifest )
93
	{
94
		delete m_manifest;
95
		m_manifest = 0;
96
	}
97
 
98
 
99
  //## end TransactionStream::~TransactionStream%420720460243_dest.body
100
}
101
 
102
 
103
 
104
//## Other Operations (implementation)
105
//## Operation: buildFileName%420821AD02EF
106
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)
107
{
108
  //## begin TransactionStream::buildFileName%420821AD02EF.body preserve=yes
109
 
110
	static const int	base = 62;
111
	static const char	encoding[ base ] =
112
		"0123456789"
113
		"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
114
		"abcdefghijklmnopqrstuvwxyz";
115
 
116
	/**
117
	 *	TDateTime is in local time, and the DCE currently uses UTC.  Therefore,
118
	 *	we use time() to get seconds since midnight in UTC, and use TDateTime
119
	 *	only to get msec.
120
	 */
121
	unsigned short	hour;
122
	unsigned short	minute;
123
	unsigned short	second;
124
	unsigned short	millisecond;
125
	struct stat		statbuf;
126
	time_t			now;
127
	char			encodingTime[ 9 ];
128
 
129
	/**
130
	 *	Do this until we have a filename, but no more than 10,000 iterations,
131
	 *	which should be a little over 10 seconds.
132
	 */
133
	for ( int safetyLimit = 10000; safetyLimit; --safetyLimit )
134
	{
135
		TDateTime::CurrentDateTime().DecodeTime(
136
			&hour,
137
			&minute,
138
			&second,
139
			&millisecond );
140
 
141
		time( &now );
142
 
143
		encodingTime[ 6 ] = encoding[ millisecond % base ];
144
		millisecond /= base;
145
		encodingTime[ 5 ] = encoding[ millisecond % base ];
146
 
147
		encodingTime[ 4 ] = encoding[ now % base ];
148
		now /= base;
149
		encodingTime[ 3 ] = encoding[ now % base ];
150
		now /= base;
151
		encodingTime[ 2 ] = encoding[ now % base ];
152
		now /= base;
153
		encodingTime[ 1 ] = encoding[ now % base ];
154
		now /= base;
155
		encodingTime[ 0 ] = encoding[ now % base ];
156
 
157
		for ( int counter=0; counter < base; ++counter )
158
		{
159
			encodingTime[ 7 ] = encoding[ counter ];
160
			encodingTime[ 8 ] = 0;
161
 
162
			std::stringstream name;
163
			if ( folder.length() )
164
			{
165
				name << folder;
166
				if ( folder[ folder.length() - 1 ] != g_separator )
167
				{
168
					name << g_separator;
169
				}
170
			}
171
 
172
			if ( prefix.length() )
173
			{
174
				name << prefix;
175
			}
176
 
177
			name << encodingTime;
178
 
179
			if ( batchName.length() )
180
			{
181
				name << '_' << batchName << '_' << std::setw( 4 ) << std::setfill( '0' ) << std::right << batchNumber;
182
			}
183
 
184
			if ( suffix.length() )
185
			{
186
				name << suffix;
187
			}
188
 
189
			filename = name.str();
190
 
191
			if ( stat( filename.c_str(), &statbuf ) == -1 )
192
			{
193
				return ( filename );
194
			}
195
		}
196
 
197
		Sleep( 1 );
198
	}
199
 
200
	MTHROW( std::runtime_error, \
201
		"Cannot build a filename that is not already in use in \"" \
202
		<< folder \
203
		<< "\" with prefix \"" \
204
		<< prefix \
205
		<< "\" and suffix \"" \
206
		<< suffix \
207
		<< "\"." );
208
 
209
  //## end TransactionStream::buildFileName%420821AD02EF.body
210
}
211
 
212
//## Operation: close%420819C203E4
213
void TransactionStream::close ()
214
{
215
  //## begin TransactionStream::close%420819C203E4.body preserve=yes
216
 
217
	if ( m_stream )
218
	{
219
		m_stream->close();
220
 
221
		delete m_stream;
222
		m_stream = 0;
223
	}
224
 
225
  //## end TransactionStream::close%420819C203E4.body
226
}
227
 
228
//## Operation: incrementCount%420723C60224
229
void TransactionStream::incrementCount ()
230
{
231
  //## begin TransactionStream::incrementCount%420723C60224.body preserve=yes
232
 
233
	/**
234
	 *	When we have a batch size (and so we batch), then we may need to
235
	 *	start a new batch.
236
	 */
237
	if ( m_batchSize )
238
	{
239
		if ( ++m_batchCount >= m_batchSize )
240
		{
241
			close();
242
			m_batchCount = 0;
243
			++m_batchNumber;
244
			open();
245
		}
246
	}
247
 
248
  //## end TransactionStream::incrementCount%420723C60224.body
249
}
250
 
251
//## Operation: newBatch%420722B50215
252
const bool TransactionStream::newBatch (const unsigned &size, const std::string &name)
253
{
254
  //## begin TransactionStream::newBatch%420722B50215.body preserve=yes
255
 
256
	m_batchSize		= size;
257
	m_batchCount	= 0;
258
	m_batchName		= name;
259
 
260
	return ( open() );
261
 
262
  //## end TransactionStream::newBatch%420722B50215.body
263
}
264
 
265
//## Operation: open%420819AE03C4
266
const bool TransactionStream::open ()
267
{
268
  //## begin TransactionStream::open%420819AE03C4.body preserve=yes
269
 
270
	close();	// Close the stream should it be open.
271
 
272
	std::string filename;
273
	buildFileName( filename, m_folder, m_batchPrefix, m_batchSuffix, m_batchName, m_batchNumber );
274
 
275
	m_stream = new std::ofstream(
276
		filename.c_str(),
277
		std::ios_base::binary | std::ios_base::out );
278
	if ( m_stream->is_open() )
279
	{
280
		if ( m_manifest )
281
		{
282
			m_manifest->addUdFile( filename );
283
		}
284
		return ( true );
285
	}
286
 
287
	// When we can't open the file, then roll back.
288
	delete m_stream;
289
	m_stream = 0;
290
 
291
	MERROR( "Cannot open \"" << filename << "\" for writing." );
292
	return ( false );
293
 
294
  //## end TransactionStream::open%420819AE03C4.body
295
}
296
 
297
//## Operation: write%4207231D014A
298
const bool TransactionStream::write (const void *buffer, const unsigned &length)
299
{
300
  //## begin TransactionStream::write%4207231D014A.body preserve=yes
301
 
302
	if ( m_stream )
303
	{
304
		m_stream->write( reinterpret_cast< const char * >( buffer ), length );
305
 
306
		if ( m_stream->good() )
307
		{
308
			return ( true );
309
		}
310
		else
311
		{
312
			MERROR( "Cannot write " << length << " byte(s) to stream." );
313
		}
314
	}
315
	else
316
	{
317
		MERROR( "Cannot write to stream because it is not open." );
318
	}
319
 
320
	return ( false );
321
 
322
  //## end TransactionStream::write%4207231D014A.body
323
}
324
 
325
// Additional Declarations
326
  //## begin TransactionStream%420720460243.declarations preserve=yes
327
  //## end TransactionStream%420720460243.declarations
328
 
329
//## begin module%420720460243.epilog preserve=yes
330
//## end module%420720460243.epilog