Logo Search packages:      
Sourcecode: sofia-sip version File versions

bnf.h

Go to the documentation of this file.
/*
 * This file is part of the Sofia-SIP package
 *
 * Copyright (C) 2005 Nokia Corporation.
 *
 * Contact: Pekka Pessi <pekka.pessi@nokia.com>
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */

#ifndef BNF_H  /** Defined when <sofia-sip/bnf.h> has been included. */
#define BNF_H

/**@file sofia-sip/bnf.h
 *
 * Parsing macros and prototypes for HTTP-like protocols.
 *
 * @author Pekka Pessi <Pekka.Pessi@nokia.com>
 *
 * @date Created: Tue Jun 06 10:59:34 2000 ppessi
 *
 */

#include <sofia-sip/su_types.h>

#include <string.h>

SOFIA_BEGIN_DECLS

/* Parsing tokens */
/** Control characters. */
00046 #define CTL   "\001\002\003\004\005\006\007" \
    "\010\011\012\013\014\015\016\017" \
    "\020\021\022\023\024\025\026\027" \
    "\030\031\032\033\034\035\036\037" "\177" "\0"
/** Space */
00051 #define SP      " "
/** Horizontal tab */
00053 #define HT      "\t"
/** Carriage return */
00055 #define CR      "\r"
/** Line feed */
00057 #define LF      "\n"
/** Line-ending characters */
00059 #define CRLF     CR LF
/** Whitespace */
00061 #define WS       SP HT
/** Linear whitespace */
00063 #define LWS      SP HT CR LF
/** Lower-case alphabetic characters */
00065 #define LOALPHA "abcdefghijklmnopqrstuvwxyz"
/** Upper-case alphabetic characters */
00067 #define UPALPHA "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
/** Alphabetic characters */
00069 #define ALPHA    LOALPHA UPALPHA
/** Digits */
00071 #define DIGIT   "0123456789"
/** RTSP safe characters */
00073 #define SAFE    "$-_." /* RTSP stuff */
#define ALPHANUM DIGIT ALPHA
#define HEX      DIGIT "ABCDEF" "abcdef"

/** SIP token characters.
 * @note $|&^# were token chars in RFC 2543, but no more in RFC 3261.
 */
00080 #define SIP_TOKEN  ALPHANUM "-.!%*_+`'~"
/** SIP separator characters */
00082 #define SIP_SEPARATOR  "()<>@,;:\\\"/[]?={}" SP HT

/** SIP Word characters (that are not token characters) */
00085 #define SIP_WORD "()<>:\\\"/[]?{}"

/** Skip whitespace (SP HT) */
00088 #define skip_ws(ss) (*(ss) += span_ws(*(ss)))

/** Skip linear whitespace (SP HT CR LF) */
00091 #define skip_lws(ss) (*(ss) += span_lws(*(ss)))

/** Skip [a-zA-Z] */
00094 #define skip_alpha(ss) (*(ss) += span_alpha(*(ss)))

/** Skip digits */
00097 #define skip_digit(ss) (*(ss) += span_digit(*(ss)))

/** Skip characters belonging to an RTSP token. */
00100 #define skip_alpha_digit_safe(ss) (*(ss) += span_alpha_digit_safe(*(ss)))

/** Skip characters belonging to a SIP token. */
00103 #define skip_token(ss)  (*(ss) += span_token(*(ss)))

/** Skip characters belonging to a SIP parameter value. */
00106 #define skip_param(ss) (*(ss) += span_param(*(ss)))

/** Skip characters belonging to a SIP word. */
00109 #define skip_word(ss) (*(ss) += span_word(*(ss)))

/** Test if @c is CR or LF */
00112 #define IS_CRLF(c)       ((c) == '\r' || (c) == '\n')
/** Test if @c is linear whitespace */
00114 #define IS_LWS(c)        ((c) == ' ' || (c) == '\t' || (c) == '\r' || (c) == '\n')
/*#define IS_LWS(c)      ((_bnf_table[(unsigned char)(c)] & bnf_lws))*/
/** Test if @c is normal whitespace */
00117 #define IS_WS(c)         ((c) == ' ' || (c) == '\t')
/** Test if @c is not whitespace (and not NUL). */
00119 #define IS_NON_WS(c)     (c && !IS_WS(c))
/*#define IS_NON_WS(c)     (c && !(_bnf_table[(unsigned char)c] & bnf_ws))*/
/** Test if @c is not linear whitespace (and not NUL). */
00122 #define IS_NON_LWS(c)    (c && !IS_LWS(c))
/*#define IS_NON_LWS(c)    (c && !(_bnf_table[(unsigned char)c] & bnf_lws))*/
/** Test if @c is a digit. */
00125 #define IS_DIGIT(c)      ((c) >= '0' && (c) <= '9')
/** Test if @c is alphabetic. */
00127 #define IS_ALPHA(c)      (c && ((_bnf_table[(unsigned char)c] & bnf_alpha)))
/** Test if @c is alphanumeric. */
00129 #define IS_ALPHANUM(c)   (c && (IS_DIGIT(c) || IS_ALPHA(c)))
/** Test if @c is URL-unreserved. */
00131 #define IS_UNRESERVED(c) ((_bnf_table[(unsigned char)c] & bnf_unreserved))
/** Test if @c is URL-reserved. */
00133 #define IS_RESERVED(c)   (c && !(_bnf_table[(unsigned char)c] & bnf_unreserved))
/** Test if @c is valid in tokens. */
00135 #define IS_TOKEN(c)      ((_bnf_table[(unsigned char)c] & bnf_token))
/** Test if @c is valid for SIP parameter value. */
00137 #define IS_PARAM(c)      ((_bnf_table[(unsigned char)c] & (bnf_token|bnf_param)))
/** Test if @c is a hex digit. */
00139 #define IS_HEX(c)        (((c) >= '0' && (c) <= '9') || ((c) >= 'A' && (c) <= 'F') || ((c) >= 'a' && (c) <= 'f'))
/** Test if @c is a linear whitespace or valid in tokens. */
00141 #define IS_TOKENLWS(c)   ((_bnf_table[(unsigned char)c] & (bnf_token|bn_lws)))

enum {
00144   bnf_ws = 1,                             /**< Whitespace character  */
00145   bnf_crlf = 2,                           /**< Line end character */
00146   bnf_lws = 3,                            /**< Linear whitespace */
00147   bnf_alpha = 4,                    /**< Alphabetic */
00148   bnf_safe = 8,                           /**< RTSP safe */
00149   bnf_mark = 16,                    /**< URL mark */
00150   bnf_unreserved = bnf_alpha | bnf_mark,  /**< URL unreserved */
00151   bnf_separator = 32,                     /**< SIP separator */
  /** SIP token, not alphabetic (0123456789-.!%*_+`'~) */
00153   bnf_token0 = 64 | bnf_safe,
00154   bnf_token = bnf_token0 | bnf_alpha,           /**< SIP token */
00155   bnf_param0 = 128,                       /**< SIP parameter, not token */
00156   bnf_param = bnf_token | bnf_param0 /**< SIP/HTTP parameter */
};

/** Table for determining class of a character. */
00160 SOFIAPUBVAR unsigned char const _bnf_table[256];

/** Get number of characters before CRLF */
00163 #define span_non_crlf(s) strcspn(s, CR LF)

/** Get number of characters before whitespace */
00166 #define span_non_ws(s) strcspn(s, WS)

/** Get number of whitespace characters */
00169 #define span_ws(s) strspn(s, WS)

/** Get number of characters before linear whitespace */
00172 #define span_non_lws(s) strcspn(s, LWS)

/** Calculate span of a linear whitespace.
 * LWS = [*WSP CRLF] 1*WSP
 */
00177 su_inline isize_t span_lws(char const *s)
{
  char const *e = s;
  int i = 0;
  e += strspn(s, WS);
  if (e[i] == '\r') i++;
  if (e[i] == '\n') i++;
  if (IS_WS(e[i]))
    e += i + strspn(e + i, WS);
  return e - s;
}

/** Calculate span of a token or linear whitespace characters.  */
00190 su_inline isize_t span_token_lws(char const *s)
{
  char const *e = s;
  while (_bnf_table[(unsigned char)(*e)] & (bnf_token | bnf_lws))
    e++;
  return e - s;
}

/** Calculate span of a token characters.  */
00199 su_inline isize_t span_token(char const *s)
{
  char const *e = s;
  while (_bnf_table[(unsigned char)(*e)] & bnf_token)
    e++;
  return e - s;
}

/** Calculate span of a alphabetic characters.  */
00208 su_inline isize_t span_alpha(char const *s)
{
  char const *e = s;
  while (_bnf_table[(unsigned char)(*e)] & bnf_alpha)
    e++;
  return e - s;
}

/** Calculate span of a digits.  */
00217 su_inline isize_t span_digit(char const *s)
{
  char const *e = s;
  while (*e >= '0' && *e <= '9')
    e++;
  return e - s;
}

/** Calculate span of a hex.  */
00226 su_inline isize_t span_hexdigit(char const *s)
{
  char const *e = s;
  while (IS_HEX(*e))
    e++;
  return e - s;
}

/** Calculate span of characters belonging to an RTSP token */
00235 su_inline isize_t span_alpha_digit_safe(char const *s)
{
  char const *e = s;
  while (_bnf_table[(unsigned char)(*e)] & (bnf_alpha | bnf_safe))
    e++;
  return e - s;
}

/** Calculate span of a characters valid in parameters.  */
00244 su_inline isize_t span_param(char const *s)
{
  char const *e = s;
  while (IS_PARAM(*e))
    e++;
  return e - s;
}

/** Calculate span of a SIP word.  */
00253 su_inline isize_t span_word(char const *s)
{
  char const *e = s;
  while (*e && (IS_TOKEN(*e) || strchr(SIP_WORD, *e)))
    e++;
  return e - s;
}

/** Calculate span of a unreserved characters.  */
00262 su_inline isize_t span_unreserved(char const *s)
{
  char const *e = s;
  while (IS_UNRESERVED(*e))
    e++;
  return e - s;
}

/** Calculate span of a double quoted string (with escaped chars inside) */
00271 su_inline isize_t span_quoted(char const *s)
{
  char const *b = s;

  if (*s++ != '"')
    return 0;

  for (;;) {
    s += strcspn(s, "\\\"");
    if (!*s)
      return 0;
    if (*s++ == '"')
      return s - b;
    if (!*s++)
      return 0;
  }
}

/* RFC 2396 defines URL chars */
/** Reserved in URLs */
00291 #define URL_RESERVED        ";/?:=+$,"

/** Non-alphanumeric characters without syntactical meaning. */
00294 #define URL_MARK            "-_.!~*'()"

/** Unreserved characters. */
00297 #define URL_UNRESERVED ALPHANUM URL_MARK

/** URL hex escape. */
00300 #define URL_ESCAPED    "%"
#define URL_DELIMS     "<>#%\""
#define URL_UNWISE     "{}|\\^[]`"
#define URL_SCHEME     ALPHANUM "+-."

/** Get number of characters belonging to url scheme */
00306 #define span_url_scheme(s) strspn(s, URL_SCHEME)

SOFIAPUBFUN int span_ip4_address(char const *host);
SOFIAPUBFUN int span_ip6_address(char const *host);
SOFIAPUBFUN int span_ip6_reference(char const *host);
SOFIAPUBFUN int span_ip_address(char const *host);
SOFIAPUBFUN isize_t span_domain(char const *host);
SOFIAPUBFUN isize_t span_host(char const *host);

SOFIAPUBFUN int scan_ip4_address(char **inout_host);
SOFIAPUBFUN int scan_ip6_address(char **inout_host);
SOFIAPUBFUN int scan_ip6_reference(char **inout_host);
SOFIAPUBFUN int scan_ip_address(char **inout_host);
SOFIAPUBFUN issize_t scan_domain(char **inout_host);
SOFIAPUBFUN issize_t scan_host(char **inout_host);

SOFIA_END_DECLS

#endif /* !defined BNF_H */

Generated by  Doxygen 1.6.0   Back to index