
com.github.katjahahn.parser.Location.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of portex_2.12 Show documentation
Show all versions of portex_2.12 Show documentation
Java library to parse Portable Executable files
The newest version!
/**
* *****************************************************************************
* Copyright 2014 Katja Hahn
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ****************************************************************************
*/
package com.github.katjahahn.parser
/**
* Contains Location classes. Every location represents a start offset and a size.
* A location is either physical (file offset and size) or virtual
* (in-memory address and size).
*
* @author Katja Hahn
*/
/**
* Location in virtual space.
*
* @param from in-memory start address
* @param size size in bytes
*/
class VirtualLocation(from: Long, size: Long) extends Location(from, size) {
override def merge(that: Location): Location =
new VirtualLocation(this.from, this.size + that.size)
}
/**
* Location in a file on disk.
*
* @param from file offset
* @param size size in bytes
*/
class PhysicalLocation(from: Long, size: Long) extends Location(from, size) {
override def merge(that: Location): Location =
new PhysicalLocation(this.from, this.size + that.size)
override def canEqual(other: Any) = {
other.isInstanceOf[PhysicalLocation]
}
override def equals(other: Any) = {
other match {
case that: PhysicalLocation => that.from == from && that.size == size
case _ => false
}
}
override def hashCode() = {
val prime = 41
prime * (prime + from.hashCode) + size.hashCode
}
}
/**
* Abstract location.
*
* @param from start address (either virtual or physical)
* @param size in bytes
*/
abstract class Location(val from: Long, val size: Long) extends Equals {
/**
* Determines whether this and that location can be merged.
*
* @param that that other location
* @return true iff this location can be merged with that location
*/
def canMerge(that: Location): Boolean =
this.getClass() == that.getClass() &&
this.from + this.size == that.from
/**
* Merges this location with that location to one location.
*
* @param that that other location
* @return the merged location
*/
def merge(that: Location): Location
def canEqual(other: Any) = {
other.isInstanceOf[Location]
}
override def toString(): String = "Loc(" + from + ", " + (from + size) + ")"
override def equals(other: Any) = {
other match {
case that: Location => that.canEqual(Location.this) && from == that.from && size == that.size
case _ => false
}
}
override def hashCode() = {
val prime = 41
prime * (prime + from.hashCode) + size.hashCode
}
}
object Location {
/**
* Merges subsequent locations in a list if possible.
*
* @param locs list of locations
* @return list of locations with the locations merged that can be merged
*/
def mergeContinuous[T <: Location](locs: List[T]): List[T] = {
locs.foldLeft(List[T]()) { (list, loc) =>
// nothing to merge in empty list
if (list.isEmpty) List(loc)
// check if mergeable
else if (list.last.canMerge(loc)) {
// merge last location from the list with present location
// return list without last element plus merged location
list.take(list.length - 1) :+ (list.last.merge(loc).asInstanceOf[T])
} else list :+ loc
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy