1 #include <stddef.h>
  2 #include <stdio.h>
  3 #include <string.h>
  4 #include "rh_string.h"
  5 
  6 
  7 #define MAP_WANT_LOWER  MAP_LOWER
  8 #define MAP_WANT_UPPER  MAP_UPPER
  9 #include "rh_charmap.h"
 10 
 11 #define WORD_INC(_ptr,_count)                                           \
 12         (void* ) (( (char *)(_ptr)) + (sizeof(size_t) * (_count) ))
 13 
 14 #define BYTE_INC(_ptr,_count)                                           \
 15         (void* ) (( (char *)(_ptr)) + (sizeof(char) * (_count) ))
 16 
 17 #define WORD_EQUAL(_ptr1,_ptr2,_off)                                    \
 18         ( ((size_t *) (_ptr1))[_off] == ((size_t *) (_ptr2))[_off] )
 19 
 20 #define BYTE_EQUAL(_ptr1,_ptr2,_off)                                    \
 21         ( ((char *) (_ptr1))[_off] == ((char *) (_ptr2))[_off] )
 22 
 23 #define BYTE_LC(_ptr,_off)                                              \
 24         MAP_LOWER[ ((unsigned char *) (_ptr))[_off] ]
 25 
 26 #define BYTE_CASE_EQUAL(_ptr1,_ptr2,_off)                               \
 27         ( BYTE_LC(_ptr1,_off) == BYTE_LC(_ptr2,_off) )
 28 
 29 
 30 const char * rh_str_rnrn (const char *data, size_t ndata)
 31 {
 32         const char *data_end;
 33         
 34         if (ndata < 4)
 35                 return NULL;
 36 
 37         data_end = (data + ndata) - 3;
 38         
 39         
 40         for (;data < data_end && data[3] > '\r'; data+=4);
 41         
 42         while (data < data_end) {
 43                 switch (data[3]) {
 44                 case '\n':
 45                         if (RH_EQUAL4("\r\n\r\n", data))
 46                                 return data;
 47                         
 48                         data += 2;
 49                         break;
 50                 case '\r':
 51                         if (RH_EQUAL2("\r\n", data+1)) {
 52                                 ++data;
 53                         } else {
 54                                 data += 3;
 55                         }
 56                         break;
 57                 default:
 58                         for (   data +=4;
 59                                 data < data_end && data[3] > '\r';
 60                                 data += 4);
 61                         break;
 62                 }
 63         }
 64         
 65         return NULL;
 66 }
 67 
 68 int rh_memcasecmp (const void *s1, const void *s2, size_t n)
 69 {
 70 #if 0
 71         printf ("\t\t%s(): %3zu = [%.*s] [%.*s]\n",
 72                         __FUNCTION__, n,
 73                         n, (char*)s1,
 74                         n, (char*)s2 );
 75 #endif
 76                         
 77         while (n > sizeof(size_t)-1) {
 78                 if (!WORD_EQUAL(s1,s2,0)) {
 79                         if (!BYTE_EQUAL(s1,s2,0) && !BYTE_CASE_EQUAL(s1,s2,0) )
 80                                 return -1;
 81                         
 82                         if (!BYTE_EQUAL(s1,s2,1) && !BYTE_CASE_EQUAL(s1,s2,1) )
 83                                 return -1;
 84                         
 85                         if (!BYTE_EQUAL(s1,s2,2) && !BYTE_CASE_EQUAL(s1,s2,2) )
 86                                 return -1;
 87                         
 88                         if (!BYTE_EQUAL(s1,s2,3) && !BYTE_CASE_EQUAL(s1,s2,3) )
 89                                 return -1;
 90                 }
 91                 
 92                 s2 = WORD_INC(s2, 1);
 93                 s1 = WORD_INC(s1, 1);
 94                 n -= sizeof(size_t);
 95         }
 96 
 97         switch (n) {
 98         case 0:
 99                 return 0;
100         case 3:
101                 if (!BYTE_EQUAL(s1,s2,2) && !BYTE_CASE_EQUAL(s1,s2,2) )
102                         return -1;
103         case 2:
104                 if (!BYTE_EQUAL(s1,s2,1) && !BYTE_CASE_EQUAL(s1,s2,1) )
105                         return -1;
106         case 1:
107                 if (!BYTE_EQUAL(s1,s2,0) && !BYTE_CASE_EQUAL(s1,s2,0) )
108                         return -1;
109         }
110 
111         return 0;
112 }
113 
114 char * rh_uint2str (char *dst, size_t ndst, size_t number, size_t *len)
115 {
116         char    *ptr;
117 
118         --ndst;
119 
120         ptr = dst + ndst;
121         
122         if (0 == number) {
123                 *ptr-- = '0';
124         } else {
125                 for (;ptr > dst && number; number/=10)
126                         *ptr-- = '0' + (number % 10);
127         }
128 
129         if (len)
130                 *len = (dst + ndst) - ptr;
131 
132         return (ptr + 1);
133 }
134 
135 size_t rh_hashcase33 (const char *src, size_t nsrc)
136 {
137         unsigned char   ch;
138         size_t          hash = 0;
139 
140         for (;nsrc;--nsrc) {
141                 ch = *src++;
142 
143                 if (ch > 'a'-1)
144                         ch = MAP_UPPER[ch];
145 
146                 hash = hash * 33 + ch;
147         }
148 
149         return hash;
150 }


syntax highlighted by Code2HTML, v. 0.9.1