Blob.java (2490B) download
1package osm.message;
2
3import java.util.zip.Inflater;
4
5import protobuf.Message;
6import protobuf.ProtobufReader;
7
8import java.io.UnsupportedEncodingException;
9import java.util.Iterator;
10import java.util.List;
11import java.util.zip.DataFormatException;
12
13// optional bytes raw = 1; // No compression
14// optional int32 raw_size = 2; // When compressed, the uncompressed size
15// optional bytes zlib_data = 3;
16// optional bytes lzma_data = 4;
17// optional bytes OBSOLETE_bzip2_data = 5 [deprecated=true]; // Don't reuse this tag number.
18public class Blob implements Message<Blob> {
19 public final String headerType;
20 public int size = 0;
21
22 public HeaderBlock header = null;
23 public List<Entity> primitive = null;
24
25 public Blob(String headerType) {
26 this.headerType = headerType;
27 }
28
29 @Override
30 public Blob parse(Iterator<ProtobufReader> tags) {
31 while (tags.hasNext()) {
32 ProtobufReader message = tags.next();
33 switch (message.tag()) {
34 case 1 -> {
35 switch (headerType) {
36 case "OSMHeader" -> header = message.message(new HeaderBlock());
37 case "OSMData" -> primitive = message.message(new PrimitiveBlock());
38 }
39 }
40 case 2 -> size = message.varint32();
41 case 3 -> {
42 switch (headerType) {
43 case "OSMHeader" -> message.delayed(new HeaderBlock(), this::decompress, this::setHeader);
44 case "OSMData" -> message.delayed(new PrimitiveBlock(), this::decompress, this::setPrimitive);
45 }
46 }
47 default -> message.throwUnexpected();
48 }
49 }
50
51 return this;
52 }
53
54 private void setHeader(HeaderBlock header) {
55 this.header = header;
56 }
57
58 private void setPrimitive(List<Entity> primitive) {
59 this.primitive = primitive;
60 }
61
62 private byte[] decompress(byte[] block) {
63 Inflater decompresser = new Inflater();
64 decompresser.setInput(block);
65
66 try {
67 byte[] buffer = new byte[size];
68 int uncompressedSize = decompresser.inflate(buffer);
69
70 if (uncompressedSize != size) {
71 throw new RuntimeException("Invalid blob payload size");
72 }
73
74 return buffer;
75 } catch (DataFormatException exc) {
76 throw new RuntimeException(exc);
77 }
78 }
79}