Home | History | Annotate | Download | only in lib
      1 /***************************************************************************
      2  *                                  _   _ ____  _
      3  *  Project                     ___| | | |  _ \| |
      4  *                             / __| | | | |_) | |
      5  *                            | (__| |_| |  _ <| |___
      6  *                             \___|\___/|_| \_\_____|
      7  *
      8  * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel (at) haxx.se>, et al.
      9  *
     10  * This software is licensed as described in the file COPYING, which
     11  * you should have received as part of this distribution. The terms
     12  * are also available at https://curl.haxx.se/docs/copyright.html.
     13  *
     14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
     15  * copies of the Software, and permit persons to whom the Software is
     16  * furnished to do so, under the terms of the COPYING file.
     17  *
     18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
     19  * KIND, either express or implied.
     20  *
     21  ***************************************************************************/
     22 
     23 #include "curl_setup.h"
     24 
     25 #include "rawstr.h"
     26 
     27 /* Portable, consistent toupper (remember EBCDIC). Do not use toupper() because
     28    its behavior is altered by the current locale. */
     29 char Curl_raw_toupper(char in)
     30 {
     31 #if !defined(CURL_DOES_CONVERSIONS)
     32   if(in >= 'a' && in <= 'z')
     33     return (char)('A' + in - 'a');
     34 #else
     35   switch (in) {
     36   case 'a':
     37     return 'A';
     38   case 'b':
     39     return 'B';
     40   case 'c':
     41     return 'C';
     42   case 'd':
     43     return 'D';
     44   case 'e':
     45     return 'E';
     46   case 'f':
     47     return 'F';
     48   case 'g':
     49     return 'G';
     50   case 'h':
     51     return 'H';
     52   case 'i':
     53     return 'I';
     54   case 'j':
     55     return 'J';
     56   case 'k':
     57     return 'K';
     58   case 'l':
     59     return 'L';
     60   case 'm':
     61     return 'M';
     62   case 'n':
     63     return 'N';
     64   case 'o':
     65     return 'O';
     66   case 'p':
     67     return 'P';
     68   case 'q':
     69     return 'Q';
     70   case 'r':
     71     return 'R';
     72   case 's':
     73     return 'S';
     74   case 't':
     75     return 'T';
     76   case 'u':
     77     return 'U';
     78   case 'v':
     79     return 'V';
     80   case 'w':
     81     return 'W';
     82   case 'x':
     83     return 'X';
     84   case 'y':
     85     return 'Y';
     86   case 'z':
     87     return 'Z';
     88   }
     89 #endif
     90 
     91   return in;
     92 }
     93 
     94 /*
     95  * Curl_raw_equal() is for doing "raw" case insensitive strings. This is meant
     96  * to be locale independent and only compare strings we know are safe for
     97  * this.  See https://daniel.haxx.se/blog/2008/10/15/strcasecmp-in-turkish/ for
     98  * some further explanation to why this function is necessary.
     99  *
    100  * The function is capable of comparing a-z case insensitively even for
    101  * non-ascii.
    102  */
    103 
    104 int Curl_raw_equal(const char *first, const char *second)
    105 {
    106   while(*first && *second) {
    107     if(Curl_raw_toupper(*first) != Curl_raw_toupper(*second))
    108       /* get out of the loop as soon as they don't match */
    109       break;
    110     first++;
    111     second++;
    112   }
    113   /* we do the comparison here (possibly again), just to make sure that if the
    114      loop above is skipped because one of the strings reached zero, we must not
    115      return this as a successful match */
    116   return (Curl_raw_toupper(*first) == Curl_raw_toupper(*second));
    117 }
    118 
    119 int Curl_raw_nequal(const char *first, const char *second, size_t max)
    120 {
    121   while(*first && *second && max) {
    122     if(Curl_raw_toupper(*first) != Curl_raw_toupper(*second)) {
    123       break;
    124     }
    125     max--;
    126     first++;
    127     second++;
    128   }
    129   if(0 == max)
    130     return 1; /* they are equal this far */
    131 
    132   return Curl_raw_toupper(*first) == Curl_raw_toupper(*second);
    133 }
    134 
    135 /* Copy an upper case version of the string from src to dest.  The
    136  * strings may overlap.  No more than n characters of the string are copied
    137  * (including any NUL) and the destination string will NOT be
    138  * NUL-terminated if that limit is reached.
    139  */
    140 void Curl_strntoupper(char *dest, const char *src, size_t n)
    141 {
    142   if(n < 1)
    143     return;
    144 
    145   do {
    146     *dest++ = Curl_raw_toupper(*src);
    147   } while(*src++ && --n);
    148 }
    149