perfsrv/analyzetool/commandlineengine/src/CATParseTraceFile.cpp
changeset 48 516af714ebb4
child 52 c2f44e33b468
equal deleted inserted replaced
45:185201be11b0 48:516af714ebb4
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Definitions for the class CATParseTraceFile.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "../inc/ATCommonDefines.h"
       
    20 #include "../inc/CATParseTraceFile.h"
       
    21 #include "../inc/catdatasaver.h"
       
    22 #include "../inc/CATDatParser.h"
       
    23 #include "../inc/CATProcessData.h"
       
    24 
       
    25 #include <time.h>
       
    26 
       
    27 
       
    28 
       
    29 // -----------------------------------------------------------------------------
       
    30 // CATParseTraceFile::CATParseTraceFile
       
    31 // Constructor.
       
    32 // -----------------------------------------------------------------------------
       
    33 CATParseTraceFile::CATParseTraceFile()
       
    34 {
       
    35 	LOG_FUNC_ENTRY("CATParseTraceFile::CATParseTraceFile");
       
    36 	m_DataSaver.SetPrintFlag( false );
       
    37 }
       
    38 
       
    39 // -----------------------------------------------------------------------------
       
    40 // CATParseTraceFile::StartParse
       
    41 // Main function to start trace parsing.
       
    42 // -----------------------------------------------------------------------------
       
    43 bool CATParseTraceFile::StartParse( const char* pFileName, const char* pOutputFileName, const char* pCleanedTraceFile )
       
    44 {
       
    45 	LOG_FUNC_ENTRY("CATParseTraceFile::StartParse");
       
    46 
       
    47 	// Return value, will be changed to true if process start found.
       
    48 	bool bRet = false;
       
    49 	bool bCreateCleanedTraces = false;
       
    50 
       
    51 	// Check pointers
       
    52 	if ( pFileName == NULL  )
       
    53 		return bRet;
       
    54 
       
    55 	if( pOutputFileName == NULL )
       
    56 		return bRet;
       
    57 
       
    58 	if ( ! FileExists( pFileName ) )
       
    59 	{
       
    60 		cout << AT_MSG << "Error, input file \""
       
    61 			<< pFileName
       
    62 			<< "\" does not exist." << endl;
       
    63 		return bRet;
       
    64 	}
       
    65 
       
    66 	ofstream cleanedTraces;
       
    67 
       
    68 	// check is creation of file needed
       
    69 	if( pCleanedTraceFile != NULL )
       
    70 	{
       
    71 		// if yes open file for cleaned traces
       
    72 	    // (<AT> messages with cleaned timestamps)
       
    73 		bCreateCleanedTraces = true;
       
    74 
       
    75 		cleanedTraces.open(pCleanedTraceFile);
       
    76 
       
    77 		if( !cleanedTraces.good() )
       
    78 		{
       
    79 			printf( "Can not open file: %s\n", pCleanedTraceFile );
       
    80 			return bRet;
       
    81 		}
       
    82 	}
       
    83 
       
    84 	// Open data file
       
    85 	ifstream in( pFileName );
       
    86 
       
    87 	// Check file opened ok
       
    88 	if ( !in.good() )
       
    89 		return false;
       
    90 
       
    91 	// Get stream size
       
    92 	size_t streamPos = in.tellg();
       
    93 	in.seekg( 0, ios::end);
       
    94 	size_t streamEnd = in.tellg();
       
    95 	in.seekg( 0, ios::beg);
       
    96 
       
    97 	//Origianl characters (not filtered).
       
    98 	char cOriginalLineFromFile[MAX_LINE_LENGTH];
       
    99 
       
   100 	vector<CProcessData> vProcessList;
       
   101 	int iProcessIDinList = -1;
       
   102 
       
   103 	bool bFileVersionSaved = false;
       
   104 	// Read lines
       
   105 	while( streamPos < streamEnd )
       
   106 	{
       
   107 		// Get one line. Don't use stream flags to determinate end of file
       
   108 		// it can be found too early because trace can contain "anything".
       
   109 		in.getline( cOriginalLineFromFile, MAX_LINE_LENGTH );
       
   110 		
       
   111 		// Refresh position
       
   112 		streamPos = in.tellg();
       
   113 
       
   114 		// Check has bad bit flag raised. (i.e. device problems reading data)
       
   115 		if( in.bad() )
       
   116 		{
       
   117 			cout << AT_MSG << "Integrity error reading the trace file, reading aborted." << endl;
       
   118 			return false;
       
   119 		}
       
   120 		//Filtered characters.
       
   121 		char cLineFromFile[MAX_LINE_LENGTH];
       
   122 		char* pFiltered = cLineFromFile;
       
   123 
       
   124 		//Loop thru all characters in original line.
       
   125 		for( size_t i = 0 ; cOriginalLineFromFile[i] != 0 ; i++ )
       
   126 		{
       
   127 			//If character in line is not in invalid character array append it
       
   128 			//to filtered line.
       
   129 			if ( strchr( cINVALID_TRACE_FILE_CHARS, cOriginalLineFromFile[i] ) == 0 )
       
   130 					*pFiltered++ =  cOriginalLineFromFile[i];
       
   131 		}
       
   132 		*pFiltered++ = 0; //Add null termination to filtered line.
       
   133 
       
   134 		if( !bFileVersionSaved && *cLineFromFile != 0 )
       
   135 		{
       
   136 			bFileVersionSaved = true;
       
   137 			m_DataSaver.AddString( AT_DATA_FILE_VERSION );
       
   138 			m_DataSaver.AddLineToLast();
       
   139 		}
       
   140 
       
   141 		// Is there main ID?
       
   142 		if( strstr( cLineFromFile, MAIN_ID ) != NULL )
       
   143 		{
       
   144 			string sRestOfLine( cLineFromFile );
       
   145 			string sTemp("");
       
   146 			unsigned __int64 iTimeStamp(0);
       
   147 			string sTime("");
       
   148 			string sLineStart("");
       
   149 
       
   150 			// Get part of line before main id. This should contain time info
       
   151 			sLineStart = GetStringUntilMainId( sRestOfLine );
       
   152 			// Get message's time stamp in microseconds
       
   153 			iTimeStamp = ParseTimeStamp( sLineStart );
       
   154 			// store whole line from MAIN_ID - to be logged to cleaned traces file
       
   155 		    string sLineToCleanedFile( sRestOfLine );
       
   156 
       
   157 			// Get main ID
       
   158 			sTemp = GetStringUntilNextSpace( sRestOfLine );
       
   159 
       
   160 			// Is there more data in line?
       
   161 			if( sRestOfLine.empty() )
       
   162 			{
       
   163 				continue;
       
   164 			}
       
   165 
       
   166 			// Get next argument
       
   167 			sTemp = GetStringUntilNextSpace( sRestOfLine );
       
   168 			// This might be process id, device info message or error message
       
   169 			if ( sTemp.compare( ERROR_OCCURED ) == 0 )
       
   170 			{
       
   171 				// Api mismatch between s60 side and atool.exe
       
   172 				if ( sRestOfLine.find( INCORRECT_ATOOL_VERSION ) != string::npos )
       
   173 				{
       
   174 					cout << "Test run failed because version conflict between device binaries\nand the atool.exe version used to build the application." << endl;
       
   175 					size_t pS = sRestOfLine.find_first_of('[');
       
   176 					size_t pE =  sRestOfLine.find_first_of(']');
       
   177 					size_t pSL = sRestOfLine.find_last_of('[');
       
   178 					size_t pEL = sRestOfLine.find_last_of(']');
       
   179 					if ( pS != string::npos && pE != string::npos && pSL != string::npos && pEL != string::npos )
       
   180 					{
       
   181 						string deviceVer = sRestOfLine.substr( pS+1, pE-pS-1 );
       
   182 						string atoolVer = sRestOfLine.substr( pSL+1, pEL-pSL-1 );
       
   183 						cout << "\tdevice: " << deviceVer << endl 
       
   184 							<<  "\tatool.exe: " << atoolVer << endl;
       
   185 					}
       
   186 				}
       
   187 				else
       
   188 					cout << sRestOfLine << endl;
       
   189 				continue;
       
   190 			}
       
   191 
       
   192 			if ( sTemp.compare( LABEL_DEVICE_INFO ) == 0 ) 
       
   193 			{
       
   194 
       
   195 				if( vProcessList[iProcessIDinList].bProcessOnGoing == false )
       
   196 				continue;
       
   197 
       
   198 				// get time string from timestamp
       
   199 			    sTime = GetTimeFromTimeStamp( iTimeStamp, vProcessList[iProcessIDinList].iTimeSpan );
       
   200 
       
   201 				// device info line, log it to cleaned file for carbide
       
   202 				if( bCreateCleanedTraces )
       
   203 				{
       
   204 				// add message to cleaned traces file
       
   205 				cleanedTraces << sTime << " "; //add time
       
   206 				cleanedTraces << MAIN_ID << " "; //add MAIN_ID
       
   207 				cleanedTraces << LABEL_DEVICE_INFO << " "; //add Message type
       
   208 				cleanedTraces << sRestOfLine << "\n"; //add the rest of the line
       
   209 				}
       
   210 				continue;
       
   211 			}
       
   212 
       
   213 			unsigned long iProcessID = _httoi( sTemp.c_str() );
       
   214 			// todo to be removed when reallocations are implemented
       
   215 			string sProcessID = sTemp;
       
   216 
       
   217 			iProcessIDinList = -1;
       
   218 			// Find process from list
       
   219 			for( unsigned int i = 0 ; i < vProcessList.size() ; i++ )
       
   220 			{
       
   221 				if( vProcessList[i].iProcessID == iProcessID )
       
   222 				{
       
   223 					iProcessIDinList = i;
       
   224 					break;
       
   225 				}
       
   226 			}
       
   227 			// Is Process ID found from list?
       
   228 			if( iProcessIDinList == -1 )
       
   229 			{
       
   230 				CProcessData ProcessData;
       
   231 				ProcessData.bProcessOnGoing = false;
       
   232 				ProcessData.iProcessID = iProcessID;
       
   233 				vProcessList.push_back( ProcessData );
       
   234 				iProcessIDinList = (int)vProcessList.size() - 1;
       
   235 			}
       
   236 
       
   237 			// Remove spaces from end of line
       
   238 			while( sRestOfLine[sRestOfLine.size()-1] == ' ' )
       
   239 			{
       
   240 				sRestOfLine.resize( sRestOfLine.size()-1 );
       
   241 			}
       
   242 
       
   243 			string sWholeTempLine( sRestOfLine );
       
   244 
       
   245 			// Get command
       
   246 			sTemp = GetStringUntilNextSpace( sRestOfLine );
       
   247 
       
   248 			// Use c style string for easy comparisong of command.
       
   249 			const char* pCommand = sTemp.c_str();		
       
   250 
       
   251 			// Process start.
       
   252 			if( ! _stricmp( pCommand, LABEL_PROCESS_START ) )
       
   253 			{
       
   254 				bRet = true; // Set return value true we found start.
       
   255 				vProcessList[iProcessIDinList].vData.push_back( sWholeTempLine );
       
   256 				vProcessList[iProcessIDinList].bProcessOnGoing = true;
       
   257 
       
   258 				// remove <processName> <processID> part
       
   259 				GetStringUntilNextSpace( sRestOfLine );
       
   260 				GetStringUntilNextSpace( sRestOfLine );
       
   261 				// get time
       
   262 				sTemp = GetStringUntilNextSpace( sRestOfLine );
       
   263 				unsigned __int64 iTemp(0);
       
   264 				sscanf_s( sTemp.c_str(), "%016I64x", &iTemp);
       
   265 				//calculate span between PCS time and PCS timestamp
       
   266 				vProcessList[iProcessIDinList].iTimeSpan = iTemp - iTimeStamp;
       
   267 
       
   268 				if( bCreateCleanedTraces )
       
   269 				{
       
   270 				// add message to cleaned traces file
       
   271 				cleanedTraces << sTemp << " "; //add time
       
   272 				cleanedTraces << MAIN_ID << " "; //add MAIN_ID
       
   273 				cleanedTraces << sProcessID << " "; //add process ID
       
   274 				cleanedTraces << sWholeTempLine << "\n"; //add the rest of the line
       
   275 				}
       
   276 
       
   277 				continue;
       
   278 			}
       
   279 
       
   280 			// Check is process ongoing if not skip other tags.
       
   281 			if( vProcessList[iProcessIDinList].bProcessOnGoing == false )
       
   282 				continue;
       
   283 
       
   284 			// get time string from timestamp
       
   285 			sTime = GetTimeFromTimeStamp( iTimeStamp, vProcessList[iProcessIDinList].iTimeSpan );
       
   286 
       
   287 			// TODO version with reallocation
       
   288 			//cleanedTraces << sTime << " "; //add time
       
   289 			//cleanedTraces << sLineToCleanedFile << "\n"; //add the rest of the line
       
   290 
       
   291 			// "Old style" allocation (< v.1.6)
       
   292 			if( ! _stricmp( pCommand, ALLOC_ID ) )
       
   293 			{
       
   294 				// Add alloc
       
   295 				vProcessList[iProcessIDinList].Alloc( sRestOfLine );
       
   296 
       
   297 				// Subtests running?
       
   298 				vector<CSubTestData>::iterator viSubTestIter = vProcessList[iProcessIDinList].vSubTests.begin();
       
   299 				while( viSubTestIter != vProcessList[iProcessIDinList].vSubTests.end() )
       
   300 				{
       
   301 					if( viSubTestIter->bRunning )
       
   302 					{
       
   303 						// Save alloc also to sub test
       
   304 						viSubTestIter->Alloc( sRestOfLine );
       
   305 					}
       
   306 					viSubTestIter++;
       
   307 				}
       
   308 			}
       
   309 			else if ( ! _stricmp( pCommand, ALLOCH_ID ) )
       
   310 			{
       
   311 				if( bCreateCleanedTraces )
       
   312 				{
       
   313 				// add message to cleaned traces file
       
   314 				cleanedTraces << sTime << " "; //add time
       
   315 				cleanedTraces << MAIN_ID << " "; //add MAIN_ID
       
   316 				cleanedTraces << sProcessID << " "; //add process ID
       
   317 				cleanedTraces << sWholeTempLine << "\n"; //add the rest of the line
       
   318 				}
       
   319 
       
   320 				// Add alloc
       
   321 				vProcessList[iProcessIDinList].AllocH( sRestOfLine, sTime );
       
   322 
       
   323 				// Subtests running?
       
   324 				vector<CSubTestData>::iterator viSubTestIter = vProcessList[iProcessIDinList].vSubTests.begin();
       
   325 				while( viSubTestIter != vProcessList[iProcessIDinList].vSubTests.end() )
       
   326 				{
       
   327 					if( viSubTestIter->bRunning )
       
   328 					{
       
   329 						// Save alloc also to sub test
       
   330 						viSubTestIter->AllocH( sRestOfLine, sTime );
       
   331 					}
       
   332 					viSubTestIter++;
       
   333 				}
       
   334 			}
       
   335 			// Allocation fragment (call stack).
       
   336 			else if ( ! _stricmp( pCommand, ALLOCF_ID ) )
       
   337 			{
       
   338 				if( bCreateCleanedTraces )
       
   339 				{
       
   340 				// add message to cleaned traces file
       
   341 				cleanedTraces << sTime << " "; //add time
       
   342 				cleanedTraces << MAIN_ID << " "; //add MAIN_ID
       
   343 				cleanedTraces << sProcessID << " "; //add process ID
       
   344 				cleanedTraces << sWholeTempLine << "\n"; //add the rest of the line
       
   345 				}
       
   346 
       
   347 				// Add alloc fragment
       
   348 				vProcessList[iProcessIDinList].AllocF( sRestOfLine, sTime );
       
   349 				
       
   350 				// Subtests running?
       
   351 				vector<CSubTestData>::iterator viSubTestIter = vProcessList[iProcessIDinList].vSubTests.begin();
       
   352 				while( viSubTestIter != vProcessList[iProcessIDinList].vSubTests.end() )
       
   353 				{
       
   354 					if( viSubTestIter->bRunning )
       
   355 					{
       
   356 						// Save alloc fragment also to sub test
       
   357 						viSubTestIter->AllocF( sRestOfLine, sTime );
       
   358 					}
       
   359 					viSubTestIter++;
       
   360 				}
       
   361 			}
       
   362 			else if ( ! _stricmp( pCommand, REALLOCH_ID ) )
       
   363 			{
       
   364 				// Add free
       
   365 
       
   366 				// get 'free' line from realloc line
       
   367 				string sFreeRestOfLine = sRestOfLine;
       
   368 				string sFreeLine = "";
       
   369 				sFreeLine.append( GetStringUntilNextSpace( sFreeRestOfLine, true ) ); //append freed memory address
       
   370 				sFreeLine.append( " " );
       
   371 				// next two strings are for 'alloc' (address and size) - lets remove them
       
   372 				GetStringUntilNextSpace( sFreeRestOfLine, true );
       
   373 				GetStringUntilNextSpace( sFreeRestOfLine, true );
       
   374 				// add rest of line to 'free' line
       
   375 				sFreeLine.append( sFreeRestOfLine );
       
   376 				//add 'free' line
       
   377 				vProcessList[iProcessIDinList].FreeH( sFreeLine, sTime );
       
   378 
       
   379 				if( bCreateCleanedTraces )
       
   380 				{
       
   381 				// add message to cleaned traces file
       
   382 				// construct 'free' header trace
       
   383 				cleanedTraces << sTime << " "; //add time
       
   384 				cleanedTraces << MAIN_ID << " "; //add MAIN_ID
       
   385 				cleanedTraces << sProcessID << " "; //add process ID
       
   386 				cleanedTraces << FREEH_ID << " "; //add FRH
       
   387 				cleanedTraces << sFreeLine << "\n"; //add the rest of the line
       
   388 				}
       
   389 
       
   390 				// Add alloc
       
   391 
       
   392 				//get 'alloc' line from realloc line
       
   393 				// only first string is unnecessary, lets remove it
       
   394 				GetStringUntilNextSpace( sRestOfLine );
       
   395      			// add 'alloc' line
       
   396 				vProcessList[iProcessIDinList].AllocH( sRestOfLine, sTime );
       
   397 
       
   398 				if( bCreateCleanedTraces )
       
   399 				{
       
   400 				// add message to cleaned traces file
       
   401 				// construct 'alloc' header trace
       
   402 				cleanedTraces << sTime << " "; //add time
       
   403 				cleanedTraces << MAIN_ID << " "; //add MAIN_ID
       
   404 				cleanedTraces << sProcessID << " "; //add process ID
       
   405 				cleanedTraces << ALLOCH_ID << " "; //add FRH
       
   406 				cleanedTraces << sRestOfLine << "\n"; //add the rest of the line
       
   407 				}
       
   408 
       
   409 				// Subtests running?
       
   410 				vector<CSubTestData>::iterator viSubTestIter = vProcessList[iProcessIDinList].vSubTests.begin();
       
   411 				while( viSubTestIter != vProcessList[iProcessIDinList].vSubTests.end() )
       
   412 				{
       
   413 					if( viSubTestIter->bRunning )
       
   414 					{
       
   415 						// Save realloc also to sub test
       
   416 						// Add free
       
   417 
       
   418 						// get 'free' line from realloc line
       
   419 						string sFreeRestOfLine = sRestOfLine;
       
   420 						string sFreeLine = "";
       
   421 						sFreeLine.append( GetStringUntilNextSpace( sFreeRestOfLine, true ) ); //append freed memory address
       
   422 						sFreeLine.append( " " );
       
   423 						// next two strings are for 'alloc' (address and size) - lets remove them
       
   424 						GetStringUntilNextSpace( sFreeRestOfLine, true );
       
   425 						GetStringUntilNextSpace( sFreeRestOfLine, true );
       
   426 						// add rest of line to 'free' line
       
   427 						sFreeLine.append( sFreeRestOfLine );
       
   428 						//add 'free' line
       
   429 						vProcessList[iProcessIDinList].FreeH( sFreeLine, sTime );
       
   430 
       
   431 						// Add alloc
       
   432 
       
   433 						//get 'alloc' line from realloc line
       
   434 						// only first string is unnecessary, lets remove it
       
   435 						GetStringUntilNextSpace( sRestOfLine );
       
   436      					// add 'alloc' line
       
   437 						vProcessList[iProcessIDinList].AllocH( sRestOfLine, sTime );
       
   438 					}
       
   439 					viSubTestIter++;
       
   440 				}
       
   441 			}
       
   442 			// rellocation fragment (call stack).
       
   443 			else if ( ! _stricmp( pCommand, REALLOCF_ID ) )
       
   444 			{
       
   445 				// Add free fragment 
       
   446 
       
   447 				// get 'free' line from realloc line
       
   448 				string sFreeRestOfLine = sRestOfLine;
       
   449 				string sFreeLine = "";
       
   450 				sFreeLine.append( GetStringUntilNextSpace( sFreeRestOfLine, true ) ); //append freed memory address
       
   451 				sFreeLine.append( " " );
       
   452 				// next string is for 'alloc' (address) - lets remove it
       
   453 				GetStringUntilNextSpace( sFreeRestOfLine, true );
       
   454 				// add rest of line to 'free' line
       
   455 				sFreeLine.append( sFreeRestOfLine );
       
   456 				//add 'free' line
       
   457 				vProcessList[iProcessIDinList].FreeH( sFreeLine, sTime );
       
   458 
       
   459 				if( bCreateCleanedTraces )
       
   460 				{
       
   461 				// add message to cleaned traces file
       
   462 				// construct 'free' fragment trace
       
   463 				cleanedTraces << sTime << " "; //add time
       
   464 				cleanedTraces << MAIN_ID << " "; //add MAIN_ID
       
   465 				cleanedTraces << sProcessID << " "; //add process ID
       
   466 				cleanedTraces << FREEF_ID << " "; //add FRF
       
   467 				cleanedTraces << sFreeLine << "\n"; //add the rest of the line
       
   468 				}
       
   469 
       
   470 				// Add alloc fragment
       
   471 
       
   472 				// first string is for 'free' (address), lets remove it first
       
   473 				GetStringUntilNextSpace( sRestOfLine, true );
       
   474 				//add 'alloc' line
       
   475 				vProcessList[iProcessIDinList].AllocF( sRestOfLine, sTime );
       
   476 
       
   477 				if( bCreateCleanedTraces )
       
   478 				{
       
   479 				// add message to cleaned traces file
       
   480 				// construct 'alloc' fragment trace
       
   481 				cleanedTraces << sTime << " "; //add time
       
   482 				cleanedTraces << MAIN_ID << " "; //add MAIN_ID
       
   483 				cleanedTraces << sProcessID << " "; //add process ID
       
   484 				cleanedTraces << ALLOCF_ID << " "; //add FRF
       
   485 				cleanedTraces << sRestOfLine << "\n"; //add the rest of the line
       
   486 				}
       
   487 				
       
   488 				// Subtests running?
       
   489 				vector<CSubTestData>::iterator viSubTestIter = vProcessList[iProcessIDinList].vSubTests.begin();
       
   490 				while( viSubTestIter != vProcessList[iProcessIDinList].vSubTests.end() )
       
   491 				{
       
   492 					if( viSubTestIter->bRunning )
       
   493 					{
       
   494 						// Save alloc fragment also to sub test
       
   495 						// Add free fragment 
       
   496 
       
   497 						// get 'free' line from realloc line
       
   498 						string sFreeRestOfLine = sRestOfLine;
       
   499 						string sFreeLine = "";
       
   500 						sFreeLine.append( GetStringUntilNextSpace( sFreeRestOfLine, true ) ); //append freed memory address
       
   501 						sFreeLine.append( " " );
       
   502 						// next string is for 'alloc' (address) - lets remove it
       
   503 						GetStringUntilNextSpace( sFreeRestOfLine, true );
       
   504 						// add rest of line to 'free' line
       
   505 						sFreeLine.append( sFreeRestOfLine );
       
   506 						//add 'free' line
       
   507 						vProcessList[iProcessIDinList].FreeH( sFreeLine, sTime );
       
   508 
       
   509 						// Add alloc fragment
       
   510 
       
   511 						// first string is for 'free' (address), lets remove it first
       
   512 						GetStringUntilNextSpace( sRestOfLine, true );
       
   513 						//add 'alloc' line
       
   514 						vProcessList[iProcessIDinList].AllocF( sRestOfLine, sTime );
       
   515 					}
       
   516 					viSubTestIter++;
       
   517 				}
       
   518 			}
       
   519 			// Command free
       
   520 			else if( ! _stricmp( pCommand, FREE_ID ) )
       
   521 			{
       
   522 				// Send free
       
   523 				vProcessList[iProcessIDinList].Free( sRestOfLine );
       
   524 
       
   525 				// Subtests running?
       
   526 				vector<CSubTestData>::iterator viSubTestIter = vProcessList[iProcessIDinList].vSubTests.begin();
       
   527 				while( viSubTestIter != vProcessList[iProcessIDinList].vSubTests.end() )
       
   528 				{
       
   529 					if( viSubTestIter->bRunning )
       
   530 					{
       
   531 						// Send free to subtest
       
   532 						viSubTestIter->Free( sRestOfLine );
       
   533 					}
       
   534 					viSubTestIter++;
       
   535 				}
       
   536 			}
       
   537 			// Header free.
       
   538 			else if( ! _stricmp( pCommand, FREEH_ID ) )
       
   539 			{
       
   540 				if( bCreateCleanedTraces )
       
   541 				{
       
   542 				// add message to cleaned traces file
       
   543 				cleanedTraces << sTime << " "; //add time
       
   544 				cleanedTraces << MAIN_ID << " "; //add MAIN_ID
       
   545 				cleanedTraces << sProcessID << " "; //add process ID
       
   546 				cleanedTraces << sWholeTempLine << "\n"; //add the rest of the line
       
   547 				}
       
   548 
       
   549 				// Send free
       
   550 				vProcessList[iProcessIDinList].FreeH( sRestOfLine, sTime );
       
   551 
       
   552 				// Subtests running?
       
   553 				vector<CSubTestData>::iterator viSubTestIter = vProcessList[iProcessIDinList].vSubTests.begin();
       
   554 				while( viSubTestIter != vProcessList[iProcessIDinList].vSubTests.end() )
       
   555 				{
       
   556 					if( viSubTestIter->bRunning )
       
   557 					{
       
   558 						// Send free to subtest
       
   559 						viSubTestIter->FreeH( sRestOfLine, sTime );
       
   560 					}
       
   561 					viSubTestIter++;
       
   562 				}
       
   563 			
       
   564 			}
       
   565 			else if( ! _stricmp( pCommand, FREEF_ID ) )
       
   566 			{
       
   567 				if( bCreateCleanedTraces )
       
   568 				{
       
   569 				// add message to cleaned traces file
       
   570 				cleanedTraces << sTime << " "; //add time
       
   571 				cleanedTraces << MAIN_ID << " "; //add MAIN_ID
       
   572 				cleanedTraces << sProcessID << " "; //add process ID
       
   573 				cleanedTraces << sWholeTempLine << "\n"; //add the rest of the line
       
   574 				}
       
   575 				// Not used currently.
       
   576 			}
       
   577 			// Command process end
       
   578 			else if( ! _stricmp( pCommand, LABEL_PROCESS_END ) )
       
   579 			{
       
   580 				// append processID and time
       
   581 				sWholeTempLine.append(" ");
       
   582 				sWholeTempLine.append( sProcessID );
       
   583 				sWholeTempLine.append(" ");
       
   584 				sWholeTempLine.append( sTime );
       
   585 
       
   586 				if( bCreateCleanedTraces )
       
   587 				{
       
   588 				// add message to cleaned traces file
       
   589 				cleanedTraces << sTime << " "; //add time
       
   590 				cleanedTraces << MAIN_ID << " "; //add MAIN_ID
       
   591 				cleanedTraces << sProcessID << " "; //add process ID
       
   592 				cleanedTraces << sWholeTempLine << "\n"; //add the rest of the line
       
   593 				}
       
   594 
       
   595 				// Set process has ended.
       
   596 				vProcessList[iProcessIDinList].bProcessOnGoing = false;
       
   597 
       
   598 				// Save leaks
       
   599 				vector<string> vLeaks;
       
   600 				vector<string>::iterator viLeaks;
       
   601 				vProcessList[iProcessIDinList].GetLeakList( vLeaks );
       
   602 				for ( viLeaks = vLeaks.begin(); viLeaks != vLeaks.end(); viLeaks++ )
       
   603 				{
       
   604 					sTemp.clear();
       
   605 					sTemp.append( LABEL_MEM_LEAK );
       
   606 					sTemp.append( " " );
       
   607 					sTemp.append( *viLeaks );
       
   608 					vProcessList[iProcessIDinList].vData.push_back( sTemp );
       
   609 				}
       
   610 				vProcessList[iProcessIDinList].ClearAllocs();
       
   611 
       
   612 				vector<string>::iterator viHandleIter = vProcessList[iProcessIDinList].vHandleLeaks.begin();
       
   613 				// Print handle leaks
       
   614 				while( viHandleIter != vProcessList[iProcessIDinList].vHandleLeaks.end() )
       
   615 				{
       
   616 					sTemp.clear();
       
   617 					sTemp.append( viHandleIter->c_str() );
       
   618 					vProcessList[iProcessIDinList].vData.push_back( sTemp );
       
   619 					viHandleIter++;
       
   620 				}
       
   621 				// Clear handle leaks from list
       
   622 				vProcessList[iProcessIDinList].vHandleLeaks.clear();
       
   623 
       
   624 				vector<CSubTestData>::iterator viSubTestIter = vProcessList[iProcessIDinList].vSubTests.begin();
       
   625 				// Print sub test leaks
       
   626 				while( viSubTestIter != vProcessList[iProcessIDinList].vSubTests.end() )
       
   627 				{
       
   628 					// Print sub test start
       
   629 					string sLine( LABEL_TEST_START ); sLine.append( " " );
       
   630 					sLine.append( viSubTestIter->sStartTime ); sLine.append( " " );
       
   631 					sLine.append( viSubTestIter->sSubTestName ); sLine.append( " " );
       
   632 					sLine.append( viSubTestIter->sSubTestStartHandleCount );
       
   633 					vProcessList[iProcessIDinList].vData.push_back( sLine );
       
   634 					sLine.clear();
       
   635 
       
   636 					// DLL Loads.
       
   637 					for( vector<string>::iterator it = viSubTestIter->vData.begin();
       
   638 						it != viSubTestIter->vData.end(); it++ )
       
   639 					{
       
   640 						vProcessList[iProcessIDinList].vData.push_back( (*it) );
       
   641 					}
       
   642 
       
   643 					// Subtest leaks.
       
   644 					vector<string> vSubLeaks;
       
   645 					vector<string>::iterator viSubLeaks;
       
   646 					viSubTestIter->GetLeakList( vSubLeaks );
       
   647 					for ( viSubLeaks = vSubLeaks.begin(); viSubLeaks != vSubLeaks.end(); viSubLeaks++ )
       
   648 					{
       
   649 						sLine.append( LABEL_MEM_LEAK );
       
   650 						sLine.append( " " );
       
   651 						sLine.append( *viSubLeaks );
       
   652 						vProcessList[iProcessIDinList].vData.push_back( sLine );
       
   653 						sLine.clear();
       
   654 					}
       
   655 					viSubTestIter->ClearAllocs();
       
   656 
       
   657 					if( !viSubTestIter->sEndTime.empty() )
       
   658 					{
       
   659 						// Print sub test end
       
   660 						sLine.append( LABEL_TEST_END ); sLine.append( " " );
       
   661 						sLine.append( viSubTestIter->sEndTime ); sLine.append( " " );
       
   662 						sLine.append( viSubTestIter->sSubTestName ); sLine.append( " " );
       
   663 						sLine.append( viSubTestIter->sSubTestEndHandleCount );
       
   664 						vProcessList[iProcessIDinList].vData.push_back( sLine );
       
   665 					}
       
   666 					viSubTestIter++;
       
   667 				}
       
   668 
       
   669 				// Clear sub tests from list
       
   670 				vProcessList[iProcessIDinList].vSubTests.clear();
       
   671 				vProcessList[iProcessIDinList].vData.push_back( sWholeTempLine );
       
   672 			}
       
   673 			else if( ! _stricmp( pCommand, LABEL_HANDLE_LEAK ) )
       
   674 			{
       
   675 				if( bCreateCleanedTraces )
       
   676 				{
       
   677 				// add message to cleaned traces file
       
   678 				cleanedTraces << sTime << " "; //add time
       
   679 				cleanedTraces << MAIN_ID << " "; //add MAIN_ID
       
   680 				cleanedTraces << sProcessID << " "; //add process ID
       
   681 				cleanedTraces << sWholeTempLine << "\n"; //add the rest of the line
       
   682 				}
       
   683 
       
   684 				// Make whole line
       
   685 				sTemp.append( " " );
       
   686 				sTemp.append( sRestOfLine );
       
   687 				vProcessList[iProcessIDinList].vHandleLeaks.push_back( sTemp );
       
   688 			}
       
   689 			else if( ! _stricmp( pCommand, LABEL_DLL_LOAD ) )
       
   690 			{
       
   691 				if( bCreateCleanedTraces )
       
   692 				{
       
   693 				// add message to cleaned traces file
       
   694 				cleanedTraces << sTime << " "; //add time
       
   695 				cleanedTraces << MAIN_ID << " "; //add MAIN_ID
       
   696 				cleanedTraces << sProcessID << " "; //add process ID
       
   697 				cleanedTraces << sWholeTempLine << "\n"; //add the rest of the line
       
   698 				}
       
   699 
       
   700 				// append time to the end of the line
       
   701 				sWholeTempLine.append( " " );
       
   702 				sWholeTempLine.append( sTime );
       
   703 
       
   704 				// Add module load to process data.
       
   705 				vProcessList[iProcessIDinList].vData.push_back( sWholeTempLine );
       
   706 				// Add module load to subtest data if test running.
       
   707 				for( vector<CSubTestData>::iterator it = vProcessList[iProcessIDinList].vSubTests.begin();
       
   708 					it != vProcessList[iProcessIDinList].vSubTests.end(); it++ )
       
   709 				{
       
   710 					if( it->bRunning )
       
   711 						it->vData.push_back( sWholeTempLine );
       
   712 				}
       
   713 
       
   714 			}
       
   715 			else if( ! _stricmp( pCommand, LABEL_DLL_UNLOAD ) )
       
   716 			{
       
   717 				if( bCreateCleanedTraces )
       
   718 				{
       
   719 				// add message to cleaned traces file
       
   720 				cleanedTraces << sTime << " "; //add time
       
   721 				cleanedTraces << MAIN_ID << " "; //add MAIN_ID
       
   722 				cleanedTraces << sProcessID << " "; //add process ID
       
   723 				cleanedTraces << sWholeTempLine << "\n"; //add the rest of the line
       
   724 				}
       
   725 
       
   726 				// append time to the end of the line
       
   727 				sWholeTempLine.append( " " );
       
   728 				sWholeTempLine.append( sTime );
       
   729 
       
   730 				// Add module load to process data.
       
   731 				vProcessList[iProcessIDinList].vData.push_back( sWholeTempLine );
       
   732 				// Add module unload to subtest data if test running.
       
   733 				for( vector<CSubTestData>::iterator it = vProcessList[iProcessIDinList].vSubTests.begin();
       
   734 					it != vProcessList[iProcessIDinList].vSubTests.end(); it++ )
       
   735 				{
       
   736 					if( it->bRunning )
       
   737 						it->vData.push_back( sWholeTempLine );
       
   738 				}
       
   739 			}
       
   740 			else if( sTemp.find( LABEL_LOGGING_CANCELLED ) != string::npos ||
       
   741 				     sTemp.find( LABEL_PROCESS_END ) != string::npos || sTemp.find( LABEL_ERROR_OCCURED ) != string::npos ||
       
   742 					 sTemp.find( LABEL_HANDLE_LEAK ) != string::npos )
       
   743 			{
       
   744 				if( bCreateCleanedTraces )
       
   745 				{
       
   746 				// add message to cleaned traces file
       
   747 				cleanedTraces << sTime << " "; //add time
       
   748 				cleanedTraces << MAIN_ID << " "; //add MAIN_ID
       
   749 				cleanedTraces << sProcessID << " "; //add process ID
       
   750 				cleanedTraces << sWholeTempLine << "\n"; //add the rest of the line
       
   751 				}
       
   752 
       
   753 				vProcessList[iProcessIDinList].vData.push_back( sWholeTempLine );
       
   754 			}
       
   755 			else if( ! _stricmp( pCommand, LABEL_TEST_START ) )
       
   756 			{
       
   757 				if( bCreateCleanedTraces )
       
   758 				{
       
   759 				// add message to cleaned traces file
       
   760 				cleanedTraces << sTime << " "; //add time
       
   761 				cleanedTraces << MAIN_ID << " "; //add MAIN_ID
       
   762 				cleanedTraces << sProcessID << " "; //add process ID
       
   763 				cleanedTraces << sWholeTempLine << "\n"; //add the rest of the line
       
   764 				}
       
   765 
       
   766 				bRet = true; // Set return value true we found start.
       
   767 				// Get sub test time
       
   768 				string sSubTestTime = GetStringUntilNextSpace( sRestOfLine );
       
   769 				// Get sub test name
       
   770 				string sSubTestName = GetStringUntilNextSpace( sRestOfLine );
       
   771 				// Get sub test start handle count
       
   772 				string sSubTestStartHandleCount = GetStringUntilNextSpace( sRestOfLine );
       
   773 
       
   774 				CSubTestData SubTestData;
       
   775 				SubTestData.bRunning = true;
       
   776 				SubTestData.sStartTime = sSubTestTime;
       
   777 				SubTestData.sSubTestName = sSubTestName;
       
   778 				SubTestData.sSubTestStartHandleCount = sSubTestStartHandleCount.c_str();
       
   779 
       
   780 				vProcessList[iProcessIDinList].vSubTests.push_back( SubTestData );
       
   781 			}
       
   782 			else if( ! _stricmp( pCommand, LABEL_TEST_END ) )
       
   783 			{
       
   784 				if( bCreateCleanedTraces )
       
   785 				{
       
   786 				// add message to cleaned traces file
       
   787 				cleanedTraces << sTime << " "; //add time
       
   788 				cleanedTraces << MAIN_ID << " "; //add MAIN_ID
       
   789 				cleanedTraces << sProcessID << " "; //add process ID
       
   790 				cleanedTraces << sWholeTempLine << "\n"; //add the rest of the line
       
   791 				}
       
   792 
       
   793 				// Get sub test time
       
   794 				string sSubTestEnd = GetStringUntilNextSpace( sRestOfLine );
       
   795 				// Get sub test name
       
   796 				string sSubTestName = GetStringUntilNextSpace( sRestOfLine );
       
   797 				// Get sub test end handle count
       
   798 				string sSubTestEndHandleCount = GetStringUntilNextSpace( sRestOfLine );
       
   799 
       
   800 				// Find subtest
       
   801 				vector<CSubTestData>::iterator viSubTestIter = vProcessList[iProcessIDinList].vSubTests.begin();
       
   802 				while( viSubTestIter != vProcessList[iProcessIDinList].vSubTests.end() )
       
   803 				{
       
   804 					if( viSubTestIter->sSubTestName == sSubTestName && viSubTestIter->sEndTime.empty() )
       
   805 					{
       
   806 						viSubTestIter->sEndTime = sSubTestEnd;
       
   807 						viSubTestIter->bRunning = false;
       
   808 						viSubTestIter->sSubTestEndHandleCount = sSubTestEndHandleCount.c_str();
       
   809 					}
       
   810 					viSubTestIter++;
       
   811 				}
       
   812 			}
       
   813 			else if( ! _stricmp( pCommand, LABEL_THREAD_START ) )
       
   814 			{
       
   815 				if( bCreateCleanedTraces )
       
   816 				{
       
   817 				// add message to cleaned traces file
       
   818 				cleanedTraces << sTime << " "; //add time
       
   819 				cleanedTraces << MAIN_ID << " "; //add MAIN_ID
       
   820 				cleanedTraces << sProcessID << " "; //add process ID
       
   821 				cleanedTraces << sWholeTempLine << "\n"; //add the rest of the line
       
   822 				}
       
   823 
       
   824 				//currently not used
       
   825 			}
       
   826 			else if( ! _stricmp( pCommand, LABEL_THREAD_END ) )
       
   827 			{
       
   828 				if( bCreateCleanedTraces )
       
   829 				{
       
   830 				// add message to cleaned traces file
       
   831 				cleanedTraces << sTime << " "; //add time
       
   832 				cleanedTraces << MAIN_ID << " "; //add MAIN_ID
       
   833 				cleanedTraces << sProcessID << " "; //add process ID
       
   834 				cleanedTraces << sWholeTempLine << "\n"; //add the rest of the line
       
   835 				}
       
   836 
       
   837 				//currently not used
       
   838 			}
       
   839 			else
       
   840 			{
       
   841 				// unknown tag, log it to cleaned file for carbide
       
   842 				if( bCreateCleanedTraces )
       
   843 				{
       
   844 				// add message to cleaned traces file
       
   845 				cleanedTraces << sTime << " "; //add time
       
   846 				cleanedTraces << MAIN_ID << " "; //add MAIN_ID
       
   847 				cleanedTraces << sProcessID << " "; //add process ID
       
   848 				cleanedTraces << sWholeTempLine << "\n"; //add the rest of the line
       
   849 				}
       
   850 			}
       
   851 		}
       
   852 	}
       
   853 
       
   854 	if( bCreateCleanedTraces )
       
   855 	{
       
   856 	// close stream
       
   857 	cleanedTraces.close();
       
   858 	}
       
   859 
       
   860 	// Print all saved data from processes
       
   861 	for( unsigned int i = 0 ; i < vProcessList.size() ; i++ )
       
   862 	{
       
   863 		// Print saved lines
       
   864 		for( unsigned int iDataCounter = 0 ; iDataCounter < vProcessList[i].vData.size() ; iDataCounter++ )
       
   865 		{
       
   866 			m_DataSaver.AddString( vProcessList[i].vData[iDataCounter].c_str() );
       
   867 			m_DataSaver.AddLineToLast();
       
   868 		}
       
   869 
       
   870 		string sTemp;
       
   871 
       
   872 		// Save leaks
       
   873 		vector<string> vLeaks;
       
   874 		vector<string>::iterator viLeaks;
       
   875 		vProcessList[i].GetLeakList( vLeaks );
       
   876 		for ( viLeaks = vLeaks.begin(); viLeaks != vLeaks.end(); viLeaks++ )
       
   877 		{
       
   878 			sTemp.clear();
       
   879 			sTemp.append( LABEL_MEM_LEAK );
       
   880 			sTemp.append( " " );
       
   881 			sTemp.append( *viLeaks );
       
   882 			m_DataSaver.AddString( sTemp.c_str() );
       
   883 			m_DataSaver.AddLineToLast();
       
   884 		}
       
   885 
       
   886 		vector<string>::iterator viHandleIter = vProcessList[i].vHandleLeaks.begin();
       
   887 		// Print handle leaks, if there is data left, there was no process end.
       
   888 		while( viHandleIter != vProcessList[i].vHandleLeaks.end() )
       
   889 		{
       
   890 			sTemp.clear();
       
   891 			sTemp.append( viHandleIter->c_str() );
       
   892 			m_DataSaver.AddString( sTemp.c_str() );
       
   893 			m_DataSaver.AddLineToLast();
       
   894 			viHandleIter++;
       
   895 		}
       
   896 		vector<CSubTestData>::iterator viSubTestIter = vProcessList[i].vSubTests.begin();
       
   897 		// Print sub test data, if there is data left, there was no process end.
       
   898 		while( viSubTestIter != vProcessList[i].vSubTests.end() )
       
   899 		{
       
   900 			// Print sub test start
       
   901 			string sLine( LABEL_TEST_START ); sLine.append( " " );
       
   902 			sLine.append( viSubTestIter->sStartTime ); sLine.append( " " );
       
   903 			sLine.append( viSubTestIter->sSubTestName ); sLine.append( " " );
       
   904 			sLine.append( viSubTestIter->sSubTestStartHandleCount );
       
   905 			m_DataSaver.AddString( sLine.c_str() );
       
   906 			m_DataSaver.AddLineToLast();
       
   907 			sLine.clear();
       
   908 
       
   909 			// DLL Loads.
       
   910 			for( vector<string>::iterator it = viSubTestIter->vData.begin();
       
   911 				it != viSubTestIter->vData.end(); it++ )
       
   912 			{
       
   913 				m_DataSaver.AddString( (*it).c_str() );
       
   914 				m_DataSaver.AddLineToLast();
       
   915 			}
       
   916 
       
   917 			// Subtest leaks.
       
   918 			vector<string> vSubLeaks;
       
   919 			vector<string>::iterator viSubLeaks;
       
   920 			viSubTestIter->GetLeakList( vSubLeaks );
       
   921 			for ( viSubLeaks = vSubLeaks.begin(); viSubLeaks != vSubLeaks.end(); viSubLeaks++ )
       
   922 			{
       
   923 				sLine.append( LABEL_MEM_LEAK );
       
   924 				sLine.append( " " );
       
   925 				sLine.append( *viSubLeaks );
       
   926 				m_DataSaver.AddString( sLine.c_str() );
       
   927 				m_DataSaver.AddLineToLast();
       
   928 				sLine.clear();
       
   929 			}
       
   930 
       
   931 			// Print sub test end
       
   932 			sLine.append( LABEL_TEST_END ); sLine.append( " " );
       
   933 			sLine.append( viSubTestIter->sEndTime ); sLine.append( " " );
       
   934 			sLine.append( viSubTestIter->sSubTestName ); sLine.append( " " );
       
   935 			sLine.append( viSubTestIter->sSubTestEndHandleCount );
       
   936 			m_DataSaver.AddString( sLine.c_str() );
       
   937 			m_DataSaver.AddLineToLast();
       
   938 
       
   939 			viSubTestIter++;
       
   940 		}
       
   941 	}
       
   942 	// Save lines to file.
       
   943 	m_DataSaver.SaveLinesToFile( pOutputFileName, TEXT_DATA );
       
   944 	// Close file.
       
   945 	in.close();
       
   946 	return bRet;
       
   947 }
       
   948 
       
   949 // -----------------------------------------------------------------------------
       
   950 // CATParseTraceFile::GetDataSaver
       
   951 // Gets data saver object.
       
   952 // -----------------------------------------------------------------------------
       
   953 CATDataSaver* CATParseTraceFile::GetDataSaver(void)	
       
   954 {
       
   955 	LOG_LOW_FUNC_ENTRY("CATParseTraceFile::GetDataSaver");
       
   956 	return &m_DataSaver;
       
   957 }
       
   958 
       
   959 
       
   960 // -----------------------------------------------------------------------------
       
   961 // CATBase::GetTimeFromTimeStamp
       
   962 // Gets time from timestamp in microseconds as string
       
   963 // -----------------------------------------------------------------------------
       
   964 string CATParseTraceFile::GetTimeFromTimeStamp( unsigned __int64 iTimeStamp, unsigned __int64 iTimeSpan )
       
   965 {
       
   966 	unsigned __int64 iTime = iTimeStamp + iTimeSpan;
       
   967 	stringstream ss;
       
   968 	ss <<  std::hex << iTime;
       
   969 
       
   970     return ss.str();
       
   971 }
       
   972 
       
   973 //EOF