Changeset 33012 in osm for applications/editors/josm


Ignore:
Timestamp:
2016-09-24T14:37:01+02:00 (8 years ago)
Author:
donvip
Message:

checkstyle

Location:
applications/editors/josm/plugins/o5m
Files:
3 added
4 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/o5m/src/org/openstreetmap/josm/plugins/o5m/O5mConstants.java

    r32833 r33012  
    1 //    JOSM o5m plugin.
    2 //    Copyright (C) 2013 Gerd Petermann
    3 //
    4 //    This program is free software: you can redistribute it and/or modify
    5 //    it under the terms of the GNU General Public License as published by
    6 //    the Free Software Foundation, either version 3 of the License, or
    7 //    (at your option) any later version.
    8 //
    9 //    This program is distributed in the hope that it will be useful,
    10 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
    11 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12 //    GNU General Public License for more details.
    13 //
    14 //    You should have received a copy of the GNU General Public License
    15 //    along with this program.  If not, see <http://www.gnu.org/licenses/>.
     1// License: GPL. For details, see LICENSE file.
    162package org.openstreetmap.josm.plugins.o5m;
    173
     
    3016     * File extension.
    3117     */
    32     public static final String EXTENSION = "o5m";
     18    String EXTENSION = "o5m";
    3319   
    3420    /**
    3521     * File filter used in import/export dialogs.
    3622     */
    37     public static final ExtensionFileFilter FILE_FILTER = new ExtensionFileFilter(EXTENSION, EXTENSION, tr("OSM Server Files o5m compressed") + " (*."+EXTENSION+")");
     23    ExtensionFileFilter FILE_FILTER = new ExtensionFileFilter(EXTENSION, EXTENSION,
     24            tr("OSM Server Files o5m compressed") + " (*."+EXTENSION+")");
    3825}
  • applications/editors/josm/plugins/o5m/src/org/openstreetmap/josm/plugins/o5m/O5mPlugin.java

    r32833 r33012  
    1 //    JOSM o5m plugin.
    2 //    Copyright (C) 2013 Gerd Petermann
    3 //
    4 //    This program is free software: you can redistribute it and/or modify
    5 //    it under the terms of the GNU General Public License as published by
    6 //    the Free Software Foundation, either version 3 of the License, or
    7 //    (at your option) any later version.
    8 //
    9 //    This program is distributed in the hope that it will be useful,
    10 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
    11 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12 //    GNU General Public License for more details.
    13 //
    14 //    You should have received a copy of the GNU General Public License
    15 //    along with this program.  If not, see <http://www.gnu.org/licenses/>.
     1// License: GPL. For details, see LICENSE file.
    162package org.openstreetmap.josm.plugins.o5m;
    173
  • applications/editors/josm/plugins/o5m/src/org/openstreetmap/josm/plugins/o5m/io/O5mImporter.java

    r32833 r33012  
    1 //    JOSM o5m plugin.
    2 //    Copyright (C) 2013 Gerd Petermann
    3 //
    4 //    This program is free software: you can redistribute it and/or modify
    5 //    it under the terms of the GNU General Public License as published by
    6 //    the Free Software Foundation, either version 3 of the License, or
    7 //    (at your option) any later version.
    8 //
    9 //    This program is distributed in the hope that it will be useful,
    10 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
    11 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12 //    GNU General Public License for more details.
    13 //
    14 //    You should have received a copy of the GNU General Public License
    15 //    along with this program.  If not, see <http://www.gnu.org/licenses/>.
     1// License: GPL. For details, see LICENSE file.
    162package org.openstreetmap.josm.plugins.o5m.io;
    173
     
    3723    }
    3824
    39         /* (non-Javadoc)
    40          * @see org.openstreetmap.josm.io.OsmImporter#parseDataSet(java.io.InputStream, org.openstreetmap.josm.gui.progress.ProgressMonitor)
    41          */
    42         @Override
    43         protected DataSet parseDataSet(InputStream in, ProgressMonitor progressMonitor) throws IllegalDataException {
    44                 return O5mReader.parseDataSet(in, progressMonitor);
    45         }
     25    @Override
     26    protected DataSet parseDataSet(InputStream in, ProgressMonitor progressMonitor) throws IllegalDataException {
     27        return O5mReader.parseDataSet(in, progressMonitor);
     28    }
    4629
    47         protected DataSet parseDataSet(final String source) throws IOException, IllegalDataException {
    48                 try(CachedFile cf = new CachedFile(source)){
    49                         return parseDataSet(cf.getInputStream(), NullProgressMonitor.INSTANCE);
    50                 }
    51         }
     30    protected DataSet parseDataSet(final String source) throws IOException, IllegalDataException {
     31        try (CachedFile cf = new CachedFile(source)) {
     32            return parseDataSet(cf.getInputStream(), NullProgressMonitor.INSTANCE);
     33        }
     34    }
    5235}
  • applications/editors/josm/plugins/o5m/src/org/openstreetmap/josm/plugins/o5m/io/O5mReader.java

    r32857 r33012  
    1 //    JOSM o5m plugin.
    2 //    Copyright (C) 2013 Gerd Petermann
    3 //
    4 //    This program is free software: you can redistribute it and/or modify
    5 //    it under the terms of the GNU General Public License as published by
    6 //    the Free Software Foundation, either version 3 of the License, or
    7 //    (at your option) any later version.
    8 //
    9 //    This program is distributed in the hope that it will be useful,
    10 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
    11 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12 //    GNU General Public License for more details.
    13 //
    14 //    You should have received a copy of the GNU General Public License
    15 //    along with this program.  If not, see <http://www.gnu.org/licenses/>.
     1// License: GPL. For details, see LICENSE file.
    162package org.openstreetmap.josm.plugins.o5m.io;
    173
     
    5238 */
    5339public class O5mReader extends AbstractReader {
    54         public IllegalDataException exception = null;
    55         private boolean discourageUpload;
    56        
     40    public IllegalDataException exception = null;
     41    private boolean discourageUpload;
     42   
    5743    private static void checkCoordinates(LatLon coor) throws IllegalDataException {
    5844        if (!coor.isValid()) {
     
    7359    }
    7460   
    75         // O5M data set constants
    76         private static final int NODE_DATASET = 0x10;
    77         private static final int WAY_DATASET = 0x11;
    78         private static final int REL_DATASET = 0x12;
    79         private static final int BBOX_DATASET = 0xdb;
    80         private static final int TIMESTAMP_DATASET = 0xdc;
    81         private static final int HEADER_DATASET = 0xe0;
    82         private static final int EOD_FLAG = 0xfe;
    83         private static final int RESET_FLAG = 0xff;
    84        
    85         private static final int EOF_FLAG = -1;
    86        
    87         // o5m constants
    88         private static final int STRING_TABLE_SIZE = 15000;
    89         private static final int MAX_STRING_PAIR_SIZE = 250 + 2;
    90         private static final String[] REL_REF_TYPES = {"node", "way", "relation", "?"};
    91         private static final double FACTOR = 1d/1000000000; // used with 100*<Val>*FACTOR
    92        
    93         private final BufferedInputStream fis;
    94         private InputStream is;
    95         private ByteArrayInputStream bis;
    96        
    97         // buffer for byte -> String conversions
    98         private byte[] cnvBuffer;
    99        
    100         private byte[] ioBuf;
    101         private int ioPos;
    102         // the o5m string table
    103         private String[][] stringTable;
    104         private String[] stringPair;
    105         private int currStringTablePos;
    106         // a counter that must be maintained by all routines that read data from the stream
    107         private int bytesToRead;
    108         // total number of bytes read from stream
    109         long countBytes;
    110 
    111         // for delta calculations
    112         private long lastNodeId;
    113         private long lastWayId;
    114         private long lastRelId;
    115         private long lastRef[];
    116         private long lastTs;
    117         private long lastChangeSet;
    118         private int lastLon,lastLat;
    119         private int version;
    120                 private User osmUser;
    121         private String header;
    122         /**
    123          * A parser for the o5m format
    124          * @param stream The InputStream that contains the OSM data in o5m format
    125          */
    126         O5mReader(InputStream stream) {
    127                 this.fis = new BufferedInputStream(stream);
    128                 is = fis;
    129                 this.cnvBuffer = new byte[4000]; // OSM data should not contain string pairs with length > 512
    130                 this.ioBuf = new byte[8192];
    131                 this.ioPos = 0;
    132                 this.stringPair = new String[2];
    133                 this.lastRef = new long[3];
    134                 reset();
    135         }
    136 
    137         /**
    138          * parse the input stream
    139          */
    140         public void parse(){
    141                 try {
    142                         int start = is.read();
    143                         ++countBytes;
    144                         if (start != RESET_FLAG)
    145                                 throw new IOException(tr("wrong header byte ") + Integer.toHexString(start));
    146                         readFile();
    147                         if (discourageUpload)
    148                                 ds.setUploadDiscouraged(true);
    149                 } catch (IOException e) {
    150                         e.printStackTrace();
    151                 }
    152         }
    153        
    154         private void readFile() throws IOException{
    155                 boolean done = false;
    156                 while(!done){
    157                         is = fis;
    158                         long size = 0;
    159                         int fileType = is.read();
    160                         ++countBytes;
    161                         if (fileType >= 0 && fileType < 0xf0){
    162                                 bytesToRead = 0;
    163                                 size = readUnsignedNum64FromStream();
    164                                 countBytes += size - bytesToRead; // bytesToRead is negative
    165                                 bytesToRead = (int)size;
    166                                
    167                                 switch(fileType){
    168                                 case NODE_DATASET:
    169                                 case WAY_DATASET:
    170                                 case REL_DATASET:
    171                                 case BBOX_DATASET:
    172                                 case TIMESTAMP_DATASET:
    173                                 case HEADER_DATASET:
    174                                         if (bytesToRead > ioBuf.length){
    175                                                 ioBuf = new byte[bytesToRead+100];
    176                                         }
    177                                         int bytesRead  = 0;
    178                                         int neededBytes = bytesToRead;
    179                                         while (neededBytes > 0){
    180                                                 bytesRead += is.read(ioBuf, bytesRead, neededBytes);
    181                                                 neededBytes -= bytesRead;
    182                                         }
    183                                         ioPos = 0;
    184                                         bis = new ByteArrayInputStream(ioBuf,0,bytesToRead);
    185                                         is = bis;
    186                                         break;                                 
    187                                 default:       
    188                                 }
    189                         }
    190                         if (fileType == EOF_FLAG) done = true;
    191                         else if (fileType == NODE_DATASET) readNode();
    192                         else if (fileType == WAY_DATASET) readWay();
    193                         else if (fileType == REL_DATASET) readRel();
    194                         else if (fileType == BBOX_DATASET) readBBox();
    195                         else if (fileType == TIMESTAMP_DATASET) readFileTimestamp();
    196                         else if (fileType == HEADER_DATASET) readHeader();
    197                         else if (fileType == EOD_FLAG) done = true;
    198                         else if (fileType == RESET_FLAG) reset();
    199                         else {
    200                                 if (fileType < 0xf0 )skip(size); // skip unknown data set
    201                         }
    202                 }
    203         }
    204        
    205         /**
    206          * read (and ignore) the file timestamp data set
    207          */
    208         private void readFileTimestamp(){
    209                 /*long fileTimeStamp = */readSignedNum64();
    210         }
    211        
    212         /**
    213          * Skip the given number of bytes
    214          * @param bytes
    215          * @throws IOException
    216          */
    217         private void skip(long bytes)throws IOException{
    218                 long toSkip = bytes;
    219                 while (toSkip > 0)
    220                         toSkip -= is.skip(toSkip);
    221         }
    222        
    223         /**
    224          * read the bounding box data set
    225          * @throws IOException
    226          */
    227         private void readBBox() {
    228                 double minlon = FACTOR * 100L * readSignedNum32();
    229                 double minlat = FACTOR * 100L * readSignedNum32();
    230                 double maxlon = FACTOR * 100L * readSignedNum32();
    231                 double maxlat = FACTOR * 100L * readSignedNum32();
     61        // O5M data set constants
     62        private static final int NODE_DATASET = 0x10;
     63        private static final int WAY_DATASET = 0x11;
     64        private static final int REL_DATASET = 0x12;
     65        private static final int BBOX_DATASET = 0xdb;
     66        private static final int TIMESTAMP_DATASET = 0xdc;
     67        private static final int HEADER_DATASET = 0xe0;
     68        private static final int EOD_FLAG = 0xfe;
     69        private static final int RESET_FLAG = 0xff;
     70       
     71        private static final int EOF_FLAG = -1;
     72       
     73        // o5m constants
     74        private static final int STRING_TABLE_SIZE = 15000;
     75        private static final int MAX_STRING_PAIR_SIZE = 250 + 2;
     76        private static final String[] REL_REF_TYPES = {"node", "way", "relation", "?"};
     77        private static final double FACTOR = 1d/1000000000; // used with 100*<Val>*FACTOR
     78       
     79        private final BufferedInputStream fis;
     80        private InputStream is;
     81        private ByteArrayInputStream bis;
     82       
     83        // buffer for byte -> String conversions
     84        private byte[] cnvBuffer;
     85       
     86        private byte[] ioBuf;
     87        private int ioPos;
     88        // the o5m string table
     89        private String[][] stringTable;
     90        private String[] stringPair;
     91        private int currStringTablePos;
     92        // a counter that must be maintained by all routines that read data from the stream
     93        private int bytesToRead;
     94        // total number of bytes read from stream
     95        long countBytes;
     96
     97        // for delta calculations
     98        private long lastNodeId;
     99        private long lastWayId;
     100        private long lastRelId;
     101        private long[] lastRef;
     102        private long lastTs;
     103        private long lastChangeSet;
     104        private int lastLon, lastLat;
     105        private int version;
     106        private User osmUser;
     107        private String header;
     108        /**
     109         * A parser for the o5m format
     110         * @param stream The InputStream that contains the OSM data in o5m format
     111         */
     112        O5mReader(InputStream stream) {
     113            this.fis = new BufferedInputStream(stream);
     114            is = fis;
     115            this.cnvBuffer = new byte[4000]; // OSM data should not contain string pairs with length > 512
     116            this.ioBuf = new byte[8192];
     117            this.ioPos = 0;
     118            this.stringPair = new String[2];
     119            this.lastRef = new long[3];
     120            reset();
     121        }
     122
     123        /**
     124         * parse the input stream
     125         */
     126        public void parse() {
     127            try {
     128                int start = is.read();
     129                ++countBytes;
     130                if (start != RESET_FLAG)
     131                    throw new IOException(tr("wrong header byte ") + Integer.toHexString(start));
     132                readFile();
     133                if (discourageUpload)
     134                    ds.setUploadDiscouraged(true);
     135            } catch (IOException e) {
     136                e.printStackTrace();
     137            }
     138        }
     139       
     140        private void readFile() throws IOException {
     141            boolean done = false;
     142            while (!done) {
     143                is = fis;
     144                long size = 0;
     145                int fileType = is.read();
     146                ++countBytes;
     147                if (fileType >= 0 && fileType < 0xf0) {
     148                    bytesToRead = 0;
     149                    size = readUnsignedNum64FromStream();
     150                    countBytes += size - bytesToRead; // bytesToRead is negative
     151                    bytesToRead = (int) size;
     152                   
     153                    switch(fileType) {
     154                    case NODE_DATASET:
     155                    case WAY_DATASET:
     156                    case REL_DATASET:
     157                    case BBOX_DATASET:
     158                    case TIMESTAMP_DATASET:
     159                    case HEADER_DATASET:
     160                        if (bytesToRead > ioBuf.length) {
     161                            ioBuf = new byte[bytesToRead+100];
     162                        }
     163                        int bytesRead = 0;
     164                        int neededBytes = bytesToRead;
     165                        while (neededBytes > 0) {
     166                            bytesRead += is.read(ioBuf, bytesRead, neededBytes);
     167                            neededBytes -= bytesRead;
     168                        }
     169                        ioPos = 0;
     170                        bis = new ByteArrayInputStream(ioBuf, 0, bytesToRead);
     171                        is = bis;
     172                        break;                   
     173                    default:   
     174                    }
     175                }
     176                if (fileType == EOF_FLAG) done = true;
     177                else if (fileType == NODE_DATASET) readNode();
     178                else if (fileType == WAY_DATASET) readWay();
     179                else if (fileType == REL_DATASET) readRel();
     180                else if (fileType == BBOX_DATASET) readBBox();
     181                else if (fileType == TIMESTAMP_DATASET) readFileTimestamp();
     182                else if (fileType == HEADER_DATASET) readHeader();
     183                else if (fileType == EOD_FLAG) done = true;
     184                else if (fileType == RESET_FLAG) reset();
     185                else {
     186                    if (fileType < 0xf0) skip(size); // skip unknown data set
     187                }
     188            }
     189        }
     190       
     191        /**
     192         * read (and ignore) the file timestamp data set
     193         */
     194        private void readFileTimestamp() {
     195            /*long fileTimeStamp = */readSignedNum64();
     196        }
     197       
     198        /**
     199         * Skip the given number of bytes
     200         * @param bytes number of bytes to skip
     201         * @throws IOException in case of I/O error
     202         */
     203        private void skip(long bytes) throws IOException {
     204            long toSkip = bytes;
     205            while (toSkip > 0) {
     206                toSkip -= is.skip(toSkip);
     207            }
     208        }
     209       
     210        /**
     211         * read the bounding box data set
     212         * @throws IOException in case of I/O error
     213         */
     214        private void readBBox() {
     215            double minlon = FACTOR * 100L * readSignedNum32();
     216            double minlat = FACTOR * 100L * readSignedNum32();
     217            double maxlon = FACTOR * 100L * readSignedNum32();
     218            double maxlat = FACTOR * 100L * readSignedNum32();
    232219
    233220            Bounds b = new Bounds(minlat, minlon, maxlat, maxlon);
     
    238225                Main.error("Invalid Bounds: "+b);
    239226            }
    240         }
    241 
    242         /**
    243          * read a node data set
    244          * @throws IOException
    245          */
    246         private void readNode() throws IOException{
    247                 if (exception != null)
    248                         return;
    249                 try{
    250                         lastNodeId += readSignedNum64();
    251                         if (bytesToRead == 0)
    252                                 return; // only nodeId: this is a delete action, we ignore it
    253                         readVersionTsAuthor();
    254 
    255                         if (bytesToRead == 0)
    256                                 return; // only nodeId+version: this is a delete action, we ignore it
    257                         int lon = readSignedNum32() + lastLon; lastLon = lon;
    258                         int lat = readSignedNum32() + lastLat; lastLat = lat;
    259 
    260                         double flon = FACTOR * (100L*lon);
    261                         double flat = FACTOR * (100L*lat);
    262                         assert flat >= -90.0 && flat <= 90.0; 
    263                         assert flon >= -180.0 && flon <= 180.0; 
    264                         if (version == 0)
    265                                 discourageUpload = true;
    266                         Node node = new Node(lastNodeId, version == 0 ? 1:version);
    267                         node.setCoor(new LatLon(flat, flon).getRoundedToOsmPrecision());
    268                        
    269 
    270                         checkCoordinates(node.getCoor());
    271                         checkChangesetId(lastChangeSet);
    272                         node.setChangesetId((int) lastChangeSet);
    273                         // User id
    274                         if (lastTs != 0){
    275                                 checkTimestamp(lastTs);
    276                                 node.setTimestamp(new Date(lastTs * 1000));
    277                                 if (osmUser != null)
    278                                         node.setUser(osmUser);
    279                         }
    280                         if (bytesToRead > 0){
    281                                 Map<String, String> keys = readTags();
    282                                 node.setKeys(keys);
    283                         }
    284                         externalIdMap.put(node.getPrimitiveId(), node);
    285                 } catch (IllegalDataException e) {
    286                         exception = e;
    287                 }
    288 
    289         }
    290        
    291         /**
    292          * read a way data set
    293          * @throws IOException
    294          */
    295         private void readWay() throws IOException{
    296                 if (exception != null)
    297                         return;
    298                 try{
    299                         lastWayId += readSignedNum64();
    300                         if (bytesToRead == 0)
    301                                 return; // only wayId: this is a delete action, we ignore it
    302 
    303                         readVersionTsAuthor();
    304                         if (bytesToRead == 0)
    305                                 return; // only wayId + version: this is a delete action, we ignore it
    306                         if (version == 0)
    307                                 discourageUpload = true;
    308                         final Way way = new Way(lastWayId, version == 0 ? 1:version);
    309                         checkChangesetId(lastChangeSet);
    310                         way.setChangesetId((int) lastChangeSet);
    311                         // User id
    312                         if (lastTs != 0){
    313                                 checkTimestamp(lastTs);
    314                                 way.setTimestamp(new Date(lastTs * 1000));
    315                                 if (osmUser != null)
    316                                         way.setUser(osmUser);
    317                         }
    318 
    319                         long refSize = readUnsignedNum32();
    320                         long stop = bytesToRead - refSize;
    321                         Collection<Long> nodeIds = new ArrayList<>();
    322 
    323                         while(bytesToRead > stop){
    324                                 lastRef[0] += readSignedNum64();
    325                                 nodeIds.add(lastRef[0]);
    326                         }
    327 
    328                         Map<String, String> keys = readTags();
    329                         way.setKeys(keys);
    330                         ways.put(way.getUniqueId(), nodeIds);
    331                         externalIdMap.put(way.getPrimitiveId(), way);
    332                 } catch (IllegalDataException e) {
    333                         exception = e;
    334                 }
    335 
    336         }
    337 
    338         /**
    339          * read a relation data set
    340          * @throws IOException
    341          */
    342         private void readRel() throws IOException{
    343                 if (exception != null)
    344                         return;
    345                 try{
    346                         lastRelId += readSignedNum64();
    347                         if (bytesToRead == 0)
    348                                 return; // only relId: this is a delete action, we ignore it
    349                         readVersionTsAuthor();
    350                         if (bytesToRead == 0)
    351                                 return; // only relId + version: this is a delete action, we ignore it
    352                         if (version == 0)
    353                                 discourageUpload = true;
    354                         final Relation rel = new Relation(lastRelId, version == 0 ? 1:version);
    355                         checkChangesetId(lastChangeSet);
    356                         rel.setChangesetId((int) lastChangeSet);
    357                         if (lastTs != 0){
    358                                 checkTimestamp(lastTs);
    359                                 rel.setTimestamp(new Date(lastTs * 1000));
    360                                 if (osmUser != null)
    361                                         rel.setUser(osmUser);
    362                         }
    363 
    364                         long refSize = readUnsignedNum32();
    365                         long stop = bytesToRead - refSize;
    366                         Collection<RelationMemberData> members = new ArrayList<>();
    367                         while(bytesToRead > stop){
    368                                 long deltaRef = readSignedNum64();
    369                                 int refType = readRelRef();
    370                                 String role = stringPair[1];
    371                                 lastRef[refType] += deltaRef;
    372                                 long memId = lastRef[refType];
    373                                 OsmPrimitiveType type = null;
    374 
    375                                 if (refType == 0){
    376                                         type = OsmPrimitiveType.NODE;
    377                                 }
    378                                 else if (refType == 1){
    379                                         type = OsmPrimitiveType.WAY;
    380                                 }
    381                                 else if (refType == 2){
    382                                         type = OsmPrimitiveType.RELATION;
    383                                 }
    384                                 members.add(new RelationMemberData(role, type, memId));
    385                         }
    386                         Map<String, String> keys = readTags();
    387                         rel.setKeys(keys);
    388                         relations.put(rel.getUniqueId(), members);
    389                         externalIdMap.put(rel.getPrimitiveId(), rel);
    390                 } catch (IllegalDataException e) {
    391                         exception = e;
    392                 }
    393         }
    394        
    395         private Map<String, String> readTags() throws IOException{
    396                 Map<String, String> keys = new HashMap<>();
    397                 while (bytesToRead > 0){
    398                         readStringPair();
    399                         keys.put(stringPair[0],stringPair[1]);
    400                 }
    401                 assert bytesToRead == 0;
    402                 return keys;
    403         }
    404         /**
    405          * Store a new string pair (length check must be performed by caller)
    406          */
    407         private void storeStringPair(){
    408                 stringTable[0][currStringTablePos] = stringPair[0];
    409                 stringTable[1][currStringTablePos] = stringPair[1];
    410                 ++currStringTablePos;
    411                 if (currStringTablePos >= STRING_TABLE_SIZE)
    412                         currStringTablePos = 0;
    413         }
    414 
    415         /**
    416          * set stringPair to the values referenced by given string reference
    417          * No checking is performed.
    418          * @param ref valid values are 1 .. STRING_TABLE_SIZE
    419          */
    420         private void setStringRefPair(int ref){
    421                 int pos = currStringTablePos - ref;
    422                 if (pos < 0)
    423                         pos += STRING_TABLE_SIZE;
    424                 stringPair[0] = stringTable[0][pos];
    425                 stringPair[1] = stringTable[1][pos];
    426         }
    427 
    428         /**
    429          * Read version, time stamp and change set and author. 
    430          * We are not interested in the values, but we have to maintain the string table.
    431          * @throws IOException
    432          */
    433        
    434         private void readVersionTsAuthor() throws IOException {
    435                 stringPair[0] = null;
    436                 stringPair[1] = null;
    437                 version = readUnsignedNum32();
    438                 if (version != 0){
    439                         // version info
    440                         long ts = readSignedNum64() + lastTs; lastTs = ts;
    441                         if (ts != 0){
    442                                 long changeSet = readSignedNum32() + lastChangeSet; lastChangeSet = changeSet;
    443                                 readAuthor();
    444                         }
    445                 }
    446         }
    447         /**
    448          * Read author .
    449          * @throws IOException
    450          */
    451         private void readAuthor() throws IOException{
    452                 int stringRef = readUnsignedNum32();
    453                 if (stringRef == 0){
    454                         long toReadStart = bytesToRead;
    455                         long uidNum = readUnsignedNum64();
    456                         if (uidNum == 0)
    457                                 stringPair[0] = "";
    458                         else{
    459                                 stringPair[0] = Long.toString(uidNum);
    460                                 ioPos++; // skip terminating zero from uid
    461                                 --bytesToRead;
    462                         }
    463                         int start = 0;
    464                         int buffPos = 0;
    465                         stringPair[1] = null;
    466                         while(stringPair[1] == null){
    467                                 final int b = ioBuf[ioPos++];
    468                                 --bytesToRead;
    469                                 cnvBuffer[buffPos++] = (byte) b;
    470 
    471                                 if (b == 0)
    472                                         stringPair[1] = new String(cnvBuffer, start, buffPos-1, "UTF-8");
    473                         }
    474                         long bytes = toReadStart - bytesToRead;
    475                         if (bytes <= MAX_STRING_PAIR_SIZE)
    476                                 storeStringPair();
    477                 }
    478                 else
    479                         setStringRefPair(stringRef);
    480                         if (stringPair[0] != null && stringPair[0].isEmpty() == false){
    481                                 long uid = Long.parseLong(stringPair[0]);
    482                                 osmUser = User.createOsmUser(uid, stringPair[1]);
    483                         }
    484                         else
    485                                 osmUser = null;
    486         }
    487        
    488         /**
    489          * read object type ("0".."2") concatenated with role (single string)
    490          * @return 0..3 for type (3 means unknown)
    491          */
    492         private int readRelRef () throws IOException{
    493                 int refType = -1;
    494                 long toReadStart = bytesToRead;
    495                 int stringRef = readUnsignedNum32();
    496                 if (stringRef == 0){
    497                         refType = ioBuf[ioPos++] - 0x30;
    498                         --bytesToRead;
    499 
    500                         if (refType < 0 || refType > 2)
    501                                 refType = 3;
    502                         stringPair[0] = REL_REF_TYPES[refType];
    503                                
    504                         int start = 0;
    505                         int buffPos = 0;
    506                         stringPair[1] = null;
    507                         while(stringPair[1] == null){
    508                                 final int b = ioBuf[ioPos++];
    509                                 --bytesToRead;
    510                                 cnvBuffer[buffPos++] =  (byte)b;
    511 
    512                                 if (b == 0)
    513                                         stringPair[1] = new String(cnvBuffer, start, buffPos-1, "UTF-8");
    514                         }
    515                         long bytes = toReadStart - bytesToRead;
    516                         if (bytes <= MAX_STRING_PAIR_SIZE)
    517                                 storeStringPair();
    518                 }
    519                 else {
    520                         setStringRefPair(stringRef);
    521                         char c = stringPair[0].charAt(0);
    522                         switch (c){
    523                         case 'n': refType = 0; break;
    524                         case 'w': refType = 1; break;
    525                         case 'r': refType = 2; break;
    526                         default: refType = 3;
    527                         }
    528                 }
    529                 return refType;
    530         }
    531        
    532         /**
    533          * read a string pair (see o5m definition)
    534          * @throws IOException
    535          */
    536         private void readStringPair() throws IOException{
    537                 int stringRef = readUnsignedNum32();
    538                 if (stringRef == 0){
    539                         long toReadStart = bytesToRead;
    540                         int cnt = 0;
    541                         int buffPos = 0;
    542                         int start = 0;
    543                         while (cnt < 2){
    544                                 final int b = ioBuf[ioPos++];
    545                                 --bytesToRead;
    546                                 cnvBuffer[buffPos++] =  (byte)b;
    547 
    548                                 if (b == 0){
    549                                         stringPair[cnt] = new String(cnvBuffer, start, buffPos-start-1, "UTF-8");
    550                                         ++cnt;
    551                                         start = buffPos;
    552                                 }
    553                         }
    554                         long bytes = toReadStart - bytesToRead;
    555                         if (bytes <= MAX_STRING_PAIR_SIZE)
    556                                 storeStringPair();
    557                 }
    558                 else
    559                         setStringRefPair(stringRef);
    560         }
    561        
    562         /** reset the delta values and string table */
    563         private void reset(){
    564                 lastNodeId = 0; lastWayId = 0; lastRelId = 0;
    565                 lastRef[0] = 0; lastRef[1] = 0;lastRef[2] = 0;
    566                 lastTs = 0; lastChangeSet = 0;
    567                 lastLon = 0; lastLat = 0;
    568                 stringTable = new String[2][STRING_TABLE_SIZE];
    569                 currStringTablePos = 0;
    570         }
    571 
    572         /**
    573          * read and verify o5m header (known values are o5m2 and o5c2)
    574          * @throws IOException
    575          */
    576         private void readHeader() throws IOException {
    577                 if (ioBuf[0] != 'o' || ioBuf[1] != '5' || (ioBuf[2]!='c'&&ioBuf[2]!='m') ||ioBuf[3] != '2' ){
    578                         throw new IOException(tr("unsupported header"));
    579                 }
    580                 header = new String(ioBuf, 0, 3, "UTF-8");
    581         }
    582        
    583         /**
    584          * read a varying length signed number (see o5m definition)
    585          * @return the number
    586          * @throws IOException
    587          */
    588         private int readSignedNum32() {
    589                 int result;
    590                 int b = ioBuf[ioPos++];
    591                 --bytesToRead;
    592                 result = b;
    593                 if ((b & 0x80) == 0){  // just one byte
    594                         if ((b & 0x01) == 1)
    595                                 return -1-(result>>1);
    596                         return result>>1;
    597                 }
    598                 int sign = b & 0x01;
    599                 result = (result & 0x7e)>>1;
    600                 int fac = 0x40;
    601                 while (((b = ioBuf[ioPos++]) & 0x80) != 0){ // more bytes will follow
    602                         --bytesToRead;
    603                         result += fac * (b & 0x7f) ;
    604                         fac  <<= 7;
    605                 }
    606                 --bytesToRead;
    607                 result += fac * b;
    608                 if (sign == 1) // negative
    609                         return -1-result;
    610                 return result;
    611 
    612         }
    613 
    614         /**
    615          * read a varying length signed number (see o5m definition)
    616          * @return the number
    617          * @throws IOException
    618          */
    619         private long readSignedNum64() {
    620                 long result;
    621                 int b = ioBuf[ioPos++];
    622                 --bytesToRead;
    623                 result = b;
    624                 if ((b & 0x80) == 0){  // just one byte
    625                         if ((b & 0x01) == 1)
    626                                 return -1-(result>>1);
    627                         return result>>1;
    628                 }
    629                 int sign = b & 0x01;
    630                 result = (result & 0x7e)>>1;
    631                 long fac = 0x40;
    632                 while (((b = ioBuf[ioPos++]) & 0x80) != 0){ // more bytes will follow
    633                         --bytesToRead;
    634                         result += fac * (b & 0x7f) ;
    635                         fac  <<= 7;
    636                 }
    637                 --bytesToRead;
    638                 result += fac * b;
    639                 if (sign == 1) // negative
    640                         return -1-result;
    641                 return result;
    642 
    643         }
    644 
    645         /**
    646          * read a varying length unsigned number (see o5m definition)
    647          * @return a long
    648          * @throws IOException
    649          */
    650         private long readUnsignedNum64FromStream()throws IOException {
    651                 int b = is.read();
    652                 --bytesToRead;
    653                 long result = b;
    654                 if ((b & 0x80) == 0){  // just one byte
    655                         return result;
    656                 }
    657                 result &= 0x7f;
    658                 long fac = 0x80;
    659                 while (((b = is.read()) & 0x80) != 0){ // more bytes will follow
    660                         --bytesToRead;
    661                         result += fac * (b & 0x7f) ;
    662                         fac  <<= 7;
    663                 }
    664                 --bytesToRead;
    665                 result += fac * b;
    666                 return result;
    667         }
    668        
    669        
    670         /**
    671          * read a varying length unsigned number (see o5m definition)
    672          * @return a long
    673          * @throws IOException
    674          */
    675         private long readUnsignedNum64(){
    676                 int b = ioBuf[ioPos++];
    677                 --bytesToRead;
    678                 long result = b;
    679                 if ((b & 0x80) == 0){  // just one byte
    680                         return result;
    681                 }
    682                 result &= 0x7f;
    683                 long fac = 0x80;
    684                 while (((b = ioBuf[ioPos++]) & 0x80) != 0){ // more bytes will follow
    685                         --bytesToRead;
    686                         result += fac * (b & 0x7f) ;
    687                         fac  <<= 7;
    688                 }
    689                 --bytesToRead;
    690                 result += fac * b;
    691                 return result;
    692         }
    693 
    694         /**
    695          * read a varying length unsigned number (see o5m definition)
    696          * is similar to the 64 bit version.
    697          * @return an int
    698          * @throws IOException
    699          */
    700         private int readUnsignedNum32(){
    701                 int b = ioBuf[ioPos++];
    702                 --bytesToRead;
    703                 int result = b;
    704                 if ((b & 0x80) == 0){  // just one byte
    705                         return result;
    706                 }
    707                 result &= 0x7f;
    708                 long fac = 0x80;
    709                 while (((b = ioBuf[ioPos++]) & 0x80) != 0){ // more bytes will follow
    710                         --bytesToRead;
    711                         result += fac * (b & 0x7f) ;
    712                         fac  <<= 7;
    713                 }
    714                 --bytesToRead;
    715                 result += fac * b;
    716                 return result;
    717         }
    718 
    719        
     227        }
     228
     229        /**
     230         * read a node data set
     231         * @throws IOException in case of I/O error
     232         */
     233        private void readNode() throws IOException {
     234            if (exception != null)
     235                return;
     236            try {
     237                lastNodeId += readSignedNum64();
     238                if (bytesToRead == 0)
     239                    return; // only nodeId: this is a delete action, we ignore it
     240                readVersionTsAuthor();
     241
     242                if (bytesToRead == 0)
     243                    return; // only nodeId+version: this is a delete action, we ignore it
     244                int lon = readSignedNum32() + lastLon; lastLon = lon;
     245                int lat = readSignedNum32() + lastLat; lastLat = lat;
     246
     247                double flon = FACTOR * (100L*lon);
     248                double flat = FACTOR * (100L*lat);
     249                assert flat >= -90.0 && flat <= 90.0; 
     250                assert flon >= -180.0 && flon <= 180.0; 
     251                if (version == 0)
     252                    discourageUpload = true;
     253                Node node = new Node(lastNodeId, version == 0 ? 1 : version);
     254                node.setCoor(new LatLon(flat, flon).getRoundedToOsmPrecision());
     255               
     256
     257                checkCoordinates(node.getCoor());
     258                checkChangesetId(lastChangeSet);
     259                node.setChangesetId((int) lastChangeSet);
     260                // User id
     261                if (lastTs != 0) {
     262                    checkTimestamp(lastTs);
     263                    node.setTimestamp(new Date(lastTs * 1000));
     264                    if (osmUser != null)
     265                        node.setUser(osmUser);
     266                }
     267                if (bytesToRead > 0) {
     268                    Map<String, String> keys = readTags();
     269                    node.setKeys(keys);
     270                }
     271                externalIdMap.put(node.getPrimitiveId(), node);
     272            } catch (IllegalDataException e) {
     273                exception = e;
     274            }
     275
     276        }
     277       
     278        /**
     279         * read a way data set
     280         * @throws IOException in case of I/O error
     281         */
     282        private void readWay() throws IOException {
     283            if (exception != null)
     284                return;
     285            try {
     286                lastWayId += readSignedNum64();
     287                if (bytesToRead == 0)
     288                    return; // only wayId: this is a delete action, we ignore it
     289
     290                readVersionTsAuthor();
     291                if (bytesToRead == 0)
     292                    return; // only wayId + version: this is a delete action, we ignore it
     293                if (version == 0)
     294                    discourageUpload = true;
     295                final Way way = new Way(lastWayId, version == 0 ? 1 : version);
     296                checkChangesetId(lastChangeSet);
     297                way.setChangesetId((int) lastChangeSet);
     298                // User id
     299                if (lastTs != 0) {
     300                    checkTimestamp(lastTs);
     301                    way.setTimestamp(new Date(lastTs * 1000));
     302                    if (osmUser != null)
     303                        way.setUser(osmUser);
     304                }
     305
     306                long refSize = readUnsignedNum32();
     307                long stop = bytesToRead - refSize;
     308                Collection<Long> nodeIds = new ArrayList<>();
     309
     310                while (bytesToRead > stop) {
     311                    lastRef[0] += readSignedNum64();
     312                    nodeIds.add(lastRef[0]);
     313                }
     314
     315                Map<String, String> keys = readTags();
     316                way.setKeys(keys);
     317                ways.put(way.getUniqueId(), nodeIds);
     318                externalIdMap.put(way.getPrimitiveId(), way);
     319            } catch (IllegalDataException e) {
     320                exception = e;
     321            }
     322
     323        }
     324
     325        /**
     326         * read a relation data set
     327         * @throws IOException in case of I/O error
     328         */
     329        private void readRel() throws IOException {
     330            if (exception != null)
     331                return;
     332            try {
     333                lastRelId += readSignedNum64();
     334                if (bytesToRead == 0)
     335                    return; // only relId: this is a delete action, we ignore it
     336                readVersionTsAuthor();
     337                if (bytesToRead == 0)
     338                    return; // only relId + version: this is a delete action, we ignore it
     339                if (version == 0)
     340                    discourageUpload = true;
     341                final Relation rel = new Relation(lastRelId, version == 0 ? 1 : version);
     342                checkChangesetId(lastChangeSet);
     343                rel.setChangesetId((int) lastChangeSet);
     344                if (lastTs != 0) {
     345                    checkTimestamp(lastTs);
     346                    rel.setTimestamp(new Date(lastTs * 1000));
     347                    if (osmUser != null)
     348                        rel.setUser(osmUser);
     349                }
     350
     351                long refSize = readUnsignedNum32();
     352                long stop = bytesToRead - refSize;
     353                Collection<RelationMemberData> members = new ArrayList<>();
     354                while (bytesToRead > stop) {
     355                    long deltaRef = readSignedNum64();
     356                    int refType = readRelRef();
     357                    String role = stringPair[1];
     358                    lastRef[refType] += deltaRef;
     359                    long memId = lastRef[refType];
     360                    OsmPrimitiveType type = null;
     361
     362                    if (refType == 0) {
     363                        type = OsmPrimitiveType.NODE;
     364                    } else if (refType == 1) {
     365                        type = OsmPrimitiveType.WAY;
     366                    } else if (refType == 2) {
     367                        type = OsmPrimitiveType.RELATION;
     368                    }
     369                    members.add(new RelationMemberData(role, type, memId));
     370                }
     371                Map<String, String> keys = readTags();
     372                rel.setKeys(keys);
     373                relations.put(rel.getUniqueId(), members);
     374                externalIdMap.put(rel.getPrimitiveId(), rel);
     375            } catch (IllegalDataException e) {
     376                exception = e;
     377            }
     378        }
     379       
     380        private Map<String, String> readTags() throws IOException {
     381            Map<String, String> keys = new HashMap<>();
     382            while (bytesToRead > 0) {
     383                readStringPair();
     384                keys.put(stringPair[0], stringPair[1]);
     385            }
     386            assert bytesToRead == 0;
     387            return keys;
     388        }
     389       
     390        /**
     391         * Store a new string pair (length check must be performed by caller)
     392         */
     393        private void storeStringPair() {
     394            stringTable[0][currStringTablePos] = stringPair[0];
     395            stringTable[1][currStringTablePos] = stringPair[1];
     396            ++currStringTablePos;
     397            if (currStringTablePos >= STRING_TABLE_SIZE)
     398                currStringTablePos = 0;
     399        }
     400
     401        /**
     402         * set stringPair to the values referenced by given string reference
     403         * No checking is performed.
     404         * @param ref valid values are 1 .. STRING_TABLE_SIZE
     405         */
     406        private void setStringRefPair(int ref) {
     407            int pos = currStringTablePos - ref;
     408            if (pos < 0)
     409                pos += STRING_TABLE_SIZE;
     410            stringPair[0] = stringTable[0][pos];
     411            stringPair[1] = stringTable[1][pos];
     412        }
     413
     414        /**
     415         * Read version, time stamp and change set and author. 
     416         * We are not interested in the values, but we have to maintain the string table.
     417         * @throws IOException in case of I/O error
     418         */
     419        private void readVersionTsAuthor() throws IOException {
     420            stringPair[0] = null;
     421            stringPair[1] = null;
     422            version = readUnsignedNum32();
     423            if (version != 0) {
     424                // version info
     425                long ts = readSignedNum64() + lastTs; lastTs = ts;
     426                if (ts != 0) {
     427                    long changeSet = readSignedNum32() + lastChangeSet; lastChangeSet = changeSet;
     428                    readAuthor();
     429                }
     430            }
     431        }
     432       
     433        /**
     434         * Read author .
     435         * @throws IOException in case of I/O error
     436         */
     437        private void readAuthor() throws IOException {
     438            int stringRef = readUnsignedNum32();
     439            if (stringRef == 0) {
     440                long toReadStart = bytesToRead;
     441                long uidNum = readUnsignedNum64();
     442                if (uidNum == 0)
     443                    stringPair[0] = "";
     444                else {
     445                    stringPair[0] = Long.toString(uidNum);
     446                    ioPos++; // skip terminating zero from uid
     447                    --bytesToRead;
     448                }
     449                int start = 0;
     450                int buffPos = 0;
     451                stringPair[1] = null;
     452                while (stringPair[1] == null) {
     453                    final int b = ioBuf[ioPos++];
     454                    --bytesToRead;
     455                    cnvBuffer[buffPos++] = (byte) b;
     456
     457                    if (b == 0)
     458                        stringPair[1] = new String(cnvBuffer, start, buffPos-1, "UTF-8");
     459                }
     460                long bytes = toReadStart - bytesToRead;
     461                if (bytes <= MAX_STRING_PAIR_SIZE)
     462                    storeStringPair();
     463            } else
     464                setStringRefPair(stringRef);
     465            if (stringPair[0] != null && stringPair[0].isEmpty() == false) {
     466                long uid = Long.parseLong(stringPair[0]);
     467                osmUser = User.createOsmUser(uid, stringPair[1]);
     468            } else
     469                osmUser = null;
     470        }
     471       
     472        /**
     473         * read object type ("0".."2") concatenated with role (single string)
     474         * @return 0..3 for type (3 means unknown)
     475         */
     476        private int readRelRef() throws IOException {
     477            int refType = -1;
     478            long toReadStart = bytesToRead;
     479            int stringRef = readUnsignedNum32();
     480            if (stringRef == 0) {
     481                refType = ioBuf[ioPos++] - 0x30;
     482                --bytesToRead;
     483
     484                if (refType < 0 || refType > 2)
     485                    refType = 3;
     486                stringPair[0] = REL_REF_TYPES[refType];
     487                   
     488                int start = 0;
     489                int buffPos = 0;
     490                stringPair[1] = null;
     491                while (stringPair[1] == null) {
     492                    final int b = ioBuf[ioPos++];
     493                    --bytesToRead;
     494                    cnvBuffer[buffPos++] = (byte) b;
     495
     496                    if (b == 0)
     497                        stringPair[1] = new String(cnvBuffer, start, buffPos-1, "UTF-8");
     498                }
     499                long bytes = toReadStart - bytesToRead;
     500                if (bytes <= MAX_STRING_PAIR_SIZE)
     501                    storeStringPair();
     502            } else {
     503                setStringRefPair(stringRef);
     504                char c = stringPair[0].charAt(0);
     505                switch (c) {
     506                case 'n': refType = 0; break;
     507                case 'w': refType = 1; break;
     508                case 'r': refType = 2; break;
     509                default: refType = 3;
     510                }
     511            }
     512            return refType;
     513        }
     514       
     515        /**
     516         * read a string pair (see o5m definition)
     517         * @throws IOException in case of I/O error
     518         */
     519        private void readStringPair() throws IOException {
     520            int stringRef = readUnsignedNum32();
     521            if (stringRef == 0) {
     522                long toReadStart = bytesToRead;
     523                int cnt = 0;
     524                int buffPos = 0;
     525                int start = 0;
     526                while (cnt < 2) {
     527                    final int b = ioBuf[ioPos++];
     528                    --bytesToRead;
     529                    cnvBuffer[buffPos++] = (byte) b;
     530
     531                    if (b == 0) {
     532                        stringPair[cnt] = new String(cnvBuffer, start, buffPos-start-1, "UTF-8");
     533                        ++cnt;
     534                        start = buffPos;
     535                    }
     536                }
     537                long bytes = toReadStart - bytesToRead;
     538                if (bytes <= MAX_STRING_PAIR_SIZE)
     539                    storeStringPair();
     540            } else
     541                setStringRefPair(stringRef);
     542        }
     543       
     544        /** reset the delta values and string table */
     545        private void reset() {
     546            lastNodeId = 0; lastWayId = 0; lastRelId = 0;
     547            lastRef[0] = 0; lastRef[1] = 0; lastRef[2] = 0;
     548            lastTs = 0; lastChangeSet = 0;
     549            lastLon = 0; lastLat = 0;
     550            stringTable = new String[2][STRING_TABLE_SIZE];
     551            currStringTablePos = 0;
     552        }
     553
     554        /**
     555         * read and verify o5m header (known values are o5m2 and o5c2)
     556         * @throws IOException in case of I/O error
     557         */
     558        private void readHeader() throws IOException {
     559            if (ioBuf[0] != 'o' || ioBuf[1] != '5' || (ioBuf[2] != 'c' && ioBuf[2] != 'm') || ioBuf[3] != '2') {
     560                throw new IOException(tr("unsupported header"));
     561            }
     562            header = new String(ioBuf, 0, 3, "UTF-8");
     563        }
     564       
     565        /**
     566         * read a varying length signed number (see o5m definition)
     567         * @return the number
     568         * @throws IOException in case of I/O error
     569         */
     570        private int readSignedNum32() {
     571            int result;
     572            int b = ioBuf[ioPos++];
     573            --bytesToRead;
     574            result = b;
     575            if ((b & 0x80) == 0) {  // just one byte
     576                if ((b & 0x01) == 1)
     577                    return -1-(result >> 1);
     578                return result >> 1;
     579            }
     580            int sign = b & 0x01;
     581            result = (result & 0x7e) >> 1;
     582            int fac = 0x40;
     583            while (((b = ioBuf[ioPos++]) & 0x80) != 0) { // more bytes will follow
     584                --bytesToRead;
     585                result += fac * (b & 0x7f);
     586                fac <<= 7;
     587            }
     588            --bytesToRead;
     589            result += fac * b;
     590            if (sign == 1) // negative
     591                return -1-result;
     592            return result;
     593
     594        }
     595
     596        /**
     597         * read a varying length signed number (see o5m definition)
     598         * @return the number
     599         * @throws IOException in case of I/O error
     600         */
     601        private long readSignedNum64() {
     602            long result;
     603            int b = ioBuf[ioPos++];
     604            --bytesToRead;
     605            result = b;
     606            if ((b & 0x80) == 0) {  // just one byte
     607                if ((b & 0x01) == 1)
     608                    return -1-(result >> 1);
     609                return result >> 1;
     610            }
     611            int sign = b & 0x01;
     612            result = (result & 0x7e) >> 1;
     613            long fac = 0x40;
     614            while (((b = ioBuf[ioPos++]) & 0x80) != 0) { // more bytes will follow
     615                --bytesToRead;
     616                result += fac * (b & 0x7f);
     617                fac <<= 7;
     618            }
     619            --bytesToRead;
     620            result += fac * b;
     621            if (sign == 1) // negative
     622                return -1-result;
     623            return result;
     624
     625        }
     626
     627        /**
     628         * read a varying length unsigned number (see o5m definition)
     629         * @return a long
     630         * @throws IOException in case of I/O error
     631         */
     632        private long readUnsignedNum64FromStream()throws IOException {
     633            int b = is.read();
     634            --bytesToRead;
     635            long result = b;
     636            if ((b & 0x80) == 0) {  // just one byte
     637                return result;
     638            }
     639            result &= 0x7f;
     640            long fac = 0x80;
     641            while (((b = is.read()) & 0x80) != 0) { // more bytes will follow
     642                --bytesToRead;
     643                result += fac * (b & 0x7f);
     644                fac <<= 7;
     645            }
     646            --bytesToRead;
     647            result += fac * b;
     648            return result;
     649        }
     650       
     651       
     652        /**
     653         * read a varying length unsigned number (see o5m definition)
     654         * @return a long
     655         * @throws IOException in case of I/O error
     656         */
     657        private long readUnsignedNum64() {
     658            int b = ioBuf[ioPos++];
     659            --bytesToRead;
     660            long result = b;
     661            if ((b & 0x80) == 0) {  // just one byte
     662                return result;
     663            }
     664            result &= 0x7f;
     665            long fac = 0x80;
     666            while (((b = ioBuf[ioPos++]) & 0x80) != 0) { // more bytes will follow
     667                --bytesToRead;
     668                result += fac * (b & 0x7f);
     669                fac <<= 7;
     670            }
     671            --bytesToRead;
     672            result += fac * b;
     673            return result;
     674        }
     675
     676        /**
     677         * read a varying length unsigned number (see o5m definition)
     678         * is similar to the 64 bit version.
     679         * @return an int
     680         * @throws IOException in case of I/O error
     681         */
     682        private int readUnsignedNum32() {
     683            int b = ioBuf[ioPos++];
     684            --bytesToRead;
     685            int result = b;
     686            if ((b & 0x80) == 0) {  // just one byte
     687                return result;
     688            }
     689            result &= 0x7f;
     690            long fac = 0x80;
     691            while (((b = ioBuf[ioPos++]) & 0x80) != 0) { // more bytes will follow
     692                --bytesToRead;
     693                result += fac * (b & 0x7f);
     694                fac <<= 7;
     695            }
     696            --bytesToRead;
     697            result += fac * b;
     698            return result;
     699        }
     700
     701       
    720702   
    721703    /**
Note: See TracChangeset for help on using the changeset viewer.