// This may look like C code, but it is really -*- C++ -*-
// 
// <copyright> 
//  
//  Copyright (c) 1995
//  Institute for Information Processing and Computer Supported New Media (IICM), 
//  Graz University of Technology, Austria. 
//  
// </copyright> 
// 
// 
// <file> 
// 
// Name:        http.h
// 
// Purpose:     
// 
// Created:     19 Feb 96   Joerg Faschingbauer
// 
// Modified:    
// 
// Description: 
// 
// $Id: http.h,v 1.6 1996/07/24 06:25:09 jfasch Exp $
// 
// $Log: http.h,v $
// Revision 1.6  1996/07/24 06:25:09  jfasch
// added HTTP::Date class
//
// Revision 1.5  1996/04/12 12:22:58  jfasch
// *** empty log message ***
//
// Revision 1.4  1996/04/09 15:24:07  tvollmer
// *** empty log message ***
//
// Revision 1.3  1996/03/07 11:21:48  jfasch
// due to a compile run on our IBM, which is always fatal
//
// Revision 1.2  1996/02/22 17:13:21  jfasch
// changed from HTTPRules to HTTP
//
// Revision 1.1  1996/02/19 15:13:18  jfasch
// Initial revision
//
// 
// </file> 
#ifndef hg_dc_utils_http_h
#define hg_dc_utils_http_h

#include <ctype.h>
#include <sys/types.h>
#include <hyperg/utils/str.h>
#include <time.h>

class RStringField ;

class HTTP {
public:
   static bool isCHAR (char) ;
   static bool isUPALPHA (char) ;
   static bool isLOALPHA (char) ;
   static bool isALPHA (char) ;
   static bool isDIGIT (char) ;
   static bool isCTL (char) ;
   static bool isCR (char) ;
   static bool isLF (char) ;
   static bool isSP (char) ;
   static bool isHT (char) ;
   static bool isSPorHT (char) ;
   static bool isDQ (char) ;
   static bool isHEX (char) ;

   static bool isTokenChar (char) ;
   static bool isTSpecial (char) ;

   // converts utc time_t to RFC 1123
   static RString httpDate(time_t);

   // comverts from RFC 1123. returns number of chars comsumed, 0 on error.
   static int rfc1123 (const char*, int, time_t&) ;

   static int crlf (const char*, int) ;
   static int lws (const char*, int) ;
   static int token (const char*, int) ;
   static int qdtext (const char*, int) ;
   static int quoted_string (const char*, int) ;
   static int word (const char*, int) ;

   // this is <min>#<max>element, according to the Augmented
   // BNF. remembers the elements in the RStringField, if passed and
   // non-nil.
   static int list (int (*element)(const char*, int), 
                    int min, int max, const char*, int, RStringField* =nil) ;
   static int list (int (*element)(const char*, int), 
                    int min, int max, const char*, int, RStringField&) ;

public:
   class Date {
   public:
      enum WkDay { Mon, Tue, Wed, Thu, Fri, Sat, Sun } ;
      enum Month { Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec } ;

      static int wkday (const char*, int) ;
      static int date1 (const char*, int) ;
      static int time (const char*, int) ;
      static int month (const char*, int) ;
   } ;
} ;

inline bool HTTP :: isCHAR (char c) {
   return isascii (c) ;
}
inline bool HTTP :: isUPALPHA (char c) {
   return isupper (c) ;
}
inline bool HTTP :: isLOALPHA (char c) {
   return islower (c) ;
}
inline bool HTTP :: isALPHA (char c) {
   return isalpha (c) ;
}
inline bool HTTP :: isDIGIT (char c) {
   return isdigit (c) ;
}
inline bool HTTP :: isCTL (char c) {
   return iscntrl (c) ;
}
inline bool HTTP :: isCR (char c) {
   return c == '\r' ;
}
inline bool HTTP :: isLF (char c) {
   return c == '\n' ;
}
inline bool HTTP :: isSP (char c) {
   return c == ' ' ;
}
inline bool HTTP :: isHT (char c) {
   return c == '\t' ;
}
inline bool HTTP :: isSPorHT (char c) {
   return isSP(c) || isHT(c) ;
}
inline bool HTTP :: isDQ (char c) {
   return c == '\"' ;
}
inline bool HTTP :: isHEX (char c) {
   return isDIGIT (c) ||
      c == 'a' || c == 'b' || c == 'c' || c == 'd' || c == 'e' || c == 'f' || 
      c == 'A' || c == 'B' || c == 'C' || c == 'D' || c == 'E' || c == 'F' ;
}
inline bool HTTP :: isTSpecial (char c) {
   return c == '(' || c == ')' || c == '<' || c == '>' || c == '@' ||
          c == ',' || c == ';' || c == ':' || c == '\\' || isDQ(c) ||
          c == '/' || c == '[' || c == ']' || c == '?' || c == '=' ||
          c == '{' || c == '}' || isSP(c) || isHT(c) ;
}
inline bool HTTP :: isTokenChar (char c) {
   return isCHAR (c) &&  ! (isCTL (c) || isTSpecial (c)) ;
}

inline int HTTP :: list (int (*elem)(const char*, int), 
                         int min, int max, const char* s, int l, RStringField& f) {
   return list (elem, min, max, s, l, &f) ;
}

#endif
