001/*
002 * ModeShape (http://www.modeshape.org)
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 */
016package org.modeshape.common.text;
017
018import java.text.CharacterIterator;
019import java.text.StringCharacterIterator;
020import java.util.BitSet;
021
022public class QuoteEncoder implements TextDecoder, TextEncoder {
023
024    private static final BitSet ESCAPE_CHARACTERS = new BitSet(256);
025
026    public static final char ESCAPE_CHARACTER = '\\';
027
028    static {
029        ESCAPE_CHARACTERS.set('"');
030        ESCAPE_CHARACTERS.set('\\');
031        ESCAPE_CHARACTERS.set('\n');
032        ESCAPE_CHARACTERS.set('\t');
033    }
034
035    public QuoteEncoder() {
036    }
037
038    @Override
039    public String decode( String encodedText ) {
040        if (encodedText == null) return null;
041        if (encodedText.length() == 0) return "";
042        final StringBuilder result = new StringBuilder();
043        final CharacterIterator iter = new StringCharacterIterator(encodedText);
044        for (char c = iter.first(); c != CharacterIterator.DONE; c = iter.next()) {
045            if (c == ESCAPE_CHARACTER) {
046                // Eat this escape character, and process the next character ...
047                char nextChar = iter.next();
048                if (nextChar == 'n') {
049                    result.append('\n');
050                } else if (nextChar == 't') {
051                    result.append('\t');
052                } else if (nextChar == 'r') {
053                    result.append('\r');
054                } else if (nextChar == 'f') {
055                    result.append('\f');
056                } else {
057                    result.append(nextChar);
058                }
059            } else {
060                result.append(c);
061            }
062        }
063        return result.toString();
064    }
065
066    @Override
067    public String encode( String text ) {
068        final StringBuilder result = new StringBuilder();
069        final CharacterIterator iter = new StringCharacterIterator(text);
070        for (char c = iter.first(); c != CharacterIterator.DONE; c = iter.next()) {
071            if (ESCAPE_CHARACTERS.get(c)) {
072                result.append(ESCAPE_CHARACTER);
073                if (c == '\n') {
074                    result.append('n');
075                } else if (c == '\t') {
076                    result.append('t');
077                } else if (c == '\r') {
078                    result.append('r');
079                } else if (c == '\f') {
080                    result.append('f');
081                }
082            } else {
083                result.append(c);
084            }
085        }
086        return result.toString();
087    }
088
089}