Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.grails.encoder.AbstractCharReplacementEncoder Maven / Gradle / Ivy
/*
* Copyright 2013-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.grails.encoder;
import java.io.IOException;
import java.io.Writer;
import java.util.List;
import org.grails.charsequences.CharSequences;
/**
* Abstract base class for implementing encoders that do character replacements
* Implements the {@link StreamingEncoder} interface that enables efficient
* streaming encoding
*
* @author Lari Hotari
* @since 2.3
*/
public abstract class AbstractCharReplacementEncoder implements Encoder, StreamingEncoder, EncodesToWriter {
protected final CodecIdentifier codecIdentifier;
public AbstractCharReplacementEncoder(CodecIdentifier codecIdentifier) {
this.codecIdentifier = codecIdentifier;
}
/**
* Escape the character, return null if no replacement has to be made
*
* @param ch the character to escape
* @param previousChar the previous char
* @return the replacement string, null if no replacement has to be made
*/
protected abstract String escapeCharacter(char ch, char previousChar);
/* (non-Javadoc)
* @see Encoder#encode(java.lang.Object)
*/
public Object encode(Object o) {
return doCharReplacementEncoding(o);
}
protected final Object doCharReplacementEncoding(Object o) {
if (o == null) {
return null;
}
CharSequence str;
if (o instanceof CharSequence) {
str = (CharSequence) o;
}
else if (o instanceof Character) {
String escaped = escapeCharacter((Character) o, (char) 0);
if (escaped != null) {
return escaped;
}
else {
return o;
}
}
else {
str = convertToString(o);
}
return escapeCharSequence(str);
}
protected String convertToString(Object o) {
return String.valueOf(o);
}
protected Object escapeCharSequence(CharSequence str) {
if (str == null || str.length() == 0) {
return str;
}
StringBuilder sb = null;
int n = str.length();
int i = 0;
int startPos = -1;
char prevChar = (char) 0;
for (; i < n; i++) {
char ch = str.charAt(i);
if (startPos == -1) {
startPos = i;
}
String escaped = escapeCharacter(ch, prevChar);
if (escaped != null) {
if (sb == null) {
sb = new StringBuilder(str.length() * 110 / 100);
}
if (i - startPos > 0) {
sb.append(str, startPos, i);
}
if (escaped.length() > 0) {
sb.append(escaped);
}
startPos = -1;
}
prevChar = ch;
}
if (sb != null) {
if (startPos > -1) {
sb.append(str, startPos, i);
}
return sb.toString();
}
else {
return str;
}
}
@Override
public void encodeToWriter(CharSequence str, int off, int len, Writer writer, EncodingState encodingState) throws IOException {
if (str == null || len <= 0) {
return;
}
int n = Math.min(str.length(), off + len);
int i;
int startPos = -1;
char prevChar = (char) 0;
for (i = off; i < n; i++) {
char ch = str.charAt(i);
if (startPos == -1) {
startPos = i;
}
String escaped = escapeCharacter(ch, prevChar);
if (escaped != null) {
if (i - startPos > 0) {
CharSequences.writeCharSequence(writer, str, startPos, i);
}
if (escaped.length() > 0) {
writer.write(escaped);
}
startPos = -1;
}
prevChar = ch;
}
if (startPos > -1) {
CharSequences.writeCharSequence(writer, str, startPos, i);
}
}
@Override
public void encodeToWriter(char[] buf, int off, int len, Writer writer, EncodingState encodingState) throws IOException {
if (buf == null || len <= 0) {
return;
}
int n = Math.min(buf.length, off + len);
int i;
int startPos = -1;
char prevChar = (char) 0;
for (i = off; i < n; i++) {
char ch = buf[i];
if (startPos == -1) {
startPos = i;
}
String escaped = escapeCharacter(ch, prevChar);
if (escaped != null) {
if (i - startPos > 0) {
writer.write(buf, startPos, i - startPos);
}
if (escaped.length() > 0) {
writer.write(escaped);
}
startPos = -1;
}
prevChar = ch;
}
if (startPos > -1) {
writer.write(buf, startPos, i - startPos);
}
}
@Override
public EncodesToWriter createChainingEncodesToWriter(List encoders, boolean applyAdditionalFirst) {
return EncodesToWriterAdapter.createChainingEncodesToWriter(this, encoders, applyAdditionalFirst);
}
/* (non-Javadoc)
* @see StreamingEncoder#encodeToStream(Encoder, java.lang.CharSequence, int, int, EncodedAppender, EncodingState)
*/
public void encodeToStream(Encoder thisInstance, CharSequence str, int off, int len, EncodedAppender appender, EncodingState encodingState)
throws IOException {
if (str == null || len <= 0) {
return;
}
int n = Math.min(str.length(), off + len);
int i;
int startPos = -1;
char prevChar = (char) 0;
for (i = off; i < n; i++) {
char ch = str.charAt(i);
if (startPos == -1) {
startPos = i;
}
String escaped = escapeCharacter(ch, prevChar);
if (escaped != null) {
if (i - startPos > 0) {
appender.appendEncoded(thisInstance, encodingState, str, startPos, i - startPos);
}
if (escaped.length() > 0) {
appender.appendEncoded(thisInstance, encodingState, escaped, 0, escaped.length());
}
startPos = -1;
}
prevChar = ch;
}
if (startPos > -1) {
appender.appendEncoded(thisInstance, encodingState, str, startPos, i - startPos);
}
}
/* (non-Javadoc)
* @see Encoder#markEncoded(java.lang.CharSequence)
*/
public void markEncoded(CharSequence string) {
// no need to implement, wrapped automaticly
}
/* (non-Javadoc)
* @see Encoder#isSafe()
*/
public boolean isSafe() {
return true;
}
/* (non-Javadoc)
* @see Encoder#isApplyToSafelyEncoded()
*/
public boolean isApplyToSafelyEncoded() {
return false;
}
/* (non-Javadoc)
* @see CodecIdentifierProvider#getCodecIdentifier()
*/
public CodecIdentifier getCodecIdentifier() {
return this.codecIdentifier;
}
}