Skip to content

Commit a56edab

Browse files
committed
Use UTF8 everywhere in writer
1 parent a4cbc9d commit a56edab

File tree

1 file changed

+178
-173
lines changed
  • KeypadMapper3/src/de/enaikoon/android/keypadmapper3/writers

1 file changed

+178
-173
lines changed
Lines changed: 178 additions & 173 deletions
Original file line numberDiff line numberDiff line change
@@ -1,173 +1,178 @@
1-
package de.enaikoon.android.keypadmapper3.writers;
2-
3-
import java.io.ByteArrayOutputStream;
4-
import java.io.IOException;
5-
import java.io.RandomAccessFile;
6-
import java.nio.ByteBuffer;
7-
import java.util.Calendar;
8-
import java.util.Map;
9-
import java.util.Map.Entry;
10-
11-
import android.util.Log;
12-
import de.enaikoon.android.keypadmapper3.KeypadMapperApplication;
13-
import de.enaikoon.android.keypadmapper3.settings.KeypadMapperSettings;
14-
import de.enaikoon.android.keypadmapper3.utils.ByteSearch;
15-
16-
public class OsmWriter {
17-
private int newNodeId = -1;
18-
19-
private static final String OSM_HEADER = "<?xml version='1.0' encoding='UTF-8'?>\n" +
20-
"<osm version='0.6' generator='" +
21-
KeypadMapperApplication.getInstance().getLocalizer().getString("app_name") +
22-
"'>\n";
23-
private static final String OSM_FOOTER = "</osm>\n";
24-
private KeypadMapperSettings settings;
25-
26-
private RandomAccessFile osmFile;
27-
28-
public OsmWriter() {
29-
settings = KeypadMapperApplication.getInstance().getSettings();
30-
}
31-
32-
private String getNewFilename() {
33-
String path = KeypadMapperApplication.getInstance().getKeypadMapperDirectory().getAbsolutePath();
34-
35-
Calendar cal = Calendar.getInstance();
36-
return path + "/" + String.format("%tF_%tH-%tM-%tS", cal, cal, cal, cal) + ".osm";
37-
}
38-
39-
/**
40-
* Adds a new node to the OSM file.
41-
*
42-
* @param lat
43-
* WGS84 latitude of the new node
44-
* @param lon
45-
* WGS84 longitude of the new node
46-
* @param tags
47-
* Map containing the tags for the new node.
48-
* @throws IOException
49-
* if an I/O error occurs
50-
*/
51-
public void addNode(double lat, double lon, Map<String, String> tags) throws IOException {
52-
int nodeId = -KeypadMapperApplication.getInstance().getMapper().getHouseNumberCount();
53-
54-
writeString("\t<node id=\"" + nodeId + "\" visible=\"true\" lat=\"" + lat
55-
+ "\" lon=\"" + lon + "\">\n");
56-
for (Entry<String, String> entry : tags.entrySet()) {
57-
if (entry.getValue() != null && entry.getValue().length() != 0
58-
&& !entry.getValue().equalsIgnoreCase("null")) {
59-
writeString("\t\t<tag k=\"" + entry.getKey() + "\" v=\"" + entry.getValue()
60-
+ "\"/>\n");
61-
}
62-
}
63-
osmFile.writeBytes("\t</node>\n");
64-
65-
}
66-
67-
private void writeString(String str) throws IOException {
68-
osmFile.write(str.getBytes("UTF-8"));
69-
}
70-
71-
public void close() throws IOException {
72-
writeString(OSM_FOOTER);
73-
osmFile.close();
74-
}
75-
76-
/**
77-
* Removes last node.
78-
* File will be open and closed by this function.
79-
*/
80-
public void deleteLastNode() {
81-
ByteArrayOutputStream baos = new ByteArrayOutputStream();
82-
83-
try {
84-
final int bufferSize = 128;
85-
byte [] buffer = new byte[ bufferSize ];
86-
87-
osmFile = new RandomAccessFile(settings.getLastOsmFile(), "rw");
88-
if (osmFile.length() < (OSM_HEADER.getBytes().length + OSM_FOOTER.getBytes().length)) {
89-
Log.e("KeypadMapper", "Cannot undo - no nodes");
90-
return;
91-
}
92-
93-
osmFile.seek(osmFile.length());
94-
95-
long seekTo = osmFile.length();
96-
while (true) {
97-
seekTo = seekTo - bufferSize;
98-
if (seekTo >= 0) {
99-
osmFile.seek(seekTo);
100-
} else {
101-
osmFile.seek(osmFile.length());
102-
osmFile.close();
103-
return;
104-
}
105-
106-
int read = osmFile.read(buffer);
107-
// read line by line
108-
if (read == -1) {
109-
osmFile.close();
110-
baos.close();
111-
return;
112-
}
113-
114-
if (baos.size() == 0) {
115-
baos.write(buffer);
116-
} else {
117-
ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
118-
baos2.write(buffer);
119-
baos2.write(baos.toByteArray());
120-
baos = baos2;
121-
baos2 = null;
122-
}
123-
124-
int idx = ByteSearch.indexOf(baos.toByteArray(), "<node id".getBytes("UTF-8"));
125-
if (idx >= 0) {
126-
127-
osmFile.seek(seekTo + idx);
128-
osmFile.write(OSM_FOOTER.getBytes("UTF-8"));
129-
osmFile.setLength(osmFile.getFilePointer());
130-
osmFile.close();
131-
132-
//Log.d("KeypadMapper", "Last node removed!");
133-
baos.close();
134-
return;
135-
}
136-
}
137-
} catch (Exception e) {
138-
Log.e("KeypadMapper", "failed to delete last node", e);
139-
if (osmFile != null) {
140-
try {
141-
osmFile.close();
142-
baos.close();
143-
} catch (Exception ignored) {}
144-
}
145-
}
146-
}
147-
148-
public void openOsmWriter(boolean append) throws IOException {
149-
if (!append || settings.getLastOsmFile() == null) {
150-
// create/overwrite file
151-
String newFile = getNewFilename();
152-
settings.setLastOsmFile(newFile);
153-
osmFile = new RandomAccessFile(newFile, "rw");
154-
155-
writeString(OSM_HEADER);
156-
} else {
157-
osmFile = new RandomAccessFile(settings.getLastOsmFile(), "rw");
158-
Log.d("KeypadMapper", "header + footer len: " + (OSM_HEADER.getBytes().length + OSM_FOOTER.getBytes().length) + " osm len:" + osmFile.length());
159-
if (osmFile.length() > 0) {
160-
if (osmFile.length() >= (OSM_HEADER.getBytes().length + OSM_FOOTER.getBytes().length)) {
161-
osmFile.seek(osmFile.length() - OSM_FOOTER.getBytes().length);
162-
} else {
163-
osmFile.seek(osmFile.length());
164-
}
165-
}
166-
167-
}
168-
}
169-
170-
public static int getEmptyFileSize() {
171-
return OSM_HEADER.getBytes().length + OSM_FOOTER.getBytes().length;
172-
}
173-
}
1+
package de.enaikoon.android.keypadmapper3.writers;
2+
3+
import java.io.ByteArrayOutputStream;
4+
import java.io.IOException;
5+
import java.io.RandomAccessFile;
6+
import java.io.UnsupportedEncodingException;
7+
import java.nio.ByteBuffer;
8+
import java.util.Calendar;
9+
import java.util.Map;
10+
import java.util.Map.Entry;
11+
12+
import android.util.Log;
13+
import de.enaikoon.android.keypadmapper3.KeypadMapperApplication;
14+
import de.enaikoon.android.keypadmapper3.settings.KeypadMapperSettings;
15+
import de.enaikoon.android.keypadmapper3.utils.ByteSearch;
16+
17+
public class OsmWriter {
18+
private int newNodeId = -1;
19+
20+
private static final String OSM_HEADER = "<?xml version='1.0' encoding='UTF-8'?>\n" +
21+
"<osm version='0.6' generator='" +
22+
KeypadMapperApplication.getInstance().getLocalizer().getString("app_name") +
23+
"'>\n";
24+
private static final String OSM_FOOTER = "</osm>\n";
25+
private KeypadMapperSettings settings;
26+
27+
private RandomAccessFile osmFile;
28+
29+
public OsmWriter() {
30+
settings = KeypadMapperApplication.getInstance().getSettings();
31+
}
32+
33+
private String getNewFilename() {
34+
String path = KeypadMapperApplication.getInstance().getKeypadMapperDirectory().getAbsolutePath();
35+
36+
Calendar cal = Calendar.getInstance();
37+
return path + "/" + String.format("%tF_%tH-%tM-%tS", cal, cal, cal, cal) + ".osm";
38+
}
39+
40+
/**
41+
* Adds a new node to the OSM file.
42+
*
43+
* @param lat
44+
* WGS84 latitude of the new node
45+
* @param lon
46+
* WGS84 longitude of the new node
47+
* @param tags
48+
* Map containing the tags for the new node.
49+
* @throws IOException
50+
* if an I/O error occurs
51+
*/
52+
public void addNode(double lat, double lon, Map<String, String> tags) throws IOException {
53+
int nodeId = -KeypadMapperApplication.getInstance().getMapper().getHouseNumberCount();
54+
55+
writeString("\t<node id=\"" + nodeId + "\" visible=\"true\" lat=\"" + lat
56+
+ "\" lon=\"" + lon + "\">\n");
57+
for (Entry<String, String> entry : tags.entrySet()) {
58+
if (entry.getValue() != null && entry.getValue().length() != 0
59+
&& !entry.getValue().equalsIgnoreCase("null")) {
60+
writeString("\t\t<tag k=\"" + entry.getKey() + "\" v=\"" + entry.getValue()
61+
+ "\"/>\n");
62+
}
63+
}
64+
osmFile.writeBytes("\t</node>\n");
65+
66+
}
67+
68+
private void writeString(String str) throws IOException {
69+
osmFile.write(str.getBytes("UTF-8"));
70+
}
71+
72+
public void close() throws IOException {
73+
writeString(OSM_FOOTER);
74+
osmFile.close();
75+
}
76+
77+
/**
78+
* Removes last node.
79+
* File will be open and closed by this function.
80+
*/
81+
public void deleteLastNode() {
82+
ByteArrayOutputStream baos = new ByteArrayOutputStream();
83+
84+
try {
85+
final int bufferSize = 128;
86+
byte [] buffer = new byte[ bufferSize ];
87+
88+
osmFile = new RandomAccessFile(settings.getLastOsmFile(), "rw");
89+
if (osmFile.length() < (OSM_HEADER.getBytes("UTF-8").length + OSM_FOOTER.getBytes("UTF-8").length)) {
90+
Log.e("KeypadMapper", "Cannot undo - no nodes");
91+
return;
92+
}
93+
94+
osmFile.seek(osmFile.length());
95+
96+
long seekTo = osmFile.length();
97+
while (true) {
98+
seekTo = seekTo - bufferSize;
99+
if (seekTo >= 0) {
100+
osmFile.seek(seekTo);
101+
} else {
102+
osmFile.seek(osmFile.length());
103+
osmFile.close();
104+
return;
105+
}
106+
107+
int read = osmFile.read(buffer);
108+
// read line by line
109+
if (read == -1) {
110+
osmFile.close();
111+
baos.close();
112+
return;
113+
}
114+
115+
if (baos.size() == 0) {
116+
baos.write(buffer);
117+
} else {
118+
ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
119+
baos2.write(buffer);
120+
baos2.write(baos.toByteArray());
121+
baos = baos2;
122+
baos2 = null;
123+
}
124+
125+
int idx = ByteSearch.indexOf(baos.toByteArray(), "<node id".getBytes("UTF-8"));
126+
if (idx >= 0) {
127+
128+
osmFile.seek(seekTo + idx);
129+
osmFile.write(OSM_FOOTER.getBytes("UTF-8"));
130+
osmFile.setLength(osmFile.getFilePointer());
131+
osmFile.close();
132+
133+
//Log.d("KeypadMapper", "Last node removed!");
134+
baos.close();
135+
return;
136+
}
137+
}
138+
} catch (Exception e) {
139+
Log.e("KeypadMapper", "failed to delete last node", e);
140+
if (osmFile != null) {
141+
try {
142+
osmFile.close();
143+
baos.close();
144+
} catch (Exception ignored) {}
145+
}
146+
}
147+
}
148+
149+
public void openOsmWriter(boolean append) throws IOException {
150+
if (!append || settings.getLastOsmFile() == null) {
151+
// create/overwrite file
152+
String newFile = getNewFilename();
153+
settings.setLastOsmFile(newFile);
154+
osmFile = new RandomAccessFile(newFile, "rw");
155+
156+
writeString(OSM_HEADER);
157+
} else {
158+
osmFile = new RandomAccessFile(settings.getLastOsmFile(), "rw");
159+
Log.d("KeypadMapper", "header + footer len: " + (OSM_HEADER.getBytes("UTF-8").length + OSM_FOOTER.getBytes("UTF-8").length) + " osm len:" + osmFile.length());
160+
if (osmFile.length() > 0) {
161+
if (osmFile.length() >= (OSM_HEADER.getBytes("UTF-8").length + OSM_FOOTER.getBytes("UTF-8").length)) {
162+
osmFile.seek(osmFile.length() - OSM_FOOTER.getBytes("UTF-8").length);
163+
} else {
164+
osmFile.seek(osmFile.length());
165+
}
166+
}
167+
168+
}
169+
}
170+
171+
public static int getEmptyFileSize() {
172+
try {
173+
return OSM_HEADER.getBytes("UTF-8").length + OSM_FOOTER.getBytes("UTF-8").length;
174+
} catch (UnsupportedEncodingException e) {
175+
throw new RuntimeException(e);
176+
}
177+
}
178+
}

0 commit comments

Comments
 (0)