blob: ae98da9aebe0e6163fddad66247d080404b6c011 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2017, 2018 Stephan Wahlbrink and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
#
# Contributors:
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.rj.server.dbg;
import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.eclipse.statet.jcommons.collections.CollectionUtils;
import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.lang.NonNull;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
@NonNullByDefault
public final class Tracepoints {
public static final Logger LOGGER= Logger.getLogger("org.eclipse.statet.rj.server.dbg"); //$NON-NLS-1$
public static final String TOPLEVEL_ELEMENT_ID= "200:"; //$NON-NLS-1$
public static final int indexOfTracepointById(final List<? extends Tracepoint> entries,
final long id) {
for (int idx= 0; idx < entries.size(); idx++) {
if (entries.get(idx).getId() == id) {
return idx;
}
}
return -1;
}
public static final @Nullable TracepointPosition getPositionById(final List<? extends TracepointPosition> list,
final long id) {
for (int j= 0; j < list.size(); j++) {
final TracepointPosition p= list.get(j);
if (p.getId() == id) {
return p;
}
}
return null;
}
public static final boolean containsPositionsById(final List<? extends TracepointPosition> list,
final List<? extends TracepointPosition> requiredIds) {
if (list == requiredIds) {
return true;
}
final int l= requiredIds.size();
if (list.size() < l) {
return false;
}
ITER_REQUIRED: for (int i= 0, j= 0; i < l; i++) {
final long id= requiredIds.get(i).getId();
while (j < list.size()) {
if (list.get(j++).getId() == id) {
continue ITER_REQUIRED;
}
}
return false;
}
return true;
}
public static final boolean equalsPositions(
final List<? extends TracepointPosition> list1, final List<? extends TracepointPosition> list2,
final List<? extends TracepointPosition> requiredIds) {
if (list1 == list2) {
return true;
}
final int l= list1.size();
if (l != list2.size()) {
return false;
}
ITER_REQUIRED: for (int i= 0, j1= 0, j2= 0; i < l; i++) {
final long id= requiredIds.get(i).getId();
while (j1 < list1.size()) {
final TracepointPosition p1= list1.get(j1++);
if (p1.getId() == id) {
while (j2 < list2.size()) {
final TracepointPosition p2= list1.get(j2++);
if (p2.getId() == id) {
if (p1.equals(p2)) {
continue ITER_REQUIRED;
}
return false;
}
}
return false;
}
}
return false;
}
return true;
}
public static final List<TracepointPosition> filterPositionsByIdRequired(final List<? extends TracepointPosition> list,
final List<? extends TracepointPosition> requiredIds) {
final int l= requiredIds.size();
if (list.size() == l) {
return ImCollections.toList(list);
}
final TracepointPosition[] array= new @NonNull TracepointPosition[l];
ITER_REQUIRED: for (int i= 0, j= 0; i < l; i++) {
final long id= requiredIds.get(i).getId();
while (j < list.size()) {
final TracepointPosition p= list.get(j++);
if (p.getId() == id) {
array[i]= p;
continue ITER_REQUIRED;
}
}
throw new IllegalArgumentException("TracepointPosition missing: id= " + id); //$NON-NLS-1$
}
return ImCollections.newList(array);
}
public static final List<TracepointPosition> filterPositionsById(final List<? extends TracepointPosition> list,
final List<? extends TracepointPosition> includedIds) {
final int l= includedIds.size();
final List<TracepointPosition> intersection= new ArrayList<>(l);
ITER_INCLUDED: for (int i= 0, j= 0; i < l; i++) {
final long id= includedIds.get(i).getId();
int j0= j;
while (j0 < list.size()) {
final TracepointPosition p= list.get(j0++);
if (p.getId() == id) {
intersection.add(p);
j= j0;
continue ITER_INCLUDED;
}
}
}
return intersection;
}
public static final List<TracepointPosition> filterPositionsById(final List<? extends TracepointPosition> list,
final long[] includedIds) {
final int l= includedIds.length;
final List<TracepointPosition> intersection= new ArrayList<>(l);
ITER_INCLUDED: for (int i= 0, j= 0; i < l; i++) {
final long id= includedIds[i];
int j0= j;
while (j0 < list.size()) {
final TracepointPosition p= list.get(j0++);
if (p.getId() == id) {
intersection.add(p);
j= j0;
continue ITER_INCLUDED;
}
}
}
return intersection;
}
public static final List<TracepointPosition> filterPositionsBySrcref(final List<? extends TracepointPosition> list,
final int[] baseSrcref, final int[] includedSrcref) {
final List<TracepointPosition> intersection= new ArrayList<>(list.size());
for (int j= 0; j < list.size(); j++) {
final TracepointPosition p= list.get(j);
final int [] @Nullable [] srcrefs= p.getSrcrefs();
for (int i= 0; i < srcrefs.length; i++) {
if (srcrefs[i] != null
&& Srcref.equalsStart(Srcref.add(srcrefs[i], baseSrcref), includedSrcref) ) {
intersection.add(p);
break;
}
}
}
return intersection;
}
public static final int @Nullable [] findIndexBySrcref(final List<? extends TracepointPosition> list,
final int[] baseSrcref, final int[] includedSrcref) {
for (int j= 0; j < list.size(); j++) {
final TracepointPosition p= list.get(j);
final int [] @Nullable [] srcrefs= p.getSrcrefs();
for (int depth= 0; depth < srcrefs.length; depth++) {
if (srcrefs[depth] != null
&& Srcref.equalsStart(Srcref.add(srcrefs[depth], baseSrcref), includedSrcref) ) {
return Arrays.copyOf(p.getIndex(), depth + 1);
}
}
}
return null;
}
public static final int @Nullable [] findIndexByReference(final List<? extends TracepointPosition> list,
final List<? extends TracepointPosition> reference) {
if (!list.isEmpty()) {
final TracepointPosition p= list.get(0);
final TracepointPosition refP= nonNullAssert(getPositionById(reference, p.getId()));
final int[] index= p.getIndex();
final int depth= index.length - 1 - refP.getIndex().length;
if (depth > 0 && depth < index.length) {
return Arrays.copyOf(index, depth + 1);
}
}
return null;
}
private static final boolean equalsIndex(final int[] index, final int[] included) {
if (index.length < included.length) {
return false;
}
for (int i= 0; i < included.length; i++) {
if (index[i] != included[i]) {
return false;
}
}
return true;
}
public static final int @Nullable [] getSrcrefForIndex(final List<? extends TracepointPosition> list,
final int[] includedIndex) {
final int depth= includedIndex.length - 1;
for (int j= 0; j < list.size(); j++) {
final TracepointPosition p= list.get(j);
final int[] srcref;
if (equalsIndex(p.getIndex(), includedIndex)
&& (srcref= p.getSrcref(depth)) != null ) {
return srcref;
}
}
return null;
}
public static final List<TracepointPosition> rebasePositionsByIndex(final List<? extends TracepointPosition> list,
final int[] newBaseIndex) {
final int depth= newBaseIndex.length - 1;
final List<TracepointPosition> intersection= new ArrayList<>(list.size());
for (int j= 0; j < list.size(); j++) {
final TracepointPosition p= list.get(j);
final int[] index= p.getIndex();
if (equalsIndex(index, newBaseIndex)
&& p.getSrcref() != null && p.getSrcref(depth) != null ) {
intersection.add(new TracepointPosition(p.getType(), p.getId(),
Arrays.copyOfRange(index, depth + 1, index.length),
Srcref.substract(p.getSrcref(), p.getSrcref(depth)) ));
}
}
return intersection;
}
private static final char[] DIGITS= new char[] {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
};
public static final String toString(long id) {
final char[] c= new char[16];
for (int i= 0; i < 16; i++) {
c[15 - i]= DIGITS[(int) id & 0xF];
id >>>= 4;
}
return new String(c, 0, 16);
}
public static final void append(long id, final StringBuilder sb) {
final char[] c= new char[16];
for (int i= 0; i < 16; i++) {
c[15 - i]= DIGITS[(int) id & 0xF];
id >>>= 4;
}
sb.append(c);
}
public static final String toLogString(final List<? extends TracepointPosition> positions) {
final int n= positions.size();
if (n <= 0) {
return ""; //$NON-NLS-1$
}
if (LOGGER.isLoggable(Level.FINEST)) {
return "\n\t\t" + CollectionUtils.toString(positions, "\n\t\t");
}
else {
final StringBuilder sb= new StringBuilder(n * 18);
sb.append(positions.get(0).getId());
for (int i= 1; i < n; i++) {
sb.append(", ");
append(positions.get(i).getId(), sb);
}
return sb.toString();
}
}
private Tracepoints() {}
}