You are viewing a plain text version of this content. The canonical link for it is here.
Posted to xmlrpc-dev@ws.apache.org by jo...@apache.org on 2005/05/13 02:18:22 UTC

cvs commit: ws-xmlrpc/src/java/org/apache/xmlrpc/util Base64.java

jochen      2005/05/12 17:18:22

  Modified:    src/java/org/apache/xmlrpc/parser Tag: b20050512_streaming
                        AtomicParser.java NullParser.java
                        RecursiveTypeParserImpl.java MapParser.java
                        XmlRpcResponseParser.java
               src/java/org/apache/xmlrpc/client Tag: b20050512_streaming
                        XmlRpcStreamTransport.java
               src/java/org/apache/xmlrpc/serializer Tag:
                        b20050512_streaming XmlRpcWriter.java
                        BaseXmlWriterFactory.java
               .        Tag: b20050512_streaming .cvsignore
               src/test/org/apache/xmlrpc/test Tag: b20050512_streaming
                        BaseTestCase.java
               src/java/org/apache/xmlrpc/server Tag: b20050512_streaming
                        XmlRpcStreamServer.java
               src/java/org/apache/xmlrpc/common Tag: b20050512_streaming
                        TypeFactoryImpl.java
               src/java/org/apache/xmlrpc/util Tag: b20050512_streaming
                        Base64.java
  Added:       src/java/org/apache/xmlrpc/parser Tag: b20050512_streaming
                        ByteArrayParser.java
               src/test/org/apache/xmlrpc/test Tag: b20050512_streaming
                        SerializerTest.java
  Log:
  Unit tests for serialization and parsing are working.
  
  Revision  Changes    Path
  No                   revision
  No                   revision
  1.1.2.2   +1 -1      ws-xmlrpc/src/java/org/apache/xmlrpc/parser/Attic/AtomicParser.java
  
  Index: AtomicParser.java
  ===================================================================
  RCS file: /home/cvs/ws-xmlrpc/src/java/org/apache/xmlrpc/parser/Attic/AtomicParser.java,v
  retrieving revision 1.1.2.1
  retrieving revision 1.1.2.2
  diff -u -r1.1.2.1 -r1.1.2.2
  --- AtomicParser.java	12 May 2005 01:58:50 -0000	1.1.2.1
  +++ AtomicParser.java	13 May 2005 00:18:21 -0000	1.1.2.2
  @@ -27,7 +27,7 @@
    */
   public abstract class AtomicParser extends TypeParserImpl {
   	private int level;
  -	private StringBuffer sb;
  +	protected StringBuffer sb;
   
   	/** Creates a new instance.
   	 */
  
  
  
  1.1.2.2   +8 -14     ws-xmlrpc/src/java/org/apache/xmlrpc/parser/Attic/NullParser.java
  
  Index: NullParser.java
  ===================================================================
  RCS file: /home/cvs/ws-xmlrpc/src/java/org/apache/xmlrpc/parser/Attic/NullParser.java,v
  retrieving revision 1.1.2.1
  retrieving revision 1.1.2.2
  diff -u -r1.1.2.1 -r1.1.2.2
  --- NullParser.java	12 May 2005 01:58:50 -0000	1.1.2.1
  +++ NullParser.java	13 May 2005 00:18:21 -0000	1.1.2.2
  @@ -15,25 +15,19 @@
    */
   package org.apache.xmlrpc.parser;
   
  -import javax.xml.namespace.QName;
  -
  -import org.xml.sax.Attributes;
   import org.xml.sax.SAXException;
   import org.xml.sax.SAXParseException;
   
   
   /** SAX parser for a nil element (null value).
    */
  -public class NullParser extends TypeParserImpl {
  -	public void endElement(String pURI, String pLocalName, String pQName) throws SAXException {
  -		throw new SAXParseException("Unexpected end tag within nil: "
  -									+ new QName(pURI, pLocalName),
  -									getDocumentLocator());
  -	}
  -
  -	public void startElement(String pURI, String pLocalName, String pQName, Attributes pAttrs) throws SAXException {
  -		throw new SAXParseException("Unexpected start tag within nil: "
  -									+ new QName(pURI, pLocalName),
  -									getDocumentLocator());
  +public class NullParser extends AtomicParser {
  +	protected void setResult(String pResult) throws SAXException {
  +		if (pResult == null  ||  "".equals(pResult.trim())) {
  +			super.setResult((Object) null);
  +		} else {
  +			throw new SAXParseException("Unexpected characters in nil element.",
  +										getDocumentLocator());
  +		}
   	}
   }
  
  
  
  1.1.2.2   +16 -2     ws-xmlrpc/src/java/org/apache/xmlrpc/parser/Attic/RecursiveTypeParserImpl.java
  
  Index: RecursiveTypeParserImpl.java
  ===================================================================
  RCS file: /home/cvs/ws-xmlrpc/src/java/org/apache/xmlrpc/parser/Attic/RecursiveTypeParserImpl.java,v
  retrieving revision 1.1.2.1
  retrieving revision 1.1.2.2
  diff -u -r1.1.2.1 -r1.1.2.2
  --- RecursiveTypeParserImpl.java	12 May 2005 01:58:50 -0000	1.1.2.1
  +++ RecursiveTypeParserImpl.java	13 May 2005 00:18:21 -0000	1.1.2.2
  @@ -15,9 +15,14 @@
    */
   package org.apache.xmlrpc.parser;
   
  +import javax.xml.namespace.QName;
  +
   import org.apache.ws.commons.util.NamespaceContextImpl;
  +import org.apache.xmlrpc.XmlRpcException;
   import org.apache.xmlrpc.common.TypeFactory;
  +import org.apache.xmlrpc.common.XmlRpcExtensionException;
   import org.apache.xmlrpc.common.XmlRpcStreamConfig;
  +import org.apache.xmlrpc.serializer.XmlRpcWriter;
   import org.xml.sax.Attributes;
   import org.xml.sax.SAXException;
   import org.xml.sax.SAXParseException;
  @@ -62,8 +67,8 @@
   				text = null;
   			} else {
   				typeParser.endDocument();
  -				typeParser = null;
   				addResult(typeParser.getResult());
  +				typeParser = null;
   			}
   		} else {
   			throw new SAXParseException("Invalid state: Not inside value tag.",
  @@ -97,7 +102,16 @@
   		if (inValueTag) {
   			if (typeParser == null) {
   				typeParser = factory.getParser(cfg, context, pURI, pLocalName);
  -				typeParser.endElement(pURI, pLocalName, pQName);
  +				if (typeParser == null) {
  +					if (XmlRpcWriter.EXTENSIONS_URI.equals(pURI)  &&  !cfg.isEnabledForExtensions()) {
  +						String msg = "The tag " + new QName(pURI, pLocalName) + " is invalid, if isEnabledForExtensions() == false.";
  +						throw new SAXParseException(msg, getDocumentLocator(),
  +													new XmlRpcExtensionException(msg));
  +					} else {
  +						throw new SAXParseException("Unknown type: " + new QName(pURI, pLocalName),
  +													getDocumentLocator());
  +					}
  +				}
   				typeParser.setDocumentLocator(getDocumentLocator());
   				typeParser.startDocument();
   				if (text != null) {
  
  
  
  1.1.2.2   +5 -2      ws-xmlrpc/src/java/org/apache/xmlrpc/parser/Attic/MapParser.java
  
  Index: MapParser.java
  ===================================================================
  RCS file: /home/cvs/ws-xmlrpc/src/java/org/apache/xmlrpc/parser/Attic/MapParser.java,v
  retrieving revision 1.1.2.1
  retrieving revision 1.1.2.2
  diff -u -r1.1.2.1 -r1.1.2.2
  --- MapParser.java	12 May 2005 01:58:50 -0000	1.1.2.1
  +++ MapParser.java	13 May 2005 00:18:21 -0000	1.1.2.2
  @@ -104,6 +104,8 @@
   												+ new QName(pURI, pLocalName),
   												getDocumentLocator());
   				}
  +				doneValue = inName = inValue = false;
  +				name = null;
   				break;
   			case 2:
   				if (doneValue) {
  @@ -143,10 +145,11 @@
   				setResult(map);
   				break;
   			case 1:
  -				inValue = inName = false;
   				break;
   			case 2:
  -				if (inValue) {
  +				if (inName) {
  +					inName = false;
  +				} else if (inValue) {
   					endValueTag();
   					doneValue = true;
   				}
  
  
  
  1.1.2.2   +23 -51    ws-xmlrpc/src/java/org/apache/xmlrpc/parser/Attic/XmlRpcResponseParser.java
  
  Index: XmlRpcResponseParser.java
  ===================================================================
  RCS file: /home/cvs/ws-xmlrpc/src/java/org/apache/xmlrpc/parser/Attic/XmlRpcResponseParser.java,v
  retrieving revision 1.1.2.1
  retrieving revision 1.1.2.2
  diff -u -r1.1.2.1 -r1.1.2.2
  --- XmlRpcResponseParser.java	12 May 2005 01:58:51 -0000	1.1.2.1
  +++ XmlRpcResponseParser.java	13 May 2005 00:18:21 -0000	1.1.2.2
  @@ -83,9 +83,9 @@
   				break;
   			case 1:
   				if ("".equals(pURI)  &&  "params".equals(pLocalName)) {
  -					isSuccess = false;
  -				} else if ("".equals(pURI)  &&  "fault".equals(pLocalName)) {
   					isSuccess = true;
  +				} else if ("".equals(pURI)  &&  "fault".equals(pLocalName)) {
  +					isSuccess = false;
   				} else {
   					throw new SAXParseException("Expected params or fault element, got "
   												+ new QName(pURI, pLocalName),
  @@ -93,33 +93,19 @@
   				}
   				break;
   			case 2:
  -				if (isSuccess) {
  -					if ("".equals(pURI)  &&  "value".equals(pLocalName)) {
  -						startValueTag();
  -					} else {
  -						throw new SAXParseException("Expected value element, got "
  -													+ new QName(pURI, pLocalName),
  -													getDocumentLocator());
  -					}
  -				} else {
  -					if (!"".equals(pURI)  ||  !"param".equals(pLocalName)) {
  -						throw new SAXParseException("Expected param element, got "
  -													+ new QName(pURI, pLocalName),
  -													getDocumentLocator());
  -					}
  +				if (!"".equals(pURI)  ||  !"param".equals(pLocalName)) {
  +					throw new SAXParseException("Expected param element, got "
  +							+ new QName(pURI, pLocalName),
  +							getDocumentLocator());
   				}
   				break;
   			case 3:
  -				if (isSuccess) {
  -					super.startElement(pURI, pLocalName, pQName, pAttrs);
  +				if ("".equals(pURI)  &&  "value".equals(pLocalName)) {
  +					startValueTag();
   				} else {
  -					if ("".equals(pURI)  &&  "value".equals(pLocalName)) {
  -						startValueTag();
  -					} else {
  -						throw new SAXParseException("Expected value element, got "
  -								+ new QName(pURI, pLocalName),
  -								getDocumentLocator());
  -					}
  +					throw new SAXParseException("Expected value element, got "
  +							+ new QName(pURI, pLocalName),
  +							getDocumentLocator());
   				}
   				break;
   			default:
  @@ -141,9 +127,9 @@
   				{
   					String tag;
   					if (isSuccess) {
  -						tag = "fault";
  -					} else {
   						tag = "params";
  +					} else {
  +						tag = "fault";
   					}
   					if (!"".equals(pURI)  ||  !tag.equals(pLocalName)) {
   						throw new SAXParseException("Expected /" + tag + " element, got "
  @@ -153,33 +139,19 @@
   					break;
   				}
   			case 2:
  -				{
  -					String tag;
  -					if (isSuccess) {
  -						tag = "value";
  -					} else {
  -						tag = "param";
  -					}
  -					if (!"".equals(pURI)  ||  !tag.equals(pLocalName)) {
  -						throw new SAXParseException("Expected /" + tag + ", got "
  -								+ new QName(pURI, pLocalName),
  -								getDocumentLocator());
  -					} else if (isSuccess) {
  -						endValueTag();
  -					}
  -					break;
  +				if (!"".equals(pURI)  ||  !"param".equals(pLocalName)) {
  +					throw new SAXParseException("Expected /param, got "
  +												+ new QName(pURI, pLocalName),
  +												getDocumentLocator());
   				}
  +				break;
   			case 3:
  -				if (isSuccess) {
  -					super.endElement(pURI, pLocalName, pQName);
  +				if ("".equals(pURI)  &&  "value".equals(pLocalName)) {
  +					endValueTag();
   				} else {
  -					if ("".equals(pURI)  &&  "value".equals(pLocalName)) {
  -						endValueTag();
  -					} else {
  -						throw new SAXParseException("Expected /value, got "
  -													+ new QName(pURI, pLocalName),
  -													getDocumentLocator());
  -					}
  +					throw new SAXParseException("Expected /value, got "
  +							+ new QName(pURI, pLocalName),
  +							getDocumentLocator());
   				}
   				break;
   			default:
  
  
  
  No                   revision
  
  Index: XmlRpcResponseParser.java
  ===================================================================
  RCS file: /home/cvs/ws-xmlrpc/src/java/org/apache/xmlrpc/parser/Attic/XmlRpcResponseParser.java,v
  retrieving revision 1.1.2.1
  retrieving revision 1.1.2.2
  diff -u -r1.1.2.1 -r1.1.2.2
  --- XmlRpcResponseParser.java	12 May 2005 01:58:51 -0000	1.1.2.1
  +++ XmlRpcResponseParser.java	13 May 2005 00:18:21 -0000	1.1.2.2
  @@ -83,9 +83,9 @@
   				break;
   			case 1:
   				if ("".equals(pURI)  &&  "params".equals(pLocalName)) {
  -					isSuccess = false;
  -				} else if ("".equals(pURI)  &&  "fault".equals(pLocalName)) {
   					isSuccess = true;
  +				} else if ("".equals(pURI)  &&  "fault".equals(pLocalName)) {
  +					isSuccess = false;
   				} else {
   					throw new SAXParseException("Expected params or fault element, got "
   												+ new QName(pURI, pLocalName),
  @@ -93,33 +93,19 @@
   				}
   				break;
   			case 2:
  -				if (isSuccess) {
  -					if ("".equals(pURI)  &&  "value".equals(pLocalName)) {
  -						startValueTag();
  -					} else {
  -						throw new SAXParseException("Expected value element, got "
  -													+ new QName(pURI, pLocalName),
  -													getDocumentLocator());
  -					}
  -				} else {
  -					if (!"".equals(pURI)  ||  !"param".equals(pLocalName)) {
  -						throw new SAXParseException("Expected param element, got "
  -													+ new QName(pURI, pLocalName),
  -													getDocumentLocator());
  -					}
  +				if (!"".equals(pURI)  ||  !"param".equals(pLocalName)) {
  +					throw new SAXParseException("Expected param element, got "
  +							+ new QName(pURI, pLocalName),
  +							getDocumentLocator());
   				}
   				break;
   			case 3:
  -				if (isSuccess) {
  -					super.startElement(pURI, pLocalName, pQName, pAttrs);
  +				if ("".equals(pURI)  &&  "value".equals(pLocalName)) {
  +					startValueTag();
   				} else {
  -					if ("".equals(pURI)  &&  "value".equals(pLocalName)) {
  -						startValueTag();
  -					} else {
  -						throw new SAXParseException("Expected value element, got "
  -								+ new QName(pURI, pLocalName),
  -								getDocumentLocator());
  -					}
  +					throw new SAXParseException("Expected value element, got "
  +							+ new QName(pURI, pLocalName),
  +							getDocumentLocator());
   				}
   				break;
   			default:
  @@ -141,9 +127,9 @@
   				{
   					String tag;
   					if (isSuccess) {
  -						tag = "fault";
  -					} else {
   						tag = "params";
  +					} else {
  +						tag = "fault";
   					}
   					if (!"".equals(pURI)  ||  !tag.equals(pLocalName)) {
   						throw new SAXParseException("Expected /" + tag + " element, got "
  @@ -153,33 +139,19 @@
   					break;
   				}
   			case 2:
  -				{
  -					String tag;
  -					if (isSuccess) {
  -						tag = "value";
  -					} else {
  -						tag = "param";
  -					}
  -					if (!"".equals(pURI)  ||  !tag.equals(pLocalName)) {
  -						throw new SAXParseException("Expected /" + tag + ", got "
  -								+ new QName(pURI, pLocalName),
  -								getDocumentLocator());
  -					} else if (isSuccess) {
  -						endValueTag();
  -					}
  -					break;
  +				if (!"".equals(pURI)  ||  !"param".equals(pLocalName)) {
  +					throw new SAXParseException("Expected /param, got "
  +												+ new QName(pURI, pLocalName),
  +												getDocumentLocator());
   				}
  +				break;
   			case 3:
  -				if (isSuccess) {
  -					super.endElement(pURI, pLocalName, pQName);
  +				if ("".equals(pURI)  &&  "value".equals(pLocalName)) {
  +					endValueTag();
   				} else {
  -					if ("".equals(pURI)  &&  "value".equals(pLocalName)) {
  -						endValueTag();
  -					} else {
  -						throw new SAXParseException("Expected /value, got "
  -													+ new QName(pURI, pLocalName),
  -													getDocumentLocator());
  -					}
  +					throw new SAXParseException("Expected /value, got "
  +							+ new QName(pURI, pLocalName),
  +							getDocumentLocator());
   				}
   				break;
   			default:
  
  
  
  No                   revision
  
  Index: XmlRpcResponseParser.java
  ===================================================================
  RCS file: /home/cvs/ws-xmlrpc/src/java/org/apache/xmlrpc/parser/Attic/XmlRpcResponseParser.java,v
  retrieving revision 1.1.2.1
  retrieving revision 1.1.2.2
  diff -u -r1.1.2.1 -r1.1.2.2
  --- XmlRpcResponseParser.java	12 May 2005 01:58:51 -0000	1.1.2.1
  +++ XmlRpcResponseParser.java	13 May 2005 00:18:21 -0000	1.1.2.2
  @@ -83,9 +83,9 @@
   				break;
   			case 1:
   				if ("".equals(pURI)  &&  "params".equals(pLocalName)) {
  -					isSuccess = false;
  -				} else if ("".equals(pURI)  &&  "fault".equals(pLocalName)) {
   					isSuccess = true;
  +				} else if ("".equals(pURI)  &&  "fault".equals(pLocalName)) {
  +					isSuccess = false;
   				} else {
   					throw new SAXParseException("Expected params or fault element, got "
   												+ new QName(pURI, pLocalName),
  @@ -93,33 +93,19 @@
   				}
   				break;
   			case 2:
  -				if (isSuccess) {
  -					if ("".equals(pURI)  &&  "value".equals(pLocalName)) {
  -						startValueTag();
  -					} else {
  -						throw new SAXParseException("Expected value element, got "
  -													+ new QName(pURI, pLocalName),
  -													getDocumentLocator());
  -					}
  -				} else {
  -					if (!"".equals(pURI)  ||  !"param".equals(pLocalName)) {
  -						throw new SAXParseException("Expected param element, got "
  -													+ new QName(pURI, pLocalName),
  -													getDocumentLocator());
  -					}
  +				if (!"".equals(pURI)  ||  !"param".equals(pLocalName)) {
  +					throw new SAXParseException("Expected param element, got "
  +							+ new QName(pURI, pLocalName),
  +							getDocumentLocator());
   				}
   				break;
   			case 3:
  -				if (isSuccess) {
  -					super.startElement(pURI, pLocalName, pQName, pAttrs);
  +				if ("".equals(pURI)  &&  "value".equals(pLocalName)) {
  +					startValueTag();
   				} else {
  -					if ("".equals(pURI)  &&  "value".equals(pLocalName)) {
  -						startValueTag();
  -					} else {
  -						throw new SAXParseException("Expected value element, got "
  -								+ new QName(pURI, pLocalName),
  -								getDocumentLocator());
  -					}
  +					throw new SAXParseException("Expected value element, got "
  +							+ new QName(pURI, pLocalName),
  +							getDocumentLocator());
   				}
   				break;
   			default:
  @@ -141,9 +127,9 @@
   				{
   					String tag;
   					if (isSuccess) {
  -						tag = "fault";
  -					} else {
   						tag = "params";
  +					} else {
  +						tag = "fault";
   					}
   					if (!"".equals(pURI)  ||  !tag.equals(pLocalName)) {
   						throw new SAXParseException("Expected /" + tag + " element, got "
  @@ -153,33 +139,19 @@
   					break;
   				}
   			case 2:
  -				{
  -					String tag;
  -					if (isSuccess) {
  -						tag = "value";
  -					} else {
  -						tag = "param";
  -					}
  -					if (!"".equals(pURI)  ||  !tag.equals(pLocalName)) {
  -						throw new SAXParseException("Expected /" + tag + ", got "
  -								+ new QName(pURI, pLocalName),
  -								getDocumentLocator());
  -					} else if (isSuccess) {
  -						endValueTag();
  -					}
  -					break;
  +				if (!"".equals(pURI)  ||  !"param".equals(pLocalName)) {
  +					throw new SAXParseException("Expected /param, got "
  +												+ new QName(pURI, pLocalName),
  +												getDocumentLocator());
   				}
  +				break;
   			case 3:
  -				if (isSuccess) {
  -					super.endElement(pURI, pLocalName, pQName);
  +				if ("".equals(pURI)  &&  "value".equals(pLocalName)) {
  +					endValueTag();
   				} else {
  -					if ("".equals(pURI)  &&  "value".equals(pLocalName)) {
  -						endValueTag();
  -					} else {
  -						throw new SAXParseException("Expected /value, got "
  -													+ new QName(pURI, pLocalName),
  -													getDocumentLocator());
  -					}
  +					throw new SAXParseException("Expected /value, got "
  +							+ new QName(pURI, pLocalName),
  +							getDocumentLocator());
   				}
   				break;
   			default:
  
  
  
  1.1.2.1   +84 -0     ws-xmlrpc/src/java/org/apache/xmlrpc/parser/Attic/ByteArrayParser.java
  
  
  
  
  No                   revision
  No                   revision
  1.1.2.2   +6 -1      ws-xmlrpc/src/java/org/apache/xmlrpc/client/Attic/XmlRpcStreamTransport.java
  
  Index: XmlRpcStreamTransport.java
  ===================================================================
  RCS file: /home/cvs/ws-xmlrpc/src/java/org/apache/xmlrpc/client/Attic/XmlRpcStreamTransport.java,v
  retrieving revision 1.1.2.1
  retrieving revision 1.1.2.2
  diff -u -r1.1.2.1 -r1.1.2.2
  --- XmlRpcStreamTransport.java	12 May 2005 01:58:51 -0000	1.1.2.1
  +++ XmlRpcStreamTransport.java	13 May 2005 00:18:21 -0000	1.1.2.2
  @@ -219,7 +219,12 @@
   		try {
   			xw.write(pRequest);
   		} catch (SAXException e) {
  -			throw new XmlRpcClientException("Failed to send request: " + e.getMessage(), e);
  +			Exception ex = e.getException();
  +			if (ex != null  &&  ex instanceof XmlRpcException) {
  +				throw (XmlRpcException) ex;
  +			} else {
  +				throw new XmlRpcClientException("Failed to send request: " + e.getMessage(), e);
  +			}
   		}
   	}
   }
  
  
  
  No                   revision
  No                   revision
  1.1.2.2   +32 -2     ws-xmlrpc/src/java/org/apache/xmlrpc/serializer/Attic/XmlRpcWriter.java
  
  Index: XmlRpcWriter.java
  ===================================================================
  RCS file: /home/cvs/ws-xmlrpc/src/java/org/apache/xmlrpc/serializer/Attic/XmlRpcWriter.java,v
  retrieving revision 1.1.2.1
  retrieving revision 1.1.2.2
  diff -u -r1.1.2.1 -r1.1.2.2
  --- XmlRpcWriter.java	12 May 2005 01:58:52 -0000	1.1.2.1
  +++ XmlRpcWriter.java	13 May 2005 00:18:21 -0000	1.1.2.2
  @@ -19,6 +19,7 @@
   import java.util.Map;
   
   import org.apache.xmlrpc.XmlRpcRequest;
  +import org.apache.xmlrpc.XmlRpcRequestConfig;
   import org.apache.xmlrpc.common.TypeFactory;
   import org.apache.xmlrpc.common.XmlRpcStreamConfig;
   import org.xml.sax.Attributes;
  @@ -56,6 +57,11 @@
   	 * @throws SAXException Writing the request failed.
   	 */
   	public void write(XmlRpcRequest pRequest) throws SAXException {
  +		handler.startDocument();
  +		boolean extensions = pRequest.getConfig().isEnabledForExtensions();
  +		if (extensions) {
  +			handler.startPrefixMapping("ex", XmlRpcWriter.EXTENSIONS_URI);
  +		}
   		handler.startElement("", "methodCall", "methodCall", ZERO_ATTRIBUTES);
   		handler.startElement("", "methodName", "methodName", ZERO_ATTRIBUTES);
   		String s = pRequest.getMethodName();
  @@ -70,13 +76,23 @@
   		}
   		handler.endElement("", "params", "params");
           handler.endElement("", "methodCall", "methodCall");
  +		if (extensions) {
  +			handler.endPrefixMapping("ex");
  +		}
  +		handler.endDocument();
   	}
   
   	/** Writes a servers response to the output stream.
  +	 * @param pConfig The request configuration.
   	 * @param pResult The result object.
   	 * @throws SAXException Writing the response failed.
   	 */
  -	public void write(Object pResult) throws SAXException {
  +	public void write(XmlRpcRequestConfig pConfig, Object pResult) throws SAXException {
  +		handler.startDocument();
  +		boolean extensions = pConfig.isEnabledForExtensions();
  +		if (extensions) {
  +			handler.startPrefixMapping("ex", XmlRpcWriter.EXTENSIONS_URI);
  +		}
   		handler.startElement("", "methodResponse", "methodResponse", ZERO_ATTRIBUTES);
   		handler.startElement("", "params", "params", ZERO_ATTRIBUTES);
   		handler.startElement("", "param", "param", ZERO_ATTRIBUTES);
  @@ -84,14 +100,24 @@
   		handler.endElement("", "param", "param");
   		handler.endElement("", "params", "params");
   		handler.endElement("", "methodResponse", "methodResponse");
  +		if (extensions) {
  +			handler.endPrefixMapping("ex");
  +		}
  +		handler.endDocument();
   	}
   
   	/** Writes a servers error message to the output stream.
  +	 * @param pConfig The request configuration.
   	 * @param pCode The error code
   	 * @param pMessage The error message
   	 * @throws SAXException Writing the error message failed.
   	 */
  -	public void write(int pCode, String pMessage) throws SAXException {
  +	public void write(XmlRpcRequestConfig pConfig, int pCode, String pMessage) throws SAXException {
  +		handler.startDocument();
  +		boolean extensions = pConfig.isEnabledForExtensions();
  +		if (extensions) {
  +			handler.startPrefixMapping("ex", XmlRpcWriter.EXTENSIONS_URI);
  +		}
   		handler.startElement("", "methodResponse", "methodResponse", ZERO_ATTRIBUTES);
   		handler.startElement("", "fault", "fault", ZERO_ATTRIBUTES);
   		Map map = new HashMap();
  @@ -100,6 +126,10 @@
   		writeValue(map);
   		handler.endElement("", "fault", "fault");
   		handler.endElement("", "methodResponse", "methodResponse");
  +		if (extensions) {
  +			handler.endPrefixMapping("ex");
  +		}
  +		handler.endDocument();
   	}
   
   	/** Writes the XML representation of a Java object.
  
  
  
  1.1.2.2   +1 -0      ws-xmlrpc/src/java/org/apache/xmlrpc/serializer/Attic/BaseXmlWriterFactory.java
  
  Index: BaseXmlWriterFactory.java
  ===================================================================
  RCS file: /home/cvs/ws-xmlrpc/src/java/org/apache/xmlrpc/serializer/Attic/BaseXmlWriterFactory.java,v
  retrieving revision 1.1.2.1
  retrieving revision 1.1.2.2
  diff -u -r1.1.2.1 -r1.1.2.2
  --- BaseXmlWriterFactory.java	12 May 2005 01:58:52 -0000	1.1.2.1
  +++ BaseXmlWriterFactory.java	13 May 2005 00:18:21 -0000	1.1.2.2
  @@ -46,6 +46,7 @@
   		}
   		xw.setEncoding(enc);
   		xw.setIndenting(false);
  +		xw.setFlushing(true);
   		try {
   			xw.setWriter(new BufferedWriter(new OutputStreamWriter(pStream, enc)));
   		} catch (UnsupportedEncodingException e) {
  
  
  
  No                   revision
  No                   revision
  1.10.2.1  +1 -0      ws-xmlrpc/.cvsignore
  
  Index: .cvsignore
  ===================================================================
  RCS file: /home/cvs/ws-xmlrpc/.cvsignore,v
  retrieving revision 1.10
  retrieving revision 1.10.2.1
  diff -u -r1.10 -r1.10.2.1
  --- .cvsignore	26 Apr 2005 09:55:57 -0000	1.10
  +++ .cvsignore	13 May 2005 00:18:21 -0000	1.10.2.1
  @@ -4,3 +4,4 @@
   maven.log
   build.properties
   lib
  +build
  
  
  
  No                   revision
  No                   revision
  1.1.2.2   +21 -14    ws-xmlrpc/src/test/org/apache/xmlrpc/test/Attic/BaseTestCase.java
  
  Index: BaseTestCase.java
  ===================================================================
  RCS file: /home/cvs/ws-xmlrpc/src/test/org/apache/xmlrpc/test/Attic/BaseTestCase.java,v
  retrieving revision 1.1.2.1
  retrieving revision 1.1.2.2
  diff -u -r1.1.2.1 -r1.1.2.2
  --- BaseTestCase.java	12 May 2005 01:58:51 -0000	1.1.2.1
  +++ BaseTestCase.java	13 May 2005 00:18:21 -0000	1.1.2.2
  @@ -183,20 +183,22 @@
   			int sum = 0;
   			for (Iterator iter = pArg.entrySet().iterator();  iter.hasNext();  ) {
   				Map.Entry entry = (Map.Entry) iter.next();
  -				sum += ((Integer) entry.getKey()).intValue() * ((Integer) entry.getValue()).intValue();
  +				String key = (String) entry.getKey();
  +				Integer value = (Integer) entry.getValue();
  +				sum += Integer.parseInt(key) * value.intValue();
   			}
   			return sum;
   		}
   		/** Returns a map with the stringified values 0..pArg as
  -		 * values and the corresponding integers as keys.
  +		 * keys and the corresponding integers as values.
   		 * @param pArg Requested map size.
  -		 * @return Map with the values "0".."pArg" as values ans
  -		 * 0..pArg as keys.
  +		 * @return Map with the keys "0".."pArg" and
  +		 * 0..pArg as values.
   		 */
   		public Map mapResult(int pArg) {
   			Map result = new HashMap();
   			for (int i = 0;  i < pArg;  i++) {
  -				result.put(new Integer(i), Integer.toString(i));
  +				result.put(Integer.toString(i), new Integer(i));
   			}
   			return result;
   		}
  @@ -502,9 +504,14 @@
   											  new Integer(3), new Long(4), "5"};
   		final String methodName = "Remote.objectArrayParam";
   		final Object[] params = new Object[]{objects};
  -		Object result = getClient().execute(getConfig(), methodName, params);
  -		assertEquals(new Integer(15), result);
  -		result = getClient().execute(getExConfig(), methodName, params);
  +		boolean ok = false;
  +		try {
  +			getClient().execute(getConfig(), methodName, params);
  +		} catch (XmlRpcExtensionException e) {
  +			ok = true;
  +		}
  +		assertTrue(ok);
  +		Object result = getClient().execute(getExConfig(), methodName, params);
   		assertEquals(new Integer(15), result);
   	}
   
  @@ -528,8 +535,8 @@
   	 */
   	public void testMapParam() throws Exception {
   		final Map map = new HashMap();
  -		map.put(new Integer(2), new Integer(3));
  -		map.put(new Integer(3), new Integer(5));
  +		map.put("2", new Integer(3));
  +		map.put("3", new Integer(5));
   		final String methodName = "Remote.mapParam";
   		final Object[] params = new Object[]{map};
   		Object result = getClient().execute(getConfig(), methodName, params);
  @@ -540,10 +547,10 @@
   
   	private void checkMap(Map pResult) {
   		assertEquals(4, pResult.size());
  -		assertEquals("0", pResult.get(new Integer(0)));
  -		assertEquals("1", pResult.get(new Integer(1)));
  -		assertEquals("2", pResult.get(new Integer(2)));
  -		assertEquals("3", pResult.get(new Integer(3)));
  +		assertEquals(new Integer(0), pResult.get("0"));
  +		assertEquals(new Integer(1), pResult.get("1"));
  +		assertEquals(new Integer(2), pResult.get("2"));
  +		assertEquals(new Integer(3), pResult.get("3"));
   	}
   
   	/** Test, whether we can invoke a method, returning a map.
  
  
  
  No                   revision
  
  Index: BaseTestCase.java
  ===================================================================
  RCS file: /home/cvs/ws-xmlrpc/src/test/org/apache/xmlrpc/test/Attic/BaseTestCase.java,v
  retrieving revision 1.1.2.1
  retrieving revision 1.1.2.2
  diff -u -r1.1.2.1 -r1.1.2.2
  --- BaseTestCase.java	12 May 2005 01:58:51 -0000	1.1.2.1
  +++ BaseTestCase.java	13 May 2005 00:18:21 -0000	1.1.2.2
  @@ -183,20 +183,22 @@
   			int sum = 0;
   			for (Iterator iter = pArg.entrySet().iterator();  iter.hasNext();  ) {
   				Map.Entry entry = (Map.Entry) iter.next();
  -				sum += ((Integer) entry.getKey()).intValue() * ((Integer) entry.getValue()).intValue();
  +				String key = (String) entry.getKey();
  +				Integer value = (Integer) entry.getValue();
  +				sum += Integer.parseInt(key) * value.intValue();
   			}
   			return sum;
   		}
   		/** Returns a map with the stringified values 0..pArg as
  -		 * values and the corresponding integers as keys.
  +		 * keys and the corresponding integers as values.
   		 * @param pArg Requested map size.
  -		 * @return Map with the values "0".."pArg" as values ans
  -		 * 0..pArg as keys.
  +		 * @return Map with the keys "0".."pArg" and
  +		 * 0..pArg as values.
   		 */
   		public Map mapResult(int pArg) {
   			Map result = new HashMap();
   			for (int i = 0;  i < pArg;  i++) {
  -				result.put(new Integer(i), Integer.toString(i));
  +				result.put(Integer.toString(i), new Integer(i));
   			}
   			return result;
   		}
  @@ -502,9 +504,14 @@
   											  new Integer(3), new Long(4), "5"};
   		final String methodName = "Remote.objectArrayParam";
   		final Object[] params = new Object[]{objects};
  -		Object result = getClient().execute(getConfig(), methodName, params);
  -		assertEquals(new Integer(15), result);
  -		result = getClient().execute(getExConfig(), methodName, params);
  +		boolean ok = false;
  +		try {
  +			getClient().execute(getConfig(), methodName, params);
  +		} catch (XmlRpcExtensionException e) {
  +			ok = true;
  +		}
  +		assertTrue(ok);
  +		Object result = getClient().execute(getExConfig(), methodName, params);
   		assertEquals(new Integer(15), result);
   	}
   
  @@ -528,8 +535,8 @@
   	 */
   	public void testMapParam() throws Exception {
   		final Map map = new HashMap();
  -		map.put(new Integer(2), new Integer(3));
  -		map.put(new Integer(3), new Integer(5));
  +		map.put("2", new Integer(3));
  +		map.put("3", new Integer(5));
   		final String methodName = "Remote.mapParam";
   		final Object[] params = new Object[]{map};
   		Object result = getClient().execute(getConfig(), methodName, params);
  @@ -540,10 +547,10 @@
   
   	private void checkMap(Map pResult) {
   		assertEquals(4, pResult.size());
  -		assertEquals("0", pResult.get(new Integer(0)));
  -		assertEquals("1", pResult.get(new Integer(1)));
  -		assertEquals("2", pResult.get(new Integer(2)));
  -		assertEquals("3", pResult.get(new Integer(3)));
  +		assertEquals(new Integer(0), pResult.get("0"));
  +		assertEquals(new Integer(1), pResult.get("1"));
  +		assertEquals(new Integer(2), pResult.get("2"));
  +		assertEquals(new Integer(3), pResult.get("3"));
   	}
   
   	/** Test, whether we can invoke a method, returning a map.
  
  
  
  No                   revision
  
  Index: BaseTestCase.java
  ===================================================================
  RCS file: /home/cvs/ws-xmlrpc/src/test/org/apache/xmlrpc/test/Attic/BaseTestCase.java,v
  retrieving revision 1.1.2.1
  retrieving revision 1.1.2.2
  diff -u -r1.1.2.1 -r1.1.2.2
  --- BaseTestCase.java	12 May 2005 01:58:51 -0000	1.1.2.1
  +++ BaseTestCase.java	13 May 2005 00:18:21 -0000	1.1.2.2
  @@ -183,20 +183,22 @@
   			int sum = 0;
   			for (Iterator iter = pArg.entrySet().iterator();  iter.hasNext();  ) {
   				Map.Entry entry = (Map.Entry) iter.next();
  -				sum += ((Integer) entry.getKey()).intValue() * ((Integer) entry.getValue()).intValue();
  +				String key = (String) entry.getKey();
  +				Integer value = (Integer) entry.getValue();
  +				sum += Integer.parseInt(key) * value.intValue();
   			}
   			return sum;
   		}
   		/** Returns a map with the stringified values 0..pArg as
  -		 * values and the corresponding integers as keys.
  +		 * keys and the corresponding integers as values.
   		 * @param pArg Requested map size.
  -		 * @return Map with the values "0".."pArg" as values ans
  -		 * 0..pArg as keys.
  +		 * @return Map with the keys "0".."pArg" and
  +		 * 0..pArg as values.
   		 */
   		public Map mapResult(int pArg) {
   			Map result = new HashMap();
   			for (int i = 0;  i < pArg;  i++) {
  -				result.put(new Integer(i), Integer.toString(i));
  +				result.put(Integer.toString(i), new Integer(i));
   			}
   			return result;
   		}
  @@ -502,9 +504,14 @@
   											  new Integer(3), new Long(4), "5"};
   		final String methodName = "Remote.objectArrayParam";
   		final Object[] params = new Object[]{objects};
  -		Object result = getClient().execute(getConfig(), methodName, params);
  -		assertEquals(new Integer(15), result);
  -		result = getClient().execute(getExConfig(), methodName, params);
  +		boolean ok = false;
  +		try {
  +			getClient().execute(getConfig(), methodName, params);
  +		} catch (XmlRpcExtensionException e) {
  +			ok = true;
  +		}
  +		assertTrue(ok);
  +		Object result = getClient().execute(getExConfig(), methodName, params);
   		assertEquals(new Integer(15), result);
   	}
   
  @@ -528,8 +535,8 @@
   	 */
   	public void testMapParam() throws Exception {
   		final Map map = new HashMap();
  -		map.put(new Integer(2), new Integer(3));
  -		map.put(new Integer(3), new Integer(5));
  +		map.put("2", new Integer(3));
  +		map.put("3", new Integer(5));
   		final String methodName = "Remote.mapParam";
   		final Object[] params = new Object[]{map};
   		Object result = getClient().execute(getConfig(), methodName, params);
  @@ -540,10 +547,10 @@
   
   	private void checkMap(Map pResult) {
   		assertEquals(4, pResult.size());
  -		assertEquals("0", pResult.get(new Integer(0)));
  -		assertEquals("1", pResult.get(new Integer(1)));
  -		assertEquals("2", pResult.get(new Integer(2)));
  -		assertEquals("3", pResult.get(new Integer(3)));
  +		assertEquals(new Integer(0), pResult.get("0"));
  +		assertEquals(new Integer(1), pResult.get("1"));
  +		assertEquals(new Integer(2), pResult.get("2"));
  +		assertEquals(new Integer(3), pResult.get("3"));
   	}
   
   	/** Test, whether we can invoke a method, returning a map.
  
  
  
  1.1.2.1   +156 -0    ws-xmlrpc/src/test/org/apache/xmlrpc/test/Attic/SerializerTest.java
  
  
  
  
  No                   revision
  No                   revision
  1.1.2.2   +2 -2      ws-xmlrpc/src/java/org/apache/xmlrpc/server/Attic/XmlRpcStreamServer.java
  
  Index: XmlRpcStreamServer.java
  ===================================================================
  RCS file: /home/cvs/ws-xmlrpc/src/java/org/apache/xmlrpc/server/Attic/XmlRpcStreamServer.java,v
  retrieving revision 1.1.2.1
  retrieving revision 1.1.2.2
  diff -u -r1.1.2.1 -r1.1.2.2
  --- XmlRpcStreamServer.java	12 May 2005 01:58:51 -0000	1.1.2.1
  +++ XmlRpcStreamServer.java	13 May 2005 00:18:22 -0000	1.1.2.2
  @@ -88,7 +88,7 @@
   	protected void writeResponse(XmlRpcStreamRequestConfig pConfig, OutputStream pStream,
   								 Object pResult) throws XmlRpcException {
   		try {
  -			getXmlRpcWriter(pConfig, pStream).write(pResult);
  +			getXmlRpcWriter(pConfig, pStream).write(pConfig, pResult);
   		} catch (SAXException e) {
   			throw new XmlRpcException("Failed to write XML-RPC response: " + e.getMessage(), e);
   		}
  @@ -107,7 +107,7 @@
   		}
   		message = pError.getMessage();
   		try {
  -			getXmlRpcWriter(pConfig, pStream).write(code, message);
  +			getXmlRpcWriter(pConfig, pStream).write(pConfig, code, message);
   		} catch (SAXException e) {
   			throw new XmlRpcException("Failed to write XML-RPC response: " + e.getMessage(), e);
   		}
  
  
  
  No                   revision
  No                   revision
  1.1.2.2   +10 -6     ws-xmlrpc/src/java/org/apache/xmlrpc/common/Attic/TypeFactoryImpl.java
  
  Index: TypeFactoryImpl.java
  ===================================================================
  RCS file: /home/cvs/ws-xmlrpc/src/java/org/apache/xmlrpc/common/Attic/TypeFactoryImpl.java,v
  retrieving revision 1.1.2.1
  retrieving revision 1.1.2.2
  diff -u -r1.1.2.1 -r1.1.2.2
  --- TypeFactoryImpl.java	12 May 2005 01:58:52 -0000	1.1.2.1
  +++ TypeFactoryImpl.java	13 May 2005 00:18:22 -0000	1.1.2.2
  @@ -22,12 +22,14 @@
   import org.apache.ws.commons.util.NamespaceContextImpl;
   import org.apache.xmlrpc.client.XmlRpcClient;
   import org.apache.xmlrpc.parser.BooleanParser;
  +import org.apache.xmlrpc.parser.ByteArrayParser;
   import org.apache.xmlrpc.parser.DateParser;
   import org.apache.xmlrpc.parser.DoubleParser;
   import org.apache.xmlrpc.parser.FloatParser;
   import org.apache.xmlrpc.parser.I1Parser;
   import org.apache.xmlrpc.parser.I2Parser;
   import org.apache.xmlrpc.parser.I4Parser;
  +import org.apache.xmlrpc.parser.I8Parser;
   import org.apache.xmlrpc.parser.MapParser;
   import org.apache.xmlrpc.parser.NullParser;
   import org.apache.xmlrpc.parser.ObjectArrayParser;
  @@ -87,7 +89,7 @@
   			if (pConfig.isEnabledForExtensions()) {
   				return NULL_SERIALIZER;
   			} else {
  -				throw new SAXException("Null values aren't supported, if isEnabledForExtensions() == false");
  +				throw new SAXException(new XmlRpcExtensionException("Null values aren't supported, if isEnabledForExtensions() == false"));
   			}
   		} else if (pObject instanceof String) {
   			return STRING_SERIALIZER;
  @@ -95,13 +97,13 @@
   			if (pConfig.isEnabledForExtensions()) {
   				return BYTE_SERIALIZER;
   			} else {
  -				throw new SAXException("Byte values aren't supported, if isEnabledForExtensions() == false");
  +				throw new SAXException(new XmlRpcExtensionException("Byte values aren't supported, if isEnabledForExtensions() == false"));
   			}
   		} else if (pObject instanceof Short) {
   			if (pConfig.isEnabledForExtensions()) {
   				return SHORT_SERIALIZER;
   			} else {
  -				throw new SAXException("Short values aren't supported, if isEnabledForExtensions() == false");
  +				throw new SAXException(new XmlRpcExtensionException("Short values aren't supported, if isEnabledForExtensions() == false"));
   			}
   		} else if (pObject instanceof Integer) {
   			return I4_SERIALIZER;
  @@ -109,7 +111,7 @@
   			if (pConfig.isEnabledForExtensions()) {
   				return LONG_SERIALIZER;
   			} else {
  -				throw new SAXException("Short values aren't supported, if isEnabledForExtensions() == false");
  +				throw new SAXException(new XmlRpcExtensionException("Long values aren't supported, if isEnabledForExtensions() == false"));
   			}
   		} else if (pObject instanceof Boolean) {
   			return BOOLEAN_SERIALIZER;
  @@ -117,7 +119,7 @@
   			if (pConfig.isEnabledForExtensions()) {
   				return FLOAT_SERIALIZER;
   			} else {
  -				throw new SAXException("Float values aren't supported, if isEnabledForExtensions() == false");
  +				throw new SAXException(new XmlRpcExtensionException("Float values aren't supported, if isEnabledForExtensions() == false"));
   			}
   		} else if (pObject instanceof Double) {
   			return DOUBLE_SERIALIZER;
  @@ -148,7 +150,7 @@
   			} else if (I2Serializer.I2_TAG.equals(pLocalName)) {
   				return new I2Parser();
   			} else if (I8Serializer.I8_TAG.equals(pLocalName)) {
  -				return new I4Parser();
  +				return new I8Parser();
   			} else if (FloatSerializer.FLOAT_TAG.equals(pLocalName)) {
   				return new FloatParser();
   			}
  @@ -165,6 +167,8 @@
   				return new ObjectArrayParser(pConfig, pContext, this);
   			} else if (MapSerializer.STRUCT_TAG.equals(pLocalName)) {
   				return new MapParser(pConfig, pContext, this);
  +			} else if (ByteArraySerializer.BASE_64_TAG.equals(pLocalName)) {
  +				return new ByteArrayParser();
   			}
   		}
   		return null;
  
  
  
  No                   revision
  No                   revision
  1.1.2.2   +20 -16    ws-xmlrpc/src/java/org/apache/xmlrpc/util/Attic/Base64.java
  
  Index: Base64.java
  ===================================================================
  RCS file: /home/cvs/ws-xmlrpc/src/java/org/apache/xmlrpc/util/Attic/Base64.java,v
  retrieving revision 1.1.2.1
  retrieving revision 1.1.2.2
  diff -u -r1.1.2.1 -r1.1.2.2
  --- Base64.java	12 May 2005 01:58:53 -0000	1.1.2.1
  +++ Base64.java	13 May 2005 00:18:22 -0000	1.1.2.2
  @@ -94,8 +94,9 @@
   		 */
   		public void write(byte[] pBuffer, int pOffset, int pLen) throws IOException {
   			for(int i = 0;  i < pLen;  i++) {
  -				num = (num << 8) + pBuffer[pOffset++];
  -				pLen--;
  +				int b = pBuffer[pOffset++];
  +				if (b < 0) { b += 256; }
  +				num = (num << 8) + b;
   				if (++numBytes == 3) {
   					charBuffer[charOffset++] = intToBase64[num >> 18];
   					charBuffer[charOffset++] = intToBase64[(num >> 12) & 0x3f];
  @@ -125,6 +126,7 @@
   					charBuffer[charOffset++] = intToBase64[num >> 10];
   					charBuffer[charOffset++] = intToBase64[(num >> 4) & 0x3f];
   					charBuffer[charOffset++] = intToBase64[(num << 2) & 0x3f];
  +					charBuffer[charOffset++] = '=';
   				}
   				writeBuffer();
   				charOffset = 0;
  @@ -179,6 +181,7 @@
   		};
   		try {
   			encoder.write(pBuffer, pOffset, pLen);
  +			encoder.flush();
   		} catch (IOException e) {
   			throw new UndeclaredThrowableException(e);
   		}
  @@ -217,7 +220,6 @@
   		public void write(char[] pData, int pOffset, int pLen) throws IOException {
   			for (int i = 0;  i < pLen;  i++) {
   				char c = pData[pOffset++];
  -				pLen--;
   				if (c == '=') {
   					++eofBytes;
   					num = num << 6;
  @@ -229,11 +231,12 @@
   							// Wait for the next '='
   							break;
   						case 4:
  -							byteBuffer[byteBufferOffset++] = (byte) (num >> 8);
  +							byteBuffer[byteBufferOffset++] = (byte) (num >> 16);
   							if (eofBytes == 1) {
  -								byteBuffer[byteBufferOffset++] = (byte) ((num >> 8) & 0xff);
  +								byteBuffer[byteBufferOffset++] = (byte) (num >> 8);
   							}
   							writeBuffer();
  +							byteBufferOffset = 0;
   							break;
   						case 5:
   							throw new DecodingException("Trailing garbage detected");
  @@ -269,14 +272,19 @@
   				}
   			}
   		}
  -		/* Indicates, that no more data is being expected.
  +		/** Indicates, that no more data is being expected. Writes all currently
  +		 * buffered data to the destination by invoking {@link #writeBuffer()}.
   		 * @throws DecodingException Decoding failed (Unexpected end of file).
   		 * @throws IOException An invocation of the {@link #writeBuffer()} method failed.
   		 */
  -		protected void finished() throws IOException {
  +		public void flush() throws IOException {
   			if (numBytes != 0  &&  numBytes != 4) {
   				throw new DecodingException("Unexpected end of file");
   			}
  +			if (byteBufferOffset > 0) {
  +				writeBuffer();
  +				byteBufferOffset = 0;
  +			}
   		}
   	}
   
  @@ -296,7 +304,7 @@
   				}
   			};
   			public void close() throws IOException {
  -				decoder.finished();
  +				decoder.flush();
   			}
   			public void flush() throws IOException {
   				decoder.writeBuffer();
  @@ -316,12 +324,7 @@
   	 * @throws DecodingException The input character stream contained invalid data.
   	 */
   	public static byte[] decode(char[] pBuffer, int pOffset, int pLen) throws DecodingException {
  -		final ByteArrayOutputStream baos = new ByteArrayOutputStream(){
  -			/** The original implementation would return a clone,
  -			 * which we don't want.
  -			 */
  -			public byte[] toByteArray() { return buf; }
  -		};
  +		final ByteArrayOutputStream baos = new ByteArrayOutputStream();
   		Decoder d = new Decoder(1024){
   			protected void writeBuffer() throws IOException {
   				baos.write(byteBuffer, 0, byteBufferOffset);
  @@ -329,6 +332,7 @@
   		};
   		try {
   			d.write(pBuffer, pOffset, pLen);
  +			d.flush();
   		} catch (DecodingException e) {
   			throw e;
   		} catch (IOException e) {
  @@ -342,7 +346,7 @@
   	 * @return Converted byte array
   	 * @throws DecodingException The input character stream contained invalid data.
   	 */
  -	public byte[] decode(char[] pBuffer) throws DecodingException {
  +	public static byte[] decode(char[] pBuffer) throws DecodingException {
   		return decode(pBuffer, 0, pBuffer.length);
   	}
   
  @@ -351,7 +355,7 @@
   	 * @return Converted byte array
   	 * @throws DecodingException The input character stream contained invalid data.
   	 */
  -	public byte[] decode(String pBuffer) throws DecodingException {
  +	public static byte[] decode(String pBuffer) throws DecodingException {
   		return decode(pBuffer.toCharArray());
   	}
   }