///////////////////////////////////////////////////////////////////////
///  Test.cpp   -  Demonstrate HiResTimer operations                ///
///  ver 1.0                                                        ///
///                                                                 ///
///  Language:     Visual C#                                        ///
///  Platform:     Dell Dimension 9150, Windows XP Pro, SP2         ///
///  Application:  CSE775 Example                                   ///
///  Author:       Jim Fawcett, CST 2-187, Syracuse Univ.           ///
///                (315) 443-3948, jfawcett@twcny.rr.com            ///
///////////////////////////////////////////////////////////////////////

#include <map>
#include <string>
#include <iostream>
#include <fstream>
#include "HiResTimer.h"

namespace HRTimer
{
  class OpTimer
  {
    std::map<std::string,int> table;
    __int64 totalTime;
    __int64 openTime;
    __int64 parseTime;
    bool verbose;

  public:
    //----< constructor >----------------------------------------------

    OpTimer() :totalTime(0), openTime(0), parseTime(0), verbose(false)
    {
    }
    //----< function never called, used to test parser >---------------

    bool tryCommas(int first,bool second, double third)
    {
      if(first*third != 0)
        return false;
      return second;
    }
    //----< display contents of parse table >--------------------------

    void showTable()
    {
      std::map<std::string,int>::iterator iter;
      for(iter=table.begin(); iter!=table.end(); ++iter)
      {
        std::cout << "\n  " << iter->second;
        std::cout << "\t" << iter->first;
      }
    }
    //----< verbose property - display parsing details? >--------------

    bool& Verbose(bool isVerbose = false)
    {
      return verbose;
    }
//
    //----< extract identifier from token string >---------------------
    //
    //  - Eliminates {}[]{};.
    //  - extracts words from comma separated list, e.g.,
    //      int first,bool second, double third
    //
    std::string extractIdent(std::string& compositeToken)
    {
      std::string temp = "";
      try
      {
        size_t len;
        len = compositeToken.find(")");
        if(len < compositeToken.size())
          compositeToken = compositeToken.erase(len,compositeToken.size()-len);
        len = compositeToken.find("(");
        if(len < compositeToken.size())
          compositeToken = compositeToken.erase(0,len+1);
        len = compositeToken.find("}");
        if(len < compositeToken.size())
          compositeToken = compositeToken.erase(len,compositeToken.size()-len);
        len = compositeToken.find("{");
        if(len < compositeToken.size())
          compositeToken = compositeToken.erase(0,len+1);
        len = compositeToken.find("]");
        if(len < compositeToken.size())
          compositeToken = compositeToken.erase(len,compositeToken.size()-len);
        len = compositeToken.find_last_of("[");
        if(len < compositeToken.size())
          compositeToken = compositeToken.erase(0,len+1);
        len = compositeToken.find_last_of(".");
        if(len < compositeToken.size())
          compositeToken = compositeToken.erase(0,len+1);
        len = compositeToken.find_last_of(";");
        if(len < compositeToken.size())
          compositeToken = compositeToken.erase(len,1);
        len = compositeToken.find(",");
        if(len < compositeToken.size())
        {
          temp = compositeToken.erase(len,compositeToken.size()-len);
          compositeToken = compositeToken.erase(0,len+1);
        }
        else
        {
          temp = compositeToken;
          compositeToken = "";
        }
      }
      catch(std::exception e)
      {
        std::cout << "\n\n--- " << e.what() << " ---\n\n";
      }
      return temp;
    }
    //
    //----< parse file into identifiers and store in Maptable >-------

    void ParseFile(const std::string& fileName)
    {
      HiResTimer total;
      HiResTimer open;
      HiResTimer parse;

      try
      {
        total.Start();
        open.Start();
        std::ifstream fs(fileName.c_str());
        if(!fs.good())
          throw std::exception("can't open file");
        open.Stop();
        openTime = open.ElapsedMicroseconds();

        parse.Start();
        size_t size = 0;
        std::string token;
        while(fs.good())
        {
          fs >> token;
          if(token == "\n" || token.size() == 0)
            continue;
          if(Verbose())
            std::cout << "\n    " << token;
          std::string tok, compositeToken = token;
          while(compositeToken != "")
          {
            tok = extractIdent(compositeToken);
            if(tok == "")
              continue;
            if(Verbose())
              std::cout << "\n      " << tok;
            if(table.find(tok) != table.end())
              table[tok] = 1 + (int)table[tok];
            else
            {
              table[tok] = 1;
              size += tok.size();
            }
          }
        }
        parse.Stop();
        parseTime = parse.ElapsedMicroseconds();
        total.Stop();
        totalTime = total.ElapsedMicroseconds();

//
        std::cout << "\n   Open time: " << openTime << " microsec"; 
        std::cout << "\n  Parse time: " << parseTime << " microsec"; 
        std::cout << "\n  total time: " << totalTime << " microsec"; 
        std::cout << "\n    Map size: " << table.size() << " tokens";
      }
      catch(...)
      {
        std::cout << "\n  Could not open file \"" << fileName << "\"\n\n";
      }
      std::cout << std::endl;
    }
    //----< lookup a word in Maptable >-------------------------------

    bool MapLookUp(const std::string& word)
    {
      return (table.find(word) != table.end());
    }
  };
}
//----< run timing tests for Project #1 >--------------------------

int main(int argc, char* argv[])
{
  std::cout << "\n  Time Parsing Operations ";
  std::cout << "\n =========================\n";

  HRTimer::OpTimer ot;
  ot.Verbose() = false;
  if(argc < 2)
  {
    std::cout << "\n  please enter name of test file on command line\n\n";
    return 1;
  }
  else
    std::cout << "\n  Processing file: " << argv[1] << std::endl;
  std::string fileName = argv[1];
  ot.ParseFile(fileName);

  HRTimer::HiResTimer hrt;
  hrt.Start();
  int N = 1000;
  for(int i=0; i<N; ++i)
    ot.MapLookUp("class");
  hrt.Stop();
  __int64 lookUpTime = hrt.ElapsedMicroseconds();
  std::cout << "\n   " << N << " lookups took " << lookUpTime << " microseconds";
  std::cout << "\n\n";
  ot.showTable();
  std::cout << "\n\n";
  return 0;
}

C:\SU\CSE775\CODE\HIREST~1
>Test Test.cpp 

  Time Parsing Operations 
 =========================

  Processing file: Test.cpp

   Open time: 136 microsec
  Parse time: 4355 microsec
  total time: 4495 microsec
    Map size: 207 tokens

   1000 lookups took 1468 microseconds


  4	!=
  26	"
  5	""
  1	"("
  1	"\"\n\n"
  13	"\n
  1	"\n"
  2	"\n\n"
  1	"\n\n---
  1	"\t"
  1	"can't
  1	"class"
  1	#1
  5	#include
  1	+
  1	++i
  1	++iter
  1	+=
  4	-
  1	---\n\n"
  8	//
  8	//----<
  16	///
  2	///////////////////////////////////////////////////////////////////////
  13	0
  5	1
  1	1000
  1	2
  1	2-187
  1	315
  1	443-3948
  1	9150
  10	<
  40	<<
  1	<fstream>
  1	<iostream>
  1	<map>
  1	<string>
  35	=
  3	==
  1	=========================\n"
  1	>-------
  1	>--------------
  1	>---------------
  1	>---------------------
  2	>--------------------------
  1	>-------------------------------
  1	>----------------------------------------------
  1	>>
  1	Application:
  1	Author:
  1	C#
  1	CSE775
  1	CST
  1	Could
  1	Dell
  1	Demonstrate
  1	Dimension
  1	Eliminates
  1	Example
  1	Fawcett
  1	HRTimer
  1	HRTimer::HiResTimer
  1	HRTimer::OpTimer
  4	HiResTimer
  1	Jim
  1	Language:
  1	Map
  2	Maptable
  2	N
  1	OpTimer
  1	Open
  1	Operations
  1	Parse
  1	Parsing
  1	Platform:
  1	Pro
  1	Processing
  1	Project
  1	SP2
  1	Syracuse
  1	Time
  2	Verbose(
  1	Visual
  1	Windows
  1	XP
  1	\""
  4	__int64
  1	a
  1	and
  2	argc
  1	begin(
  4	bool
  1	bool&
  1	c_str(
  1	called
  1	char*
  1	class
  1	com
  1	comma
  1	command
  15	compositeToken
  2	const
  1	constructor
  1	contents
  2	continue
  1	cpp
  1	details?
  2	display
  2	double
  1	e
  3	else
  1	enter
  1	extract
  1	extracts
  4	false
  3	file
  1	file"
  1	file:
  4	fileName
  1	find(tok
  1	find(word
  2	first
  1	first*third
  1	for
  2	from
  1	fs
  1	function
  2	good(
  1	h"
  1	hrt
  1	i<N
  1	i=0
  1	identifier
  1	identifiers
  2	in
  7	int
  1	into
  1	isVerbose
  1	iter
  1	iter->first
  1	iter->second
  20	len
  1	line\n\n"
  1	list
  2	lookUpTime
  1	lookup
  1	lookups
  3	microsec"
  1	microseconds"
  1	name
  1	namespace
  1	never
  1	not
  2	of
  1	on
  3	open
  3	openTime
  1	operations
  1	ot
  3	parse
  3	parseTime
  1	parser
  1	parsing
  1	please
  1	property
  1	public:
  7	return
  1	run
  3	second
  1	separated
  2	size
  4	size(
  1	size:
  2	size_t
  18	std::cout
  2	std::endl
  1	std::exception
  1	std::ifstream
  2	std::map<std::string
  5	std::string
  3	std::string&
  1	store
  1	string
  2	table
  4	temp
  2	test
  1	tests
  2	third
  1	throw
  3	time:
  1	timing
  1	to
  6	tok
  6	token
  1	tokens"
  1	took
  2	total
  3	totalTime
  2	try
  1	used
  1	ver
  3	verbose
  2	void
  2	word
  1	words
  1	||

