↑ 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