/*******************************************************************************
* Copyright (c) 2006-2010 eBay Inc. All Rights Reserved.
* 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
*******************************************************************************/
package org.ebayopensource.turmeric.runtime.binding.utils;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
/**
* URLDecoderInputStreamReader URL decodes the input stream except for the character '&' and '%'.
*
* @author wdeng
*
*/
public class URLDecoderInputStream extends InputStream implements Closeable{
private final static int NO_CHAR = -1;
private InputStream m_is;
private int[] m_unreadChar = {NO_CHAR, NO_CHAR};
/**
* Constructor with InputStream as argument.
*
* @param is an InputStream.
*/
public URLDecoderInputStream(InputStream is) {
m_is = is;
}
@Override
public int read() throws IOException {
int c = readFromUnreadBuffer();
if (c == NO_CHAR) {
c = m_is.read();
}
if (c == NO_CHAR) {
return c;
}
// assume that any '+' is really a space
if (c == '+') {
return ' ';
}
// do HTTP URL decoding
if (c == '%') {
int c1 = m_is.read();
if (c1 == NO_CHAR) {
return c;
}
int b1 = BindingUtils.getHexDigitValue(c1);
if (b1 == NO_CHAR) {
unread(c1);
return c;
}
int c2 = m_is.read();
if (c2 == NO_CHAR) {
unread(c1);
return c;
}
int b2 = BindingUtils.getHexDigitValue(c2);
if (b2 == -1) {
unread(c1);
unread(c2);
return c;
}
char ch = (char) ((b1<<4)|b2);
if (ch == '&' || ch == '%') {
unread(c1);
unread(c2);
return c;
}
return ch;
}
return c;
}
private int readFromUnreadBuffer() {
int c = m_unreadChar[0];
m_unreadChar[0] = m_unreadChar[1];
m_unreadChar[1] = NO_CHAR;
return c;
}
private void unread(int ch) {
if (m_unreadChar[0] == NO_CHAR) {
m_unreadChar[0] = ch;
return;
}
m_unreadChar[1] = ch;
}
}