• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

ParseRules.cc

Go to the documentation of this file.
00001 /** @file
00002 
00003   A brief file description
00004 
00005   @section license License
00006 
00007   Licensed to the Apache Software Foundation (ASF) under one
00008   or more contributor license agreements.  See the NOTICE file
00009   distributed with this work for additional information
00010   regarding copyright ownership.  The ASF licenses this file
00011   to you under the Apache License, Version 2.0 (the
00012   "License"); you may not use this file except in compliance
00013   with the License.  You may obtain a copy of the License at
00014 
00015       http://www.apache.org/licenses/LICENSE-2.0
00016 
00017   Unless required by applicable law or agreed to in writing, software
00018   distributed under the License is distributed on an "AS IS" BASIS,
00019   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00020   See the License for the specific language governing permissions and
00021   limitations under the License.
00022  */
00023 
00024 /*************************** -*- Mod: C++ -*- ******************************
00025 
00026    ParseRules.h --
00027 
00028 
00029  ****************************************************************************/
00030 
00031 #include "libts.h"      /* MAGIC_EDITING_TAG */
00032 
00033 const unsigned int parseRulesCType[256] = {
00034 #include "ParseRulesCType"
00035 };
00036 const char parseRulesCTypeToUpper[256] = {
00037 #include "ParseRulesCTypeToUpper"
00038 };
00039 const char parseRulesCTypeToLower[256] = {
00040 #include "ParseRulesCTypeToLower"
00041 };
00042 
00043 unsigned char *
00044 ParseRules::scan_while(unsigned char *ptr, unsigned int n, uint32_t bitmask)
00045 {
00046   unsigned int i;
00047   uint32_t *wptr;
00048   unsigned char *align_ptr;
00049   uintptr_t f_bytes, b_bytes, words, align_off;
00050 
00051   align_off = ((uintptr_t) ptr & 3);
00052   align_ptr = (unsigned char *) (((uintptr_t) ptr) & ~3);
00053 
00054   f_bytes = (align_off ? 4 - align_off : 0);
00055 
00056   words = (n - f_bytes) >> 2;
00057 
00058   if (words == 0) {
00059     for (i = 0; i < n; i++)
00060       if (!is_type(ptr[i], bitmask))
00061         return (&ptr[i]);
00062   } else {
00063     wptr = ((uint32_t *) align_ptr) + (align_off ? 1 : 0);
00064     switch (align_off) {
00065     case 1:
00066       if (!is_type(align_ptr[1], bitmask))
00067         return (&ptr[1]);
00068     case 2:
00069       if (!is_type(align_ptr[2], bitmask))
00070         return (&ptr[2]);
00071     case 3:
00072       if (!is_type(align_ptr[3], bitmask))
00073         return (&ptr[3]);
00074       break;
00075     default:
00076       break;
00077     }
00078 
00079     b_bytes = n - ((words << 2) + f_bytes);
00080 
00081     for (i = 0; i < words; i++) {
00082       uint32_t word = wptr[i];
00083       uint32_t result = (is_type(((word >> 0) & 0xFF), bitmask) &
00084                        is_type(((word >> 8) & 0xFF), bitmask) &
00085                        is_type(((word >> 16) & 0xFF), bitmask) & is_type(((word >> 24) & 0xFF), bitmask));
00086       if (result == 0) {
00087         unsigned char *cptr = (unsigned char *) &(wptr[i]);
00088         if (!is_type(cptr[0], bitmask))
00089           return (&cptr[0]);
00090         if (!is_type(cptr[1], bitmask))
00091           return (&cptr[1]);
00092         if (!is_type(cptr[2], bitmask))
00093           return (&cptr[2]);
00094         return (&cptr[3]);
00095       }
00096     }
00097 
00098     align_ptr = (unsigned char *) &(wptr[words]);
00099 
00100     switch (b_bytes) {
00101     case 1:
00102       if (!is_type(align_ptr[0], bitmask))
00103         return (&align_ptr[0]);
00104       break;
00105     case 2:
00106       if (!is_type(align_ptr[0], bitmask))
00107         return (&align_ptr[0]);
00108       if (!is_type(align_ptr[1], bitmask))
00109         return (&align_ptr[1]);
00110       break;
00111     case 3:
00112       if (!is_type(align_ptr[0], bitmask))
00113         return (&align_ptr[0]);
00114       if (!is_type(align_ptr[1], bitmask))
00115         return (&align_ptr[1]);
00116       if (!is_type(align_ptr[2], bitmask))
00117         return (&align_ptr[2]);
00118       break;
00119     default:
00120       break;
00121     }
00122   }
00123   return 0;
00124 }
00125 
00126 
00127 void
00128 ParseRules::ink_tolower_buffer(char *ptr, unsigned int n)
00129 {
00130   unsigned int i;
00131 
00132   if (n < 8) {
00133     for (i = 0; i < n; i++)
00134       ptr[i] = ParseRules::ink_tolower(ptr[i]);
00135   } else {
00136     uintptr_t fpad = 4 - ((uintptr_t) ptr & 3);
00137     uintptr_t words = (n - fpad) >> 2;
00138     uintptr_t bpad = n - fpad - (words << 2);
00139 
00140     switch (fpad) {
00141     case 3:
00142       *ptr = ParseRules::ink_tolower(*ptr);
00143       ++ptr;
00144     case 2:
00145       *ptr = ParseRules::ink_tolower(*ptr);
00146       ++ptr;
00147     case 1:
00148       *ptr = ParseRules::ink_tolower(*ptr);
00149       ++ptr;
00150     default:
00151       break;
00152     }
00153 
00154     uint32_t *wptr = (uint32_t *) ptr;
00155     for (i = 0; i < words; i++) {
00156       uint32_t word = *wptr;
00157       ((unsigned char *) &word)[0] = ParseRules::ink_tolower(((unsigned char *) &word)[0]);
00158       ((unsigned char *) &word)[1] = ParseRules::ink_tolower(((unsigned char *) &word)[1]);
00159       ((unsigned char *) &word)[2] = ParseRules::ink_tolower(((unsigned char *) &word)[2]);
00160       ((unsigned char *) &word)[3] = ParseRules::ink_tolower(((unsigned char *) &word)[3]);
00161       *wptr++ = word;
00162     }
00163 
00164     switch (bpad) {
00165     case 3:
00166       *ptr = ParseRules::ink_tolower(*ptr);
00167       ++ptr;
00168     case 2:
00169       *ptr = ParseRules::ink_tolower(*ptr);
00170       ++ptr;
00171     case 1:
00172       *ptr = ParseRules::ink_tolower(*ptr);
00173       ++ptr;
00174     default:
00175       break;
00176     }
00177   }
00178 }
00179 
00180 // Implement our atol() / strtol() utility functions. Note that these will
00181 // deal with two cases atol does not:
00182 //
00183 //   1. They will handle both base 10 and base 16, always. 0x indicates hex.
00184 //   2. They all honor the SI multipliers (i.e. K, M, G and T.
00185 //
00186 int64_t
00187 ink_atoi64(const char *str)
00188 {
00189   int64_t num = 0;
00190   int negative = 0;
00191 
00192   while (*str && ParseRules::is_wslfcr(*str))
00193     str += 1;
00194 
00195   if (unlikely(str[0] == '0' && str[1] == 'x')) {
00196     str += 2;
00197     while (*str && ParseRules::is_hex(*str))
00198       num = (num << 4) + ink_get_hex(*str++);
00199   } else {
00200     if (unlikely(*str == '-')) {
00201       negative = 1;
00202       str += 1;
00203     }
00204 
00205     /*
00206       NOTE: we first compute the value as negative then correct the
00207       sign back to positive. This enables us to correctly parse MININT.
00208     */
00209     while (*str && ParseRules::is_digit(*str))
00210       num = (num * 10) - (*str++ - '0');
00211 #if USE_SI_MULTILIERS
00212     if (*str) {
00213       if (*str == 'K')
00214         num = num * (1LL << 10);
00215       else if (*str == 'M')
00216         num = num * (1LL << 20);
00217       else if (*str == 'G')
00218         num = num * (1LL << 30);
00219       else if (*str == 'T')
00220         num = num * (1LL << 40);
00221     }
00222 #endif
00223     if (!negative)
00224       num = -num;
00225   }
00226   return num;
00227 }
00228 
00229 uint64_t
00230 ink_atoui64(const char *str)
00231 {
00232   uint64_t num = 0;
00233 
00234   while (*str && ParseRules::is_wslfcr(*str))
00235     str += 1;
00236 
00237   if (unlikely(str[0] == '0' && str[1] == 'x')) {
00238     str += 2;
00239     while (*str && ParseRules::is_hex(*str))
00240       num = (num << 4) + ink_get_hex(*str++);
00241   } else {
00242     while (*str && ParseRules::is_digit(*str))
00243       num = (num * 10) + (*str++ - '0');
00244 #if USE_SI_MULTILIERS
00245     if (*str) {
00246       if (*str == 'K')
00247         num = num * (1LL << 10);
00248       else if (*str == 'M')
00249         num = num * (1LL << 20);
00250       else if (*str == 'G')
00251         num = num * (1LL << 30);
00252       else if (*str == 'T')
00253         num = num * (1LL << 40);
00254     }
00255 #endif
00256   }
00257   return num;
00258 }
00259 
00260 int64_t
00261 ink_atoi64(const char *str, int len)
00262 {
00263   int64_t num = 0;
00264   int negative = 0;
00265 
00266   while (len > 0 && *str && ParseRules::is_wslfcr(*str)) {
00267     str += 1;
00268     len--;
00269   }
00270 
00271   if (len <= 1)
00272     return 0;
00273 
00274   if (unlikely(str[0] == '0' && len > 1 && str[1] == 'x')) {
00275     str += 2;
00276     while (len > 0 && *str && ParseRules::is_hex(*str)) {
00277       num = (num << 4) + ink_get_hex(*str++);
00278       len--;
00279     }
00280   } else {
00281     if (unlikely(*str == '-')) {
00282       negative = 1;
00283       str += 1;
00284     }
00285 
00286     /*
00287       NOTE: we first compute the value as negative then correct the
00288       sign back to positive. This enables us to correctly parse MININT.
00289     */
00290     while (len > 0 && *str && ParseRules::is_digit(*str)) {
00291       num = (num * 10) - (*str++ - '0');
00292       len--;
00293     }
00294 #if USE_SI_MULTILIERS
00295     if (len > 0 && *str) {
00296       if (*str == 'K')
00297         num = num * (1 << 10);
00298       else if (*str == 'M')
00299         num = num * (1 << 20);
00300       else if (*str == 'G')
00301         num = num * (1 << 30);
00302     }
00303 #endif
00304 
00305     if (!negative)
00306       num = -num;
00307   }
00308   return num;
00309 }

Generated by  doxygen 1.7.1