org.sosy_lab.cpachecker.util.states.MemoryLocation.java Source code

Java tutorial

Introduction

Here is the source code for org.sosy_lab.cpachecker.util.states.MemoryLocation.java

Source

/*
 * CPAchecker is a tool for configurable software verification.
 *  This file is part of CPAchecker.
 *
 *  Copyright (C) 2007-2015  Dirk Beyer
 *  All rights reserved.
 *
 *  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.
 *
 *
 *  CPAchecker web page:
 *    http://cpachecker.sosy-lab.org
 */
package org.sosy_lab.cpachecker.util.states;

import static com.google.common.base.Preconditions.checkNotNull;

import java.io.Serializable;
import java.util.Map;
import java.util.Objects;

import org.sosy_lab.common.collect.PathCopyingPersistentTreeMap;
import org.sosy_lab.common.collect.PersistentMap;

import com.google.common.base.Function;
import com.google.common.collect.ComparisonChain;
import com.google.common.primitives.Longs;

/**
* This class describes a location in the memory.
*/
public class MemoryLocation implements Comparable<MemoryLocation>, Serializable {

    private static final long serialVersionUID = -8910967707373729034L;
    private final String functionName;
    private final String identifier;
    private final long offset;

    /**
     * This function can be used to {@link com.google.common.collect.Iterables#transform transform}
     * a collection of {@link String}s to a collection of {@link MemoryLocation}s, representing the
     * respective memory location of the identifiers.
     */
    public static final Function<String, MemoryLocation> FROM_STRING_TO_MEMORYLOCATION = new Function<String, MemoryLocation>() {
        @Override
        public MemoryLocation apply(String variableName) {
            return MemoryLocation.valueOf(variableName);
        }
    };

    /**
     * This function can be used to {@link com.google.common.collect.Iterables#transform transform} a
     * collection of {@link MemoryLocation}s
     * to a collection of {@link String}s, representing the respective variable identifiers.
     */
    public static final Function<MemoryLocation, String> FROM_MEMORYLOCATION_TO_STRING = new Function<MemoryLocation, String>() {
        @Override
        public String apply(MemoryLocation memoryLocation) {
            return memoryLocation.getAsSimpleString();
        }
    };

    private MemoryLocation(String pFunctionName, String pIdentifier, long pOffset) {
        checkNotNull(pFunctionName);
        checkNotNull(pIdentifier);

        functionName = pFunctionName;
        identifier = pIdentifier;
        offset = pOffset;
    }

    private MemoryLocation(String pIdentifier, long pOffset) {
        checkNotNull(pIdentifier);

        int separatorIndex = pIdentifier.indexOf("::");
        if (separatorIndex >= 0) {
            functionName = pIdentifier.substring(0, separatorIndex);
            identifier = pIdentifier.substring(separatorIndex + 2);
        } else {
            functionName = null;
            identifier = pIdentifier;
        }
        offset = pOffset;
    }

    public static MemoryLocation valueOf(String pFunctionName, String pIdentifier, long pOffest) {
        return new MemoryLocation(pFunctionName, pIdentifier, pOffest);
    }

    @Override
    public boolean equals(Object other) {

        if (this == other) {
            return true;
        }

        if (!(other instanceof MemoryLocation)) {
            return false;
        }

        MemoryLocation otherLocation = (MemoryLocation) other;

        return Objects.equals(functionName, otherLocation.functionName)
                && Objects.equals(identifier, otherLocation.identifier) && offset == otherLocation.offset;
    }

    @Override
    public int hashCode() {

        int hc = 17;
        int hashMultiplier = 59;

        hc = hc * hashMultiplier + Objects.hashCode(functionName);
        hc = hc * hashMultiplier + identifier.hashCode();
        hc = hc * hashMultiplier + Longs.hashCode(offset);

        return hc;
    }

    public static MemoryLocation valueOf(String pIdentifier, long pOffest) {
        return new MemoryLocation(pIdentifier, pOffest);
    }

    public static MemoryLocation valueOf(String pVariableName) {

        String[] nameParts = pVariableName.split("::");
        String[] offsetParts = pVariableName.split("/");

        boolean isScoped = nameParts.length == 2;
        boolean hasOffset = offsetParts.length == 2;

        int offset = hasOffset ? Integer.parseInt(offsetParts[1]) : 0;

        if (isScoped) {
            return new MemoryLocation(nameParts[0], nameParts[1].replace("/" + offset, ""), offset);

        } else {
            return new MemoryLocation(nameParts[0].replace("/" + offset, ""), offset);
        }
    }

    public String getAsSimpleString() {
        /*
              String simpleName = identifier + "[" + offset + "]";
            
        return isOnFunctionStack() ? (functionName + "::" + simpleName) : simpleName;
        */

        return isOnFunctionStack() ? (functionName + "::" + identifier) : (identifier);
    }

    public String serialize() {
        String simpleName = identifier + "/" + offset;

        return isOnFunctionStack() ? (functionName + "::" + simpleName) : simpleName;
    }

    public boolean isOnFunctionStack() {
        return functionName != null;
    }

    public boolean isOnFunctionStack(String pFunctionName) {
        return functionName != null && pFunctionName.equals(functionName);
    }

    public String getFunctionName() {
        return checkNotNull(functionName);
    }

    public String getIdentifier() {
        return identifier;
    }

    public long getOffset() {
        return offset;
    }

    @Override
    public String toString() {
        return getAsSimpleString();
    }

    public static PersistentMap<MemoryLocation, Long> transform(PersistentMap<String, Long> pConstantMap) {

        PersistentMap<MemoryLocation, Long> result = PathCopyingPersistentTreeMap.of();

        for (Map.Entry<String, Long> entry : pConstantMap.entrySet()) {
            result = result.putAndCopy(valueOf(entry.getKey()), checkNotNull(entry.getValue()));
        }

        return result;
    }

    @Override
    public int compareTo(MemoryLocation other) {

        int result = 0;

        if (isOnFunctionStack()) {
            if (other.isOnFunctionStack()) {
                result = functionName.compareTo(other.functionName);
            } else {
                result = 1;
            }
        } else {
            if (other.isOnFunctionStack()) {
                result = -1;
            } else {
                result = 0;
            }
        }

        if (result != 0) {
            return result;
        }

        return ComparisonChain.start().compare(identifier, other.identifier).compare(offset, other.offset).result();
    }
}