1/***************************************************************************
2 *                                  _   _ ____  _
3 *  Project                     ___| | | |  _ \| |
4 *                             / __| | | | |_) | |
5 *                            | (__| |_| |  _ <| |___
6 *                             \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@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 http://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 "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. */
29char Curl_raw_toupper(char in)
30{
31  switch (in) {
32  case 'a':
33    return 'A';
34  case 'b':
35    return 'B';
36  case 'c':
37    return 'C';
38  case 'd':
39    return 'D';
40  case 'e':
41    return 'E';
42  case 'f':
43    return 'F';
44  case 'g':
45    return 'G';
46  case 'h':
47    return 'H';
48  case 'i':
49    return 'I';
50  case 'j':
51    return 'J';
52  case 'k':
53    return 'K';
54  case 'l':
55    return 'L';
56  case 'm':
57    return 'M';
58  case 'n':
59    return 'N';
60  case 'o':
61    return 'O';
62  case 'p':
63    return 'P';
64  case 'q':
65    return 'Q';
66  case 'r':
67    return 'R';
68  case 's':
69    return 'S';
70  case 't':
71    return 'T';
72  case 'u':
73    return 'U';
74  case 'v':
75    return 'V';
76  case 'w':
77    return 'W';
78  case 'x':
79    return 'X';
80  case 'y':
81    return 'Y';
82  case 'z':
83    return 'Z';
84  }
85  return in;
86}
87
88/*
89 * Curl_raw_equal() is for doing "raw" case insensitive strings. This is meant
90 * to be locale independent and only compare strings we know are safe for
91 * this.  See http://daniel.haxx.se/blog/2008/10/15/strcasecmp-in-turkish/ for
92 * some further explanation to why this function is necessary.
93 *
94 * The function is capable of comparing a-z case insensitively even for
95 * non-ascii.
96 */
97
98int Curl_raw_equal(const char *first, const char *second)
99{
100  while(*first && *second) {
101    if(Curl_raw_toupper(*first) != Curl_raw_toupper(*second))
102      /* get out of the loop as soon as they don't match */
103      break;
104    first++;
105    second++;
106  }
107  /* we do the comparison here (possibly again), just to make sure that if the
108     loop above is skipped because one of the strings reached zero, we must not
109     return this as a successful match */
110  return (Curl_raw_toupper(*first) == Curl_raw_toupper(*second));
111}
112
113int Curl_raw_nequal(const char *first, const char *second, size_t max)
114{
115  while(*first && *second && max) {
116    if(Curl_raw_toupper(*first) != Curl_raw_toupper(*second)) {
117      break;
118    }
119    max--;
120    first++;
121    second++;
122  }
123  if(0 == max)
124    return 1; /* they are equal this far */
125
126  return Curl_raw_toupper(*first) == Curl_raw_toupper(*second);
127}
128
129/* Copy an upper case version of the string from src to dest.  The
130 * strings may overlap.  No more than n characters of the string are copied
131 * (including any NUL) and the destination string will NOT be
132 * NUL-terminated if that limit is reached.
133 */
134void Curl_strntoupper(char *dest, const char *src, size_t n)
135{
136  if(n < 1)
137    return;
138
139  do {
140    *dest++ = Curl_raw_toupper(*src);
141  } while(*src++ && --n);
142}
143