+ /**
+ * find series of intervals mapping from start-end in the to map.
+ * @param start position in from map
+ * @param end position in from map
+ * @return series of ranges in to map
+ */
+ public int[] locateInTo(int start, int end) {
+ // inefficient implementation
+ int toStart[] = shiftFrom(start);
+ int toEnd[] = shiftFrom(end);
+ if (toStart==null || toEnd==null)
+ return null;
+ int iv[] = getIntervals(toShifts, toStart, toEnd, toRatio);
+ return iv;
+ }
+ /**
+ * like shift - except returns the intervals in the given vector of shifts which were spanned
+ * in traversing fromStart to fromEnd
+ * @param fromShifts2
+ * @param fromStart
+ * @param fromEnd
+ * @param fromRatio2
+ * @return
+ */
+ private int[] getIntervals(Vector fromShifts2, int[] fromStart, int[] fromEnd, int fromRatio2)
+ {
+ // correct for word direction for start and end
+ int startpos = fromStart[0]+fromStart[2]*(fromRatio2-1);
+ int endpos = fromEnd[0]+fromEnd[2]*(fromRatio2-1);
+ int intv=0,intvSize= fromShifts2.size();
+ int iv[],i=0,fs=-1,fe=-1; // containing intervals
+ while (intv<intvSize && (fs==-1 || fe==-1)) {
+ iv = (int[]) fromShifts2.elementAt(intv++);
+ if (iv[0]<=iv[1]) {
+ if (fs==-1 && startpos>=iv[0] && startpos<=iv[1]) {
+ fs = i;
+ }
+ if (fe==-1 && endpos>=iv[0] && endpos<=iv[1]) {
+ fe = i;
+ }
+ } else {
+ if (fs==-1 && startpos<=iv[0] && startpos>=iv[1]) {
+ fs = i;
+ }
+ if (fe==-1 && endpos<=iv[0] && endpos>=iv[1]) {
+ fe = i;
+ }
+ }
+ i++;
+ }
+ if (fs==fe && fe==-1)
+ return null;
+ Vector ranges=new Vector();
+ if (fs<=fe) {
+ intv = fs;
+ i=fs;
+ // truncate initial interval
+ iv = (int[]) fromShifts2.elementAt(intv++);
+ iv = new int[] { iv[0], iv[1]};// clone
+ if (i==fs)
+ iv[0] = startpos;
+ while (i!=fe) {
+ ranges.addElement(iv); // add initial range
+ iv = (int[]) fromShifts2.elementAt(intv++); // get next interval
+ iv = new int[] { iv[0], iv[1]};// clone
+ i++;
+ }
+ if (i==fe)
+ iv[1] = endpos;
+ ranges.addElement(iv); // add only - or final range
+ } else {
+ // walk from end of interval.
+ i=fromShifts2.size()-1;
+ while (i>fs) {
+ i--;
+ }
+ iv = (int[]) fromShifts2.elementAt(i);
+ iv = new int[] { iv[1], iv[0]};// reverse and clone
+ // truncate initial interval
+ if (i==fs)
+ {
+ iv[0] = startpos;
+ }
+ while (i!=fe) {
+ ranges.addElement(iv); // add (truncated) reversed interval
+ iv = (int[]) fromShifts2.elementAt(--i);
+ iv = new int[] { iv[1], iv[0] }; // reverse and clone
+ }
+ if (i==fe) {
+ // interval is already reversed
+ iv[1] = endpos;
+ }
+ ranges.addElement(iv); // add only - or final range
+ }
+ // create array of start end intervals.
+ int[] range = null;
+ if (ranges!=null && ranges.size()>0)
+ {
+ range = new int[ranges.size()*2];
+ intv = 0;
+ intvSize=ranges.size();
+ i=0;
+ while (intv<intvSize)
+ {
+ iv = (int[]) ranges.elementAt(intv);
+ range[i++] = iv[0];
+ range[i++] = iv[1];
+ ranges.setElementAt(null, intv++); // remove
+ }
+ }
+ return range;
+ }
+ /**
+ * test routine. not incremental.
+ * @param ml
+ * @param fromS
+ * @param fromE
+ */