Rev 3408 |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* Copyright (C) 2008 Steve Ratcliffe
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* 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 General Public License for more details.
*
*
* Author: Steve Ratcliffe, Robert Vollmert
* Create date: 18-Jul-2008
*/
package uk.me.parabola.imgfmt.app.net;
import java.util.ArrayList;
import java.util.List;
import uk.me.parabola.imgfmt.FormatException;
import uk.me.parabola.imgfmt.app.ImgFileWriter;
/**
* @author Steve Ratcliffe, Robert Vollmert
*/
public class TableC
{
// size of the table, excluding the size field
private int size
;
private final TableA tabA
;
private final List<RouteRestriction
> restrictions =
new ArrayList<RouteRestriction
>();
public TableC
(TableA tabA
) {
this.
tabA = tabA
;
}
/**
* Write the table including size field.
*/
public void write
(ImgFileWriter writer,
int tablesOffset
) {
if (!restrictions.
isEmpty()) {
if (size
< 0x100
)
writer.
put((byte) size
);
else
writer.
putChar((char) size
);
for (RouteRestriction restr : restrictions
)
restr.
write(writer, tablesOffset
);
}
if(tabA.
numRoundaboutArcs() > 0)
writer.
put((byte)tabA.
numRoundaboutArcs());
if(tabA.
numUnpavedArcs() > 0)
writer.
put((byte)tabA.
numUnpavedArcs());
if(tabA.
numFerryArcs() > 0)
writer.
put((byte)tabA.
numFerryArcs());
}
/**
* Add a restriction.
*
* @param restr A new restriction.
* @return The offset into Table C at which the restriction will
* be written.
*/
public int addRestriction
(RouteRestriction restr
) {
int offset = size
;
restrictions.
add(restr
);
size += restr.
getSize();
return offset
;
}
/**
* The size of restriction indices in the nodes area.
*/
private byte getOffsetSize
() {
if (size
< 0x80
)
return 1; // allows 7 bit index (8th bit is flag)
else if (size
< 0x8000
)
return 2; // allows 15 bit index (16th bit is flag)
else
// XXX: haven't seen larger than 2, may well be possible
throw new FormatException
("too many restrictions");
}
public void propagateSizeBytes
() {
byte b = getOffsetSize
();
for (RouteRestriction restr : restrictions
)
restr.
setOffsetSize(b
);
}
public byte getFormat
() {
// Table C format bitmask
// 0x01 = 1-255 bytes of restrictions
// 0x02 = 256-65535 bytes of restrictions
// 0x08 = unpaved roads count present
// 0x10 = ferry count present
int format =
0;
if(size
> 0) {
++format
;
if(size
> 0xff
)
++format
;
}
if(tabA.
numRoundaboutArcs() > 0)
format |= 0x04
;
if(tabA.
numUnpavedArcs() > 0)
format |= 0x08
;
if(tabA.
numFerryArcs() > 0)
format |= 0x10
;
return (byte)format
;
}
}