/***************************************************************************
 $RCSfile: parser.h,v $
                             -------------------
    cvs         : $Id: parser.h,v 1.7 2002/09/20 09:01:24 cstim Exp $
    begin       : Tue Aug 28 2001
    copyright   : (C) 2001 by Martin Preuss
    email       : martin@aquamaniac.de
*/

/***************************************************************************
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Lesser General Public            *
 *   License as published by the Free Software Foundation; either          *
 *   version 2.1 of the License, or (at your option) any later version.    *
 *                                                                         *
 *   This library is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
 *   Lesser General Public License for more details.                       *
 *                                                                         *
 *   You should have received a copy of the GNU Lesser General Public      *
 *   License along with this library; if not, write to the Free Software   *
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
 *   MA  02111-1307  USA                                                   *
 *                                                                         *
 ***************************************************************************/

/*
 */


#ifndef C_PARSER_H
#define C_PARSER_H


#define PARSER_FLAGS_SKIP_BLANKS            0x0001
#define PARSER_FLAGS_CUT_BLANKS             0x0002
#define PARSER_FLAGS_REMOVE_QUOTATION_MARKS 0x0004



#include <string>
#include <list>

#include <openhbci/error.h>

namespace HBCI {
  class Stream;
}

namespace HBCI {

/**
 * @short Internal helper class used by Config
 * @author Martin Preuss<martin@aquamaniac.de>
 */
class DLLIMPORT parser {
private:

    static DLLIMPORT int _fromhex(char c);
    static DLLIMPORT void _tohex(string &dst, char c);
    static DLLIMPORT bool _checkChar(char c);
    static DLLIMPORT bool _cmpSegment(const string &w, unsigned int &wpos,
                                      const string &p, unsigned int &ppos,
                                      bool sensecase,
                                      unsigned int &matches);
    static DLLIMPORT bool _findSegment(const string &w, unsigned int &wpos,
                                       const string &p, unsigned int &ppos,
                                       bool sensecase,
                                       unsigned int &matches);

public:
    parser();
    ~parser();

    /**
     * Cuts off a string from another one.
     * @author Martin Preuss<martin@aquamaniac.de>
     * @return error code (ERROR_NONE if none)
     * @param src source string
     * @param dst target string to receive the new word. On error this string
     * holds the word read until the error occurred.
     * @param delimiters all the characters in this string mark the end
     * of the word to cut out
     * @param nestchars holds a list of character pairs which lead to nesting.
     * the first character marks the beginning of the nesting, the second
     * marks the end (e.g. "()")
     * @param pos the pos at which to start examining the source string
     * When this method returns this pointer is advanced. On error, this
     * pointer shows the position of the error.
     * @param maxsize FIXME: add docs here
     */
    static DLLIMPORT Error getString(string src,
                                         string &dst,
                                         string delimiters,
                                         string nestchars,
                                         unsigned int &pos,
                                         unsigned int maxsize=1024);

    /**
     * Does the same as the other method with that name does, but
     * it reads its data from a stream rather than from a string.
     * @author Martin Preuss<martin@aquamaniac.de>
     * @return error code (ERROR_NONE if none)
     * @param st pointer to the stream to read from
     * @param dst target string to receive the new word. On error this string
     * holds the word read until the error occurred.
     * @param delimiters all the characters in this string mark the end
     * of the word to cut out
     * @param nestchars holds a list of character pairs which lead to nesting.
     * the first character marks the beginning of the nesting, the second
     * marks the end (e.g. "()")
     * @param maxsize FIXME: add docs here
     */
    static DLLIMPORT Error getString(Stream *st,
                                         string &dst,
                                         string delimiters,
                                         string nestchars,
                                         unsigned int maxsize=1024);

    /**
     * Processes a given string according to the given mode.
     * @author Martin Preuss<martin@aquamaniac.de>
     * @return true if ok, false on error
     * @param s reference to a string to process
     * @param mode the mode of operation (OR all the flags you need)
     * - PARSER_FLAGS_SKIP_BLANKS: Skips blanks at the beginning of words
     * - PARSER_FLAGS_CUT_BLANKS: Skips blanks at the end of words
     * - PARSER_FLAGS_ALLOW_EMPTY_VALUES: Guess what ;-)
     * - PARSER_FLAGS_REMOVE_QUOTATION_MARKS: removes leading/trailing
     *   quotation marks
     */
    static DLLIMPORT Error processString(string &s, unsigned int mode);

    /**
     * This method escapes special characters the way an HTTP server
     * expects them. That means that all special characters get translated
     * into a sequence of "%XX", where the "XX" is a two digit hex number
     * representing the ASCII code of the special character.
     * @author Martin Preuss<martin@aquamaniac.de>
     * @return error code (ERROR_NONE if none)
     * @param src reference to a string to convert (result will be stored
     * here, too!)
     * @param pos position in the string to start at.
     */
    static DLLIMPORT Error escapeHTTP(string &src, unsigned int &pos);

    /**
     * This method unescapes all occurences of "%XX" sequences.
     * @author Martin Preuss<martin@aquamaniac.de>
     * @return error code (ERROR_NONE if none)
     * @param src reference to a string to convert (result will be stored
     * here, too!)
     * @param pos position in the string to start at.
     */
    static DLLIMPORT Error unescapeHTTP(string &src, unsigned int &pos);

    /**
     * Compares a word against a pattern.
     * The pattern may include wildcards such as '?' or '*'.
     * If the word matches the pattern the number of direct matches is
     * returned. Please note that a return value of zero indicates a
     * match, too ! This is the case for patterns like "*".
     * The counter for direct matches is incremented whenever one character
     * in the pattern is EQUAL to a character in the word.
     * A return value of -1 indicates that the word does not match the pattern.
     * @author Martin Preuss<martin@aquamaniac.de>
     * @return number of direct matches (-1 if pattern doesnt match the word)
     * @param w the word to compare
     * @param p the pattern to compare against
     * @param sensecase if true the case matters
     */
    static DLLIMPORT int cmpPattern(const string &w,
                                    const string &p,
                                    bool sensecase);

    /**
     * Parses a comma separated list of ranges and returns them.
     * When this method successfully returns the list contains a number
     * of string values specifying a startpoint and an endpoint.
     * An empty value means "not stated".
     * @return error object
     * @param range string to examine
     * @param ranges reference to a list of string values (see above)
     */
    static DLLIMPORT Error parseRanges(string range,
                                           list<string> &ranges);

    /**
     * Converts a number to a string.
     * @param number number to convert
     * @param fillWithZero if true then the number will be filled with zeros
     * on the left
     * @param length length the resulting string should have
     */
    static DLLIMPORT string num2string(int number,
                                       bool fillWithZero=false,
                                       int length=0);
};



} /* namespace HBCI */
#endif



