/*
  Утилиты парсинга
  v. 0.543
*/

#ifndef __PARSERTOOLS_H__
#define __PARSERTOOLS_H__

#include <string>
#include <fstream>
#include <vector>
#include <iostream>
#include <ctime>

using namespace std;

class SrcReader {
        private:
                ifstream iFile;                         
                vector <string> iEndLineComments;
                int iLine;
                bool lastReadedLine; // флаг того, что последний раз из файла читалась строка, а не слово
                string iFileName;               
                bool __ReadWord(string &aStr);
                
        public:
                SrcReader();
                ~SrcReader();
                bool Open(const string &aFileName);
                void AddEndLineComment(const string &aComment);
                bool ReadLine(string &aStr);
                bool ReadWord(string &aStr);
                string ReadWord();      // если слово не удалось считать, генерирует ошибку
                void Error(const string &aMessage);
                int GetInt(const string &aStr);
                bool VerifyWord(const string &aStr, bool aIgnoreCase = false);
                // считывает слово, если оно не совпадает с переданным, выдает ошибку и возвражает false
                // если aIgnoreCase установлен, игнорирует регистр 
                


                bool errorFlag;
                string strSpacesChars;  // символы пустого пространства
                string strDelimsChars;  // символы, считающиеся разделителями языка
                string strWordChars;    // символы, из которых состоят идентификаторы                   
};


// последовательное извлечение подстрок из строки
class StringReader {
        string str;
        int pos;

        StringReader() {};
public:
        string strSpacesChars;  // символы пустого пространства
        string strDelimsChars;  // символы, считающиеся разделителями языка


        StringReader(string aStr): str(aStr), pos(0) {
                strSpacesChars = " \t\x0a\x0d";
                strDelimsChars = ";,{}()";      
        };

        // true - если слово прочитано, иначе - конец строки
        bool ReadWord(string &aStr);
};



class BinReader {
        private:
                ifstream iFile;
        public:
                BinReader();
                ~BinReader();
                bool Open(const string &aFileName);
                void Read(const void *aP, const int aSize);
                unsigned int ReadByte();
                unsigned int ReadWord();
                unsigned int ReadDword();
                string ReadString(const int aLen);              
                bool eof();
                unsigned int size();
};



class BinWriter {
        //private:
                ofstream iFile;

        public:
                BinWriter();
                ~BinWriter();
                bool Open(const string &aFileName);
                void Write(const void *aP, const int aSize);
                void WriteByte(const unsigned int aVal);
                void Write3Byte(const unsigned int aVal);
                void WriteWord(const unsigned int aVal);
                void WriteDword(const unsigned int aVal);
                void WriteString(const string &aStr, const int aLen);

                void Seek(long aPos, ios_base::seekdir aDir) {                  
                        iFile.seekp(aPos, aDir);
                }

};




// возвращает строку с удаленными начальными и конечными символами пустого пространства
string Trim(const string &aStr);

// возвращает количество слов в строке для набора разделителей
int WordCount(const string &aStr, const string &aWordDelims);

// возвращает положение указанного слова в строке или -1, если слова не найдено
int WordPosition(const int aN, const string &aStr, const string &aWordDelims);

// возвращает указанное слово из строки
string ExtractWord(const int aN, const string &aStr, const string &aWordDelims);

// удаляет символы кавычек, в которые заключено слово
// возвращает true, если кавычки были найдены и удалены
bool DeleteApostrof(string &aStr);

// конвертирует строку в целое
inline int StrToInt(const string &aStr) {
        return atoi(aStr.c_str());
}

// проверяет, что строка является представлением целого
bool VerifyInt(const string &aStr);

// конвертирует строку в вещественное число
inline double StrToFloat(const string &aStr) {
        return atof(aStr.c_str());
}

// проверяет, что строка является представлением вещественного числа
bool VerifyFloat(const string &aStr);

// конвертирует hex представления байта (2 символа!) в его значение
// возвращает -1/-2 в случае ошибки 
int HexToByte(const string &aStr);

// конвертирует байт в hex-представление
string ByteToHex(int aVal);


bool VerifyDate(const string &aStr);
// проверяет, что строка является представлением даты в формате "DD.MM.YYYY"
bool VerifyTime(const string &aStr);
// проверяет, что строка является представлением времени в формате "HH:MM:SS"
bool VerifyDateTime(const string &aStr);
// проверяет, что строка является представлением даты и времени в формате "DD.MM.YYYY HH:MM:SS"

tm StrToDate(const string &aStr);
// парсит строку даты
tm StrToTime(const string &aStr);
// парсит строку времени
tm StrToDateTime(const string &aStr);
// парсит строку даты/времени



// для строки даты/времени возвращает кол-во секунд, прошедших с 1.01.1970 0:00:00 GMT

//      перевод строки в верхний регистр (ANSI)

inline string StrUpper(const string &aStr) {
  std::string result;

  result.resize(aStr.length());
  for (size_t i = 0; i < aStr.length(); i++)
    result[i] = toupper(aStr[i]);
  return result;

};


//      перевод строки в верхний регистр (ANSI)
inline string StrLower(const string &aStr) {
  std::string result;

  result.resize(aStr.length());
  for (size_t i = 0; i < aStr.length(); i++)
    result[i] = tolower(aStr[i]);
  return result;
};



#endif

