1 /*
2
3 ----------------------------------------------------
4 httpry - HTTP logging and information retrieval tool
5 ----------------------------------------------------
6
7 Copyright (c) 2005-2014 Jason Bittel <jason.bittel@gmail.com>
8
9 */
10
11 #include <ctype.h>
12 #include <string.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include "error.h"
16
17 /* Strip leading and trailing spaces from parameter string, modifying
18 the string in place and returning a pointer to the (potentially)
19 new starting point */
str_strip_whitespace(char * str)20 char *str_strip_whitespace(char *str) {
21 size_t len = strlen(str);
22
23 #ifdef DEBUG
24 ASSERT(str);
25 ASSERT(strlen(str) > 0);
26 #endif
27
28 while (isspace(*str)) str++;
29 while (len && isspace(*(str + len - 1)))
30 *(str + (len--) - 1) = '\0';
31
32 return str;
33 }
34
35 /* Convert the paramter string to lowercase */
str_tolower(char * str)36 char *str_tolower(char *str) {
37 char *c;
38
39 #ifdef DEBUG
40 ASSERT(str);
41 ASSERT(strlen(str) > 0);
42 #endif
43
44 for (c = str; *c != '\0'; c++) {
45 *c = tolower(*c);
46 }
47
48 return str;
49 }
50
51 /* Compare two strings, ignoring the case of str1 and
52 assuming str2 is lowercase. Break if we find a string
53 terminator in str2 and consider it a match as str1
54 will not always have a string terminator. */
str_compare(const char * str1,const char * str2)55 int str_compare(const char *str1, const char *str2) {
56
57 #ifdef DEBUG
58 ASSERT(str2);
59 ASSERT(strlen(str2) > 0);
60 ASSERT(str1 != str2);
61 #endif
62
63 while (tolower(*str1) == *str2) {
64 str1++;
65 str2++;
66 if (*str2 == '\0') return 0;
67 }
68
69 return tolower(*str1) - *str2;
70 }
71
72 /* Copy at most len characters from src to dest, guaranteeing
73 dest will be properly terminated. Returns the total number of
74 characters copied, not including the string terminator. */
str_copy(char * dest,const char * src,size_t len)75 int str_copy(char *dest, const char *src, size_t len) {
76 const char *start = dest;
77
78 if (len > 0) {
79 while ((*src != '\0') && --len) {
80 *dest++ = *src++;
81 }
82 *dest = '\0';
83 }
84
85 return dest - start;
86 }
87
88 /* Wrapper function around str_copy() that first allocates
89 memory for the destination string and then copies the
90 parameter string into it. */
str_duplicate(const char * str)91 char *str_duplicate(const char *str) {
92 char *new;
93 size_t len = strlen(str);
94
95 if ((new = malloc(len + 1)) == NULL)
96 return NULL;
97
98 #ifdef DEBUG
99 ASSERT(str_copy(new, str, len + 1) <= (len + 1));
100 #else
101 str_copy(new, str, len + 1);
102 #endif
103
104 return new;
105 }
106
107 /* Implementation of Jenkins's One-at-a-Time hash, as described on
108 this page: http://www.burtleburtle.net/bob/hash/doobs.html */
hash_str(char * str,unsigned int hashsize)109 unsigned int hash_str(char *str, unsigned int hashsize) {
110 unsigned long int hash;
111
112 #ifdef DEBUG
113 ASSERT(str);
114 ASSERT(strlen(str) > 0);
115 #endif
116
117 for (hash = 0; *str != '\0'; str++) {
118 hash += tolower(*str);
119 hash += (hash << 10);
120 hash ^= (hash >> 6);
121 }
122
123 hash += (hash << 3);
124 hash ^= (hash >> 11);
125 hash += (hash << 15);
126
127 /* Restrict hash value to a maximum of hashsize;
128 hashsize must be a power of 2 */
129 return (unsigned int) (hash & (hashsize - 1));
130 }
131