//
// StarEncode.cpp 
//
// by Mark Nelson - February, 2002
//
// This console based C++ program reads a text file from
// standard input and star encodes it, writing the result
// to standard output.
// 
// In order to perform this encoding, it expects to be
// called with the name of a dictionary file as its only
// command line argument.
//
// The star encoding created by this program is described in
// the accompanying article. Note that this program properly 
// encodes files using dictionaries created using either the 
// A format or the B format.
//
// Decoding the encoded file can be done with StarDecode.cpp.
//
// This code compiles with Visual C++ 6 SP3 and g++ 2.96:
// 
// cl /GX StarEncode.cpp
//  - or -
//  g++ -o StarEncode StarEncode.cpp
//

#pragma warning( disable : 4786 )
#include <iostream>
#include <fstream>
#include <map>
#include <string>
using namespace std;

int main(int argc, char* argv[])
{
    if ( argc < 2 )
    {
        cerr << "Usage: star0 dict-file\n\n"
	     << "encodes stdin to stdout using the dictionary\n";
	exit( 0 );
    }
    //
    // The program has two distinct segments. The first, following
    // immediately after these comments, reads the dictionary and
    // creates an encoding table.
    //
    ifstream infile( *++argv, ios::in | ios::binary );
    map< string, string > codes;
    int pacifier = 0;
    cerr << "Reading codes..." << endl;
    while ( infile )
    {
        string word;
        string star_code;
        int count;
        infile >> word >> star_code >> count;
        codes[ word ] = star_code;
        cerr << pacifier++ << '\r';
    }
    cerr << "\n";
    //
    // The second segment of the program, starting here, reads
    // tokens from standard input and attempts to locate them in
    // the dictionary file. If succesful, it outputs the encoded
    // token to stdout, otherwise it sends the plain text. While
    // all this is occuring, it will simply copy any punctuation
    // or white space directly to stdout.
    //
    cin.unsetf( ios::skipws );
    pacifier = 0;
    string word;
    while ( cin )
    {
        char c;
        cin >> c;
	if ( !cin )
	    break;
        if ( isalpha( c ) || c == '\'' || c == '*' )
            word += c;
        else
        {
            if ( word.size() > 0 )
            {
                map<string,string>::iterator ii = codes.find(word);
                if ( ii == codes.end() )
                    cout << word;
                else
                    cout << (string) codes[ word ];
                word = "";
                cerr << pacifier++ << '\r';
            }
            cout << c;
        }
    }
    if ( word.size() > 0 )
    {
        map<string,string>::iterator ii = codes.find(word);
        if ( ii == codes.end() )
            cout << word;
        else
            cout << (string) codes[ word ];
    }
    cerr << "\n";
    return 0;
}


