/*
* Copyright (C) 2008 Steve Ratcliffe
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 or
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
/* Create date: 17-Feb-2009 */
package func.files;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Comparator;
import java.util.List;
import uk.me.parabola.imgfmt.Utils;
import uk.me.parabola.imgfmt.fs.DirectoryEntry;
import uk.me.parabola.imgfmt.fs.FileSystem;
import uk.me.parabola.imgfmt.fs.ImgChannel;
import uk.me.parabola.imgfmt.mps.MapBlock;
import uk.me.parabola.imgfmt.mps.MpsFileReader;
import uk.me.parabola.imgfmt.mps.ProductBlock;
import uk.me.parabola.imgfmt.sys.ImgFS;
import uk.me.parabola.mkgmap.main.Main;
import func.Base;
import func.lib.Args;
import func.lib.Outputs;
import func.lib.TestUtils;
import org.junit.Test;
import static org.junit.Assert.*;
public class GmapsuppTest extends Base {
private static final String GMAPSUPP_IMG = "gmapsupp.img";
@Test
public void testBasic() throws IOException {
File f = new File(GMAPSUPP_IMG);
assertFalse("does not pre-exist", f.exists());
Main.mainNoSystemExit(Args.TEST_STYLE_ARG,
"--gmapsupp",
Args.TEST_RESOURCE_IMG + "63240001.img",
Args.TEST_RESOURCE_IMG + "63240002.img");
assertTrue("gmapsupp.img is created", f.exists());
FileSystem fs = openFs(GMAPSUPP_IMG);
DirectoryEntry entry = fs.lookup("63240001.TRE");
assertNotNull("first file TRE", entry);
assertEquals("first file TRE size", getFileSize(Args.TEST_RESOURCE_IMG + "63240001.img", "63240001.TRE"), entry.getSize());
entry = fs.lookup("63240002.TRE");
assertNotNull("second file TRE", entry);
assertEquals("second file TRE size", getFileSize(Args.TEST_RESOURCE_IMG + "63240002.img", "63240002.TRE"), entry.getSize());
}
/**
* Check the values inside the MPS file, when the family id etc is
* common to all files.
*/
@Test
public void testMpsFile() throws IOException {
Main.mainNoSystemExit(Args.TEST_STYLE_ARG,
"--gmapsupp",
"--family-id=150",
"--product-id=24",
"--series-name=tst series",
"--family-name=tst family",
"--area-name=tst area",
Args.TEST_RESOURCE_IMG + "63240001.img",
Args.TEST_RESOURCE_IMG + "63240002.img");
MpsFileReader reader = getMpsFile();
List<MapBlock> list = reader.getMaps();
reader.close();
assertEquals("number of map blocks", 2, list.size());
// All maps will have the same parameters apart from map name here
int count = 0;
for (MapBlock map : list) {
assertEquals("map number", 63240001 + count++, map.getMapNumber());
assertEquals("family id", 150, map.getFamilyId());
assertEquals("product id", 24, map.getProductId());
assertEquals("series name", "tst series", map.getSeriesName());
assertEquals("area name", "tst area", map.getAreaName());
assertEquals("map description", "uk test " + count, map.getMapDescription());
}
}
/**
* Test combining gmapsupp files. The family id etc should be taken from
* the MPS file in the gmapsupp.
*/
@Test
public void testCombiningSupps() throws IOException {
TestUtils.registerFile("g1.img", "g2.img");
Main.mainNoSystemExit(Args.TEST_STYLE_ARG,
"--gmapsupp",
"--family-id=150",
"--product-id=24",
"--series-name=tst series",
"--family-name=tst family",
"--area-name=tst area",
Args.TEST_RESOURCE_IMG + "63240001.img");
File f = new File("gmapsupp.img");
f.renameTo(new File("g1.img"));
Main.mainNoSystemExit(Args.TEST_STYLE_ARG,
"--gmapsupp",
"--family-id=152",
"--product-id=26",
"--series-name=tst series 2",
"--family-name=tst family 2",
"--area-name=tst area 2",
Args.TEST_RESOURCE_IMG + "63240002.img");
f.renameTo(new File("g2.img"));
Main.mainNoSystemExit(Args.TEST_STYLE_ARG, "--gmapsupp", "g1.img", "g2.img");
MpsFileReader reader = getMpsFile();
List<MapBlock> list = reader.getMaps();
assertEquals("number of map blocks", 2, list.size());
for (MapBlock map : list) {
if (map.getMapNumber() == 63240001) {
assertEquals("family id", 150, map.getFamilyId());
assertEquals("product id", 24, map.getProductId());
assertEquals("series name", "tst series", map.getSeriesName());
assertEquals("area name", "tst area", map.getAreaName());
assertEquals("hex name", 63240001, map.getHexNumber());
assertEquals("map description", "uk test 1", map.getMapDescription());
} else if (map.getMapNumber() == 63240002) {
assertEquals("family id", 152, map.getFamilyId());
assertEquals("product id", 26, map.getProductId());
assertEquals("series name", "tst series 2", map.getSeriesName());
assertEquals("area name", "tst area 2", map.getAreaName());
assertEquals("hex name", 63240002, map.getHexNumber());
assertEquals("map description", "uk test 2", map.getMapDescription());
} else {
assertTrue("Unexpected map found", false);
}
}
}
/**
* Test the case where we are combining img files with different family
* and product ids.
*/
@Test
public void testDifferentFamilies() throws IOException {
Main.mainNoSystemExit(Args.TEST_STYLE_ARG,
"--gmapsupp",
"--family-id=101",
"--product-id=1",
"--series-name=tst series1",
Args.TEST_RESOURCE_IMG + "63240001.img",
"--family-id=102",
"--product-id=2",
"--series-name=tst series2",
Args.TEST_RESOURCE_IMG + "63240002.img");
MpsFileReader reader = getMpsFile();
List<MapBlock> list = reader.getMaps();
reader.close();
assertEquals("number of map blocks", 2, list.size());
// Directly check the family id's
assertEquals("family in map1", 101, list.get(0).getFamilyId());
assertEquals("family in map2", 102, list.get(1).getFamilyId());
// Check more things
int count = 0;
for (MapBlock map : list) {
count++;
assertEquals("family in map" + count, 100 + count, map.getFamilyId());
assertEquals("product in map" + count, count, map.getProductId());
assertEquals("series name in map" + count, "tst series" + count, map.getSeriesName());
}
}
/**
* The mps file has a block for each family/product in the map set.
*/
@Test
public void testProductBlocks() throws IOException {
Main.mainNoSystemExit(Args.TEST_STYLE_ARG,
"--gmapsupp",
"--family-id=101",
"--product-id=1",
"--family-name=tst family1",
"--series-name=tst series1",
Args.TEST_RESOURCE_IMG + "63240001.img",
"--family-id=102",
"--product-id=2",
"--family-name=tst family2",
"--series-name=tst series2",
Args.TEST_RESOURCE_IMG + "63240002.img");
MpsFileReader reader = getMpsFile();
List<ProductBlock> products = reader.getProducts();
products.sort(new Comparator<ProductBlock>() {
public int compare(ProductBlock o1, ProductBlock o2) {
if (o1.getFamilyId() == o2.getFamilyId())
return 0;
else if (o1.getFamilyId() > o2.getFamilyId())
return 1;
else return -1;
}
});
ProductBlock block = products.get(0);
assertEquals("product block first family", 101, block.getFamilyId());
assertEquals("product block first product id", 1, block.getProductId());
assertEquals("product block first family name", "tst family1", block.getDescription());
block = products.get(1);
assertEquals("product block second family", 102, block.getFamilyId());
assertEquals("product block first product id", 2, block.getProductId());
assertEquals("product block first family name", "tst family2", block.getDescription());
}
/**
* Make sure that if we have multiple maps in the same family, which after
* all is the common case, that we only get one product block.
*/
@Test
public void testProductWithSeveralMaps() throws IOException {
Main.mainNoSystemExit(Args.TEST_STYLE_ARG,
"--gmapsupp",
"--family-id=101",
"--product-id=1",
"--family-name=tst family1",
"--series-name=tst series1",
Args.TEST_RESOURCE_IMG + "63240001.img",
Args.TEST_RESOURCE_IMG + "63240002.img");
MpsFileReader reader = getMpsFile();
assertEquals("number of map blocks", 2, reader.getMaps().size());
assertEquals("number of product blocks", 1, reader.getProducts().size());
}
@Test
public void testWithIndex() throws IOException {
new File("osmmap_mdr.img").delete();
Main.mainNoSystemExit(Args.TEST_STYLE_ARG,
"--gmapsupp",
"--index",
"--latin1",
"--family-id=101",
"--product-id=1",
"--family-name=tst family1",
"--series-name=tst series1",
Args.TEST_RESOURCE_IMG + "63240001.img",
Args.TEST_RESOURCE_IMG + "63240002.img");
assertFalse(new File("osmmap_mdr.img").exists());
// All we are doing here is checking that the file was created and that it is
// not completely empty.
FileSystem fs = openFs(GMAPSUPP_IMG);
ImgChannel r = fs.open("00000101.MDR", "r");
r.position(2);
ByteBuffer buf = ByteBuffer.allocate(1024);
int read = r.read(buf);
assertEquals(1024, read);
buf.flip();
byte[] b = new byte[3];
buf.get(b, 0, 3);
assertEquals('G', b[0]);
}
@Test
public void testWithTwoIndexes() throws IOException {
TestUtils.registerFile("osmmap_mdr.img", "osmmap.img", "osmmap.tbd", "osmmap.mdx");
Main.mainNoSystemExit(Args.TEST_STYLE_ARG,
"--gmapsupp",
"--index",
"--tdbfile",
"--latin1",
"--family-id=101",
"--product-id=1",
"--family-name=tst family1",
"--series-name=tst series1",
Args.TEST_RESOURCE_IMG + "63240001.img",
Args.TEST_RESOURCE_IMG + "63240002.img");
assertTrue(new File("osmmap_mdr.img").exists());
// All we are doing here is checking that the file was created and that it is
// not completely empty.
FileSystem fs = openFs(GMAPSUPP_IMG);
ImgChannel r = fs.open("00000101.MDR", "r");
r.position(2);
ByteBuffer buf = ByteBuffer.allocate(1024);
int read = r.read(buf);
assertEquals(1024, read);
buf.flip();
byte[] b = new byte[3];
buf.get(b, 0, 3);
assertEquals('G', b[0]);
}
/**
* If there are files in two (or more) families then there should be a MDR and SRT for each.
*/
@Test
public void testTwoFamilyIndex() throws IOException {
TestUtils.registerFile("osmmap_mdr.img", "osmmap.img", "osmmap.tbd", "osmmap.mdx");
Main.mainNoSystemExit(Args.TEST_STYLE_ARG,
"--gmapsupp",
"--index",
"--latin1",
"--family-id=101",
"--product-id=1",
"--family-name=tst family1",
"--series-name=tst series1",
Args.TEST_RESOURCE_OSM + "uk-test-1.osm.gz",
"--family-id=202",
"--family-name=tst family2",
"--series-name=tst series2",
Args.TEST_RESOURCE_OSM + "uk-test-2.osm.gz");
assertFalse(new File("osmmap_mdr.img").exists());
// All we are doing here is checking that the file was created and that it is
// not completely empty.
FileSystem fs = openFs(GMAPSUPP_IMG);
ImgChannel r = fs.open("00000101.MDR", "r");
r.position(2);
ByteBuffer buf = ByteBuffer.allocate(1024);
int read = r.read(buf);
assertEquals(1024, read);
fs = openFs(GMAPSUPP_IMG);
r = fs.open("00000202.MDR", "r");
r.position(2);
buf.clear();
read = r.read(buf);
assertEquals(1024, read);
r = fs.open("00000202.SRT", "r");
buf = ByteBuffer.allocate(512);
read = r.read(buf);
assertEquals(512, read);
r = fs.open("00000101.SRT", "r");
buf.clear();
read = r.read(buf);
assertEquals(512, read);
}
/**
* If no code page is given for the index, it is taken from the input files.
*/
@Test
public void testImplicitCodePageIndex() throws IOException {
TestUtils.registerFile("osmmap_mdr.img", "osmmap.img", "osmmap.tbd", "osmmap.mdx");
Main.mainNoSystemExit(Args.TEST_STYLE_ARG, "--code-page=1256",
Args.TEST_RESOURCE_OSM + "uk-test-1.osm.gz");
Main.mainNoSystemExit(Args.TEST_STYLE_ARG, "--gmapsupp", "--index", "63240001.img");
assertFalse(new File("osmmap_mdr.img").exists());
FileSystem fs = openFs(GMAPSUPP_IMG);
ImgChannel r = fs.open("00006324.MDR", "r");
ByteBuffer buf = ByteBuffer.allocate(1024);
buf.order(ByteOrder.LITTLE_ENDIAN);
r.read(buf);
assertEquals(1256, buf.getChar(0x15));
assertEquals(0x010009, buf.getInt(0x17));
}
/**
* If there are mis-matching code-pages in the input files there should be a warning.
*/
@Test
public void testWarningOnMismatchedCodePages() throws IOException {
TestUtils.registerFile("osmmap.img");
Main.mainNoSystemExit(Args.TEST_STYLE_ARG, "--route", "--code-page=1256",
Args.TEST_RESOURCE_OSM + "uk-test-1.osm.gz",
"--latin1",
Args.TEST_RESOURCE_OSM + "uk-test-2.osm.gz");
Outputs outputs = TestUtils.run(Args.TEST_STYLE_ARG,
"--gmapsupp",
"--index",
"63240001.img",
"63240002.img"
);
outputs.checkError("different code page");
}
private MpsFileReader getMpsFile() throws IOException {
FileSystem fs = openFs(GMAPSUPP_IMG);
MpsFileReader reader = new MpsFileReader(fs.open("MAKEGMAP.MPS", "r"), 0);
TestUtils.registerFile(reader);
return reader;
}
private int getFileSize(String imgName, String fileName) throws IOException {
FileSystem fs = ImgFS.openFs(imgName);
try {
return fs.lookup(fileName).getSize();
} finally {
Utils.closeFile(fs);
}
}
}