1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2014 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
7 ///////////////////////////////////////////////////////////////////////////////
10 #include "Quadruple.hh"
16 Quad::Quad(unsigned int value
) : u() {
20 Quad::Quad(unsigned char group
, unsigned char plane
, unsigned char row
,
21 unsigned char cell
) : u() {
28 Quad::Quad(const Quad
& rhs
) : u() {
29 u
.value
= rhs
.u
.value
;
32 unsigned int Quad::get_value() const {
36 void Quad::set(int field
, unsigned char c
) {
53 void Quad::set(unsigned char group
, unsigned char plane
, unsigned char row
,
61 const Quad
Quad::operator-(const Quad
& rhs
) const {
62 return Quad(u
.value
- rhs
.u
.value
);
65 const Quad
& Quad::operator=(const Quad
& rhs
) {
66 u
.value
= rhs
.u
.value
;
70 bool Quad::operator==(unsigned int i
) const {
74 bool Quad::operator==(const Quad
& rhs
) const {
75 return u
.value
== rhs
.u
.value
;
78 bool Quad::operator<=(const Quad
& rhs
) const {
79 return u
.value
<= rhs
.u
.value
;
82 bool Quad::operator>=(const Quad
& rhs
) const {
83 return u
.value
>= rhs
.u
.value
;
86 bool Quad::operator<(const Quad
& rhs
) const {
87 return u
.value
< rhs
.u
.value
;
90 bool Quad::operator<(const QuadInterval
& rhs
) const {
91 return u
.value
< rhs
.lower
.u
.value
;
94 unsigned char Quad::operator[](int i
) const {
105 TTCN_pattern_error("Accessing a nonexistent field of a quadruple: %d.", i
);
107 return 0; // to get rid of the warning
110 char* Quad::get_hexrepr() const {
111 return Quad::get_hexrepr(u
.value
);
114 char* Quad::get_hexrepr(unsigned int value
) {
117 get_hexrepr(value
, hex
);
118 return mcopystr(hex
);
121 void Quad::get_hexrepr(const Quad
& q
, char* const str
) {
122 str
[0] = 'A' + (q
.u
.comp
.group
>> 4); // high end
123 str
[1] = 'A' + (q
.u
.comp
.group
& 15);
124 str
[2] = 'A' + (q
.u
.comp
.plane
>> 4);
125 str
[3] = 'A' + (q
.u
.comp
.plane
& 15);
126 str
[4] = 'A' + (q
.u
.comp
.row
>> 4);
127 str
[5] = 'A' + (q
.u
.comp
.row
& 15);
128 str
[6] = 'A' + (q
.u
.comp
.cell
>> 4);
129 str
[7] = 'A' + (q
.u
.comp
.cell
& 15); // low end
132 char* Quad::char_hexrepr(unsigned char c
) {
135 hex
[1] = (c
& 15) + 'A';
136 hex
[0] = (c
>> 4) + 'A';
137 return mcopystr(hex
);
140 // QuadInterval ----------------------------------------------------------------
142 QuadInterval::QuadInterval(Quad p_lower
, Quad p_upper
) :
143 lower(p_lower
), upper(p_upper
)
147 QuadInterval::QuadInterval(const QuadInterval
& rhs
)
148 : lower(rhs
.lower
), upper(rhs
.upper
) {
151 const Quad
& QuadInterval::get_lower() const {
155 const Quad
& QuadInterval::get_upper() const {
159 bool QuadInterval::contains(const Quad
& rhs
) const {
160 return lower
<= rhs
&& upper
>= rhs
;
163 bool QuadInterval::contains(const QuadInterval
& rhs
) const {
164 return lower
<= rhs
.lower
&& upper
>= rhs
.upper
;
167 bool QuadInterval::has_intersection(const QuadInterval
& rhs
) const {
168 return (rhs
.lower
<= upper
&& rhs
.lower
>= lower
) ||
169 (rhs
.upper
<= upper
&& rhs
.upper
>= lower
);
172 void QuadInterval::join(const QuadInterval
& rhs
) {
173 if (rhs
.lower
<= lower
)
175 if (rhs
.upper
>= upper
)
179 bool QuadInterval::operator <(const Quad
& rhs
) const {
183 bool QuadInterval::operator <(const QuadInterval
& rhs
) const {
184 return !has_intersection(rhs
) && upper
< rhs
.lower
;
187 unsigned int QuadInterval::width() const {
188 return (upper
- lower
).get_value();
191 char* QuadInterval::generate_posix() {
192 expstring_t res
= memptystr();
196 for (i
= 0; i
< 4; i
++)
197 diff
[i
] = upper
[i
] - lower
[i
];
199 for (c
= 0; c
< 4 && diff
[c
] == 0; c
++) ;
202 for (i
= 0; i
<= diff
[c
]; i
++) {
204 res
= mputc(res
, '|');
207 res
= mputc(res
, '(');
210 for (j
= 3; j
> c
; j
--) {
211 if (j
== 3 || (j
< 3 && q1
[j
] < 255)) {
213 res
= mputc(res
, '|');
214 for (k
= 0; k
< j
; k
++) {
215 res
= mputprintf(res
, "%s", str
= Quad::char_hexrepr(q1
[k
]));
219 res
= mputprintf(res
, "%s",
220 str
= generate_hex_interval(q1
[j
], q2
[j
]));
223 if (j
> 0 && q1
[j
-1] < 255)
224 q1
.set(j
- 1, q1
[j
-1] + 1);
225 for (k
= j
+ 1; k
< 4; k
++) {
226 res
= mputprintf(res
, "%s",
227 str
= generate_hex_interval(0, 255));
234 res
= mputc(res
, ')');
235 } else if (i
< diff
[c
]) {
236 for (j
= 0; j
< c
; j
++) {
237 res
= mputstr(res
, str
= Quad::char_hexrepr(lower
[j
]));
240 str
= generate_hex_interval(lower
[c
] + 1,
241 (unsigned char)(lower
[c
] + diff
[c
] - 1));
242 res
= mputprintf(res
, "%s", str
);
246 for (j
= 0; j
< k
; j
++)
247 res
= mputc(res
, '.');
249 res
= mputprintf(res
, ".\\{%d\\}", k
);
252 res
= mputc(res
, '(');
253 for (k
= c
; k
< 4 && c
< 3; k
++) {
256 for (j
= 0; j
<= c
; j
++) {
258 res
= mputstr(res
, str
= Quad::char_hexrepr(q1
[j
]));
263 q2
.set(c
, upper
[c
] - 1);
264 res
= mputstr(res
, str
= generate_hex_interval(q1
[c
], q2
[c
]));
266 for (j
= c
+ 1; j
< 4; j
++) {
268 res
= mputstr(res
, str
= generate_hex_interval(q1
[j
], q2
[j
]));
271 if (k
< 3 && c
< 3) {
272 res
= mputc(res
, '|');
275 res
= mputc(res
, ')');
278 } else if (diff
[c
] == 0) {
282 TTCN_pattern_error("In set interval: end is lower than start.");
288 for (j
= 0; j
< 3; j
++) {
289 res
= mputstr(res
, str
= Quad::char_hexrepr(lower
[j
]));
292 res
= mputstr(res
, str
= generate_hex_interval(lower
[3], upper
[3]));
300 char* QuadInterval::generate_hex_interval(unsigned char source
,
301 unsigned char dest
) {
302 expstring_t res
= memptystr();
303 int s_lo
, s_hi
, d_lo
, d_hi
, lo
, hi
;
304 s_lo
= (source
& 15) + 'A';
305 s_hi
= (source
>> 4) + 'A';
306 d_lo
= (dest
& 15) + 'A';
307 d_hi
= (dest
>> 4) + 'A';
311 res
= mputc(res
, '(');
314 if (lo
< 0) { // This is possibly reported during parsing.
315 TTCN_pattern_error("Illegal interval in set: start > end.");
317 res
= mputc(res
, (char)s_hi
);
318 if (s_lo
== 'A' && d_lo
== 'P')
319 res
= mputc(res
, '.');
321 res
= mputprintf(res
, "[%c-%c]", s_lo
, d_lo
);
323 res
= mputc(res
, (char)s_hi
);
324 res
= mputc(res
, (char)s_lo
);
332 res
= mputprintf(res
, "%c[%c-P]", s_hi
, s_lo
);
338 res
= mputc(res
, '|');
341 res
= mputprintf(res
, "%c[A-%c]", d_hi
, d_lo
);
346 res
= mputc(res
, '|');
347 if (s_hi
== 'A' && d_hi
== 'P')
348 res
= mputc(res
, '.');
350 res
= mputprintf(res
, "[%c-%c]", s_hi
, d_hi
);
351 res
= mputc(res
, '.');
356 res
= mputc(res
, ')');
360 // -------- QuadSet ------------------------------------------------------------
363 set(0), negate(false)
367 bool QuadSet::add(Quad
* p_quad
) {
368 bool contains
= false;
369 quadset_node_t
* it
= set
;
370 quadset_node_t
* after
= 0, *it_old
= 0;
374 contains
= *(it
->u
.p_quad
) == *p_quad
;
375 if (!contains
&& *p_quad
< *(it
->u
.p_quad
))
379 contains
= it
->u
.p_interval
->contains(*p_quad
);
380 if (!contains
&& *p_quad
< *(it
->u
.p_quad
))
388 quadset_node_t
* newnode
= new quadset_node_t
;
389 newnode
->etype
= QSET_QUAD
;
390 newnode
->u
.p_quad
= p_quad
;
391 if (after
== 0) { // largest element in the set so far
394 it_old
->next
= newnode
;
398 newnode
->next
= after
->next
;
399 after
->next
= newnode
;
408 void QuadSet::add(QuadInterval
* interval
) {
409 bool contains
= false;
410 quadset_node_t
* it
= set
;
411 quadset_node_t
* after
= 0, *it_old
= 0;
415 if (interval
->contains(*(it
->u
.p_quad
))) { // delete the quad
419 quadset_node_t
* p
= it
;
423 } else if (*interval
< *(it
->u
.p_quad
)) {
428 contains
= it
->u
.p_interval
->contains(*interval
);
430 if (it
->u
.p_interval
->has_intersection(*interval
)) { // merge
431 it
->u
.p_interval
->join(*interval
);
433 join_if_possible(it
);
435 } else if (*interval
< *(it
->u
.p_interval
))
444 quadset_node_t
* newnode
= new quadset_node_t
;
445 newnode
->etype
= QSET_INTERVAL
;
446 newnode
->u
.p_interval
= interval
;
447 if (after
== 0) { // largest element in the set so far
450 it_old
->next
= newnode
;
454 newnode
->next
= after
->next
;
455 after
->next
= newnode
;
462 void QuadSet::join(QuadSet
* rhs
) {
463 quadset_node_t
* it
= rhs
->set
;
467 add(new Quad(*(it
->u
.p_quad
)));
470 add(new QuadInterval(*(it
->u
.p_interval
)));
477 void QuadSet::set_negate(bool neg
) {
481 bool QuadSet::has_quad(const Quad
& q
) const {
482 quadset_node_t
* it
= set
;
486 if (q
== *(it
->u
.p_quad
))
490 if (it
->u
.p_interval
->contains(q
))
498 bool QuadSet::is_empty() const {
502 char* QuadSet::generate_posix() {
506 char* res
= memptystr();
507 res
= mputc(res
, '(');
508 quadset_node_t
* it
= set
;
511 res
= mputc(res
, '|');
514 str
= it
->u
.p_quad
->get_hexrepr();
515 res
= mputprintf(res
, "%s", str
);
519 str
= it
->u
.p_interval
->generate_posix();
520 res
= mputprintf(res
, "%s", str
);
526 res
= mputc(res
, ')');
530 QuadSet::~QuadSet() {
534 void QuadSet::clean(quadset_node_t
* start
) {
535 quadset_node_t
* it
= start
;
542 delete it
->u
.p_interval
;
545 quadset_node_t
* p
= it
;
551 void QuadSet::do_negate() {
552 QuadSet
* qs
= new QuadSet();
553 quadset_node_t
* it
= set
;
558 q2
= it
->u
.p_quad
->get_value() - 1;
559 qs
->add_negate_interval(q1
, q2
);
560 q1
= q2
.get_value() + 1;
563 q2
= it
->u
.p_interval
->get_lower().get_value() - 1;
564 qs
->add_negate_interval(q1
, q2
);
565 q1
= it
->u
.p_interval
->get_upper().get_value() + 1;
571 q2
.set(255, 255, 255, 255);
572 qs
->add_negate_interval(q1
, q2
);
581 void QuadSet::add_negate_interval(const Quad
& q1
, const Quad
& q2
) {
584 w
= q2
.get_value() - q1
.get_value();
586 add(new QuadInterval(q1
, q2
));
593 void QuadSet::join_if_possible(quadset_node_t
* start
) {
594 quadset_node_t
* it
= start
->next
;
598 if (start
->u
.p_interval
->contains(*(it
->u
.p_quad
))) {
600 quadset_node_t
* p
= it
;
607 if (start
->u
.p_interval
->has_intersection(*(it
->u
.p_interval
))) {
608 start
->u
.p_interval
->join(*(it
->u
.p_interval
));
609 delete it
->u
.p_interval
;
610 quadset_node_t
* p
= it
;
This page took 0.042943 seconds and 6 git commands to generate.