Files
gzz-mirror/Java/media/Span.java
2026-09-14 20:19:29 -04:00

179 lines
5.1 KiB
Java

/*
Span.java
*
* Copyright (c) 1999, Ted Nelson and Tuomas Lukka
*
* You may use and distribute under the terms of either the GNU Lesser
* General Public License, either version 2 of the license or,
* at your choice, any later version. Alternatively, you may use and
* distribute under the terms of the XPL.
*
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
* the licenses.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README
* file for more details.
*
*/
/*
* Written by Tuomas Lukka
*/
package org.gzigzag;
import java.util.*;
/** An address span in the stable media streams.
* Currently just a silly pointer but will be later extended
* to include full tumblers.
* <p>
* Spans are immutable, just like Strings: all the verb-like method
* like join and split return new Span objects.
*/
public class Span {
public static final String rcsid = "$Id: Span.java,v 1.9 2001/03/11 19:14:38 veparkki Exp $";
public static final boolean dbg = false;
static final void p(String s) { if(dbg) System.out.println(s); }
Address a1;
Address a2;
public Address getStart() { return a1; }
public Address getEnd() { return a2; }
public long getStartOffs() { return a1.offset; }
public long getEndOffs() { return a2.offset; }
public static Span parse(String str) {
StringTokenizer st = new StringTokenizer(str, ":");
if(st.countTokens() != 2)
throw new ZZError("Wrong number of ':' toks in '"+str+"'");
Span s = new Span();
s.a1 = Address.parse(st.nextToken());
s.a2 = Address.parse(st.nextToken());
if(!s.a1.getStream().equals(s.a2.getStream()))
throw new ZZError("Must be same stream for now '" + str
+"' '"+s.a1.getStream()+"' '"+s.a2.getStream()+"'");
return s;
}
public static Span create(Address i1, Address i2) {
Span s = new Span();
s.a1 = i1; s.a2 = i2;
return s;
}
public String toString() {
return a1+":"+a2;
}
public boolean overlaps(Span s) {
if(a2.lessThan(s.a1) || s.a2.lessThan(a1)) return false;
return true;
}
/** The string pointed to by the span.
*/
public String getString(ZZCell c) {
Scroll scr //= c.getSpace().getStringScroll(a1.getStream());
= Scroll.obtain((c==null?null:c.getSpace()),
a1.getStream());
p("Scroll: "+scr);
if(scr instanceof StringScroll) {
StringScroll s = (StringScroll) scr;
int o1 = (int)a1.getOffs();
int o2 = (int)a2.getOffs();
if(o1 > o2) {
// This is allowed
if(o1-o2 == 1) return "";
// This is not
throw new ZZError("Too negative span "+ this);
}
return s.getString(a1.getOffs(),
(int)(o2-o1)+1);
} if(scr instanceof ByteScroll) {
ByteScroll s = (ByteScroll)scr;
return s.getString(a1.getOffs(),
(int)(a2.getOffs()-a1.getOffs())+1);
}
if(scr instanceof CharScroll) {
CharScroll s = (CharScroll)scr;
return s.getString(a1.getOffs(),
(int)(a2.getOffs()-a1.getOffs())+1);
}
if(scr instanceof SoundScroll) {
return "SND " + toString();
}
return "???";
}
public Span adjustEdge(int edge, long units) {
Address adj = (edge==0?a1:a2);
adj = Address.streamOffs(adj.getStream(), adj.getOffs()+units);
Address x = (edge==0?adj:a1);
Address y = (edge==1?adj:a2);
return create(x,y);
}
public Span[] adjustEdgeLocked(long units, Span other, long allowfudge) {
Address adj = a2;
adj = Address.streamOffs(adj.getStream(), adj.getOffs()+units);
long d = adj.getOffs() - other.a1.getOffs();
if(d<0) d = -d;
if(d>allowfudge)
return new Span[] {
create(a1, adj), other
};
return new Span[] {
create(a1, adj),
create(Address.streamOffs(adj.getStream(), adj.getOffs()+1),
other.a2)
};
}
public Span[] splitInHalf() {
long off = (a1.getOffs() + a2.getOffs()) / 2;
return new Span[] {
create(a1, Address.streamOffs(a1.getStream(), off-1)),
create(Address.streamOffs(a1.getStream(), off), a2),
};
}
public Span join(Span next, long allowfudge) {
if(! a2.getStream().equals(next.a1.getStream()))
return null;
long diff = a2.getOffs() - next.a1.getOffs();
if(diff<0) diff = -diff;
if(diff > allowfudge)
return null;
return create(a1, next.a2);
}
/** Does exactly what substring does to String.
* This is in opposition to the other span routines
* in which the last address is given, not one beyond!
*/
public Span subSpan(int o1, int o2) {
return create(a1.addOffs(o1), a1.addOffs(o2-1));
}
public Span subSpan(int o1) {
return create(a1.addOffs(o1), a2);
}
/** Whether this span can be joined with the other span.
*/
public boolean isAppendable(Span s) {
return a2.getStream().equals(s.a1.getStream())
&& a2.getOffs() == s.a1.getOffs()-1;
}
// XXX Check?
public Span append(Span s) {
return create(a1, s.a2);
}
public long length() {
return a2.getOffs() - a1.getOffs() + 1;
}
}