|
16 | 16 |
|
17 | 17 | package com.mapcode; |
18 | 18 |
|
| 19 | +import org.slf4j.Logger; |
| 20 | +import org.slf4j.LoggerFactory; |
| 21 | + |
19 | 22 | import java.io.ByteArrayOutputStream; |
20 | 23 | import java.io.IOException; |
21 | 24 | import java.io.InputStream; |
|
28 | 31 | * This class contains the module that reads the Mapcode areas into memory and processes them. |
29 | 32 | */ |
30 | 33 | class DataAccess { |
| 34 | + private static final Logger LOG = LoggerFactory.getLogger(DataAccess.class); |
31 | 35 |
|
32 | | - private static final byte[] FILE_DATA; |
| 36 | + private static final int[] FILE_DATA; |
33 | 37 | private static final String FILE_NAME = "/com/mapcode/mminfo.dat"; |
34 | 38 |
|
35 | 39 | // Read data only once in static initializer. |
36 | 40 | static { |
37 | | - final InputStream inputStream = DataAccess.class.getResourceAsStream(FILE_NAME); |
38 | | - try { |
39 | | - final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); |
40 | | - for (int readBytes = inputStream.read(); readBytes >= 0; readBytes = inputStream.read()) { |
41 | | - outputStream.write(readBytes); |
42 | | - } |
| 41 | + LOG.info("DataAccess: reading regions from file: {}", FILE_NAME); |
| 42 | + final int bufferSize = 100000; |
| 43 | + final byte[] readBuffer = new byte[bufferSize]; |
| 44 | + int total = 0; |
| 45 | + try (final InputStream inputStream = DataAccess.class.getResourceAsStream(FILE_NAME)) { |
| 46 | + try (final ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { |
| 47 | + int nrBytes = inputStream.read(readBuffer); |
| 48 | + while (nrBytes >= 0) { |
| 49 | + total += nrBytes; |
| 50 | + outputStream.write(readBuffer, 0, nrBytes); |
| 51 | + nrBytes = inputStream.read(readBuffer); |
| 52 | + } |
| 53 | + |
| 54 | + // Copy stream as unsigned bytes (ints). |
| 55 | + final byte[] bytes = outputStream.toByteArray(); |
| 56 | + assert total == bytes.length; |
| 57 | + FILE_DATA = new int[total]; |
| 58 | + for (int i = 0; i < total; ++i) { |
| 59 | + FILE_DATA[i] = (bytes[i] < 0) ? (bytes[i] + 256) : bytes[i]; |
43 | 60 |
|
44 | | - FILE_DATA = outputStream.toByteArray(); |
45 | | - inputStream.close(); |
46 | | - outputStream.close(); |
47 | | - } catch (final IOException e) { |
48 | | - throw new ExceptionInInitializerError("Cannot initialize static data structure from: " + FILE_NAME + |
49 | | - ", exception=" + e); |
50 | | - } finally { |
51 | | - try { |
52 | | - if (inputStream != null) { |
53 | | - inputStream.close(); |
54 | 61 | } |
55 | | - } catch (final IOException ignored) { |
56 | | - // Ignore. |
57 | 62 | } |
| 63 | + } catch (final IOException e) { |
| 64 | + throw new ExceptionInInitializerError("Cannot initialize static data structure from: " + |
| 65 | + FILE_NAME + ", exception=" + e); |
58 | 66 | } |
| 67 | + LOG.info("DataAccess: regions initialized, read {} bytes", total); |
59 | 68 | } |
60 | 69 |
|
61 | 70 | private DataAccess() { |
62 | 71 | // Empty. |
63 | 72 | } |
64 | 73 |
|
65 | | - private static int asUnsignedByte(final int i) { |
66 | | - int u = FILE_DATA[i]; |
67 | | - if (u < 0) { |
68 | | - u += 256; |
69 | | - } |
70 | | - return u; |
71 | | - } |
72 | | - |
73 | 74 | static int dataFlags(final int i) { |
74 | | - return asUnsignedByte((i * 20) + 16) + (asUnsignedByte((i * 20) + 17) * 256); |
| 75 | + return FILE_DATA[(i * 20) + 16] + |
| 76 | + (FILE_DATA[(i * 20) + 17] * 256); |
75 | 77 | } |
76 | 78 |
|
77 | 79 | static int asLong(final int i) { |
78 | | - return asUnsignedByte(i) + |
79 | | - (asUnsignedByte(i + 1) << 8) + |
80 | | - (asUnsignedByte(i + 2) << 16) + |
81 | | - (asUnsignedByte(i + 3) << 24); |
| 80 | + return FILE_DATA[i] + |
| 81 | + (FILE_DATA[i + 1] << 8) + |
| 82 | + (FILE_DATA[i + 2] << 16) + |
| 83 | + (FILE_DATA[i + 3] << 24); |
82 | 84 | } |
83 | 85 |
|
84 | 86 | static int smartDiv(final int i) { |
85 | | - return asUnsignedByte((i * 20) + 18) + (asUnsignedByte((i * 20) + 19) * 256); |
| 87 | + return FILE_DATA[(i * 20) + 18] + |
| 88 | + (FILE_DATA[(i * 20) + 19] * 256); |
86 | 89 | } |
87 | 90 |
|
88 | 91 | private final static int[] DATA_START = { |
|
0 commit comments