
com.cloudhopper.commons.util.codec.URLDecoder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ch-commons-util Show documentation
Show all versions of ch-commons-util Show documentation
Common Java utility classes used across Cloudhopper-based projects
package com.cloudhopper.commons.util.codec;
/*
* #%L
* ch-commons-util
* %%
* Copyright (C) 2012 Cloudhopper by Twitter
* %%
* 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
*
* http://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.
* #L%
*/
import java.io.Closeable;
import java.io.Flushable;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CoderResult;
import java.nio.charset.CodingErrorAction;
/**
* http://ziesemer.dev.java.net/
*
* @author Mark A. Ziesemer
* <www.ziesemer.com>
*/
public class URLDecoder implements Appendable, Flushable, Closeable{
protected static final int DEFAULT_BUFFER_SIZE = 1 << 10;
protected final Appendable out;
protected final Charset charset;
protected final CharBuffer singleCharBuffer = CharBuffer.allocate(1);
protected final CharsetDecoder cd;
protected final ByteBuffer bb;
protected final CharBuffer cb;
/**
* Decodes to the specified {@link Appendable},
* using {@link #DEFAULT_BUFFER_SIZE}
* and {@link URLCodec#UTF_8}.
* Convenience method for {@link #URLDecoder(Appendable, int, Charset)}.
*/
public URLDecoder(Appendable out){
this(out, DEFAULT_BUFFER_SIZE, URLCodec.UTF_8);
}
/**
* Decodes to the specified {@link Appendable}
* with the specified bufferSize,
* using {@link URLCodec#UTF_8}.
* Convenience method for {@link #URLDecoder(Appendable, int, Charset)}.
*/
public URLDecoder(Appendable out, int bufferSize){
this(out, bufferSize, URLCodec.UTF_8);
}
/**
* Decodes to the specified {@link Appendable}
* with the specified bufferSize and charset.
*/
public URLDecoder(Appendable out, int bufferSize, Charset charset){
this.out = out;
this.charset = charset;
this.cd = charset.newDecoder()
.onMalformedInput(CodingErrorAction.REPLACE)
.onUnmappableCharacter(CodingErrorAction.REPLACE);
this.bb = ByteBuffer.allocate(bufferSize);
this.cb = CharBuffer.allocate((int)Math.ceil(bufferSize * cd.maxCharsPerByte()));
}
public Appendable append(CharSequence in) throws IOException{
// Ideally, this would share code with URLCodec#decodeUrl(CharSequence, OutputStream),
// but due to operational difference and no common interface between
// ByteBuffer and OutputStream, any attempts to share code result in
// severe performance penalties.
if(in == null) return this;
for(int i=0, len=in.length(); i