From e285cac1365df2b407647660ffe935c3521de16b Mon Sep 17 00:00:00 2001 From: Erik Bos Date: Mon, 17 Aug 2015 17:24:04 +0200 Subject: [PATCH 1/2] Prettified and tidied up code. Moved variable initialisation to place of first use. Removed uncessary braces to make functions more readable. Do not use braces for simple statements, do use them for complex ones. --- mapcodelib/mapcoder.c | 1934 ++++++++++++++++++++--------------------- 1 file changed, 941 insertions(+), 993 deletions(-) diff --git a/mapcodelib/mapcoder.c b/mapcodelib/mapcoder.c index 66daee9..6a7c43c 100644 --- a/mapcodelib/mapcoder.c +++ b/mapcodelib/mapcoder.c @@ -50,7 +50,7 @@ typedef struct { int context; // input territory context (or negative) const char *iso; // input territory alphacode (context) // output - double lat, lon; // result + double lat, lon; // result int lat32, lon32; // result in integer arithmetic (millionts of degrees) } decodeRec; @@ -61,9 +61,15 @@ typedef struct { // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -static int firstrec(int ccode) { return data_start[ccode]; } +static int firstrec(int ccode) +{ + return data_start[ccode]; +} -static int lastrec(int ccode) { return data_start[ccode + 1] - 1; } +static int lastrec(int ccode) +{ + return data_start[ccode + 1] - 1; +} static int ParentLetter(int ccode) // returns parent index (>0), or 0 { @@ -83,9 +89,13 @@ static int ParentTerritoryOf(int ccode) // returns parent, or -1 return parentnr[ParentLetter(ccode)]; } -static int isSubdivision(int ccode) { return (ParentTerritoryOf(ccode) >= 0); } +static int isSubdivision(int ccode) +{ + return (ParentTerritoryOf(ccode) >= 0); +} -static int coDex(int m) { +static int coDex(int m) +{ int c = mminfo[m].flags & 31; return 10 * (c / 5) + ((c % 5) + 1); } @@ -102,18 +112,29 @@ static int coDex(int m) { static int isInRange(int x, int minx, int maxx) // returns nonzero if x in the range minx...maxx { - if (minx <= x && x < maxx) { return 1; } - if (x < minx) { x += 360000000; } else { x -= 360000000; } // 1.32 fix FIJI edge case - if (minx <= x && x < maxx) { return 1; } + if (minx <= x && x < maxx) + return 1; + + // 1.32 fix FIJI edge case + if (x < minx) + x += 360000000; + else + x -= 360000000; + + if (minx <= x && x < maxx) + return 1; + return 0; } -static int fitsInside(int x, int y, int m) { +static int fitsInside(int x, int y, int m) +{ const mminforec *b = boundaries(m); return (b->miny <= y && y < b->maxy && isInRange(x, b->minx, b->maxx)); } -static int xDivider4(int miny, int maxy) { +static int xDivider4(int miny, int maxy) +{ if (miny >= 0) { // both above equator? then miny is closest return xdivider19[(miny) >> 19]; } @@ -123,7 +144,8 @@ static int xDivider4(int miny, int maxy) { return xdivider19[(-maxy) >> 19]; // both negative, so maxy is closest to equator } -static int fitsInsideWithRoom(int x, int y, int m) { +static int fitsInsideWithRoom(int x, int y, int m) +{ const mminforec *b = boundaries(m); int xdiv8 = xDivider4(b->miny, b->maxy) / 4; // should be /8 but there's some extra margin return (b->miny - 60 <= y && y < b->maxy + 60 && isInRange(x, b->minx - xdiv8, b->maxx + xdiv8)); @@ -135,38 +157,44 @@ static int fitsInsideWithRoom(int x, int y, int m) { // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -static const char *get_entity_iso3(char *entity_iso3_result, int ccode) { - if (ccode < 0 || ccode >= MAX_MAPCODE_TERRITORY_CODE) { ccode = ccode_earth; } // solve bad args +static const char *get_entity_iso3(char *entity_iso3_result, int ccode) +{ + if (ccode < 0 || ccode >= MAX_MAPCODE_TERRITORY_CODE) + ccode = ccode_earth; // solve bad args + memcpy(entity_iso3_result, entity_iso + ccode * 4, 3); entity_iso3_result[3] = 0; + return entity_iso3_result; } static int disambiguate_str(const char *s, int len) // returns disambiguation >=1, or negative if error { + if (s[0] == 0 || s[1] == 0) + return -27; // solve bad args + + if (len != 2 && len != 3) + return -923; // solve bad args + const char *p = (len == 2 ? parents2 : parents3); - const char *f; char country[4]; - if (s[0] == 0 || s[1] == 0) { return -27; } // solve bad args - if (len != 2 && len != 3) { return -923; } // solve bad args memcpy(country, s, len); country[len] = 0; - { - char *t; - for (t = country; *t != 0; t++) { - *t = (char) toupper(*t); - } - } - f = strstr(p, country); - if (f == NULL) { - return -23; - } // unknown country + + for (char *t = country; *t != 0; t++) + *t = (char) toupper(*t); + + char *f = strstr(p, country); + if (f == NULL) + return -23; // unknown country + return 1 + (int) ((f - p) / (len + 1)); } // returns coode, or negative if invalid -static int ccode_of_iso3(const char *in_iso, int parentcode) { +static int ccode_of_iso3(const char *in_iso, int parentcode) +{ const char *aliases = ALIASES; char iso[4]; const char *s; @@ -178,27 +206,28 @@ static int ccode_of_iso3(const char *in_iso, int parentcode) { parentcode = disambiguate_str(in_iso, 2); hyphenated = (parentcode > 0); in_iso += 3; - } - else if (in_iso[3] == '-') { + } else if (in_iso[3] == '-') { parentcode = disambiguate_str(in_iso, 3); hyphenated = (parentcode > 0); in_iso += 4; } } - } else { return -23; } // solve bad args + } else { + return -23; // solve bad args + } // make (uppercased) copy of at most three characters iso[0] = (char) toupper(in_iso[0]); - if (iso[0]) { iso[1] = (char) toupper(in_iso[1]); } - if (iso[1]) { iso[2] = (char) toupper(in_iso[2]); } + if (iso[0]) + iso[1] = (char) toupper(in_iso[1]); + if (iso[1]) + iso[2] = (char) toupper(in_iso[2]); iso[3] = 0; - if (iso[2] == 0 || iso[2] == ' ') // 2-letter iso code? - { + if (iso[2] == 0 || iso[2] == ' ') { // 2-letter iso code? static char disambiguate_iso3[4] = {'1', '?', '?', 0}; // cache for disambiguation - if (parentcode > 0) { + if (parentcode > 0) disambiguate_iso3[0] = (char) ('0' + parentcode); - } disambiguate_iso3[1] = iso[0]; disambiguate_iso3[2] = iso[1]; @@ -221,9 +250,8 @@ static int ccode_of_iso3(const char *in_iso, int parentcode) { // find the FIRST disambiguation option, if any for (s = entity_iso - 1; ;) { s = strstr(s + 1, disambiguate_iso3 + 1); - if (s == NULL) { + if (s == NULL) break; - } if (s && s[-1] >= '1' && s[-1] <= '9') { s--; break; @@ -233,9 +261,8 @@ static int ccode_of_iso3(const char *in_iso, int parentcode) { // find first disambiguation option in aliases, if any for (s = aliases - 1; ;) { s = strstr(s + 1, disambiguate_iso3 + 1); - if (s == NULL) { + if (s == NULL) break; - } if (s && s[-1] >= '1' && s[-1] <= '9') { memcpy(iso, s + 3, 3); s = strstr(entity_iso, iso); // search disambiguated 2-letter iso @@ -244,21 +271,20 @@ static int ccode_of_iso3(const char *in_iso, int parentcode) { } } - if (s == NULL) { + if (s == NULL) return -26; - } } - } - else { + } else { s = strstr(entity_iso, iso); // search 3-letter iso if (s == NULL || hyphenated) { const char *a = aliases; while (a) { a = strstr(a, iso); // search in aliases - if (a && a[3] == '=' && (a[4] > '9' || a[4] == (char) (48 + parentcode) || parentcode < 0)) { - memcpy(iso, a + 4, 3); - a = NULL; - s = strstr(entity_iso, iso); + if (a && a[3] == '=' && (a[4] > '9' || + a[4] == (char) (48 + parentcode) || parentcode < 0)) { + memcpy(iso, a + 4, 3); + a = NULL; + s = strstr(entity_iso, iso); } else { if (a) { a++; @@ -266,9 +292,8 @@ static int ccode_of_iso3(const char *in_iso, int parentcode) { } } } - if (s == NULL) { + if (s == NULL) return -23; - } } // return result return (int) ((s - entity_iso) / 4); @@ -286,63 +311,65 @@ static void encodeExtension(char *result, int extrax4, int extray, int dividerx4 const encodeRec *enc) // append extra characters to result for more precision { #ifndef SUPPORT_HIGH_PRECISION // old integer-arithmetic version - if (extraDigits<0) extraDigits=0; else if (extraDigits>2) extraDigits=2; - while (extraDigits-->0) - { - int gx=((30*extrax4)/dividerx4); - int gy=((30*extray )/dividery ); - int column1=(gx/6); - int column2=(gx%6); - int row1=(gy/5); - int row2=(gy%5); - // add postfix: - char *s = result+strlen(result); - *s++ = '-'; - *s++ = encode_chars[ row1*5+column1 ]; - if (extraDigits-->0) - *s++ = encode_chars[ row2*6+column2 ]; - *s++ = 0; - } + if (extraDigits < 0) + extraDigits = 0; + else if (extraDigits > 2) + extraDigits = 2; + + while (extraDigits-- > 0) { + int gx = (30 * extrax4) / dividerx4; + int gy = (30 * extray) / dividery; + int column1 = gx / 6; + int column2 = gx % 6; + int row1 = gy / 5; + int row2 = gy % 5; + // add postfix: + char *s = result + strlen(result); + *s++ = '-'; + *s++ = encode_chars[row1 * 5 + column1]; + if (extraDigits-->0) + *s++ = encode_chars[row2 * 6 + column2]; + *s++ = 0; + } #else // new floating-point version char *s = result + strlen(result); double encx = (extrax4 + 4 * enc->fraclon) / (dividerx4); double ency = (extray + enc->fraclat * ydirection) / (dividery); - if (extraDigits < 0) { extraDigits = 0; } else if (extraDigits > MAX_PRECISION_DIGITS) { + if (extraDigits < 0) + extraDigits = 0; + else if (extraDigits > MAX_PRECISION_DIGITS) extraDigits = MAX_PRECISION_DIGITS; - } - if (extraDigits > 0) { + if (extraDigits > 0) *s++ = '-'; - } while (extraDigits-- > 0) { - int gx, gy, column1, column2, row1, row2; - encx *= 30; - gx = (int) encx; - if (gx < 0) { + int gx = (int) encx; + if (gx < 0) gx = 0; - } else if (gx > 29) { + else if (gx > 29) gx = 29; - } + ency *= 30; - gy = (int) ency; - if (gy < 0) { + int gy = (int) ency; + if (gy < 0) gy = 0; - } else if (gy > 29) { + else if (gy > 29) gy = 29; - } - column1 = (gx / 6); - column2 = (gx % 6); - row1 = (gy / 5); - row2 = (gy % 5); + + int column1 = gx / 6; + int column2 = gx % 6; + int row1 = gy / 5; + int row2 = gy % 5; + // add postfix: *s++ = encode_chars[row1 * 5 + column1]; - if (extraDigits-- > 0) { + if (extraDigits-- > 0) *s++ = encode_chars[row2 * 6 + column2]; - } *s = 0; + encx -= gx; ency -= gy; } @@ -352,65 +379,76 @@ static void encodeExtension(char *result, int extrax4, int extray, int dividerx4 #define decodeChar(c) decode_chars[(unsigned char)c] // force c to be in range of the index, between 0 and 255 // this routine takes the integer-arithmeteic decoding results (in millionths of degrees), adds any floating-point precision digits, and returns the result (still in millionths) -static int decodeExtension(decodeRec *dec, int dividerx4, int dividery, int ydirection) { +static int decodeExtension(decodeRec *dec, int dividerx4, int dividery, + int ydirection) +{ const char *extrapostfix = dec->extension; #ifndef SUPPORT_HIGH_PRECISION // old integer-arithmetic version - int extrax,extray; + int extrax, extray; + if (*extrapostfix) { - int column1,row1,column2,row2,c1,c2; - c1 = extrapostfix[0]; - c1 = decodeChar(c1); - if (c1<0) c1=0; else if (c1>29) c1=29; - row1 =(c1/5); column1 = (c1%5); - c2 = (extrapostfix[1]) ? extrapostfix[1] : 72; // 72='H'=code 15=(3+2*6) - c2 = decodeChar(c2); - if (c2<0) c2=0; else if (c2>29) c2=29; - row2 =(c2/6); column2 = (c2%6); - - extrax = ((column1*12 + 2*column2 + 1)*dividerx4+120)/240; - extray = ((row1*10 + 2*row2 + 1)*dividery +30)/ 60; - } - else { - extrax = (dividerx4/8); - extray = (dividery/2); + c1 = decodeChar(extrapostfix[0]); + if (c1 < 0) + c1 = 0; + else if (c1 > 29) + c1 = 29; + int row1 =(c1 / 5); + int column1 = (c1 % 5); + + c2 = decodeChar(extrapostfix[1]) ? extrapostfix[1] : 72); // 72='H'=code 15=(3+2*6) + if (c2 < 0) + c2 = 0; + else if (c2 > 29) + c2 = 29; + int row2 =(c2 / 6); + int column2 = (c2 % 6); + + extrax = ((column1 * 12 + 2 * column2 + 1) * dividerx4 + 120) / 240; + extray = ((row1 * 10 + 2 * row2 + 1) * dividery +30) / 60; + } else { + extrax = dividerx4 / 8; + extray = dividery / 2; } extray *= ydirection; dec->lon32 = extrax + dec->lon32; dec->lat32 = extray + dec->lat32; #else // new floating-point version - double dividerx = dividerx4 / 4.0, processor = 1.0; + double dividerx = dividerx4 / 4.0; + double processor = 1.0; dec->lon = 0; dec->lat = 0; while (*extrapostfix) { - int column1, row1, column2, row2; + int c1 = decodeChar(*extrapostfix++); + if (c1 < 0 || c1 == 30) + return -1; // illegal extension character + + int row1 = c1 / 5; + int column1 = c1 % 5; + int column2, row2; double halfcolumn = 0; - int c1 = *extrapostfix++; - c1 = decodeChar(c1); - if (c1 < 0 || c1 == 30) { return -1; } // illegal extension character - row1 = (c1 / 5); - column1 = (c1 % 5); if (*extrapostfix) { int c2 = decodeChar(*extrapostfix++); - if (c2 < 0 || c2 == 30) { return -1; } // illegal extension character - row2 = (c2 / 6); - column2 = (c2 % 6); - } - else { + if (c2 < 0 || c2 == 30) { + return -1; // illegal extension character + } + row2 = c2 / 6; + column2 = c2 % 6; + } else { row2 = 2; halfcolumn = 0.5; column2 = 3; } processor *= 30; - dec->lon += ((column1 * 6 + column2)) / processor; - dec->lat += ((row1 * 5 + row2 - halfcolumn)) / processor; + dec->lon += (column1 * 6 + column2) / processor; + dec->lat += (row1 * 5 + row2 - halfcolumn) / processor; } - dec->lon += (0.5 / processor); - dec->lat += (0.5 / processor); + dec->lon += 0.5 / processor; + dec->lat += 0.5 / processor; dec->lon *= dividerx; - dec->lat *= (dividery * ydirection); + dec->lat *= dividery * ydirection; dec->lon += dec->lon32; dec->lat += dec->lat32; @@ -423,7 +461,6 @@ static int decodeExtension(decodeRec *dec, int dividerx4, int dividery, int ydir } - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // LOWEST-LEVEL BASE31 ENCODING/DECODING @@ -431,7 +468,8 @@ static int decodeExtension(decodeRec *dec, int dividerx4, int dividery, int ydir //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // encode 'value' into result[nrchars] -static void encodeBase31(char *result, int value, int nrchars) { +static void encodeBase31(char *result, int value, int nrchars) +{ result[nrchars] = 0; // zero-terminate! while (nrchars-- > 0) { result[nrchars] = encode_chars[value % 31]; @@ -440,11 +478,12 @@ static void encodeBase31(char *result, int value, int nrchars) { } // decode 'code' until either a dot or an end-of-string is encountered -static int decodeBase31(const char *code) { +static int decodeBase31(const char *code) +{ int value = 0; - while (*code != '.' && *code != 0) { + while (*code != '.' && *code != 0) value = value * 31 + decodeChar(*code++); - } + return value; } @@ -455,30 +494,27 @@ static int decodeBase31(const char *code) { // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -static void encode_triple(char *result, int difx, int dify) { - if (dify < 4 * 34) // first 4(x34) rows of 6(x28) wide - { +static void encode_triple(char *result, int difx, int dify) +{ + if (dify < 4 * 34) { // first 4(x34) rows of 6(x28) wide encodeBase31(result, ((difx / 28) + 6 * (dify / 34)), 1); encodeBase31(result + 1, ((difx % 28) * 34 + (dify % 34)), 2); - } - else // bottom row - { + } else { // bottom row encodeBase31(result, (difx / 24) + 24, 1); encodeBase31(result + 1, (difx % 24) * 40 + (dify - 136), 2); } } // encode_triple -static void decode_triple(const char *result, int *difx, int *dify) { +static void decode_triple(const char *result, int *difx, int *dify) +{ // decode the first character int c1 = decodeChar(*result++); if (c1 < 24) { int m = decodeBase31(result); *difx = (c1 % 6) * 28 + (m / 34); *dify = (c1 / 6) * 34 + (m % 34); - } - else // bottom row - { + } else { // bottom row int x = decodeBase31(result); *dify = (x % 40) + 136; *difx = (x / 40) + 24 * (c1 - 24); @@ -486,35 +522,33 @@ static void decode_triple(const char *result, int *difx, int *dify) { } // decode_triple - - - - - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // SECOND-LEVEL ECCODING/DECODING : GRID // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -static int encodeSixWide(int x, int y, int width, int height) { - int v; +static int encodeSixWide(int x, int y, int width, int height) +{ int D = 6; int col = x / 6; int maxcol = (width - 4) / 6; + if (col >= maxcol) { col = maxcol; D = width - maxcol * 6; } - v = (height * 6 * col) + (height - 1 - y) * D + (x - col * 6); - return v; + return (height * 6 * col) + (height - 1 - y) * D + (x - col * 6); } -static void decodeSixWide(int v, int width, int height, int *x, int *y) { + +static void decodeSixWide(int v, int width, int height, int *x, int *y) +{ int w; int D = 6; int col = v / (height * 6); int maxcol = (width - 4) / 6; + if (col >= maxcol) { col = maxcol; D = width - maxcol * 6; @@ -527,13 +561,16 @@ static void decodeSixWide(int v, int width, int height, int *x, int *y) { // decodes dec->mapcode in context of territory rectangle m -static int decodeGrid(decodeRec *dec, int m, int hasHeaderLetter) { +static int decodeGrid(decodeRec *dec, int m, int hasHeaderLetter) +{ const char *input = (hasHeaderLetter ? dec->mapcode + 1 : dec->mapcode); int codexlen = (int) (strlen(input) - 1); int prelen = (int) (strchr(input, '.') - input); char result[MAX_PROPER_MAPCODE_LEN + 1]; - if (codexlen > MAX_PROPER_MAPCODE_LEN) { return -109; } + if (codexlen > MAX_PROPER_MAPCODE_LEN) + return -109; + strcpy(result, input); if (prelen == 1 && codexlen == 5) { result[1] = result[2]; @@ -541,391 +578,340 @@ static int decodeGrid(decodeRec *dec, int m, int hasHeaderLetter) { prelen++; } - { - int postlen = codexlen - prelen; + int postlen = codexlen - prelen; + int divx; + int divy = smartDiv(m); + if (divy == 1) { + divx = xside[prelen]; + divy = yside[prelen]; + } else { + divx = (nc[prelen] / divy); + } - int divx, divy; + if (prelen == 4 && divx == xside[4] && divy == yside[4]) { + char t = result[1]; + result[1] = result[2]; + result[2] = t; + } - divy = smartDiv(m); - if (divy == 1) { - divx = xside[prelen]; - divy = yside[prelen]; - } - else { - int pw = nc[prelen]; - divx = (pw / divy); - } + int relx = 0, rely = 0, v = 0; + if (prelen <= MAXFITLONG) { + v = decodeBase31(result); - if (prelen == 4 && divx == xside[4] && divy == yside[4]) { - char t = result[1]; - result[1] = result[2]; - result[2] = t; + if (divx != divy && prelen > 2) { // D==6 special grid, useful when prefix is 3 or more, and not a nice 961x961 + decodeSixWide(v, divx, divy, &relx, &rely); // DECODE + } else { + relx = (v / divy); + rely = divy - 1 - (v % divy); } + } - { - int relx = 0, rely = 0, v = 0; - - if (prelen <= MAXFITLONG) { - v = decodeBase31(result); - - if (divx != divy && - prelen > 2) // D==6 special grid, useful when prefix is 3 or more, and not a nice 961x961 - { // DECODE - decodeSixWide(v, divx, divy, &relx, &rely); - } - else { - relx = (v / divy); - rely = divy - 1 - (v % divy); - } - - } - - { - const mminforec *b = boundaries(m); - int ygridsize = (b->maxy - b->miny + divy - 1) / divy; // lonlat per cell - int xgridsize = (b->maxx - b->minx + divx - 1) / divx; // lonlat per cell - - if (relx < 0 || rely < 0 || relx >= divx || rely >= divy) { - return -111; - } - - // and then encodde relative to THE CORNER of this cell - rely = b->miny + (rely * ygridsize); - relx = b->minx + (relx * xgridsize); - - { - int xp = xside[postlen]; - int dividerx = ((((xgridsize)) + xp - 1) / xp); - int yp = yside[postlen]; - int dividery = ((((ygridsize)) + yp - 1) / yp); - // decoderelative + const mminforec *b = boundaries(m); + int ygridsize = (b->maxy - b->miny + divy - 1) / divy; // lonlat per cell + int xgridsize = (b->maxx - b->minx + divx - 1) / divx; // lonlat per cell - { - char *r = result + prelen + 1; - int difx, dify; + if (relx < 0 || rely < 0 || relx >= divx || rely >= divy) + return -111; - if (postlen == 3) // decode special - { - decode_triple(r, &difx, &dify); - } - else { - int v2; - if (postlen == 4) { - char t = r[1]; - r[1] = r[2]; - r[2] = t; - } // swap - v2 = decodeBase31(r); - difx = (v2 / yp); - dify = (v2 % yp); - if (postlen == 4) { - char t = r[1]; - r[1] = r[2]; - r[2] = t; - } // swap back - } + // and then encode relative to THE CORNER of this cell + rely = b->miny + (rely * ygridsize); + relx = b->minx + (relx * xgridsize); - // reverse y-direction - dify = yp - 1 - dify; + int xp = xside[postlen]; + int dividerx = (((xgridsize)) + xp - 1) / xp; + int yp = yside[postlen]; + int dividery = (((ygridsize)) + yp - 1) / yp; - dec->lon32 = relx + (difx * dividerx); - dec->lat32 = rely + (dify * dividery); - return decodeExtension(dec, dividerx << 2, dividery, 1); // grid - } // decoderelative + // decoderelative + char *r = result + prelen + 1; + int difx, dify; - } - } - } + if (postlen == 3) { // decode special + decode_triple(r, &difx, &dify); + } else { + if (postlen == 4) { + char t = r[1]; + r[1] = r[2]; + r[2] = t; + } // swap + int v2 = decodeBase31(r); + difx = (v2 / yp); + dify = (v2 % yp); + if (postlen == 4) { + char t = r[1]; + r[1] = r[2]; + r[2] = t; + } // swap back } + // reverse y-direction + dify = yp - 1 - dify; + + dec->lon32 = relx + (difx * dividerx); + dec->lat32 = rely + (dify * dividery); + return decodeExtension(dec, dividerx << 2, dividery, 1); // grid + // decoderelative } -static void encodeGrid(char *result, const encodeRec *enc, int const m, int extraDigits, char headerLetter) { +static void encodeGrid(char *result, const encodeRec *enc, int const m, + int extraDigits, char headerLetter) +{ int y = enc->lat32, x = enc->lon32; const mminforec *b = boundaries(m); int orgcodex = coDex(m); int codexm = orgcodex; - if (codexm == 21) { codexm = 22; } - if (codexm == 14) { codexm = 23; } - - *result = 0; - if (headerLetter) { result++; } + if (codexm == 21) + codexm = 22; - { // encode - int divx, divy; - int prelen = codexm / 10; - int postlen = codexm % 10; + if (codexm == 14) + codexm = 23; - divy = smartDiv(m); - if (divy == 1) { - divx = xside[prelen]; - divy = yside[prelen]; - } - else { - int pw = nc[prelen]; - divx = (pw / divy); - } - - { // grid - int ygridsize = (b->maxy - b->miny + divy - 1) / divy; - int xgridsize = (b->maxx - b->minx + divx - 1) / divx; - int rely = y - b->miny; - int relx = x - b->minx; - - if (relx < 0) { - relx += 360000000; - x += 360000000; - } - else if (relx >= 360000000) // 1.32 fix FIJI edge case - { - relx -= 360000000; - x -= 360000000; - } - - rely /= ygridsize; - relx /= xgridsize; - - if (relx >= divx || rely >= divy) { return; } - - { // prefix - int v; - if (divx != divy && prelen > 2) { - v = encodeSixWide(relx, rely, divx, divy); - } else { - v = relx * divy + (divy - 1 - rely); - } - encodeBase31(result, v, prelen); - } // prefix + *result = 0; + if (headerLetter) + result++; - if (prelen == 4 && divx == xside[4] && divy == yside[4]) { - char t = result[1]; - result[1] = result[2]; - result[2] = t; - } + int prelen = codexm / 10; + int postlen = codexm % 10; - rely = b->miny + (rely * ygridsize); - relx = b->minx + (relx * xgridsize); + int divx; + int divy = smartDiv(m); + if (divy == 1) { + divx = xside[prelen]; + divy = yside[prelen]; + } else { + divx = (nc[prelen] / divy); + } - { // postfix - int dividery = ((((ygridsize)) + yside[postlen] - 1) / yside[postlen]); - int dividerx = ((((xgridsize)) + xside[postlen] - 1) / xside[postlen]); - int extrax, extray; + // grid + int ygridsize = (b->maxy - b->miny + divy - 1) / divy; + int xgridsize = (b->maxx - b->minx + divx - 1) / divx; + int rely = y - b->miny; + int relx = x - b->minx; + + if (relx < 0) { + relx += 360000000; + x += 360000000; + } else if (relx >= 360000000) { // 1.32 fix FIJI edge case + relx -= 360000000; + x -= 360000000; + } + rely /= ygridsize; + relx /= xgridsize; - { - char *resultptr = result + prelen; + if (relx >= divx || rely >= divy) + return; + // prefix + int v; + if (divx != divy && prelen > 2) + v = encodeSixWide(relx, rely, divx, divy); + else + v = relx * divy + (divy - 1 - rely); + encodeBase31(result, v, prelen); + + if (prelen == 4 && divx == xside[4] && divy == yside[4]) { + char t = result[1]; + result[1] = result[2]; + result[2] = t; + } - int difx = x - relx; - int dify = y - rely; + rely = b->miny + (rely * ygridsize); + relx = b->minx + (relx * xgridsize); - *resultptr++ = '.'; + // postfix + int dividery = (((ygridsize)) + yside[postlen] - 1) / yside[postlen]; + int dividerx = (((xgridsize)) + xside[postlen] - 1) / xside[postlen]; - extrax = difx % dividerx; - extray = dify % dividery; - difx /= dividerx; - dify /= dividery; + char *resultptr = result + prelen; + *resultptr++ = '.'; + int difx = x - relx; + int dify = y - rely; + int extrax = difx % dividerx; + int extray = dify % dividery; + difx /= dividerx; + dify /= dividery; - // reverse y-direction - dify = yside[postlen] - 1 - dify; + // reverse y-direction + dify = yside[postlen] - 1 - dify; - if (postlen == 3) // encode special - { - encode_triple(resultptr, difx, dify); - } - else { - encodeBase31(resultptr, (difx) * yside[postlen] + dify, postlen); - // swap 4-int codes for readability - if (postlen == 4) { - char t = resultptr[1]; - resultptr[1] = resultptr[2]; - resultptr[2] = t; - } - } - } + if (postlen == 3) { // encode special + encode_triple(resultptr, difx, dify); + } else { + encodeBase31(resultptr, (difx) * yside[postlen] + dify, postlen); + // swap 4-int codes for readability + if (postlen == 4) { + char t = resultptr[1]; + resultptr[1] = resultptr[2]; + resultptr[2] = t; + } + } - if (orgcodex == 14) { - result[2] = result[1]; - result[1] = '.'; - } + if (orgcodex == 14) { + result[2] = result[1]; + result[1] = '.'; + } - encodeExtension(result, extrax << 2, extray, dividerx << 2, dividery, extraDigits, 1, enc); // grid - if (headerLetter) { - result--; - *result = headerLetter; - } - } // postfix - } // grid - } // encode + encodeExtension(result, extrax << 2, extray, dividerx << 2, dividery, extraDigits, 1, enc); // grid + if (headerLetter) { + result--; + *result = headerLetter; + } } // find first territory rectangle of the same type as m -static int firstNamelessRecord(int m, int firstcode) { +static int firstNamelessRecord(int m, int firstcode) +{ int i = m; int codexm = coDex(m); - while (i >= firstcode && coDex(i) == codexm && isNameless(i)) { i--; } + + while (i >= firstcode && coDex(i) == codexm && isNameless(i)) + i--; + return (i + 1); } + // count all territory rectangles of the same type as m -static int countNamelessRecords(int m, int firstcode) { +static int countNamelessRecords(int m, int firstcode) +{ int i = firstNamelessRecord(m, firstcode); int codexm = coDex(m); - while (coDex(m) == codexm) { m++; } + + while (coDex(m) == codexm) + m++; + return (m - i); } // decodes dec->mapcode in context of territory rectangle m, territory dec->context // Returns negative in case of error -static int decodeNameless(decodeRec *dec, int m) { +static int decodeNameless(decodeRec *dec, int m) +{ int A, F; char input[8]; int codexm = coDex(m); int dc = (codexm != 22) ? 2 : 3; int codexlen = (int) (strlen(dec->mapcode) - 1); - if (codexlen != 4 && codexlen != 5) { - return -2; - } // solve bad args + if (codexlen != 4 && codexlen != 5) + return -2; // solve bad args // copy without dot strcpy(input, dec->mapcode); strcpy(input + dc, dec->mapcode + dc + 1); - A = countNamelessRecords(m, firstrec(dec->context)); F = firstNamelessRecord(m, firstrec(dec->context)); - { - int p = 31 / A; - int r = 31 % A; - int v = 0; - int SIDE; - int swapletters = 0; - int xSIDE; - int X; - const mminforec *b; - - // make copy of input, so we can swap around letters during the decoding - char result[32]; - strcpy(result, input); - - // now determine X = index of first area, and SIDE - if (codexm != 21 && A <= 31) { - int offset = decodeChar(*result); - - if (offset < r * (p + 1)) { - X = offset / (p + 1); - } - else { - swapletters = (p == 1 && codexm == 22); - X = r + (offset - (r * (p + 1))) / p; - } - } - else if (codexm != 21 && A < 62) { + int p = 31 / A; + int r = 31 % A; + int v = 0; + int swapletters = 0; + int X; - X = decodeChar(*result); - if (X < (62 - A)) { - swapletters = (codexm == 22); - } - else { - X = X + (X - (62 - A)); - } - } - else // code==21 || A>=62 - { - int BASEPOWER = (codexm == 21) ? 961 * 961 : 961 * 961 * 31; - int BASEPOWERA = (BASEPOWER / A); + // make copy of input, so we can swap around letters during the decoding + char result[32]; + strcpy(result, input); - if (A == 62) { BASEPOWERA++; } else { BASEPOWERA = 961 * (BASEPOWERA / 961); } + // now determine X = index of first area, and SIDE + if (codexm != 21 && A <= 31) { + int offset = decodeChar(*result); - v = decodeBase31(result); - X = (v / BASEPOWERA); - v %= BASEPOWERA; + if (offset < r * (p + 1)) { + X = offset / (p + 1); + } else { + swapletters = (p == 1 && codexm == 22); + X = r + (offset - (r * (p + 1))) / p; } + } else if (codexm != 21 && A < 62) { + X = decodeChar(*result); + if (X < (62 - A)) { + swapletters = (codexm == 22); + } else { + X = X + (X - (62 - A)); + } + } else { // code==21 || A>=62 + int BASEPOWER = (codexm == 21) ? 961 * 961 : 961 * 961 * 31; + int BASEPOWERA = (BASEPOWER / A); + + if (A == 62) + BASEPOWERA++; + else + BASEPOWERA = 961 * (BASEPOWERA / 961); + + v = decodeBase31(result); + X = (v / BASEPOWERA); + v %= BASEPOWERA; + } - - if (swapletters) { - if (!isSpecialShape22(F + X)) { - char t = result[codexlen - 3]; - result[codexlen - 3] = result[codexlen - 2]; - result[codexlen - 2] = t; - } + if (swapletters) { + if (!isSpecialShape22(F + X)) { + char t = result[codexlen - 3]; + result[codexlen - 3] = result[codexlen - 2]; + result[codexlen - 2] = t; } + } - if (codexm != 21 && A <= 31) { - v = decodeBase31(result); - if (X > 0) { - v -= (X * p + (X < r ? X : r)) * (961 * 961); - } + if (codexm != 21 && A <= 31) { + v = decodeBase31(result); + if (X > 0) { + v -= (X * p + (X < r ? X : r)) * (961 * 961); } - else if (codexm != 21 && A < 62) { - v = decodeBase31(result + 1); - if (X >= (62 - A)) { - if (v >= (16 * 961 * 31)) { - v -= (16 * 961 * 31); - X++; - } + } else if (codexm != 21 && A < 62) { + v = decodeBase31(result + 1); + if (X >= (62 - A)) { + if (v >= (16 * 961 * 31)) { + v -= (16 * 961 * 31); + X++; } } + } - m = (F + X); - - xSIDE = SIDE = smartDiv(m); - - b = boundaries(m); - if (isSpecialShape22(m)) { - xSIDE *= SIDE; - SIDE = 1 + ((b->maxy - b->miny) / 90); // side purely on y range - xSIDE = xSIDE / SIDE; - } - - // decode - { - int dx, dy; - - if (isSpecialShape22(m)) { - decodeSixWide(v, xSIDE, SIDE, &dx, &dy); - dy = SIDE - 1 - dy; - } - else { - dy = v % SIDE; - dx = v / SIDE; - } + m = (F + X); + int SIDE = smartDiv(m); + int xSIDE = SIDE; + const mminforec *b = boundaries(m); + if (isSpecialShape22(m)) { + xSIDE *= SIDE; + SIDE = 1 + ((b->maxy - b->miny) / 90); // side purely on y range + xSIDE = xSIDE / SIDE; + } + // decode + int dx, dy; + if (isSpecialShape22(m)) { + decodeSixWide(v, xSIDE, SIDE, &dx, &dy); + dy = SIDE - 1 - dy; + } else { + dy = v % SIDE; + dx = v / SIDE; + } - if (dx >= xSIDE) { - return -123; - } + if (dx >= xSIDE) + return -123; - { - int dividerx4 = xDivider4(b->miny, b->maxy); // *** note: dividerx4 is 4 times too large! - int dividery = 90; - int err; + int dividerx4 = xDivider4(b->miny, b->maxy); // *** note: dividerx4 is 4 times too large! + int dividery = 90; - dec->lon32 = b->minx + ((dx * dividerx4) / - 4); // *** note: FIRST multiply, then divide... more precise, larger rects - dec->lat32 = b->maxy - (dy * dividery); - err = decodeExtension(dec, dividerx4, dividery, -1); // nameless + dec->lon32 = b->minx + ((dx * dividerx4) / 4); // *** note: FIRST multiply, then divide... more precise, larger rects + dec->lat32 = b->maxy - (dy * dividery); + int err = decodeExtension(dec, dividerx4, dividery, -1); // nameless #ifdef SUPPORT_HIGH_PRECISION - dec->lon += ((dx * dividerx4) % 4) / 4.0; + dec->lon += ((dx * dividerx4) % 4) / 4.0; #endif - return err; - } - } - } + return err; } - -static void repack_if_alldigits(char *input, int aonly) { - char *s = input; +static void repack_if_alldigits(char *input, int aonly) +{ + char *e, *s = input; int alldigits = 1; // assume all digits - char *e; char *dotpos = NULL; for (e = s; *e != 0 && *e != '-'; e++) { @@ -940,18 +926,13 @@ static void repack_if_alldigits(char *input, int aonly) { } e--; s = e - 1; - if (alldigits && dotpos && - s > dotpos) // e is last char, s is one before, both are beyond dot, all characters are digits - { - if (aonly) // v1.50 - encode only using the letter A - { + if (alldigits && dotpos && s > dotpos) { // e is last char, s is one before, both are beyond dot, all characters are digits + if (aonly) { // v1.50 - encode only using the letter A int v = ((*input) - '0') * 100 + ((*s) - '0') * 10 + ((*e) - '0'); *input = 'A'; *s = encode_chars[v / 32]; *e = encode_chars[v % 32]; - } - else // encode using A,E,U - { + } else { // encode using A,E,U int v = ((*s) - '0') * 10 + ((*e) - '0'); *s = encode_chars[(v / 34) + 31]; *e = encode_chars[v % 34]; @@ -959,26 +940,26 @@ static void repack_if_alldigits(char *input, int aonly) { } } -static int unpack_if_alldigits( - char *input) // returns 1 if unpacked, 0 if left unchanged, negative if unchanged and an error was detected +static int unpack_if_alldigits(char *input) // returns 1 if unpacked, 0 if left unchanged, negative if unchanged and an error was detected { // rewrite all-digit codes char *s = input; char *dotpos = NULL; + int aonly = (*s == 'A' || *s == 'a'); - if (aonly) { s++; } //*** v1.50 + if (aonly) + s++; //*** v1.50 + for (; *s != 0 && s[2] != 0 && s[2] != '-'; s++) { - if (*s == '-') { + if (*s == '-') break; - } else if (*s == '.' && !dotpos) { + else if (*s == '.' && !dotpos) dotpos = s; - } else if (decodeChar(*s) < 0 || decodeChar(*s) > 9) { - return 0; - } // nondigit, so stop + else if (decodeChar(*s) < 0 || decodeChar(*s) > 9) + return 0; // nondigit, so stop } if (dotpos) { - if (aonly) // v1.50 encoded only with A's - { + if (aonly) { // v1.50 encoded only with A's int v = (s[0] == 'A' || s[0] == 'a' ? 31 : decodeChar(s[0])) * 32 + (s[1] == 'A' || s[1] == 'a' ? 31 : decodeChar(s[1])); *input = (char) ('0' + (v / 100)); @@ -987,25 +968,27 @@ static int unpack_if_alldigits( return 1; } // v1.50 - if (*s == 'a' || *s == 'e' || *s == 'u' || *s == 'A' || *s == 'E' || - *s == 'U') // thus, all digits, s[2]=0, after dot - { + if (*s == 'a' || *s == 'e' || *s == 'u' || + *s == 'A' || *s == 'E' || *s == 'U') { // thus, all digits, s[2]=0, after dot + char *e = s + 1; // s is vowel, e is lastchar int v = 0; - if (*s == 'e' || *s == 'E') { + if (*s == 'e' || *s == 'E') v = 34; - } else if (*s == 'u' || *s == 'U') { v = 68; } + else if (*s == 'u' || *s == 'U') + v = 68; - if (*e == 'a' || *e == 'A') { + if (*e == 'a' || *e == 'A') v += 31; - } else if (*e == 'e' || *e == 'E') { + else if (*e == 'e' || *e == 'E') v += 32; - } else if (*e == 'u' || *e == 'U') { + else if (*e == 'u' || *e == 'U') v += 33; - } else if (decodeChar(*e) < 0) { + else if (decodeChar(*e) < 0) return -9; // invalid last character! - } else { v += decodeChar(*e); } + else + v += decodeChar(*e); if (v < 100) { *s = encode_chars[(unsigned int) v / 10]; @@ -1018,146 +1001,120 @@ static int unpack_if_alldigits( } -/* -{ -} -*/ - // returns -1 (error), or m (also returns *result!=0 in case of success) -static int encodeNameless(char *result, const encodeRec *enc, int input_ctry, int extraDigits, int m) { +static int encodeNameless(char *result, const encodeRec *enc, + int input_ctry, int extraDigits, int m) +{ // determine how many nameless records there are (A), and which one is this (X)... int y = enc->lat32, x = enc->lon32; int A = countNamelessRecords(m, firstrec(input_ctry)); int X = m - firstNamelessRecord(m, firstrec(input_ctry)); *result = 0; + int p = 31 / A; + int r = 31 % A; // the first r items are p+1 - { - int p = 31 / A; - int r = 31 % A; // the first r items are p+1 - int codexm = coDex(m); - int codexlen = (codexm / 10) + (codexm % 10); - // determine side of square around centre - int SIDE; - - int storage_offset; - const mminforec *b; - - int xSIDE, orgSIDE; - - - if (codexm != 21 && A <= 31) { - storage_offset = (X * p + (X < r ? X : r)) * (961 * 961); // p=4,r=3: offset(X)={0,5,10,15,19,23,27}-31 - } - else if (codexm != 21 && A < 62) { - if (X < (62 - A)) { - storage_offset = X * (961 * 961); - } - else { - storage_offset = (62 - A + ((X - 62 + A) / 2)) * (961 * 961); - if ((X + A) & 1) { - storage_offset += (16 * 961 * 31); - } - } - } - else { - int BASEPOWER = (codexm == 21) ? 961 * 961 : 961 * 961 * 31; - int BASEPOWERA = (BASEPOWER / A); - if (A == 62) { - BASEPOWERA++; - } else { - BASEPOWERA = (961) * (BASEPOWERA / 961); - } - - storage_offset = X * BASEPOWERA; + int codexm = coDex(m); + int codexlen = (codexm / 10) + (codexm % 10); + int storage_offset; + if (codexm != 21 && A <= 31) { + storage_offset = (X * p + (X < r ? X : r)) * (961 * 961); // p=4,r=3: offset(X)={0,5,10,15,19,23,27}-31 + } else if (codexm != 21 && A < 62) { + if (X < (62 - A)) { + storage_offset = X * (961 * 961); + } else { + storage_offset = (62 - A + ((X - 62 + A) / 2)) * (961 * 961); + if ((X + A) & 1) + storage_offset += (16 * 961 * 31); } - SIDE = smartDiv(m); - + } else { + int BASEPOWER = (codexm == 21) ? 961 * 961 : 961 * 961 * 31; + int BASEPOWERA = (BASEPOWER / A); + if (A == 62) + BASEPOWERA++; + else + BASEPOWERA = (961) * (BASEPOWERA / 961); + storage_offset = X * BASEPOWERA; + } - b = boundaries(m); - orgSIDE = xSIDE = SIDE; - if (isSpecialShape22(m)) // - keep the existing rectangle! - { - SIDE = 1 + ((b->maxy - b->miny) / 90); // new side, based purely on y-distance - xSIDE = (orgSIDE * orgSIDE) / SIDE; - } + // determine side of square around centre + int SIDE = smartDiv(m); + int xSIDE = SIDE; + int orgSIDE = SIDE; + const mminforec *b = boundaries(m); + if (isSpecialShape22(m)) { // - keep the existing rectangle! + SIDE = 1 + ((b->maxy - b->miny) / 90); // new side, based purely on y-distance + xSIDE = (orgSIDE * orgSIDE) / SIDE; + } - if (fitsInside(x, y, m)) { - int v = storage_offset; + if (fitsInside(x, y, m)) { + int v = storage_offset; - int dividerx4 = xDivider4(b->miny, b->maxy); // *** note: dividerx4 is 4 times too large! + int dividerx4 = xDivider4(b->miny, b->maxy); // *** note: dividerx4 is 4 times too large! #ifdef SUPPORT_HIGH_PRECISION // precise encoding: take fraction into account! - int xFracture = (int) (4 * enc->fraclon); + int xFracture = (int) (4 * enc->fraclon); #else - int xFracture = 0; + int xFracture = 0; #endif - int dx = (4 * (x - b->minx) + xFracture) / dividerx4; // like div, but with floating point value - int extrax4 = (x - b->minx) * 4 - dx * dividerx4; // like modulus, but with floating point value + int dx = (4 * (x - b->minx) + xFracture) / dividerx4; // like div, but with floating point value + int extrax4 = (x - b->minx) * 4 - dx * dividerx4; // like modulus, but with floating point value - int dividery = 90; - int dy = (b->maxy - y) / dividery; // between 0 and SIDE-1 - int extray = (b->maxy - y) % dividery; + int dividery = 90; + int dy = (b->maxy - y) / dividery; // between 0 and SIDE-1 + int extray = (b->maxy - y) % dividery; #ifdef SUPPORT_HIGH_PRECISION // precise encoding: check if fraction takes this out of range - if (extray == 0 && enc->fraclat > 0) { - if (dy == 0) { - return -1; - } // fraction takes this coordinate out of range - dy--; - extray += dividery; + if (extray == 0 && enc->fraclat > 0) { + if (dy == 0) + return -1; // fraction takes this coordinate out of range - } + dy--; + extray += dividery; + } #endif - - if (isSpecialShape22(m)) { - v += encodeSixWide(dx, SIDE - 1 - dy, xSIDE, SIDE); - } - else { - v += (dx * SIDE + dy); - } - - encodeBase31(result, v, codexlen + 1); // nameless - { - int dotp = codexlen; - if (codexm == 13) { - dotp--; - } - memmove(result + dotp, result + dotp - 1, 4); - result[dotp - 1] = '.'; - } - - if (!isSpecialShape22(m)) { - if (codexm == 22 && A < 62 && orgSIDE == 961) { - char t = result[codexlen - 2]; - result[codexlen - 2] = result[codexlen]; - result[codexlen] = t; - } + if (isSpecialShape22(m)) + v += encodeSixWide(dx, SIDE - 1 - dy, xSIDE, SIDE); + else + v += (dx * SIDE + dy); + + encodeBase31(result, v, codexlen + 1); // nameless + int dotp = codexlen; + if (codexm == 13) + dotp--; + + memmove(result + dotp, result + dotp - 1, 4); + result[dotp - 1] = '.'; + + if (!isSpecialShape22(m)) { + if (codexm == 22 && A < 62 && orgSIDE == 961) { + char t = result[codexlen - 2]; + result[codexlen - 2] = result[codexlen]; + result[codexlen] = t; } + } - encodeExtension(result, extrax4, extray, dividerx4, dividery, extraDigits, -1, enc); // nameless + encodeExtension(result, extrax4, extray, dividerx4, dividery, extraDigits, -1, enc); // nameless - return m; + return m; - } // in range - } + } // in range return -1; } // decodes dec->mapcode in context of territory rectangle m -static int decodeAutoHeader(decodeRec *dec, int m) { +static int decodeAutoHeader(decodeRec *dec, int m) +{ const char *input = dec->mapcode; int codexm = coDex(m); char *dot = strchr(input, '.'); int STORAGE_START = 0; - int value; - if (dot == NULL) { + if (dot == NULL) return -201; - } - value = decodeBase31(input); // decode top + int value = decodeBase31(input); // decode top value *= (961 * 31); for (; coDex(m) == codexm && recType(m) > 1; m++) { @@ -1185,22 +1142,16 @@ static int decodeAutoHeader(decodeRec *dec, int m) { value -= STORAGE_START; value /= (961 * 31); - { - int difx, dify; - decode_triple(dot + 1, &difx, &dify); // decode bottom 3 chars - { - int vx = (value / (H / 176)) * 168 + difx; // is vx/168 - int vy = (value % (H / 176)) * 176 + dify; // is vy/176 - - dec->lat32 = b->maxy - vy * dividery; - dec->lon32 = b->minx + vx * dividerx; - if (dec->lon32 < b->minx || dec->lon32 >= b->maxx || dec->lat32 < b->miny || - dec->lat32 > b->maxy) // *** CAREFUL! do this test BEFORE adding remainder... - { - return -122; // invalid code - } - } - } + int difx, dify; + decode_triple(dot + 1, &difx, &dify); // decode bottom 3 chars + int vx = (value / (H / 176)) * 168 + difx; // is vx/168 + int vy = (value % (H / 176)) * 176 + dify; // is vy/176 + + dec->lat32 = b->maxy - vy * dividery; + dec->lon32 = b->minx + vx * dividerx; + if (dec->lon32 < b->minx || dec->lon32 >= b->maxx || dec->lat32 < b->miny || + dec->lat32 > b->maxy) // *** CAREFUL! do this test BEFORE adding remainder... + return -122; // invalid code return decodeExtension(dec, dividerx << 2, dividery, -1); // autoheader decode } @@ -1210,7 +1161,8 @@ static int decodeAutoHeader(decodeRec *dec, int m) { } // encode in m (know to fit) -static int encodeAutoHeader(char *result, const encodeRec *enc, int m, int extraDigits) { +static int encodeAutoHeader(char *result, const encodeRec *enc, int m, int extraDigits) +{ int i; int STORAGE_START = 0; int y = enc->lat32, x = enc->lon32; @@ -1218,9 +1170,8 @@ static int encodeAutoHeader(char *result, const encodeRec *enc, int m, int extra // search back to first of the group int firstindex = m; int codexm = coDex(m); - while (recType(firstindex - 1) > 1 && coDex(firstindex - 1) == codexm) { + while (recType(firstindex - 1) > 1 && coDex(firstindex - 1) == codexm) firstindex--; - } for (i = firstindex; coDex(i) == codexm; i++) { int W, H, xdiv, product; @@ -1263,7 +1214,6 @@ static int encodeAutoHeader(char *result, const encodeRec *enc, int m, int extra extray += dividery; } #endif - value += (vy / 176); // PIPELETTER ENCODE @@ -1274,7 +1224,6 @@ static int encodeAutoHeader(char *result, const encodeRec *enc, int m, int extra encodeExtension(result, extrax << 2, extray, dividerx << 2, dividery, extraDigits, -1, enc); // autoheader return m; } - STORAGE_START += product; } return i - 1; // return last autoheader record as the (failing) record @@ -1283,95 +1232,86 @@ static int encodeAutoHeader(char *result, const encodeRec *enc, int m, int extra static int debugStopAt = -1; -static void encoderEngine(int ccode, const encodeRec *enc, int stop_with_one_result, int extraDigits, - int result_override) { - int from, upto; - int y = enc->lat32, x = enc->lon32; - - if (enc == NULL || ccode < 0 || ccode > ccode_earth) { - return; - } // bad arguments +static void encoderEngine(int ccode, const encodeRec *enc, int stop_with_one_result, + int extraDigits, int result_override) +{ + if (enc == NULL || ccode < 0 || ccode > ccode_earth) + return; // bad arguments - from = firstrec(ccode); - upto = lastrec(ccode); + int from = firstrec(ccode); + int upto = lastrec(ccode); + int x = enc->lon32; + int y = enc->lat32; - if (ccode != ccode_earth) { - if (!fitsInside(x, y, upto)) { + if (ccode != ccode_earth) + if (!fitsInside(x, y, upto)) return; - } - } /////////////////////////////////////////////////////////// // look for encoding options /////////////////////////////////////////////////////////// - { - int i; - char result[128]; - int result_counter = 0; - - *result = 0; - for (i = from; i <= upto; i++) { - int codex = coDex(i); - if (codex < 54) { - if (fitsInside(x, y, i)) { - if (isNameless(i)) { - int ret = encodeNameless(result, enc, ccode, extraDigits, i); - if (ret >= 0) { - i = ret; - } - } - else if (recType(i) > 1) { - encodeAutoHeader(result, enc, i, extraDigits); - } - else if (i == upto && isRestricted(i) && - isSubdivision(ccode)) // if the last item is a reference to a state's country - { - // *** do a recursive call for the parent *** - encoderEngine(ParentTerritoryOf(ccode), enc, stop_with_one_result, extraDigits, ccode); - return; /**/ + char result[128]; + *result = 0; + int result_counter = 0; + + for (int i = from; i <= upto; i++) { + if (coDex(i) < 54) { + if (fitsInside(x, y, i)) { + if (isNameless(i)) { + int ret = encodeNameless(result, enc, ccode, extraDigits, i); + if (ret >= 0) { + i = ret; } - else // must be grid - { - if (result_counter > 0 || - !isRestricted(i)) // skip isRestricted records unless there already is a result - { - char headerletter = (char) ((recType(i) == 1) ? headerLetter(i) : 0); - encodeGrid(result, enc, i, extraDigits, headerletter); - } + } + else if (recType(i) > 1) { + encodeAutoHeader(result, enc, i, extraDigits); + // if the last item is a reference to a state's country + } else if (i == upto && isRestricted(i) && isSubdivision(ccode)) { + // *** do a recursive call for the parent *** + encoderEngine(ParentTerritoryOf(ccode), enc, stop_with_one_result, extraDigits, ccode); + return; + } else { // must be grid + // skip isRestricted records unless there already is a result + if (result_counter > 0 || !isRestricted(i)) { + char headerletter = (char) ((recType(i) == 1) ? headerLetter(i) : 0); + encodeGrid(result, enc, i, extraDigits, headerletter); } + } - // =========== handle result (if any) - if (*result) { - result_counter++; - - repack_if_alldigits(result, 0); - - if (debugStopAt < 0 || debugStopAt == i) { - int cc = (result_override >= 0 ? result_override : ccode); - if (*result && enc->mapcodes && enc->mapcodes->count < MAX_NR_OF_MAPCODE_RESULTS) { - char *s = enc->mapcodes->mapcode[enc->mapcodes->count++]; - if (cc == ccode_earth) - strcpy(s, result); - else { - getTerritoryIsoName(s, cc + 1, 0); - strcat(s, " "); - strcat(s, result); - } + // =========== handle result (if any) + if (*result) { + result_counter++; + + repack_if_alldigits(result, 0); + + if (debugStopAt < 0 || debugStopAt == i) { + int cc = (result_override >= 0 ? result_override : ccode); + if (*result && enc->mapcodes && enc->mapcodes->count < MAX_NR_OF_MAPCODE_RESULTS) { + char *s = enc->mapcodes->mapcode[enc->mapcodes->count++]; + if (cc == ccode_earth) { + strcpy(s, result); + } else { + getTerritoryIsoName(s, cc + 1, 0); + strcat(s, " "); + strcat(s, result); } - if (debugStopAt == i) { return; } } - if (stop_with_one_result) { return; } - *result = 0; // clear for next iteration + if (debugStopAt == i) + return; } + if (stop_with_one_result) + return; + *result = 0; // clear for next iteration } } - } // for i - } + } + } // for i } // returns nonzero if error -static int decoderEngine(decodeRec *dec) { +static int decoderEngine(decodeRec *dec) +{ int parentcode; int err; int ccode, len; @@ -1380,41 +1320,45 @@ static int decoderEngine(decodeRec *dec) { char *s = dec->minput; // copy input, cleaned of leading and trailing whitespace, into private, non-const buffer - { - const char *r = dec->orginput; - while (*r > 0 && *r <= 32) { r++; } // skip lead - len = (int) strlen(r); - if (len > MAX_MAPCODE_RESULT_LEN - 1) { len = MAX_MAPCODE_RESULT_LEN - 1; } - while (len > 0 && r[len - 1] >= 0 && r[len - 1] <= 32) { len--; } // remove trail - memcpy(s, r, len); - s[len] = 0; - } + const char *r = dec->orginput; + while (*r > 0 && *r <= 32) + r++; // skip lead + + len = (int) strlen(r); + if (len > MAX_MAPCODE_RESULT_LEN - 1) + len = MAX_MAPCODE_RESULT_LEN - 1; + while (len > 0 && r[len - 1] >= 0 && r[len - 1] <= 32) + len--; // remove trail + memcpy(s, r, len); + s[len] = 0; // make input (excluding territory) uppercase, and replace digits 0 and 1 with O and I - { - char *t = strchr(s, ' '); - if (t == NULL) { t = s; } - for (; *t != 0; t++) { - if (*t >= 'a' && *t <= 'z') { *t += ('A' - 'a'); } - if (*t == 'O') { *t = '0'; } - if (*t == 'I') { *t = '1'; } - } + char *t = strchr(s, ' '); + if (t == NULL) + t = s; + + for (; *t != 0; t++) { + if (*t >= 'a' && *t <= 'z') + *t += ('A' - 'a'); + if (*t == 'O') + *t = '0'; + if (*t == 'I') + *t = '1'; } // check if extension, determine length without extension minus = strchr(s + 4, '-'); - if (minus) { + if (minus) len = (int) (minus - s); - } // make sure there is valid context iso3 = convertTerritoryCodeToIsoName(dec->context, 0); // get context string (or empty string) - if (*iso3 == 0) { iso3 = "AAA"; } + if (*iso3 == 0) + iso3 = "AAA"; parentcode = disambiguate_str(iso3, (int) strlen(iso3)); // pass for future context disambiguation // insert context if none in input - if (len > 0 && len <= 9 && strchr(s, ' ') == 0) // just a non-international mapcode without a territory code? - { + if (len > 0 && len <= 9 && strchr(s, ' ') == 0) { // just a non-international mapcode without a territory code? int ilen = (int) strlen(iso3); memmove(s + ilen + 1, s, strlen(s) + 1); s[ilen] = ' '; @@ -1424,210 +1368,193 @@ static int decoderEngine(decodeRec *dec) { } // parse off extension s[len] = 0; - if (minus) { + if (minus) dec->extension = &s[len + 1]; - } else { + else dec->extension = ""; - } // now split off territory, make point to start of proper mapcode - if (len > 8 && (s[3] == ' ' || s[3] == '-') && - (s[6] == ' ' || s[7] == ' ')) // assume ISO3 space|minus ISO23 space MAPCODE - { + // assume ISO3 space|minus ISO23 space MAPCODE + if (len > 8 && (s[3] == ' ' || s[3] == '-') && (s[6] == ' ' || s[7] == ' ')) { parentcode = disambiguate_str(s, 3); - if (parentcode < 0) { return parentcode; } + if (parentcode < 0) + return parentcode; + s += 4; len -= 4; - } - else if (len > 7 && (s[2] == ' ' || s[2] == '-') && - (s[5] == ' ' || s[6] == ' ')) // assume ISO2 space|minus ISO23 space MAPCODE - { - parentcode = disambiguate_str(s, 2); - if (parentcode < 0) { return parentcode; } - s += 3; - len -= 3; + } else { + // assume ISO2 space|minus ISO23 space MAPCODE + if (len > 7 && (s[2] == ' ' || s[2] == '-') && (s[5] == ' ' || s[6] == ' ')) { + parentcode = disambiguate_str(s, 2); + if (parentcode < 0) + return parentcode; + + s += 3; + len -= 3; + } } - if (len > 4 && s[3] == ' ') // assume ISO whitespace MAPCODE, overriding iso3 - { + // assume ISO whitespace MAPCODE, overriding iso3 + if (len > 4 && s[3] == ' ') { iso3 = s; // overrides iso code! s += 4; len -= 4; - } - else if (len > 3 && s[2] == ' ') // assume ISO2 whitespace MAPCODE, overriding iso3 - { + } else if (len > 3 && s[2] == ' ') { // assume ISO2 whitespace MAPCODE, overriding iso3 iso3 = s; // overrides iso code! s += 3; len -= 3; } + // skip further whitespace while (*s > 0 && *s <= 32) { s++; len--; - } // skip further whitespace + } // returns nonzero if error + // special case for mexico country vs state ccode = ccode_of_iso3(iso3, parentcode); - if (ccode == ccode_mex && len < 8) { ccode = ccode_of_iso3("5MX", -1); } // special case for mexico country vs state + if (ccode == ccode_mex && len < 8) + ccode = ccode_of_iso3("5MX", -1); // master_decode(s,ccode) - { - const char *dot = NULL; // dot position in input - int prelen; // input prefix length - int postlen; // input postfix length - int codex; // input codex - int from, upto; // record range for territory - int i; - - - // unpack digits (a-lead or aeu-encoded - int voweled = unpack_if_alldigits(s); - if (voweled < 0) { - return -7; - } + // unpack digits (a-lead or aeu-encoded + int voweled = unpack_if_alldigits(s); + if (voweled < 0) + return -7; - // debug support: U-lead pre-processing - if (*s == 'u' || *s == 'U') { - s++; - len--; - voweled = 1; - } + // debug support: U-lead pre-processing + if (*s == 'u' || *s == 'U') { + s++; + len--; + voweled = 1; + } - if (len > 10) { return -8; } + if (len > 10) + return -8; - // find dot and check that all characters are valid - { - int nrd = 0; // nr of true digits - const char *r = s; - for (; *r != 0; r++) { - if (*r == '.') { - if (dot) { - return -5; - } // more than one dot - dot = r; - } - else if (decodeChar(*r) < 0) { // invalid char? - return -4; - } else if (decodeChar(*r) < 10) { // digit? - nrd++; - } - } - if (dot == NULL) { - return -2; - } else if (!voweled && nrd + 1 == len) { // everything but the dot is digit, so MUST be voweled! - return -998; + // find dot and check that all characters are valid + int nrd = 0; // nr of true digits + const char *dot = NULL; // dot position in input + for (r = s; *r != 0; r++) { + if (*r == '.') { + if (dot) { + return -5; // more than one dot } + dot = r; + } else if (decodeChar(*r) < 0) { // invalid char? + return -4; + } else if (decodeChar(*r) < 10) { // digit? + nrd++; } + } + if (dot == NULL) + return -2; + else if (!voweled && nrd + 1 == len) // everything but the dot is digit, so MUST be voweled! + return -998; //////////// AT THIS POINT, dot=FIRST DOT, input=CLEAN INPUT (no vowels) ilen=INPUT LENGTH - // analyse input - prelen = (int) (dot - s); - postlen = len - 1 - prelen; - codex = prelen * 10 + postlen; - if (prelen < 2 || prelen > 5 || postlen < 2 || postlen > 4) { - return -3; - } - - if (len == 10) { - // international mapcodes must be in international context - ccode = ccode_earth; - } - else if (isSubdivision(ccode)) { - // int mapcodes must be interpreted in the parent of a subdivision - - int parent = ParentTerritoryOf(ccode); - if (len == 9 || (len == 8 && (parent == ccode_ind || parent == ccode_mex))) { - ccode = parent; - } - } + // analyse input + int prelen = (int) (dot - s); + int postlen = len - 1 - prelen; + int codex = prelen * 10 + postlen; + if (prelen < 2 || prelen > 5 || postlen < 2 || postlen > 4) + return -3; + + if (len == 10) { + // international mapcodes must be in international context + ccode = ccode_earth; + } else if (isSubdivision(ccode)) { + // int mapcodes must be interpreted in the parent of a subdivision + + int parent = ParentTerritoryOf(ccode); + if (len == 9 || (len == 8 && (parent == ccode_ind || parent == ccode_mex))) + ccode = parent; + } - // remember final territory context - dec->context = ccode; - dec->mapcode = s; - - err = -817; - from = firstrec(ccode); - upto = lastrec(ccode); - - // try all ccode rectangles to decode s (pointing to first character of proper mapcode) - for (i = from; i <= upto; i++) { - int codexi = coDex(i); - if (recType(i) == 0 && !isNameless(i) && (codexi == codex || (codex == 22 && codexi == 21))) { - err = decodeGrid(dec, i, 0); - - if (isRestricted(i)) { - int fitssomewhere = 0; - int j; - for (j = i - 1; j >= from; j--) { // look in previous rects - if (!isRestricted((j))) { - if (fitsInsideWithRoom(dec->lon32, dec->lat32, j)) { - fitssomewhere = 1; - break; - } + // remember final territory context + dec->context = ccode; + dec->mapcode = s; + + err = -817; + int from = firstrec(ccode); + int upto = lastrec(ccode); + + // try all ccode rectangles to decode s (pointing to first character of proper mapcode) + for (int i = from; i <= upto; i++) { + int codexi = coDex(i); + if (recType(i) == 0 && !isNameless(i) && (codexi == codex || (codex == 22 && codexi == 21))) { + err = decodeGrid(dec, i, 0); + + if (isRestricted(i)) { + int fitssomewhere = 0; + int j; + for (j = i - 1; j >= from; j--) { // look in previous rects + if (!isRestricted((j))) { + if (fitsInsideWithRoom(dec->lon32, dec->lat32, j)) { + fitssomewhere = 1; + break; } } - if (!fitssomewhere) { - err = -1234; - } } - - break; - } - else if (recType(i) == 1 && prefixLength(i) + 1 == prelen && postfixLength(i) == postlen && - headerLetter(i) == *s) { - err = decodeGrid(dec, i, 1); - break; - } - else if (isNameless(i) && - ((codexi == 21 && codex == 22) - || (codexi == 22 && codex == 32) - || (codexi == 13 && codex == 23))) { - err = decodeNameless(dec, i); - break; - } - else if (recType(i) >= 2 && postlen == 3 && prefixLength(i) + postfixLength(i) == prelen + 2) { - err = decodeAutoHeader(dec, i); - break; + if (!fitssomewhere) { + err = -1234; + } } - } // for - } - + break; + } else if (recType(i) == 1 && prefixLength(i) + 1 == prelen && postfixLength(i) == postlen && + headerLetter(i) == *s) { + err = decodeGrid(dec, i, 1); + break; + } else if (isNameless(i) && + ((codexi == 21 && codex == 22) || + (codexi == 22 && codex == 32) || + (codexi == 13 && codex == 23))) { + err = decodeNameless(dec, i); + break; + } else if (recType(i) >= 2 && postlen == 3 && prefixLength(i) + postfixLength(i) == prelen + 2) { + err = decodeAutoHeader(dec, i); + break; + } + } // for #ifdef SUPPORT_HIGH_PRECISION // convert from millionths if (err) { dec->lat = dec->lon = 0; - } - else { + } else { dec->lat /= (double) 1000000.0; dec->lon /= (double) 1000000.0; } #else // convert from millionths - if (err) dec->lat32 = dec->lon32 = 0; - dec->lat = dec->lat32/(double)1000000.0; - dec->lon = dec->lon32/(double)1000000.0; + if (err) + dec->lat32 = dec->lon32 = 0; + + dec->lat = dec->lat32 / (double)1000000.0; + dec->lon = dec->lon32 / (double)1000000.0; #endif // normalise between =180 and 180 - if (dec->lat < -90.0) { dec->lat = -90.0; } - if (dec->lat > 90.0) { dec->lat = 90.0; } - if (dec->lon < -180.0) { dec->lon += 360.0; } - if (dec->lon >= 180.0) { dec->lon -= 360.0; } + if (dec->lat < -90.0) + dec->lat = -90.0; + if (dec->lat > 90.0) + dec->lat = 90.0; + if (dec->lon < -180.0) + dec->lon += 360.0; + if (dec->lon >= 180.0) + dec->lon -= 360.0; // store as integers for legacy's sake dec->lat32 = (int) (dec->lat * 1000000); dec->lon32 = (int) (dec->lon * 1000000); // make sure decode result fits the country - if (err == 0) { - if (ccode != ccode_earth) { - if (!fitsInsideWithRoom(dec->lon32, dec->lat32, lastrec(ccode))) { + if (err == 0) + if (ccode != ccode_earth) + if (!fitsInsideWithRoom(dec->lon32, dec->lat32, lastrec(ccode))) err = -2222; - } - } - } return err; } @@ -1636,72 +1563,75 @@ static int decoderEngine(decodeRec *dec) { #ifdef SUPPORT_FOREIGN_ALPHABETS // WARNING - these alphabets have NOT yet been released as standard! use at your own risk! check www.mapcode.com for details. -static UWORD asc2lan[MAX_LANGUAGES][36] = // A-Z equivalents for ascii characters A to Z, 0-9 - { - {0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039}, // roman - {0x0391, 0x0392, 0x039e, 0x0394, 0x003f, 0x0395, 0x0393, 0x0397, 0x0399, 0x03a0, 0x039a, 0x039b, 0x039c, 0x039d, 0x039f, 0x03a1, 0x0398, 0x03a8, 0x03a3, 0x03a4, 0x003f, 0x03a6, 0x03a9, 0x03a7, 0x03a5, 0x0396, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039}, // greek - {0x0410, 0x0412, 0x0421, 0x0414, 0x0415, 0x0416, 0x0413, 0x041d, 0x0418, 0x041f, 0x041a, 0x041b, 0x041c, 0x0417, 0x041e, 0x0420, 0x0424, 0x042f, 0x0426, 0x0422, 0x042d, 0x0427, 0x0428, 0x0425, 0x0423, 0x0411, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039}, // cyrillic - {0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05e3, 0x05d4, 0x05d6, 0x05d7, 0x05d5, 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05e1, 0x05dd, 0x05de, 0x05e0, 0x05e2, 0x05e4, 0x05e5, 0x05e6, 0x05e7, 0x05e8, 0x05e9, 0x05ea, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039}, // hebrew - {0x0905, 0x0915, 0x0917, 0x0918, 0x090f, 0x091a, 0x091c, 0x091f, 0x003f, 0x0920, 0x0923, 0x0924, 0x0926, 0x0927, 0x003f, 0x0928, 0x092a, 0x092d, 0x092e, 0x0930, 0x092b, 0x0932, 0x0935, 0x0938, 0x0939, 0x0921, 0x0966, 0x0967, 0x0968, 0x0969, 0x096a, 0x096b, 0x096c, 0x096d, 0x096e, 0x096f}, // hindi - {0x0d12, 0x0d15, 0x0d16, 0x0d17, 0x0d0b, 0x0d1a, 0x0d1c, 0x0d1f, 0x0d07, 0x0d21, 0x0d24, 0x0d25, 0x0d26, 0x0d27, 0x0d20, 0x0d28, 0x0d2e, 0x0d30, 0x0d31, 0x0d32, 0x0d09, 0x0d34, 0x0d35, 0x0d36, 0x0d38, 0x0d39, 0x0d66, 0x0d67, 0x0d68, 0x0d69, 0x0d6a, 0x0d6b, 0x0d6c, 0x0d6d, 0x0d6e, 0x0d6f}, // malay - {0x10a0, 0x10a1, 0x10a3, 0x10a6, 0x10a4, 0x10a9, 0x10ab, 0x10ac, 0x10b3, 0x10ae, 0x10b0, 0x10b1, 0x10b2, 0x10b4, 0x10ad, 0x10b5, 0x10b6, 0x10b7, 0x10b8, 0x10b9, 0x10a8, 0x10ba, 0x10bb, 0x10bd, 0x10be, 0x10bf, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039}, // Georgian - {0x30a2, 0x30ab, 0x30ad, 0x30af, 0x30aa, 0x30b1, 0x30b3, 0x30b5, 0x30a4, 0x30b9, 0x30c1, 0x30c8, 0x30ca, 0x30cc, 0x30a6, 0x30d2, 0x30d5, 0x30d8, 0x30db, 0x30e1, 0x30a8, 0x30e2, 0x30e8, 0x30e9, 0x30ed, 0x30f2, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039}, // Katakana - {0x0e30, 0x0e01, 0x0e02, 0x0e04, 0x0e32, 0x0e07, 0x0e08, 0x0e09, 0x0e31, 0x0e0a, 0x0e11, 0x0e14, 0x0e16, 0x0e17, 0x0e0d, 0x0e18, 0x0e1a, 0x0e1c, 0x0e21, 0x0e23, 0x0e2c, 0x0e25, 0x0e27, 0x0e2d, 0x0e2e, 0x0e2f, 0x0e50, 0x0e51, 0x0e52, 0x0e53, 0x0e54, 0x0e55, 0x0e56, 0x0e57, 0x0e58, 0x0e59}, // Thai - {0x0eb0, 0x0e81, 0x0e82, 0x0e84, 0x0ec3, 0x0e87, 0x0e88, 0x0e8a, 0x0ec4, 0x0e8d, 0x0e94, 0x0e97, 0x0e99, 0x0e9a, 0x0ec6, 0x0e9c, 0x0e9e, 0x0ea1, 0x0ea2, 0x0ea3, 0x0ebd, 0x0ea7, 0x0eaa, 0x0eab, 0x0ead, 0x0eaf, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039}, // Laos - {0x0556, 0x0532, 0x0533, 0x0534, 0x0535, 0x0538, 0x0539, 0x053a, 0x053b, 0x053d, 0x053f, 0x0540, 0x0541, 0x0543, 0x0555, 0x0547, 0x0548, 0x054a, 0x054d, 0x054e, 0x0545, 0x054f, 0x0550, 0x0551, 0x0552, 0x0553, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039}, // armenian - {0x0985, 0x098c, 0x0995, 0x0996, 0x098f, 0x0997, 0x0999, 0x099a, 0x003f, 0x099d, 0x09a0, 0x09a1, 0x09a2, 0x09a3, 0x003f, 0x09a4, 0x09a5, 0x09a6, 0x09a8, 0x09aa, 0x0993, 0x09ac, 0x09ad, 0x09af, 0x09b2, 0x09b9, 0x09e6, 0x09e7, 0x09e8, 0x09e9, 0x09ea, 0x09eb, 0x09ec, 0x09ed, 0x09ee, 0x09ef}, // Bengali - {0x0a05, 0x0a15, 0x0a17, 0x0a18, 0x0a0f, 0x0a1a, 0x0a1c, 0x0a1f, 0x003f, 0x0a20, 0x0a23, 0x0a24, 0x0a26, 0x0a27, 0x003f, 0x0a28, 0x0a2a, 0x0a2d, 0x0a2e, 0x0a30, 0x0a2b, 0x0a32, 0x0a35, 0x0a38, 0x0a39, 0x0a21, 0x0a66, 0x0a67, 0x0a68, 0x0a69, 0x0a6a, 0x0a6b, 0x0a6c, 0x0a6d, 0x0a6e, 0x0a6f}, // Gurmukhi - {0x0f58, 0x0f40, 0x0f41, 0x0f42, 0x0f64, 0x0f44, 0x0f45, 0x0f46, 0x003f, 0x0f47, 0x0f4a, 0x0f4c, 0x0f4e, 0x0f4f, 0x003f, 0x0f51, 0x0f53, 0x0f54, 0x0f56, 0x0f5e, 0x0f65, 0x0f5f, 0x0f61, 0x0f62, 0x0f63, 0x0f66, 0x0f20, 0x0f21, 0x0f22, 0x0f23, 0x0f24, 0x0f25, 0x0f26, 0x0f27, 0x0f28, 0x0f29}, // Tibetan - }; +// A-Z equivalents for ascii characters A to Z, 0-9 +static UWORD asc2lan[MAX_LANGUAGES][36] = { + {0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039}, // roman + {0x0391, 0x0392, 0x039e, 0x0394, 0x003f, 0x0395, 0x0393, 0x0397, 0x0399, 0x03a0, 0x039a, 0x039b, 0x039c, 0x039d, 0x039f, 0x03a1, 0x0398, 0x03a8, 0x03a3, 0x03a4, 0x003f, 0x03a6, 0x03a9, 0x03a7, 0x03a5, 0x0396, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039}, // greek + {0x0410, 0x0412, 0x0421, 0x0414, 0x0415, 0x0416, 0x0413, 0x041d, 0x0418, 0x041f, 0x041a, 0x041b, 0x041c, 0x0417, 0x041e, 0x0420, 0x0424, 0x042f, 0x0426, 0x0422, 0x042d, 0x0427, 0x0428, 0x0425, 0x0423, 0x0411, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039}, // cyrillic + {0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05e3, 0x05d4, 0x05d6, 0x05d7, 0x05d5, 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05e1, 0x05dd, 0x05de, 0x05e0, 0x05e2, 0x05e4, 0x05e5, 0x05e6, 0x05e7, 0x05e8, 0x05e9, 0x05ea, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039}, // hebrew + {0x0905, 0x0915, 0x0917, 0x0918, 0x090f, 0x091a, 0x091c, 0x091f, 0x003f, 0x0920, 0x0923, 0x0924, 0x0926, 0x0927, 0x003f, 0x0928, 0x092a, 0x092d, 0x092e, 0x0930, 0x092b, 0x0932, 0x0935, 0x0938, 0x0939, 0x0921, 0x0966, 0x0967, 0x0968, 0x0969, 0x096a, 0x096b, 0x096c, 0x096d, 0x096e, 0x096f}, // hindi + {0x0d12, 0x0d15, 0x0d16, 0x0d17, 0x0d0b, 0x0d1a, 0x0d1c, 0x0d1f, 0x0d07, 0x0d21, 0x0d24, 0x0d25, 0x0d26, 0x0d27, 0x0d20, 0x0d28, 0x0d2e, 0x0d30, 0x0d31, 0x0d32, 0x0d09, 0x0d34, 0x0d35, 0x0d36, 0x0d38, 0x0d39, 0x0d66, 0x0d67, 0x0d68, 0x0d69, 0x0d6a, 0x0d6b, 0x0d6c, 0x0d6d, 0x0d6e, 0x0d6f}, // malay + {0x10a0, 0x10a1, 0x10a3, 0x10a6, 0x10a4, 0x10a9, 0x10ab, 0x10ac, 0x10b3, 0x10ae, 0x10b0, 0x10b1, 0x10b2, 0x10b4, 0x10ad, 0x10b5, 0x10b6, 0x10b7, 0x10b8, 0x10b9, 0x10a8, 0x10ba, 0x10bb, 0x10bd, 0x10be, 0x10bf, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039}, // Georgian + {0x30a2, 0x30ab, 0x30ad, 0x30af, 0x30aa, 0x30b1, 0x30b3, 0x30b5, 0x30a4, 0x30b9, 0x30c1, 0x30c8, 0x30ca, 0x30cc, 0x30a6, 0x30d2, 0x30d5, 0x30d8, 0x30db, 0x30e1, 0x30a8, 0x30e2, 0x30e8, 0x30e9, 0x30ed, 0x30f2, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039}, // Katakana + {0x0e30, 0x0e01, 0x0e02, 0x0e04, 0x0e32, 0x0e07, 0x0e08, 0x0e09, 0x0e31, 0x0e0a, 0x0e11, 0x0e14, 0x0e16, 0x0e17, 0x0e0d, 0x0e18, 0x0e1a, 0x0e1c, 0x0e21, 0x0e23, 0x0e2c, 0x0e25, 0x0e27, 0x0e2d, 0x0e2e, 0x0e2f, 0x0e50, 0x0e51, 0x0e52, 0x0e53, 0x0e54, 0x0e55, 0x0e56, 0x0e57, 0x0e58, 0x0e59}, // Thai + {0x0eb0, 0x0e81, 0x0e82, 0x0e84, 0x0ec3, 0x0e87, 0x0e88, 0x0e8a, 0x0ec4, 0x0e8d, 0x0e94, 0x0e97, 0x0e99, 0x0e9a, 0x0ec6, 0x0e9c, 0x0e9e, 0x0ea1, 0x0ea2, 0x0ea3, 0x0ebd, 0x0ea7, 0x0eaa, 0x0eab, 0x0ead, 0x0eaf, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039}, // Laos + {0x0556, 0x0532, 0x0533, 0x0534, 0x0535, 0x0538, 0x0539, 0x053a, 0x053b, 0x053d, 0x053f, 0x0540, 0x0541, 0x0543, 0x0555, 0x0547, 0x0548, 0x054a, 0x054d, 0x054e, 0x0545, 0x054f, 0x0550, 0x0551, 0x0552, 0x0553, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039}, // armenian + {0x0985, 0x098c, 0x0995, 0x0996, 0x098f, 0x0997, 0x0999, 0x099a, 0x003f, 0x099d, 0x09a0, 0x09a1, 0x09a2, 0x09a3, 0x003f, 0x09a4, 0x09a5, 0x09a6, 0x09a8, 0x09aa, 0x0993, 0x09ac, 0x09ad, 0x09af, 0x09b2, 0x09b9, 0x09e6, 0x09e7, 0x09e8, 0x09e9, 0x09ea, 0x09eb, 0x09ec, 0x09ed, 0x09ee, 0x09ef}, // Bengali + {0x0a05, 0x0a15, 0x0a17, 0x0a18, 0x0a0f, 0x0a1a, 0x0a1c, 0x0a1f, 0x003f, 0x0a20, 0x0a23, 0x0a24, 0x0a26, 0x0a27, 0x003f, 0x0a28, 0x0a2a, 0x0a2d, 0x0a2e, 0x0a30, 0x0a2b, 0x0a32, 0x0a35, 0x0a38, 0x0a39, 0x0a21, 0x0a66, 0x0a67, 0x0a68, 0x0a69, 0x0a6a, 0x0a6b, 0x0a6c, 0x0a6d, 0x0a6e, 0x0a6f}, // Gurmukhi + {0x0f58, 0x0f40, 0x0f41, 0x0f42, 0x0f64, 0x0f44, 0x0f45, 0x0f46, 0x003f, 0x0f47, 0x0f4a, 0x0f4c, 0x0f4e, 0x0f4f, 0x003f, 0x0f51, 0x0f53, 0x0f54, 0x0f56, 0x0f5e, 0x0f65, 0x0f5f, 0x0f61, 0x0f62, 0x0f63, 0x0f66, 0x0f20, 0x0f21, 0x0f22, 0x0f23, 0x0f24, 0x0f25, 0x0f26, 0x0f27, 0x0f28, 0x0f29}, // Tibetan +}; static struct { UWORD min; UWORD max; const char *convert; -} unicode2asc[] = - { - {0x0041, 0x005a, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"}, // Roman - {0x0391, 0x03a9, "ABGDFZHQIKLMNCOJP?STYVXRW"}, // Greek - {0x0410, 0x042f, "AZBGDEFNI?KLMHOJPCTYQXSVW????U?R"}, // Cyrillic - {0x05d0, 0x05ea, "ABCDFIGHJKLMNPQ?ROSETUVWXYZ"}, // Hebrew - {0x0905, 0x0939, "A?????????E?????B?CD?F?G??HJZ?KL?MNP?QU?RS?T?V??W??XY"}, // Hindi - {0x0d07, 0x0d39, "I?U?E??????A??BCD??F?G??HOJ??KLMNP?????Q?RST?VWX?YZ"}, // Malay - {0x10a0, 0x10bf, "AB?CE?D?UF?GHOJ?KLMINPQRSTVW?XYZ"}, // Georgisch - {0x30a2, 0x30f2, "A?I?O?U?EB?C?D?F?G?H???J???????K??????L?M?N?????P??Q??R??S?????TV?????WX???Y????Z"}, // Katakana - {0x0e01, 0x0e32, "BC?D??FGHJ??O???K??L?MNP?Q?R????S?T?V?W????UXYZAIE"}, // Thai - {0x0e81, 0x0ec6, "BC?D??FG?H??J??????K??L?MN?P?Q??RST???V??WX?Y?ZA????????????U?????EI?O"}, // Lao - {0x0532, 0x0556, "BCDE??FGHI?J?KLM?N?U?PQ?R??STVWXYZ?OA"}, // Armenian - {0x0985, 0x09b9, "A??????B??E???U?CDF?GH??J??KLMNPQR?S?T?VW?X??Y??????Z"}, // Bengali - {0x0a05, 0x0a39, "A?????????E?????B?CD?F?G??HJZ?KL?MNP?QU?RS?T?V??W??XY"}, // Gurmukhi - {0x0f40, 0x0f66, "BCD?FGHJ??K?L?MN?P?QR?S?A?????TV?WXYEUZ"}, // Tibetan - - {0x0966, 0x096f, ""}, // Hindi - {0x0d66, 0x0d6f, ""}, // Malai - {0x0e50, 0x0e59, ""}, // Thai - {0x09e6, 0x09ef, ""}, // Bengali - {0x0a66, 0x0a6f, ""}, // Gurmukhi - {0x0f20, 0x0f29, ""}, // Tibetan - - // lowercase variants: greek, georgisch - {0x03B1, 0x03c9, "ABGDFZHQIKLMNCOJP?STYVXRW"}, // Greek lowercase - {0x10d0, 0x10ef, "AB?CE?D?UF?GHOJ?KLMINPQRSTVW?XYZ"}, // Georgisch lowercase - {0x0562, 0x0586, "BCDE??FGHI?J?KLM?N?U?PQ?R??STVWXYZ?OA"}, // Armenian lowercase - {0, 0, NULL} - }; - - -char *convertToRoman(char *asciibuf, int maxlen, const UWORD *s) { +} unicode2asc[] = { + {0x0041, 0x005a, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"}, // Roman + {0x0391, 0x03a9, "ABGDFZHQIKLMNCOJP?STYVXRW"}, // Greek + {0x0410, 0x042f, "AZBGDEFNI?KLMHOJPCTYQXSVW????U?R"}, // Cyrillic + {0x05d0, 0x05ea, "ABCDFIGHJKLMNPQ?ROSETUVWXYZ"}, // Hebrew + {0x0905, 0x0939, "A?????????E?????B?CD?F?G??HJZ?KL?MNP?QU?RS?T?V??W??XY"}, // Hindi + {0x0d07, 0x0d39, "I?U?E??????A??BCD??F?G??HOJ??KLMNP?????Q?RST?VWX?YZ"}, // Malay + {0x10a0, 0x10bf, "AB?CE?D?UF?GHOJ?KLMINPQRSTVW?XYZ"}, // Georgisch + {0x30a2, 0x30f2, "A?I?O?U?EB?C?D?F?G?H???J???????K??????L?M?N?????P??Q??R??S?????TV?????WX???Y????Z"}, // Katakana + {0x0e01, 0x0e32, "BC?D??FGHJ??O???K??L?MNP?Q?R????S?T?V?W????UXYZAIE"}, // Thai + {0x0e81, 0x0ec6, "BC?D??FG?H??J??????K??L?MN?P?Q??RST???V??WX?Y?ZA????????????U?????EI?O"}, // Lao + {0x0532, 0x0556, "BCDE??FGHI?J?KLM?N?U?PQ?R??STVWXYZ?OA"}, // Armenian + {0x0985, 0x09b9, "A??????B??E???U?CDF?GH??J??KLMNPQR?S?T?VW?X??Y??????Z"}, // Bengali + {0x0a05, 0x0a39, "A?????????E?????B?CD?F?G??HJZ?KL?MNP?QU?RS?T?V??W??XY"}, // Gurmukhi + {0x0f40, 0x0f66, "BCD?FGHJ??K?L?MN?P?QR?S?A?????TV?WXYEUZ"}, // Tibetan + + {0x0966, 0x096f, ""}, // Hindi + {0x0d66, 0x0d6f, ""}, // Malai + {0x0e50, 0x0e59, ""}, // Thai + {0x09e6, 0x09ef, ""}, // Bengali + {0x0a66, 0x0a6f, ""}, // Gurmukhi + {0x0f20, 0x0f29, ""}, // Tibetan + + // lowercase variants: greek, georgisch + {0x03B1, 0x03c9, "ABGDFZHQIKLMNCOJP?STYVXRW"}, // Greek lowercase + {0x10d0, 0x10ef, "AB?CE?D?UF?GHOJ?KLMINPQRSTVW?XYZ"}, // Georgisch lowercase + {0x0562, 0x0586, "BCDE??FGHI?J?KLM?N?U?PQ?R??STVWXYZ?OA"}, // Armenian lowercase + {0, 0, NULL} +}; + + +char *convertToRoman(char *asciibuf, int maxlen, const UWORD *s) +{ char *w = asciibuf; const char *e = w + maxlen - 1; + for (; *s != 0 && w < e; s++) { if (*s >= 1 && *s <= 'z') { // normal ascii *w++ = (char) (*s); } else { - int i, found = 0; - for (i = 0; unicode2asc[i].min != 0; i++) { + int found = 0; + for (int i = 0; unicode2asc[i].min != 0; i++) { if (*s >= unicode2asc[i].min && *s <= unicode2asc[i].max) { const char *cv = unicode2asc[i].convert; - if (*cv == 0) { cv = "0123456789"; } + if (*cv == 0) + cv = "0123456789"; + *w++ = cv[*s - unicode2asc[i].min]; found = 1; break; @@ -1714,8 +1644,7 @@ char *convertToRoman(char *asciibuf, int maxlen, const UWORD *s) { } } *w = 0; - if (*asciibuf == 'A') // v1.50 - { + if (*asciibuf == 'A') { // v1.50 unpack_if_alldigits(asciibuf); repack_if_alldigits(asciibuf, 0); } @@ -1729,9 +1658,12 @@ static UWORD *encode_utf16(UWORD *unibuf, int maxlen, const char *mapcode, UWORD *w = unibuf; const UWORD *e = w + maxlen - 1; const char *r = mapcode; + while (*r != 0 && w < e) { char c = *r++; - if (c >= 'a' && c <= 'z') { c += ('A' - 'a'); } + if (c >= 'a' && c <= 'z') { + c += ('A' - 'a'); + } if (c < 0 || c > 'Z') { // not in any valid range? *w++ = '?'; } else if (c < 'A') { // valid but not a letter (e.g. a dot, a space...) @@ -1754,6 +1686,8 @@ static UWORD *encode_utf16(UWORD *unibuf, int maxlen, const char *mapcode, #define TOKENVOWEL 3 #define TOKENZERO 4 #define TOKENHYPH 5 + + #define ERR -1 #define Prt -9 // partial #define GO 99 @@ -1761,62 +1695,38 @@ static UWORD *encode_utf16(UWORD *unibuf, int maxlen, const char *mapcode, static signed char fullmc_statemachine[23][6] = { // WHI DOT DET VOW ZER HYP /* 0 start */ {0, ERR, 1, 1, ERR, ERR}, // looking for very first detter - /* 1 gotL */ - {ERR, ERR, 2, 2, ERR, ERR}, // got one detter, MUST get another one - /* 2 gotLL */ - {18, 6, 3, 3, ERR, 14}, // GOT2: white: got territory + start prefix | dot: 2.X mapcode | det:3letter | hyphen: 2-state - /* 3 gotLLL */ - {18, 6, 4, ERR, ERR, 14}, // white: got territory + start prefix | dot: 3.X mapcode | det:4letterprefix | hyphen: 3-state - /* 4 gotprefix4 */ - {ERR, 6, 5, ERR, ERR, ERR}, // dot: 4.X mapcode | det: got 5th prefix letter - /* 5 gotprefix5 */ - {ERR, 6, ERR, ERR, ERR, ERR}, // got 5char so MUST get dot! - /* 6 prefix. */ - {ERR, ERR, 7, 7, Prt, ERR}, // MUST get first letter after dot - /* 7 prefix.L */ - {ERR, ERR, 8, 8, Prt, ERR}, // MUST get second letter after dot - /* 8 prefix.LL */ - {22, ERR, 9, 9, GO, 11}, // get 3d letter after dot | X.2- | X.2 done! - /* 9 prefix.LLL */ - {22, ERR, 10, 10, GO, 11}, // get 4th letter after dot | X.3- | X.3 done! - /*10 prefix.LLLL */ - {22, ERR, ERR, ERR, GO, 11}, // X.4- | x.4 done! - - /*11 mc- */ - {ERR, ERR, 12, ERR, Prt, ERR}, // MUST get first precision letter - /*12 mc-L */ - {22, ERR, 13, ERR, GO, ERR}, // Get 2nd precision letter | done X.Y-1 - /*13 mc-LL* */ - {22, ERR, 13, ERR, GO, ERR}, // *** keep reading precision detters *** until whitespace or done - - /*14 ctry- */ - {ERR, ERR, 15, 15, ERR, ERR}, // MUST get first state letter - /*15 ctry-L */ - {ERR, ERR, 16, 16, ERR, ERR}, // MUST get 2nd state letter - /*16 ctry-LL */ - {18, ERR, 17, 17, ERR, ERR}, // white: got CCC-SS and get prefix | got 3d letter - /*17 ctry-LLL */ - {18, ERR, ERR, ERR, ERR, ERR}, // got CCC-SSS so MUST get whitespace and then get prefix - - /*18 startprefix */ - {18, ERR, 19, 19, ERR, ERR}, // skip more whitespace, MUST get 1st prefix letter - /*19 gotprefix1 */ - {ERR, ERR, 20, ERR, ERR, ERR}, // MUST get second prefix letter - /*20 gotprefix2 */ - {ERR, 6, 21, ERR, ERR, ERR}, // dot: 2.X mapcode | det: 3d perfix letter - /*21 gotprefix3 */ - {ERR, 6, 4, ERR, ERR, ERR}, // dot: 3.x mapcode | det: got 4th prefix letter - - /*22 whitespace */ - {22, ERR, ERR, ERR, GO, ERR} // whitespace until end of string + /* 1 gotL */ {ERR, ERR, 2, 2, ERR, ERR}, // got one detter, MUST get another one + /* 2 gotLL */ {18, 6, 3, 3, ERR, 14}, // GOT2: white: got territory + start prefix | dot: 2.X mapcode | det:3letter | hyphen: 2-state + /* 3 gotLLL */ {18, 6, 4, ERR, ERR, 14}, // white: got territory + start prefix | dot: 3.X mapcode | det:4letterprefix | hyphen: 3-state + /* 4 gotprefix4 */ {ERR, 6, 5, ERR, ERR, ERR}, // dot: 4.X mapcode | det: got 5th prefix letter + /* 5 gotprefix5 */ {ERR, 6, ERR, ERR, ERR, ERR}, // got 5char so MUST get dot! + /* 6 prefix. */ {ERR, ERR, 7, 7, Prt, ERR}, // MUST get first letter after dot + /* 7 prefix.L */ {ERR, ERR, 8, 8, Prt, ERR}, // MUST get second letter after dot + /* 8 prefix.LL */ {22, ERR, 9, 9, GO, 11}, // get 3d letter after dot | X.2- | X.2 done! + /* 9 prefix.LLL */ {22, ERR, 10, 10, GO, 11}, // get 4th letter after dot | X.3- | X.3 done! + /*10 prefix.LLLL */ {22, ERR, ERR, ERR, GO, 11}, // X.4- | x.4 done! + /*11 mc- */ {ERR, ERR, 12, ERR, Prt, ERR}, // MUST get first precision letter + /*12 mc-L */ {22, ERR, 13, ERR, GO, ERR}, // Get 2nd precision letter | done X.Y-1 + /*13 mc-LL* */ {22, ERR, 13, ERR, GO, ERR}, // *** keep reading precision detters *** until whitespace or done + /*14 ctry- */ {ERR, ERR, 15, 15, ERR, ERR}, // MUST get first state letter + /*15 ctry-L */ {ERR, ERR, 16, 16, ERR, ERR}, // MUST get 2nd state letter + /*16 ctry-LL */ {18, ERR, 17, 17, ERR, ERR}, // white: got CCC-SS and get prefix | got 3d letter + /*17 ctry-LLL */ {18, ERR, ERR, ERR, ERR, ERR}, // got CCC-SSS so MUST get whitespace and then get prefix + /*18 startprefix */ {18, ERR, 19, 19, ERR, ERR}, // skip more whitespace, MUST get 1st prefix letter + /*19 gotprefix1 */ {ERR, ERR, 20, ERR, ERR, ERR}, // MUST get second prefix letter + /*20 gotprefix2 */ {ERR, 6, 21, ERR, ERR, ERR}, // dot: 2.X mapcode | det: 3d perfix letter + /*21 gotprefix3 */ {ERR, 6, 4, ERR, ERR, ERR}, // dot: 3.x mapcode | det: got 4th prefix letter + /*22 whitespace */ {22, ERR, ERR, ERR, GO, ERR} // whitespace until end of string }; // pass fullcode=1 to recognise territory and mapcode, pass fullcode=0 to only recognise proper mapcode (without optional territory) // returns 0 if ok, negative in case of error (where -999 represents "may BECOME a valid mapcode if more characters are added) -int compareWithMapcodeFormat(const char *s, int fullcode) { +int compareWithMapcodeFormat(const char *s, int fullcode) +{ int nondigits = 0, vowels = 0; int state = (fullcode ? 0 : 18); // initial state + for (; ; s++) { int newstate, token; // recognise token: decode returns -2=a -3=e -4=0, 0..9 for digit or "o" or "i", 10..31 for char, -1 for illegal char @@ -1840,7 +1750,9 @@ int compareWithMapcodeFormat(const char *s, int fullcode) { token = TOKENCHR; // digit } else { // charcter B-Z token = TOKENCHR; - if (state != 11 && state != 12 && state != 13) { nondigits++; } + if (state != 11 && state != 12 && state != 13) { + nondigits++; + } } } newstate = fullmc_statemachine[state][token]; @@ -1875,15 +1787,28 @@ static int encodeLatLonToMapcodes_internal(char **v, Mapcodes *mapcodes, double enc.mapcodes = mapcodes; enc.mapcodes->count = 0; - if (lat < -90) { lat = -90; } - if (lat > 90) { lat = 90; } - while (lon < -180) { lon += 360; } - while (lon >= 180) { lon -= 360; } + if (lat < -90) + lat = -90; + if (lat > 90) + lat = 90; + while (lon < -180) + lon += 360; + while (lon >= 180) + lon -= 360; + #ifndef SUPPORT_HIGH_PRECISION - lat*=1000000; if (lat<0) lat-=0.5; else lat+=0.5; - lon*=1000000; if (lon<0) lon-=0.5; else lon+=0.5; - enc.lat32=(int)lat; - enc.lon32=(int)lon; + lat *= 1000000; + if (lat < 0) + lat -= 0.5; + else + lat += 0.5; + lon *= 1000000; + if (lon<0) + lon-=0.5; + else + lon+=0.5; + enc.lat32 = (int)lat; + enc.lon32 = (int)lon; #else // precise encoding: do NOT round, instead remember the fraction... lat += 90; lon += 180; @@ -1895,26 +1820,33 @@ static int encodeLatLonToMapcodes_internal(char **v, Mapcodes *mapcodes, double enc.fraclon = lon - enc.lon32; // for 8-digit precision, cells are divided into 810,000 by 810,000 minicells. enc.fraclat *= 810000; - if (enc.fraclat < 1) { enc.fraclat = 0; } else { + if (enc.fraclat < 1) { + enc.fraclat = 0; + } else { if (enc.fraclat > 809999) { enc.fraclat = 0; enc.lat32++; - } else { enc.fraclat /= 810000; } + } else { + enc.fraclat /= 810000; + } } enc.fraclon *= 810000; - if (enc.fraclon < 1) { enc.fraclon = 0; } else { + if (enc.fraclon < 1) { + enc.fraclon = 0; + } else { if (enc.fraclon > 809999) { enc.fraclon = 0; enc.lon32++; - } else { enc.fraclon /= 810000; } + } else { + enc.fraclon /= 810000; + } } enc.lat32 -= 90000000; enc.lon32 %= 360000000; enc.lon32 -= 180000000; #endif - if (tc <= 0) // ALL results? - { + if (tc <= 0) { // ALL results? #ifdef FAST_ENCODE int HOR = 1; int i = 0; // pointer into redivar @@ -1926,7 +1858,9 @@ static int encodeLatLonToMapcodes_internal(char **v, Mapcodes *mapcodes, double for (j = 0; j <= nr; j++) { int ctry = (j == nr ? ccode_earth : redivar[i + j]); encoderEngine(ctry, &enc, stop_with_one_result, extraDigits, -1); - if ((stop_with_one_result || debugStopAt >= 0) && enc.mapcodes->count > 0) { break; } + if ((stop_with_one_result || debugStopAt >= 0) && enc.mapcodes->count > 0) { + break; + } } break; } @@ -1941,20 +1875,18 @@ static int encodeLatLonToMapcodes_internal(char **v, Mapcodes *mapcodes, double } } #else - int i; - for(i=0;i=0) && enc.mapcodes->count>0) break; - } + for(int i = 0; i < MAX_MAPCODE_TERRITORY_CODE ; i++) { + encoderEngine(i, &enc, stop_with_one_result, extraDigits, -1); + if ((stop_with_one_result || debugStopAt >= 0) && enc.mapcodes->count > 0) + break; + } #endif - } - else { + } else { encoderEngine((tc - 1), &enc, stop_with_one_result, extraDigits, -1); } if (v) { - int i; - for (i = 0; i < enc.mapcodes->count; i++) { + for (int i = 0; i < enc.mapcodes->count; i++) { char *s = &enc.mapcodes->mapcode[i][0]; char *p = strchr(s, ' '); if (p == NULL) { @@ -1974,8 +1906,7 @@ static int encodeLatLonToMapcodes_internal(char **v, Mapcodes *mapcodes, double // threadsafe -char *getTerritoryIsoName(char *result, int territoryCode, - int format) // formats: 0=full 1=short (returns empty string in case of error) +char *getTerritoryIsoName(char *result, int territoryCode, int format) // formats: 0=full 1=short (returns empty string in case of error) { if (territoryCode < 1 || territoryCode > MAX_MAPCODE_TERRITORY_CODE) { *result = 0; @@ -1983,7 +1914,9 @@ char *getTerritoryIsoName(char *result, int territoryCode, int p = ParentLetter(territoryCode - 1); char iso3[4]; const char *ei = get_entity_iso3(iso3, territoryCode - 1); - if (*ei >= '0' && *ei <= '9') { ei++; } + if (*ei >= '0' && *ei <= '9') { + ei++; + } if (format == 0 && p) { memcpy(result, &parents2[p * 3 - 3], 2); result[2] = '-'; @@ -2000,16 +1933,19 @@ char *getTerritoryIsoName(char *result, int territoryCode, int getParentCountryOf(int tc) // returns negative if tc is not a code that has a parent country { int parentccode = ParentTerritoryOf(tc - 1); // returns parent ccode or -1 - if (parentccode >= 0) { return parentccode + 1; } + if (parentccode >= 0) { + return parentccode + 1; + } return -1; } -int getCountryOrParentCountry( - int tc) // returns tc if tc is a country, parent country if tc is a state, -1 if tc is invalid +int getCountryOrParentCountry(int tc) // returns tc if tc is a country, parent country if tc is a state, -1 if tc is invalid { if (tc > 0 && tc < MAX_MAPCODE_TERRITORY_CODE) { int tp = getParentCountryOf(tc); - if (tp > 0) { return tp; } + if (tp > 0) + return tp; + return tc; } return -1; @@ -2017,14 +1953,18 @@ int getCountryOrParentCountry( int convertTerritoryIsoNameToCode(const char *string, int optional_tc) // optional_tc: pass 0 or negative if unknown { + if (string == NULL) + return -1; + + while (*string > 0 && *string <= 32) { + string++; + } // skip leading whitespace + int ccode = optional_tc - 1; - if (string == NULL) { return -1; } - while (*string > 0 && *string <= 32) { string++; } // skip leading whitespace if (ccode < 0 || strchr(string, '-') || strlen(string) > 3) { ccode = ccode_of_iso3(string, -1); // ignore optional_tc - } - else // there is a ccode, there is no hyphen in the string, and the string is as most 3 chars - { + } else { + // there is a ccode, there is no hyphen in the string, and the string is as most 3 chars char tmp[12]; int tc = getCountryOrParentCountry(optional_tc); @@ -2033,24 +1973,25 @@ int convertTerritoryIsoNameToCode(const char *string, int optional_tc) // option strcat(tmp, string); ccode = ccode_of_iso3(tmp, -1); } - if (ccode < 0) { return -1; } else { return ccode + 1; } + if (ccode < 0) + return -1; + else + return ccode + 1; } // decode string into lat,lon; returns negative in case of error -int decodeMapcodeToLatLon(double *lat, double *lon, const char *input, - int context_tc) // context_tc is used to disambiguate ambiguous short mapcode inputs; pass 0 or negative if not available +// context_tc is used to disambiguate ambiguous short mapcode inputs; pass 0 or negative if not available +int decodeMapcodeToLatLon(double *lat, double *lon, const char *input, int context_tc) { if (lat == NULL || lon == NULL || input == NULL) { return -100; - } - else { - int ret; + } else { decodeRec dec; dec.orginput = input; dec.context = context_tc; - ret = decoderEngine(&dec); + int ret = decoderEngine(&dec); *lat = dec.lat; *lon = dec.lon; return ret; @@ -2063,7 +2004,7 @@ UWORD *convertToAlphabet(UWORD *unibuf, int maxlength, const char *mapcode, int { if (asc2lan[alphabet][4] == 0x003f) { // alphabet has no letter E if (strchr(mapcode, 'E') || strchr(mapcode, 'U') || strchr(mapcode, 'e') || - strchr(mapcode, 'u')) // v1.50 get rid of E and U + strchr(mapcode, 'u')) // v1.50 get rid of E and U { // safely copy mapcode into temporary buffer u char u[MAX_MAPCODE_RESULT_LEN]; @@ -2085,7 +2026,8 @@ UWORD *convertToAlphabet(UWORD *unibuf, int maxlength, const char *mapcode, int // Legacy: NOT threadsafe static char asciibuf[MAX_MAPCODE_RESULT_LEN]; -const char *decodeToRoman(const UWORD *s) { +const char *decodeToRoman(const UWORD *s) +{ return convertToRoman(asciibuf, MAX_MAPCODE_RESULT_LEN, s); } @@ -2099,7 +2041,8 @@ const UWORD *encodeToAlphabet(const char *mapcode, int alphabet) // 0=roman, 2=c #endif -int encodeLatLonToSingleMapcode(char *result, double lat, double lon, int tc, int extraDigits) { +int encodeLatLonToSingleMapcode(char *result, double lat, double lon, int tc, int extraDigits) +{ char *v[2]; Mapcodes rlocal; int ret = encodeLatLonToMapcodes_internal(v, &rlocal, lat, lon, tc, 1, extraDigits); @@ -2117,14 +2060,16 @@ int encodeLatLonToSingleMapcode(char *result, double lat, double lon, int tc, in } // Threadsafe -int encodeLatLonToMapcodes(Mapcodes *results, double lat, double lon, int territoryCode, int extraDigits) { +int encodeLatLonToMapcodes(Mapcodes *results, double lat, double lon, int territoryCode, int extraDigits) +{ return encodeLatLonToMapcodes_internal(NULL, results, lat, lon, territoryCode, 0, extraDigits); } // Legacy: NOT threadsafe Mapcodes rglobal; -int encodeLatLonToMapcodes_Deprecated(char **v, double lat, double lon, int territoryCode, int extraDigits) { +int encodeLatLonToMapcodes_Deprecated(char **v, double lat, double lon, int territoryCode, int extraDigits) +{ return encodeLatLonToMapcodes_internal(v, &rglobal, lat, lon, territoryCode, 0, extraDigits); } @@ -2132,9 +2077,12 @@ int encodeLatLonToMapcodes_Deprecated(char **v, double lat, double lon, int terr static char makeiso_bufbytes[16]; static char *makeiso_buf; -const char *convertTerritoryCodeToIsoName(int tc, int format) { - if (makeiso_buf == makeiso_bufbytes) { +const char *convertTerritoryCodeToIsoName(int tc, int format) +{ + if (makeiso_buf == makeiso_bufbytes) makeiso_buf = makeiso_bufbytes + 8; - } else { makeiso_buf = makeiso_bufbytes; } + else + makeiso_buf = makeiso_bufbytes; + return (const char *) getTerritoryIsoName(makeiso_buf, tc, format); } From adc345bf497018ab75fe4f44ba3e415830d38a67 Mon Sep 17 00:00:00 2001 From: Erik Bos Date: Mon, 17 Aug 2015 17:24:04 +0200 Subject: [PATCH 2/2] Prettified and tidied up code. Moved variable initialisation to place of first use. Removed uncessary braces to make functions more readable. Do not use braces for simple statements, do use them for complex ones. --- mapcodelib/mapcoder.c | 1934 ++++++++++++++++++++--------------------- 1 file changed, 941 insertions(+), 993 deletions(-) diff --git a/mapcodelib/mapcoder.c b/mapcodelib/mapcoder.c index 66daee9..6a7c43c 100644 --- a/mapcodelib/mapcoder.c +++ b/mapcodelib/mapcoder.c @@ -50,7 +50,7 @@ typedef struct { int context; // input territory context (or negative) const char *iso; // input territory alphacode (context) // output - double lat, lon; // result + double lat, lon; // result int lat32, lon32; // result in integer arithmetic (millionts of degrees) } decodeRec; @@ -61,9 +61,15 @@ typedef struct { // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -static int firstrec(int ccode) { return data_start[ccode]; } +static int firstrec(int ccode) +{ + return data_start[ccode]; +} -static int lastrec(int ccode) { return data_start[ccode + 1] - 1; } +static int lastrec(int ccode) +{ + return data_start[ccode + 1] - 1; +} static int ParentLetter(int ccode) // returns parent index (>0), or 0 { @@ -83,9 +89,13 @@ static int ParentTerritoryOf(int ccode) // returns parent, or -1 return parentnr[ParentLetter(ccode)]; } -static int isSubdivision(int ccode) { return (ParentTerritoryOf(ccode) >= 0); } +static int isSubdivision(int ccode) +{ + return (ParentTerritoryOf(ccode) >= 0); +} -static int coDex(int m) { +static int coDex(int m) +{ int c = mminfo[m].flags & 31; return 10 * (c / 5) + ((c % 5) + 1); } @@ -102,18 +112,29 @@ static int coDex(int m) { static int isInRange(int x, int minx, int maxx) // returns nonzero if x in the range minx...maxx { - if (minx <= x && x < maxx) { return 1; } - if (x < minx) { x += 360000000; } else { x -= 360000000; } // 1.32 fix FIJI edge case - if (minx <= x && x < maxx) { return 1; } + if (minx <= x && x < maxx) + return 1; + + // 1.32 fix FIJI edge case + if (x < minx) + x += 360000000; + else + x -= 360000000; + + if (minx <= x && x < maxx) + return 1; + return 0; } -static int fitsInside(int x, int y, int m) { +static int fitsInside(int x, int y, int m) +{ const mminforec *b = boundaries(m); return (b->miny <= y && y < b->maxy && isInRange(x, b->minx, b->maxx)); } -static int xDivider4(int miny, int maxy) { +static int xDivider4(int miny, int maxy) +{ if (miny >= 0) { // both above equator? then miny is closest return xdivider19[(miny) >> 19]; } @@ -123,7 +144,8 @@ static int xDivider4(int miny, int maxy) { return xdivider19[(-maxy) >> 19]; // both negative, so maxy is closest to equator } -static int fitsInsideWithRoom(int x, int y, int m) { +static int fitsInsideWithRoom(int x, int y, int m) +{ const mminforec *b = boundaries(m); int xdiv8 = xDivider4(b->miny, b->maxy) / 4; // should be /8 but there's some extra margin return (b->miny - 60 <= y && y < b->maxy + 60 && isInRange(x, b->minx - xdiv8, b->maxx + xdiv8)); @@ -135,38 +157,44 @@ static int fitsInsideWithRoom(int x, int y, int m) { // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -static const char *get_entity_iso3(char *entity_iso3_result, int ccode) { - if (ccode < 0 || ccode >= MAX_MAPCODE_TERRITORY_CODE) { ccode = ccode_earth; } // solve bad args +static const char *get_entity_iso3(char *entity_iso3_result, int ccode) +{ + if (ccode < 0 || ccode >= MAX_MAPCODE_TERRITORY_CODE) + ccode = ccode_earth; // solve bad args + memcpy(entity_iso3_result, entity_iso + ccode * 4, 3); entity_iso3_result[3] = 0; + return entity_iso3_result; } static int disambiguate_str(const char *s, int len) // returns disambiguation >=1, or negative if error { + if (s[0] == 0 || s[1] == 0) + return -27; // solve bad args + + if (len != 2 && len != 3) + return -923; // solve bad args + const char *p = (len == 2 ? parents2 : parents3); - const char *f; char country[4]; - if (s[0] == 0 || s[1] == 0) { return -27; } // solve bad args - if (len != 2 && len != 3) { return -923; } // solve bad args memcpy(country, s, len); country[len] = 0; - { - char *t; - for (t = country; *t != 0; t++) { - *t = (char) toupper(*t); - } - } - f = strstr(p, country); - if (f == NULL) { - return -23; - } // unknown country + + for (char *t = country; *t != 0; t++) + *t = (char) toupper(*t); + + char *f = strstr(p, country); + if (f == NULL) + return -23; // unknown country + return 1 + (int) ((f - p) / (len + 1)); } // returns coode, or negative if invalid -static int ccode_of_iso3(const char *in_iso, int parentcode) { +static int ccode_of_iso3(const char *in_iso, int parentcode) +{ const char *aliases = ALIASES; char iso[4]; const char *s; @@ -178,27 +206,28 @@ static int ccode_of_iso3(const char *in_iso, int parentcode) { parentcode = disambiguate_str(in_iso, 2); hyphenated = (parentcode > 0); in_iso += 3; - } - else if (in_iso[3] == '-') { + } else if (in_iso[3] == '-') { parentcode = disambiguate_str(in_iso, 3); hyphenated = (parentcode > 0); in_iso += 4; } } - } else { return -23; } // solve bad args + } else { + return -23; // solve bad args + } // make (uppercased) copy of at most three characters iso[0] = (char) toupper(in_iso[0]); - if (iso[0]) { iso[1] = (char) toupper(in_iso[1]); } - if (iso[1]) { iso[2] = (char) toupper(in_iso[2]); } + if (iso[0]) + iso[1] = (char) toupper(in_iso[1]); + if (iso[1]) + iso[2] = (char) toupper(in_iso[2]); iso[3] = 0; - if (iso[2] == 0 || iso[2] == ' ') // 2-letter iso code? - { + if (iso[2] == 0 || iso[2] == ' ') { // 2-letter iso code? static char disambiguate_iso3[4] = {'1', '?', '?', 0}; // cache for disambiguation - if (parentcode > 0) { + if (parentcode > 0) disambiguate_iso3[0] = (char) ('0' + parentcode); - } disambiguate_iso3[1] = iso[0]; disambiguate_iso3[2] = iso[1]; @@ -221,9 +250,8 @@ static int ccode_of_iso3(const char *in_iso, int parentcode) { // find the FIRST disambiguation option, if any for (s = entity_iso - 1; ;) { s = strstr(s + 1, disambiguate_iso3 + 1); - if (s == NULL) { + if (s == NULL) break; - } if (s && s[-1] >= '1' && s[-1] <= '9') { s--; break; @@ -233,9 +261,8 @@ static int ccode_of_iso3(const char *in_iso, int parentcode) { // find first disambiguation option in aliases, if any for (s = aliases - 1; ;) { s = strstr(s + 1, disambiguate_iso3 + 1); - if (s == NULL) { + if (s == NULL) break; - } if (s && s[-1] >= '1' && s[-1] <= '9') { memcpy(iso, s + 3, 3); s = strstr(entity_iso, iso); // search disambiguated 2-letter iso @@ -244,21 +271,20 @@ static int ccode_of_iso3(const char *in_iso, int parentcode) { } } - if (s == NULL) { + if (s == NULL) return -26; - } } - } - else { + } else { s = strstr(entity_iso, iso); // search 3-letter iso if (s == NULL || hyphenated) { const char *a = aliases; while (a) { a = strstr(a, iso); // search in aliases - if (a && a[3] == '=' && (a[4] > '9' || a[4] == (char) (48 + parentcode) || parentcode < 0)) { - memcpy(iso, a + 4, 3); - a = NULL; - s = strstr(entity_iso, iso); + if (a && a[3] == '=' && (a[4] > '9' || + a[4] == (char) (48 + parentcode) || parentcode < 0)) { + memcpy(iso, a + 4, 3); + a = NULL; + s = strstr(entity_iso, iso); } else { if (a) { a++; @@ -266,9 +292,8 @@ static int ccode_of_iso3(const char *in_iso, int parentcode) { } } } - if (s == NULL) { + if (s == NULL) return -23; - } } // return result return (int) ((s - entity_iso) / 4); @@ -286,63 +311,65 @@ static void encodeExtension(char *result, int extrax4, int extray, int dividerx4 const encodeRec *enc) // append extra characters to result for more precision { #ifndef SUPPORT_HIGH_PRECISION // old integer-arithmetic version - if (extraDigits<0) extraDigits=0; else if (extraDigits>2) extraDigits=2; - while (extraDigits-->0) - { - int gx=((30*extrax4)/dividerx4); - int gy=((30*extray )/dividery ); - int column1=(gx/6); - int column2=(gx%6); - int row1=(gy/5); - int row2=(gy%5); - // add postfix: - char *s = result+strlen(result); - *s++ = '-'; - *s++ = encode_chars[ row1*5+column1 ]; - if (extraDigits-->0) - *s++ = encode_chars[ row2*6+column2 ]; - *s++ = 0; - } + if (extraDigits < 0) + extraDigits = 0; + else if (extraDigits > 2) + extraDigits = 2; + + while (extraDigits-- > 0) { + int gx = (30 * extrax4) / dividerx4; + int gy = (30 * extray) / dividery; + int column1 = gx / 6; + int column2 = gx % 6; + int row1 = gy / 5; + int row2 = gy % 5; + // add postfix: + char *s = result + strlen(result); + *s++ = '-'; + *s++ = encode_chars[row1 * 5 + column1]; + if (extraDigits-->0) + *s++ = encode_chars[row2 * 6 + column2]; + *s++ = 0; + } #else // new floating-point version char *s = result + strlen(result); double encx = (extrax4 + 4 * enc->fraclon) / (dividerx4); double ency = (extray + enc->fraclat * ydirection) / (dividery); - if (extraDigits < 0) { extraDigits = 0; } else if (extraDigits > MAX_PRECISION_DIGITS) { + if (extraDigits < 0) + extraDigits = 0; + else if (extraDigits > MAX_PRECISION_DIGITS) extraDigits = MAX_PRECISION_DIGITS; - } - if (extraDigits > 0) { + if (extraDigits > 0) *s++ = '-'; - } while (extraDigits-- > 0) { - int gx, gy, column1, column2, row1, row2; - encx *= 30; - gx = (int) encx; - if (gx < 0) { + int gx = (int) encx; + if (gx < 0) gx = 0; - } else if (gx > 29) { + else if (gx > 29) gx = 29; - } + ency *= 30; - gy = (int) ency; - if (gy < 0) { + int gy = (int) ency; + if (gy < 0) gy = 0; - } else if (gy > 29) { + else if (gy > 29) gy = 29; - } - column1 = (gx / 6); - column2 = (gx % 6); - row1 = (gy / 5); - row2 = (gy % 5); + + int column1 = gx / 6; + int column2 = gx % 6; + int row1 = gy / 5; + int row2 = gy % 5; + // add postfix: *s++ = encode_chars[row1 * 5 + column1]; - if (extraDigits-- > 0) { + if (extraDigits-- > 0) *s++ = encode_chars[row2 * 6 + column2]; - } *s = 0; + encx -= gx; ency -= gy; } @@ -352,65 +379,76 @@ static void encodeExtension(char *result, int extrax4, int extray, int dividerx4 #define decodeChar(c) decode_chars[(unsigned char)c] // force c to be in range of the index, between 0 and 255 // this routine takes the integer-arithmeteic decoding results (in millionths of degrees), adds any floating-point precision digits, and returns the result (still in millionths) -static int decodeExtension(decodeRec *dec, int dividerx4, int dividery, int ydirection) { +static int decodeExtension(decodeRec *dec, int dividerx4, int dividery, + int ydirection) +{ const char *extrapostfix = dec->extension; #ifndef SUPPORT_HIGH_PRECISION // old integer-arithmetic version - int extrax,extray; + int extrax, extray; + if (*extrapostfix) { - int column1,row1,column2,row2,c1,c2; - c1 = extrapostfix[0]; - c1 = decodeChar(c1); - if (c1<0) c1=0; else if (c1>29) c1=29; - row1 =(c1/5); column1 = (c1%5); - c2 = (extrapostfix[1]) ? extrapostfix[1] : 72; // 72='H'=code 15=(3+2*6) - c2 = decodeChar(c2); - if (c2<0) c2=0; else if (c2>29) c2=29; - row2 =(c2/6); column2 = (c2%6); - - extrax = ((column1*12 + 2*column2 + 1)*dividerx4+120)/240; - extray = ((row1*10 + 2*row2 + 1)*dividery +30)/ 60; - } - else { - extrax = (dividerx4/8); - extray = (dividery/2); + c1 = decodeChar(extrapostfix[0]); + if (c1 < 0) + c1 = 0; + else if (c1 > 29) + c1 = 29; + int row1 =(c1 / 5); + int column1 = (c1 % 5); + + c2 = decodeChar(extrapostfix[1]) ? extrapostfix[1] : 72); // 72='H'=code 15=(3+2*6) + if (c2 < 0) + c2 = 0; + else if (c2 > 29) + c2 = 29; + int row2 =(c2 / 6); + int column2 = (c2 % 6); + + extrax = ((column1 * 12 + 2 * column2 + 1) * dividerx4 + 120) / 240; + extray = ((row1 * 10 + 2 * row2 + 1) * dividery +30) / 60; + } else { + extrax = dividerx4 / 8; + extray = dividery / 2; } extray *= ydirection; dec->lon32 = extrax + dec->lon32; dec->lat32 = extray + dec->lat32; #else // new floating-point version - double dividerx = dividerx4 / 4.0, processor = 1.0; + double dividerx = dividerx4 / 4.0; + double processor = 1.0; dec->lon = 0; dec->lat = 0; while (*extrapostfix) { - int column1, row1, column2, row2; + int c1 = decodeChar(*extrapostfix++); + if (c1 < 0 || c1 == 30) + return -1; // illegal extension character + + int row1 = c1 / 5; + int column1 = c1 % 5; + int column2, row2; double halfcolumn = 0; - int c1 = *extrapostfix++; - c1 = decodeChar(c1); - if (c1 < 0 || c1 == 30) { return -1; } // illegal extension character - row1 = (c1 / 5); - column1 = (c1 % 5); if (*extrapostfix) { int c2 = decodeChar(*extrapostfix++); - if (c2 < 0 || c2 == 30) { return -1; } // illegal extension character - row2 = (c2 / 6); - column2 = (c2 % 6); - } - else { + if (c2 < 0 || c2 == 30) { + return -1; // illegal extension character + } + row2 = c2 / 6; + column2 = c2 % 6; + } else { row2 = 2; halfcolumn = 0.5; column2 = 3; } processor *= 30; - dec->lon += ((column1 * 6 + column2)) / processor; - dec->lat += ((row1 * 5 + row2 - halfcolumn)) / processor; + dec->lon += (column1 * 6 + column2) / processor; + dec->lat += (row1 * 5 + row2 - halfcolumn) / processor; } - dec->lon += (0.5 / processor); - dec->lat += (0.5 / processor); + dec->lon += 0.5 / processor; + dec->lat += 0.5 / processor; dec->lon *= dividerx; - dec->lat *= (dividery * ydirection); + dec->lat *= dividery * ydirection; dec->lon += dec->lon32; dec->lat += dec->lat32; @@ -423,7 +461,6 @@ static int decodeExtension(decodeRec *dec, int dividerx4, int dividery, int ydir } - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // LOWEST-LEVEL BASE31 ENCODING/DECODING @@ -431,7 +468,8 @@ static int decodeExtension(decodeRec *dec, int dividerx4, int dividery, int ydir //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // encode 'value' into result[nrchars] -static void encodeBase31(char *result, int value, int nrchars) { +static void encodeBase31(char *result, int value, int nrchars) +{ result[nrchars] = 0; // zero-terminate! while (nrchars-- > 0) { result[nrchars] = encode_chars[value % 31]; @@ -440,11 +478,12 @@ static void encodeBase31(char *result, int value, int nrchars) { } // decode 'code' until either a dot or an end-of-string is encountered -static int decodeBase31(const char *code) { +static int decodeBase31(const char *code) +{ int value = 0; - while (*code != '.' && *code != 0) { + while (*code != '.' && *code != 0) value = value * 31 + decodeChar(*code++); - } + return value; } @@ -455,30 +494,27 @@ static int decodeBase31(const char *code) { // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -static void encode_triple(char *result, int difx, int dify) { - if (dify < 4 * 34) // first 4(x34) rows of 6(x28) wide - { +static void encode_triple(char *result, int difx, int dify) +{ + if (dify < 4 * 34) { // first 4(x34) rows of 6(x28) wide encodeBase31(result, ((difx / 28) + 6 * (dify / 34)), 1); encodeBase31(result + 1, ((difx % 28) * 34 + (dify % 34)), 2); - } - else // bottom row - { + } else { // bottom row encodeBase31(result, (difx / 24) + 24, 1); encodeBase31(result + 1, (difx % 24) * 40 + (dify - 136), 2); } } // encode_triple -static void decode_triple(const char *result, int *difx, int *dify) { +static void decode_triple(const char *result, int *difx, int *dify) +{ // decode the first character int c1 = decodeChar(*result++); if (c1 < 24) { int m = decodeBase31(result); *difx = (c1 % 6) * 28 + (m / 34); *dify = (c1 / 6) * 34 + (m % 34); - } - else // bottom row - { + } else { // bottom row int x = decodeBase31(result); *dify = (x % 40) + 136; *difx = (x / 40) + 24 * (c1 - 24); @@ -486,35 +522,33 @@ static void decode_triple(const char *result, int *difx, int *dify) { } // decode_triple - - - - - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // SECOND-LEVEL ECCODING/DECODING : GRID // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -static int encodeSixWide(int x, int y, int width, int height) { - int v; +static int encodeSixWide(int x, int y, int width, int height) +{ int D = 6; int col = x / 6; int maxcol = (width - 4) / 6; + if (col >= maxcol) { col = maxcol; D = width - maxcol * 6; } - v = (height * 6 * col) + (height - 1 - y) * D + (x - col * 6); - return v; + return (height * 6 * col) + (height - 1 - y) * D + (x - col * 6); } -static void decodeSixWide(int v, int width, int height, int *x, int *y) { + +static void decodeSixWide(int v, int width, int height, int *x, int *y) +{ int w; int D = 6; int col = v / (height * 6); int maxcol = (width - 4) / 6; + if (col >= maxcol) { col = maxcol; D = width - maxcol * 6; @@ -527,13 +561,16 @@ static void decodeSixWide(int v, int width, int height, int *x, int *y) { // decodes dec->mapcode in context of territory rectangle m -static int decodeGrid(decodeRec *dec, int m, int hasHeaderLetter) { +static int decodeGrid(decodeRec *dec, int m, int hasHeaderLetter) +{ const char *input = (hasHeaderLetter ? dec->mapcode + 1 : dec->mapcode); int codexlen = (int) (strlen(input) - 1); int prelen = (int) (strchr(input, '.') - input); char result[MAX_PROPER_MAPCODE_LEN + 1]; - if (codexlen > MAX_PROPER_MAPCODE_LEN) { return -109; } + if (codexlen > MAX_PROPER_MAPCODE_LEN) + return -109; + strcpy(result, input); if (prelen == 1 && codexlen == 5) { result[1] = result[2]; @@ -541,391 +578,340 @@ static int decodeGrid(decodeRec *dec, int m, int hasHeaderLetter) { prelen++; } - { - int postlen = codexlen - prelen; + int postlen = codexlen - prelen; + int divx; + int divy = smartDiv(m); + if (divy == 1) { + divx = xside[prelen]; + divy = yside[prelen]; + } else { + divx = (nc[prelen] / divy); + } - int divx, divy; + if (prelen == 4 && divx == xside[4] && divy == yside[4]) { + char t = result[1]; + result[1] = result[2]; + result[2] = t; + } - divy = smartDiv(m); - if (divy == 1) { - divx = xside[prelen]; - divy = yside[prelen]; - } - else { - int pw = nc[prelen]; - divx = (pw / divy); - } + int relx = 0, rely = 0, v = 0; + if (prelen <= MAXFITLONG) { + v = decodeBase31(result); - if (prelen == 4 && divx == xside[4] && divy == yside[4]) { - char t = result[1]; - result[1] = result[2]; - result[2] = t; + if (divx != divy && prelen > 2) { // D==6 special grid, useful when prefix is 3 or more, and not a nice 961x961 + decodeSixWide(v, divx, divy, &relx, &rely); // DECODE + } else { + relx = (v / divy); + rely = divy - 1 - (v % divy); } + } - { - int relx = 0, rely = 0, v = 0; - - if (prelen <= MAXFITLONG) { - v = decodeBase31(result); - - if (divx != divy && - prelen > 2) // D==6 special grid, useful when prefix is 3 or more, and not a nice 961x961 - { // DECODE - decodeSixWide(v, divx, divy, &relx, &rely); - } - else { - relx = (v / divy); - rely = divy - 1 - (v % divy); - } - - } - - { - const mminforec *b = boundaries(m); - int ygridsize = (b->maxy - b->miny + divy - 1) / divy; // lonlat per cell - int xgridsize = (b->maxx - b->minx + divx - 1) / divx; // lonlat per cell - - if (relx < 0 || rely < 0 || relx >= divx || rely >= divy) { - return -111; - } - - // and then encodde relative to THE CORNER of this cell - rely = b->miny + (rely * ygridsize); - relx = b->minx + (relx * xgridsize); - - { - int xp = xside[postlen]; - int dividerx = ((((xgridsize)) + xp - 1) / xp); - int yp = yside[postlen]; - int dividery = ((((ygridsize)) + yp - 1) / yp); - // decoderelative + const mminforec *b = boundaries(m); + int ygridsize = (b->maxy - b->miny + divy - 1) / divy; // lonlat per cell + int xgridsize = (b->maxx - b->minx + divx - 1) / divx; // lonlat per cell - { - char *r = result + prelen + 1; - int difx, dify; + if (relx < 0 || rely < 0 || relx >= divx || rely >= divy) + return -111; - if (postlen == 3) // decode special - { - decode_triple(r, &difx, &dify); - } - else { - int v2; - if (postlen == 4) { - char t = r[1]; - r[1] = r[2]; - r[2] = t; - } // swap - v2 = decodeBase31(r); - difx = (v2 / yp); - dify = (v2 % yp); - if (postlen == 4) { - char t = r[1]; - r[1] = r[2]; - r[2] = t; - } // swap back - } + // and then encode relative to THE CORNER of this cell + rely = b->miny + (rely * ygridsize); + relx = b->minx + (relx * xgridsize); - // reverse y-direction - dify = yp - 1 - dify; + int xp = xside[postlen]; + int dividerx = (((xgridsize)) + xp - 1) / xp; + int yp = yside[postlen]; + int dividery = (((ygridsize)) + yp - 1) / yp; - dec->lon32 = relx + (difx * dividerx); - dec->lat32 = rely + (dify * dividery); - return decodeExtension(dec, dividerx << 2, dividery, 1); // grid - } // decoderelative + // decoderelative + char *r = result + prelen + 1; + int difx, dify; - } - } - } + if (postlen == 3) { // decode special + decode_triple(r, &difx, &dify); + } else { + if (postlen == 4) { + char t = r[1]; + r[1] = r[2]; + r[2] = t; + } // swap + int v2 = decodeBase31(r); + difx = (v2 / yp); + dify = (v2 % yp); + if (postlen == 4) { + char t = r[1]; + r[1] = r[2]; + r[2] = t; + } // swap back } + // reverse y-direction + dify = yp - 1 - dify; + + dec->lon32 = relx + (difx * dividerx); + dec->lat32 = rely + (dify * dividery); + return decodeExtension(dec, dividerx << 2, dividery, 1); // grid + // decoderelative } -static void encodeGrid(char *result, const encodeRec *enc, int const m, int extraDigits, char headerLetter) { +static void encodeGrid(char *result, const encodeRec *enc, int const m, + int extraDigits, char headerLetter) +{ int y = enc->lat32, x = enc->lon32; const mminforec *b = boundaries(m); int orgcodex = coDex(m); int codexm = orgcodex; - if (codexm == 21) { codexm = 22; } - if (codexm == 14) { codexm = 23; } - - *result = 0; - if (headerLetter) { result++; } + if (codexm == 21) + codexm = 22; - { // encode - int divx, divy; - int prelen = codexm / 10; - int postlen = codexm % 10; + if (codexm == 14) + codexm = 23; - divy = smartDiv(m); - if (divy == 1) { - divx = xside[prelen]; - divy = yside[prelen]; - } - else { - int pw = nc[prelen]; - divx = (pw / divy); - } - - { // grid - int ygridsize = (b->maxy - b->miny + divy - 1) / divy; - int xgridsize = (b->maxx - b->minx + divx - 1) / divx; - int rely = y - b->miny; - int relx = x - b->minx; - - if (relx < 0) { - relx += 360000000; - x += 360000000; - } - else if (relx >= 360000000) // 1.32 fix FIJI edge case - { - relx -= 360000000; - x -= 360000000; - } - - rely /= ygridsize; - relx /= xgridsize; - - if (relx >= divx || rely >= divy) { return; } - - { // prefix - int v; - if (divx != divy && prelen > 2) { - v = encodeSixWide(relx, rely, divx, divy); - } else { - v = relx * divy + (divy - 1 - rely); - } - encodeBase31(result, v, prelen); - } // prefix + *result = 0; + if (headerLetter) + result++; - if (prelen == 4 && divx == xside[4] && divy == yside[4]) { - char t = result[1]; - result[1] = result[2]; - result[2] = t; - } + int prelen = codexm / 10; + int postlen = codexm % 10; - rely = b->miny + (rely * ygridsize); - relx = b->minx + (relx * xgridsize); + int divx; + int divy = smartDiv(m); + if (divy == 1) { + divx = xside[prelen]; + divy = yside[prelen]; + } else { + divx = (nc[prelen] / divy); + } - { // postfix - int dividery = ((((ygridsize)) + yside[postlen] - 1) / yside[postlen]); - int dividerx = ((((xgridsize)) + xside[postlen] - 1) / xside[postlen]); - int extrax, extray; + // grid + int ygridsize = (b->maxy - b->miny + divy - 1) / divy; + int xgridsize = (b->maxx - b->minx + divx - 1) / divx; + int rely = y - b->miny; + int relx = x - b->minx; + + if (relx < 0) { + relx += 360000000; + x += 360000000; + } else if (relx >= 360000000) { // 1.32 fix FIJI edge case + relx -= 360000000; + x -= 360000000; + } + rely /= ygridsize; + relx /= xgridsize; - { - char *resultptr = result + prelen; + if (relx >= divx || rely >= divy) + return; + // prefix + int v; + if (divx != divy && prelen > 2) + v = encodeSixWide(relx, rely, divx, divy); + else + v = relx * divy + (divy - 1 - rely); + encodeBase31(result, v, prelen); + + if (prelen == 4 && divx == xside[4] && divy == yside[4]) { + char t = result[1]; + result[1] = result[2]; + result[2] = t; + } - int difx = x - relx; - int dify = y - rely; + rely = b->miny + (rely * ygridsize); + relx = b->minx + (relx * xgridsize); - *resultptr++ = '.'; + // postfix + int dividery = (((ygridsize)) + yside[postlen] - 1) / yside[postlen]; + int dividerx = (((xgridsize)) + xside[postlen] - 1) / xside[postlen]; - extrax = difx % dividerx; - extray = dify % dividery; - difx /= dividerx; - dify /= dividery; + char *resultptr = result + prelen; + *resultptr++ = '.'; + int difx = x - relx; + int dify = y - rely; + int extrax = difx % dividerx; + int extray = dify % dividery; + difx /= dividerx; + dify /= dividery; - // reverse y-direction - dify = yside[postlen] - 1 - dify; + // reverse y-direction + dify = yside[postlen] - 1 - dify; - if (postlen == 3) // encode special - { - encode_triple(resultptr, difx, dify); - } - else { - encodeBase31(resultptr, (difx) * yside[postlen] + dify, postlen); - // swap 4-int codes for readability - if (postlen == 4) { - char t = resultptr[1]; - resultptr[1] = resultptr[2]; - resultptr[2] = t; - } - } - } + if (postlen == 3) { // encode special + encode_triple(resultptr, difx, dify); + } else { + encodeBase31(resultptr, (difx) * yside[postlen] + dify, postlen); + // swap 4-int codes for readability + if (postlen == 4) { + char t = resultptr[1]; + resultptr[1] = resultptr[2]; + resultptr[2] = t; + } + } - if (orgcodex == 14) { - result[2] = result[1]; - result[1] = '.'; - } + if (orgcodex == 14) { + result[2] = result[1]; + result[1] = '.'; + } - encodeExtension(result, extrax << 2, extray, dividerx << 2, dividery, extraDigits, 1, enc); // grid - if (headerLetter) { - result--; - *result = headerLetter; - } - } // postfix - } // grid - } // encode + encodeExtension(result, extrax << 2, extray, dividerx << 2, dividery, extraDigits, 1, enc); // grid + if (headerLetter) { + result--; + *result = headerLetter; + } } // find first territory rectangle of the same type as m -static int firstNamelessRecord(int m, int firstcode) { +static int firstNamelessRecord(int m, int firstcode) +{ int i = m; int codexm = coDex(m); - while (i >= firstcode && coDex(i) == codexm && isNameless(i)) { i--; } + + while (i >= firstcode && coDex(i) == codexm && isNameless(i)) + i--; + return (i + 1); } + // count all territory rectangles of the same type as m -static int countNamelessRecords(int m, int firstcode) { +static int countNamelessRecords(int m, int firstcode) +{ int i = firstNamelessRecord(m, firstcode); int codexm = coDex(m); - while (coDex(m) == codexm) { m++; } + + while (coDex(m) == codexm) + m++; + return (m - i); } // decodes dec->mapcode in context of territory rectangle m, territory dec->context // Returns negative in case of error -static int decodeNameless(decodeRec *dec, int m) { +static int decodeNameless(decodeRec *dec, int m) +{ int A, F; char input[8]; int codexm = coDex(m); int dc = (codexm != 22) ? 2 : 3; int codexlen = (int) (strlen(dec->mapcode) - 1); - if (codexlen != 4 && codexlen != 5) { - return -2; - } // solve bad args + if (codexlen != 4 && codexlen != 5) + return -2; // solve bad args // copy without dot strcpy(input, dec->mapcode); strcpy(input + dc, dec->mapcode + dc + 1); - A = countNamelessRecords(m, firstrec(dec->context)); F = firstNamelessRecord(m, firstrec(dec->context)); - { - int p = 31 / A; - int r = 31 % A; - int v = 0; - int SIDE; - int swapletters = 0; - int xSIDE; - int X; - const mminforec *b; - - // make copy of input, so we can swap around letters during the decoding - char result[32]; - strcpy(result, input); - - // now determine X = index of first area, and SIDE - if (codexm != 21 && A <= 31) { - int offset = decodeChar(*result); - - if (offset < r * (p + 1)) { - X = offset / (p + 1); - } - else { - swapletters = (p == 1 && codexm == 22); - X = r + (offset - (r * (p + 1))) / p; - } - } - else if (codexm != 21 && A < 62) { + int p = 31 / A; + int r = 31 % A; + int v = 0; + int swapletters = 0; + int X; - X = decodeChar(*result); - if (X < (62 - A)) { - swapletters = (codexm == 22); - } - else { - X = X + (X - (62 - A)); - } - } - else // code==21 || A>=62 - { - int BASEPOWER = (codexm == 21) ? 961 * 961 : 961 * 961 * 31; - int BASEPOWERA = (BASEPOWER / A); + // make copy of input, so we can swap around letters during the decoding + char result[32]; + strcpy(result, input); - if (A == 62) { BASEPOWERA++; } else { BASEPOWERA = 961 * (BASEPOWERA / 961); } + // now determine X = index of first area, and SIDE + if (codexm != 21 && A <= 31) { + int offset = decodeChar(*result); - v = decodeBase31(result); - X = (v / BASEPOWERA); - v %= BASEPOWERA; + if (offset < r * (p + 1)) { + X = offset / (p + 1); + } else { + swapletters = (p == 1 && codexm == 22); + X = r + (offset - (r * (p + 1))) / p; } + } else if (codexm != 21 && A < 62) { + X = decodeChar(*result); + if (X < (62 - A)) { + swapletters = (codexm == 22); + } else { + X = X + (X - (62 - A)); + } + } else { // code==21 || A>=62 + int BASEPOWER = (codexm == 21) ? 961 * 961 : 961 * 961 * 31; + int BASEPOWERA = (BASEPOWER / A); + + if (A == 62) + BASEPOWERA++; + else + BASEPOWERA = 961 * (BASEPOWERA / 961); + + v = decodeBase31(result); + X = (v / BASEPOWERA); + v %= BASEPOWERA; + } - - if (swapletters) { - if (!isSpecialShape22(F + X)) { - char t = result[codexlen - 3]; - result[codexlen - 3] = result[codexlen - 2]; - result[codexlen - 2] = t; - } + if (swapletters) { + if (!isSpecialShape22(F + X)) { + char t = result[codexlen - 3]; + result[codexlen - 3] = result[codexlen - 2]; + result[codexlen - 2] = t; } + } - if (codexm != 21 && A <= 31) { - v = decodeBase31(result); - if (X > 0) { - v -= (X * p + (X < r ? X : r)) * (961 * 961); - } + if (codexm != 21 && A <= 31) { + v = decodeBase31(result); + if (X > 0) { + v -= (X * p + (X < r ? X : r)) * (961 * 961); } - else if (codexm != 21 && A < 62) { - v = decodeBase31(result + 1); - if (X >= (62 - A)) { - if (v >= (16 * 961 * 31)) { - v -= (16 * 961 * 31); - X++; - } + } else if (codexm != 21 && A < 62) { + v = decodeBase31(result + 1); + if (X >= (62 - A)) { + if (v >= (16 * 961 * 31)) { + v -= (16 * 961 * 31); + X++; } } + } - m = (F + X); - - xSIDE = SIDE = smartDiv(m); - - b = boundaries(m); - if (isSpecialShape22(m)) { - xSIDE *= SIDE; - SIDE = 1 + ((b->maxy - b->miny) / 90); // side purely on y range - xSIDE = xSIDE / SIDE; - } - - // decode - { - int dx, dy; - - if (isSpecialShape22(m)) { - decodeSixWide(v, xSIDE, SIDE, &dx, &dy); - dy = SIDE - 1 - dy; - } - else { - dy = v % SIDE; - dx = v / SIDE; - } + m = (F + X); + int SIDE = smartDiv(m); + int xSIDE = SIDE; + const mminforec *b = boundaries(m); + if (isSpecialShape22(m)) { + xSIDE *= SIDE; + SIDE = 1 + ((b->maxy - b->miny) / 90); // side purely on y range + xSIDE = xSIDE / SIDE; + } + // decode + int dx, dy; + if (isSpecialShape22(m)) { + decodeSixWide(v, xSIDE, SIDE, &dx, &dy); + dy = SIDE - 1 - dy; + } else { + dy = v % SIDE; + dx = v / SIDE; + } - if (dx >= xSIDE) { - return -123; - } + if (dx >= xSIDE) + return -123; - { - int dividerx4 = xDivider4(b->miny, b->maxy); // *** note: dividerx4 is 4 times too large! - int dividery = 90; - int err; + int dividerx4 = xDivider4(b->miny, b->maxy); // *** note: dividerx4 is 4 times too large! + int dividery = 90; - dec->lon32 = b->minx + ((dx * dividerx4) / - 4); // *** note: FIRST multiply, then divide... more precise, larger rects - dec->lat32 = b->maxy - (dy * dividery); - err = decodeExtension(dec, dividerx4, dividery, -1); // nameless + dec->lon32 = b->minx + ((dx * dividerx4) / 4); // *** note: FIRST multiply, then divide... more precise, larger rects + dec->lat32 = b->maxy - (dy * dividery); + int err = decodeExtension(dec, dividerx4, dividery, -1); // nameless #ifdef SUPPORT_HIGH_PRECISION - dec->lon += ((dx * dividerx4) % 4) / 4.0; + dec->lon += ((dx * dividerx4) % 4) / 4.0; #endif - return err; - } - } - } + return err; } - -static void repack_if_alldigits(char *input, int aonly) { - char *s = input; +static void repack_if_alldigits(char *input, int aonly) +{ + char *e, *s = input; int alldigits = 1; // assume all digits - char *e; char *dotpos = NULL; for (e = s; *e != 0 && *e != '-'; e++) { @@ -940,18 +926,13 @@ static void repack_if_alldigits(char *input, int aonly) { } e--; s = e - 1; - if (alldigits && dotpos && - s > dotpos) // e is last char, s is one before, both are beyond dot, all characters are digits - { - if (aonly) // v1.50 - encode only using the letter A - { + if (alldigits && dotpos && s > dotpos) { // e is last char, s is one before, both are beyond dot, all characters are digits + if (aonly) { // v1.50 - encode only using the letter A int v = ((*input) - '0') * 100 + ((*s) - '0') * 10 + ((*e) - '0'); *input = 'A'; *s = encode_chars[v / 32]; *e = encode_chars[v % 32]; - } - else // encode using A,E,U - { + } else { // encode using A,E,U int v = ((*s) - '0') * 10 + ((*e) - '0'); *s = encode_chars[(v / 34) + 31]; *e = encode_chars[v % 34]; @@ -959,26 +940,26 @@ static void repack_if_alldigits(char *input, int aonly) { } } -static int unpack_if_alldigits( - char *input) // returns 1 if unpacked, 0 if left unchanged, negative if unchanged and an error was detected +static int unpack_if_alldigits(char *input) // returns 1 if unpacked, 0 if left unchanged, negative if unchanged and an error was detected { // rewrite all-digit codes char *s = input; char *dotpos = NULL; + int aonly = (*s == 'A' || *s == 'a'); - if (aonly) { s++; } //*** v1.50 + if (aonly) + s++; //*** v1.50 + for (; *s != 0 && s[2] != 0 && s[2] != '-'; s++) { - if (*s == '-') { + if (*s == '-') break; - } else if (*s == '.' && !dotpos) { + else if (*s == '.' && !dotpos) dotpos = s; - } else if (decodeChar(*s) < 0 || decodeChar(*s) > 9) { - return 0; - } // nondigit, so stop + else if (decodeChar(*s) < 0 || decodeChar(*s) > 9) + return 0; // nondigit, so stop } if (dotpos) { - if (aonly) // v1.50 encoded only with A's - { + if (aonly) { // v1.50 encoded only with A's int v = (s[0] == 'A' || s[0] == 'a' ? 31 : decodeChar(s[0])) * 32 + (s[1] == 'A' || s[1] == 'a' ? 31 : decodeChar(s[1])); *input = (char) ('0' + (v / 100)); @@ -987,25 +968,27 @@ static int unpack_if_alldigits( return 1; } // v1.50 - if (*s == 'a' || *s == 'e' || *s == 'u' || *s == 'A' || *s == 'E' || - *s == 'U') // thus, all digits, s[2]=0, after dot - { + if (*s == 'a' || *s == 'e' || *s == 'u' || + *s == 'A' || *s == 'E' || *s == 'U') { // thus, all digits, s[2]=0, after dot + char *e = s + 1; // s is vowel, e is lastchar int v = 0; - if (*s == 'e' || *s == 'E') { + if (*s == 'e' || *s == 'E') v = 34; - } else if (*s == 'u' || *s == 'U') { v = 68; } + else if (*s == 'u' || *s == 'U') + v = 68; - if (*e == 'a' || *e == 'A') { + if (*e == 'a' || *e == 'A') v += 31; - } else if (*e == 'e' || *e == 'E') { + else if (*e == 'e' || *e == 'E') v += 32; - } else if (*e == 'u' || *e == 'U') { + else if (*e == 'u' || *e == 'U') v += 33; - } else if (decodeChar(*e) < 0) { + else if (decodeChar(*e) < 0) return -9; // invalid last character! - } else { v += decodeChar(*e); } + else + v += decodeChar(*e); if (v < 100) { *s = encode_chars[(unsigned int) v / 10]; @@ -1018,146 +1001,120 @@ static int unpack_if_alldigits( } -/* -{ -} -*/ - // returns -1 (error), or m (also returns *result!=0 in case of success) -static int encodeNameless(char *result, const encodeRec *enc, int input_ctry, int extraDigits, int m) { +static int encodeNameless(char *result, const encodeRec *enc, + int input_ctry, int extraDigits, int m) +{ // determine how many nameless records there are (A), and which one is this (X)... int y = enc->lat32, x = enc->lon32; int A = countNamelessRecords(m, firstrec(input_ctry)); int X = m - firstNamelessRecord(m, firstrec(input_ctry)); *result = 0; + int p = 31 / A; + int r = 31 % A; // the first r items are p+1 - { - int p = 31 / A; - int r = 31 % A; // the first r items are p+1 - int codexm = coDex(m); - int codexlen = (codexm / 10) + (codexm % 10); - // determine side of square around centre - int SIDE; - - int storage_offset; - const mminforec *b; - - int xSIDE, orgSIDE; - - - if (codexm != 21 && A <= 31) { - storage_offset = (X * p + (X < r ? X : r)) * (961 * 961); // p=4,r=3: offset(X)={0,5,10,15,19,23,27}-31 - } - else if (codexm != 21 && A < 62) { - if (X < (62 - A)) { - storage_offset = X * (961 * 961); - } - else { - storage_offset = (62 - A + ((X - 62 + A) / 2)) * (961 * 961); - if ((X + A) & 1) { - storage_offset += (16 * 961 * 31); - } - } - } - else { - int BASEPOWER = (codexm == 21) ? 961 * 961 : 961 * 961 * 31; - int BASEPOWERA = (BASEPOWER / A); - if (A == 62) { - BASEPOWERA++; - } else { - BASEPOWERA = (961) * (BASEPOWERA / 961); - } - - storage_offset = X * BASEPOWERA; + int codexm = coDex(m); + int codexlen = (codexm / 10) + (codexm % 10); + int storage_offset; + if (codexm != 21 && A <= 31) { + storage_offset = (X * p + (X < r ? X : r)) * (961 * 961); // p=4,r=3: offset(X)={0,5,10,15,19,23,27}-31 + } else if (codexm != 21 && A < 62) { + if (X < (62 - A)) { + storage_offset = X * (961 * 961); + } else { + storage_offset = (62 - A + ((X - 62 + A) / 2)) * (961 * 961); + if ((X + A) & 1) + storage_offset += (16 * 961 * 31); } - SIDE = smartDiv(m); - + } else { + int BASEPOWER = (codexm == 21) ? 961 * 961 : 961 * 961 * 31; + int BASEPOWERA = (BASEPOWER / A); + if (A == 62) + BASEPOWERA++; + else + BASEPOWERA = (961) * (BASEPOWERA / 961); + storage_offset = X * BASEPOWERA; + } - b = boundaries(m); - orgSIDE = xSIDE = SIDE; - if (isSpecialShape22(m)) // - keep the existing rectangle! - { - SIDE = 1 + ((b->maxy - b->miny) / 90); // new side, based purely on y-distance - xSIDE = (orgSIDE * orgSIDE) / SIDE; - } + // determine side of square around centre + int SIDE = smartDiv(m); + int xSIDE = SIDE; + int orgSIDE = SIDE; + const mminforec *b = boundaries(m); + if (isSpecialShape22(m)) { // - keep the existing rectangle! + SIDE = 1 + ((b->maxy - b->miny) / 90); // new side, based purely on y-distance + xSIDE = (orgSIDE * orgSIDE) / SIDE; + } - if (fitsInside(x, y, m)) { - int v = storage_offset; + if (fitsInside(x, y, m)) { + int v = storage_offset; - int dividerx4 = xDivider4(b->miny, b->maxy); // *** note: dividerx4 is 4 times too large! + int dividerx4 = xDivider4(b->miny, b->maxy); // *** note: dividerx4 is 4 times too large! #ifdef SUPPORT_HIGH_PRECISION // precise encoding: take fraction into account! - int xFracture = (int) (4 * enc->fraclon); + int xFracture = (int) (4 * enc->fraclon); #else - int xFracture = 0; + int xFracture = 0; #endif - int dx = (4 * (x - b->minx) + xFracture) / dividerx4; // like div, but with floating point value - int extrax4 = (x - b->minx) * 4 - dx * dividerx4; // like modulus, but with floating point value + int dx = (4 * (x - b->minx) + xFracture) / dividerx4; // like div, but with floating point value + int extrax4 = (x - b->minx) * 4 - dx * dividerx4; // like modulus, but with floating point value - int dividery = 90; - int dy = (b->maxy - y) / dividery; // between 0 and SIDE-1 - int extray = (b->maxy - y) % dividery; + int dividery = 90; + int dy = (b->maxy - y) / dividery; // between 0 and SIDE-1 + int extray = (b->maxy - y) % dividery; #ifdef SUPPORT_HIGH_PRECISION // precise encoding: check if fraction takes this out of range - if (extray == 0 && enc->fraclat > 0) { - if (dy == 0) { - return -1; - } // fraction takes this coordinate out of range - dy--; - extray += dividery; + if (extray == 0 && enc->fraclat > 0) { + if (dy == 0) + return -1; // fraction takes this coordinate out of range - } + dy--; + extray += dividery; + } #endif - - if (isSpecialShape22(m)) { - v += encodeSixWide(dx, SIDE - 1 - dy, xSIDE, SIDE); - } - else { - v += (dx * SIDE + dy); - } - - encodeBase31(result, v, codexlen + 1); // nameless - { - int dotp = codexlen; - if (codexm == 13) { - dotp--; - } - memmove(result + dotp, result + dotp - 1, 4); - result[dotp - 1] = '.'; - } - - if (!isSpecialShape22(m)) { - if (codexm == 22 && A < 62 && orgSIDE == 961) { - char t = result[codexlen - 2]; - result[codexlen - 2] = result[codexlen]; - result[codexlen] = t; - } + if (isSpecialShape22(m)) + v += encodeSixWide(dx, SIDE - 1 - dy, xSIDE, SIDE); + else + v += (dx * SIDE + dy); + + encodeBase31(result, v, codexlen + 1); // nameless + int dotp = codexlen; + if (codexm == 13) + dotp--; + + memmove(result + dotp, result + dotp - 1, 4); + result[dotp - 1] = '.'; + + if (!isSpecialShape22(m)) { + if (codexm == 22 && A < 62 && orgSIDE == 961) { + char t = result[codexlen - 2]; + result[codexlen - 2] = result[codexlen]; + result[codexlen] = t; } + } - encodeExtension(result, extrax4, extray, dividerx4, dividery, extraDigits, -1, enc); // nameless + encodeExtension(result, extrax4, extray, dividerx4, dividery, extraDigits, -1, enc); // nameless - return m; + return m; - } // in range - } + } // in range return -1; } // decodes dec->mapcode in context of territory rectangle m -static int decodeAutoHeader(decodeRec *dec, int m) { +static int decodeAutoHeader(decodeRec *dec, int m) +{ const char *input = dec->mapcode; int codexm = coDex(m); char *dot = strchr(input, '.'); int STORAGE_START = 0; - int value; - if (dot == NULL) { + if (dot == NULL) return -201; - } - value = decodeBase31(input); // decode top + int value = decodeBase31(input); // decode top value *= (961 * 31); for (; coDex(m) == codexm && recType(m) > 1; m++) { @@ -1185,22 +1142,16 @@ static int decodeAutoHeader(decodeRec *dec, int m) { value -= STORAGE_START; value /= (961 * 31); - { - int difx, dify; - decode_triple(dot + 1, &difx, &dify); // decode bottom 3 chars - { - int vx = (value / (H / 176)) * 168 + difx; // is vx/168 - int vy = (value % (H / 176)) * 176 + dify; // is vy/176 - - dec->lat32 = b->maxy - vy * dividery; - dec->lon32 = b->minx + vx * dividerx; - if (dec->lon32 < b->minx || dec->lon32 >= b->maxx || dec->lat32 < b->miny || - dec->lat32 > b->maxy) // *** CAREFUL! do this test BEFORE adding remainder... - { - return -122; // invalid code - } - } - } + int difx, dify; + decode_triple(dot + 1, &difx, &dify); // decode bottom 3 chars + int vx = (value / (H / 176)) * 168 + difx; // is vx/168 + int vy = (value % (H / 176)) * 176 + dify; // is vy/176 + + dec->lat32 = b->maxy - vy * dividery; + dec->lon32 = b->minx + vx * dividerx; + if (dec->lon32 < b->minx || dec->lon32 >= b->maxx || dec->lat32 < b->miny || + dec->lat32 > b->maxy) // *** CAREFUL! do this test BEFORE adding remainder... + return -122; // invalid code return decodeExtension(dec, dividerx << 2, dividery, -1); // autoheader decode } @@ -1210,7 +1161,8 @@ static int decodeAutoHeader(decodeRec *dec, int m) { } // encode in m (know to fit) -static int encodeAutoHeader(char *result, const encodeRec *enc, int m, int extraDigits) { +static int encodeAutoHeader(char *result, const encodeRec *enc, int m, int extraDigits) +{ int i; int STORAGE_START = 0; int y = enc->lat32, x = enc->lon32; @@ -1218,9 +1170,8 @@ static int encodeAutoHeader(char *result, const encodeRec *enc, int m, int extra // search back to first of the group int firstindex = m; int codexm = coDex(m); - while (recType(firstindex - 1) > 1 && coDex(firstindex - 1) == codexm) { + while (recType(firstindex - 1) > 1 && coDex(firstindex - 1) == codexm) firstindex--; - } for (i = firstindex; coDex(i) == codexm; i++) { int W, H, xdiv, product; @@ -1263,7 +1214,6 @@ static int encodeAutoHeader(char *result, const encodeRec *enc, int m, int extra extray += dividery; } #endif - value += (vy / 176); // PIPELETTER ENCODE @@ -1274,7 +1224,6 @@ static int encodeAutoHeader(char *result, const encodeRec *enc, int m, int extra encodeExtension(result, extrax << 2, extray, dividerx << 2, dividery, extraDigits, -1, enc); // autoheader return m; } - STORAGE_START += product; } return i - 1; // return last autoheader record as the (failing) record @@ -1283,95 +1232,86 @@ static int encodeAutoHeader(char *result, const encodeRec *enc, int m, int extra static int debugStopAt = -1; -static void encoderEngine(int ccode, const encodeRec *enc, int stop_with_one_result, int extraDigits, - int result_override) { - int from, upto; - int y = enc->lat32, x = enc->lon32; - - if (enc == NULL || ccode < 0 || ccode > ccode_earth) { - return; - } // bad arguments +static void encoderEngine(int ccode, const encodeRec *enc, int stop_with_one_result, + int extraDigits, int result_override) +{ + if (enc == NULL || ccode < 0 || ccode > ccode_earth) + return; // bad arguments - from = firstrec(ccode); - upto = lastrec(ccode); + int from = firstrec(ccode); + int upto = lastrec(ccode); + int x = enc->lon32; + int y = enc->lat32; - if (ccode != ccode_earth) { - if (!fitsInside(x, y, upto)) { + if (ccode != ccode_earth) + if (!fitsInside(x, y, upto)) return; - } - } /////////////////////////////////////////////////////////// // look for encoding options /////////////////////////////////////////////////////////// - { - int i; - char result[128]; - int result_counter = 0; - - *result = 0; - for (i = from; i <= upto; i++) { - int codex = coDex(i); - if (codex < 54) { - if (fitsInside(x, y, i)) { - if (isNameless(i)) { - int ret = encodeNameless(result, enc, ccode, extraDigits, i); - if (ret >= 0) { - i = ret; - } - } - else if (recType(i) > 1) { - encodeAutoHeader(result, enc, i, extraDigits); - } - else if (i == upto && isRestricted(i) && - isSubdivision(ccode)) // if the last item is a reference to a state's country - { - // *** do a recursive call for the parent *** - encoderEngine(ParentTerritoryOf(ccode), enc, stop_with_one_result, extraDigits, ccode); - return; /**/ + char result[128]; + *result = 0; + int result_counter = 0; + + for (int i = from; i <= upto; i++) { + if (coDex(i) < 54) { + if (fitsInside(x, y, i)) { + if (isNameless(i)) { + int ret = encodeNameless(result, enc, ccode, extraDigits, i); + if (ret >= 0) { + i = ret; } - else // must be grid - { - if (result_counter > 0 || - !isRestricted(i)) // skip isRestricted records unless there already is a result - { - char headerletter = (char) ((recType(i) == 1) ? headerLetter(i) : 0); - encodeGrid(result, enc, i, extraDigits, headerletter); - } + } + else if (recType(i) > 1) { + encodeAutoHeader(result, enc, i, extraDigits); + // if the last item is a reference to a state's country + } else if (i == upto && isRestricted(i) && isSubdivision(ccode)) { + // *** do a recursive call for the parent *** + encoderEngine(ParentTerritoryOf(ccode), enc, stop_with_one_result, extraDigits, ccode); + return; + } else { // must be grid + // skip isRestricted records unless there already is a result + if (result_counter > 0 || !isRestricted(i)) { + char headerletter = (char) ((recType(i) == 1) ? headerLetter(i) : 0); + encodeGrid(result, enc, i, extraDigits, headerletter); } + } - // =========== handle result (if any) - if (*result) { - result_counter++; - - repack_if_alldigits(result, 0); - - if (debugStopAt < 0 || debugStopAt == i) { - int cc = (result_override >= 0 ? result_override : ccode); - if (*result && enc->mapcodes && enc->mapcodes->count < MAX_NR_OF_MAPCODE_RESULTS) { - char *s = enc->mapcodes->mapcode[enc->mapcodes->count++]; - if (cc == ccode_earth) - strcpy(s, result); - else { - getTerritoryIsoName(s, cc + 1, 0); - strcat(s, " "); - strcat(s, result); - } + // =========== handle result (if any) + if (*result) { + result_counter++; + + repack_if_alldigits(result, 0); + + if (debugStopAt < 0 || debugStopAt == i) { + int cc = (result_override >= 0 ? result_override : ccode); + if (*result && enc->mapcodes && enc->mapcodes->count < MAX_NR_OF_MAPCODE_RESULTS) { + char *s = enc->mapcodes->mapcode[enc->mapcodes->count++]; + if (cc == ccode_earth) { + strcpy(s, result); + } else { + getTerritoryIsoName(s, cc + 1, 0); + strcat(s, " "); + strcat(s, result); } - if (debugStopAt == i) { return; } } - if (stop_with_one_result) { return; } - *result = 0; // clear for next iteration + if (debugStopAt == i) + return; } + if (stop_with_one_result) + return; + *result = 0; // clear for next iteration } } - } // for i - } + } + } // for i } // returns nonzero if error -static int decoderEngine(decodeRec *dec) { +static int decoderEngine(decodeRec *dec) +{ int parentcode; int err; int ccode, len; @@ -1380,41 +1320,45 @@ static int decoderEngine(decodeRec *dec) { char *s = dec->minput; // copy input, cleaned of leading and trailing whitespace, into private, non-const buffer - { - const char *r = dec->orginput; - while (*r > 0 && *r <= 32) { r++; } // skip lead - len = (int) strlen(r); - if (len > MAX_MAPCODE_RESULT_LEN - 1) { len = MAX_MAPCODE_RESULT_LEN - 1; } - while (len > 0 && r[len - 1] >= 0 && r[len - 1] <= 32) { len--; } // remove trail - memcpy(s, r, len); - s[len] = 0; - } + const char *r = dec->orginput; + while (*r > 0 && *r <= 32) + r++; // skip lead + + len = (int) strlen(r); + if (len > MAX_MAPCODE_RESULT_LEN - 1) + len = MAX_MAPCODE_RESULT_LEN - 1; + while (len > 0 && r[len - 1] >= 0 && r[len - 1] <= 32) + len--; // remove trail + memcpy(s, r, len); + s[len] = 0; // make input (excluding territory) uppercase, and replace digits 0 and 1 with O and I - { - char *t = strchr(s, ' '); - if (t == NULL) { t = s; } - for (; *t != 0; t++) { - if (*t >= 'a' && *t <= 'z') { *t += ('A' - 'a'); } - if (*t == 'O') { *t = '0'; } - if (*t == 'I') { *t = '1'; } - } + char *t = strchr(s, ' '); + if (t == NULL) + t = s; + + for (; *t != 0; t++) { + if (*t >= 'a' && *t <= 'z') + *t += ('A' - 'a'); + if (*t == 'O') + *t = '0'; + if (*t == 'I') + *t = '1'; } // check if extension, determine length without extension minus = strchr(s + 4, '-'); - if (minus) { + if (minus) len = (int) (minus - s); - } // make sure there is valid context iso3 = convertTerritoryCodeToIsoName(dec->context, 0); // get context string (or empty string) - if (*iso3 == 0) { iso3 = "AAA"; } + if (*iso3 == 0) + iso3 = "AAA"; parentcode = disambiguate_str(iso3, (int) strlen(iso3)); // pass for future context disambiguation // insert context if none in input - if (len > 0 && len <= 9 && strchr(s, ' ') == 0) // just a non-international mapcode without a territory code? - { + if (len > 0 && len <= 9 && strchr(s, ' ') == 0) { // just a non-international mapcode without a territory code? int ilen = (int) strlen(iso3); memmove(s + ilen + 1, s, strlen(s) + 1); s[ilen] = ' '; @@ -1424,210 +1368,193 @@ static int decoderEngine(decodeRec *dec) { } // parse off extension s[len] = 0; - if (minus) { + if (minus) dec->extension = &s[len + 1]; - } else { + else dec->extension = ""; - } // now split off territory, make point to start of proper mapcode - if (len > 8 && (s[3] == ' ' || s[3] == '-') && - (s[6] == ' ' || s[7] == ' ')) // assume ISO3 space|minus ISO23 space MAPCODE - { + // assume ISO3 space|minus ISO23 space MAPCODE + if (len > 8 && (s[3] == ' ' || s[3] == '-') && (s[6] == ' ' || s[7] == ' ')) { parentcode = disambiguate_str(s, 3); - if (parentcode < 0) { return parentcode; } + if (parentcode < 0) + return parentcode; + s += 4; len -= 4; - } - else if (len > 7 && (s[2] == ' ' || s[2] == '-') && - (s[5] == ' ' || s[6] == ' ')) // assume ISO2 space|minus ISO23 space MAPCODE - { - parentcode = disambiguate_str(s, 2); - if (parentcode < 0) { return parentcode; } - s += 3; - len -= 3; + } else { + // assume ISO2 space|minus ISO23 space MAPCODE + if (len > 7 && (s[2] == ' ' || s[2] == '-') && (s[5] == ' ' || s[6] == ' ')) { + parentcode = disambiguate_str(s, 2); + if (parentcode < 0) + return parentcode; + + s += 3; + len -= 3; + } } - if (len > 4 && s[3] == ' ') // assume ISO whitespace MAPCODE, overriding iso3 - { + // assume ISO whitespace MAPCODE, overriding iso3 + if (len > 4 && s[3] == ' ') { iso3 = s; // overrides iso code! s += 4; len -= 4; - } - else if (len > 3 && s[2] == ' ') // assume ISO2 whitespace MAPCODE, overriding iso3 - { + } else if (len > 3 && s[2] == ' ') { // assume ISO2 whitespace MAPCODE, overriding iso3 iso3 = s; // overrides iso code! s += 3; len -= 3; } + // skip further whitespace while (*s > 0 && *s <= 32) { s++; len--; - } // skip further whitespace + } // returns nonzero if error + // special case for mexico country vs state ccode = ccode_of_iso3(iso3, parentcode); - if (ccode == ccode_mex && len < 8) { ccode = ccode_of_iso3("5MX", -1); } // special case for mexico country vs state + if (ccode == ccode_mex && len < 8) + ccode = ccode_of_iso3("5MX", -1); // master_decode(s,ccode) - { - const char *dot = NULL; // dot position in input - int prelen; // input prefix length - int postlen; // input postfix length - int codex; // input codex - int from, upto; // record range for territory - int i; - - - // unpack digits (a-lead or aeu-encoded - int voweled = unpack_if_alldigits(s); - if (voweled < 0) { - return -7; - } + // unpack digits (a-lead or aeu-encoded + int voweled = unpack_if_alldigits(s); + if (voweled < 0) + return -7; - // debug support: U-lead pre-processing - if (*s == 'u' || *s == 'U') { - s++; - len--; - voweled = 1; - } + // debug support: U-lead pre-processing + if (*s == 'u' || *s == 'U') { + s++; + len--; + voweled = 1; + } - if (len > 10) { return -8; } + if (len > 10) + return -8; - // find dot and check that all characters are valid - { - int nrd = 0; // nr of true digits - const char *r = s; - for (; *r != 0; r++) { - if (*r == '.') { - if (dot) { - return -5; - } // more than one dot - dot = r; - } - else if (decodeChar(*r) < 0) { // invalid char? - return -4; - } else if (decodeChar(*r) < 10) { // digit? - nrd++; - } - } - if (dot == NULL) { - return -2; - } else if (!voweled && nrd + 1 == len) { // everything but the dot is digit, so MUST be voweled! - return -998; + // find dot and check that all characters are valid + int nrd = 0; // nr of true digits + const char *dot = NULL; // dot position in input + for (r = s; *r != 0; r++) { + if (*r == '.') { + if (dot) { + return -5; // more than one dot } + dot = r; + } else if (decodeChar(*r) < 0) { // invalid char? + return -4; + } else if (decodeChar(*r) < 10) { // digit? + nrd++; } + } + if (dot == NULL) + return -2; + else if (!voweled && nrd + 1 == len) // everything but the dot is digit, so MUST be voweled! + return -998; //////////// AT THIS POINT, dot=FIRST DOT, input=CLEAN INPUT (no vowels) ilen=INPUT LENGTH - // analyse input - prelen = (int) (dot - s); - postlen = len - 1 - prelen; - codex = prelen * 10 + postlen; - if (prelen < 2 || prelen > 5 || postlen < 2 || postlen > 4) { - return -3; - } - - if (len == 10) { - // international mapcodes must be in international context - ccode = ccode_earth; - } - else if (isSubdivision(ccode)) { - // int mapcodes must be interpreted in the parent of a subdivision - - int parent = ParentTerritoryOf(ccode); - if (len == 9 || (len == 8 && (parent == ccode_ind || parent == ccode_mex))) { - ccode = parent; - } - } + // analyse input + int prelen = (int) (dot - s); + int postlen = len - 1 - prelen; + int codex = prelen * 10 + postlen; + if (prelen < 2 || prelen > 5 || postlen < 2 || postlen > 4) + return -3; + + if (len == 10) { + // international mapcodes must be in international context + ccode = ccode_earth; + } else if (isSubdivision(ccode)) { + // int mapcodes must be interpreted in the parent of a subdivision + + int parent = ParentTerritoryOf(ccode); + if (len == 9 || (len == 8 && (parent == ccode_ind || parent == ccode_mex))) + ccode = parent; + } - // remember final territory context - dec->context = ccode; - dec->mapcode = s; - - err = -817; - from = firstrec(ccode); - upto = lastrec(ccode); - - // try all ccode rectangles to decode s (pointing to first character of proper mapcode) - for (i = from; i <= upto; i++) { - int codexi = coDex(i); - if (recType(i) == 0 && !isNameless(i) && (codexi == codex || (codex == 22 && codexi == 21))) { - err = decodeGrid(dec, i, 0); - - if (isRestricted(i)) { - int fitssomewhere = 0; - int j; - for (j = i - 1; j >= from; j--) { // look in previous rects - if (!isRestricted((j))) { - if (fitsInsideWithRoom(dec->lon32, dec->lat32, j)) { - fitssomewhere = 1; - break; - } + // remember final territory context + dec->context = ccode; + dec->mapcode = s; + + err = -817; + int from = firstrec(ccode); + int upto = lastrec(ccode); + + // try all ccode rectangles to decode s (pointing to first character of proper mapcode) + for (int i = from; i <= upto; i++) { + int codexi = coDex(i); + if (recType(i) == 0 && !isNameless(i) && (codexi == codex || (codex == 22 && codexi == 21))) { + err = decodeGrid(dec, i, 0); + + if (isRestricted(i)) { + int fitssomewhere = 0; + int j; + for (j = i - 1; j >= from; j--) { // look in previous rects + if (!isRestricted((j))) { + if (fitsInsideWithRoom(dec->lon32, dec->lat32, j)) { + fitssomewhere = 1; + break; } } - if (!fitssomewhere) { - err = -1234; - } } - - break; - } - else if (recType(i) == 1 && prefixLength(i) + 1 == prelen && postfixLength(i) == postlen && - headerLetter(i) == *s) { - err = decodeGrid(dec, i, 1); - break; - } - else if (isNameless(i) && - ((codexi == 21 && codex == 22) - || (codexi == 22 && codex == 32) - || (codexi == 13 && codex == 23))) { - err = decodeNameless(dec, i); - break; - } - else if (recType(i) >= 2 && postlen == 3 && prefixLength(i) + postfixLength(i) == prelen + 2) { - err = decodeAutoHeader(dec, i); - break; + if (!fitssomewhere) { + err = -1234; + } } - } // for - } - + break; + } else if (recType(i) == 1 && prefixLength(i) + 1 == prelen && postfixLength(i) == postlen && + headerLetter(i) == *s) { + err = decodeGrid(dec, i, 1); + break; + } else if (isNameless(i) && + ((codexi == 21 && codex == 22) || + (codexi == 22 && codex == 32) || + (codexi == 13 && codex == 23))) { + err = decodeNameless(dec, i); + break; + } else if (recType(i) >= 2 && postlen == 3 && prefixLength(i) + postfixLength(i) == prelen + 2) { + err = decodeAutoHeader(dec, i); + break; + } + } // for #ifdef SUPPORT_HIGH_PRECISION // convert from millionths if (err) { dec->lat = dec->lon = 0; - } - else { + } else { dec->lat /= (double) 1000000.0; dec->lon /= (double) 1000000.0; } #else // convert from millionths - if (err) dec->lat32 = dec->lon32 = 0; - dec->lat = dec->lat32/(double)1000000.0; - dec->lon = dec->lon32/(double)1000000.0; + if (err) + dec->lat32 = dec->lon32 = 0; + + dec->lat = dec->lat32 / (double)1000000.0; + dec->lon = dec->lon32 / (double)1000000.0; #endif // normalise between =180 and 180 - if (dec->lat < -90.0) { dec->lat = -90.0; } - if (dec->lat > 90.0) { dec->lat = 90.0; } - if (dec->lon < -180.0) { dec->lon += 360.0; } - if (dec->lon >= 180.0) { dec->lon -= 360.0; } + if (dec->lat < -90.0) + dec->lat = -90.0; + if (dec->lat > 90.0) + dec->lat = 90.0; + if (dec->lon < -180.0) + dec->lon += 360.0; + if (dec->lon >= 180.0) + dec->lon -= 360.0; // store as integers for legacy's sake dec->lat32 = (int) (dec->lat * 1000000); dec->lon32 = (int) (dec->lon * 1000000); // make sure decode result fits the country - if (err == 0) { - if (ccode != ccode_earth) { - if (!fitsInsideWithRoom(dec->lon32, dec->lat32, lastrec(ccode))) { + if (err == 0) + if (ccode != ccode_earth) + if (!fitsInsideWithRoom(dec->lon32, dec->lat32, lastrec(ccode))) err = -2222; - } - } - } return err; } @@ -1636,72 +1563,75 @@ static int decoderEngine(decodeRec *dec) { #ifdef SUPPORT_FOREIGN_ALPHABETS // WARNING - these alphabets have NOT yet been released as standard! use at your own risk! check www.mapcode.com for details. -static UWORD asc2lan[MAX_LANGUAGES][36] = // A-Z equivalents for ascii characters A to Z, 0-9 - { - {0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039}, // roman - {0x0391, 0x0392, 0x039e, 0x0394, 0x003f, 0x0395, 0x0393, 0x0397, 0x0399, 0x03a0, 0x039a, 0x039b, 0x039c, 0x039d, 0x039f, 0x03a1, 0x0398, 0x03a8, 0x03a3, 0x03a4, 0x003f, 0x03a6, 0x03a9, 0x03a7, 0x03a5, 0x0396, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039}, // greek - {0x0410, 0x0412, 0x0421, 0x0414, 0x0415, 0x0416, 0x0413, 0x041d, 0x0418, 0x041f, 0x041a, 0x041b, 0x041c, 0x0417, 0x041e, 0x0420, 0x0424, 0x042f, 0x0426, 0x0422, 0x042d, 0x0427, 0x0428, 0x0425, 0x0423, 0x0411, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039}, // cyrillic - {0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05e3, 0x05d4, 0x05d6, 0x05d7, 0x05d5, 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05e1, 0x05dd, 0x05de, 0x05e0, 0x05e2, 0x05e4, 0x05e5, 0x05e6, 0x05e7, 0x05e8, 0x05e9, 0x05ea, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039}, // hebrew - {0x0905, 0x0915, 0x0917, 0x0918, 0x090f, 0x091a, 0x091c, 0x091f, 0x003f, 0x0920, 0x0923, 0x0924, 0x0926, 0x0927, 0x003f, 0x0928, 0x092a, 0x092d, 0x092e, 0x0930, 0x092b, 0x0932, 0x0935, 0x0938, 0x0939, 0x0921, 0x0966, 0x0967, 0x0968, 0x0969, 0x096a, 0x096b, 0x096c, 0x096d, 0x096e, 0x096f}, // hindi - {0x0d12, 0x0d15, 0x0d16, 0x0d17, 0x0d0b, 0x0d1a, 0x0d1c, 0x0d1f, 0x0d07, 0x0d21, 0x0d24, 0x0d25, 0x0d26, 0x0d27, 0x0d20, 0x0d28, 0x0d2e, 0x0d30, 0x0d31, 0x0d32, 0x0d09, 0x0d34, 0x0d35, 0x0d36, 0x0d38, 0x0d39, 0x0d66, 0x0d67, 0x0d68, 0x0d69, 0x0d6a, 0x0d6b, 0x0d6c, 0x0d6d, 0x0d6e, 0x0d6f}, // malay - {0x10a0, 0x10a1, 0x10a3, 0x10a6, 0x10a4, 0x10a9, 0x10ab, 0x10ac, 0x10b3, 0x10ae, 0x10b0, 0x10b1, 0x10b2, 0x10b4, 0x10ad, 0x10b5, 0x10b6, 0x10b7, 0x10b8, 0x10b9, 0x10a8, 0x10ba, 0x10bb, 0x10bd, 0x10be, 0x10bf, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039}, // Georgian - {0x30a2, 0x30ab, 0x30ad, 0x30af, 0x30aa, 0x30b1, 0x30b3, 0x30b5, 0x30a4, 0x30b9, 0x30c1, 0x30c8, 0x30ca, 0x30cc, 0x30a6, 0x30d2, 0x30d5, 0x30d8, 0x30db, 0x30e1, 0x30a8, 0x30e2, 0x30e8, 0x30e9, 0x30ed, 0x30f2, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039}, // Katakana - {0x0e30, 0x0e01, 0x0e02, 0x0e04, 0x0e32, 0x0e07, 0x0e08, 0x0e09, 0x0e31, 0x0e0a, 0x0e11, 0x0e14, 0x0e16, 0x0e17, 0x0e0d, 0x0e18, 0x0e1a, 0x0e1c, 0x0e21, 0x0e23, 0x0e2c, 0x0e25, 0x0e27, 0x0e2d, 0x0e2e, 0x0e2f, 0x0e50, 0x0e51, 0x0e52, 0x0e53, 0x0e54, 0x0e55, 0x0e56, 0x0e57, 0x0e58, 0x0e59}, // Thai - {0x0eb0, 0x0e81, 0x0e82, 0x0e84, 0x0ec3, 0x0e87, 0x0e88, 0x0e8a, 0x0ec4, 0x0e8d, 0x0e94, 0x0e97, 0x0e99, 0x0e9a, 0x0ec6, 0x0e9c, 0x0e9e, 0x0ea1, 0x0ea2, 0x0ea3, 0x0ebd, 0x0ea7, 0x0eaa, 0x0eab, 0x0ead, 0x0eaf, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039}, // Laos - {0x0556, 0x0532, 0x0533, 0x0534, 0x0535, 0x0538, 0x0539, 0x053a, 0x053b, 0x053d, 0x053f, 0x0540, 0x0541, 0x0543, 0x0555, 0x0547, 0x0548, 0x054a, 0x054d, 0x054e, 0x0545, 0x054f, 0x0550, 0x0551, 0x0552, 0x0553, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039}, // armenian - {0x0985, 0x098c, 0x0995, 0x0996, 0x098f, 0x0997, 0x0999, 0x099a, 0x003f, 0x099d, 0x09a0, 0x09a1, 0x09a2, 0x09a3, 0x003f, 0x09a4, 0x09a5, 0x09a6, 0x09a8, 0x09aa, 0x0993, 0x09ac, 0x09ad, 0x09af, 0x09b2, 0x09b9, 0x09e6, 0x09e7, 0x09e8, 0x09e9, 0x09ea, 0x09eb, 0x09ec, 0x09ed, 0x09ee, 0x09ef}, // Bengali - {0x0a05, 0x0a15, 0x0a17, 0x0a18, 0x0a0f, 0x0a1a, 0x0a1c, 0x0a1f, 0x003f, 0x0a20, 0x0a23, 0x0a24, 0x0a26, 0x0a27, 0x003f, 0x0a28, 0x0a2a, 0x0a2d, 0x0a2e, 0x0a30, 0x0a2b, 0x0a32, 0x0a35, 0x0a38, 0x0a39, 0x0a21, 0x0a66, 0x0a67, 0x0a68, 0x0a69, 0x0a6a, 0x0a6b, 0x0a6c, 0x0a6d, 0x0a6e, 0x0a6f}, // Gurmukhi - {0x0f58, 0x0f40, 0x0f41, 0x0f42, 0x0f64, 0x0f44, 0x0f45, 0x0f46, 0x003f, 0x0f47, 0x0f4a, 0x0f4c, 0x0f4e, 0x0f4f, 0x003f, 0x0f51, 0x0f53, 0x0f54, 0x0f56, 0x0f5e, 0x0f65, 0x0f5f, 0x0f61, 0x0f62, 0x0f63, 0x0f66, 0x0f20, 0x0f21, 0x0f22, 0x0f23, 0x0f24, 0x0f25, 0x0f26, 0x0f27, 0x0f28, 0x0f29}, // Tibetan - }; +// A-Z equivalents for ascii characters A to Z, 0-9 +static UWORD asc2lan[MAX_LANGUAGES][36] = { + {0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039}, // roman + {0x0391, 0x0392, 0x039e, 0x0394, 0x003f, 0x0395, 0x0393, 0x0397, 0x0399, 0x03a0, 0x039a, 0x039b, 0x039c, 0x039d, 0x039f, 0x03a1, 0x0398, 0x03a8, 0x03a3, 0x03a4, 0x003f, 0x03a6, 0x03a9, 0x03a7, 0x03a5, 0x0396, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039}, // greek + {0x0410, 0x0412, 0x0421, 0x0414, 0x0415, 0x0416, 0x0413, 0x041d, 0x0418, 0x041f, 0x041a, 0x041b, 0x041c, 0x0417, 0x041e, 0x0420, 0x0424, 0x042f, 0x0426, 0x0422, 0x042d, 0x0427, 0x0428, 0x0425, 0x0423, 0x0411, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039}, // cyrillic + {0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05e3, 0x05d4, 0x05d6, 0x05d7, 0x05d5, 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05e1, 0x05dd, 0x05de, 0x05e0, 0x05e2, 0x05e4, 0x05e5, 0x05e6, 0x05e7, 0x05e8, 0x05e9, 0x05ea, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039}, // hebrew + {0x0905, 0x0915, 0x0917, 0x0918, 0x090f, 0x091a, 0x091c, 0x091f, 0x003f, 0x0920, 0x0923, 0x0924, 0x0926, 0x0927, 0x003f, 0x0928, 0x092a, 0x092d, 0x092e, 0x0930, 0x092b, 0x0932, 0x0935, 0x0938, 0x0939, 0x0921, 0x0966, 0x0967, 0x0968, 0x0969, 0x096a, 0x096b, 0x096c, 0x096d, 0x096e, 0x096f}, // hindi + {0x0d12, 0x0d15, 0x0d16, 0x0d17, 0x0d0b, 0x0d1a, 0x0d1c, 0x0d1f, 0x0d07, 0x0d21, 0x0d24, 0x0d25, 0x0d26, 0x0d27, 0x0d20, 0x0d28, 0x0d2e, 0x0d30, 0x0d31, 0x0d32, 0x0d09, 0x0d34, 0x0d35, 0x0d36, 0x0d38, 0x0d39, 0x0d66, 0x0d67, 0x0d68, 0x0d69, 0x0d6a, 0x0d6b, 0x0d6c, 0x0d6d, 0x0d6e, 0x0d6f}, // malay + {0x10a0, 0x10a1, 0x10a3, 0x10a6, 0x10a4, 0x10a9, 0x10ab, 0x10ac, 0x10b3, 0x10ae, 0x10b0, 0x10b1, 0x10b2, 0x10b4, 0x10ad, 0x10b5, 0x10b6, 0x10b7, 0x10b8, 0x10b9, 0x10a8, 0x10ba, 0x10bb, 0x10bd, 0x10be, 0x10bf, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039}, // Georgian + {0x30a2, 0x30ab, 0x30ad, 0x30af, 0x30aa, 0x30b1, 0x30b3, 0x30b5, 0x30a4, 0x30b9, 0x30c1, 0x30c8, 0x30ca, 0x30cc, 0x30a6, 0x30d2, 0x30d5, 0x30d8, 0x30db, 0x30e1, 0x30a8, 0x30e2, 0x30e8, 0x30e9, 0x30ed, 0x30f2, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039}, // Katakana + {0x0e30, 0x0e01, 0x0e02, 0x0e04, 0x0e32, 0x0e07, 0x0e08, 0x0e09, 0x0e31, 0x0e0a, 0x0e11, 0x0e14, 0x0e16, 0x0e17, 0x0e0d, 0x0e18, 0x0e1a, 0x0e1c, 0x0e21, 0x0e23, 0x0e2c, 0x0e25, 0x0e27, 0x0e2d, 0x0e2e, 0x0e2f, 0x0e50, 0x0e51, 0x0e52, 0x0e53, 0x0e54, 0x0e55, 0x0e56, 0x0e57, 0x0e58, 0x0e59}, // Thai + {0x0eb0, 0x0e81, 0x0e82, 0x0e84, 0x0ec3, 0x0e87, 0x0e88, 0x0e8a, 0x0ec4, 0x0e8d, 0x0e94, 0x0e97, 0x0e99, 0x0e9a, 0x0ec6, 0x0e9c, 0x0e9e, 0x0ea1, 0x0ea2, 0x0ea3, 0x0ebd, 0x0ea7, 0x0eaa, 0x0eab, 0x0ead, 0x0eaf, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039}, // Laos + {0x0556, 0x0532, 0x0533, 0x0534, 0x0535, 0x0538, 0x0539, 0x053a, 0x053b, 0x053d, 0x053f, 0x0540, 0x0541, 0x0543, 0x0555, 0x0547, 0x0548, 0x054a, 0x054d, 0x054e, 0x0545, 0x054f, 0x0550, 0x0551, 0x0552, 0x0553, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039}, // armenian + {0x0985, 0x098c, 0x0995, 0x0996, 0x098f, 0x0997, 0x0999, 0x099a, 0x003f, 0x099d, 0x09a0, 0x09a1, 0x09a2, 0x09a3, 0x003f, 0x09a4, 0x09a5, 0x09a6, 0x09a8, 0x09aa, 0x0993, 0x09ac, 0x09ad, 0x09af, 0x09b2, 0x09b9, 0x09e6, 0x09e7, 0x09e8, 0x09e9, 0x09ea, 0x09eb, 0x09ec, 0x09ed, 0x09ee, 0x09ef}, // Bengali + {0x0a05, 0x0a15, 0x0a17, 0x0a18, 0x0a0f, 0x0a1a, 0x0a1c, 0x0a1f, 0x003f, 0x0a20, 0x0a23, 0x0a24, 0x0a26, 0x0a27, 0x003f, 0x0a28, 0x0a2a, 0x0a2d, 0x0a2e, 0x0a30, 0x0a2b, 0x0a32, 0x0a35, 0x0a38, 0x0a39, 0x0a21, 0x0a66, 0x0a67, 0x0a68, 0x0a69, 0x0a6a, 0x0a6b, 0x0a6c, 0x0a6d, 0x0a6e, 0x0a6f}, // Gurmukhi + {0x0f58, 0x0f40, 0x0f41, 0x0f42, 0x0f64, 0x0f44, 0x0f45, 0x0f46, 0x003f, 0x0f47, 0x0f4a, 0x0f4c, 0x0f4e, 0x0f4f, 0x003f, 0x0f51, 0x0f53, 0x0f54, 0x0f56, 0x0f5e, 0x0f65, 0x0f5f, 0x0f61, 0x0f62, 0x0f63, 0x0f66, 0x0f20, 0x0f21, 0x0f22, 0x0f23, 0x0f24, 0x0f25, 0x0f26, 0x0f27, 0x0f28, 0x0f29}, // Tibetan +}; static struct { UWORD min; UWORD max; const char *convert; -} unicode2asc[] = - { - {0x0041, 0x005a, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"}, // Roman - {0x0391, 0x03a9, "ABGDFZHQIKLMNCOJP?STYVXRW"}, // Greek - {0x0410, 0x042f, "AZBGDEFNI?KLMHOJPCTYQXSVW????U?R"}, // Cyrillic - {0x05d0, 0x05ea, "ABCDFIGHJKLMNPQ?ROSETUVWXYZ"}, // Hebrew - {0x0905, 0x0939, "A?????????E?????B?CD?F?G??HJZ?KL?MNP?QU?RS?T?V??W??XY"}, // Hindi - {0x0d07, 0x0d39, "I?U?E??????A??BCD??F?G??HOJ??KLMNP?????Q?RST?VWX?YZ"}, // Malay - {0x10a0, 0x10bf, "AB?CE?D?UF?GHOJ?KLMINPQRSTVW?XYZ"}, // Georgisch - {0x30a2, 0x30f2, "A?I?O?U?EB?C?D?F?G?H???J???????K??????L?M?N?????P??Q??R??S?????TV?????WX???Y????Z"}, // Katakana - {0x0e01, 0x0e32, "BC?D??FGHJ??O???K??L?MNP?Q?R????S?T?V?W????UXYZAIE"}, // Thai - {0x0e81, 0x0ec6, "BC?D??FG?H??J??????K??L?MN?P?Q??RST???V??WX?Y?ZA????????????U?????EI?O"}, // Lao - {0x0532, 0x0556, "BCDE??FGHI?J?KLM?N?U?PQ?R??STVWXYZ?OA"}, // Armenian - {0x0985, 0x09b9, "A??????B??E???U?CDF?GH??J??KLMNPQR?S?T?VW?X??Y??????Z"}, // Bengali - {0x0a05, 0x0a39, "A?????????E?????B?CD?F?G??HJZ?KL?MNP?QU?RS?T?V??W??XY"}, // Gurmukhi - {0x0f40, 0x0f66, "BCD?FGHJ??K?L?MN?P?QR?S?A?????TV?WXYEUZ"}, // Tibetan - - {0x0966, 0x096f, ""}, // Hindi - {0x0d66, 0x0d6f, ""}, // Malai - {0x0e50, 0x0e59, ""}, // Thai - {0x09e6, 0x09ef, ""}, // Bengali - {0x0a66, 0x0a6f, ""}, // Gurmukhi - {0x0f20, 0x0f29, ""}, // Tibetan - - // lowercase variants: greek, georgisch - {0x03B1, 0x03c9, "ABGDFZHQIKLMNCOJP?STYVXRW"}, // Greek lowercase - {0x10d0, 0x10ef, "AB?CE?D?UF?GHOJ?KLMINPQRSTVW?XYZ"}, // Georgisch lowercase - {0x0562, 0x0586, "BCDE??FGHI?J?KLM?N?U?PQ?R??STVWXYZ?OA"}, // Armenian lowercase - {0, 0, NULL} - }; - - -char *convertToRoman(char *asciibuf, int maxlen, const UWORD *s) { +} unicode2asc[] = { + {0x0041, 0x005a, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"}, // Roman + {0x0391, 0x03a9, "ABGDFZHQIKLMNCOJP?STYVXRW"}, // Greek + {0x0410, 0x042f, "AZBGDEFNI?KLMHOJPCTYQXSVW????U?R"}, // Cyrillic + {0x05d0, 0x05ea, "ABCDFIGHJKLMNPQ?ROSETUVWXYZ"}, // Hebrew + {0x0905, 0x0939, "A?????????E?????B?CD?F?G??HJZ?KL?MNP?QU?RS?T?V??W??XY"}, // Hindi + {0x0d07, 0x0d39, "I?U?E??????A??BCD??F?G??HOJ??KLMNP?????Q?RST?VWX?YZ"}, // Malay + {0x10a0, 0x10bf, "AB?CE?D?UF?GHOJ?KLMINPQRSTVW?XYZ"}, // Georgisch + {0x30a2, 0x30f2, "A?I?O?U?EB?C?D?F?G?H???J???????K??????L?M?N?????P??Q??R??S?????TV?????WX???Y????Z"}, // Katakana + {0x0e01, 0x0e32, "BC?D??FGHJ??O???K??L?MNP?Q?R????S?T?V?W????UXYZAIE"}, // Thai + {0x0e81, 0x0ec6, "BC?D??FG?H??J??????K??L?MN?P?Q??RST???V??WX?Y?ZA????????????U?????EI?O"}, // Lao + {0x0532, 0x0556, "BCDE??FGHI?J?KLM?N?U?PQ?R??STVWXYZ?OA"}, // Armenian + {0x0985, 0x09b9, "A??????B??E???U?CDF?GH??J??KLMNPQR?S?T?VW?X??Y??????Z"}, // Bengali + {0x0a05, 0x0a39, "A?????????E?????B?CD?F?G??HJZ?KL?MNP?QU?RS?T?V??W??XY"}, // Gurmukhi + {0x0f40, 0x0f66, "BCD?FGHJ??K?L?MN?P?QR?S?A?????TV?WXYEUZ"}, // Tibetan + + {0x0966, 0x096f, ""}, // Hindi + {0x0d66, 0x0d6f, ""}, // Malai + {0x0e50, 0x0e59, ""}, // Thai + {0x09e6, 0x09ef, ""}, // Bengali + {0x0a66, 0x0a6f, ""}, // Gurmukhi + {0x0f20, 0x0f29, ""}, // Tibetan + + // lowercase variants: greek, georgisch + {0x03B1, 0x03c9, "ABGDFZHQIKLMNCOJP?STYVXRW"}, // Greek lowercase + {0x10d0, 0x10ef, "AB?CE?D?UF?GHOJ?KLMINPQRSTVW?XYZ"}, // Georgisch lowercase + {0x0562, 0x0586, "BCDE??FGHI?J?KLM?N?U?PQ?R??STVWXYZ?OA"}, // Armenian lowercase + {0, 0, NULL} +}; + + +char *convertToRoman(char *asciibuf, int maxlen, const UWORD *s) +{ char *w = asciibuf; const char *e = w + maxlen - 1; + for (; *s != 0 && w < e; s++) { if (*s >= 1 && *s <= 'z') { // normal ascii *w++ = (char) (*s); } else { - int i, found = 0; - for (i = 0; unicode2asc[i].min != 0; i++) { + int found = 0; + for (int i = 0; unicode2asc[i].min != 0; i++) { if (*s >= unicode2asc[i].min && *s <= unicode2asc[i].max) { const char *cv = unicode2asc[i].convert; - if (*cv == 0) { cv = "0123456789"; } + if (*cv == 0) + cv = "0123456789"; + *w++ = cv[*s - unicode2asc[i].min]; found = 1; break; @@ -1714,8 +1644,7 @@ char *convertToRoman(char *asciibuf, int maxlen, const UWORD *s) { } } *w = 0; - if (*asciibuf == 'A') // v1.50 - { + if (*asciibuf == 'A') { // v1.50 unpack_if_alldigits(asciibuf); repack_if_alldigits(asciibuf, 0); } @@ -1729,9 +1658,12 @@ static UWORD *encode_utf16(UWORD *unibuf, int maxlen, const char *mapcode, UWORD *w = unibuf; const UWORD *e = w + maxlen - 1; const char *r = mapcode; + while (*r != 0 && w < e) { char c = *r++; - if (c >= 'a' && c <= 'z') { c += ('A' - 'a'); } + if (c >= 'a' && c <= 'z') { + c += ('A' - 'a'); + } if (c < 0 || c > 'Z') { // not in any valid range? *w++ = '?'; } else if (c < 'A') { // valid but not a letter (e.g. a dot, a space...) @@ -1754,6 +1686,8 @@ static UWORD *encode_utf16(UWORD *unibuf, int maxlen, const char *mapcode, #define TOKENVOWEL 3 #define TOKENZERO 4 #define TOKENHYPH 5 + + #define ERR -1 #define Prt -9 // partial #define GO 99 @@ -1761,62 +1695,38 @@ static UWORD *encode_utf16(UWORD *unibuf, int maxlen, const char *mapcode, static signed char fullmc_statemachine[23][6] = { // WHI DOT DET VOW ZER HYP /* 0 start */ {0, ERR, 1, 1, ERR, ERR}, // looking for very first detter - /* 1 gotL */ - {ERR, ERR, 2, 2, ERR, ERR}, // got one detter, MUST get another one - /* 2 gotLL */ - {18, 6, 3, 3, ERR, 14}, // GOT2: white: got territory + start prefix | dot: 2.X mapcode | det:3letter | hyphen: 2-state - /* 3 gotLLL */ - {18, 6, 4, ERR, ERR, 14}, // white: got territory + start prefix | dot: 3.X mapcode | det:4letterprefix | hyphen: 3-state - /* 4 gotprefix4 */ - {ERR, 6, 5, ERR, ERR, ERR}, // dot: 4.X mapcode | det: got 5th prefix letter - /* 5 gotprefix5 */ - {ERR, 6, ERR, ERR, ERR, ERR}, // got 5char so MUST get dot! - /* 6 prefix. */ - {ERR, ERR, 7, 7, Prt, ERR}, // MUST get first letter after dot - /* 7 prefix.L */ - {ERR, ERR, 8, 8, Prt, ERR}, // MUST get second letter after dot - /* 8 prefix.LL */ - {22, ERR, 9, 9, GO, 11}, // get 3d letter after dot | X.2- | X.2 done! - /* 9 prefix.LLL */ - {22, ERR, 10, 10, GO, 11}, // get 4th letter after dot | X.3- | X.3 done! - /*10 prefix.LLLL */ - {22, ERR, ERR, ERR, GO, 11}, // X.4- | x.4 done! - - /*11 mc- */ - {ERR, ERR, 12, ERR, Prt, ERR}, // MUST get first precision letter - /*12 mc-L */ - {22, ERR, 13, ERR, GO, ERR}, // Get 2nd precision letter | done X.Y-1 - /*13 mc-LL* */ - {22, ERR, 13, ERR, GO, ERR}, // *** keep reading precision detters *** until whitespace or done - - /*14 ctry- */ - {ERR, ERR, 15, 15, ERR, ERR}, // MUST get first state letter - /*15 ctry-L */ - {ERR, ERR, 16, 16, ERR, ERR}, // MUST get 2nd state letter - /*16 ctry-LL */ - {18, ERR, 17, 17, ERR, ERR}, // white: got CCC-SS and get prefix | got 3d letter - /*17 ctry-LLL */ - {18, ERR, ERR, ERR, ERR, ERR}, // got CCC-SSS so MUST get whitespace and then get prefix - - /*18 startprefix */ - {18, ERR, 19, 19, ERR, ERR}, // skip more whitespace, MUST get 1st prefix letter - /*19 gotprefix1 */ - {ERR, ERR, 20, ERR, ERR, ERR}, // MUST get second prefix letter - /*20 gotprefix2 */ - {ERR, 6, 21, ERR, ERR, ERR}, // dot: 2.X mapcode | det: 3d perfix letter - /*21 gotprefix3 */ - {ERR, 6, 4, ERR, ERR, ERR}, // dot: 3.x mapcode | det: got 4th prefix letter - - /*22 whitespace */ - {22, ERR, ERR, ERR, GO, ERR} // whitespace until end of string + /* 1 gotL */ {ERR, ERR, 2, 2, ERR, ERR}, // got one detter, MUST get another one + /* 2 gotLL */ {18, 6, 3, 3, ERR, 14}, // GOT2: white: got territory + start prefix | dot: 2.X mapcode | det:3letter | hyphen: 2-state + /* 3 gotLLL */ {18, 6, 4, ERR, ERR, 14}, // white: got territory + start prefix | dot: 3.X mapcode | det:4letterprefix | hyphen: 3-state + /* 4 gotprefix4 */ {ERR, 6, 5, ERR, ERR, ERR}, // dot: 4.X mapcode | det: got 5th prefix letter + /* 5 gotprefix5 */ {ERR, 6, ERR, ERR, ERR, ERR}, // got 5char so MUST get dot! + /* 6 prefix. */ {ERR, ERR, 7, 7, Prt, ERR}, // MUST get first letter after dot + /* 7 prefix.L */ {ERR, ERR, 8, 8, Prt, ERR}, // MUST get second letter after dot + /* 8 prefix.LL */ {22, ERR, 9, 9, GO, 11}, // get 3d letter after dot | X.2- | X.2 done! + /* 9 prefix.LLL */ {22, ERR, 10, 10, GO, 11}, // get 4th letter after dot | X.3- | X.3 done! + /*10 prefix.LLLL */ {22, ERR, ERR, ERR, GO, 11}, // X.4- | x.4 done! + /*11 mc- */ {ERR, ERR, 12, ERR, Prt, ERR}, // MUST get first precision letter + /*12 mc-L */ {22, ERR, 13, ERR, GO, ERR}, // Get 2nd precision letter | done X.Y-1 + /*13 mc-LL* */ {22, ERR, 13, ERR, GO, ERR}, // *** keep reading precision detters *** until whitespace or done + /*14 ctry- */ {ERR, ERR, 15, 15, ERR, ERR}, // MUST get first state letter + /*15 ctry-L */ {ERR, ERR, 16, 16, ERR, ERR}, // MUST get 2nd state letter + /*16 ctry-LL */ {18, ERR, 17, 17, ERR, ERR}, // white: got CCC-SS and get prefix | got 3d letter + /*17 ctry-LLL */ {18, ERR, ERR, ERR, ERR, ERR}, // got CCC-SSS so MUST get whitespace and then get prefix + /*18 startprefix */ {18, ERR, 19, 19, ERR, ERR}, // skip more whitespace, MUST get 1st prefix letter + /*19 gotprefix1 */ {ERR, ERR, 20, ERR, ERR, ERR}, // MUST get second prefix letter + /*20 gotprefix2 */ {ERR, 6, 21, ERR, ERR, ERR}, // dot: 2.X mapcode | det: 3d perfix letter + /*21 gotprefix3 */ {ERR, 6, 4, ERR, ERR, ERR}, // dot: 3.x mapcode | det: got 4th prefix letter + /*22 whitespace */ {22, ERR, ERR, ERR, GO, ERR} // whitespace until end of string }; // pass fullcode=1 to recognise territory and mapcode, pass fullcode=0 to only recognise proper mapcode (without optional territory) // returns 0 if ok, negative in case of error (where -999 represents "may BECOME a valid mapcode if more characters are added) -int compareWithMapcodeFormat(const char *s, int fullcode) { +int compareWithMapcodeFormat(const char *s, int fullcode) +{ int nondigits = 0, vowels = 0; int state = (fullcode ? 0 : 18); // initial state + for (; ; s++) { int newstate, token; // recognise token: decode returns -2=a -3=e -4=0, 0..9 for digit or "o" or "i", 10..31 for char, -1 for illegal char @@ -1840,7 +1750,9 @@ int compareWithMapcodeFormat(const char *s, int fullcode) { token = TOKENCHR; // digit } else { // charcter B-Z token = TOKENCHR; - if (state != 11 && state != 12 && state != 13) { nondigits++; } + if (state != 11 && state != 12 && state != 13) { + nondigits++; + } } } newstate = fullmc_statemachine[state][token]; @@ -1875,15 +1787,28 @@ static int encodeLatLonToMapcodes_internal(char **v, Mapcodes *mapcodes, double enc.mapcodes = mapcodes; enc.mapcodes->count = 0; - if (lat < -90) { lat = -90; } - if (lat > 90) { lat = 90; } - while (lon < -180) { lon += 360; } - while (lon >= 180) { lon -= 360; } + if (lat < -90) + lat = -90; + if (lat > 90) + lat = 90; + while (lon < -180) + lon += 360; + while (lon >= 180) + lon -= 360; + #ifndef SUPPORT_HIGH_PRECISION - lat*=1000000; if (lat<0) lat-=0.5; else lat+=0.5; - lon*=1000000; if (lon<0) lon-=0.5; else lon+=0.5; - enc.lat32=(int)lat; - enc.lon32=(int)lon; + lat *= 1000000; + if (lat < 0) + lat -= 0.5; + else + lat += 0.5; + lon *= 1000000; + if (lon<0) + lon-=0.5; + else + lon+=0.5; + enc.lat32 = (int)lat; + enc.lon32 = (int)lon; #else // precise encoding: do NOT round, instead remember the fraction... lat += 90; lon += 180; @@ -1895,26 +1820,33 @@ static int encodeLatLonToMapcodes_internal(char **v, Mapcodes *mapcodes, double enc.fraclon = lon - enc.lon32; // for 8-digit precision, cells are divided into 810,000 by 810,000 minicells. enc.fraclat *= 810000; - if (enc.fraclat < 1) { enc.fraclat = 0; } else { + if (enc.fraclat < 1) { + enc.fraclat = 0; + } else { if (enc.fraclat > 809999) { enc.fraclat = 0; enc.lat32++; - } else { enc.fraclat /= 810000; } + } else { + enc.fraclat /= 810000; + } } enc.fraclon *= 810000; - if (enc.fraclon < 1) { enc.fraclon = 0; } else { + if (enc.fraclon < 1) { + enc.fraclon = 0; + } else { if (enc.fraclon > 809999) { enc.fraclon = 0; enc.lon32++; - } else { enc.fraclon /= 810000; } + } else { + enc.fraclon /= 810000; + } } enc.lat32 -= 90000000; enc.lon32 %= 360000000; enc.lon32 -= 180000000; #endif - if (tc <= 0) // ALL results? - { + if (tc <= 0) { // ALL results? #ifdef FAST_ENCODE int HOR = 1; int i = 0; // pointer into redivar @@ -1926,7 +1858,9 @@ static int encodeLatLonToMapcodes_internal(char **v, Mapcodes *mapcodes, double for (j = 0; j <= nr; j++) { int ctry = (j == nr ? ccode_earth : redivar[i + j]); encoderEngine(ctry, &enc, stop_with_one_result, extraDigits, -1); - if ((stop_with_one_result || debugStopAt >= 0) && enc.mapcodes->count > 0) { break; } + if ((stop_with_one_result || debugStopAt >= 0) && enc.mapcodes->count > 0) { + break; + } } break; } @@ -1941,20 +1875,18 @@ static int encodeLatLonToMapcodes_internal(char **v, Mapcodes *mapcodes, double } } #else - int i; - for(i=0;i=0) && enc.mapcodes->count>0) break; - } + for(int i = 0; i < MAX_MAPCODE_TERRITORY_CODE ; i++) { + encoderEngine(i, &enc, stop_with_one_result, extraDigits, -1); + if ((stop_with_one_result || debugStopAt >= 0) && enc.mapcodes->count > 0) + break; + } #endif - } - else { + } else { encoderEngine((tc - 1), &enc, stop_with_one_result, extraDigits, -1); } if (v) { - int i; - for (i = 0; i < enc.mapcodes->count; i++) { + for (int i = 0; i < enc.mapcodes->count; i++) { char *s = &enc.mapcodes->mapcode[i][0]; char *p = strchr(s, ' '); if (p == NULL) { @@ -1974,8 +1906,7 @@ static int encodeLatLonToMapcodes_internal(char **v, Mapcodes *mapcodes, double // threadsafe -char *getTerritoryIsoName(char *result, int territoryCode, - int format) // formats: 0=full 1=short (returns empty string in case of error) +char *getTerritoryIsoName(char *result, int territoryCode, int format) // formats: 0=full 1=short (returns empty string in case of error) { if (territoryCode < 1 || territoryCode > MAX_MAPCODE_TERRITORY_CODE) { *result = 0; @@ -1983,7 +1914,9 @@ char *getTerritoryIsoName(char *result, int territoryCode, int p = ParentLetter(territoryCode - 1); char iso3[4]; const char *ei = get_entity_iso3(iso3, territoryCode - 1); - if (*ei >= '0' && *ei <= '9') { ei++; } + if (*ei >= '0' && *ei <= '9') { + ei++; + } if (format == 0 && p) { memcpy(result, &parents2[p * 3 - 3], 2); result[2] = '-'; @@ -2000,16 +1933,19 @@ char *getTerritoryIsoName(char *result, int territoryCode, int getParentCountryOf(int tc) // returns negative if tc is not a code that has a parent country { int parentccode = ParentTerritoryOf(tc - 1); // returns parent ccode or -1 - if (parentccode >= 0) { return parentccode + 1; } + if (parentccode >= 0) { + return parentccode + 1; + } return -1; } -int getCountryOrParentCountry( - int tc) // returns tc if tc is a country, parent country if tc is a state, -1 if tc is invalid +int getCountryOrParentCountry(int tc) // returns tc if tc is a country, parent country if tc is a state, -1 if tc is invalid { if (tc > 0 && tc < MAX_MAPCODE_TERRITORY_CODE) { int tp = getParentCountryOf(tc); - if (tp > 0) { return tp; } + if (tp > 0) + return tp; + return tc; } return -1; @@ -2017,14 +1953,18 @@ int getCountryOrParentCountry( int convertTerritoryIsoNameToCode(const char *string, int optional_tc) // optional_tc: pass 0 or negative if unknown { + if (string == NULL) + return -1; + + while (*string > 0 && *string <= 32) { + string++; + } // skip leading whitespace + int ccode = optional_tc - 1; - if (string == NULL) { return -1; } - while (*string > 0 && *string <= 32) { string++; } // skip leading whitespace if (ccode < 0 || strchr(string, '-') || strlen(string) > 3) { ccode = ccode_of_iso3(string, -1); // ignore optional_tc - } - else // there is a ccode, there is no hyphen in the string, and the string is as most 3 chars - { + } else { + // there is a ccode, there is no hyphen in the string, and the string is as most 3 chars char tmp[12]; int tc = getCountryOrParentCountry(optional_tc); @@ -2033,24 +1973,25 @@ int convertTerritoryIsoNameToCode(const char *string, int optional_tc) // option strcat(tmp, string); ccode = ccode_of_iso3(tmp, -1); } - if (ccode < 0) { return -1; } else { return ccode + 1; } + if (ccode < 0) + return -1; + else + return ccode + 1; } // decode string into lat,lon; returns negative in case of error -int decodeMapcodeToLatLon(double *lat, double *lon, const char *input, - int context_tc) // context_tc is used to disambiguate ambiguous short mapcode inputs; pass 0 or negative if not available +// context_tc is used to disambiguate ambiguous short mapcode inputs; pass 0 or negative if not available +int decodeMapcodeToLatLon(double *lat, double *lon, const char *input, int context_tc) { if (lat == NULL || lon == NULL || input == NULL) { return -100; - } - else { - int ret; + } else { decodeRec dec; dec.orginput = input; dec.context = context_tc; - ret = decoderEngine(&dec); + int ret = decoderEngine(&dec); *lat = dec.lat; *lon = dec.lon; return ret; @@ -2063,7 +2004,7 @@ UWORD *convertToAlphabet(UWORD *unibuf, int maxlength, const char *mapcode, int { if (asc2lan[alphabet][4] == 0x003f) { // alphabet has no letter E if (strchr(mapcode, 'E') || strchr(mapcode, 'U') || strchr(mapcode, 'e') || - strchr(mapcode, 'u')) // v1.50 get rid of E and U + strchr(mapcode, 'u')) // v1.50 get rid of E and U { // safely copy mapcode into temporary buffer u char u[MAX_MAPCODE_RESULT_LEN]; @@ -2085,7 +2026,8 @@ UWORD *convertToAlphabet(UWORD *unibuf, int maxlength, const char *mapcode, int // Legacy: NOT threadsafe static char asciibuf[MAX_MAPCODE_RESULT_LEN]; -const char *decodeToRoman(const UWORD *s) { +const char *decodeToRoman(const UWORD *s) +{ return convertToRoman(asciibuf, MAX_MAPCODE_RESULT_LEN, s); } @@ -2099,7 +2041,8 @@ const UWORD *encodeToAlphabet(const char *mapcode, int alphabet) // 0=roman, 2=c #endif -int encodeLatLonToSingleMapcode(char *result, double lat, double lon, int tc, int extraDigits) { +int encodeLatLonToSingleMapcode(char *result, double lat, double lon, int tc, int extraDigits) +{ char *v[2]; Mapcodes rlocal; int ret = encodeLatLonToMapcodes_internal(v, &rlocal, lat, lon, tc, 1, extraDigits); @@ -2117,14 +2060,16 @@ int encodeLatLonToSingleMapcode(char *result, double lat, double lon, int tc, in } // Threadsafe -int encodeLatLonToMapcodes(Mapcodes *results, double lat, double lon, int territoryCode, int extraDigits) { +int encodeLatLonToMapcodes(Mapcodes *results, double lat, double lon, int territoryCode, int extraDigits) +{ return encodeLatLonToMapcodes_internal(NULL, results, lat, lon, territoryCode, 0, extraDigits); } // Legacy: NOT threadsafe Mapcodes rglobal; -int encodeLatLonToMapcodes_Deprecated(char **v, double lat, double lon, int territoryCode, int extraDigits) { +int encodeLatLonToMapcodes_Deprecated(char **v, double lat, double lon, int territoryCode, int extraDigits) +{ return encodeLatLonToMapcodes_internal(v, &rglobal, lat, lon, territoryCode, 0, extraDigits); } @@ -2132,9 +2077,12 @@ int encodeLatLonToMapcodes_Deprecated(char **v, double lat, double lon, int terr static char makeiso_bufbytes[16]; static char *makeiso_buf; -const char *convertTerritoryCodeToIsoName(int tc, int format) { - if (makeiso_buf == makeiso_bufbytes) { +const char *convertTerritoryCodeToIsoName(int tc, int format) +{ + if (makeiso_buf == makeiso_bufbytes) makeiso_buf = makeiso_bufbytes + 8; - } else { makeiso_buf = makeiso_bufbytes; } + else + makeiso_buf = makeiso_bufbytes; + return (const char *) getTerritoryIsoName(makeiso_buf, tc, format); }