/******************************************************************************* * Copyright (c) 2005-2011, G. Weirich and Elexis * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * G. Weirich - initial implementation * *******************************************************************************/ package ch.rgw.tools; public class GenericRange { int pos; int len; public GenericRange(GenericRange other){ pos = other.pos; len = other.len; } public GenericRange(){ pos = 0; len = 0; } public GenericRange(int pos){ this.pos = pos; len = 0; } public GenericRange(int start, int len){ pos = start; this.len = len; } public int getLength(){ return len; } public int getPos(){ return pos; } public int getEnd(){ return pos + len - 1; } public void setPos(int p){ int end = getEnd(); pos = p; setEnd(end); } public void setLen(int l){ len = l; } public void setEnd(int e){ len = e - pos; } public static final int IS_BEFORE_OTHER = 1; public static final int IS_AFTER_OTHER = 2; public static final int IS_INSIDE_OTHER = 3; public static final int IS_AT_BEGIN_OF_OTHER = 4; public static final int IS_AT_END_OF_OTHER = 5; public static final int IS_OVER_OTHER = 6; public static final int IS_ZERO_LENGTH = 7; /** * Feststellen, wie dise Range in Bezug auf eine andere liegt * * @return <ul> * <li>IS_BEFORE-OTHER: Liegt ganz vor der anderen</li> * <li>IS_AFTER_OTHER: Liegt ganz nach der anderen</li> * <li>IS_INSIDE_OTHER: Liegt ganz innerhalb der anderen</li> * <li>IS_AT_BEGIN_OF_OTHER: überlappt den Anfang der anderen</li> * <li>IS_AT_END_OF_OTHER: überlappt das Ende der anderen</li> * <li>IS_OVER_OTHER: überlagert die andere ganz</li> * <li>IS_ZERO_LENGTH: Länge null sekunden</li> * </ul> */ public int positionTo(GenericRange other){ if (len == 0 || (other.len == 0)) { return IS_ZERO_LENGTH; } if (pos <= other.pos) { if (getEnd() <= other.pos) { return IS_BEFORE_OTHER; } else if (getEnd() >= other.getEnd()) { return IS_OVER_OTHER; } else { return IS_AT_BEGIN_OF_OTHER; } } else // offset > other.offset) { if (getEnd() <= other.getEnd()) { return IS_INSIDE_OTHER; } else if (pos >= other.getEnd()) { return IS_AFTER_OTHER; } else { return IS_AT_END_OF_OTHER; } } } /** * Schnitt-Range aus zwei Ranges erzeugen * * @param other * die andere Range * @return eine neue Range, die die Überlappung enthält oder null, wenn keine überlappung * vorliegt */ public GenericRange overlap(GenericRange other){ GenericRange ret = null; switch (positionTo(other)) { case IS_BEFORE_OTHER: case IS_AFTER_OTHER: case IS_ZERO_LENGTH: return null; case IS_AT_BEGIN_OF_OTHER: ret = new GenericRange(pos); ret.setEnd(other.getEnd()); return ret; case IS_OVER_OTHER: return other; case IS_INSIDE_OTHER: return other; case IS_AT_END_OF_OTHER: ret = new GenericRange(other.getEnd()); ret.setEnd(getEnd()); return ret; } return ret; } }