Skip to content

Commit 50f37ed

Browse files
Removed DataSetup, all Data() access now static
1 parent 7f1009b commit 50f37ed

File tree

3 files changed

+131
-242
lines changed

3 files changed

+131
-242
lines changed

src/main/java/com/mapcode/Data.java

Lines changed: 13 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -34,110 +34,7 @@ class Data {
3434
'A', 'E', 'U'
3535
};
3636

37-
private int flags;
38-
private int codex;
39-
private int codexLo;
40-
private int codexHi;
41-
private int codexLen;
42-
private boolean nameless;
43-
private boolean restricted;
44-
private boolean specialShape;
45-
private int pipeType;
46-
@Nullable
47-
private String pipeLetter;
48-
@Nullable
49-
private SubArea mapcoderRect;
50-
private boolean initialized;
51-
52-
int getFlags() {
53-
assert initialized;
54-
return flags;
55-
}
56-
57-
int getCodex() {
58-
assert initialized;
59-
return codex;
60-
}
61-
62-
int getCodexLo() {
63-
assert initialized;
64-
return codexLo;
65-
}
66-
67-
int getCodexHi() {
68-
assert initialized;
69-
return codexHi;
70-
}
71-
72-
int getCodexLen() {
73-
assert initialized;
74-
return codexLen;
75-
}
76-
77-
boolean isNameless() {
78-
assert initialized;
79-
return nameless;
80-
}
81-
82-
boolean isRestricted() {
83-
assert initialized;
84-
return restricted;
85-
}
86-
87-
boolean isSpecialShape() {
88-
assert initialized;
89-
return specialShape;
90-
}
91-
92-
int getPipeType() {
93-
assert initialized;
94-
return pipeType;
95-
}
96-
97-
@Nonnull
98-
String getPipeLetter() {
99-
assert initialized;
100-
assert pipeLetter != null;
101-
return pipeLetter;
102-
}
103-
104-
@Nonnull
105-
SubArea getMapcoderRect() {
106-
assert initialized;
107-
assert mapcoderRect != null;
108-
return mapcoderRect;
109-
}
110-
111-
Data(final int i) {
112-
dataSetup(i);
113-
}
114-
11537
Data() {
116-
initialized = false;
117-
}
118-
119-
void dataSetup(final int i) {
120-
flags = DataAccess.dataFlags(i);
121-
codexHi = calcCodexHi(flags);
122-
codexLo = calcCodexLo(flags);
123-
codexLen = calcCodexLen(codexHi, codexLo);
124-
codex = calcCodex(codexHi, codexLo);
125-
nameless = isNameless(i);
126-
restricted = (flags & 512) != 0;
127-
specialShape = isSpecialShape(i);
128-
pipeType = (flags >> 5) & 12; // 4=pipe 8=plus 12=star
129-
if (pipeType == 4) {
130-
pipeLetter = Character.toString(ENCODE_CHARS[(flags >> 11) & 31]);
131-
} else {
132-
pipeLetter = "";
133-
}
134-
if ((codex == 21) && !nameless) {
135-
codex++;
136-
codexLo++;
137-
codexLen++;
138-
}
139-
mapcoderRect = SubArea.getArea(i);
140-
initialized = true;
14138
}
14239

14340
static boolean isNameless(final int i) {
@@ -152,33 +49,24 @@ static int recType(final int i) {
15249
return (DataAccess.dataFlags(i) >> 7) & 3; // 1=pipe 2=plus 3=star
15350
}
15451

155-
static int calcCodex(final int i) {
156-
final int flags = DataAccess.dataFlags(i);
157-
return calcCodex(calcCodexHi(flags), calcCodexLo(flags));
158-
}
159-
160-
static int calcCodexLen(final int i) {
161-
final int flags = DataAccess.dataFlags(i);
162-
return calcCodexLen(calcCodexHi(flags), calcCodexLo(flags));
163-
}
164-
165-
static boolean isAutoHeader(final int i) {
166-
return (DataAccess.dataFlags(i) & (8 << 5)) != 0;
52+
static boolean isRestricted(final int i) {
53+
return (DataAccess.dataFlags(i) & 512) != 0;
16754
}
16855

169-
private static int calcCodexHi(final int flags) {
170-
return (flags & 31) / 5;
171-
}
172-
173-
private static int calcCodexLo(final int flags) {
174-
return ((flags & 31) % 5) + 1;
56+
static int calcCodex(final int i) {
57+
final int codexflags = DataAccess.dataFlags(i) & 31;
58+
return (10 * (codexflags / 5)) + (codexflags % 5) + 1;
17559
}
17660

177-
private static int calcCodex(final int codexhi, final int codexlo) {
178-
return (10 * codexhi) + codexlo;
61+
static String headerLetter(final int i) {
62+
final int flags = DataAccess.dataFlags(i);
63+
if (((flags >> 7) & 3) == 1) {
64+
return Character.toString(ENCODE_CHARS[(flags >> 11) & 31]);
65+
}
66+
return "";
17967
}
18068

181-
private static int calcCodexLen(final int codexhi, final int codexlo) {
182-
return codexhi + codexlo;
69+
static SubArea getBoundaries(final int i) {
70+
return SubArea.getArea(i);
18371
}
18472
}

src/main/java/com/mapcode/Decoder.java

Lines changed: 71 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -82,63 +82,73 @@ static Point decode(@Nonnull final String argMapcode,
8282
final int ccode = territory.getNumber();
8383

8484
final int from = DataAccess.dataFirstRecord(ccode);
85-
if (DataAccess.dataFlags(from) == 0) {
85+
if (DataAccess.dataFlags(from) == 0) { // no data for this territory?
8686
return Point.undefined(); // this territory is not in the current data
8787
}
8888
final int upto = DataAccess.dataLastRecord(ccode);
8989

9090
final int incodexhi = mapcode.indexOf('.');
91+
final int incodex = (incodexhi * 10) + (incodexlen - incodexhi);
9192

9293
final Data mapcoderData = new Data();
9394

9495
for (int i = from; i <= upto; i++) {
95-
mapcoderData.dataSetup(i);
96-
if ((mapcoderData.getPipeType() == 0) && !mapcoderData.isNameless()
97-
&& (mapcoderData.getCodexLen() == incodexlen) && (mapcoderData.getCodexHi() == incodexhi)) {
98-
99-
result = decodeGrid(mapcode, mapcoderData.getMapcoderRect().getMinX(), mapcoderData.getMapcoderRect()
100-
.getMinY(), mapcoderData.getMapcoderRect().getMaxX(), mapcoderData.getMapcoderRect().getMaxY(),
101-
i, extrapostfix);
102-
// RESTRICTUSELESS
103-
if (mapcoderData.isRestricted() && result.isDefined()) {
104-
boolean fitssomewhere = false;
105-
int j;
106-
for (j = upto - 1; j >= from; j--) { // look in previous
107-
// rects
108-
mapcoderData.dataSetup(j);
109-
if (mapcoderData.isRestricted()) {
110-
continue;
111-
}
112-
final int xdiv8 = Common.xDivider(mapcoderData.getMapcoderRect().getMinY(),
113-
mapcoderData.getMapcoderRect().getMaxY()) / 4;
114-
if (mapcoderData.getMapcoderRect().extendBounds(xdiv8, 60).containsPoint(result)) {
115-
fitssomewhere = true;
96+
final int codexi = mapcoderData.calcCodex(i);
97+
if (mapcoderData.recType(i) == 0) {
98+
if (mapcoderData.isNameless(i)) {
99+
// i = nameless
100+
if (((codexi == 21) && (incodex == 22)) ||
101+
((codexi == 22) && (incodex == 32)) ||
102+
((codexi == 13) && (incodex == 23))) {
103+
result = decodeNameless(mapcode, i, extrapostfix, mapcoderData);
116104
break;
117-
}
118105
}
119-
if (!fitssomewhere) {
120-
result.setUndefined();
106+
} else {
107+
// i = grid without headerletter
108+
if ((codexi == incodex) || ((incodex == 22) && (codexi == 21))) {
109+
result = decodeGrid(mapcode,
110+
mapcoderData.getBoundaries(i).getMinX(), mapcoderData.getBoundaries(i).getMinY(),
111+
mapcoderData.getBoundaries(i).getMaxX(), mapcoderData.getBoundaries(i).getMaxY(),
112+
i, extrapostfix);
113+
114+
if (mapcoderData.isRestricted(i) && result.isDefined()) {
115+
boolean fitssomewhere = false;
116+
int j;
117+
for (j = upto - 1; j >= from; j--) {
118+
if (!mapcoderData.isRestricted(j)) {
119+
final int xdiv8 = Common.xDivider(mapcoderData.getBoundaries(j).getMinY(),
120+
mapcoderData.getBoundaries(j).getMaxY()) / 4;
121+
if (mapcoderData.getBoundaries(j).extendBounds(xdiv8, 60).containsPoint(result)) {
122+
fitssomewhere = true;
123+
break;
124+
}
125+
}
126+
}
127+
if (!fitssomewhere) {
128+
result.setUndefined();
129+
}
130+
}
131+
break;
121132
}
122133
}
123-
break;
124-
} else if ((mapcoderData.getPipeType() == 4) && ((mapcoderData.getCodexLen() + 1) == incodexlen)
125-
&& ((mapcoderData.getCodexHi() + 1) == incodexhi)
126-
&& (mapcoderData.getPipeLetter().charAt(0) == mapcode.charAt(0))) {
127-
result = decodeGrid(mapcode.substring(1), mapcoderData.getMapcoderRect().getMinX(), mapcoderData
128-
.getMapcoderRect().getMinY(), mapcoderData.getMapcoderRect().getMaxX(), mapcoderData
129-
.getMapcoderRect().getMaxY(), i, extrapostfix);
130-
break;
131-
} else if (mapcoderData.isNameless()
132-
&& (((mapcoderData.getCodex() == 21) && (incodexlen == 4) && (incodexhi == 2))
133-
|| ((mapcoderData.getCodex() == 22) && (incodexlen == 5) && (incodexhi == 3)) || ((mapcoderData
134-
.getCodex() == 13) && (incodexlen == 5) && (incodexhi == 2)))) {
135-
result = decodeNameless(mapcode, i, extrapostfix, mapcoderData);
136-
break;
137-
} else if ((mapcoderData.getPipeType() > 4) && (incodexlen == (incodexhi + 3))
138-
&& ((mapcoderData.getCodexLen() + 1) == incodexlen)) {
139-
result = decodeAutoHeader(mapcode, i, extrapostfix, mapcoderData);
140-
break;
134+
} else if (mapcoderData.recType(i) == 1) {
135+
// i = grid with headerletter
136+
if ((incodex == codexi + 10) && (mapcoderData.headerLetter(i).charAt(0) == mapcode.charAt(0))) {
137+
result = decodeGrid(mapcode.substring(1),
138+
mapcoderData.getBoundaries(i).getMinX(), mapcoderData.getBoundaries(i).getMinY(),
139+
mapcoderData.getBoundaries(i).getMaxX(), mapcoderData.getBoundaries(i).getMaxY(),
140+
i, extrapostfix);
141+
break;
142+
}
143+
}
144+
else {
145+
// i = autoheader
146+
if (((incodex == 23) && (codexi == 22)) || ((incodex == 33) && (codexi == 23))) {
147+
result = decodeAutoHeader(mapcode, i, extrapostfix, mapcoderData);
148+
break;
149+
}
141150
}
151+
142152
}
143153

144154
if (result.isDefined()) {
@@ -150,7 +160,7 @@ static Point decode(@Nonnull final String argMapcode,
150160

151161
// LIMIT_TO_OUTRECT : make sure it fits the country
152162
if (ccode != CCODE_EARTH) {
153-
final SubArea mapcoderRect = SubArea.getArea(upto); // find
163+
final SubArea mapcoderRect = mapcoderData.getBoundaries(upto); // find
154164
// encompassing
155165
// rect
156166
final int xdiv8 = Common.xDivider(mapcoderRect.getMinY(), mapcoderRect.getMaxY()) / 4;
@@ -341,7 +351,7 @@ private static Point decodeGrid(final String str, final int minx, final int miny
341351
private static Point decodeNameless(final String str, final int firstrec, final String extrapostfix,
342352
final Data mapcoderData) {
343353
String result = str;
344-
final int codexm = mapcoderData.getCodex();
354+
final int codexm = mapcoderData.calcCodex(firstrec);
345355
if (codexm == 22) {
346356
result = result.substring(0, 3) + result.substring(4);
347357
} else {
@@ -405,19 +415,19 @@ private static Point decodeNameless(final String str, final int firstrec, final
405415
}
406416
}
407417

408-
mapcoderData.dataSetup(firstrec + nrX);
418+
final int m = firstrec + nrX;
409419

410-
int side = DataAccess.smartDiv(firstrec + nrX);
420+
int side = DataAccess.smartDiv(m);
411421
int xSIDE = side;
412422

413-
final int maxy = mapcoderData.getMapcoderRect().getMaxY();
414-
final int minx = mapcoderData.getMapcoderRect().getMinX();
415-
final int miny = mapcoderData.getMapcoderRect().getMinY();
423+
final int maxy = mapcoderData.getBoundaries(m).getMaxY();
424+
final int minx = mapcoderData.getBoundaries(m).getMinX();
425+
final int miny = mapcoderData.getBoundaries(m).getMinY();
416426

417427
final int dx;
418428
final int dy;
419429

420-
if (mapcoderData.isSpecialShape()) {
430+
if (mapcoderData.isSpecialShape(m)) {
421431
xSIDE *= side;
422432
side = 1 + ((maxy - miny) / 90);
423433
xSIDE = xSIDE / side;
@@ -444,31 +454,28 @@ private static Point decodeNameless(final String str, final int firstrec, final
444454
}
445455

446456
@Nonnull
447-
private static Point decodeAutoHeader(final String input, final int firstindex, final String extrapostfix,
457+
private static Point decodeAutoHeader(final String input, final int m, final String extrapostfix,
448458
@Nonnull final Data mapcoderData) {
449459
// returns Point.isUndefined() in case or error
450460
int storageStart = 0;
451-
final int thiscodexlen = mapcoderData.getCodexLen();
461+
final int codexm = mapcoderData.calcCodex(m);
452462

453463
int value = decodeBase31(input); // decode top (before dot)
454464
value *= 961 * 31;
455465
final Point triple = decodeTriple(input.substring(input.length() - 3));
456466
// decode bottom 3 chars
457467

458468
int i;
459-
i = firstindex;
469+
i = m;
460470
while (true) {
461-
if (Data.calcCodexLen(i) != thiscodexlen) {
471+
if ((mapcoderData.recType(i)<2) || (Data.calcCodex(i) != codexm)) {
462472
return Point.undefined(); // return undefined
463473
}
464-
if (i > firstindex) {
465-
mapcoderData.dataSetup(i);
466-
}
467474

468-
final int maxx = mapcoderData.getMapcoderRect().getMaxX();
469-
final int maxy = mapcoderData.getMapcoderRect().getMaxY();
470-
final int minx = mapcoderData.getMapcoderRect().getMinX();
471-
final int miny = mapcoderData.getMapcoderRect().getMinY();
475+
final int maxx = mapcoderData.getBoundaries(i).getMaxX();
476+
final int maxy = mapcoderData.getBoundaries(i).getMaxY();
477+
final int minx = mapcoderData.getBoundaries(i).getMinX();
478+
final int miny = mapcoderData.getBoundaries(i).getMinY();
472479

473480
int h = ((maxy - miny) + 89) / 90;
474481
final int xdiv = Common.xDivider(miny, maxy);
@@ -479,8 +486,8 @@ private static Point decodeAutoHeader(final String input, final int firstindex,
479486

480487
int product = (w / 168) * (h / 176) * 961 * 31;
481488

482-
if (mapcoderData.getPipeType() == 8) {
483-
final int goodRounder = (mapcoderData.getCodex() >= 23) ? (961 * 961 * 31) : (961 * 961);
489+
if (mapcoderData.recType(i) == 2) {
490+
final int goodRounder = (codexm >= 23) ? (961 * 961 * 31) : (961 * 961);
484491
product = ((((storageStart + product + goodRounder) - 1) / goodRounder) * goodRounder) - storageStart;
485492
}
486493

0 commit comments

Comments
 (0)