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 PTYPES_BEGIN
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 
include(char min,char max)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 
hex4(char c)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 
parsechar(const char * & p)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 
assign(const char * p)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 
unite(const cset & s)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 
subtract(const cset & s)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 
intersect(const cset & s)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 
invert()119 void cset::invert()
120 {
121     for(int i = 0; i < _csetwords; i++)
122         *(pint(data) + i) = ~(*(pint(data) + i));
123 }
124 
125 
le(const cset & s) const126 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 PTYPES_END
140