You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@santuario.apache.org by ra...@apache.org on 2004/09/23 22:23:20 UTC

cvs commit: xml-security/src/org/apache/xml/security/c14n/implementations CanonicalizerBase.java

raul        2004/09/23 13:23:20

  Modified:    src/org/apache/xml/security/signature XMLSignature.java
                        Reference.java XMLSignatureInput.java Manifest.java
                        SignedInfo.java
               src/org/apache/xml/security/transforms/implementations
                        TransformBase64Decode.java TransformXPath.java
                        TransformC14NExclusiveWithComments.java
                        TransformXSLT.java TransformC14NWithComments.java
                        TransformC14NExclusive.java
                        TransformEnvelopedSignature.java TransformC14N.java
               src/org/apache/xml/security/utils Base64.java XMLUtils.java
               src/org/apache/xml/security/transforms Transforms.java
                        Transform.java TransformSpi.java
               src/org/apache/xml/security/encryption XMLCipherInput.java
               src_unitTests/org/apache/xml/security/test/utils
                        Base64Test.java
               src_samples/org/apache/xml/security/samples MyResolver.java
               src/org/apache/xml/security/c14n Canonicalizer.java
                        CanonicalizerSpi.java
               src/org/apache/xml/security/c14n/implementations
                        CanonicalizerBase.java
  Added:       src/org/apache/xml/security/utils SignerOutputStream.java
                        DigesterOutputStream.java
  Log:
  - Reduce the memory consuming during digesting using a digester wrapper
  in the last transformation or when c14n.
  - Reduce the memory consuming during signing using a sign wrapper
  when c14n the SignedInfo.
  
  Revision  Changes    Path
  1.40      +10 -11    xml-security/src/org/apache/xml/security/signature/XMLSignature.java
  
  Index: XMLSignature.java
  ===================================================================
  RCS file: /home/cvs/xml-security/src/org/apache/xml/security/signature/XMLSignature.java,v
  retrieving revision 1.39
  retrieving revision 1.40
  diff -u -r1.39 -r1.40
  --- XMLSignature.java	3 Aug 2004 18:01:19 -0000	1.39
  +++ XMLSignature.java	23 Sep 2004 20:23:18 -0000	1.40
  @@ -18,6 +18,8 @@
   
   
   
  +import java.io.BufferedOutputStream;
  +import java.io.OutputStream;
   import java.security.Key;
   import java.security.PublicKey;
   import java.security.cert.X509Certificate;
  @@ -39,6 +41,7 @@
   import org.apache.xml.security.utils.I18n;
   import org.apache.xml.security.utils.IdResolver;
   import org.apache.xml.security.utils.SignatureElementProxy;
  +import org.apache.xml.security.utils.SignerOutputStream;
   import org.apache.xml.security.utils.XMLUtils;
   import org.apache.xml.security.utils.resolver.ResourceResolver;
   import org.apache.xml.security.utils.resolver.ResourceResolverSpi;
  @@ -493,12 +496,10 @@
   
               // generate digest values for all References in this SignedInfo
               si.generateDigestValues();
  -
  +            OutputStream so=new BufferedOutputStream(new SignerOutputStream(sa));
  +            
               // get the canonicalized bytes from SignedInfo
  -            byte signedInfoOctets[] = si.getCanonicalizedOctetStream();
  -
  -            // sign those bytes
  -            sa.update(signedInfoOctets);
  +            si.signInOctectStream(so);
   
               byte jcebytes[] = sa.sign();
   
  @@ -601,11 +602,9 @@
            sa.initVerify(pk);
   
            // Get the canonicalized (normalized) SignedInfo
  -         byte inputBytes[] = this._signedInfo.getCanonicalizedOctetStream();
  -
  -         //set the input bytes on the SignateAlgorithm
  -         sa.update(inputBytes);
  -
  +         SignerOutputStream so=new SignerOutputStream(sa);
  +         this._signedInfo.signInOctectStream(so);
  +         
            //retrieve the byte[] from the stored signature
            byte sigBytes[] = this.getSignatureValue();
   
  
  
  
  1.36      +36 -34    xml-security/src/org/apache/xml/security/signature/Reference.java
  
  Index: Reference.java
  ===================================================================
  RCS file: /home/cvs/xml-security/src/org/apache/xml/security/signature/Reference.java,v
  retrieving revision 1.35
  retrieving revision 1.36
  diff -u -r1.35 -r1.36
  --- Reference.java	20 Sep 2004 21:25:15 -0000	1.35
  +++ Reference.java	23 Sep 2004 20:23:18 -0000	1.36
  @@ -19,7 +19,9 @@
   
   
   
  +import java.io.BufferedOutputStream;
   import java.io.IOException;
  +import java.io.OutputStream;
   import java.util.HashSet;
   import java.util.Set;
   
  @@ -36,6 +38,7 @@
   import org.apache.xml.security.utils.Base64;
   import org.apache.xml.security.utils.CachedXPathAPIHolder;
   import org.apache.xml.security.utils.Constants;
  +import org.apache.xml.security.utils.DigesterOutputStream;
   import org.apache.xml.security.utils.IdResolver;
   import org.apache.xml.security.utils.SignatureElementProxy;
   import org.apache.xml.security.utils.XMLUtils;
  @@ -333,6 +336,7 @@
            Node n=digestValueElement.getFirstChild();
            while (n!=null) {
                  digestValueElement.removeChild(n);
  +               n = n.getNextSibling();
            }
   
            String base64codedValue = Base64.encode(digestValue);
  @@ -352,9 +356,8 @@
              throws XMLSignatureException, ReferenceNotInitializedException {
   
         if (this._state == MODE_SIGN) {
  -         byte calculatedBytes[] = this.calculateDigest();
   
  -         this.setDigestValueElement(calculatedBytes);
  +         this.setDigestValueElement(this.calculateDigest());
         }
      }
   
  @@ -417,8 +420,6 @@
   			result = new XMLSignatureInput(input.getBytes());
   		} catch (CanonicalizationException ex) {
   			 throw new ReferenceNotInitializedException("empty", ex);
  -		} catch (InvalidCanonicalizerException ex) {
  -			 throw new ReferenceNotInitializedException("empty", ex);
   		} catch (IOException ex) {
   			 throw new ReferenceNotInitializedException("empty", ex);
   		}
  @@ -427,7 +428,7 @@
   	
      }
   
  -   private XMLSignatureInput getContentsAfterTransformation(XMLSignatureInput input)
  +   private XMLSignatureInput getContentsAfterTransformation(XMLSignatureInput input, OutputStream os)
              throws XMLSignatureException {
   
         try {
  @@ -435,7 +436,7 @@
            XMLSignatureInput output = null;
   
            if (transforms != null) {
  -            output = transforms.performTransforms(input);
  +            output = transforms.performTransforms(input,os);
               this._transformsOutput = output;//new XMLSignatureInput(output.getBytes());
   
               //this._transformsOutput.setSourceURI(output.getSourceURI());
  @@ -467,7 +468,7 @@
   
         XMLSignatureInput input = this.getContentsBeforeTransformation();
   
  -      return this.getContentsAfterTransformation(input);
  +      return this.getContentsAfterTransformation(input, null);
      }
   
      /**
  @@ -502,7 +503,7 @@
                     break doTransforms;
                  }
   
  -               output = t.performTransform(output);
  +               output = t.performTransform(output, null);
               }
   
               output.setSourceURI(input.getSourceURI());
  @@ -594,16 +595,18 @@
      /**
       * This method returns the {@link XMLSignatureInput} which is referenced by the
       * <CODE>URI</CODE> Attribute.
  +    * @param os TODO
  +    * @return
       *
       * @throws XMLSignatureException
       * @see Manifest#verifyReferences()
       */
  -   protected void dereferenceURIandPerformTransforms()
  +   protected XMLSignatureInput dereferenceURIandPerformTransforms(OutputStream os)
              throws XMLSignatureException {
   
         try {
            XMLSignatureInput input = this.getContentsBeforeTransformation();
  -         XMLSignatureInput output = this.getContentsAfterTransformation(input);
  +         XMLSignatureInput output = this.getContentsAfterTransformation(input, os);
   
            /* at this stage, this._transformsInput and this._transformsOutput
             * contain a huge amount of nodes. When we do not cache these nodes
  @@ -616,6 +619,7 @@
   
               //this._transformsOutput.setSourceURI(output.getSourceURI());
            }
  +         return output;
         } catch (XMLSecurityException ex) {
            throw new ReferenceNotInitializedException("empty", ex);
         }
  @@ -655,22 +659,21 @@
       */
      public byte[] getReferencedBytes()
              throws ReferenceNotInitializedException, XMLSignatureException {
  +    try {
  +        XMLSignatureInput output=this.dereferenceURIandPerformTransforms(null);
   
  -      try {
  -         this.dereferenceURIandPerformTransforms();
  +        byte[] signedBytes = output.getBytes();
   
  -         byte[] signedBytes = this.getTransformsOutput().getBytes();
  +        return signedBytes;
  +     } catch (IOException ex) {
  +        throw new ReferenceNotInitializedException("empty", ex);
  +     } catch (CanonicalizationException ex) {
  +        throw new ReferenceNotInitializedException("empty", ex);
  +     } 
   
  -         return signedBytes;
  -      } catch (IOException ex) {
  -         throw new ReferenceNotInitializedException("empty", ex);
  -      } catch (CanonicalizationException ex) {
  -         throw new ReferenceNotInitializedException("empty", ex);
  -      } catch (InvalidCanonicalizerException ex) {
  -         throw new ReferenceNotInitializedException("empty", ex);
  -      }
      }
   
  +
      /**
       * Method resolverResult
       *
  @@ -682,25 +685,24 @@
              throws ReferenceNotInitializedException, XMLSignatureException {
   
         try {
  -         byte[] data = this.getReferencedBytes();
  +         
            MessageDigestAlgorithm mda = this.getMessageDigestAlgorithm();
   
            mda.reset();
  -         mda.update(data);
  -
  -         byte calculatedDigestValue[] = mda.digest();
  +         DigesterOutputStream diOs=new DigesterOutputStream(mda);
  +         OutputStream os=new BufferedOutputStream(diOs);
  +         XMLSignatureInput output=this.dereferenceURIandPerformTransforms(os);         
  +         output.updateOutputStream(os);
  +         os.flush();
  +         //this.getReferencedBytes(diOs);
  +         //mda.update(data);
   
  -         //J-
  -         if (data.length < 20) {
  -            log.debug(new String(data));
  -         } else {
  -            log.debug(new String(data).substring(0, 20) + " ...");
  -         }
  -         //J+
  -         return calculatedDigestValue;
  +         return diOs.getDigestValue();
         } catch (XMLSecurityException ex) {
            throw new ReferenceNotInitializedException("empty", ex);
  -      }
  +      } catch (IOException ex) {
  +      	 throw new ReferenceNotInitializedException("empty", ex);
  +	}
      }
   
      /**
  
  
  
  1.31      +138 -86   xml-security/src/org/apache/xml/security/signature/XMLSignatureInput.java
  
  Index: XMLSignatureInput.java
  ===================================================================
  RCS file: /home/cvs/xml-security/src/org/apache/xml/security/signature/XMLSignatureInput.java,v
  retrieving revision 1.30
  retrieving revision 1.31
  diff -u -r1.30 -r1.31
  --- XMLSignatureInput.java	20 Sep 2004 21:28:19 -0000	1.30
  +++ XMLSignatureInput.java	23 Sep 2004 20:23:18 -0000	1.31
  @@ -23,6 +23,7 @@
   import java.io.ByteArrayOutputStream;
   import java.io.IOException;
   import java.io.InputStream;
  +import java.io.OutputStream;
   import java.io.StringWriter;
   import java.io.UnsupportedEncodingException;
   import java.io.Writer;
  @@ -36,7 +37,6 @@
   import javax.xml.transform.TransformerException;
   
   import org.apache.xml.security.c14n.CanonicalizationException;
  -import org.apache.xml.security.c14n.InvalidCanonicalizerException;
   import org.apache.xml.security.c14n.helper.AttrCompare;
   import org.apache.xml.security.c14n.implementations.Canonicalizer20010315OmitComments;
   import org.apache.xml.security.utils.JavaUtils;
  @@ -106,6 +106,8 @@
   
      /** Field _cxpathAPI */
      CachedXPathAPIHolder _cxpathAPI=null;
  +   
  +   OutputStream outputStream=null;
   
      /**
       * Construct a XMLSignatureInput from an octet array.
  @@ -117,22 +119,21 @@
      public XMLSignatureInput(byte[] inputOctets) {
   
         // NO  defensive copy
  -
  -      this._inputOctetStreamProxy = new ByteArrayInputStream(inputOctets);
  +   	  
  +      //this._inputOctetStreamProxy = new ByteArrayInputStream(inputOctets);
         this.bytes=inputOctets;
      }
   
   
  -   /**
  +      /**
       * Constructs a <code>XMLSignatureInput</code> from an octet stream. The
       * stream is directly read.
       *
       * @param inputOctetStream
  -    * @throws IOException
       */
  -   public XMLSignatureInput(InputStream inputOctetStream) throws IOException {
  -
  -      this(JavaUtils.getBytesFromStream(inputOctetStream));
  +   public XMLSignatureInput(InputStream inputOctetStream)  {
  +   	  this._inputOctetStreamProxy=inputOctetStream;
  +      //this(JavaUtils.getBytesFromStream(inputOctetStream));
   
      }
   
  @@ -235,20 +236,32 @@
       * @throws SAXException
       * @throws IOException
       * @throws ParserConfigurationException
  -    * @throws InvalidCanonicalizerException
       * @throws CanonicalizationException
       * @throws CanonicalizationException
       * @throws IOException
  -    * @throws InvalidCanonicalizerException
       * @throws ParserConfigurationException
       * @throws SAXException
       */
  -   public Set getNodeSet() throws CanonicalizationException, InvalidCanonicalizerException, ParserConfigurationException, IOException, SAXException {
  +   public Set getNodeSet() throws CanonicalizationException, ParserConfigurationException, IOException, SAXException {
      	      return getNodeSet(false);
      }
  +   /**
  +    * Returns the node set from input which was specified as the parameter of {@link XMLSignatureInput} constructor
  +    * @param circunvent
  +    *
  +    * @return the node set
  +    * @throws SAXException
  +    * @throws IOException
  +    * @throws ParserConfigurationException
  +    * @throws CanonicalizationException
  +    * @throws CanonicalizationException
  +    * @throws IOException
  +    * @throws ParserConfigurationException
  +    * @throws SAXException
  +    */
      public Set getNodeSet(boolean circunvent)
              throws ParserConfigurationException, IOException, SAXException,
  -                  CanonicalizationException, InvalidCanonicalizerException {
  +                  CanonicalizationException {
         if (this._inputNodeSet!=null) {
         	  return this._inputNodeSet;
         }
  @@ -315,32 +328,58 @@
       * @return the Octect stream(byte Stream) from input which was specified as the parameter of {@link XMLSignatureInput} constructor
       * @throws CanonicalizationException
       * @throws IOException
  -    * @throws InvalidCanonicalizerException
       */
      public InputStream getOctetStream()
  -           throws IOException, CanonicalizationException,
  -                  InvalidCanonicalizerException {
  -   	  if (this._inputOctetStreamProxy!=null) {
  -   	  	this._inputOctetStreamProxy.reset();
  -
  -   	  	return this._inputOctetStreamProxy;
  +           throws IOException, CanonicalizationException {
         
  -      } else  if (this.isElement()) {     
  -         if (bytes==null) {         	
  -         	Canonicalizer20010315OmitComments c14nizer =
  -         		new Canonicalizer20010315OmitComments();                  
  -         	bytes=c14nizer.engineCanonicalizeSubTree(this._subNode,this.excludeNode);
  -         }
  -        ByteArrayOutputStream baos = new ByteArrayOutputStream();
  - 		baos.write(bytes);
  -        return new ByteArrayInputStream(baos.toByteArray());
  +   	  InputStream is = this._inputOctetStreamProxy;
  +      if (is!=null) {
  +      	    if (is.markSupported()) {
  +      	    	is.reset();
  +      	    	return is;
  +            }
  +            bytes=JavaUtils.getBytesFromStream(is);
  +      }           
  +      return _inputOctetStreamProxy=new ByteArrayInputStream(getBytes());
   
  -      } else if (this.isNodeSet()) {
  -      	if (bytes!=null) {
  -            ByteArrayOutputStream baos = new ByteArrayOutputStream();
  -            baos.write(bytes);
  -            return new ByteArrayInputStream(baos.toByteArray());
  +   }
  +   /**
  +     * @return
  +     */
  +    public InputStream getOctetStreamReal () {
  +       return this._inputOctetStreamProxy;
  +   }
  +   /**
  +    * Returns the byte array from input which was specified as the parameter of {@link XMLSignatureInput} constructor
  +    *
  +    * @return the byte[] from input which was specified as the parameter of {@link XMLSignatureInput} constructor
  +    *
  +    * @throws CanonicalizationException
  +    * @throws IOException
  +    */
  +   public byte[] getBytes()
  +           throws IOException, CanonicalizationException {
  +    if (bytes!=null) {
  +        return bytes;      
  +      }
  +   	  InputStream is = this._inputOctetStreamProxy;
  +   	  if (is!=null) {
  +   	  	//is.reset();
  +   	  	if (is.markSupported()) {
  +            is.reset();       
  +            bytes=JavaUtils.getBytesFromStream(is);
  +   	  	} else {
  +   	  		bytes=JavaUtils.getBytesFromStream(is);
  +   	  		_inputOctetStreamProxy=new ByteArrayInputStream(bytes);
           }
  +   	  	   	  	
  +   	  	return bytes;   	  	      
  +      } else if (this.isElement()) {                    
  +         Canonicalizer20010315OmitComments c14nizer =
  +         		new Canonicalizer20010315OmitComments();                  
  +        bytes=c14nizer.engineCanonicalizeSubTree(this._subNode,this.excludeNode);         
  +        return bytes;
  +      } else if (this.isNodeSet()) {      	
            /* If we have a node set but an octet stream is needed, we MUST c14nize
             * without any comments.
             *
  @@ -348,64 +387,20 @@
             * little bit faster...
             */
            Canonicalizer20010315OmitComments c14nizer =
  -            new Canonicalizer20010315OmitComments();
  -         ByteArrayOutputStream baos = new ByteArrayOutputStream();
  +            new Canonicalizer20010315OmitComments();         
   
            if (this._inputNodeSet.size() == 0) {
  -
               // empty nodeset
  -            return new ByteArrayInputStream(baos.toByteArray());
  -         }
  -
  -         try {         	
  -            Set nodes = this.getNodeSet();
  -            if (bytes==null) {
  -            bytes = c14nizer.engineCanonicalizeXPathNodeSet(nodes);
  -            }
  -            baos.write(bytes);
  -            /** $todo$ Clarify behavior. If isNodeSet() and we getOctetStream, do we have to this._inputOctetStream=xxx ? */
  -
  -            /*
  -            this._inputOctetStream = new ByteArrayInputStream(baos.toByteArray());
  -            this._inputNodeSet = null;
  -            return this._inputOctetStream;
  -            */
  -            return new ByteArrayInputStream(baos.toByteArray());
  -         } catch (SAXException ex) {
  -            throw new CanonicalizationException("empty", ex);
  -         } catch (ParserConfigurationException ex) {
  -            throw new CanonicalizationException("empty", ex);
  -         }
  +            return null;
  +         }              
  +         bytes = c14nizer.engineCanonicalizeXPathNodeSet(_inputNodeSet);
  +          return bytes;         
         }
   
         throw new RuntimeException(
  -         "getOctetStream() called but no input data present");
  +         "getBytes() called but no input data present");
      }
   
  -   /**
  -    * Returns the byte array from input which was specified as the parameter of {@link XMLSignatureInput} constructor
  -    *
  -    * @return the byte[] from input which was specified as the parameter of {@link XMLSignatureInput} constructor
  -    *
  -    * @throws CanonicalizationException
  -    * @throws IOException
  -    * @throws InvalidCanonicalizerException
  -    */
  -   public byte[] getBytes()
  -           throws IOException, CanonicalizationException,
  -                  InvalidCanonicalizerException {
  -      if ( bytes!=null) {
  -      	return bytes;
  -      }
  -      InputStream is = this.getOctetStream();      
  -      int available = is.available();
  -      bytes = new byte[available];
  -      is.read(bytes);
  -      if (available != bytes.length) {
  -         throw new IOException("Not enough bytes read");
  -      }
  -      return bytes;
  -   }
   
      /**
       * Determines if the object has been set up with a Node set
  @@ -433,8 +428,8 @@
       * @return true is the object has been set up with an octet stream
       */
      public boolean isOctetStream() {
  -      return ((this._inputOctetStreamProxy != null)
  -              && (this._inputNodeSet == null));
  +      return ( ((this._inputOctetStreamProxy != null) || bytes!=null)
  +              && ((this._inputNodeSet == null) && _subNode ==null));
      }
   
      /**
  @@ -1247,4 +1242,61 @@
   	         }
   	      }
   	   }
  +
  +	/**
  +	 * @param diOs
  +	 * @throws IOException
  +	 * @throws CanonicalizationException
  +	 */
  +	public void updateOutputStream(OutputStream diOs) throws CanonicalizationException, IOException {        
  +        if (diOs==outputStream) {
  +        	return;
  +        }
  +        if (bytes!=null) {
  +            diOs.write(bytes);
  +            return;      
  +         }else if (this.isElement()) {                    
  +             Canonicalizer20010315OmitComments c14nizer =
  +                    new Canonicalizer20010315OmitComments();       
  +             c14nizer.setWriter(diOs);
  +            c14nizer.engineCanonicalizeSubTree(this._subNode,this.excludeNode); 
  +            return;
  +          } else if (this.isNodeSet()) {        
  +             /* If we have a node set but an octet stream is needed, we MUST c14nize
  +              * without any comments.
  +              *
  +              * We don't use the factory because direct instantiation should be a
  +              * little bit faster...
  +              */
  +             Canonicalizer20010315OmitComments c14nizer =
  +                new Canonicalizer20010315OmitComments();         
  +             c14nizer.setWriter(diOs);
  +             if (this._inputNodeSet.size() == 0) {
  +                // empty nodeset
  +                return;
  +             }                              
  +             c14nizer.engineCanonicalizeXPathNodeSet(this._inputNodeSet);                
  +             return;             
  +          } else {
  +            InputStream is = this._inputOctetStreamProxy;
  +            if (is.markSupported())
  +                is.reset();
  +                int num;
  +                bytes = new byte[1024];
  +                while ((num=is.read(bytes))>0) {
  +                	diOs.write(bytes,0,num);
  +                }
  +                
  +          }
  +		
  +	}
  +
  +
  +	/**
  +	 * @param os
  +	 */
  +	public void setOutputStream(OutputStream os) {
  +		outputStream=os;
  +		
  +	}
   }
  
  
  
  1.29      +2 -4      xml-security/src/org/apache/xml/security/signature/Manifest.java
  
  Index: Manifest.java
  ===================================================================
  RCS file: /home/cvs/xml-security/src/org/apache/xml/security/signature/Manifest.java,v
  retrieving revision 1.28
  retrieving revision 1.29
  diff -u -r1.28 -r1.29
  --- Manifest.java	3 Aug 2004 18:01:19 -0000	1.28
  +++ Manifest.java	23 Sep 2004 20:23:19 -0000	1.29
  @@ -328,11 +328,9 @@
                       && currentRef.typeIsReferenceToManifest()) {
                  log.debug("We have to follow a nested Manifest");
   
  -               try {
  -                  currentRef.dereferenceURIandPerformTransforms();
  -
  +                try {
                     XMLSignatureInput signedManifestNodes =
  -                     currentRef.getTransformsOutput();
  +                    currentRef.dereferenceURIandPerformTransforms(null);
                     Set nl = signedManifestNodes.getNodeSet();
                     Manifest referencedManifest = null;
                     Iterator nlIterator = nl.iterator();
  
  
  
  1.22      +26 -0     xml-security/src/org/apache/xml/security/signature/SignedInfo.java
  
  Index: SignedInfo.java
  ===================================================================
  RCS file: /home/cvs/xml-security/src/org/apache/xml/security/signature/SignedInfo.java,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- SignedInfo.java	3 Aug 2004 18:01:19 -0000	1.21
  +++ SignedInfo.java	23 Sep 2004 20:23:19 -0000	1.22
  @@ -20,6 +20,7 @@
   
   import java.io.ByteArrayInputStream;
   import java.io.IOException;
  +import java.io.OutputStream;
   
   import javax.crypto.SecretKey;
   import javax.crypto.spec.SecretKeySpec;
  @@ -249,6 +250,31 @@
         System.arraycopy(this._c14nizedBytes, 0, output, 0, output.length);
   
         return output;
  +   }
  +   
  +   /**
  +    *  Output the C14n stream to the give outputstream.
  +    * @param os
  +    * @throws CanonicalizationException
  +    * @throws InvalidCanonicalizerException
  +    * @throws XMLSecurityException
  +    */
  +   public void signInOctectStream(OutputStream os)            
  +       throws CanonicalizationException, InvalidCanonicalizerException,
  +	   XMLSecurityException {
  +
  +   	if ((this._c14nizedBytes == null)) {
  +       Canonicalizer c14nizer =
  +          Canonicalizer.getInstance(this.getCanonicalizationMethodURI());
  +       c14nizer.setWriter(os);       
  +       c14nizer.canonicalizeSubtree(this._constructionElement);
  +    } else {
  +        try {
  +			os.write(this._c14nizedBytes);
  +		} catch (IOException e) {
  +			throw new RuntimeException(e);
  +		}  
  +    }    
      }
   
      /**
  
  
  
  1.17      +32 -9     xml-security/src/org/apache/xml/security/transforms/implementations/TransformBase64Decode.java
  
  Index: TransformBase64Decode.java
  ===================================================================
  RCS file: /home/cvs/xml-security/src/org/apache/xml/security/transforms/implementations/TransformBase64Decode.java,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- TransformBase64Decode.java	20 Sep 2004 21:36:28 -0000	1.16
  +++ TransformBase64Decode.java	23 Sep 2004 20:23:19 -0000	1.17
  @@ -19,13 +19,14 @@
   
   
   
  +import java.io.BufferedInputStream;
   import java.io.IOException;
  +import java.io.OutputStream;
   
   import javax.xml.parsers.DocumentBuilderFactory;
   import javax.xml.parsers.ParserConfigurationException;
   
   import org.apache.xml.security.c14n.CanonicalizationException;
  -import org.apache.xml.security.c14n.InvalidCanonicalizerException;
   import org.apache.xml.security.exceptions.Base64DecodingException;
   import org.apache.xml.security.signature.XMLSignatureInput;
   import org.apache.xml.security.transforms.TransformSpi;
  @@ -99,13 +100,17 @@
       * @inheritDoc
       * @throws CanonicalizationException
       * @throws IOException
  -    * @throws InvalidCanonicalizerException
       * @throws TransformationException
       */
      protected XMLSignatureInput enginePerformTransform(XMLSignatureInput input)
              throws IOException, CanonicalizationException,
  -                  TransformationException, InvalidCanonicalizerException {
  -
  +                  TransformationException {
  +   	return enginePerformTransform(input,null);
  +   }
  +    protected XMLSignatureInput enginePerformTransform(XMLSignatureInput input,
  +            OutputStream os)
  +    throws IOException, CanonicalizationException,
  +           TransformationException {
   	 try {
         if (input.isElement()) {
            Node el=input.getSubNode();
  @@ -114,13 +119,31 @@
            }
            StringBuffer sb=new StringBuffer();
            traverseElement((Element)el,sb);
  -         byte[] decodedBytes = Base64.decode(sb.toString());            
  -         return new XMLSignatureInput(decodedBytes);         
  +         if (os==null) {
  +         	byte[] decodedBytes = Base64.decode(sb.toString());            
  +         	return new XMLSignatureInput(decodedBytes);
  +         } 
  +         	Base64.decode(sb.toString().getBytes(),os);
  +            XMLSignatureInput output=new XMLSignatureInput((byte[])null);
  +            output.setOutputStream(os);
  +            return output;
  +         
         }
         if (input.isOctetStream() ) {
  -        byte[] base64Bytes = input.getBytes();            
  -        byte[] decodedBytes = Base64.decode(base64Bytes);
  -        return new XMLSignatureInput(decodedBytes);
  +                    
  +        
  +        if (os==null) {
  +            byte[] base64Bytes = input.getBytes();
  +            byte[] decodedBytes = Base64.decode(base64Bytes);            
  +            return new XMLSignatureInput(decodedBytes);
  +         } 
  +            Base64.decode(new BufferedInputStream(input.getOctetStreamReal())
  +                    ,os);
  +            XMLSignatureInput output=new XMLSignatureInput((byte[])null);
  +            output.setOutputStream(os);
  +            return output;
  +         
  +        
         } 
          
   	 try {
  
  
  
  1.18      +0 -3      xml-security/src/org/apache/xml/security/transforms/implementations/TransformXPath.java
  
  Index: TransformXPath.java
  ===================================================================
  RCS file: /home/cvs/xml-security/src/org/apache/xml/security/transforms/implementations/TransformXPath.java,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- TransformXPath.java	20 Sep 2004 21:35:16 -0000	1.17
  +++ TransformXPath.java	23 Sep 2004 20:23:19 -0000	1.18
  @@ -27,7 +27,6 @@
   import javax.xml.transform.TransformerException;
   
   import org.apache.xml.security.c14n.CanonicalizationException;
  -import org.apache.xml.security.c14n.InvalidCanonicalizerException;
   import org.apache.xml.security.exceptions.XMLSecurityException;
   import org.apache.xml.security.signature.XMLSignatureInput;
   import org.apache.xml.security.transforms.TransformSpi;
  @@ -189,8 +188,6 @@
         } catch (IOException ex) {
            throw new TransformationException("empty", ex);
         } catch (CanonicalizationException ex) {
  -         throw new TransformationException("empty", ex);
  -      } catch (InvalidCanonicalizerException ex) {
            throw new TransformationException("empty", ex);
         } catch (ParserConfigurationException ex) {
            throw new TransformationException("empty", ex);
  
  
  
  1.8       +54 -55    xml-security/src/org/apache/xml/security/transforms/implementations/TransformC14NExclusiveWithComments.java
  
  Index: TransformC14NExclusiveWithComments.java
  ===================================================================
  RCS file: /home/cvs/xml-security/src/org/apache/xml/security/transforms/implementations/TransformC14NExclusiveWithComments.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- TransformC14NExclusiveWithComments.java	20 Sep 2004 21:33:31 -0000	1.7
  +++ TransformC14NExclusiveWithComments.java	23 Sep 2004 20:23:19 -0000	1.8
  @@ -19,7 +19,7 @@
   
   
   import java.io.IOException;
  -import java.util.Set;
  +import java.io.OutputStream;
   
   import javax.xml.parsers.ParserConfigurationException;
   
  @@ -32,7 +32,6 @@
   import org.apache.xml.security.transforms.params.InclusiveNamespaces;
   import org.apache.xml.security.utils.XMLUtils;
   import org.w3c.dom.Element;
  -import org.w3c.dom.Node;
   import org.xml.sax.SAXException;
   
   
  @@ -69,65 +68,65 @@
      }
   
      /**
  -    * Method enginePerformTransform
  -    *
  -    * @param input
       * @inheritDoc 
  -    * @throws CanonicalizationException
       */
      protected XMLSignatureInput enginePerformTransform(XMLSignatureInput input)
              throws CanonicalizationException {
  +   	    return enginePerformTransform(input,null);
  +   }
  +    protected XMLSignatureInput enginePerformTransform(XMLSignatureInput input,OutputStream os)
  +    throws CanonicalizationException {
  +     try {
  +        String inclusiveNamespaces = null;
  +
  +        if (this._transformObject
  +                .length(InclusiveNamespaces
  +                   .ExclusiveCanonicalizationNamespace, InclusiveNamespaces
  +                   ._TAG_EC_INCLUSIVENAMESPACES) == 1) {
  +           Element inclusiveElement =
  +               XMLUtils.selectNode(
  +              this._transformObject.getElement().getFirstChild(),
  +                 InclusiveNamespaces.ExclusiveCanonicalizationNamespace,
  +                 InclusiveNamespaces._TAG_EC_INCLUSIVENAMESPACES,0);
  +
  +           inclusiveNamespaces = new InclusiveNamespaces(inclusiveElement,
  +                   this._transformObject.getBaseURI()).getInclusiveNamespaces();
  +        }
   
  -      try {
  -         Element inclusiveElement =XMLUtils.selectNode(
  -            this._transformObject.getElement().getFirstChild(),
  -               InclusiveNamespaces.ExclusiveCanonicalizationNamespace,
  -               InclusiveNamespaces._TAG_EC_INCLUSIVENAMESPACES,0);
  -         InclusiveNamespaces inclusiveNamespaces = null;
  -
  -         if (inclusiveElement != null) {
  -            inclusiveNamespaces = new InclusiveNamespaces(inclusiveElement,
  -                    this._transformObject.getBaseURI());
  -         }
  -
  -         Canonicalizer20010315ExclWithComments c14n =
  +        Canonicalizer20010315ExclWithComments c14n =
               new Canonicalizer20010315ExclWithComments();
            c14n.set_includeComments(!input.isExcludeComments());
  -         if (input.isOctetStream()) {
  -            return new XMLSignatureInput(c14n
  -               .engineCanonicalize(input.getBytes()));
  -         } 
  -         	if (input.isElement()) {
  -         		if (inclusiveNamespaces == null) {
  -             		Node excl=input.getExcludeNode();
  -         			return new XMLSignatureInput(
  -         					c14n.engineCanonicalizeSubTree(input.getSubNode(),"",
  -         							excl));
  -         		} 
  -         		Node excl=input.getExcludeNode();
  -         			return new XMLSignatureInput(
  -         					c14n.engineCanonicalizeSubTree(input.getSubNode(),inclusiveNamespaces.getInclusiveNamespaces(),
  -         							excl));
  -         		
  -         	}
  -            String inclusiveNamespacesS=null;
  -            if (inclusiveNamespaces != null) {
  -                inclusiveNamespacesS=inclusiveNamespaces.getInclusiveNamespaces();
  -            } 
  -            
  -               return new XMLSignatureInput(c14n
  -                  .engineCanonicalizeXPathNodeSet(input.getNodeSet()
  -                     , inclusiveNamespacesS));
  -            
  -         
  -      } catch (IOException ex) {
  -         throw new CanonicalizationException("empty", ex);
  -      } catch (ParserConfigurationException ex) {
  -         throw new CanonicalizationException("empty", ex);
  -      } catch (XMLSecurityException ex) {
  -         throw new CanonicalizationException("empty", ex);
  -      } catch (SAXException ex) {
  -         throw new CanonicalizationException("empty", ex);
  -      }
  +        if (os!=null) {
  +           c14n.setWriter( os);
  +        }
  +        byte []result;
  +        if (input.isOctetStream()) {
  +           result=c14n.engineCanonicalize(input.getBytes());
  +        } else if (input.isElement()) {
  +                org.w3c.dom.Node excl=input.getExcludeNode();
  +                result =c14n
  +                           .engineCanonicalizeSubTree(input
  +                              .getSubNode(), inclusiveNamespaces
  +                              ,excl);
  +          }    else {
  +              result = c14n
  +                 .engineCanonicalizeXPathNodeSet(input
  +                    .getNodeSet(), inclusiveNamespaces
  +                    );      
  +          }
  +        XMLSignatureInput output=new XMLSignatureInput(result);
  +        if (os!=null) {
  +           output.setOutputStream(os);
  +        }
  +        return output;
  +     } catch (IOException ex) {
  +        throw new CanonicalizationException("empty", ex);
  +     } catch (ParserConfigurationException ex) {
  +        throw new CanonicalizationException("empty", ex);
  +     } catch (XMLSecurityException ex) {
  +        throw new CanonicalizationException("empty", ex);
  +     } catch (SAXException ex) {
  +        throw new CanonicalizationException("empty", ex);
  +     }
      }
   }
  
  
  
  1.9       +17 -10    xml-security/src/org/apache/xml/security/transforms/implementations/TransformXSLT.java
  
  Index: TransformXSLT.java
  ===================================================================
  RCS file: /home/cvs/xml-security/src/org/apache/xml/security/transforms/implementations/TransformXSLT.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- TransformXSLT.java	3 Aug 2004 18:01:20 -0000	1.8
  +++ TransformXSLT.java	23 Sep 2004 20:23:19 -0000	1.9
  @@ -22,6 +22,7 @@
   import java.io.ByteArrayInputStream;
   import java.io.ByteArrayOutputStream;
   import java.io.IOException;
  +import java.io.OutputStream;
   
   import javax.xml.transform.Source;
   import javax.xml.transform.Transformer;
  @@ -32,7 +33,6 @@
   import javax.xml.transform.stream.StreamResult;
   import javax.xml.transform.stream.StreamSource;
   
  -import org.apache.xml.security.c14n.InvalidCanonicalizerException;
   import org.apache.xml.security.exceptions.XMLSecurityException;
   import org.apache.xml.security.signature.XMLSignatureInput;
   import org.apache.xml.security.transforms.TransformSpi;
  @@ -90,7 +90,11 @@
      protected XMLSignatureInput enginePerformTransform(XMLSignatureInput input)
              throws IOException,
                     TransformationException {
  -
  +   	return enginePerformTransform(input,null);
  +   }
  +    protected XMLSignatureInput enginePerformTransform(XMLSignatureInput input,OutputStream baos)
  +    throws IOException,
  +           TransformationException {
         try {
            Element transformElement = this._transformObject.getElement();        
   
  @@ -137,16 +141,19 @@
            }
   
            Transformer transformer = tFactory.newTransformer(stylesheet);
  -         ByteArrayOutputStream baos = new ByteArrayOutputStream();
  -         StreamResult outputTarget = new StreamResult(baos);
  +         if (baos==null) {
  +         	    ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
  +               StreamResult outputTarget = new StreamResult(baos1);
  +               transformer.transform(xmlSource, outputTarget);
  +               return new XMLSignatureInput(baos1.toByteArray());
   
  -         transformer.transform(xmlSource, outputTarget);
  -
  -         return new XMLSignatureInput(baos.toByteArray());
  -      } catch (InvalidCanonicalizerException ex) {
  -         Object exArgs[] = { ex.getMessage() };
  +         }
  +         StreamResult outputTarget = new StreamResult(baos);
   
  -         throw new TransformationException("generic.EmptyMessage", exArgs, ex);
  +         transformer.transform(xmlSource, outputTarget);         
  +         XMLSignatureInput output=new XMLSignatureInput((byte[])null);
  +         output.setOutputStream(baos);
  +         return output;
         } catch (XMLSecurityException ex) {
            Object exArgs[] = { ex.getMessage() };
   
  
  
  
  1.10      +21 -23    xml-security/src/org/apache/xml/security/transforms/implementations/TransformC14NWithComments.java
  
  Index: TransformC14NWithComments.java
  ===================================================================
  RCS file: /home/cvs/xml-security/src/org/apache/xml/security/transforms/implementations/TransformC14NWithComments.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- TransformC14NWithComments.java	20 Sep 2004 21:36:28 -0000	1.9
  +++ TransformC14NWithComments.java	23 Sep 2004 20:23:19 -0000	1.10
  @@ -19,17 +19,16 @@
   
   
   import java.io.IOException;
  +import java.io.OutputStream;
   import java.util.Set;
   
   import javax.xml.parsers.ParserConfigurationException;
   
   import org.apache.xml.security.c14n.CanonicalizationException;
  -import org.apache.xml.security.c14n.InvalidCanonicalizerException;
   import org.apache.xml.security.c14n.implementations.Canonicalizer20010315WithComments;
   import org.apache.xml.security.signature.XMLSignatureInput;
   import org.apache.xml.security.transforms.TransformSpi;
   import org.apache.xml.security.transforms.Transforms;
  -import org.apache.xml.security.utils.XMLUtils;
   import org.w3c.dom.Node;
   import org.xml.sax.SAXException;
   
  @@ -47,39 +46,34 @@
         Transforms.TRANSFORM_C14N_WITH_COMMENTS;
   
      //J-
  +   /** @inheritDoc */
      public boolean wantsOctetStream ()   { return true; }
  +   /** @inheritDoc */
      public boolean wantsNodeSet ()       { return true; }
  +   /** @inheritDoc */
      public boolean returnsOctetStream () { return true; }
  +   /** @inheritDoc */
      public boolean returnsNodeSet ()     { return false; }
      //J+
   
  -   /**
  -    * Method engineGetURI
  -    *
  -    *
  -    */
  +   /** @inheritDoc */
      protected String engineGetURI() {
         return implementedTransformURI;
      }
  -
  -   /**
  -    * Method enginePerformTransform
  -    *
  -    * @param input
  -    *
  -    * @throws CanonicalizationException
  -    * @throws IOException
  -    * @throws InvalidCanonicalizerException
  -    * @throws ParserConfigurationException
  -    * @throws SAXException
  -    */
  +   /** @inheritDoc */
      protected XMLSignatureInput enginePerformTransform(XMLSignatureInput input)
  -           throws IOException, CanonicalizationException,
  -                  InvalidCanonicalizerException, ParserConfigurationException,
  -                  SAXException {
  +   throws IOException, CanonicalizationException {
  +   	    return enginePerformTransform(input,null);
  +   }
  +   /** @inheritDoc */
  +   protected XMLSignatureInput enginePerformTransform(XMLSignatureInput input,OutputStream os)
  +           throws IOException, CanonicalizationException {
   
         try {
           Canonicalizer20010315WithComments c14n = new Canonicalizer20010315WithComments();
  +        if (os!=null) {
  +        	c14n.setWriter( os);
  +        }
           c14n.set_includeComments(!input.isExcludeComments());
            byte[] result = null;
            if (input.isOctetStream()) {
  @@ -93,7 +87,11 @@
            		result = c14n.engineCanonicalizeXPathNodeSet(set);
            	}
            }
  -         return new XMLSignatureInput(result);
  +         XMLSignatureInput output=new XMLSignatureInput(result);
  +         if (os!=null) {
  +         	output.setOutputStream(os);
  +         }
  +         return output;
         } catch (ParserConfigurationException ex) {
            Object[] exArgs = { ex.getMessage() };
            CanonicalizationException cex = new CanonicalizationException(
  
  
  
  1.9       +26 -28    xml-security/src/org/apache/xml/security/transforms/implementations/TransformC14NExclusive.java
  
  Index: TransformC14NExclusive.java
  ===================================================================
  RCS file: /home/cvs/xml-security/src/org/apache/xml/security/transforms/implementations/TransformC14NExclusive.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- TransformC14NExclusive.java	3 Aug 2004 18:01:20 -0000	1.8
  +++ TransformC14NExclusive.java	23 Sep 2004 20:23:19 -0000	1.9
  @@ -19,11 +19,11 @@
   
   
   import java.io.IOException;
  +import java.io.OutputStream;
   
   import javax.xml.parsers.ParserConfigurationException;
   
   import org.apache.xml.security.c14n.CanonicalizationException;
  -import org.apache.xml.security.c14n.InvalidCanonicalizerException;
   import org.apache.xml.security.c14n.implementations.Canonicalizer20010315ExclOmitComments;
   import org.apache.xml.security.exceptions.XMLSecurityException;
   import org.apache.xml.security.signature.XMLSignatureInput;
  @@ -76,9 +76,12 @@
       */
      protected XMLSignatureInput enginePerformTransform(XMLSignatureInput input)
              throws CanonicalizationException {
  -
  +   	    return enginePerformTransform(input,null);
  +   }
  +    protected XMLSignatureInput enginePerformTransform(XMLSignatureInput input,OutputStream os)
  +    throws CanonicalizationException {
         try {
  -         InclusiveNamespaces inclusiveNamespaces = null;
  +         String inclusiveNamespaces = null;
   
            if (this._transformObject
                    .length(InclusiveNamespaces
  @@ -91,39 +94,34 @@
                     InclusiveNamespaces._TAG_EC_INCLUSIVENAMESPACES,0);
   
               inclusiveNamespaces = new InclusiveNamespaces(inclusiveElement,
  -                    this._transformObject.getBaseURI());
  +                    this._transformObject.getBaseURI()).getInclusiveNamespaces();
            }
   
            Canonicalizer20010315ExclOmitComments c14n =
               new Canonicalizer20010315ExclOmitComments();
  -         
  +         if (os!=null) {
  +            c14n.setWriter(os);
  +         }
  +         byte []result;
            if (input.isOctetStream()) {
  -            return new XMLSignatureInput(c14n
  -               .engineCanonicalize(input.getBytes()));
  -         } 
  -         	byte []result;
  -            if (inclusiveNamespaces == null) {
  -            	if (input.isElement()) {
  -             		org.w3c.dom.Node excl=input.getExcludeNode();             	
  -             		result=c14n.engineCanonicalizeSubTree(input.getSubNode(),"",excl);             		
  -             	} else {
  -             		result=c14n
  -	                  .engineCanonicalizeXPathNodeSet(input.getNodeSet());
  -             	}
  -               return new XMLSignatureInput(result);
  -            }
  -            	if (input.isElement()) {
  +            result=c14n.engineCanonicalize(input.getBytes());
  +         } else if (input.isElement()) {
               		org.w3c.dom.Node excl=input.getExcludeNode();
  -            		return new XMLSignatureInput(c14n
  +            		result =c14n
                               .engineCanonicalizeSubTree(input
                                  .getSubNode(), inclusiveNamespaces
  -                               .getInclusiveNamespaces(),excl));
  -            	}
  -               return new XMLSignatureInput(c14n
  +                               ,excl);
  +           }    else {
  +               result = c14n
                     .engineCanonicalizeXPathNodeSet(input
                        .getNodeSet(), inclusiveNamespaces
  -                     .getInclusiveNamespaces()));      
  -         
  +                     );      
  +           }
  +         XMLSignatureInput output=new XMLSignatureInput(result);
  +         if (os!=null) {
  +            output.setOutputStream(os);
  +         }
  +         return output;
         } catch (IOException ex) {
            throw new CanonicalizationException("empty", ex);
         } catch (ParserConfigurationException ex) {
  
  
  
  1.13      +1 -9      xml-security/src/org/apache/xml/security/transforms/implementations/TransformEnvelopedSignature.java
  
  Index: TransformEnvelopedSignature.java
  ===================================================================
  RCS file: /home/cvs/xml-security/src/org/apache/xml/security/transforms/implementations/TransformEnvelopedSignature.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- TransformEnvelopedSignature.java	20 Sep 2004 21:36:28 -0000	1.12
  +++ TransformEnvelopedSignature.java	23 Sep 2004 20:23:19 -0000	1.13
  @@ -24,14 +24,12 @@
   import javax.xml.parsers.ParserConfigurationException;
   
   import org.apache.xml.security.c14n.CanonicalizationException;
  -import org.apache.xml.security.c14n.InvalidCanonicalizerException;
   import org.apache.xml.security.signature.XMLSignatureInput;
   import org.apache.xml.security.transforms.TransformSpi;
   import org.apache.xml.security.transforms.TransformationException;
   import org.apache.xml.security.transforms.Transforms;
   import org.apache.xml.security.utils.Constants;
   import org.apache.xml.security.utils.XMLUtils;
  -import org.w3c.dom.Document;
   import org.w3c.dom.Element;
   import org.w3c.dom.Node;
   import org.xml.sax.SAXException;
  @@ -70,11 +68,7 @@
      }
   
      /**
  -    * This transform performs the Enveloped-Signature-Transform by
  -    *
  -    * @param input
       * @inheritDoc
  -    * @throws TransformationException
       */
      protected XMLSignatureInput enginePerformTransform(XMLSignatureInput input)
              throws TransformationException {
  @@ -133,9 +127,7 @@
            throw new TransformationException("empty", ex);
         } catch (CanonicalizationException ex) {
            throw new TransformationException("empty", ex);
  -      } catch (InvalidCanonicalizerException ex) {
  -         throw new TransformationException("empty", ex);
  -      }
  +      } 
      }
   
      /**
  
  
  
  1.11      +20 -19    xml-security/src/org/apache/xml/security/transforms/implementations/TransformC14N.java
  
  Index: TransformC14N.java
  ===================================================================
  RCS file: /home/cvs/xml-security/src/org/apache/xml/security/transforms/implementations/TransformC14N.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- TransformC14N.java	20 Sep 2004 21:36:28 -0000	1.10
  +++ TransformC14N.java	23 Sep 2004 20:23:19 -0000	1.11
  @@ -19,17 +19,16 @@
   
   
   import java.io.IOException;
  +import java.io.OutputStream;
   import java.util.Set;
   
   import javax.xml.parsers.ParserConfigurationException;
   
   import org.apache.xml.security.c14n.CanonicalizationException;
  -import org.apache.xml.security.c14n.InvalidCanonicalizerException;
   import org.apache.xml.security.c14n.implementations.Canonicalizer20010315OmitComments;
   import org.apache.xml.security.signature.XMLSignatureInput;
   import org.apache.xml.security.transforms.TransformSpi;
   import org.apache.xml.security.transforms.Transforms;
  -import org.apache.xml.security.utils.XMLUtils;
   import org.w3c.dom.Node;
   import org.xml.sax.SAXException;
   
  @@ -47,39 +46,37 @@
         Transforms.TRANSFORM_C14N_OMIT_COMMENTS;
   
      //J-
  +   /** @inheritDoc */
      public boolean wantsOctetStream ()   { return true; }
  +   /** @inheritDoc */
      public boolean wantsNodeSet ()       { return true; }
  +   /** @inheritDoc */
      public boolean returnsOctetStream () { return true; }
  +   /** @inheritDoc */
      public boolean returnsNodeSet ()     { return false; }
      //J+
   
      /**
  -    * Method engineGetURI
  -    *
  -    *
  +    * @inheritDoc 
       */
      protected String engineGetURI() {
         return TransformC14N.implementedTransformURI;
      }
   
      /**
  -    * Method enginePerformTransform
  -    *
  -    * @param input
  -    *
  -    * @throws CanonicalizationException
  -    * @throws IOException
  -    * @throws InvalidCanonicalizerException
  -    * @throws ParserConfigurationException
  -    * @throws SAXException
  +    *  @inheritDoc 
       */
      protected XMLSignatureInput enginePerformTransform(XMLSignatureInput input)
  -           throws IOException, CanonicalizationException,
  -                  InvalidCanonicalizerException, ParserConfigurationException,
  -                  SAXException {
  -
  +           throws IOException, CanonicalizationException {
  +   	    return enginePerformTransform(input,null);
  +   }
  +    protected XMLSignatureInput enginePerformTransform(XMLSignatureInput input,OutputStream os)
  +    throws IOException, CanonicalizationException {
         try {
            Canonicalizer20010315OmitComments c14n = new Canonicalizer20010315OmitComments();
  +         if (os!=null) {
  +         	c14n.setWriter(os);
  +         }
            byte[] result = null;
            if (input.isOctetStream()) {
               result = c14n.engineCanonicalize(input.getBytes());
  @@ -92,7 +89,11 @@
            		result = c14n.engineCanonicalizeXPathNodeSet(set);
               }
            }
  -         return new XMLSignatureInput(result);
  +         XMLSignatureInput output=new XMLSignatureInput(result);
  +         if (os!=null) {
  +            output.setOutputStream(os);
  +         }
  +         return output;
         } catch (ParserConfigurationException ex) {
            Object[] exArgs = { ex.getMessage() };
            CanonicalizationException cex = new CanonicalizationException(
  
  
  
  1.15      +220 -56   xml-security/src/org/apache/xml/security/utils/Base64.java
  
  Index: Base64.java
  ===================================================================
  RCS file: /home/cvs/xml-security/src/org/apache/xml/security/utils/Base64.java,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- Base64.java	3 Aug 2004 18:01:21 -0000	1.14
  +++ Base64.java	23 Sep 2004 20:23:19 -0000	1.15
  @@ -21,9 +21,10 @@
   import java.io.BufferedReader;
   import java.io.ByteArrayOutputStream;
   import java.io.IOException;
  +import java.io.InputStream;
  +import java.io.OutputStream;
   import java.io.StringReader;
   import java.math.BigInteger;
  -import java.util.Arrays;
   
   import javax.xml.parsers.DocumentBuilder;
   import javax.xml.parsers.DocumentBuilderFactory;
  @@ -271,13 +272,8 @@
       * @throws Base64DecodingException
       *
       */
  -   public static byte[] decode(byte[] base64) throws Base64DecodingException  {
  -   	    int length=base64.length;
  -        char []a=new char[length];
  -        for (int i=0;i<length;i++) {
  -             a[i]=(char)base64[i];
  -        }
  -         return decode(a);
  +   public static byte[] decode(byte[] base64) throws Base64DecodingException  {   	   
  +         return decodeInternal(base64);
      }
   
   
  @@ -384,15 +380,15 @@
   
      }
   
  -   protected static boolean isWhiteSpace(char octect) {
  +   protected static final boolean isWhiteSpace(byte octect) {
          return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9);
      }
   
  -   protected static boolean isPad(char octect) {
  +   protected static final boolean isPad(byte octect) {
          return (octect == PAD);
      }
   
  -   protected static boolean isData(char octect) {
  +   protected static final boolean isData(byte octect) {
          return (base64Alphabet[octect] != -1);
      }
   
  @@ -550,10 +546,9 @@
          if (encoded == null)
              return null;
   
  -       char[] base64Data = encoded.toCharArray();
  -       return decode(base64Data);
  +       return decodeInternal(encoded.getBytes());
      }
  -   protected final static byte[] decode(char[] base64Data) throws Base64DecodingException {
  +   protected final static byte[] decodeInternal(byte[] base64Data) throws Base64DecodingException {
          // remove white spaces
          int len = removeWhiteSpace(base64Data);
          
  @@ -569,13 +564,55 @@
   
          byte     decodedData[]      = null;
          byte     b1=0,b2=0,b3=0, b4=0;
  -       char     d1=0,d2=0,d3=0,d4=0;
  +       byte     d1=0,d2=0,d3=0,d4=0;
   
          int i = 0;
          int encodedIndex = 0;
          int dataIndex    = 0;
  -       decodedData      = new byte[ (numberQuadruple)*3];
  +       
  +       //decodedData      = new byte[ (numberQuadruple)*3];
  +       dataIndex=(numberQuadruple-1)*4;
  +       encodedIndex=(numberQuadruple-1)*3;
  +       //first last bits.
  +       if (!isData( (d1 = base64Data[dataIndex++]) ) ||
  +            !isData( (d2 = base64Data[dataIndex++]) )) {
  +                throw new Base64DecodingException("Error while decoding");//if found "no data" just return null
  +        }
  +
  +        b1 = base64Alphabet[d1];
  +        b2 = base64Alphabet[d2];
   
  +        d3 = base64Data[dataIndex++];
  +        d4 = base64Data[dataIndex++];
  +        if (!isData( (d3 ) ) ||
  +            !isData( (d4 ) )) {//Check if they are PAD characters
  +            if (isPad( d3 ) && isPad( d4)) {               //Two PAD e.g. 3c[Pad][Pad]
  +                if ((b2 & 0xf) != 0)//last 4 bits should be zero
  +                        throw new Base64DecodingException("Error while decoding");
  +                decodedData = new byte[ encodedIndex + 1 ];                
  +                decodedData[encodedIndex]   = (byte)(  b1 <<2 | b2>>4 ) ;                
  +            } else if (!isPad( d3) && isPad(d4)) {               //One PAD  e.g. 3cQ[Pad]
  +                b3 = base64Alphabet[ d3 ];
  +                if ((b3 & 0x3 ) != 0)//last 2 bits should be zero
  +                        throw new Base64DecodingException("Error while decoding");
  +                decodedData = new byte[ encodedIndex + 2 ];                
  +                decodedData[encodedIndex++] = (byte)(  b1 <<2 | b2>>4 );
  +                decodedData[encodedIndex]   = (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) );                
  +            } else {
  +                throw new Base64DecodingException("Error while decoding");//an error  like "3c[Pad]r", "3cdX", "3cXd", "3cXX" where X is non data
  +            }
  +        } else {
  +            //No PAD e.g 3cQl
  +            decodedData = new byte[encodedIndex+3];
  +            b3 = base64Alphabet[ d3 ];
  +            b4 = base64Alphabet[ d4 ];
  +            decodedData[encodedIndex++] = (byte)(  b1 <<2 | b2>>4 ) ;
  +            decodedData[encodedIndex++] = (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) );
  +            decodedData[encodedIndex++] = (byte)( b3<<6 | b4 );
  +        }
  +        encodedIndex=0;
  +        dataIndex=0;
  +       //the begin
          for (; i<numberQuadruple-1; i++) {
   
              if (!isData( (d1 = base64Data[dataIndex++]) )||
  @@ -592,58 +629,185 @@
              decodedData[encodedIndex++] = (byte)(  b1 <<2 | b2>>4 ) ;
              decodedData[encodedIndex++] = (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) );
              decodedData[encodedIndex++] = (byte)( b3<<6 | b4 );
  -       }
  +       }            
  +       return decodedData;
  +   }
  +   
  +   /**
  +    * Decodes Base64 data into  outputstream
  +    *
  +    * @param base64Data Byte array containing Base64 data
  +    * @param os the outputstream
  +    * @throws IOException
  +    * @throws Base64DecodingException
  +    */
  +   public final static void decode(byte[] base64Data,
  +        OutputStream os) throws Base64DecodingException, IOException {
  +    // remove white spaces
  +    int len = removeWhiteSpace(base64Data);
  +    
  +    if (len%FOURBYTE != 0) {
  +        throw new Base64DecodingException("It should be dived by four");
  +        //should be divisible by four
  +    }
   
  -       if (!isData( (d1 = base64Data[dataIndex++]) ) ||
  -           !isData( (d2 = base64Data[dataIndex++]) )) {
  -       	    throw new Base64DecodingException("Error while decoding");//if found "no data" just return null
  -       }
  +    int      numberQuadruple    = (len/FOURBYTE );
   
  -       b1 = base64Alphabet[d1];
  -       b2 = base64Alphabet[d2];
  +    if (numberQuadruple == 0)
  +        return;
   
  -       d3 = base64Data[dataIndex++];
  -       d4 = base64Data[dataIndex++];
  -       if (!isData( (d3 ) ) ||
  -           !isData( (d4 ) )) {//Check if they are PAD characters
  -           if (isPad( d3 ) && isPad( d4)) {               //Two PAD e.g. 3c[Pad][Pad]
  -               if ((b2 & 0xf) != 0)//last 4 bits should be zero
  -               	    throw new Base64DecodingException("Error while decoding");
  -               byte[] tmp = new byte[ i*3 + 1 ];
  -               System.arraycopy( decodedData, 0, tmp, 0, i*3 );
  -               tmp[encodedIndex]   = (byte)(  b1 <<2 | b2>>4 ) ;
  -               return tmp;
  -           } else if (!isPad( d3) && isPad(d4)) {               //One PAD  e.g. 3cQ[Pad]
  -               b3 = base64Alphabet[ d3 ];
  -               if ((b3 & 0x3 ) != 0)//last 2 bits should be zero
  -               	    throw new Base64DecodingException("Error while decoding");
  -               byte[] tmp = new byte[ i*3 + 2 ];
  -               System.arraycopy( decodedData, 0, tmp, 0, i*3 );
  -               tmp[encodedIndex++] = (byte)(  b1 <<2 | b2>>4 );
  -               tmp[encodedIndex]   = (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) );
  -               return tmp;
  -           } else {
  -               throw new Base64DecodingException("Error while decoding");//an error  like "3c[Pad]r", "3cdX", "3cXd", "3cXX" where X is non data
  -           }
  -       } //No PAD e.g 3cQl
  -           b3 = base64Alphabet[ d3 ];
  -           b4 = base64Alphabet[ d4 ];
  -           decodedData[encodedIndex++] = (byte)(  b1 <<2 | b2>>4 ) ;
  -           decodedData[encodedIndex++] = (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) );
  -           decodedData[encodedIndex++] = (byte)( b3<<6 | b4 );
  +    //byte     decodedData[]      = null;
  +    byte     b1=0,b2=0,b3=0, b4=0;
  +    byte     d1=0,d2=0,d3=0,d4=0;
   
  -       
  +    int i = 0;
   
  -       return decodedData;
  +    int dataIndex    = 0;    
  +    
  +    //the begin
  +    for (; i<numberQuadruple-1; i++) {
  +
  +        if (!isData( (d1 = base64Data[dataIndex++]) )||
  +            !isData( (d2 = base64Data[dataIndex++]) )||
  +            !isData( (d3 = base64Data[dataIndex++]) )||
  +            !isData( (d4 = base64Data[dataIndex++]) ))
  +         throw new Base64DecodingException("Error while decoding");//if found "no data" just return null
  +
  +        b1 = base64Alphabet[d1];
  +        b2 = base64Alphabet[d2];
  +        b3 = base64Alphabet[d3];
  +        b4 = base64Alphabet[d4];
  +
  +        os.write((byte)(  b1 <<2 | b2>>4 ) );
  +        os.write((byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) ));
  +        os.write( (byte)( b3<<6 | b4 ));
  +    }       
  +//  first last bits.
  +    if (!isData( (d1 = base64Data[dataIndex++]) ) ||
  +         !isData( (d2 = base64Data[dataIndex++]) )) {
  +             throw new Base64DecodingException("Error while decoding");//if found "no data" just return null
  +     }
  +
  +     b1 = base64Alphabet[d1];
  +     b2 = base64Alphabet[d2];
  +
  +     d3 = base64Data[dataIndex++];
  +     d4 = base64Data[dataIndex++];
  +     if (!isData( (d3 ) ) ||
  +         !isData( (d4 ) )) {//Check if they are PAD characters
  +         if (isPad( d3 ) && isPad( d4)) {               //Two PAD e.g. 3c[Pad][Pad]
  +             if ((b2 & 0xf) != 0)//last 4 bits should be zero
  +                     throw new Base64DecodingException("Error while decoding");                             
  +             os.write( (byte)(  b1 <<2 | b2>>4 ) );                
  +         } else if (!isPad( d3) && isPad(d4)) {               //One PAD  e.g. 3cQ[Pad]
  +             b3 = base64Alphabet[ d3 ];
  +             if ((b3 & 0x3 ) != 0)//last 2 bits should be zero
  +                     throw new Base64DecodingException("Error while decoding");                            
  +             os.write( (byte)(  b1 <<2 | b2>>4 ));
  +             os.write( (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) ));                
  +         } else {
  +             throw new Base64DecodingException("Error while decoding");//an error  like "3c[Pad]r", "3cdX", "3cXd", "3cXX" where X is non data
  +         }
  +     } else {
  +         //No PAD e.g 3cQl         
  +         b3 = base64Alphabet[ d3 ];
  +         b4 = base64Alphabet[ d4 ];
  +         os.write((byte)(  b1 <<2 | b2>>4 ) );
  +         os.write( (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) ));
  +         os.write((byte)( b3<<6 | b4 ));
  +     }
  +    return ;
      }
  +   
  +   /**
  +    * Decodes Base64 data into  outputstream
  +    *
  +    * @param is containing Base64 data
  +    * @param os the outputstream
  +    * @throws IOException
  +    * @throws Base64DecodingException
  +    */
  +   public final static void decode(InputStream is,
  +        OutputStream os) throws Base64DecodingException, IOException {
  +    // remove white spaces
  +
   
  +
  +    //byte     decodedData[]      = null;
  +    byte     b1=0,b2=0,b3=0, b4=0;    
  +
  +    int index=0;
  +    byte []data=new byte[4];
  +    int read;
  +    //the begin
  +    while ((read=is.read())>0) {
  +        byte readed=(byte)read;
  +    	if (isWhiteSpace(readed)) {
  +    		continue;
  +        }
  +        if (isPad(readed)) {
  +            data[index++]=readed;
  +            if (index==3)
  +                data[index++]=(byte)is.read();
  +            break;   
  +        }
  +        if (!isData(readed)) {
  +         throw new Base64DecodingException("Error while decoding");//if found "no data" just return null
  +        } 
  +        
  +        data[index++]=readed;
  +        
  +        if (index!=4) {
  +        	continue;
  +        }
  +        index=0;
  +        b1 = base64Alphabet[data[0]];
  +        b2 = base64Alphabet[data[1]];
  +        b3 = base64Alphabet[data[2]];
  +        b4 = base64Alphabet[data[3]];
  +
  +        os.write((byte)(  b1 <<2 | b2>>4 ) );
  +        os.write((byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) ));
  +        os.write( (byte)( b3<<6 | b4 ));
  +    }       
  +    
  +
  +    byte     d1=data[0],d2=data[1],d3=data[2], d4=data[3];
  +    b1 = base64Alphabet[d1];
  +    b2 = base64Alphabet[d2];
  +     if (!isData( (d3 ) ) ||
  +         !isData( (d4 ) )) {//Check if they are PAD characters
  +         if (isPad( d3 ) && isPad( d4)) {               //Two PAD e.g. 3c[Pad][Pad]
  +             if ((b2 & 0xf) != 0)//last 4 bits should be zero
  +                     throw new Base64DecodingException("Error while decoding");                             
  +             os.write( (byte)(  b1 <<2 | b2>>4 ) );                
  +         } else if (!isPad( d3) && isPad(d4)) {               //One PAD  e.g. 3cQ[Pad]
  +             b3 = base64Alphabet[ d3 ];
  +             if ((b3 & 0x3 ) != 0)//last 2 bits should be zero
  +                     throw new Base64DecodingException("Error while decoding");                            
  +             os.write( (byte)(  b1 <<2 | b2>>4 ));
  +             os.write( (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) ));                
  +         } else {
  +             throw new Base64DecodingException("Error while decoding");//an error  like "3c[Pad]r", "3cdX", "3cXd", "3cXX" where X is non data
  +         }
  +     } else {
  +         //No PAD e.g 3cQl         
  +         b3 = base64Alphabet[ d3 ];
  +         b4 = base64Alphabet[ d4 ];
  +         os.write((byte)(  b1 <<2 | b2>>4 ) );
  +         os.write( (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) ));
  +         os.write((byte)( b3<<6 | b4 ));
  +     }
  +    
  +    return ;
  +   }
      /**
       * remove WhiteSpace from MIME containing encoded Base64 data.
       * 
       * @param data  the byte array of base64 data (with WS)
       * @return      the new length
       */
  -   protected static int removeWhiteSpace(char[] data) {
  +   protected static int removeWhiteSpace(byte[] data) {
          if (data == null)
              return 0;
   
  @@ -651,7 +815,7 @@
          int newSize = 0;
          int len = data.length;
          for (int i = 0; i < len; i++) {
  -           char dataS=data[i];
  +           byte dataS=data[i];
              if (!isWhiteSpace(dataS))
                  data[newSize++] = dataS;
          }
  
  
  
  1.43      +6 -8      xml-security/src/org/apache/xml/security/utils/XMLUtils.java
  
  Index: XMLUtils.java
  ===================================================================
  RCS file: /home/cvs/xml-security/src/org/apache/xml/security/utils/XMLUtils.java,v
  retrieving revision 1.42
  retrieving revision 1.43
  diff -u -r1.42 -r1.43
  --- XMLUtils.java	20 Sep 2004 21:37:33 -0000	1.42
  +++ XMLUtils.java	23 Sep 2004 20:23:19 -0000	1.43
  @@ -64,7 +64,8 @@
      /**
       * @param rootNode
       * @param result
  -    * @return
  +    * @param exclude
  +    * @param com wheather comments or not
       */   
      public static void getSet(Node rootNode,Set result,Node exclude ,boolean com) {
      	  if ((exclude!=null) && isDescendantOrSelf(exclude,rootNode)){
  @@ -313,9 +314,8 @@
   
         if (classLoader == null) {
            return Class.forName(className);
  -      } else {
  -         return classLoader.loadClass(className);
  -      }
  +      } 
  +       return classLoader.loadClass(className);      
      }
   
      /**
  @@ -323,10 +323,8 @@
       * For JDK 1.2 and later use the context ClassLoader.
       * Copied from javax.xml.*.FactoryFinder
       * @return the appropriate ClassLoader
  -    * @throws ClassNotFoundException
       */
  -   protected static ClassLoader findClassLoader()
  -           throws ClassNotFoundException {
  +   protected static ClassLoader findClassLoader() {
   
         Method m = null;
   
  @@ -856,7 +854,7 @@
       * @return
       */
       public static Element[] selectNodes(Node sibling,String uri,String nodeName) {
  -    	int size=10;
  +    	int size=20;
       	Element[] a= new Element[size];
       	int curr=0;
       	//List list=new ArrayList();
  
  
  
  1.1                  xml-security/src/org/apache/xml/security/utils/SignerOutputStream.java
  
  Index: SignerOutputStream.java
  ===================================================================
  /*
   * Copyright  1999-2004 The Apache Software Foundation.
   *
   *  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.
   *
   */
  package org.apache.xml.security.utils;
  
  import java.io.ByteArrayOutputStream;
  
  import org.apache.xml.security.algorithms.SignatureAlgorithm;
  import org.apache.xml.security.signature.XMLSignatureException;
  
  /**
   * @author raul
   *
   */
  public class SignerOutputStream extends ByteArrayOutputStream {
      final static byte none[]="error".getBytes();
      final SignatureAlgorithm sa;
      /**
       * @param sa
       */
      public SignerOutputStream(SignatureAlgorithm sa) {
          this.sa=sa;       
      }
  
      /** @inheritDoc */
      public byte[] toByteArray() {
          // TODO Auto-generated method stub
          return none;
      }
      
      /** @inheritDoc */
      public void write(byte[] arg0)  {
          try {
  			sa.update(arg0);
  		} catch (XMLSignatureException e) {
              throw new RuntimeException(e);
  		}
      }
      
      /** @inheritDoc */
      public void write(int arg0) {
          try {
              sa.update((byte)arg0);
          } catch (XMLSignatureException e) {
              throw new RuntimeException(e);
          }
      }
      
      /** @inheritDoc */
      public void write(byte[] arg0, int arg1, int arg2) {
          // TODO Auto-generated method stub
          try {
              sa.update(arg0,arg1,arg2);
          } catch (XMLSignatureException e) {
              throw new RuntimeException(e);
          }
      }
      
  
  }
  
  
  
  1.1                  xml-security/src/org/apache/xml/security/utils/DigesterOutputStream.java
  
  Index: DigesterOutputStream.java
  ===================================================================
  /*
   * Copyright  1999-2004 The Apache Software Foundation.
   *
   *  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.
   *
   */
  package org.apache.xml.security.utils;
  
  import java.io.ByteArrayOutputStream;
  
  import org.apache.xml.security.algorithms.MessageDigestAlgorithm;
  
  /**
   * @author raul
   *
   */
  public class DigesterOutputStream extends ByteArrayOutputStream {
      final static byte none[]="error".getBytes();
      final MessageDigestAlgorithm mda;
  	/**
  	 * @param mda
  	 */
  	public DigesterOutputStream(MessageDigestAlgorithm mda) {
          this.mda=mda;		
  	}
  
      /** @inheritDoc */ 
  	public byte[] toByteArray() {
  		// TODO Auto-generated method stub
  		return none;
  	}
      
  	/** @inheritDoc */
  	public void write(byte[] arg0) {
  		// TODO Auto-generated method stub
  		mda.update(arg0);
  	}
      
      /** @inheritDoc */
  	public void write(int arg0) {
  		mda.update((byte)arg0);
  	}
      
      /** @inheritDoc */
  	public void write(byte[] arg0, int arg1, int arg2) {
  		// TODO Auto-generated method stub
  		mda.update(arg0, arg1, arg2);
  	}
      
      /**
       * @return the digest value 
       */
      public byte[] getDigestValue() {
           return mda.digest();   
      }
  }
  
  
  
  1.17      +22 -2     xml-security/src/org/apache/xml/security/transforms/Transforms.java
  
  Index: Transforms.java
  ===================================================================
  RCS file: /home/cvs/xml-security/src/org/apache/xml/security/transforms/Transforms.java,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- Transforms.java	3 Aug 2004 18:01:21 -0000	1.16
  +++ Transforms.java	23 Sep 2004 20:23:20 -0000	1.17
  @@ -19,6 +19,7 @@
   
   
   import java.io.IOException;
  +import java.io.OutputStream;
   
   import org.apache.xml.security.c14n.CanonicalizationException;
   import org.apache.xml.security.c14n.Canonicalizer;
  @@ -206,14 +207,33 @@
       */
      public XMLSignatureInput performTransforms(
              XMLSignatureInput xmlSignatureInput) throws TransformationException {
  +   	     return performTransforms(xmlSignatureInput,null);
  +   }
  +   
  +   /**
  +    * Applies all included <code>Transform</code>s to xmlSignatureInput and returns the result of these transformations.
  +    *
  +    * @param xmlSignatureInput the input for the <code>Transform</code>s
  +    * @param os where to output the last transformation.
  +    * @return the result of the <code>Transforms</code>
  +    * @throws TransformationException
  +    */
  +    public XMLSignatureInput performTransforms(
  +            XMLSignatureInput xmlSignatureInput,OutputStream os) throws TransformationException {
   
         try {
  -         for (int i = 0; i < this.getLength(); i++) {
  +        int transformLength=this.getLength();
  +        int last=transformLength-1;
  +         for (int i = 0; i < transformLength; i++) {
               Transform t = this.item(i);
               if (log.isDebugEnabled()) {
               	log.debug("Preform the (" + i + ")th " + t.getURI() + " transform");
               }
  -            xmlSignatureInput = t.performTransform(xmlSignatureInput);
  +            if (i==last) {
  +            	xmlSignatureInput = t.performTransform(xmlSignatureInput, os);
  +            } else {
  +            	xmlSignatureInput = t.performTransform(xmlSignatureInput);
  +            }
            }
   
            /*
  
  
  
  1.15      +44 -6     xml-security/src/org/apache/xml/security/transforms/Transform.java
  
  Index: Transform.java
  ===================================================================
  RCS file: /home/cvs/xml-security/src/org/apache/xml/security/transforms/Transform.java,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- Transform.java	12 May 2004 12:00:45 -0000	1.14
  +++ Transform.java	23 Sep 2004 20:23:20 -0000	1.15
  @@ -19,6 +19,7 @@
   
   
   import java.io.IOException;
  +import java.io.OutputStream;
   import java.util.HashMap;
   import java.util.Iterator;
   
  @@ -29,7 +30,6 @@
   import org.apache.xml.security.exceptions.AlgorithmAlreadyRegisteredException;
   import org.apache.xml.security.exceptions.XMLSecurityException;
   import org.apache.xml.security.signature.XMLSignatureInput;
  -import org.apache.xml.security.utils.*;
   import org.apache.xml.security.utils.Constants;
   import org.apache.xml.security.utils.HelperNodeList;
   import org.apache.xml.security.utils.SignatureElementProxy;
  @@ -51,7 +51,6 @@
    * @author Christian Geuer-Pollmann
    * @see Transforms
    * @see TransformSpi
  - * @see Canonicalizer
    *
    */
   public final class Transform extends SignatureElementProxy {
  @@ -73,7 +72,9 @@
       * Constructs {@link Transform}
       *
       * @param doc the {@link Document} in which <code>Transform</code> will be placed
  -    * @param algorithmURI URI representation of <code>Transform algorithm</code> will be specified as parameter of {@link #getInstance}, when generate. </br>
  +    * @param algorithmURI URI representation of 
  +    * <code>Transform algorithm</code> will be specified as parameter of 
  +    * {@link #getInstance(Document, String)}, when generate. </br>
       * @param contextNodes the child node list of <code>Transform</code> element
       * @throws InvalidTransformException
       */
  @@ -246,7 +247,8 @@
      /**
       * Registers implementing class of the Transform algorithm with algorithmURI
       *
  -    * @param algorithmURI algorithmURI URI representation of <code>Transform algorithm</code> will be specified as parameter of {@link #getInstance}, when generate. </br>
  +    * @param algorithmURI algorithmURI URI representation of <code>Transform algorithm</code>
  +    *  will be specified as parameter of {@link #getInstance(Document, String)}, when generate. </br>
       * @param implementingClass <code>implementingClass</code> the implementing class of {@link TransformSpi}
       * @throws AlgorithmAlreadyRegisteredException if specified algorithmURI is already registered
       */
  @@ -280,8 +282,8 @@
   
      /**
       * Transforms the input, and generats {@link XMLSignatureInput} as output.
  -    *
       * @param input input {@link XMLSignatureInput} which can supplied Octect Stream and NodeSet as Input of Transformation
  +    *
       * @return the {@link XMLSignatureInput} class as the result of transformation
       * @throws CanonicalizationException
       * @throws IOException
  @@ -310,12 +312,46 @@
   
         return result;
      }
  +   
  +   /**
  +    * Transforms the input, and generats {@link XMLSignatureInput} as output.
  +    * @param input input {@link XMLSignatureInput} which can supplied Octect Stream and NodeSet as Input of Transformation
  +    * @param os where to output the result of the last transformation
  +    *
  +    * @return the {@link XMLSignatureInput} class as the result of transformation
  +    * @throws CanonicalizationException
  +    * @throws IOException
  +    * @throws InvalidCanonicalizerException
  +    * @throws TransformationException
  +    */
  +   public XMLSignatureInput performTransform(XMLSignatureInput input, OutputStream os)
  +   throws IOException, CanonicalizationException,
  +          InvalidCanonicalizerException, TransformationException {
  +
  +   	    XMLSignatureInput result = null;
  +
  +   	    try {
  +   	    	result = transformSpi.enginePerformTransform(input,os);
  +   	    } catch (ParserConfigurationException ex) {
  +   	    	Object exArgs[] = { this.getURI(), "ParserConfigurationException" };
  +
  +   	    	throw new CanonicalizationException(
  +   	    			"signature.Transform.ErrorDuringTransform", exArgs, ex);
  +   	    } catch (SAXException ex) {
  +   	    	Object exArgs[] = { this.getURI(), "SAXException" };
  +
  +   	    	throw new CanonicalizationException(
  +   	    			"signature.Transform.ErrorDuringTransform", exArgs, ex);
  +   	    }
  +
  +   	    return result;
  +   }
   
      /**
       * Method getImplementingClass
       *
       * @param URI
  -    *
  +    * @return The name of the class implementing the URI.
       */
      private static String getImplementingClass(String URI) {
   
  @@ -334,6 +370,8 @@
         return null;
      }
   
  +   
  +   /** @inheritDoc */
      public String getBaseLocalName() {
         return Constants._TAG_TRANSFORM;
      }
  
  
  
  1.6       +23 -2     xml-security/src/org/apache/xml/security/transforms/TransformSpi.java
  
  Index: TransformSpi.java
  ===================================================================
  RCS file: /home/cvs/xml-security/src/org/apache/xml/security/transforms/TransformSpi.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- TransformSpi.java	8 Feb 2004 06:11:35 -0000	1.5
  +++ TransformSpi.java	23 Sep 2004 20:23:20 -0000	1.6
  @@ -20,6 +20,7 @@
   
   
   import java.io.IOException;
  +import java.io.OutputStream;
   
   import javax.xml.parsers.ParserConfigurationException;
   
  @@ -31,7 +32,7 @@
   
   /**
    * Base class which all Transform algorithms extend. The common methods that
  - * have to be overridden are the {@link #enginePerformTransform} method.
  + * have to be overridden are the {@link #enginePerformTransform(XMLSignatureInput)} method.
    *
    * @author Christian Geuer-Pollmann
    */
  @@ -77,11 +78,31 @@
       * The mega method which MUST be implemented by the Transformation Algorithm.
       *
       * @param input {@link XMLSignatureInput} as the input of transformation
  +    * @param os where to output this transformation.
  +    * @return {@link XMLSignatureInput} as the result of transformation
  +    * @throws CanonicalizationException
  +    * @throws IOException
  +    * @throws InvalidCanonicalizerException
  +    * @throws ParserConfigurationException
  +    * @throws SAXException
  +    * @throws TransformationException
  +    */
  +   protected XMLSignatureInput enginePerformTransform(
  +      XMLSignatureInput input, OutputStream os)
  +         throws IOException,
  +                CanonicalizationException, InvalidCanonicalizerException,
  +                TransformationException, ParserConfigurationException,
  +                SAXException {
  +   	    return enginePerformTransform(input);
  +   }
  +   /**
  +    * The mega method which MUST be implemented by the Transformation Algorithm.
  +    *
  +    * @param input {@link XMLSignatureInput} as the input of transformation
       * @return {@link XMLSignatureInput} as the result of transformation
       * @throws CanonicalizationException
       * @throws IOException
       * @throws InvalidCanonicalizerException
  -    * @throws NotYetImplementedException
       * @throws ParserConfigurationException
       * @throws SAXException
       * @throws TransformationException
  
  
  
  1.6       +0 -4      xml-security/src/org/apache/xml/security/encryption/XMLCipherInput.java
  
  Index: XMLCipherInput.java
  ===================================================================
  RCS file: /home/cvs/xml-security/src/org/apache/xml/security/encryption/XMLCipherInput.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- XMLCipherInput.java	3 Aug 2004 18:01:21 -0000	1.5
  +++ XMLCipherInput.java	23 Sep 2004 20:23:20 -0000	1.6
  @@ -20,12 +20,10 @@
   import java.io.IOException;
   
   import org.apache.xml.security.c14n.CanonicalizationException;
  -import org.apache.xml.security.c14n.InvalidCanonicalizerException;
   import org.apache.xml.security.utils.resolver.ResourceResolver;
   import org.apache.xml.security.utils.resolver.ResourceResolverException;
   import org.apache.xml.security.exceptions.Base64DecodingException;
   import org.apache.xml.security.signature.XMLSignatureInput;
  -import org.apache.xml.security.exceptions.XMLSecurityException;
   import org.apache.xml.security.transforms.TransformationException;
   import org.w3c.dom.Attr;
   import org.apache.xml.security.utils.Base64;
  @@ -159,8 +157,6 @@
   				return input.getBytes();
   			}
   			catch (IOException ex) {
  -				throw new XMLEncryptionException("empty", ex);
  -			} catch (InvalidCanonicalizerException ex) {
   				throw new XMLEncryptionException("empty", ex);
   			} catch (CanonicalizationException ex) {
   				throw new XMLEncryptionException("empty", ex);
  
  
  
  1.9       +22 -7     xml-security/src_unitTests/org/apache/xml/security/test/utils/Base64Test.java
  
  Index: Base64Test.java
  ===================================================================
  RCS file: /home/cvs/xml-security/src_unitTests/org/apache/xml/security/test/utils/Base64Test.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- Base64Test.java	21 Feb 2004 02:06:40 -0000	1.8
  +++ Base64Test.java	23 Sep 2004 20:23:20 -0000	1.9
  @@ -19,11 +19,12 @@
   
   
   
  +import java.io.ByteArrayOutputStream;
  +
   import junit.framework.Test;
   import junit.framework.TestCase;
   import junit.framework.TestSuite;
   
  -import org.apache.xml.security.exceptions.Base64DecodingException;
   import org.apache.xml.security.utils.Base64;
   
   
  @@ -40,8 +41,8 @@
   
      /**
       * Method suite
  -    *
  -    *
  +    * @return
  +    *    
       */
      public static Test suite() {
         return new TestSuite(Base64Test.class);
  @@ -70,11 +71,12 @@
   
      /**
       * Method testA1
  +    * @throws Exception
       *
       * @throws java.io.UnsupportedEncodingException
       * $todo$ Extend more tests
       */
  -   public static void testA1() throws java.io.UnsupportedEncodingException, Base64DecodingException {
  +   public static void testA1() throws Exception {
   
         String textData = "Hallo";
         String result0 = Base64.encode(textData.getBytes("UTF-8"));
  @@ -85,6 +87,10 @@
         String resultStr = new String(resultBytes, "UTF-8");
   
         assertEquals("Result of decoding", 0, textData.compareTo(resultStr));
  +      ByteArrayOutputStream os=new ByteArrayOutputStream();
  +      Base64.decode(result0.getBytes(),os);
  +      resultStr = new String(os.toByteArray(), "UTF-8");
  +      assertEquals("Result of decoding", 0, textData.compareTo(resultStr));
      }
   
      /**
  @@ -93,10 +99,11 @@
   	* Test for correct line wrapping at end of an exactly 76 char string
   	*
       * @throws java.io.UnsupportedEncodingException
  +    * @throws Exception
       */
   
   	public static void testWrap1() 
  -		throws java.io.UnsupportedEncodingException, Base64DecodingException {
  +		throws java.io.UnsupportedEncodingException,Exception {
   
   		String inputData = "The quick brown fox jumps over the lazy dog and some extr";
   		String expectedResult = "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZyBhbmQgc29tZSBleHRy";
  @@ -105,6 +112,10 @@
   
   		String result2 = new String(Base64.decode(result), "UTF-8");
   		assertEquals("Result of encoding", result2, inputData);
  +        ByteArrayOutputStream os=new ByteArrayOutputStream();
  +        Base64.decode(expectedResult.getBytes(),os);
  +          result2 = new String(os.toByteArray(), "UTF-8");
  +          assertEquals("Result of encoding", result2, inputData);
   
   	}
   
  @@ -114,10 +125,11 @@
   	* Test for correct line wrapping after more than 76 characters
   	*
       * @throws java.io.UnsupportedEncodingException
  +    * @throws Exception
       */
   
   	public static void testWrap2() 
  -		throws java.io.UnsupportedEncodingException, Base64DecodingException {
  +		throws java.io.UnsupportedEncodingException, Exception {
   
   		String inputData = "The quick brown fox jumps over the lazy dog and some extra text that will cause a line wrap";
   		String expectedResult = "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZyBhbmQgc29tZSBleHRy\nYSB0ZXh0IHRoYXQgd2lsbCBjYXVzZSBhIGxpbmUgd3JhcA==";
  @@ -126,7 +138,10 @@
   
   		String result2 = new String(Base64.decode(result), "UTF-8");
   		assertEquals("Result of encoding", result2, inputData);
  -
  +        ByteArrayOutputStream os=new ByteArrayOutputStream();
  +        Base64.decode(expectedResult.getBytes(),os);
  +          result2 = new String(os.toByteArray(), "UTF-8");
  +          assertEquals("Result of encoding", result2, inputData);
   	}
   
      static {
  
  
  
  1.7       +6 -12     xml-security/src_samples/org/apache/xml/security/samples/MyResolver.java
  
  Index: MyResolver.java
  ===================================================================
  RCS file: /home/cvs/xml-security/src_samples/org/apache/xml/security/samples/MyResolver.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- MyResolver.java	8 Feb 2004 06:08:41 -0000	1.6
  +++ MyResolver.java	23 Sep 2004 20:23:20 -0000	1.7
  @@ -19,10 +19,8 @@
   
   
   import java.io.ByteArrayInputStream;
  -import java.io.IOException;
   
   import org.apache.xml.security.signature.XMLSignatureInput;
  -import org.apache.xml.security.utils.resolver.ResourceResolverException;
   import org.apache.xml.security.utils.resolver.ResourceResolverSpi;
   import org.w3c.dom.Attr;
   
  @@ -36,28 +34,24 @@
   
      /**
       * Method engineResolve
  -    *
  +    * @inheritDoc
       * @param uri
       * @param BaseURI
       *
  -    * @throws ResourceResolverException
       */
  -   public XMLSignatureInput engineResolve(Attr uri, String BaseURI)
  -           throws ResourceResolverException {
  +   public XMLSignatureInput engineResolve(Attr uri, String BaseURI) {
  +
   
  -      try {
            ByteArrayInputStream is =
               new ByteArrayInputStream("string".getBytes());
   
            return new XMLSignatureInput(is);
  -      } catch (IOException ex) {
  -         throw new ResourceResolverException("empty", ex, uri, BaseURI);
  -      }
  +      
      }
   
      /**
       * Method engineCanResolve
  -    *
  +    * @inheritDoc
       * @param uri
       * @param BaseURI
       *
  
  
  
  1.9       +10 -0     xml-security/src/org/apache/xml/security/c14n/Canonicalizer.java
  
  Index: Canonicalizer.java
  ===================================================================
  RCS file: /home/cvs/xml-security/src/org/apache/xml/security/c14n/Canonicalizer.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- Canonicalizer.java	3 Aug 2004 18:01:23 -0000	1.8
  +++ Canonicalizer.java	23 Sep 2004 20:23:20 -0000	1.9
  @@ -19,6 +19,7 @@
   
   
   import java.io.ByteArrayInputStream;
  +import java.io.OutputStream;
   import java.util.HashMap;
   import java.util.Iterator;
   import java.util.Map;
  @@ -305,6 +306,15 @@
                 throws CanonicalizationException {
         return this.canonicalizerSpi.engineCanonicalizeXPathNodeSet(xpathNodeSet,
                 inclusiveNamespaces);
  +   }
  +   
  +   /**
  +    * Sets the writter where the cannocalization ends. ByteArrayOutputStream if 
  +    * none is setted.
  +    * @param os
  +    */
  +   public void setWriter(OutputStream os) {
  +   	    this.canonicalizerSpi.setWriter(os);
      }
   
      /**
  
  
  
  1.10      +57 -5     xml-security/src/org/apache/xml/security/c14n/CanonicalizerSpi.java
  
  Index: CanonicalizerSpi.java
  ===================================================================
  RCS file: /home/cvs/xml-security/src/org/apache/xml/security/c14n/CanonicalizerSpi.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- CanonicalizerSpi.java	8 Feb 2004 06:10:12 -0000	1.9
  +++ CanonicalizerSpi.java	23 Sep 2004 20:23:20 -0000	1.10
  @@ -19,6 +19,7 @@
   
   
   import java.io.ByteArrayInputStream;
  +import java.io.OutputStream;
   import java.util.Set;
   
   import javax.xml.parsers.DocumentBuilder;
  @@ -44,7 +45,7 @@
       *
       *
       * @param inputBytes
  -    *
  +    * @return the c14n bytes. 
       *
       *
       * @throws CanonicalizationException
  @@ -102,7 +103,7 @@
       * Method engineCanonicalizeXPathNodeSet
       *
       * @param xpathNodeSet
  -    *
  +    * @return the c14n bytes
       * @throws CanonicalizationException
       */
      public byte[] engineCanonicalizeXPathNodeSet(NodeList xpathNodeSet)
  @@ -112,7 +113,15 @@
            .engineCanonicalizeXPathNodeSet(XMLUtils
               .convertNodelistToSet(xpathNodeSet));
      }
  -
  +   
  +   /**
  +    * Method engineCanonicalizeXPathNodeSet
  +    *
  +    * @param xpathNodeSet
  +    * @param inclusiveNamespaces
  +    * @return the c14n bytes
  +    * @throws CanonicalizationException
  +    */
      public byte[] engineCanonicalizeXPathNodeSet(NodeList xpathNodeSet, String inclusiveNamespaces)
              throws CanonicalizationException {
   
  @@ -122,20 +131,63 @@
      }
   
      //J-
  +   /** Returns the URI of this engine.
  +    * @return the URI
  +    */
      public abstract String engineGetURI();
  -
  +   
  +   /** Returns the URI if include comments
  +    * @return true if include.
  +    */
      public abstract boolean engineGetIncludeComments();
  -
  +   
  +   /**
  +    * C14n a nodeset
  +    *
  +    * @param xpathNodeSet
  +    * @return the c14n bytes
  +    * @throws CanonicalizationException
  +    */
      public abstract byte[] engineCanonicalizeXPathNodeSet(Set xpathNodeSet)
         throws CanonicalizationException;
   
  +   /**
  +    * C14n a nodeset
  +    *
  +    * @param xpathNodeSet
  +    * @param inclusiveNamespaces
  +    * @return the c14n bytes
  +    * @throws CanonicalizationException
  +    */
      public abstract byte[] engineCanonicalizeXPathNodeSet(Set xpathNodeSet, String inclusiveNamespaces)
         throws CanonicalizationException;
   
  +   /**
  +    * C14n a node tree.
  +    *
  +    * @param rootNode
  +    * @return the c14n bytes
  +    * @throws CanonicalizationException
  +    */
      public abstract byte[] engineCanonicalizeSubTree(Node rootNode)
         throws CanonicalizationException;
   
  +   /**
  +    * C14n a node tree.
  +    *
  +    * @param rootNode
  +    * @param inclusiveNamespaces
  +    * @return the c14n bytes
  +    * @throws CanonicalizationException
  +    */
      public abstract byte[] engineCanonicalizeSubTree(Node rootNode, String inclusiveNamespaces)
         throws CanonicalizationException;
  +   
  +   /**
  +    * Sets the writter where the cannocalization ends. ByteArrayOutputStream if 
  +    * none is setted.
  +    * @param os
  +    */
  +   public abstract void setWriter(OutputStream os);
      //J+
   }
  
  
  
  1.9       +18 -11    xml-security/src/org/apache/xml/security/c14n/implementations/CanonicalizerBase.java
  
  Index: CanonicalizerBase.java
  ===================================================================
  RCS file: /home/cvs/xml-security/src/org/apache/xml/security/c14n/implementations/CanonicalizerBase.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- CanonicalizerBase.java	18 Sep 2004 16:49:44 -0000	1.8
  +++ CanonicalizerBase.java	23 Sep 2004 20:23:20 -0000	1.9
  @@ -22,18 +22,13 @@
   import java.io.IOException;
   import java.io.OutputStream;
   import java.io.UnsupportedEncodingException;
  -import java.nio.ByteOrder;
   import java.util.ArrayList;
   import java.util.Iterator;
   import java.util.List;
   import java.util.ListIterator;
   import java.util.Set;
  -import java.util.TreeSet;
   
  -import javax.xml.parsers.DocumentBuilder;
   import javax.xml.parsers.DocumentBuilderFactory;
  -import javax.xml.parsers.FactoryConfigurationError;
  -import javax.xml.parsers.ParserConfigurationException;
   
   import org.apache.xml.security.c14n.CanonicalizationException;
   import org.apache.xml.security.c14n.CanonicalizerSpi;
  @@ -42,8 +37,6 @@
   import org.apache.xml.security.utils.XMLUtils;
   import org.w3c.dom.Attr;
   import org.w3c.dom.Comment;
  -import org.w3c.dom.DOMException;
  -import org.w3c.dom.Document;
   import org.w3c.dom.Element;
   import org.w3c.dom.NamedNodeMap;
   import org.w3c.dom.Node;
  @@ -97,7 +90,7 @@
       * in subtree canonicalizations.
       */
      Node _excludeNode =null;
  -   final ByteArrayOutputStream _writer = new ByteArrayOutputStream();//null;
  +   OutputStream _writer = new ByteArrayOutputStream();//null;
   
      /**
       * Constructor CanonicalizerBase
  @@ -136,7 +129,11 @@
            }
            this.canonicalizeSubTree(rootNode,ns);
            this._writer.close();
  -         return this._writer.toByteArray();
  +         if (this._writer instanceof ByteArrayOutputStream) {
  +         	return ((ByteArrayOutputStream)this._writer).toByteArray();
  +         } 
  +         return null;
  +         
         } catch (UnsupportedEncodingException ex) {
            throw new CanonicalizationException("empty", ex);
         } catch (IOException ex) {
  @@ -277,7 +274,10 @@
            Node rootNodeOfC14n = XMLUtils.getOwnerDocument(this._xpathNodeSet);
            this.canonicalizeXPathNodeSet(rootNodeOfC14n,new  NameSpaceSymbTable());
            this._writer.close();
  -         return this._writer.toByteArray();
  +         if (this._writer instanceof ByteArrayOutputStream) {
  +         	return ((ByteArrayOutputStream)this._writer).toByteArray();
  +         }
  +         return null;
         } catch (UnsupportedEncodingException ex) {
            throw new CanonicalizationException("empty", ex);
         } catch (IOException ex) {
  @@ -717,5 +717,12 @@
       */
       final public void set_includeComments(boolean comments) {
   	    _includeComments = comments;
  +    }
  +    
  +    /**
  +     * @param _writer The _writer to set.
  +     */
  +    public void setWriter(OutputStream _writer) {
  +    	this._writer = _writer;
       }
   }