You are viewing a plain text version of this content. The canonical link for it is here.
Posted to j-users@xerces.apache.org by mo...@telenor.com on 2002/04/22 20:11:10 UTC

The WrappedOutputStream class and large XML documents

Using the WrappedOutputStream and WrappedInputStream classes (from the samples.socket.io package of Xerces) for the transport of XML documents between a client and a server, we recently became aware of the following problem with the WrappedOutputStream class:

   It is currently only possible to send XML documents
   whose byte[] representation doesn't exceed 65535 bytes
   using the write(byte[] b,int offset,int length) method. 

As I see it, this is caused by a combination of the particular method implementation and the fact that the protocol used by these classes represents the size of each byte[] "packet" by a short, i.e. 16 bits.


There are several ways one can fix/circumvent this problem of course, some of which are:

1) Introduce a loop, and use WrappedOutputStream's write(int b) method instead of the write(byte[] b, int offset, int length) method. The write(int b) method buffers the bytes in an internal byte[] array which is 1024 bytes long (by default), and sends a 1024 byte packet each time the buffer is filled up. 
 
2) One could modify the write(byte[] b, int offset, int length) method so that it chunks the byte[] argument into several smaller pieces, each less than 65535 bytes long, and sends these as separate packets.

3) One could modify the WrappedOutputStream/WrappedInputStream classes so that they use a long (64 bits) instead of a short to represents the size of each byte[] packet.


I tried approach 1) first, replacing

    wrap_os.write(bytes, 0, bytes.length);

by

    for(int i=0; i<bytes.length; i++) {
        wrap_os.write(bytes[i]);
    }

in my code, where wrap_os is a WrappedOutputStream object. This failed, and revealed a bug in the write(int b) method in WrappedOutputStream:

[snippet from WrappedOutputStream.java]

    /** 
     * Writes a single byte to the output. 
     * <p>
     * <strong>Note:</strong> Single bytes written to the output stream
     * will be buffered
     */
    public void write(int b) throws IOException {
        fBuffer[fPosition++] = (byte)b;
        if (fPosition == fBuffer.length) {
            fPosition = 0;
            fDataOutputStream.writeShort(fBuffer.length);  <------- 
            write(fBuffer, 0, fBuffer.length);
        }
    } // write(int)

    /** Writes an array of bytes to the output. */
    public void write(byte[] b, int offset, int length) 
        throws IOException {

        // flush existing buffer
        if (fPosition > 0) {
            flush0();
        }

        // write header followed by actual bytes
        fDataOutputStream.writeShort(length);
        super.out.write(b, offset, length);

    } // write(byte[])



When fBuffer is filled up, the size of the buffer is written as a short onto the DataOutputStream, and then the fBuffer is written using the write(byte[] b, int offset, int length) which also writes the size of the buffer onto the DataOutputStream before writing the actual byte array. This makes the WrappedInputStream object at the receiving end somewhat confused... This is easily fixed by deleting the fDataOutputStream.writeShort(fBuffer.length); line from the write(int b) method.


Anyhow, I guess I will have to do something along the lines of 2) or 3) above, since the WrappedOutputStream class currently doesn't handle large byte[] arrays as it seems. If anyone has experienced/dealt with the same problem, tips and comments are of course greatly appreciated.


--
------------------------------------------------
 Morten Bjørhus
 TBS Communications, Messaging and Mobility
 morten.bjorhus@telenor.com,  tel: +47 41660525
------------------------------------------------


 

---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-j-user-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-j-user-help@xml.apache.org


Re: The WrappedOutputStream class and large XML documents

Posted by Andy Clark <an...@apache.org>.
morten.bjorhus@telenor.com wrote:
>    It is currently only possible to send XML documents
>    whose byte[] representation doesn't exceed 65535 bytes
>    using the write(byte[] b,int offset,int length) method.

Yikes!  I can see from the code that I made a tragic mistake 
in these classes -- I've submitted the fix into CVS.

-- 
Andy Clark * andyc@apache.org

---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-j-user-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-j-user-help@xml.apache.org


Re: How to add this the xsl reference to xml document... --- In a hurry

Posted by Scott Vachalek <sc...@Integrisoft.COM>.
Hi Ragunath,

As a matter of style, I think it's better to use "getDocumentElement()"
rather than "getFirstChild()" because if there are any other PIs or comments
in front, you might get unexpected results.

In this case, though, it looks like it should work.  I have some very
similar code that is working for me now (I'm using version 2.0.0).

Have you tried calling getFirstChild() after the insertion, to see if you
get your PI?  There could be a problem in the document serialization phase
where it's stripping the PI.

Hope this helps,
Scott

----- Original Message -----
From: "Ragunath Marudhachalam" <rm...@circuitvision.com>
To: <xe...@xml.apache.org>
Sent: Monday, April 22, 2002 12:28 PM
Subject: How to add this the xsl reference to xml document... --- In a hurry


> Hello All,
>
> could anyone suggest me how to add these lines(reference to a xsl
> document)in the xml document which i generate dynamically....
>
>
> I'm getting the following xml document, even though i had these code in my
> servlet.
>
>
> ProcessingInstruction pi =
> cvcontext.OutDocument.createProcessingInstruction("xml-stylesheet",
> "href=\"instruction.xsl\" type=\"text/xsl\"");
> cvcontext.OutDocument.insertBefore(pi,
> cvcontext.OutDocument.getFirstChild()); (cvcontext.outDocument is a
Document
> object)
>
> //if i print the document after these lines, i get this xml document.
>
> <?xml version="1.0" encoding="UTF-8"?>
> <cv>
> <status>
> <type>Success</type>
> <statusbar>
> <code>CVM-00871</code><text>Action Completed</text>
> </statusbar>
> </status>
> </cv>
>
>
> but i'm expecting a document like this,
>
>
> <?xml version="1.0" encoding="UTF-8"?>
> <?xml:stylesheet type="text/xsl" href="instruction.xsl" >
> <cv>
> <status>
> <type>Success</type>
> <statusbar>
> <code>CVM-00871</code><text>Action Completed</text>
> </statusbar>
> </status>
> </cv>
>
> Could anyone suggest me what i'm doing wrong. I would appreciate if
someone
> can help me with some sample code.
>
> Ragu
> CircuitVision
>
>


----------------------------------------------------------------------------
----


> ---------------------------------------------------------------------
> To unsubscribe, e-mail: xerces-j-user-unsubscribe@xml.apache.org
> For additional commands, e-mail: xerces-j-user-help@xml.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-j-user-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-j-user-help@xml.apache.org


How to add this the xsl reference to xml document... --- In a hurry

Posted by Ragunath Marudhachalam <rm...@circuitvision.com>.
Hello All,

could anyone suggest me how to add these lines(reference to a xsl
document)in the xml document which i generate dynamically....


I'm getting the following xml document, even though i had these code in my
servlet.


ProcessingInstruction pi =
cvcontext.OutDocument.createProcessingInstruction("xml-stylesheet",
"href=\"instruction.xsl\" type=\"text/xsl\"");
cvcontext.OutDocument.insertBefore(pi,
cvcontext.OutDocument.getFirstChild()); (cvcontext.outDocument is a Document
object)

//if i print the document after these lines, i get this xml document.

<?xml version="1.0" encoding="UTF-8"?>
<cv>
<status>
<type>Success</type>
<statusbar>
	<code>CVM-00871</code><text>Action Completed</text>
</statusbar>
</status>
</cv>


but i'm expecting a document like this,


<?xml version="1.0" encoding="UTF-8"?>
<?xml:stylesheet type="text/xsl" href="instruction.xsl" >
<cv>
<status>
<type>Success</type>
<statusbar>
	<code>CVM-00871</code><text>Action Completed</text>
</statusbar>
</status>
</cv>

Could anyone suggest me what i'm doing wrong. I would appreciate if someone
can help me with some sample code.

Ragu
CircuitVision