Main Page | Modules | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

qvalue.c

Go to the documentation of this file.
00001 /*
00002  * $Id: qvalue.c,v 1.2 2005/02/18 18:16:48 janakj Exp $
00003  *
00004  * Handling of the q value
00005  *
00006  * Copyright (C) 2004 FhG FOKUS
00007  *
00008  * This file is part of ser, a free SIP server.
00009  *
00010  * ser is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version
00014  *
00015  * For a license to use the ser software under conditions
00016  * other than those described here, or to purchase support for this
00017  * software, please contact iptel.org by e-mail at the following addresses:
00018  *    info@iptel.org
00019  *
00020  * ser is distributed in the hope that it will be useful,
00021  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00022  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023  * GNU General Public License for more details.
00024  *
00025  * You should have received a copy of the GNU General Public License 
00026  * along with this program; if not, write to the Free Software 
00027  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00028  *
00029  * History
00030  * ------
00031  * 2004-04-25 created (janakj)
00032  */
00033 
00034 #include "error.h"
00035 #include "qvalue.h"
00036 
00037 
00038 /*
00039  * Convert string representation of q parameter in qvalue_t
00040  */
00041 int str2q(qvalue_t* q, char* s, int len)
00042 {
00043         int i, digits, order;
00044 
00045              /* States and equivalent regular expressions of input */
00046         enum {
00047                 ST_START,   /* (SPC|TAB)* */
00048                 ST_0,       /* 0+ */
00049                 ST_1,       /* 1 */
00050                 ST_0_PT,    /* 0*\. */
00051                 ST_1_PT,    /* 1\. */
00052                 ST_1_PT_0,  /* 1\.0+ */
00053                 ST_0_PT_N   /* 0*\.[0-9]+ */
00054         } state = ST_START;
00055 
00056         if (!q || !s) {
00057                 return E_INVALID_PARAMS;
00058         }
00059 
00060         digits = 1;
00061         order = 100;
00062         for(i = 0; i < len; i++) {
00063                 switch(state) {
00064                 case ST_START:
00065                         switch(s[i]) {
00066                         case ' ':
00067                         case '\t':
00068                                 break;
00069 
00070                         case '0':
00071                                 *q = 0;
00072                                 state = ST_0;
00073                                 break;
00074 
00075                         case '1':
00076                                 *q = 1000;
00077                                 state = ST_1;
00078                                 break;
00079 
00080                         case '.':
00081                                 state = ST_0_PT;
00082                                 break;
00083 
00084                         default:
00085                                 return E_Q_INV_CHAR;
00086                         }
00087                         break;
00088 
00089                 case ST_0:
00090                         switch(s[i]) {
00091                         case '0':
00092                                 break;
00093 
00094                         case '.':
00095                                 state = ST_0_PT;
00096                                 break;
00097 
00098                         case '1':
00099                                 *q = 1000;
00100                                 state = ST_1;
00101                                 break;
00102 
00103                         default:
00104                                 if (s[i] >= '2' && s[i] <= '9') {
00105                                         return E_Q_TOO_BIG;
00106                                 } else {
00107                                         return E_Q_INV_CHAR;
00108                                 }
00109                         }
00110                         break;
00111 
00112                 case ST_1:
00113                         if (s[i] == '.') {
00114                                 state = ST_1_PT;
00115                                 break;
00116                         } else {
00117                                 if (s[i] >= '0' && s[i] <= '9') {
00118                                         return E_Q_TOO_BIG;
00119                                 } else {
00120                                         return E_Q_INV_CHAR;
00121                                 }
00122                         }
00123                         break;
00124 
00125                 case ST_0_PT:
00126                         if (s[i] >= '0' && s[i] <= '9') {
00127                                 *q =  (s[i] - '0') * order;
00128                                 order /= 10;
00129                                 state = ST_0_PT_N;
00130                         } else {
00131                                 return E_Q_INV_CHAR;
00132                         }
00133                         break;
00134 
00135                 case ST_1_PT:
00136                         if (s[i] == '0') {
00137                                 state = ST_1_PT_0;
00138                         } else {
00139                                 if (s[i] >= '1' && s[i] <= '9') {
00140                                         return E_Q_TOO_BIG;
00141                                 } else {
00142                                         return E_Q_INV_CHAR;
00143                                 }
00144                         }
00145                         break;
00146 
00147                 case ST_1_PT_0:
00148                         if (s[i] == '0') {
00149                                 break;
00150                         } else {
00151                                 if (s[i] >= '1' && s[i] <= '9') {
00152                                         return E_Q_TOO_BIG;
00153                                 } else {
00154                                         return E_Q_INV_CHAR;
00155                                 }
00156                         }
00157                         break;
00158 
00159                 case ST_0_PT_N:
00160                         if (s[i] >= '0' && s[i] <= '9') {
00161                                 if (digits <= 3) {
00162                                         *q += (s[i] - '0') * order;
00163                                         order /= 10;
00164                                         digits++;
00165                                 }
00166                         } else {
00167                                 return E_Q_INV_CHAR;
00168                         }
00169                         break;
00170                 }
00171         }
00172 
00173         switch(state) {
00174         case ST_START:
00175                 return E_Q_EMPTY;
00176                 
00177         case ST_0_PT:
00178         case ST_1_PT:
00179                 return E_Q_DEC_MISSING;
00180                 
00181         default:
00182                 return 0;
00183         }
00184 }

Generated on Tue Sep 7 04:16:13 2010 for SIPExpressRouter by  doxygen 1.3.9.1