Return-Path: Delivered-To: apmail-jakarta-commons-dev-archive@www.apache.org Received: (qmail 81359 invoked from network); 31 Mar 2004 23:55:31 -0000 Received: from daedalus.apache.org (HELO mail.apache.org) (208.185.179.12) by minotaur-2.apache.org with SMTP; 31 Mar 2004 23:55:31 -0000 Received: (qmail 51027 invoked by uid 500); 31 Mar 2004 23:54:58 -0000 Delivered-To: apmail-jakarta-commons-dev-archive@jakarta.apache.org Received: (qmail 50925 invoked by uid 500); 31 Mar 2004 23:54:58 -0000 Mailing-List: contact commons-dev-help@jakarta.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Subscribe: List-Help: List-Post: List-Id: "Jakarta Commons Developers List" Reply-To: "Jakarta Commons Developers List" Delivered-To: mailing list commons-dev@jakarta.apache.org Received: (qmail 50735 invoked from network); 31 Mar 2004 23:54:56 -0000 Received: from unknown (HELO mailao.vtcif.telstra.com.au) (202.12.144.17) by daedalus.apache.org with SMTP; 31 Mar 2004 23:54:56 -0000 Received: from mailai.vtcif.telstra.com.au (mailai.vtcif.telstra.com.au [202.12.142.17]) by mailao.vtcif.telstra.com.au (Postfix) with ESMTP id 2F05D22FE6 for ; Thu, 1 Apr 2004 09:54:43 +1000 (EST) Received: from mail.cdn.telstra.com.au (localhost [127.0.0.1]) by mailai.vtcif.telstra.com.au (Postfix) with ESMTP id 8FE6D22887 for ; Thu, 1 Apr 2004 09:54:42 +1000 (EST) Received: from 353661-bh ([141.168.99.130]) by mail.cdn.telstra.com.au (8.8.2/8.6.9) with ESMTP id JAA27553 for ; Thu, 1 Apr 2004 09:54:42 +1000 (EST) Received: from 353661bh ([127.0.0.1]) by 353661-bh with Microsoft SMTPSVC(6.0.2600.1106); Thu, 1 Apr 2004 09:55:03 +1000 From: "Brett Henderson" To: "'Jakarta Commons Developers List'" Subject: RE: [codec] StatefulDecoders Date: Thu, 1 Apr 2004 09:55:03 +1000 Message-ID: <002801c4177b$961bd840$8263a88d@353661bh> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_0029_01C417CF.67C7E840" X-Priority: 3 (Normal) X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook, Build 10.0.4510 In-Reply-To: <20040324012303.SBZL1781.imf18aec.mail.bellsouth.net@franklin> X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1106 Importance: Normal X-OriginalArrivalTime: 31 Mar 2004 23:55:04.0014 (UTC) FILETIME=[961D5EE0:01C4177B] X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N X-Spam-Rating: minotaur-2.apache.org 1.6.2 0/1000/N ------=_NextPart_000_0029_01C417CF.67C7E840 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Alex, Sorry about the delay. I'm a bit snowed under at the moment. I've attached producers/consumers that process Object instances instead = of type specific data. Some differences between these interfaces and those you've already built are: 1. These have no monitor facility. All errors result in a = CodecException being thrown. There is no concept of a warning. 2. These have a finalize concept which is required for implementations = such as base64 where padding on the final data block is required. 3. These have flush methods to allow the chain to be flushed without = being finalized. 4. These have a propogating flag which allows finalize/flush calls to be propagated through codec chains. By default this is true but can be set = to false. This is necessary when a single consumer (eg. = OutputStreamConsumer) receives streams from multiple sources and each of those sources are finalized before the next is started. In this case you don't want the OutputStreamConsumer to be finalized (and the underlying stream closed) multiple times, you want this to occur only after the final input source completes. Hope this makes sense. With regards to each difference: 1. Not sure of the correct approach here. I threw exceptions because it = was simpler to implement and made it harder to end up with silent errors occurring. A monitor approach is more flexible although perhaps harder = to use from a client perspective. 2. I believe you will need to add a finalize concept. Some codecs = require notification that this is the final processing call (ie. Base64). 3. Flush isn't critical. I just added it for completeness. 4. A propagating option isn't critical and java IOStreams don't have = this concept. However a common problem is where you wish to feed the result = of several streams into a single stream without the close on each top level stream calling close on the receiving stream. Another way of overcoming this is to create a special Noop Nopropagate codec that you insert into = the chain to prevent these calls propagating. I meant to create some sample code using my interfaces to compare with = yours but I can't get it done at the moment. You're obviously clued in on what's required, any differences between = mine and yours is relatively small and I'm sure either would suit the = purposes of codec. Given that I'm taking way too long to do anything at the moment I'll = leave it in your capable hands. My current work should ease up in a few weeks = and I'll try to give you a hand again then. Cheers, Brett > Could you give some example's of how this would look just using >=20 > Objects instead of specific types to implement what the DecoderStack >=20 > does here: >=20 >=20 >=20 > http://cvs.apache.org/viewcvs.cgi/incubator/directory/snickers > /trunk/codec-s >=20 > tateful/src/java/org/apache/commons/codec/stateful/DecoderStac > k.java?rev=3D972 >=20 > 4&root=3DApache-SVN&view=3Dauto >=20 >=20 >=20 > And go on to show how it's used like in this test code here: >=20 >=20 >=20 > http://cvs.apache.org/viewcvs.cgi/incubator/directory/snickers > /trunk/codec-s >=20 > tateful/src/test/org/apache/commons/codec/stateful/DecoderStac > kTest.java?rev >=20 > =3D9724&root=3DApache-SVN&view=3Dauto >=20 >=20 >=20 > Specifically I'm referring to the usage of the DecoderStack in the >=20 > testDecode() example which shows the chaining really simply. >=20 > Perhaps looking at the two use cases we can come to a better > conclusion. >=20 >=20 >=20 >=20 >=20 > > Does the above make sense? If so, please give it careful > > consideration >=20 > > because I originally used the callback design and modified it to use >=20 > > producers/consumers because I think it is actually simpler > and is much >=20 > > more >=20 > > flexible. >=20 >=20 >=20 > Yes it makes sense I just want to see it and play with it. > Can you whip >=20 > it up and we'll begin getting a feel for both sets of interfaces. >=20 >=20 >=20 > > If you're still not convinced I guess I'll have to give in > and go with > > the >=20 > > flow ;-) >=20 >=20 >=20 > Nah we'll try come to an understanding. >=20 >=20 >=20 ------=_NextPart_000_0029_01C417CF.67C7E840 Content-Type: java/*; name="Producer.java" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="Producer.java" package com.bretth.codec; /** * Provides definition of all classes providing producer * functionality. A Producer is a class that can produce * outgoing data. * Producer implementations can assume they have been provided * with a Consumer and do not need to explicitly check for error * conditions (ie. NullPointerException) that arise from not * being provided with a Consumer. *=20 * @author Brett Henderson */ public interface Producer { /** * Sets the Consumer to receive all processed data. */ public void setConsumer(Consumer consumer); =09 =09 /** * This method defines whether propagation of stream control = information * to consumers is allowed. This includes the finalize flag, finalize = method, * flush method, and reset method. * By default, propagating is true. */ public void setPropagating(boolean propagating) throws CodecException; } ------=_NextPart_000_0029_01C417CF.67C7E840 Content-Type: java/*; name="Consumer.java" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="Consumer.java" package com.bretth.codec; import com.bretth.codec.CodecException; /** * Provides definition of all classes providing consumer * functionality. A Consumer is a class that can receive * incoming data. * * @author Brett Henderson */ public interface Consumer { /** * Restores the internal state of a Consumer to initial settings. */ public void reset() throws CodecException; /** * Flushes data from internal buffers to the output destination. * This doesn't finalize codecs or flush data that cannot be * processed yet. */ public void flush() throws CodecException; /** * Finalises the codec and writes all available output to the * output destination. All process methods defined by extending * interfaces should provide an optional finalize flag that allows * a call to this method to be eliminated. This simplifies cases * where all data is provided in a single call. */ public void finalize() throws CodecException; /** * Processes the specified data. * Finalises the Consumer so that all data is processed. */ public void process(Object data) throws CodecException; /** * Processes the specified data. */ public void process(Object data, boolean finalize) throws CodecException; } ------=_NextPart_000_0029_01C417CF.67C7E840 Content-Type: text/plain; charset=us-ascii --------------------------------------------------------------------- To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org For additional commands, e-mail: commons-dev-help@jakarta.apache.org ------=_NextPart_000_0029_01C417CF.67C7E840--