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