BESRegex.cc

Go to the documentation of this file.
00001 
00002 // -*- mode: c++; c-basic-offset:4 -*-
00003 
00004 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
00005 // Access Protocol.
00006 
00007 // Copyright (c) 2005 OPeNDAP, Inc.
00008 // Author: James Gallagher <jgallagher@opendap.org>
00009 //
00010 // This library is free software; you can redistribute it and/or
00011 // modify it under the terms of the GNU Lesser General Public
00012 // License as published by the Free Software Foundation; either
00013 // version 2.1 of the License, or (at your option) any later version.
00014 // 
00015 // This library is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 // 
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023 //
00024 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
00025 
00026 #include <config.h>
00027 
00028 #ifndef WIN32
00029 #include <alloca.h>
00030 #endif
00031 #include <stdlib.h>
00032  
00033 #include <sys/types.h>
00034 #include <regex.h>
00035 
00036 #include <new>
00037 #include <string>
00038 #include <stdexcept>
00039 
00040 #include "BESRegex.h"
00041 #include "BESException.h"
00042 #include "BESScrub.h"
00043 
00044 using namespace std;
00045 
00046 void
00047 BESRegex::init(const char *t)
00048 {
00049     d_preg = static_cast<void*>(new regex_t);
00050     int result = regcomp(static_cast<regex_t*>(d_preg), t, REG_EXTENDED);
00051 
00052     if  (result != 0) {
00053         size_t msg_len = regerror(result, static_cast<regex_t*>(d_preg),
00054                                   static_cast<char*>(NULL),
00055                                   static_cast<size_t>(0));
00056         char *msg = new char[msg_len+1];
00057         regerror(result, static_cast<regex_t*>(d_preg), msg, msg_len);
00058         BESException e(string("BESRegex error: ") + string(msg), __FILE__, __LINE__ );
00059         delete[] msg;
00060         throw e;
00061     }
00062 }
00063 
00064 BESRegex::~BESRegex()
00065 {
00066     regfree(static_cast<regex_t*>(d_preg));
00067     delete static_cast<regex_t*>(d_preg); d_preg = 0;
00068 
00069 }
00070 
00074 BESRegex::BESRegex(const char* t)
00075 {
00076     init(t);
00077 }
00078 
00081 BESRegex::BESRegex(const char* t, int)
00082 {
00083     init(t);
00084 }
00085 
00092 int 
00093 BESRegex::match(const char* s, int len, int pos)
00094 {
00095     regmatch_t pmatch[len];
00096     string ss = s;
00097 
00098     int result = regexec(static_cast<regex_t*>(d_preg), 
00099                          ss.substr(pos, len-pos).c_str(), len, pmatch, 0);
00100     if (result == REG_NOMATCH)
00101         return -1;
00102 
00103     return pmatch[0].rm_eo - pmatch[0].rm_so;
00104 }
00105 
00116 int 
00117 BESRegex::search(const char* s, int len, int& matchlen, int pos)
00118 {
00119         // sanitize allocation
00120     if (!BESScrub::size_ok(sizeof(regmatch_t), len+1))
00121         return -1;
00122         
00123     // alloc space for len matches, which is theoretical max.
00124     regmatch_t *pmatch = new regmatch_t[len+1];
00125     string ss = s;
00126      
00127     int result = regexec(static_cast<regex_t*>(d_preg),
00128                          ss.substr(pos, len-pos).c_str(), len, pmatch, 0);
00129     if (result == REG_NOMATCH) {
00130         delete[] pmatch; pmatch = 0;
00131         return -1;
00132     }
00133 
00134     // Match found, find the first one (pmatch lists the longest first)
00135     int m = 0;
00136     for (int i = 1; i < len; ++i)
00137         if (pmatch[i].rm_so != -1 && pmatch[i].rm_so < pmatch[m].rm_so)
00138             m = i;
00139             
00140     matchlen = pmatch[m].rm_eo - pmatch[m].rm_so;
00141     int matchpos = pmatch[m].rm_so;
00142     
00143     delete[] pmatch; pmatch = 0;
00144     return matchpos;
00145 }
00146 

Generated on Wed Jan 2 06:00:39 2008 for OPeNDAP Back End Server (BES) by  doxygen 1.5.4