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