// export_type_user_id is needed if we have more than one export type
void MDIOAnalyzerResults::GenerateExportFile( const char* file, DisplayBase display_base, U32 /*export_type_user_id*/ )
{
	std::ofstream file_stream( file, std::ios::out );

	U64 trigger_sample = mAnalyzer->GetTriggerSample();
	U32 sample_rate = mAnalyzer->GetSampleRate();

	file_stream << "Time [s],Packet ID,MDIOClause,OP,PHYADDR,REGADDR/DEVTYPE,ADDR/DATA" << std::endl;

	U64 num_packets = GetNumPackets();

	for( U32 packet_id=0; packet_id < num_packets; ++packet_id )
	{

		// get the frames contained in packet with index packet_id
		U64 first_frame_id;
		U64 last_frame_id;
		GetFramesContainedInPacket( packet_id, &first_frame_id, &last_frame_id );
	
		U64 frame_id = first_frame_id;

		// get MDIO_START frame to get the MDIOClause column value
		Frame frame = GetFrame( frame_id );

		char time_str[128];
		AnalyzerHelpers::GetTimeString( frame.mStartingSampleInclusive, trigger_sample, sample_rate, time_str, 128 );

		// Time [s] and Packet ID column
		file_stream << time_str << "," << packet_id << ",";
		
		if( frame.mType == MDIO_C22_START ) 
		{
			file_stream << "22,";
		}
		else if( frame.mType == MDIO_C45_START ) 
		{
			file_stream << "45,";
		}
		else 
		{
			file_stream << ",";
		}

		++frame_id;

		if( frame_id > last_frame_id )
		{
			continue;
		}

		// OP frame
		frame = GetFrame( frame_id );

		switch( frame.mType ) 
		{
			case MDIO_OP_W: 				file_stream << "Write,"; break;
			case MDIO_OP_R: 				file_stream << "Read,"; break;
			case MDIO_C45_OP_ADDR: 			file_stream << "Address,"; break;
			case MDIO_C45_OP_READ_INC_ADDR: file_stream << "Read +Addr,"; break;
			default: 						file_stream << ","; break;
		}

		++frame_id;

		if( frame_id > last_frame_id ) 
		{
			continue;
		}

		// PHYADDR frame
		frame = GetFrame( frame_id );

		if( frame.mType != MDIO_PHYADDR ) 
		{
			file_stream << ",";
		}

		char number_str[128];
		AnalyzerHelpers::GetNumberString( frame.mData1, display_base, 5, number_str, 128 );
		
		file_stream << number_str << ",";
		
		++frame_id;
		
		if( frame_id > last_frame_id ) 
		{
			continue;
		}

		// REGADR or DEVTYPE frame
		frame = GetFrame( frame_id );

		char number_str2[128];
		AnalyzerHelpers::GetNumberString( frame.mData1, display_base, 5, number_str2, 128 );
		
		switch( frame.mType ) 
		{
			case MDIO_C22_REGADDR: 			file_stream << number_str2 << ","; break;
			case MDIO_C45_DEVTYPE_RESERVED:	file_stream << number_str2 << "(Reserved),"; break;
			case MDIO_C45_DEVTYPE_PMD_PMA:	file_stream << number_str2 << "(PMD/PMA),"; break;
			case MDIO_C45_DEVTYPE_WIS: 		file_stream << number_str2 << "(WIS),"; break;
			case MDIO_C45_DEVTYPE_PCS:		file_stream << number_str2 << "(PCS),"; break;
			case MDIO_C45_DEVTYPE_PHY_XS:	file_stream << number_str2 << "(PHY XS),"; break;
			case MDIO_C45_DEVTYPE_DTE_XS:	file_stream << number_str2 << "(DTE XS),"; break;
			case MDIO_C45_DEVTYPE_OTHER:	file_stream << number_str2 << "(Other),"; break;
			default:						file_stream << ","; 
		}
		
		++frame_id;
		if( frame_id > last_frame_id ) 
		{
			continue;
		}
		
		// TA frame
		frame = GetFrame( frame_id );
		
		if( frame.mType != MDIO_TA ) 
		{
			file_stream << ",";
		}
		
		++frame_id;
		if( frame_id > last_frame_id ) 
		{
			continue;
		}
		
		// MDIO_C22_DATA or MDIO_C45_ADDRDATA frame
		frame = GetFrame( frame_id );
		
		if( frame.mType == MDIO_C22_DATA || 
			frame.mType == MDIO_C45_ADDR || 
			frame.mType == MDIO_C45_DATA ) 
		{
			char number_str[128];
			AnalyzerHelpers::GetNumberString( frame.mData1, display_base, 16, number_str, 128 );
			file_stream << number_str;
		}
		else 
		{
			file_stream << ",";
		}
	
		file_stream << std::endl;
	
		// check for cancel and update progress
		if( UpdateExportProgressAndCheckForCancel( packet_id, num_packets ) )
		{
			return;
		}
	
	}

	UpdateExportProgressAndCheckForCancel( num_packets, num_packets );
}
void CanAnalyzerResults::GenerateExportFile( const char* file, DisplayBase display_base, U32 /*export_type_user_id*/ )
{
	//export_type_user_id is only important if we have more than one export type.
	std::stringstream ss;
	void* f = AnalyzerHelpers::StartFile( file );

	U64 trigger_sample = mAnalyzer->GetTriggerSample();
	U32 sample_rate = mAnalyzer->GetSampleRate();

	ss << "Time [s],Packet,Type,Identifier,Control,Data,CRC,ACK" << std::endl;
	U64 num_frames = GetNumFrames();
	U64 num_packets = GetNumPackets();
	for( U32 i=0; i < num_packets; i++ )
	{
		if( i != 0 )
		{
			//below, we "continue" the loop rather than run to the end.  So we need to save to the file here.
			ss << std::endl;

			AnalyzerHelpers::AppendToFile( (U8*)ss.str().c_str(), ss.str().length(), f );
			ss.str( std::string() );


			if( UpdateExportProgressAndCheckForCancel( i, num_packets ) == true )
			{
				AnalyzerHelpers::EndFile( f );
				return;
			}
		}


		U64 first_frame_id;
		U64 last_frame_id;
		GetFramesContainedInPacket( i, &first_frame_id, &last_frame_id );
		Frame frame = GetFrame( first_frame_id );
		
		//static void GetTimeString( U64 sample, U64 trigger_sample, U32 sample_rate_hz, char* result_string, U32 result_string_max_length );
		char time_str[128];
		AnalyzerHelpers::GetTimeString( frame.mStartingSampleInclusive, trigger_sample, sample_rate, time_str, 128 );

		char packet_str[128];
		AnalyzerHelpers::GetNumberString( i, Decimal, 0, packet_str, 128 );

		if( frame.HasFlag( REMOTE_FRAME ) == false )
			ss << time_str << "," << packet_str << ",DATA";
		else
			ss << time_str << "," << packet_str << ",REMOTE";
		
		U64 frame_id = first_frame_id;

		frame = GetFrame( frame_id );

		char number_str[128];

		if( frame.mType == IdentifierField )
		{
			AnalyzerHelpers::GetNumberString( frame.mData1, display_base, 12, number_str, 128);
			ss << "," << number_str;
			++frame_id;
		}
		else if( frame.mType == IdentifierFieldEx )
		{
			AnalyzerHelpers::GetNumberString( frame.mData1, display_base, 32, number_str, 128 );
			ss << "," << number_str;
			++frame_id;
		}
		else
		{
			ss << ",";
		}

		if( frame_id > last_frame_id )
			continue;

		frame = GetFrame( frame_id );
		if( frame.mType == ControlField )
		{
			AnalyzerHelpers::GetNumberString( frame.mData1, display_base, 4, number_str, 128);
			ss << "," << number_str;
			++frame_id;
		}
		else
		{
			ss << ",";
		}
		ss << ",";
		if( frame_id > last_frame_id )
			continue;

		for( ; ; )
		{
			frame = GetFrame( frame_id );
			if( frame.mType != DataField )
				break;

			AnalyzerHelpers::GetNumberString( frame.mData1, display_base, 8, number_str, 128 );
			ss << number_str;
			if( frame_id == last_frame_id )
				break;

			++frame_id;
			if( GetFrame( frame_id ).mType == DataField )
				ss << " ";
		}

		if( frame_id > last_frame_id )
			continue;

		frame = GetFrame( frame_id );
		if( frame.mType == CrcField )
		{
			AnalyzerHelpers::GetNumberString( frame.mData1, display_base, 15, number_str, 128);
			ss << "," << number_str;
			++frame_id;
		}else
		{
			ss << ",";
		}
		if( frame_id > last_frame_id )
			continue;

		frame = GetFrame( frame_id );
		if( frame.mType == AckField )
		{
			if( bool( frame.mData1 ) == true )
				ss << "," << "ACK";
			else
				ss << "," << "NAK";

			++frame_id;
		}else
		{
			ss << ",";
		}
	}

	UpdateExportProgressAndCheckForCancel( num_frames, num_frames );
	AnalyzerHelpers::EndFile( f );
}