001    /*
002     * Copyright (C) 2009 the original author(s).
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    package org.fusesource.jansi;
018    
019    import org.fusesource.jansi.AnsiOutputStream;
020    
021    import java.io.ByteArrayOutputStream;
022    import java.io.IOException;
023    
024    /**
025     * An ANSI string which reports the size of rendered text correctly (ignoring any ANSI escapes).
026     *
027     * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
028     * @since 1.1
029     */
030    public class AnsiString
031        implements CharSequence
032    {
033        private final CharSequence encoded;
034    
035        private final CharSequence plain;
036    
037        public AnsiString(final CharSequence str) {
038            assert str != null;
039            this.encoded = str;
040            this.plain = chew(str);
041        }
042    
043        private CharSequence chew(final CharSequence str) {
044            assert str != null;
045    
046            ByteArrayOutputStream buff = new ByteArrayOutputStream();
047            AnsiOutputStream out = new AnsiOutputStream(buff);
048    
049            try {
050                out.write(str.toString().getBytes());
051                out.flush();
052                out.close();
053            }
054            catch (IOException e) {
055                throw new RuntimeException(e);
056            }
057    
058            return new String(buff.toByteArray());
059        }
060    
061        public CharSequence getEncoded() {
062            return encoded;
063        }
064    
065        public CharSequence getPlain() {
066            return plain;
067        }
068    
069        // FIXME: charAt() and subSequence() will make things barf, need to call toString() first to get expected results
070    
071        public char charAt(final int index) {
072            return getEncoded().charAt(index);
073        }
074    
075        public CharSequence subSequence(final int start, final int end) {
076            return getEncoded().subSequence(start, end);
077        }
078    
079        public int length() {
080            return getPlain().length();
081        }
082    
083        @Override
084        public boolean equals(final Object obj) {
085            return getEncoded().equals(obj);
086        }
087    
088        @Override
089        public int hashCode() {
090            return getEncoded().hashCode();
091        }
092    
093        @Override
094        public String toString() {
095            return getEncoded().toString();
096        }
097    }