1 /******************************************************************************
2 * Copyright (c) 2000-2016 Ericsson Telecom AB
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
11 * Zalanyi, Balazs Andor
13 ******************************************************************************/
16 #include "Quadruple.hh"
22 Quad::Quad(unsigned int value
) : u() {
26 Quad::Quad(unsigned char group
, unsigned char plane
, unsigned char row
,
27 unsigned char cell
) : u() {
34 Quad::Quad(const Quad
& rhs
) : u() {
35 u
.value
= rhs
.u
.value
;
38 unsigned int Quad::get_value() const {
42 void Quad::set(int field
, unsigned char c
) {
59 void Quad::set(unsigned char group
, unsigned char plane
, unsigned char row
,
67 const Quad
Quad::operator-(const Quad
& rhs
) const {
68 return Quad(u
.value
- rhs
.u
.value
);
71 const Quad
& Quad::operator=(const Quad
& rhs
) {
72 u
.value
= rhs
.u
.value
;
76 bool Quad::operator==(unsigned int i
) const {
80 bool Quad::operator==(const Quad
& rhs
) const {
81 return u
.value
== rhs
.u
.value
;
84 bool Quad::operator<=(const Quad
& rhs
) const {
85 return u
.value
<= rhs
.u
.value
;
88 bool Quad::operator>=(const Quad
& rhs
) const {
89 return u
.value
>= rhs
.u
.value
;
92 bool Quad::operator<(const Quad
& rhs
) const {
93 return u
.value
< rhs
.u
.value
;
96 bool Quad::operator<(const QuadInterval
& rhs
) const {
97 return u
.value
< rhs
.lower
.u
.value
;
100 unsigned char Quad::operator[](int i
) const {
111 TTCN_pattern_error("Accessing a nonexistent field of a quadruple: %d.", i
);
113 return 0; // to get rid of the warning
116 char* Quad::get_hexrepr() const {
117 return Quad::get_hexrepr(u
.value
);
120 char* Quad::get_hexrepr(unsigned int value
) {
123 get_hexrepr(value
, hex
);
124 return mcopystr(hex
);
127 void Quad::get_hexrepr(const Quad
& q
, char* const str
) {
128 str
[0] = 'A' + (q
.u
.comp
.group
>> 4); // high end
129 str
[1] = 'A' + (q
.u
.comp
.group
& 15);
130 str
[2] = 'A' + (q
.u
.comp
.plane
>> 4);
131 str
[3] = 'A' + (q
.u
.comp
.plane
& 15);
132 str
[4] = 'A' + (q
.u
.comp
.row
>> 4);
133 str
[5] = 'A' + (q
.u
.comp
.row
& 15);
134 str
[6] = 'A' + (q
.u
.comp
.cell
>> 4);
135 str
[7] = 'A' + (q
.u
.comp
.cell
& 15); // low end
138 char* Quad::char_hexrepr(unsigned char c
) {
141 hex
[1] = (c
& 15) + 'A';
142 hex
[0] = (c
>> 4) + 'A';
143 return mcopystr(hex
);
146 // QuadInterval ----------------------------------------------------------------
148 QuadInterval::QuadInterval(Quad p_lower
, Quad p_upper
) :
149 lower(p_lower
), upper(p_upper
)
153 QuadInterval::QuadInterval(const QuadInterval
& rhs
)
154 : lower(rhs
.lower
), upper(rhs
.upper
) {
157 const Quad
& QuadInterval::get_lower() const {
161 const Quad
& QuadInterval::get_upper() const {
165 bool QuadInterval::contains(const Quad
& rhs
) const {
166 return lower
<= rhs
&& upper
>= rhs
;
169 bool QuadInterval::contains(const QuadInterval
& rhs
) const {
170 return lower
<= rhs
.lower
&& upper
>= rhs
.upper
;
173 bool QuadInterval::has_intersection(const QuadInterval
& rhs
) const {
174 return (rhs
.lower
<= upper
&& rhs
.lower
>= lower
) ||
175 (rhs
.upper
<= upper
&& rhs
.upper
>= lower
);
178 void QuadInterval::join(const QuadInterval
& rhs
) {
179 if (rhs
.lower
<= lower
)
181 if (rhs
.upper
>= upper
)
185 bool QuadInterval::operator <(const Quad
& rhs
) const {
189 bool QuadInterval::operator <(const QuadInterval
& rhs
) const {
190 return !has_intersection(rhs
) && upper
< rhs
.lower
;
193 unsigned int QuadInterval::width() const {
194 return (upper
- lower
).get_value();
197 char* QuadInterval::generate_posix() {
198 expstring_t res
= memptystr();
202 for (i
= 0; i
< 4; i
++)
203 diff
[i
] = upper
[i
] - lower
[i
];
205 for (c
= 0; c
< 4 && diff
[c
] == 0; c
++) ;
208 for (i
= 0; i
<= diff
[c
]; i
++) {
210 res
= mputc(res
, '|');
213 res
= mputc(res
, '(');
216 for (j
= 3; j
> c
; j
--) {
217 if (j
== 3 || (j
< 3 && q1
[j
] < 255)) {
219 res
= mputc(res
, '|');
220 for (k
= 0; k
< j
; k
++) {
221 res
= mputprintf(res
, "%s", str
= Quad::char_hexrepr(q1
[k
]));
225 res
= mputprintf(res
, "%s",
226 str
= generate_hex_interval(q1
[j
], q2
[j
]));
229 if (j
> 0 && q1
[j
-1] < 255)
230 q1
.set(j
- 1, q1
[j
-1] + 1);
231 for (k
= j
+ 1; k
< 4; k
++) {
232 res
= mputprintf(res
, "%s",
233 str
= generate_hex_interval(0, 255));
240 res
= mputc(res
, ')');
241 } else if (i
< diff
[c
]) {
242 for (j
= 0; j
< c
; j
++) {
243 res
= mputstr(res
, str
= Quad::char_hexrepr(lower
[j
]));
246 str
= generate_hex_interval(lower
[c
] + 1,
247 (unsigned char)(lower
[c
] + diff
[c
] - 1));
248 res
= mputprintf(res
, "%s", str
);
252 for (j
= 0; j
< k
; j
++)
253 res
= mputc(res
, '.');
255 res
= mputprintf(res
, ".\\{%d\\}", k
);
258 res
= mputc(res
, '(');
259 for (k
= c
; k
< 4 && c
< 3; k
++) {
262 for (j
= 0; j
<= c
; j
++) {
264 res
= mputstr(res
, str
= Quad::char_hexrepr(q1
[j
]));
269 q2
.set(c
, upper
[c
] - 1);
270 res
= mputstr(res
, str
= generate_hex_interval(q1
[c
], q2
[c
]));
272 for (j
= c
+ 1; j
< 4; j
++) {
274 res
= mputstr(res
, str
= generate_hex_interval(q1
[j
], q2
[j
]));
277 if (k
< 3 && c
< 3) {
278 res
= mputc(res
, '|');
281 res
= mputc(res
, ')');
284 } else if (diff
[c
] == 0) {
288 TTCN_pattern_error("In set interval: end is lower than start.");
294 for (j
= 0; j
< 3; j
++) {
295 res
= mputstr(res
, str
= Quad::char_hexrepr(lower
[j
]));
298 res
= mputstr(res
, str
= generate_hex_interval(lower
[3], upper
[3]));
306 char* QuadInterval::generate_hex_interval(unsigned char source
,
307 unsigned char dest
) {
308 expstring_t res
= memptystr();
309 int s_lo
, s_hi
, d_lo
, d_hi
, lo
, hi
;
310 s_lo
= (source
& 15) + 'A';
311 s_hi
= (source
>> 4) + 'A';
312 d_lo
= (dest
& 15) + 'A';
313 d_hi
= (dest
>> 4) + 'A';
317 res
= mputc(res
, '(');
320 if (lo
< 0) { // This is possibly reported during parsing.
321 TTCN_pattern_error("Illegal interval in set: start > end.");
323 res
= mputc(res
, (char)s_hi
);
324 if (s_lo
== 'A' && d_lo
== 'P')
325 res
= mputc(res
, '.');
327 res
= mputprintf(res
, "[%c-%c]", s_lo
, d_lo
);
329 res
= mputc(res
, (char)s_hi
);
330 res
= mputc(res
, (char)s_lo
);
338 res
= mputprintf(res
, "%c[%c-P]", s_hi
, s_lo
);
344 res
= mputc(res
, '|');
347 res
= mputprintf(res
, "%c[A-%c]", d_hi
, d_lo
);
352 res
= mputc(res
, '|');
353 if (s_hi
== 'A' && d_hi
== 'P')
354 res
= mputc(res
, '.');
356 res
= mputprintf(res
, "[%c-%c]", s_hi
, d_hi
);
357 res
= mputc(res
, '.');
362 res
= mputc(res
, ')');
366 // -------- QuadSet ------------------------------------------------------------
369 set(0), negate(false)
373 bool QuadSet::add(Quad
* p_quad
) {
374 bool contains
= false;
375 quadset_node_t
* it
= set
;
376 quadset_node_t
* after
= 0, *it_old
= 0;
380 contains
= *(it
->u
.p_quad
) == *p_quad
;
381 if (!contains
&& *p_quad
< *(it
->u
.p_quad
))
385 contains
= it
->u
.p_interval
->contains(*p_quad
);
386 if (!contains
&& *p_quad
< *(it
->u
.p_quad
))
394 quadset_node_t
* newnode
= new quadset_node_t
;
395 newnode
->etype
= QSET_QUAD
;
396 newnode
->u
.p_quad
= p_quad
;
397 if (after
== 0) { // largest element in the set so far
400 it_old
->next
= newnode
;
404 newnode
->next
= after
->next
;
405 after
->next
= newnode
;
414 void QuadSet::add(QuadInterval
* interval
) {
415 bool contains
= false;
416 quadset_node_t
* it
= set
;
417 quadset_node_t
* after
= 0, *it_old
= 0;
421 if (interval
->contains(*(it
->u
.p_quad
))) { // delete the quad
425 quadset_node_t
* p
= it
;
429 } else if (*interval
< *(it
->u
.p_quad
)) {
434 contains
= it
->u
.p_interval
->contains(*interval
);
436 if (it
->u
.p_interval
->has_intersection(*interval
)) { // merge
437 it
->u
.p_interval
->join(*interval
);
439 join_if_possible(it
);
441 } else if (*interval
< *(it
->u
.p_interval
))
450 quadset_node_t
* newnode
= new quadset_node_t
;
451 newnode
->etype
= QSET_INTERVAL
;
452 newnode
->u
.p_interval
= interval
;
453 if (after
== 0) { // largest element in the set so far
456 it_old
->next
= newnode
;
460 newnode
->next
= after
->next
;
461 after
->next
= newnode
;
468 void QuadSet::join(QuadSet
* rhs
) {
469 quadset_node_t
* it
= rhs
->set
;
473 add(new Quad(*(it
->u
.p_quad
)));
476 add(new QuadInterval(*(it
->u
.p_interval
)));
483 void QuadSet::set_negate(bool neg
) {
487 bool QuadSet::has_quad(const Quad
& q
) const {
488 quadset_node_t
* it
= set
;
492 if (q
== *(it
->u
.p_quad
))
496 if (it
->u
.p_interval
->contains(q
))
504 bool QuadSet::is_empty() const {
508 char* QuadSet::generate_posix() {
512 char* res
= memptystr();
513 res
= mputc(res
, '(');
514 quadset_node_t
* it
= set
;
517 res
= mputc(res
, '|');
520 str
= it
->u
.p_quad
->get_hexrepr();
521 res
= mputprintf(res
, "%s", str
);
525 str
= it
->u
.p_interval
->generate_posix();
526 res
= mputprintf(res
, "%s", str
);
532 res
= mputc(res
, ')');
536 QuadSet::~QuadSet() {
540 void QuadSet::clean(quadset_node_t
* start
) {
541 quadset_node_t
* it
= start
;
548 delete it
->u
.p_interval
;
551 quadset_node_t
* p
= it
;
557 void QuadSet::do_negate() {
558 QuadSet
* qs
= new QuadSet();
559 quadset_node_t
* it
= set
;
564 q2
= it
->u
.p_quad
->get_value() - 1;
565 qs
->add_negate_interval(q1
, q2
);
566 q1
= q2
.get_value() + 1;
569 q2
= it
->u
.p_interval
->get_lower().get_value() - 1;
570 qs
->add_negate_interval(q1
, q2
);
571 q1
= it
->u
.p_interval
->get_upper().get_value() + 1;
577 q2
.set(255, 255, 255, 255);
578 qs
->add_negate_interval(q1
, q2
);
587 void QuadSet::add_negate_interval(const Quad
& q1
, const Quad
& q2
) {
590 w
= q2
.get_value() - q1
.get_value();
592 add(new QuadInterval(q1
, q2
));
599 void QuadSet::join_if_possible(quadset_node_t
* start
) {
600 quadset_node_t
* it
= start
->next
;
604 if (start
->u
.p_interval
->contains(*(it
->u
.p_quad
))) {
606 quadset_node_t
* p
= it
;
613 if (start
->u
.p_interval
->has_intersection(*(it
->u
.p_interval
))) {
614 start
->u
.p_interval
->join(*(it
->u
.p_interval
));
615 delete it
->u
.p_interval
;
616 quadset_node_t
* p
= it
;
This page took 0.073914 seconds and 5 git commands to generate.