001 /* 002 * Copyright (C) 2012 eXo Platform SAS. 003 * 004 * This is free software; you can redistribute it and/or modify it 005 * under the terms of the GNU Lesser General Public License as 006 * published by the Free Software Foundation; either version 2.1 of 007 * the License, or (at your option) any later version. 008 * 009 * This software is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * You should have received a copy of the GNU Lesser General Public 015 * License along with this software; if not, write to the Free 016 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 017 * 02110-1301 USA, or see the FSF site: http://www.fsf.org. 018 */ 019 020 package org.crsh.util; 021 022 import java.util.Iterator; 023 import java.util.NoSuchElementException; 024 025 public class CharSlicer { 026 027 /** . */ 028 private final String value; 029 030 /** . */ 031 private Pair<Integer, Integer> size; 032 033 public CharSlicer(String value) { 034 this.value = value; 035 this.size = size(); 036 } 037 038 public Pair<Integer, Integer> size() { 039 if (size == null) { 040 size = size(value, 0, 1); 041 } 042 return size; 043 } 044 045 private static Pair<Integer, Integer> size(String s, int index, int height) { 046 if (index < s.length()) { 047 int pos = s.indexOf('\n', index); 048 if (pos == -1) { 049 return Pair.of(s.length() - index, height); 050 } else { 051 Pair<Integer, Integer> ret = size(s, pos + 1, height + 1); 052 return new Pair<Integer, Integer>(Math.max(pos - index, ret.getFirst()), ret.getSecond()); 053 } 054 } else { 055 return Pair.of(0, height); 056 } 057 } 058 059 public Pair<Integer, Integer>[] lines(final int width) { 060 return lines(linesIterator(width), 0); 061 } 062 063 private Pair<Integer, Integer>[] lines(Iterator<Pair<Integer, Integer>> i, int count) { 064 Pair<Integer, Integer>[] lines; 065 if (i.hasNext()) { 066 Pair<Integer, Integer> n = i.next(); 067 lines = lines(i, count + 1); 068 lines[count] = n; 069 } else { 070 lines = new Pair[count]; 071 } 072 return lines; 073 } 074 075 public Iterator<Pair<Integer, Integer>> linesIterator(final int width) { 076 077 return new BaseIterator<Pair<Integer, Integer>>() { 078 079 /** . */ 080 int index = 0; 081 082 /** . */ 083 Pair<Integer, Integer> next = null; 084 085 public boolean hasNext() { 086 if (next == null) { 087 if (index != Integer.MAX_VALUE) { 088 int pos = value.indexOf('\n', index); 089 int nextIndex; 090 if (pos == -1) { 091 pos = Math.min(index + width, value.length()); 092 nextIndex = pos; 093 } else { 094 if (pos <= index + width) { 095 nextIndex = pos + 1; 096 } else { 097 nextIndex = pos = index + width; 098 } 099 } 100 next = Pair.of(index, pos); 101 if (pos < value.length()) { 102 index = nextIndex; 103 } else { 104 // Stop value 105 index = Integer.MAX_VALUE; 106 } 107 } 108 } 109 return next != null; 110 } 111 112 public Pair<Integer, Integer> next() { 113 if (!hasNext()) { 114 throw new NoSuchElementException(); 115 } 116 Pair<Integer, Integer> next = this.next; 117 this.next = null; 118 return next; 119 } 120 }; 121 } 122 }