|
23 | 23 |
|
24 | 24 | import org.citydb.model.geometry.*;
|
25 | 25 |
|
26 |
| -import java.nio.ByteBuffer; |
27 |
| -import java.nio.ByteOrder; |
28 | 26 | import java.util.ArrayList;
|
29 | 27 | import java.util.List;
|
30 | 28 |
|
31 | 29 | public class WKBParser {
|
32 | 30 |
|
33 | 31 | public Geometry<?> parse(String wkb) throws GeometryException {
|
34 |
| - return wkb != null ? read(ByteBuffer.wrap(toBytes(wkb))) : null; |
| 32 | + return wkb != null ? read(new StringBuffer(wkb)) : null; |
35 | 33 | }
|
36 | 34 |
|
37 | 35 | public Geometry<?> parse(Object wkb) throws GeometryException {
|
38 |
| - return wkb != null ? read(ByteBuffer.wrap(toBytes(wkb.toString()))) : null; |
| 36 | + return wkb != null ? read(new StringBuffer(wkb.toString())) : null; |
39 | 37 | }
|
40 | 38 |
|
41 | 39 | public Geometry<?> parse(byte[] bytes) throws GeometryException {
|
42 |
| - return bytes != null ? read(ByteBuffer.wrap(bytes)) : null; |
| 40 | + return bytes != null ? read(new ArrayBuffer(bytes)) : null; |
43 | 41 | }
|
44 | 42 |
|
45 | 43 | private Geometry<?> read(ByteBuffer buffer) throws GeometryException {
|
46 |
| - byte byteOrder = buffer.get(); |
47 |
| - buffer.order(byteOrder == 1 ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN); |
| 44 | + buffer.order(buffer.getByte()); |
48 | 45 |
|
49 | 46 | int typeInt = buffer.getInt();
|
50 | 47 | int geometryType = typeInt & 0xff;
|
@@ -182,14 +179,69 @@ private Coordinate getCoordinate(ByteBuffer buffer, int dimension) {
|
182 | 179 | Coordinate.of(x, y, buffer.getDouble());
|
183 | 180 | }
|
184 | 181 |
|
185 |
| - private byte[] toBytes(String hex) { |
186 |
| - int len = hex.length(); |
187 |
| - byte[] bytes = new byte[len / 2]; |
188 |
| - for (int i = 0; i < len; i += 2) { |
189 |
| - bytes[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4) + |
190 |
| - Character.digit(hex.charAt(i + 1), 16)); |
| 182 | + private static abstract class ByteBuffer { |
| 183 | + final int[] bigEndian = new int[]{1, 0, 1, 2, 3, 4, 5, 6, 7}; |
| 184 | + final int[] littleEndian = new int[]{5, 7, 6, 5, 4, 3, 2, 1, 0}; |
| 185 | + int[] indexes = bigEndian; |
| 186 | + int pos; |
| 187 | + |
| 188 | + abstract int get(int pos); |
| 189 | + |
| 190 | + void order(byte order) { |
| 191 | + indexes = order == 0 ? bigEndian : littleEndian; |
| 192 | + } |
| 193 | + |
| 194 | + byte getByte() { |
| 195 | + return (byte) get(pos++); |
| 196 | + } |
| 197 | + |
| 198 | + int getInt() { |
| 199 | + int low = indexes[0]; |
| 200 | + int value = (get(pos + indexes[low]) << 24) + (get(pos + indexes[low + 1]) << 16) |
| 201 | + + (get(pos + indexes[low + 2]) << 8) + get(pos + indexes[low + 3]); |
| 202 | + pos += 4; |
| 203 | + return value; |
191 | 204 | }
|
192 | 205 |
|
193 |
| - return bytes; |
| 206 | + long getLong() { |
| 207 | + long value = ((long) get(pos + indexes[1]) << 56) + ((long) get(pos + indexes[2]) << 48) |
| 208 | + + ((long) get(pos + indexes[3]) << 40) + ((long) get(pos + indexes[4]) << 32) |
| 209 | + + ((long) get(pos + indexes[5]) << 24) + ((long) get(pos + indexes[6]) << 16) |
| 210 | + + ((long) get(pos + indexes[7]) << 8) + ((long) get(pos + indexes[8])); |
| 211 | + pos += 8; |
| 212 | + return value; |
| 213 | + } |
| 214 | + |
| 215 | + double getDouble() { |
| 216 | + return Double.longBitsToDouble(getLong()); |
| 217 | + } |
| 218 | + } |
| 219 | + |
| 220 | + private static class StringBuffer extends ByteBuffer { |
| 221 | + final String data; |
| 222 | + |
| 223 | + StringBuffer(String data) { |
| 224 | + this.data = data; |
| 225 | + } |
| 226 | + |
| 227 | + @Override |
| 228 | + int get(int pos) { |
| 229 | + pos *= 2; |
| 230 | + return (Character.digit(data.charAt(pos), 16) << 4) + |
| 231 | + Character.digit(data.charAt(pos + 1), 16); |
| 232 | + } |
| 233 | + } |
| 234 | + |
| 235 | + private static class ArrayBuffer extends ByteBuffer { |
| 236 | + final byte[] data; |
| 237 | + |
| 238 | + ArrayBuffer(byte[] data) { |
| 239 | + this.data = data; |
| 240 | + } |
| 241 | + |
| 242 | + @Override |
| 243 | + int get(int pos) { |
| 244 | + return data[pos] & 0xFF; |
| 245 | + } |
194 | 246 | }
|
195 | 247 | }
|
0 commit comments