Skip to content

Commit

Permalink
Add PositionInfo interface.
Browse files Browse the repository at this point in the history
  • Loading branch information
Mingun committed May 11, 2021
1 parent 24923ed commit 3ff5133
Show file tree
Hide file tree
Showing 3 changed files with 196 additions and 0 deletions.
54 changes: 54 additions & 0 deletions src/main/java/io/kaitai/struct/ArrayRegion.java
Original file line number Diff line number Diff line change
@@ -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<Region> items;

public ArrayRegion(KaitaiStream io) {
super(io);
items = new ArrayList<Region>();
}

public ArrayRegion(KaitaiStream io, int size) {
super(io);
items = new ArrayList<Region>(size);
}

public Region addRegion(KaitaiStream io) {
final Region region = new Region(io);
items.add(region);
return region;
}
}
55 changes: 55 additions & 0 deletions src/main/java/io/kaitai/struct/PositionInfo.java
Original file line number Diff line number Diff line change
@@ -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.
* <p>
* If you want to work with generated structures in the generic way, you can use
* following code snipped to deal with positions information:
* <code>
* 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;
* //...
* }
* </code>
*
* @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<String, Region> _regions();
}
87 changes: 87 additions & 0 deletions src/main/java/io/kaitai/struct/Region.java
Original file line number Diff line number Diff line change
@@ -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()}.
* <p>
* 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.
* <p>
* 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.
* <p>
* 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; }
}

0 comments on commit 3ff5133

Please sign in to comment.