// Path: mapsforge-core/src/main/java/org/mapsforge/core/util/Parameters.java
// public final class Parameters {
// 
//     public enum ParentTilesRendering {QUALITY, SPEED, OFF}
// 
//     public enum SymbolScaling {ALL, POI}
// 
//     /**
//      * If true will use anti-aliasing in rendering.
//      */
//     public static boolean ANTI_ALIASING = true;
// 
//     /**
//      * If true the <code>FrameBufferHA3</code> will be used instead of default <code>FrameBufferHA2}</code>.
//      */
//     public static boolean FRAME_BUFFER_HA3 = true;
// 
//     /**
//      * Process layer scroll events.
//      */
//     public static boolean LAYER_SCROLL_EVENT = false;
// 
//     /**
//      * Maximum buffer size for map files.
//      */
//     public static int MAXIMUM_BUFFER_SIZE = 10000000;
// 
//     /**
//      * The default number of threads is one greater than the number of processors, as one thread is
//      * likely to be blocked on I/O reading map data. Technically this value can change to a better
//      * implementation, maybe one that also takes the available memory into account would be good.
//      * For stability reasons (see #591), we set default number of threads to 1.
//      */
//     public static int NUMBER_OF_THREADS = 1;//Runtime.getRuntime().availableProcessors() + 1;
// 
//     /**
//      * Parent tiles rendering mode.
//      */
//     public static ParentTilesRendering PARENT_TILES_RENDERING = ParentTilesRendering.QUALITY;
// 
//     /**
//      * If square frame buffer is enabled, the frame buffer allocated for drawing will be
//      * large enough for drawing in either orientation, so no change is needed when the device
//      * orientation changes. To avoid overly large frame buffers, the aspect ratio for this policy
//      * determines when this will be used.
//      */
//     public static boolean SQUARE_FRAME_BUFFER = true;
// 
//     /**
//      * Symbol scaling mode.
//      */
//     public static SymbolScaling SYMBOL_SCALING = SymbolScaling.POI;
// 
//     /**
//      * Validate coordinates.
//      */
//     public static boolean VALIDATE_COORDINATES = true;
// 
//     private Parameters() {
//         throw new IllegalStateException();
//     }
// }


import org.mapsforge.core.model.Tag;
import org.mapsforge.core.util.Parameters;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
/*
 * Copyright 2010, 2011, 2012, 2013 mapsforge.org
 * Copyright 2015-2020 devemux86
 * Copyright 2016 bvgastel
 * Copyright 2017 linuskr
 * Copyright 2017 Gustl22
 *
 * This program is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along with
 * this program. If not, see <http://www.gnu.org/licenses/>.
 */
package org.mapsforge.map.reader;



/**
 * Reads from a {@link RandomAccessFile} into a buffer and decodes the data.
 */
public class ReadBuffer {

    private static final String CHARSET_UTF8 = "UTF-8";
    private static final Logger LOGGER = Logger.getLogger(ReadBuffer.class.getName());

    private byte[] bufferData;
    private int bufferPosition;
    private ByteBuffer bufferWrapper;
    private final FileChannel inputChannel;

    private final List<Integer> tagIds = new ArrayList<>();

    ReadBuffer(FileChannel inputChannel) {
        this.inputChannel = inputChannel;
    }

    /**
     * Returns one byte from the read buffer.
     *
     * @return the byte value.
     */
    public byte readByte() {
        return this.bufferData[this.bufferPosition++];
    }

    /**
     * Converts four bytes from the read buffer to a float.
     * <p/>
     * The byte order is big-endian.
     *
     * @return the float value.
     */
    public float readFloat() {
        return Float.intBitsToFloat(readInt());
    }

    /**
     * Reads the given amount of bytes from the file into the read buffer and resets the internal buffer position. If
     * the capacity of the read buffer is too small, a larger one is created automatically.
     *
     * @param length the amount of bytes to read from the file.
     * @return true if the whole data was read successfully, false otherwise.
     * @throws IOException if an error occurs while reading the file.
     */
    public boolean readFromFile(int length) throws IOException {
        // ensure that the read buffer is large enough
        if (this.bufferData == null || this.bufferData.length < length) {
            // ensure that the read buffer is not too large
// Path: mapsforge-core/src/main/java/org/mapsforge/core/util/Parameters.java
// public final class Parameters {
// 
//     public enum ParentTilesRendering {QUALITY, SPEED, OFF}
// 
//     public enum SymbolScaling {ALL, POI}
// 
//     /**
//      * If true will use anti-aliasing in rendering.
//      */
//     public static boolean ANTI_ALIASING = true;
// 
//     /**
//      * If true the <code>FrameBufferHA3</code> will be used instead of default <code>FrameBufferHA2}</code>.
//      */
//     public static boolean FRAME_BUFFER_HA3 = true;
// 
//     /**
//      * Process layer scroll events.
//      */
//     public static boolean LAYER_SCROLL_EVENT = false;
// 
//     /**
//      * Maximum buffer size for map files.
//      */
//     public static int MAXIMUM_BUFFER_SIZE = 10000000;
// 
//     /**
//      * The default number of threads is one greater than the number of processors, as one thread is
//      * likely to be blocked on I/O reading map data. Technically this value can change to a better
//      * implementation, maybe one that also takes the available memory into account would be good.
//      * For stability reasons (see #591), we set default number of threads to 1.
//      */
//     public static int NUMBER_OF_THREADS = 1;//Runtime.getRuntime().availableProcessors() + 1;
// 
//     /**
//      * Parent tiles rendering mode.
//      */
//     public static ParentTilesRendering PARENT_TILES_RENDERING = ParentTilesRendering.QUALITY;
// 
//     /**
//      * If square frame buffer is enabled, the frame buffer allocated for drawing will be
//      * large enough for drawing in either orientation, so no change is needed when the device
//      * orientation changes. To avoid overly large frame buffers, the aspect ratio for this policy
//      * determines when this will be used.
//      */
//     public static boolean SQUARE_FRAME_BUFFER = true;
// 
//     /**
//      * Symbol scaling mode.
//      */
//     public static SymbolScaling SYMBOL_SCALING = SymbolScaling.POI;
// 
//     /**
//      * Validate coordinates.
//      */
//     public static boolean VALIDATE_COORDINATES = true;
// 
//     private Parameters() {
//         throw new IllegalStateException();
//     }
// }


// Path: mapsforge-map-reader/src/main/java/org/mapsforge/map/reader/ReadBuffer.java
import org.mapsforge.core.model.Tag;
import org.mapsforge.core.util.Parameters;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/*
 * Copyright 2010, 2011, 2012, 2013 mapsforge.org
 * Copyright 2015-2020 devemux86
 * Copyright 2016 bvgastel
 * Copyright 2017 linuskr
 * Copyright 2017 Gustl22
 *
 * This program is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along with
 * this program. If not, see <http://www.gnu.org/licenses/>.
 */
package org.mapsforge.map.reader;



/**
 * Reads from a {@link RandomAccessFile} into a buffer and decodes the data.
 */
public class ReadBuffer {

    private static final String CHARSET_UTF8 = "UTF-8";
    private static final Logger LOGGER = Logger.getLogger(ReadBuffer.class.getName());

    private byte[] bufferData;
    private int bufferPosition;
    private ByteBuffer bufferWrapper;
    private final FileChannel inputChannel;

    private final List<Integer> tagIds = new ArrayList<>();

    ReadBuffer(FileChannel inputChannel) {
        this.inputChannel = inputChannel;
    }

    /**
     * Returns one byte from the read buffer.
     *
     * @return the byte value.
     */
    public byte readByte() {
        return this.bufferData[this.bufferPosition++];
    }

    /**
     * Converts four bytes from the read buffer to a float.
     * <p/>
     * The byte order is big-endian.
     *
     * @return the float value.
     */
    public float readFloat() {
        return Float.intBitsToFloat(readInt());
    }

    /**
     * Reads the given amount of bytes from the file into the read buffer and resets the internal buffer position. If
     * the capacity of the read buffer is too small, a larger one is created automatically.
     *
     * @param length the amount of bytes to read from the file.
     * @return true if the whole data was read successfully, false otherwise.
     * @throws IOException if an error occurs while reading the file.
     */
    public boolean readFromFile(int length) throws IOException {
        // ensure that the read buffer is large enough
        if (this.bufferData == null || this.bufferData.length < length) {
            // ensure that the read buffer is not too large
            if (length > Parameters.MAXIMUM_BUFFER_SIZE) {