Ticket #19624: 19624.patch

File 19624.patch, 3.2 KB (added by taylor.smock, 4 years ago)

RFC 7464 reading implementation

  • src/org/openstreetmap/josm/io/GeoJSONReader.java

     
    33
    44import static org.openstreetmap.josm.tools.I18n.tr;
    55
     6import java.io.BufferedReader;
     7import java.io.ByteArrayInputStream;
     8import java.io.IOException;
    69import java.io.InputStream;
     10import java.io.InputStreamReader;
     11import java.nio.charset.StandardCharsets;
    712import java.util.List;
    813import java.util.Map;
    914import java.util.Objects;
     
    5156    private static final String PROPERTIES = "properties";
    5257    private static final String GEOMETRY = "geometry";
    5358    private static final String TYPE = "type";
     59    /** The record separator is 0x1E per RFC 7464 */
     60    private static final byte RECORD_SEPARATOR_BYTE = 0x1E;
    5461    private JsonParser parser;
    5562    private Projection projection = Projections.getProjectionByCode("EPSG:4326"); // WGS 84
    5663
     
    350357        return tags;
    351358    }
    352359
     360    /**
     361     * Check if the inputstream follows RFC 7464
     362     * @param source The source to check (should be at the beginning)
     363     * @return {@code true} if the initial character is {@link GeoJSONReader#RECORD_SEPARATOR_BYTE}.
     364     */
     365    private static boolean isLineDelimited(InputStream source) {
     366        source.mark(2);
     367        try {
     368            int start = source.read();
     369            if (RECORD_SEPARATOR_BYTE == start) {
     370                return true;
     371            }
     372            source.reset();
     373        } catch (IOException e) {
     374            Logging.error(e);
     375        }
     376        return false;
     377    }
     378
    353379    @Override
    354380    protected DataSet doParseDataSet(InputStream source, ProgressMonitor progressMonitor) throws IllegalDataException {
    355         setParser(Json.createParser(source));
    356381        ds.setUploadPolicy(UploadPolicy.DISCOURAGED);
    357         try {
    358             parse();
    359         } catch (JsonParsingException e) {
    360             throw new IllegalDataException(e);
     382        if (isLineDelimited(source)) {
     383            BufferedReader reader = new BufferedReader(new InputStreamReader(source));
     384            String line = null;
     385            String rs = new String(new byte[]{RECORD_SEPARATOR_BYTE}, StandardCharsets.US_ASCII);
     386            try {
     387                while ((line = reader.readLine()) != null) {
     388                    line = line.replaceFirst(rs, "");
     389                    InputStream is = new ByteArrayInputStream(line.getBytes());
     390                    setParser(Json.createParser(is));
     391                    try {
     392                        parse();
     393                    } catch (JsonParsingException e) {
     394                        throw new IllegalDataException(e);
     395                    } finally {
     396                        is.close();
     397                        parser.close();
     398                    }
     399                }
     400            } catch (IOException e) {
     401                throw new IllegalDataException(e);
     402            }
     403        } else {
     404            setParser(Json.createParser(source));
     405            try {
     406                parse();
     407            } catch (JsonParsingException e) {
     408                throw new IllegalDataException(e);
     409            }
    361410        }
    362411        return getDataSet();
    363412    }