Main Page   Class Hierarchy   Compound List   File List   Compound Members  

parser.cpp

00001 /*
00002  *  This program is free software; you can redistribute it and/or modify
00003  *  it under the terms of the GNU General Public License as published by
00004  *  the Free Software Foundation; either version 2 of the License, or
00005  *  (at your option) any later version.
00006  *
00007  *  This program is distributed in the hope that it will be useful,
00008  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00009  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00010  *  GNU General Public License for more details.
00011  *
00012  *  You should have received a copy of the GNU General Public License
00013  *  along with this program; if not, write to the Free Software
00014  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00015  *
00016  * (c)Copyright 2006 Hewlett-Packard Development Company, LP.
00017  *
00018  */
00019 
00020 #include "parser.hpp"
00021 #include "iostream_t.hpp"
00022 #include <regex.h>
00023 #include "string_t.hpp"
00024 #include "Utils.hpp"
00025 
00026 C_ProtocolFrame::T_MsgError parse_xml (char   *P_buf,
00027                                        size_t *P_size,
00028                                        char   *P_buf_header,
00029                                        size_t  P_size_header) {
00030 
00031   C_ProtocolFrame::T_MsgError L_error = C_ProtocolFrame::E_MSG_ERROR_DECODING ;
00032   regex_t    L_reg_expr ;
00033   int        L_status ;
00034   char       L_buffer[100];
00035   regmatch_t L_pmatch[2] ;
00036   size_t     L_size = 0 ;
00037   char       L_tag[100] ;
00038   regoff_t   L_next ;
00039 
00040   size_t     L_parsed_size = 0 ;
00041 
00042   regex_t    L_reg_final ;
00043   string_t   L_string = "<[[:blank:]]*[/]" ;
00044 
00045   int        L_i = 0 ;
00046   char      *L_ptr = P_buf ;
00047 
00048   int        L_nb_loop = 0 ;
00049 
00050   // no body 
00051 
00052   if ((*P_size >= 2) && (P_buf[0] == '\r') && (P_buf[1]='\n')) {
00053     // there is no body 
00054     *P_size -= 2 ;
00055     L_error = C_ProtocolFrame::E_MSG_OK ;
00056   } else {
00057 
00058 
00059   L_status = regcomp (&L_reg_expr, 
00060                       "[[:blank:]]*<[[:blank:]]*([!-=?-z]*)",
00061                       REG_EXTENDED) ;
00062   
00063   if (L_status != 0) {
00064 
00065     regerror(L_status, &L_reg_expr, L_buffer, 100);
00066     regfree (&L_reg_expr) ;
00067 
00068   } else {
00069 
00070 
00071     while (L_nb_loop < 2) {
00072   
00073       L_tag[0]='\0' ;
00074 
00075       L_status = regexec (&L_reg_expr, L_ptr, 2, L_pmatch, 0) ;
00076 
00077 
00078       if (L_status == 0) {
00079         
00080         L_parsed_size += L_pmatch[0].rm_eo ;
00081         
00082         L_next = L_pmatch[0].rm_eo ;
00083         L_size = L_pmatch[1].rm_eo - L_pmatch[1].rm_so ; // tag xml
00084         
00085         memcpy(L_tag, L_ptr+L_pmatch[1].rm_so, L_size);
00086         L_tag[L_size]='\0' ;
00087         
00088         if (strcmp(L_tag,(char*)"?xml") == 0 ) {
00089           while ( ((L_next + L_i) <= (int)*P_size ) && (*(L_ptr+L_next+L_i) != '>') ) {
00090             L_i++;
00091           }
00092 
00093           L_ptr += L_next + L_i + 1 ;
00094 
00095           L_parsed_size += (L_i+1) ;
00096 
00097         } else {
00098           L_string += L_tag ;
00099           L_string += "[[:blank:]]*>[[:blank:]]*" ;
00100           L_status = regcomp (&L_reg_final, 
00101                               L_string.c_str(),
00102                               REG_EXTENDED) ;
00103           
00104           if (L_status != 0) {
00105             regerror(L_status, &L_reg_final, L_buffer, 100);
00106             regfree (&L_reg_final) ;
00107             break ;
00108           } else {
00109             L_status = regexec (&L_reg_final, L_ptr+L_next, 
00110                                 1, L_pmatch, 0) ;
00111             regfree (&L_reg_final) ;
00112             
00113             if (L_status == 0) {
00114 
00115               L_parsed_size += L_pmatch[0].rm_eo ;
00116 
00117               // find \r\n at the end
00118               if ((L_parsed_size+2) <= *P_size) {
00119                 if (   (*((L_ptr+L_next)+L_pmatch[0].rm_eo) == '\r')
00120                        && (*((L_ptr+L_next)+L_pmatch[0].rm_eo+1) == '\n')) {
00121                   L_parsed_size += 2 ; // \r\n parsed
00122                   L_error = C_ProtocolFrame::E_MSG_OK ;
00123                   break ;
00124                 } else {
00125                   L_error = C_ProtocolFrame::E_MSG_ERROR_DECODING ;
00126                   break ;
00127                 }
00128               } else {
00129                 L_error = C_ProtocolFrame::E_MSG_ERROR_DECODING_SIZE_LESS ;
00130                 break ;
00131               }
00132               
00133             } else {
00134               L_error = C_ProtocolFrame::E_MSG_ERROR_DECODING_SIZE_LESS ;
00135               break ;
00136             }
00137             
00138           }
00139         } 
00140       } else {
00141         L_error = C_ProtocolFrame::E_MSG_ERROR_DECODING ;
00142         break ;
00143       }
00144       
00145       L_nb_loop ++ ;
00146     } // while 
00147 
00148     regfree (&L_reg_expr) ;
00149     if (L_error == C_ProtocolFrame::E_MSG_OK) {
00150       *P_size -= L_parsed_size ;
00151     }
00152 
00153   }
00154 
00155   }
00156 
00157   return (L_error) ;
00158 }
00159 
00160 
00161 char* skip_blank(char    *P_ptr, 
00162                  char    *P_buffer, 
00163                  size_t   P_size_buffer,
00164                  size_t  *P_size) {
00165   
00166   char     *L_blank_ptr    = NULL     ;
00167   char     *L_new_ptr      = P_ptr    ;
00168 
00169 
00170   L_blank_ptr = P_ptr ;
00171   while (((L_blank_ptr) && (L_blank_ptr < (P_buffer + P_size_buffer))) &&
00172          ((*L_blank_ptr == ' ') ||
00173           (*L_blank_ptr == '\t'))) { L_blank_ptr++ ; }
00174   if (L_blank_ptr != P_ptr) {
00175     *(P_size) = (L_blank_ptr - P_ptr) ;
00176     L_new_ptr = L_blank_ptr ;
00177   }
00178 
00179   return (L_new_ptr) ;
00180 }
00181 
00182 
00183 
00184 
00185 char * filter_xml(char* P_buffer) {
00186 
00187   size_t    L_size         = 0        ;
00188 
00189   size_t    L_size_buffer  = 0        ;
00190   size_t    L_size_end     = 0        ;
00191   
00192   char     *L_pos          = NULL     ;
00193   char     *L_ptr          = P_buffer ;
00194 
00195   char     *L_result       = NULL     ;
00196   char     *L_new          = NULL     ;
00197 
00198   bool      L_skip_blank   = true     ;
00199   size_t    L_size_blank   = 0        ;
00200 
00201 
00202   if ((P_buffer != NULL) && 
00203       ((L_size_buffer = strlen(P_buffer)) > 0 )) {
00204 
00205     L_size_end = L_size_buffer ;
00206 
00207     ALLOC_TABLE(L_result, 
00208                 char*, 
00209                 sizeof(char), 
00210                 (2*L_size_buffer));
00211     
00212 
00213     if ((strchr(L_ptr,'\n')) == NULL) {
00214 
00215       L_new = L_result ;
00216       L_size = L_size_buffer ;
00217 
00218       // skip blank
00219       if (L_skip_blank) {
00220         L_ptr = skip_blank(L_ptr,P_buffer, L_size_buffer, &L_size_blank) ;
00221         L_size -= L_size_blank ;
00222       }
00223 
00224       memcpy(L_new, L_ptr, L_size);
00225       L_new += (L_size - 1) ;
00226       if (*L_new != '\r') {
00227         L_new += 1 ;
00228         *L_new = '\r' ;
00229       }
00230       L_new += 2 ;
00231       *L_new = '\0' ;
00232       *(L_new-1) = '\n' ;
00233 
00234     } else {
00235       // if '\n' exists
00236 
00237       while(   (L_ptr) 
00238             && (L_pos = strchr(L_ptr,'\n')) != NULL) {
00239 
00240         L_size_blank = 0 ;
00241         // L_size : from start to '\n' not included
00242         L_size = L_pos - L_ptr ;
00243         // skip blank
00244         if (L_skip_blank) {
00245 
00246           L_ptr = skip_blank(L_ptr,P_buffer, L_size_buffer, &L_size_blank) ;
00247           L_size -= L_size_blank ;
00248           L_size_end -= L_size_blank ;
00249 
00250         }
00251 
00252         if (L_new == NULL) { L_new = L_result ; } else { L_new += 1 ; }
00253         memcpy(L_new, L_ptr, L_size);
00254         L_new += (L_size - 1) ;
00255         // test end needed ? for L_ptr
00256         if ((L_pos + 1) <= (P_buffer+L_size_buffer)) { 
00257           L_ptr = L_pos + 1 ; 
00258         } else { 
00259           L_ptr = NULL ; 
00260         }
00261 
00262         L_size_end -= (L_size + 1) ;
00263 
00264         if (*L_new != '\r') {
00265           L_new += 1 ;
00266           *(L_new) = '\r' ;
00267         }
00268         L_new += 1 ;
00269         *(L_new) = '\n' ;
00270 
00271       } // while
00272 
00273         
00274       // ctrl the end of buffer
00275       if (L_size_end > 0) {
00276 
00277         L_size = L_size_end ;
00278         L_size_blank = 0 ;
00279 
00280         // skip blank
00281         if (L_skip_blank) {
00282 
00283           L_ptr = skip_blank(L_ptr,P_buffer, L_size_buffer, &L_size_blank) ;
00284           L_size -= L_size_blank ;
00285         }
00286 
00287         if (L_size) {
00288           L_new +=1 ;
00289 
00290           memcpy(L_new, L_ptr, L_size);
00291           L_new += (L_size-1) ;
00292         
00293           if (*L_new != '\r') {
00294             L_new += 1 ;
00295             *(L_new) = '\r' ;
00296           }
00297           L_new += 2 ;
00298           *L_new = '\0' ;
00299           *(L_new-1) = '\n' ;
00300         } else {
00301           // add final '\0' 
00302           L_new += 1 ;
00303           *L_new = '\0' ;
00304         }
00305       } else {
00306         // add final '\0' 
00307         L_new += 1 ;
00308         *L_new = '\0' ;
00309         
00310       }
00311     }
00312   }
00313 
00314   if (L_result != NULL) {
00315     L_ptr = L_result ;
00316     while ((L_ptr = strstr(L_ptr, "\r\n\r\n")) != NULL ) {
00317       memmove(L_ptr+2, L_ptr+4, strlen(L_ptr+4));
00318       L_ptr += 2 ;
00319     }
00320   }
00321 
00322   return (L_result);
00323 }

Generated on Wed Mar 7 14:44:59 2007 for Seagull by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002