1
2 /* Web Polygraph http://www.web-polygraph.org/
3 * Copyright 2003-2011 The Measurement Factory
4 * Licensed under the Apache License, Version 2.0 */
5
6 #include "pgl/pgl.h"
7
8 #include "xstd/h/iostream.h"
9 #include "xstd/h/string.h"
10
11 #include "xstd/Assert.h"
12 #include "xstd/gadgets.h"
13 #include "pgl/PglStrBlocks.h"
14
15
16 /* PglStrBlock */
17
diffCount(const PglStrBlock & b) const18 int PglStrBlock::diffCount(const PglStrBlock &b) const {
19 if (theType == sbtPoint) {
20 if (b.type() == sbtPoint)
21 return ((const PglStrPointBlock*)this)->
22 countDiffs((const PglStrPointBlock&)b);
23 else
24 return 2; // "big" difference
25 }
26
27 if (theType == sbtRange) {
28 if (b.type() == sbtRange)
29 return ((const PglStrRangeBlock*)this)->
30 countDiffs((const PglStrRangeBlock&)b);
31 else
32 return 2; // "big" difference
33 }
34
35 Assert(false);
36 return 2;
37 }
38
merge(PglStrBlock & b)39 void PglStrBlock::merge(PglStrBlock &b) {
40 if (type() == sbtPoint && b.type() == sbtPoint) {
41 ((PglStrPointBlock*)this)->
42 mergeWith((const PglStrPointBlock&)b);
43 } else
44 if (type() == sbtRange && b.type() == sbtRange) {
45 ((PglStrRangeBlock*)this)->
46 mergeWith((const PglStrRangeBlock&)b);
47 } else {
48 Assert(false);
49 }
50 }
51
52
53 /* PglStrPointBlock */
54
PglStrPointBlock(const char * aStart,const char * aStop)55 PglStrPointBlock::PglStrPointBlock(const char *aStart, const char *aStop):
56 PglStrBlock(sbtPoint), theStart(aStart), theStop(aStop) {
57 }
58
clone() const59 PglStrBlock *PglStrPointBlock::clone() const {
60 return new PglStrPointBlock(theStart, theStop);
61 }
62
count() const63 int PglStrPointBlock::count() const {
64 return 1;
65 }
66
countDiffs(const PglStrPointBlock & b) const67 int PglStrPointBlock::countDiffs(const PglStrPointBlock &b) const {
68 return
69 (theStop-theStart == b.theStop-b.theStart &&
70 strncmp(theStart, b.theStart, theStop-theStart) == 0) ? 0 : 2;
71 }
72
mergeWith(const PglStrPointBlock & b)73 void PglStrPointBlock::mergeWith(const PglStrPointBlock &b) {
74 Assert(countDiffs(b) == 0);
75 }
76
atLast() const77 bool PglStrPointBlock::atLast() const {
78 return true;
79 }
80
pos() const81 int PglStrPointBlock::pos() const {
82 return 0;
83 }
84
start()85 void PglStrPointBlock::start() {
86 }
87
next()88 void PglStrPointBlock::next() {
89 Assert(false);
90 }
91
pos(int aPos)92 void PglStrPointBlock::pos(int aPos) {
93 Assert(aPos == 0);
94 }
95
print(ostream & os) const96 void PglStrPointBlock::print(ostream &os) const {
97 os.write(theStart, theStop-theStart);
98 }
99
printCur(ostream & os) const100 void PglStrPointBlock::printCur(ostream &os) const {
101 print(os);
102 }
103
104
105 /* PglStrRangeBlock */
106
PglStrRangeBlock(int aStart,int aStop,bool beIsolated)107 PglStrRangeBlock::PglStrRangeBlock(int aStart, int aStop, bool beIsolated):
108 PglStrBlock(sbtRange), theStart(aStart), theStop(aStop), thePos(aStart) ,
109 isIsolated(beIsolated) {
110 }
111
clone() const112 PglStrBlock *PglStrRangeBlock::clone() const {
113 return new PglStrRangeBlock(theStart, theStop, isIsolated);
114 }
115
count() const116 int PglStrRangeBlock::count() const {
117 return theStop - theStart;
118 }
119
countDiffs(const PglStrRangeBlock & b) const120 int PglStrRangeBlock::countDiffs(const PglStrRangeBlock &b) const {
121 // exact match
122 if (theStart == b.theStart && theStop == b.theStop)
123 return 0;
124
125 // can only merge without changing the number of addresses
126 // if one range follows the other
127 if (theStop == b.theStart || b.theStop == theStart)
128 return 1;
129
130 // "big" difference
131 return 2;
132 }
133
mergeWith(const PglStrRangeBlock & b)134 void PglStrRangeBlock::mergeWith(const PglStrRangeBlock &b) {
135 theStart = Min(theStart, b.theStart);
136 theStop = Max(theStop, b.theStop);
137 // isIsolated does not change?
138 }
139
atLast() const140 bool PglStrRangeBlock::atLast() const {
141 return thePos == theStop-1;
142 }
143
pos() const144 int PglStrRangeBlock::pos() const {
145 return thePos - theStart;
146 }
147
start()148 void PglStrRangeBlock::start() {
149 thePos = theStart;
150 }
151
next()152 void PglStrRangeBlock::next() {
153 thePos++;
154 }
155
pos(int aPos)156 void PglStrRangeBlock::pos(int aPos) {
157 thePos = theStart + aPos; // local coordinates
158 Assert(theStart <= thePos && thePos < theStop);
159 }
160
print(ostream & os) const161 void PglStrRangeBlock::print(ostream &os) const {
162 if (!isIsolated)
163 os << '[';
164 os << theStart;
165 if (theStart != theStop-1)
166 os << '-' << (theStop-1);
167 if (!isIsolated)
168 os << ']';
169 }
170
printCur(ostream & os) const171 void PglStrRangeBlock::printCur(ostream &os) const {
172 os << thePos;
173 }
174