diff --git a/src/main/java/io/kaitai/struct/ArrayRegion.java b/src/main/java/io/kaitai/struct/ArrayRegion.java new file mode 100644 index 0000000..c35130b --- /dev/null +++ b/src/main/java/io/kaitai/struct/ArrayRegion.java @@ -0,0 +1,54 @@ +/** + * Copyright 2015-2020 Kaitai Project: MIT license + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package io.kaitai.struct; + +import java.util.ArrayList; +import java.util.List; + +/** + * Region that represents positional information of array field and each of it + * elements. + * + * @since 0.9 + */ +public class ArrayRegion extends Region { + /** Individual regions of each item in the array. */ + public final List items; + + public ArrayRegion(KaitaiStream io) { + super(io); + items = new ArrayList(); + } + + public ArrayRegion(KaitaiStream io, int size) { + super(io); + items = new ArrayList(size); + } + + public Region addRegion(KaitaiStream io) { + final Region region = new Region(io); + items.add(region); + return region; + } +} diff --git a/src/main/java/io/kaitai/struct/PositionInfo.java b/src/main/java/io/kaitai/struct/PositionInfo.java new file mode 100644 index 0000000..c5a73ab --- /dev/null +++ b/src/main/java/io/kaitai/struct/PositionInfo.java @@ -0,0 +1,55 @@ +/** + * Copyright 2015-2020 Kaitai Project: MIT license + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package io.kaitai.struct; + +import java.util.Map; + +/** + * This interface is implemented by each {@link KaitaiStruct} successor, if + * class was generated with positional information. + *

+ * If you want to work with generated structures in the generic way, you can use + * following code snipped to deal with positions information: + * + * final KaitaiStruct struct = ...; + * // Generator generates classes, that implements this interface, + * // if debug mode/positions-info is enabled + * if (struct instanceof PositionInfo) { + * final PositionInfo info = (PositionInfo)struct; + * //... + * } + * + * + * @since 0.9 + */ +public interface PositionInfo { + /** + * Information about each struct field. If field is array, than corresponding + * {@code Region} will be of {@link ArrayRegion} instance. Field names equals + * to names of java methods/fields in generated class. + * + * @return the map from field name to region information. + */ + Map _regions(); +} diff --git a/src/main/java/io/kaitai/struct/Region.java b/src/main/java/io/kaitai/struct/Region.java new file mode 100644 index 0000000..86ec7a4 --- /dev/null +++ b/src/main/java/io/kaitai/struct/Region.java @@ -0,0 +1,87 @@ +/** + * Copyright 2015-2020 Kaitai Project: MIT license + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package io.kaitai.struct; + +/** + * Information about positions of parsed value in the streams. + * + * @since 0.9 + */ +public class Region { + /** Offset from begin of root stream, for which that region was created. */ + public final long offset; + /** + * Offset from begin of stream, from which value was parsed. This is relative + * position, to get absolute position (relative to root stream) use + * {@link #absoluteStart()}. That offset always non-negative. + */ + public final long start; + /** + * Offset from begin of stream, from which value was parsed. This is relative + * position, to get absolute position (relative to root stream) use + * {@link #absoluteEnd()}. + *

+ * If that offset is negative, then value wasn't parsed yet or exception was + * thrown while parsing value. + */ + public long end = -1; + + /** + * Creates region that starts at current stream offset and ends at unknown position. + * + * @param io the stream to get positional information + */ + public Region(KaitaiStream io) { + this(io.offset(), io.pos()); + } + private Region(long offset, long start) { + this.offset = offset; + this.start = start; + } + + /** + * Offset to the start of this region relative to the root stream. + * + * @return start offset from the root stream + */ + public long absoluteStart() { return offset + start; } + /** + * Offset to the end of this region relative to the root stream. + *

+ * If that offset is negative, then value wasn't parsed yet or exception was + * thrown while parsing value. + * + * @return start offset from the root stream or negative value if value not yet parsed + */ + public long absoluteEnd() { return end < 0 ? -1 : offset + end; } + /** + * Size of this region in bytes. + *

+ * If size is negative, then value wasn't parsed yet or exception was + * thrown while parsing value. + * + * @return size of the region + */ + public long size() { return end < 0 ? -1 : end - start; } +}