pcset.cxx (2606B)
1 /* 2 * 3 * C++ Portable Types Library (PTypes) 4 * Version 2.1.1 Released 27-Jun-2007 5 * 6 * Copyright (C) 2001-2007 Hovik Melikyan 7 * 8 * http://www.melikyan.com/ptypes/ 9 * 10 */ 11 12 #include "ptypes.h" 13 14 15 namespace ptypes { 16 17 18 typedef int* pint; 19 20 21 static uchar lbitmask[8] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80}; 22 static uchar rbitmask[8] = {0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff}; 23 24 25 void cset::include(char min, char max) 26 { 27 if (uchar(min) > uchar(max)) 28 return; 29 int lidx = uchar(min) / 8; 30 int ridx = uchar(max) / 8; 31 uchar lbits = lbitmask[uchar(min) % 8]; 32 uchar rbits = rbitmask[uchar(max) % 8]; 33 34 if (lidx == ridx) 35 { 36 data[lidx] |= lbits & rbits; 37 } 38 else 39 { 40 data[lidx] |= lbits; 41 for (int i = lidx + 1; i < ridx; i++) 42 data[i] = -1; 43 data[ridx] |= rbits; 44 } 45 46 } 47 48 49 char hex4(char c) 50 { 51 if (c >= 'a') 52 return uchar(c - 'a' + 10); 53 else if (c >= 'A') 54 return uchar(c - 'A' + 10); 55 else 56 return char(c - '0'); 57 } 58 59 60 static uchar parsechar(const char*& p) 61 { 62 uchar ret = *p; 63 if (ret == _csetesc) { 64 p++; 65 ret = *p; 66 if ((ret >= '0' && ret <= '9') || (ret >= 'a' && ret <= 'f') || (ret >= 'A' && ret <= 'F')) { 67 ret = hex4(ret); 68 p++; 69 if (*p != 0) 70 ret = uchar((ret << 4) | hex4(*p)); 71 } 72 } 73 return ret; 74 } 75 76 77 void cset::assign(const char* p) 78 { 79 if (*p == '*' && *(p + 1) == 0) 80 fill(); 81 else 82 { 83 clear(); 84 for (; *p != 0; p++) { 85 uchar left = parsechar(p); 86 if (*(p + 1) == '-') { 87 p += 2; 88 uchar right = parsechar(p); 89 include(left, right); 90 } 91 else 92 include(left); 93 } 94 } 95 } 96 97 98 void cset::unite(const cset& s) 99 { 100 for(int i = 0; i < _csetwords; i++) 101 *(pint(data) + i) |= *(pint(s.data) + i); 102 } 103 104 105 void cset::subtract(const cset& s) 106 { 107 for(int i = 0; i < _csetwords; i++) 108 *(pint(data) + i) &= ~(*(pint(s.data) + i)); 109 } 110 111 112 void cset::intersect(const cset& s) 113 { 114 for(int i = 0; i < _csetwords; i++) 115 *(pint(data) + i) &= *(pint(s.data) + i); 116 } 117 118 119 void cset::invert() 120 { 121 for(int i = 0; i < _csetwords; i++) 122 *(pint(data) + i) = ~(*(pint(data) + i)); 123 } 124 125 126 bool cset::le(const cset& s) const 127 { 128 for (int i = 0; i < _csetwords; i++) 129 { 130 int w1 = *(pint(data) + i); 131 int w2 = *(pint(s.data) + i); 132 if ((w2 | w1) != w2) 133 return false; 134 } 135 return true; 136 } 137 138 139 }