mina-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From build...@apache.org
Subject svn commit: r836681 [18/23] - in /websites/staging/mina/trunk/content: ./ asyncweb/ css/ ftpserver/ mina/ mina/userguide/ mina/userguide/ch1-getting-started/ mina/userguide/ch10-executor-filter/ mina/userguide/ch11-ssl-filter/ mina/userguide/ch12-loggi...
Date Wed, 31 Oct 2012 04:53:40 GMT
Added: websites/staging/mina/trunk/content/mina/userguide/ch8-iobuffer/ch8-iobuffer.html
==============================================================================
--- websites/staging/mina/trunk/content/mina/userguide/ch8-iobuffer/ch8-iobuffer.html (added)
+++ websites/staging/mina/trunk/content/mina/userguide/ch8-iobuffer/ch8-iobuffer.html Wed Oct 31 04:53:33 2012
@@ -0,0 +1,286 @@
+<!DOCTYPE html>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You 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.
+-->
+<html>
+<head>
+	<title>Chapter 10 - IoBuffer &mdash; Apache MINA</title>
+	
+		<link href="./../../../css/common.css" rel="stylesheet" type="text/css">
+		<link href="./../../../css/mina.css" rel="stylesheet" type="text/css">
+	
+</head>
+  <body>
+    <div id="container">
+      <div id="header">
+        <div id="subProjectsNavBar">
+          <a href="./../../../">
+            
+              Apache MINA Project
+            
+          </a>
+          &nbsp;|&nbsp;
+          <a href="./../../../mina/index.html">
+            
+              <strong>MINA</strong>
+            
+          </a>
+          &nbsp;|&nbsp;
+          <a href="./../../../asyncweb/index.html">
+            
+              AsyncWeb
+            
+          </a>
+          &nbsp;|&nbsp;
+          <a href="./../../../ftpserver/index.html">
+            
+              FtpServer
+            
+          </a>
+          &nbsp;|&nbsp;
+          <a href="./../../../sshd/index.html">
+            
+              Sshd
+            
+          </a>
+          &nbsp;|&nbsp;
+          <a href="./../../../vysper/index.html">
+            
+              Vysper
+            
+          </a>
+        </div><!-- subProjectsNavBar -->
+      </div><!-- header -->
+      <div id="content">
+        <div id="leftColumn">
+                              
+          
+          
+          
+            <div id="navigation">
+
+    <h5>Latest Downloads</h5>
+    <ul>
+        <li><a href="./../../../mina/downloads.html">Mina 2.0.7</a></li>
+    </ul>
+    <h5>Documentation</h5>
+    <ul>
+      <li><a href="./../../../mina/userguide/user-guide-toc.html" class="external-link" rel="nofollow">User guide</a></li>
+      <li><a href="./../../../mina/features.html" class="external-link" rel="nofollow">Features</a/</li>
+      <li><a href="./../../../mina/road-map.html" class="external-link" rel="nofollow">Road Map</a/</li>
+      <li><a href="./../../../mina/faq.html" class="external-link" rel="nofollow">FAQ</a/</li>
+    </ul>
+    <h5>Resources</h5>
+    <ul>
+      <li><a href="./../../../mina/downloads.html" class="external-link" rel="nofollow">Downloads</a></li>
+      <li><a href="./../../../mina/mailing-lists.html" class="external-link" rel="nofollow">Mailing lists & IRC</a></li>
+      <li><a href="./../../../mina/issue-tracking.html" class="external-link" rel="nofollow">Issue tracking</a></li>
+      <li><a href="./../../../mina/sources.html" class="external-link" rel="nofollow">Sources</a></li>
+      <li><a href="./../../../mina/performances.html" class="external-link" rel="nofollow">Performances</a></li>
+      <li><a href="./../../../mina/testimonials.html" class="external-link" rel="nofollow">Testimonials</a></li>
+      <li><a href="./../../../mina/conferences.html" class="external-link" rel="nofollow">Conferences</a></li>
+      <li><a href="./../../../mina/developper-guide.html" class="external-link" rel="nofollow">Developers Guide</a></li>
+      <li><a href="./../../../mina/related-projects.html" class="external-link" rel="nofollow">Related Projects</a></li>
+      <li><a href="http://people.apache.org/~vgritsenko/stats/projects/mina.html" class="external-link" rel="nofollow">Statistics</a></li>
+    </ul>
+
+    <h5>Community</h5>
+    <ul>
+      <li><a href="http://www.apache.org/foundation/contributing.html" class="external-link" rel="nofollow">Contributing</a></li>
+      <li><a href="./../../../contributors.html" class="external-link" rel="nofollow">Team</a></li>
+      <li><a href="./../../../special-thanks.html" class="external-link" rel="nofollow">Special Thanks</a></li>
+      <li><a href="http://www.apache.org/security/" class="external-link" rel="nofollow">Security</a></li>
+    </ul>
+
+    <h5>About Apache</h5>
+    <ul>
+      <li><a href="http://www.apache.org" class="external-link" rel="nofollow">Apache main site</a></li>
+      <li><a href="http://www.apache.org/licenses/" class="external-link" rel="nofollow">License</a></li>
+      <li><a href="http://www.apache.org/foundation/sponsorship.html" title="The ASF sponsorship program" class="external-link" rel="nofollow">Sponsorship program</a></li>
+      <li><a href="http://www.apache.org/foundation/thanks.html" class="external-link" rel="nofollow">Thanks</a></li>
+    </ul>
+
+    <h3><a name="Navigation-Upcoming"></a>Upcoming</h3>
+    <ul>
+      <li>No event</li>
+    </ul>
+
+</div>
+
+<!-- navigation -->
+          
+          
+        </div><!-- leftColumn -->
+      <div id="rightColumn">
+
+
+
+    <div class="nav">
+        <div class="nav_prev">
+        
+            <a href="../ch7-handler/ch7-handler.html">Chapter 7 - IoHandler</a>
+		
+        </div>
+        <div class="nav_up">
+        
+            <a href="../user-guide-toc.html">User Guide</a>
+		
+        </div>
+        <div class="nav_next">
+        
+            <a href="../ch9-codec-filter/ch9-codec-filter.html">Chapter 9 - Codec Filter</a>
+		
+        </div>
+        <div class="clearfix"></div>
+    </div>
+
+
+<h1 id="chapter-8-iobuffer">Chapter 8 - IoBuffer</h1>
+<p>A byte buffer used by MINA applications.</p>
+<p>This is a replacement for <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/nio/ByteBuffer.html">ByteBuffer</a>. MINA does not use NIO ByteBuffer directly for two reasons:</p>
+<ul>
+<li>It doesn't provide useful getters and putters such as fill, get/putString, and get/putAsciiInt() .</li>
+<li>It is difficult to write variable-length data due to its fixed capacity</li>
+</ul>
+<p><DIV class="note" markdown="1">
+    This will change in MINA 3. The main reason why MINA has its own wrapper on top of nio ByteBuffer is to have extensible buffers. This was a very bad decision. Buffers are just buffers : a temporary place to store temporary data, before it is used. Many other solutions exist, like defining a wrapper which relies on a list of NIO ByteBuffers, instead of copying the existing buffer to a bigger one just because we want to extend the buffer capacity.</p>
+<div class="codehilite"><pre><span class="nt">&lt;P&gt;</span>It might also be more comfortable to use an InputStream instead of a byte buffer all along the filters, as it does not imply anything about the nature of the stored data : it can be a byte array, strings, messages...<span class="nt">&lt;/P&gt;</span>
+
+<span class="nt">&lt;P&gt;</span>Last, not least, the current implementation defeat one of the target : zero-copy strategy (ie, once we have read the data from the socket, we want to avoid a copy being done later). As we use extensible byte buffers, we will most certainly copy those data if we have to manage big messages. Assuming that the MINA ByteBuffer is just a wrapper on top of NIO ByteBuffer, this can be a real problem when using direct buffers.<span class="nt">&lt;/P&gt;</span>
+</pre></div>
+
+
+<p></DIV></p>
+<h2 id="iobuffer-operations">IoBuffer Operations</h2>
+<h3 id="allocating-a-new-buffer">Allocating a new Buffer</h3>
+<p>IoBuffer is an abstract class, hence can't be instantiated directly. To allocate IoBuffer, we need to use one of the two allocate() methods.</p>
+<div class="codehilite"><pre><span class="sr">//</span> <span class="n">Allocates</span> <span class="n">a</span> <span class="k">new</span> <span class="n">buffer</span> <span class="n">with</span> <span class="n">a</span> <span class="n">specific</span> <span class="n">size</span><span class="p">,</span> <span class="n">defining</span> <span class="n">its</span> <span class="n">type</span> <span class="p">(</span><span class="n">direct</span> <span class="ow">or</span> <span class="n">heap</span><span class="p">)</span>
+<span class="n">public</span> <span class="n">static</span> <span class="n">IoBuffer</span> <span class="n">allocate</span><span class="p">(</span><span class="nb">int</span> <span class="n">capacity</span><span class="p">,</span> <span class="n">boolean</span> <span class="n">direct</span><span class="p">)</span>
+
+<span class="sr">//</span> <span class="n">Allocates</span> <span class="n">a</span> <span class="k">new</span> <span class="n">buffer</span> <span class="n">with</span> <span class="n">a</span> <span class="n">specific</span> <span class="n">size</span>
+<span class="n">public</span> <span class="n">static</span> <span class="n">IoBuffer</span> <span class="n">allocate</span><span class="p">(</span><span class="nb">int</span> <span class="n">capacity</span><span class="p">)</span>
+</pre></div>
+
+
+<p>The allocate() method takes one or two arguments. The first form takes two arguments :</p>
+<ul>
+<li><strong>capacity</strong> - the capacity of the buffer</li>
+<li><strong>direct</strong> - type of buffer. true to get direct buffer, false to get heap buffer</li>
+</ul>
+<p>The default buffer allocation is handled by <a href="http://mina.apache.org/report/trunk/xref/org/apache/mina/core/buffer/SimpleBufferAllocator.html">SimpleBufferAllocator</a></p>
+<p>Alternatively, following form can also be used</p>
+<div class="codehilite"><pre><span class="sr">//</span> <span class="n">Allocates</span> <span class="n">heap</span> <span class="n">buffer</span> <span class="n">by</span> <span class="n">default</span><span class="o">.</span>
+<span class="n">IoBuffer</span><span class="o">.</span><span class="n">setUseDirectBuffer</span><span class="p">(</span><span class="n">false</span><span class="p">);</span>
+<span class="sr">//</span> <span class="n">A</span> <span class="k">new</span> <span class="n">heap</span> <span class="n">buffer</span> <span class="n">is</span> <span class="n">returned</span><span class="o">.</span>
+<span class="n">IoBuffer</span> <span class="n">buf</span> <span class="o">=</span> <span class="n">IoBuffer</span><span class="o">.</span><span class="n">allocate</span><span class="p">(</span><span class="mi">1024</span><span class="p">);</span>
+</pre></div>
+
+
+<p>When using the second form, don't forget to set the default buffer type before, otherwise you will get Heap buffers by default.</p>
+<h2 id="creating-auto-expanding-buffer">Creating Auto Expanding Buffer</h2>
+<p>Creating auto expanding buffer is not very easy with java NIO API's, because of the fixed size of the buffers. Having a buffer, that can auto expand on needs is a big plus for networking applications. To address this, IoBuffer has introduced the autoExpand property. It automatically expands its capacity and limit value.</p>
+<p>Lets see how to create an auto expanding buffer :</p>
+<div class="codehilite"><pre><span class="n">IoBuffer</span> <span class="n">buffer</span> <span class="o">=</span> <span class="n">IoBuffer</span><span class="o">.</span><span class="n">allocate</span><span class="p">(</span><span class="mi">8</span><span class="p">);</span>
+<span class="n">buffer</span><span class="o">.</span><span class="n">setAutoExpand</span><span class="p">(</span><span class="n">true</span><span class="p">);</span>
+<span class="n">buffer</span><span class="o">.</span><span class="n">putString</span><span class="p">(</span><span class="s">&quot;12345678&quot;</span><span class="p">,</span> <span class="n">encoder</span><span class="p">);</span>
+<span class="sr">//</span> <span class="n">Add</span> <span class="n">more</span> <span class="n">to</span> <span class="n">this</span> <span class="n">buffer</span>
+<span class="n">buffer</span><span class="o">.</span><span class="n">put</span><span class="p">((</span><span class="n">byte</span><span class="p">)</span><span class="mi">10</span><span class="p">);</span>
+</pre></div>
+
+
+<p>The underlying ByteBuffer is reallocated by IoBuffer behind the scene if the encoded data is larger than 8 bytes in the example above. Its capacity will double, and its limit will increase to the last position the string is written. This behavior is very similar to the way StringBuffer class works.</p>
+<p><DIV class="note" markdown="1">
+    This mechanism is very likely to be removed from MINA 3.0, as it's not really the best way to handle increased buffer size. It should be replaced by something like a InputStream hiding a list or an array of fixed sized ByteBuffers.
+</DIV></p>
+<h2 id="creating-auto-shrinking-buffer">Creating Auto Shrinking Buffer</h2>
+<p>There are situations which calls for releasing additionally allocated bytes from the buffer, to preserve memory. IoBuffer provides autoShrink property to address the need.  If autoShrink is turned on, IoBuffer halves the capacity of the buffer when compact() is invoked and only 1/4 or less of the current capacity is being used. To manually shrink the buffer, use shrink() method.</p>
+<p>Lets see this in action :</p>
+<div class="codehilite"><pre><span class="n">IoBuffer</span> <span class="n">buffer</span> <span class="o">=</span> <span class="n">IoBuffer</span><span class="o">.</span><span class="n">allocate</span><span class="p">(</span><span class="mi">16</span><span class="p">);</span>
+<span class="n">buffer</span><span class="o">.</span><span class="n">setAutoShrink</span><span class="p">(</span><span class="n">true</span><span class="p">);</span>
+<span class="n">buffer</span><span class="o">.</span><span class="n">put</span><span class="p">((</span><span class="n">byte</span><span class="p">)</span><span class="mi">1</span><span class="p">);</span>
+<span class="n">System</span><span class="o">.</span><span class="n">out</span><span class="o">.</span><span class="n">println</span><span class="p">(</span><span class="s">&quot;Initial Buffer capacity = &quot;</span><span class="o">+</span><span class="n">buffer</span><span class="o">.</span><span class="n">capacity</span><span class="p">());</span>
+<span class="n">buffer</span><span class="o">.</span><span class="n">shrink</span><span class="p">();</span>
+<span class="n">System</span><span class="o">.</span><span class="n">out</span><span class="o">.</span><span class="n">println</span><span class="p">(</span><span class="s">&quot;Initial Buffer capacity after shrink = &quot;</span><span class="o">+</span><span class="n">buffer</span><span class="o">.</span><span class="n">capacity</span><span class="p">());</span>
+<span class="n">buffer</span><span class="o">.</span><span class="n">capacity</span><span class="p">(</span><span class="mi">32</span><span class="p">);</span>
+<span class="n">System</span><span class="o">.</span><span class="n">out</span><span class="o">.</span><span class="n">println</span><span class="p">(</span><span class="s">&quot;Buffer capacity after incrementing capacity to 32 = &quot;</span><span class="o">+</span><span class="n">buffer</span><span class="o">.</span><span class="n">capacity</span><span class="p">());</span>
+<span class="n">buffer</span><span class="o">.</span><span class="n">shrink</span><span class="p">();</span>
+<span class="n">System</span><span class="o">.</span><span class="n">out</span><span class="o">.</span><span class="n">println</span><span class="p">(</span><span class="s">&quot;Buffer capacity after shrink= &quot;</span><span class="o">+</span><span class="n">buffer</span><span class="o">.</span><span class="n">capacity</span><span class="p">());</span>
+</pre></div>
+
+
+<p>We have initially allocated a capacity as 16, and set the autoShrink property as true.</p>
+<p>Lets see the output of this :</p>
+<div class="codehilite"><pre><span class="n">Initial</span> <span class="n">Buffer</span> <span class="n">capacity</span> <span class="o">=</span> <span class="mi">16</span>
+<span class="n">Initial</span> <span class="n">Buffer</span> <span class="n">capacity</span> <span class="n">after</span> <span class="n">shrink</span> <span class="o">=</span> <span class="mi">16</span>
+<span class="n">Buffer</span> <span class="n">capacity</span> <span class="n">after</span> <span class="n">incrementing</span> <span class="n">capacity</span> <span class="n">to</span> <span class="mi">32</span> <span class="o">=</span> <span class="mi">32</span>
+<span class="n">Buffer</span> <span class="n">capacity</span> <span class="n">after</span> <span class="n">shrink</span><span class="o">=</span> <span class="mi">16</span>
+</pre></div>
+
+
+<p>Lets take a break and analyze the output</p>
+<ul>
+<li>Initial buffer capacity is 16, as we created the buffer with this capacity. Internally this becomes the minimum capacity of the buffer</li>
+<li>After calling shrink(), the capacity remains 16, as capacity shall never be less than minimum capacity</li>
+<li>After incrementing capacity to 32, the capacity becomes 32</li>
+<li>Call to shrink(), reduces the capacity to 16, thereby eliminating extra storage</li>
+</ul>
+<p><DIV class="note" markdown="1">
+    Again, this mechanism should be a default one, without needing to explicitely tells the buffer that it can shrink.
+</DIV></p>
+<h2 id="buffer-allocation">Buffer Allocation</h2>
+<p>IoBufferAllocater is responsible for allocating and managing buffers. To have precise control on the buffer allocation policy, implement the IoBufferAllocater interface.</p>
+<p>MINA ships with following implementations of IoBufferAllocater</p>
+<ul>
+<li><strong>SimpleBufferAllocator (default)</strong> - Create a new buffer every time</li>
+<li><strong>CachedBufferAllocator</strong> - caches the buffer which are likely to be reused during expansion</li>
+</ul>
+<p><DIV class="note" markdown="1">
+    With the new available JVM, using cached IoBuffer is very unlikely to improve performances.
+</DIV></p>
+<p>You can implement you own implementation of IoBufferAllocator and call setAllocator() on IoBuffer to use the same.</p>
+
+
+    <div class="nav">
+        <div class="nav_prev">
+        
+            <a href="../ch7-handler/ch7-handler.html">Chapter 7 - IoHandler</a>
+		
+        </div>
+        <div class="nav_up">
+        
+            <a href="../user-guide-toc.html">User Guide</a>
+		
+        </div>
+        <div class="nav_next">
+        
+            <a href="../ch9-codec-filter/ch9-codec-filter.html">Chapter 9 - Codec Filter</a>
+		
+        </div>
+        <div class="clearfix"></div>
+    </div>
+
+
+                </div><!-- rightColumn -->
+                <div id="endContent"></div>
+            </div><!-- content -->
+            <div id="footer">&copy; 2003-2012, <a href="http://www.apache.org">The Apache Software Foundation</a> - <a href="privacy-policy.html">Privacy Policy</a><br />
+                Apache MINA, MINA, Apache Vysper, Vysper, Apache SSHd, SSHd, Apache FtpServer, FtpServer, Apache AsyncWeb, AsyncWeb,
+                Apache, the Apache feather logo, and the Apache Mina project logos are trademarks of The Apache Software Foundation.
+            </div>
+        </div><!-- container -->
+    </body>
+</html>
+

Added: websites/staging/mina/trunk/content/mina/userguide/ch9-codec-filter/ch9-codec-filter.html
==============================================================================
--- websites/staging/mina/trunk/content/mina/userguide/ch9-codec-filter/ch9-codec-filter.html (added)
+++ websites/staging/mina/trunk/content/mina/userguide/ch9-codec-filter/ch9-codec-filter.html Wed Oct 31 04:53:33 2012
@@ -0,0 +1,611 @@
+<!DOCTYPE html>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You 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.
+-->
+<html>
+<head>
+	<title>Chapter 9 - Codec Filter &mdash; Apache MINA</title>
+	
+		<link href="./../../../css/common.css" rel="stylesheet" type="text/css">
+		<link href="./../../../css/mina.css" rel="stylesheet" type="text/css">
+	
+</head>
+  <body>
+    <div id="container">
+      <div id="header">
+        <div id="subProjectsNavBar">
+          <a href="./../../../">
+            
+              Apache MINA Project
+            
+          </a>
+          &nbsp;|&nbsp;
+          <a href="./../../../mina/index.html">
+            
+              <strong>MINA</strong>
+            
+          </a>
+          &nbsp;|&nbsp;
+          <a href="./../../../asyncweb/index.html">
+            
+              AsyncWeb
+            
+          </a>
+          &nbsp;|&nbsp;
+          <a href="./../../../ftpserver/index.html">
+            
+              FtpServer
+            
+          </a>
+          &nbsp;|&nbsp;
+          <a href="./../../../sshd/index.html">
+            
+              Sshd
+            
+          </a>
+          &nbsp;|&nbsp;
+          <a href="./../../../vysper/index.html">
+            
+              Vysper
+            
+          </a>
+        </div><!-- subProjectsNavBar -->
+      </div><!-- header -->
+      <div id="content">
+        <div id="leftColumn">
+                              
+          
+          
+          
+            <div id="navigation">
+
+    <h5>Latest Downloads</h5>
+    <ul>
+        <li><a href="./../../../mina/downloads.html">Mina 2.0.7</a></li>
+    </ul>
+    <h5>Documentation</h5>
+    <ul>
+      <li><a href="./../../../mina/userguide/user-guide-toc.html" class="external-link" rel="nofollow">User guide</a></li>
+      <li><a href="./../../../mina/features.html" class="external-link" rel="nofollow">Features</a/</li>
+      <li><a href="./../../../mina/road-map.html" class="external-link" rel="nofollow">Road Map</a/</li>
+      <li><a href="./../../../mina/faq.html" class="external-link" rel="nofollow">FAQ</a/</li>
+    </ul>
+    <h5>Resources</h5>
+    <ul>
+      <li><a href="./../../../mina/downloads.html" class="external-link" rel="nofollow">Downloads</a></li>
+      <li><a href="./../../../mina/mailing-lists.html" class="external-link" rel="nofollow">Mailing lists & IRC</a></li>
+      <li><a href="./../../../mina/issue-tracking.html" class="external-link" rel="nofollow">Issue tracking</a></li>
+      <li><a href="./../../../mina/sources.html" class="external-link" rel="nofollow">Sources</a></li>
+      <li><a href="./../../../mina/performances.html" class="external-link" rel="nofollow">Performances</a></li>
+      <li><a href="./../../../mina/testimonials.html" class="external-link" rel="nofollow">Testimonials</a></li>
+      <li><a href="./../../../mina/conferences.html" class="external-link" rel="nofollow">Conferences</a></li>
+      <li><a href="./../../../mina/developper-guide.html" class="external-link" rel="nofollow">Developers Guide</a></li>
+      <li><a href="./../../../mina/related-projects.html" class="external-link" rel="nofollow">Related Projects</a></li>
+      <li><a href="http://people.apache.org/~vgritsenko/stats/projects/mina.html" class="external-link" rel="nofollow">Statistics</a></li>
+    </ul>
+
+    <h5>Community</h5>
+    <ul>
+      <li><a href="http://www.apache.org/foundation/contributing.html" class="external-link" rel="nofollow">Contributing</a></li>
+      <li><a href="./../../../contributors.html" class="external-link" rel="nofollow">Team</a></li>
+      <li><a href="./../../../special-thanks.html" class="external-link" rel="nofollow">Special Thanks</a></li>
+      <li><a href="http://www.apache.org/security/" class="external-link" rel="nofollow">Security</a></li>
+    </ul>
+
+    <h5>About Apache</h5>
+    <ul>
+      <li><a href="http://www.apache.org" class="external-link" rel="nofollow">Apache main site</a></li>
+      <li><a href="http://www.apache.org/licenses/" class="external-link" rel="nofollow">License</a></li>
+      <li><a href="http://www.apache.org/foundation/sponsorship.html" title="The ASF sponsorship program" class="external-link" rel="nofollow">Sponsorship program</a></li>
+      <li><a href="http://www.apache.org/foundation/thanks.html" class="external-link" rel="nofollow">Thanks</a></li>
+    </ul>
+
+    <h3><a name="Navigation-Upcoming"></a>Upcoming</h3>
+    <ul>
+      <li>No event</li>
+    </ul>
+
+</div>
+
+<!-- navigation -->
+          
+          
+        </div><!-- leftColumn -->
+      <div id="rightColumn">
+
+
+
+    <div class="nav">
+        <div class="nav_prev">
+        
+            <a href="../ch8-iobuffer/ch8-iobuffer.html">Chapter 8 - IoBuffer</a>
+		
+        </div>
+        <div class="nav_up">
+        
+            <a href="../user-guide-toc.html">User Guide</a>
+		
+        </div>
+        <div class="nav_next">
+        
+            <a href="../ch10-executor-filter/ch10-executor-filter.html">Chapter 10 - Executor Filter</a>
+		
+        </div>
+        <div class="clearfix"></div>
+    </div>
+
+
+<h1 id="chapter-9-codec-filter">Chapter 9 - Codec Filter</h1>
+<p>This tutorial tries to explain why and how to use a ProtocolCodecFilter.</p>
+<h2 id="why-use-a-protocolcodecfilter">Why use a ProtocolCodecFilter?</h2>
+<ul>
+<li>TCP guarantess delivery of all packets in the correct order.
+But there is no guarantee that one write operation on the sender-side will result in one read event on the receiving side.
+see <a href="http://en.wikipedia.org/wiki/IPv4#Fragmentation_and_reassembly">http://en.wikipedia.org/wiki/IPv4#Fragmentation_and_reassembly</a> and <a href="http://en.wikipedia.org/wiki/Nagle%27s_algorithm">http://en.wikipedia.org/wiki/Nagle%27s_algorithm</a>
+In MINA terminology: without a ProtocolCodecFilter one call of IoSession.write(Object message) by the sender can result in multiple messageReceived(IoSession session, Object message) events on the receiver; and multiple calls of IoSession.write(Object message) can lead to a single messageReceived event. You might not encounter this behavior when client and server are running on the same host (or an a local network) but your applications should be able to cope with this.</li>
+<li>Most network applications need a way to find out where the current message ends and where the next message starts.</li>
+<li>You could implement all this logic in your IoHandler, but adding a ProtocolCodecFilter will make your code much cleaner and easier to maintain.</li>
+<li>It allows you to separate your protocol logic from your business logic (IoHandler).</li>
+</ul>
+<h2 id="how">How ?</h2>
+<p>Your application is basically just receiving a bunch of bytes and you need to convert these bytes into messages (higher level objects).</p>
+<p>There are three common techniques for splitting the stream of bytes into messages:</p>
+<ul>
+<li>use fixed length messages</li>
+<li>use a fixed length header that indicates the length of the body</li>
+<li>using a delimiter; for example many text-based protocols append a newline (or CR LF pair) after every message (<a href="http://www.faqs.org/rfcs/rfc977.html">http://www.faqs.org/rfcs/rfc977.html</a>)</li>
+</ul>
+<p>In this tutorial we will use the first and second method since they are definitely easier to implement. Afterwards we will look at using a delimiter.</p>
+<h2 id="example">Example</h2>
+<p>We will develop a (pretty useless) graphical chargen server to illustrate how to implement your own protocol codec (ProtocolEncoder, ProtocolDecoder, and ProtocolCodecFactory).
+The protocol is really simple. This is the layout of a request message:</p>
+<p><DIV class="table-wrap">
+<TABLE class="confluenceTable"><TBODY>
+<TR>
+<TH class="confluenceTh">4 bytes</TH>
+<TH class="confluenceTh">4 bytes</TH>
+<TH class="confluenceTh">4 bytes</TH>
+</TR>
+<TR>
+<TD class="confluenceTd">width</TD>
+<TD class="confluenceTd">height</TD>
+<TD class="confluenceTd">numchars</TD>
+</TR>
+</TBODY></TABLE>
+</DIV></p>
+<ul>
+<li>width: the width of the requested image (an integer in network byte-order)</li>
+<li>height: the height of the requested image (an integer in network byte-order)</li>
+<li>numchars: the number of chars to generate (an integer in network byte-order)</li>
+</ul>
+<p>The server responds with two images of the requested dimensions, with the requested number of characters painted on it.
+This is the layout of a response message:</p>
+<p><DIV class="table-wrap">
+<TABLE class="confluenceTable"><TBODY>
+<TR>
+<TH class="confluenceTh">4 bytes</TH>
+<TH class="confluenceTh">variable length body</TH>
+<TH class="confluenceTh">4 bytes</TH>
+<TH class="confluenceTh">variable length body</TH>
+</TR>
+<TR>
+<TD class="confluenceTd">length1</TD>
+<TD class="confluenceTd">image1</TD>
+<TD class="confluenceTd">length2</TD>
+<TD class="confluenceTd">image2</TD>
+</TR>
+</TBODY></TABLE>
+</DIV></p>
+<p>Overview of the classes we need for encoding and decoding requests and responses:</p>
+<ul>
+<li><strong>ImageRequest</strong>: a simple POJO representing a request to our ImageServer.</li>
+<li><strong>ImageRequestEncoder</strong>: encodes ImageRequest objects into protocol-specific data (used by the client)</li>
+<li><strong>ImageRequestDecoder</strong>: decodes protocol-specific data into ImageRequest objects (used by the server)</li>
+<li><strong>ImageResponse</strong>: a simple POJO representing a response from our ImageServer.</li>
+<li><strong>ImageResponseEncoder</strong>: used by the server for encoding ImageResponse objects</li>
+<li><strong>ImageResponseDecoder</strong>: used by the client for decoding ImageResponse objects</li>
+<li><strong>ImageCodecFactory</strong>: this class creates the necesarry encoders and decoders</li>
+</ul>
+<p>Here is the ImageRequest class :</p>
+<div class="codehilite"><pre><span class="n">public</span> <span class="n">class</span> <span class="n">ImageRequest</span> <span class="p">{</span>
+
+    <span class="n">private</span> <span class="nb">int</span> <span class="n">width</span><span class="p">;</span>
+    <span class="n">private</span> <span class="nb">int</span> <span class="n">height</span><span class="p">;</span>
+    <span class="n">private</span> <span class="nb">int</span> <span class="n">numberOfCharacters</span><span class="p">;</span>
+
+    <span class="n">public</span> <span class="n">ImageRequest</span><span class="p">(</span><span class="nb">int</span> <span class="n">width</span><span class="p">,</span> <span class="nb">int</span> <span class="n">height</span><span class="p">,</span> <span class="nb">int</span> <span class="n">numberOfCharacters</span><span class="p">)</span> <span class="p">{</span>
+        <span class="n">this</span><span class="o">.</span><span class="n">width</span> <span class="o">=</span> <span class="n">width</span><span class="p">;</span>
+        <span class="n">this</span><span class="o">.</span><span class="n">height</span> <span class="o">=</span> <span class="n">height</span><span class="p">;</span>
+        <span class="n">this</span><span class="o">.</span><span class="n">numberOfCharacters</span> <span class="o">=</span> <span class="n">numberOfCharacters</span><span class="p">;</span>
+    <span class="p">}</span>
+
+    <span class="n">public</span> <span class="nb">int</span> <span class="n">getWidth</span><span class="p">()</span> <span class="p">{</span>
+        <span class="k">return</span> <span class="n">width</span><span class="p">;</span>
+    <span class="p">}</span>
+
+    <span class="n">public</span> <span class="nb">int</span> <span class="n">getHeight</span><span class="p">()</span> <span class="p">{</span>
+        <span class="k">return</span> <span class="n">height</span><span class="p">;</span>
+    <span class="p">}</span>
+
+    <span class="n">public</span> <span class="nb">int</span> <span class="n">getNumberOfCharacters</span><span class="p">()</span> <span class="p">{</span>
+        <span class="k">return</span> <span class="n">numberOfCharacters</span><span class="p">;</span>
+    <span class="p">}</span>
+<span class="p">}</span>
+</pre></div>
+
+
+<p>Encoding is usually simpler than decoding, so let's start with the ImageRequestEncoder:</p>
+<div class="codehilite"><pre><span class="n">public</span> <span class="n">class</span> <span class="n">ImageRequestEncoder</span> <span class="n">implements</span> <span class="n">ProtocolEncoder</span> <span class="p">{</span>
+
+    <span class="n">public</span> <span class="n">void</span> <span class="n">encode</span><span class="p">(</span><span class="n">IoSession</span> <span class="n">session</span><span class="p">,</span> <span class="n">Object</span> <span class="n">message</span><span class="p">,</span> <span class="n">ProtocolEncoderOutput</span> <span class="n">out</span><span class="p">)</span> <span class="n">throws</span> <span class="n">Exception</span> <span class="p">{</span>
+        <span class="n">ImageRequest</span> <span class="n">request</span> <span class="o">=</span> <span class="p">(</span><span class="n">ImageRequest</span><span class="p">)</span> <span class="n">message</span><span class="p">;</span>
+        <span class="n">IoBuffer</span> <span class="n">buffer</span> <span class="o">=</span> <span class="n">IoBuffer</span><span class="o">.</span><span class="n">allocate</span><span class="p">(</span><span class="mi">12</span><span class="p">,</span> <span class="n">false</span><span class="p">);</span>
+        <span class="n">buffer</span><span class="o">.</span><span class="n">putInt</span><span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">getWidth</span><span class="p">());</span>
+        <span class="n">buffer</span><span class="o">.</span><span class="n">putInt</span><span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">getHeight</span><span class="p">());</span>
+        <span class="n">buffer</span><span class="o">.</span><span class="n">putInt</span><span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">getNumberOfCharacters</span><span class="p">());</span>
+        <span class="n">buffer</span><span class="o">.</span><span class="n">flip</span><span class="p">();</span>
+        <span class="n">out</span><span class="o">.</span><span class="nb">write</span><span class="p">(</span><span class="n">buffer</span><span class="p">);</span>
+    <span class="p">}</span>
+
+    <span class="n">public</span> <span class="n">void</span> <span class="n">dispose</span><span class="p">(</span><span class="n">IoSession</span> <span class="n">session</span><span class="p">)</span> <span class="n">throws</span> <span class="n">Exception</span> <span class="p">{</span>
+        <span class="sr">//</span> <span class="n">nothing</span> <span class="n">to</span> <span class="n">dispose</span>
+    <span class="p">}</span>
+<span class="p">}</span>
+</pre></div>
+
+
+<p>Remarks:</p>
+<ul>
+<li>MINA will call the encode function for all messages in the IoSession's write queue. Since our client will only write ImageRequest objects, we can safely cast message to ImageRequest.</li>
+<li>We allocate a new IoBuffer from the heap. It's best to avoid using direct buffers, since generally heap buffers perform better.
+ see <a href="http://issues.apache.org/jira/browse/DIRMINA-289">http://issues.apache.org/jira/browse/DIRMINA-289</a>)</li>
+<li>You do not have to release the buffer, MINA will do it for you, see <a href="http://mina.apache.org/report/trunk/apidocs/org/apache/mina/common/IoBuffer.html">http://mina.apache.org/report/trunk/apidocs/org/apache/mina/common/IoBuffer.html</a></li>
+<li>In the dispose() method you should release all resources acquired during encoding for the specified session. If there is nothing to dispose you could let your encoder inherit from ProtocolEncoderAdapter.</li>
+</ul>
+<p>Now let's have a look at the decoder. The CumulativeProtocolDecoder is a great help for writing your own decoder: it will buffer all incoming data until your decoder decides it can do something with it.
+In this case the message has a fixed size, so it's easiest to wait until all data is available:</p>
+<div class="codehilite"><pre><span class="n">public</span> <span class="n">class</span> <span class="n">ImageRequestDecoder</span> <span class="n">extends</span> <span class="n">CumulativeProtocolDecoder</span> <span class="p">{</span>
+
+    <span class="n">protected</span> <span class="n">boolean</span> <span class="n">doDecode</span><span class="p">(</span><span class="n">IoSession</span> <span class="n">session</span><span class="p">,</span> <span class="n">IoBuffer</span> <span class="n">in</span><span class="p">,</span> <span class="n">ProtocolDecoderOutput</span> <span class="n">out</span><span class="p">)</span> <span class="n">throws</span> <span class="n">Exception</span> <span class="p">{</span>
+        <span class="k">if</span> <span class="p">(</span><span class="n">in</span><span class="o">.</span><span class="n">remaining</span><span class="p">()</span> <span class="o">&gt;=</span> <span class="mi">12</span><span class="p">)</span> <span class="p">{</span>
+            <span class="nb">int</span> <span class="n">width</span> <span class="o">=</span> <span class="n">in</span><span class="o">.</span><span class="n">getInt</span><span class="p">();</span>
+            <span class="nb">int</span> <span class="n">height</span> <span class="o">=</span> <span class="n">in</span><span class="o">.</span><span class="n">getInt</span><span class="p">();</span>
+            <span class="nb">int</span> <span class="n">numberOfCharachters</span> <span class="o">=</span> <span class="n">in</span><span class="o">.</span><span class="n">getInt</span><span class="p">();</span>
+            <span class="n">ImageRequest</span> <span class="n">request</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ImageRequest</span><span class="p">(</span><span class="n">width</span><span class="p">,</span> <span class="n">height</span><span class="p">,</span> <span class="n">numberOfCharachters</span><span class="p">);</span>
+            <span class="n">out</span><span class="o">.</span><span class="nb">write</span><span class="p">(</span><span class="n">request</span><span class="p">);</span>
+            <span class="k">return</span> <span class="n">true</span><span class="p">;</span>
+        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
+            <span class="k">return</span> <span class="n">false</span><span class="p">;</span>
+        <span class="p">}</span>
+    <span class="p">}</span>
+<span class="p">}</span>
+</pre></div>
+
+
+<p>Remarks:</p>
+<ul>
+<li>everytime a complete message is decoded, you should write it to the ProtocolDecoderOutput; these messages will travel along the filter-chain and eventually arrive in your IoHandler.messageReceived method</li>
+<li>you are not responsible for releasing the IoBuffer</li>
+<li>when there is not enough data available to decode a message, just return false</li>
+</ul>
+<p>The response is also a very simple POJO:</p>
+<div class="codehilite"><pre><span class="n">public</span> <span class="n">class</span> <span class="n">ImageResponse</span> <span class="p">{</span>
+
+    <span class="n">private</span> <span class="n">BufferedImage</span> <span class="n">image1</span><span class="p">;</span>
+
+    <span class="n">private</span> <span class="n">BufferedImage</span> <span class="n">image2</span><span class="p">;</span>
+
+    <span class="n">public</span> <span class="n">ImageResponse</span><span class="p">(</span><span class="n">BufferedImage</span> <span class="n">image1</span><span class="p">,</span> <span class="n">BufferedImage</span> <span class="n">image2</span><span class="p">)</span> <span class="p">{</span>
+        <span class="n">this</span><span class="o">.</span><span class="n">image1</span> <span class="o">=</span> <span class="n">image1</span><span class="p">;</span>
+        <span class="n">this</span><span class="o">.</span><span class="n">image2</span> <span class="o">=</span> <span class="n">image2</span><span class="p">;</span>
+    <span class="p">}</span>
+
+    <span class="n">public</span> <span class="n">BufferedImage</span> <span class="n">getImage1</span><span class="p">()</span> <span class="p">{</span>
+        <span class="k">return</span> <span class="n">image1</span><span class="p">;</span>
+    <span class="p">}</span>
+
+    <span class="n">public</span> <span class="n">BufferedImage</span> <span class="n">getImage2</span><span class="p">()</span> <span class="p">{</span>
+        <span class="k">return</span> <span class="n">image2</span><span class="p">;</span>
+    <span class="p">}</span>
+<span class="p">}</span>
+</pre></div>
+
+
+<p>Encoding the response is also trivial:</p>
+<div class="codehilite"><pre><span class="n">public</span> <span class="n">class</span> <span class="n">ImageResponseEncoder</span> <span class="n">extends</span> <span class="n">ProtocolEncoderAdapter</span> <span class="p">{</span>
+
+    <span class="n">public</span> <span class="n">void</span> <span class="n">encode</span><span class="p">(</span><span class="n">IoSession</span> <span class="n">session</span><span class="p">,</span> <span class="n">Object</span> <span class="n">message</span><span class="p">,</span> <span class="n">ProtocolEncoderOutput</span> <span class="n">out</span><span class="p">)</span> <span class="n">throws</span> <span class="n">Exception</span> <span class="p">{</span>
+        <span class="n">ImageResponse</span> <span class="n">imageResponse</span> <span class="o">=</span> <span class="p">(</span><span class="n">ImageResponse</span><span class="p">)</span> <span class="n">message</span><span class="p">;</span>
+        <span class="n">byte</span><span class="o">[]</span> <span class="n">bytes1</span> <span class="o">=</span> <span class="n">getBytes</span><span class="p">(</span><span class="n">imageResponse</span><span class="o">.</span><span class="n">getImage1</span><span class="p">());</span>
+        <span class="n">byte</span><span class="o">[]</span> <span class="n">bytes2</span> <span class="o">=</span> <span class="n">getBytes</span><span class="p">(</span><span class="n">imageResponse</span><span class="o">.</span><span class="n">getImage2</span><span class="p">());</span>
+        <span class="nb">int</span> <span class="n">capacity</span> <span class="o">=</span> <span class="n">bytes1</span><span class="o">.</span><span class="nb">length</span> <span class="o">+</span> <span class="n">bytes2</span><span class="o">.</span><span class="nb">length</span> <span class="o">+</span> <span class="mi">8</span><span class="p">;</span>
+        <span class="n">IoBuffer</span> <span class="n">buffer</span> <span class="o">=</span> <span class="n">IoBuffer</span><span class="o">.</span><span class="n">allocate</span><span class="p">(</span><span class="n">capacity</span><span class="p">,</span> <span class="n">false</span><span class="p">);</span>
+        <span class="n">buffer</span><span class="o">.</span><span class="n">setAutoExpand</span><span class="p">(</span><span class="n">true</span><span class="p">);</span>
+        <span class="n">buffer</span><span class="o">.</span><span class="n">putInt</span><span class="p">(</span><span class="n">bytes1</span><span class="o">.</span><span class="nb">length</span><span class="p">);</span>
+        <span class="n">buffer</span><span class="o">.</span><span class="n">put</span><span class="p">(</span><span class="n">bytes1</span><span class="p">);</span>
+        <span class="n">buffer</span><span class="o">.</span><span class="n">putInt</span><span class="p">(</span><span class="n">bytes2</span><span class="o">.</span><span class="nb">length</span><span class="p">);</span>
+        <span class="n">buffer</span><span class="o">.</span><span class="n">put</span><span class="p">(</span><span class="n">bytes2</span><span class="p">);</span>
+        <span class="n">buffer</span><span class="o">.</span><span class="n">flip</span><span class="p">();</span>
+        <span class="n">out</span><span class="o">.</span><span class="nb">write</span><span class="p">(</span><span class="n">buffer</span><span class="p">);</span>
+    <span class="p">}</span>
+
+    <span class="n">private</span> <span class="n">byte</span><span class="o">[]</span> <span class="n">getBytes</span><span class="p">(</span><span class="n">BufferedImage</span> <span class="n">image</span><span class="p">)</span> <span class="n">throws</span> <span class="n">IOException</span> <span class="p">{</span>
+        <span class="n">ByteArrayOutputStream</span> <span class="n">baos</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ByteArrayOutputStream</span><span class="p">();</span>
+        <span class="n">ImageIO</span><span class="o">.</span><span class="nb">write</span><span class="p">(</span><span class="n">image</span><span class="p">,</span> <span class="s">&quot;PNG&quot;</span><span class="p">,</span> <span class="n">baos</span><span class="p">);</span>
+        <span class="k">return</span> <span class="n">baos</span><span class="o">.</span><span class="n">toByteArray</span><span class="p">();</span>
+    <span class="p">}</span>
+<span class="p">}</span>
+</pre></div>
+
+
+<p>Remarks:</p>
+<ul>
+<li>when it is impossible to calculate the length of the IoBuffer beforehand, you can use an auto-expanding buffer by calling buffer.setAutoExpand(true);</li>
+</ul>
+<p>Now let's have a look at decoding the response:</p>
+<div class="codehilite"><pre><span class="n">public</span> <span class="n">class</span> <span class="n">ImageResponseDecoder</span> <span class="n">extends</span> <span class="n">CumulativeProtocolDecoder</span> <span class="p">{</span>
+
+    <span class="n">private</span> <span class="n">static</span> <span class="n">final</span> <span class="n">String</span> <span class="n">DECODER_STATE_KEY</span> <span class="o">=</span> <span class="n">ImageResponseDecoder</span><span class="o">.</span><span class="n">class</span><span class="o">.</span><span class="n">getName</span><span class="p">()</span> <span class="o">+</span> <span class="s">&quot;.STATE&quot;</span><span class="p">;</span>
+
+    <span class="n">public</span> <span class="n">static</span> <span class="n">final</span> <span class="nb">int</span> <span class="n">MAX_IMAGE_SIZE</span> <span class="o">=</span> <span class="mi">5</span> <span class="o">*</span> <span class="mi">1024</span> <span class="o">*</span> <span class="mi">1024</span><span class="p">;</span>
+
+    <span class="n">private</span> <span class="n">static</span> <span class="n">class</span> <span class="n">DecoderState</span> <span class="p">{</span>
+        <span class="n">BufferedImage</span> <span class="n">image1</span><span class="p">;</span>
+    <span class="p">}</span>
+
+    <span class="n">protected</span> <span class="n">boolean</span> <span class="n">doDecode</span><span class="p">(</span><span class="n">IoSession</span> <span class="n">session</span><span class="p">,</span> <span class="n">IoBuffer</span> <span class="n">in</span><span class="p">,</span> <span class="n">ProtocolDecoderOutput</span> <span class="n">out</span><span class="p">)</span> <span class="n">throws</span> <span class="n">Exception</span> <span class="p">{</span>
+        <span class="n">DecoderState</span> <span class="n">decoderState</span> <span class="o">=</span> <span class="p">(</span><span class="n">DecoderState</span><span class="p">)</span> <span class="n">session</span><span class="o">.</span><span class="n">getAttribute</span><span class="p">(</span><span class="n">DECODER_STATE_KEY</span><span class="p">);</span>
+        <span class="k">if</span> <span class="p">(</span><span class="n">decoderState</span> <span class="o">==</span> <span class="n">null</span><span class="p">)</span> <span class="p">{</span>
+            <span class="n">decoderState</span> <span class="o">=</span> <span class="k">new</span> <span class="n">DecoderState</span><span class="p">();</span>
+            <span class="n">session</span><span class="o">.</span><span class="n">setAttribute</span><span class="p">(</span><span class="n">DECODER_STATE_KEY</span><span class="p">,</span> <span class="n">decoderState</span><span class="p">);</span>
+        <span class="p">}</span>
+        <span class="k">if</span> <span class="p">(</span><span class="n">decoderState</span><span class="o">.</span><span class="n">image1</span> <span class="o">==</span> <span class="n">null</span><span class="p">)</span> <span class="p">{</span>
+            <span class="sr">//</span> <span class="n">try</span> <span class="n">to</span> <span class="nb">read</span> <span class="n">first</span> <span class="n">image</span>
+            <span class="k">if</span> <span class="p">(</span><span class="n">in</span><span class="o">.</span><span class="n">prefixedDataAvailable</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="n">MAX_IMAGE_SIZE</span><span class="p">))</span> <span class="p">{</span>
+                <span class="n">decoderState</span><span class="o">.</span><span class="n">image1</span> <span class="o">=</span> <span class="n">readImage</span><span class="p">(</span><span class="n">in</span><span class="p">);</span>
+            <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
+                <span class="sr">//</span> <span class="ow">not</span> <span class="n">enough</span> <span class="n">data</span> <span class="n">available</span> <span class="n">to</span> <span class="nb">read</span> <span class="n">first</span> <span class="n">image</span>
+                <span class="k">return</span> <span class="n">false</span><span class="p">;</span>
+            <span class="p">}</span>
+        <span class="p">}</span>
+        <span class="k">if</span> <span class="p">(</span><span class="n">decoderState</span><span class="o">.</span><span class="n">image1</span> <span class="o">!=</span> <span class="n">null</span><span class="p">)</span> <span class="p">{</span>
+            <span class="sr">//</span> <span class="n">try</span> <span class="n">to</span> <span class="nb">read</span> <span class="n">second</span> <span class="n">image</span>
+            <span class="k">if</span> <span class="p">(</span><span class="n">in</span><span class="o">.</span><span class="n">prefixedDataAvailable</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="n">MAX_IMAGE_SIZE</span><span class="p">))</span> <span class="p">{</span>
+                <span class="n">BufferedImage</span> <span class="n">image2</span> <span class="o">=</span> <span class="n">readImage</span><span class="p">(</span><span class="n">in</span><span class="p">);</span>
+                <span class="n">ImageResponse</span> <span class="n">imageResponse</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ImageResponse</span><span class="p">(</span><span class="n">decoderState</span><span class="o">.</span><span class="n">image1</span><span class="p">,</span> <span class="n">image2</span><span class="p">);</span>
+                <span class="n">out</span><span class="o">.</span><span class="nb">write</span><span class="p">(</span><span class="n">imageResponse</span><span class="p">);</span>
+                <span class="n">decoderState</span><span class="o">.</span><span class="n">image1</span> <span class="o">=</span> <span class="n">null</span><span class="p">;</span>
+                <span class="k">return</span> <span class="n">true</span><span class="p">;</span>
+            <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
+                <span class="sr">//</span> <span class="ow">not</span> <span class="n">enough</span> <span class="n">data</span> <span class="n">available</span> <span class="n">to</span> <span class="nb">read</span> <span class="n">second</span> <span class="n">image</span>
+                <span class="k">return</span> <span class="n">false</span><span class="p">;</span>
+            <span class="p">}</span>
+        <span class="p">}</span>
+        <span class="k">return</span> <span class="n">false</span><span class="p">;</span>
+    <span class="p">}</span>
+
+    <span class="n">private</span> <span class="n">BufferedImage</span> <span class="n">readImage</span><span class="p">(</span><span class="n">IoBuffer</span> <span class="n">in</span><span class="p">)</span> <span class="n">throws</span> <span class="n">IOException</span> <span class="p">{</span>
+        <span class="nb">int</span> <span class="nb">length</span> <span class="o">=</span> <span class="n">in</span><span class="o">.</span><span class="n">getInt</span><span class="p">();</span>
+        <span class="n">byte</span><span class="o">[]</span> <span class="n">bytes</span> <span class="o">=</span> <span class="k">new</span> <span class="n">byte</span><span class="p">[</span><span class="nb">length</span><span class="p">];</span>
+        <span class="n">in</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">bytes</span><span class="p">);</span>
+        <span class="n">ByteArrayInputStream</span> <span class="n">bais</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ByteArrayInputStream</span><span class="p">(</span><span class="n">bytes</span><span class="p">);</span>
+        <span class="k">return</span> <span class="n">ImageIO</span><span class="o">.</span><span class="nb">read</span><span class="p">(</span><span class="n">bais</span><span class="p">);</span>
+    <span class="p">}</span>
+<span class="p">}</span>
+</pre></div>
+
+
+<p>Remarks:</p>
+<ul>
+<li>We store the state of the decoding process in a session attribute. It would also be possible to store this state in the Decoder object itself but this has several disadvantages:<ul>
+<li>every IoSession would need its own Decoder instance</li>
+<li>MINA ensures that there will never be more than one thread simultaneously executing the decode() function for the same IoSession, but it does not guarantee that it will always be the same thread. Suppose the first piece of data is handled by thread-1 who decides it cannot yet decode, when the next piece of data arrives, it could be handled by another thread. To avoid visibility problems, you must properly synchronize access to this decoder state (IoSession attributes are stored in a ConcurrentHashMap, so they are automatically visible to other threads).</li>
+<li>a discussion on the mailing list has lead to this conclusion: choosing between storing state in the IoSession or in the Decoder instance itself is more a matter of taste. To ensure that no two threads will run the decode method for the same IoSession, MINA needs to do some form of synchronization =&gt; this synchronization will also ensure you can't have the visibility problem described above.
+(Thanks to Adam Fisk for pointing this out)
+see <a href="http://www.nabble.com/Tutorial-on-ProtocolCodecFilter,-state-and-threads-t3965413.html">http://www.nabble.com/Tutorial-on-ProtocolCodecFilter,-state-and-threads-t3965413.html</a></li>
+</ul>
+</li>
+<li>IoBuffer.prefixedDataAvailable() is very convenient when your protocol uses a length-prefix; it supports a prefix of 1, 2 or 4 bytes.</li>
+<li>don't forget to reset the decoder state when you've decoded a response (removing the session attribute is another way to do it)</li>
+</ul>
+<p>If the response would consist of a single image, we would not need to store decoder state:</p>
+<div class="codehilite"><pre><span class="n">protected</span> <span class="n">boolean</span> <span class="n">doDecode</span><span class="p">(</span><span class="n">IoSession</span> <span class="n">session</span><span class="p">,</span> <span class="n">IoBuffer</span> <span class="n">in</span><span class="p">,</span> <span class="n">ProtocolDecoderOutput</span> <span class="n">out</span><span class="p">)</span> <span class="n">throws</span> <span class="n">Exception</span> <span class="p">{</span>
+    <span class="k">if</span> <span class="p">(</span><span class="n">in</span><span class="o">.</span><span class="n">prefixedDataAvailable</span><span class="p">(</span><span class="mi">4</span><span class="p">))</span> <span class="p">{</span>
+        <span class="nb">int</span> <span class="nb">length</span> <span class="o">=</span> <span class="n">in</span><span class="o">.</span><span class="n">getInt</span><span class="p">();</span>
+        <span class="n">byte</span><span class="o">[]</span> <span class="n">bytes</span> <span class="o">=</span> <span class="k">new</span> <span class="n">byte</span><span class="p">[</span><span class="nb">length</span><span class="p">];</span>
+        <span class="n">in</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">bytes</span><span class="p">);</span>
+        <span class="n">ByteArrayInputStream</span> <span class="n">bais</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ByteArrayInputStream</span><span class="p">(</span><span class="n">bytes</span><span class="p">);</span>
+        <span class="n">BufferedImage</span> <span class="n">image</span> <span class="o">=</span> <span class="n">ImageIO</span><span class="o">.</span><span class="nb">read</span><span class="p">(</span><span class="n">bais</span><span class="p">);</span>
+        <span class="n">out</span><span class="o">.</span><span class="nb">write</span><span class="p">(</span><span class="n">image</span><span class="p">);</span>
+        <span class="k">return</span> <span class="n">true</span><span class="p">;</span>
+    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
+        <span class="k">return</span> <span class="n">false</span><span class="p">;</span>
+    <span class="p">}</span>
+<span class="p">}</span>
+</pre></div>
+
+
+<p>Now let's glue it all together:</p>
+<div class="codehilite"><pre><span class="n">public</span> <span class="n">class</span> <span class="n">ImageCodecFactory</span> <span class="n">implements</span> <span class="n">ProtocolCodecFactory</span> <span class="p">{</span>
+    <span class="n">private</span> <span class="n">ProtocolEncoder</span> <span class="n">encoder</span><span class="p">;</span>
+    <span class="n">private</span> <span class="n">ProtocolDecoder</span> <span class="n">decoder</span><span class="p">;</span>
+
+    <span class="n">public</span> <span class="n">ImageCodecFactory</span><span class="p">(</span><span class="n">boolean</span> <span class="n">client</span><span class="p">)</span> <span class="p">{</span>
+        <span class="k">if</span> <span class="p">(</span><span class="n">client</span><span class="p">)</span> <span class="p">{</span>
+            <span class="n">encoder</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ImageRequestEncoder</span><span class="p">();</span>
+            <span class="n">decoder</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ImageResponseDecoder</span><span class="p">();</span>
+        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
+            <span class="n">encoder</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ImageResponseEncoder</span><span class="p">();</span>
+            <span class="n">decoder</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ImageRequestDecoder</span><span class="p">();</span>
+        <span class="p">}</span>
+    <span class="p">}</span>
+
+    <span class="n">public</span> <span class="n">ProtocolEncoder</span> <span class="n">getEncoder</span><span class="p">(</span><span class="n">IoSession</span> <span class="n">ioSession</span><span class="p">)</span> <span class="n">throws</span> <span class="n">Exception</span> <span class="p">{</span>
+        <span class="k">return</span> <span class="n">encoder</span><span class="p">;</span>
+    <span class="p">}</span>
+
+    <span class="n">public</span> <span class="n">ProtocolDecoder</span> <span class="n">getDecoder</span><span class="p">(</span><span class="n">IoSession</span> <span class="n">ioSession</span><span class="p">)</span> <span class="n">throws</span> <span class="n">Exception</span> <span class="p">{</span>
+        <span class="k">return</span> <span class="n">decoder</span><span class="p">;</span>
+    <span class="p">}</span>
+<span class="p">}</span>
+</pre></div>
+
+
+<p>Remarks:</p>
+<ul>
+<li>for every new session, MINA will ask the ImageCodecFactory for an encoder and a decoder.</li>
+<li>since our encoders and decoders store no conversational state, it is safe to let all sessions share a single instance.</li>
+</ul>
+<p>This is how the server would use the ProtocolCodecFactory:</p>
+<div class="codehilite"><pre><span class="n">public</span> <span class="n">class</span> <span class="n">ImageServer</span> <span class="p">{</span>
+    <span class="n">public</span> <span class="n">static</span> <span class="n">final</span> <span class="nb">int</span> <span class="n">PORT</span> <span class="o">=</span> <span class="mi">33789</span><span class="p">;</span>
+
+    <span class="n">public</span> <span class="n">static</span> <span class="n">void</span> <span class="n">main</span><span class="p">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="p">)</span> <span class="n">throws</span> <span class="n">IOException</span> <span class="p">{</span>
+        <span class="n">ImageServerIoHandler</span> <span class="n">handler</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ImageServerIoHandler</span><span class="p">();</span>
+        <span class="n">NioSocketAcceptor</span> <span class="n">acceptor</span> <span class="o">=</span> <span class="k">new</span> <span class="n">NioSocketAcceptor</span><span class="p">();</span>
+        <span class="n">acceptor</span><span class="o">.</span><span class="n">getFilterChain</span><span class="p">()</span><span class="o">.</span><span class="n">addLast</span><span class="p">(</span><span class="s">&quot;protocol&quot;</span><span class="p">,</span> <span class="k">new</span> <span class="n">ProtocolCodecFilter</span><span class="p">(</span><span class="k">new</span> <span class="n">ImageCodecFactory</span><span class="p">(</span><span class="n">false</span><span class="p">)));</span>
+        <span class="n">acceptor</span><span class="o">.</span><span class="n">setLocalAddress</span><span class="p">(</span><span class="k">new</span> <span class="n">InetSocketAddress</span><span class="p">(</span><span class="n">PORT</span><span class="p">));</span>
+        <span class="n">acceptor</span><span class="o">.</span><span class="n">setHandler</span><span class="p">(</span><span class="n">handler</span><span class="p">);</span>
+        <span class="n">acceptor</span><span class="o">.</span><span class="nb">bind</span><span class="p">();</span>
+        <span class="n">System</span><span class="o">.</span><span class="n">out</span><span class="o">.</span><span class="n">println</span><span class="p">(</span><span class="s">&quot;server is listenig at port &quot;</span> <span class="o">+</span> <span class="n">PORT</span><span class="p">);</span>
+    <span class="p">}</span>
+<span class="p">}</span>
+</pre></div>
+
+
+<p>Usage by the client is identical:</p>
+<div class="codehilite"><pre><span class="n">public</span> <span class="n">class</span> <span class="n">ImageClient</span> <span class="n">extends</span> <span class="n">IoHandlerAdapter</span> <span class="p">{</span>
+    <span class="n">public</span> <span class="n">static</span> <span class="n">final</span> <span class="nb">int</span> <span class="n">CONNECT_TIMEOUT</span> <span class="o">=</span> <span class="mi">3000</span><span class="p">;</span>
+
+    <span class="n">private</span> <span class="n">String</span> <span class="n">host</span><span class="p">;</span>
+    <span class="n">private</span> <span class="nb">int</span> <span class="n">port</span><span class="p">;</span>
+    <span class="n">private</span> <span class="n">SocketConnector</span> <span class="n">connector</span><span class="p">;</span>
+    <span class="n">private</span> <span class="n">IoSession</span> <span class="n">session</span><span class="p">;</span>
+    <span class="n">private</span> <span class="n">ImageListener</span> <span class="n">imageListener</span><span class="p">;</span>
+
+    <span class="n">public</span> <span class="n">ImageClient</span><span class="p">(</span><span class="n">String</span> <span class="n">host</span><span class="p">,</span> <span class="nb">int</span> <span class="n">port</span><span class="p">,</span> <span class="n">ImageListener</span> <span class="n">imageListener</span><span class="p">)</span> <span class="p">{</span>
+        <span class="n">this</span><span class="o">.</span><span class="n">host</span> <span class="o">=</span> <span class="n">host</span><span class="p">;</span>
+        <span class="n">this</span><span class="o">.</span><span class="n">port</span> <span class="o">=</span> <span class="n">port</span><span class="p">;</span>
+        <span class="n">this</span><span class="o">.</span><span class="n">imageListener</span> <span class="o">=</span> <span class="n">imageListener</span><span class="p">;</span>
+        <span class="n">connector</span> <span class="o">=</span> <span class="k">new</span> <span class="n">NioSocketConnector</span><span class="p">();</span>
+        <span class="n">connector</span><span class="o">.</span><span class="n">getFilterChain</span><span class="p">()</span><span class="o">.</span><span class="n">addLast</span><span class="p">(</span><span class="s">&quot;codec&quot;</span><span class="p">,</span> <span class="k">new</span> <span class="n">ProtocolCodecFilter</span><span class="p">(</span><span class="k">new</span> <span class="n">ImageCodecFactory</span><span class="p">(</span><span class="n">true</span><span class="p">)));</span>
+        <span class="n">connector</span><span class="o">.</span><span class="n">setHandler</span><span class="p">(</span><span class="n">this</span><span class="p">);</span>
+    <span class="p">}</span>
+
+    <span class="n">public</span> <span class="n">void</span> <span class="n">messageReceived</span><span class="p">(</span><span class="n">IoSession</span> <span class="n">session</span><span class="p">,</span> <span class="n">Object</span> <span class="n">message</span><span class="p">)</span> <span class="n">throws</span> <span class="n">Exception</span> <span class="p">{</span>
+        <span class="n">ImageResponse</span> <span class="n">response</span> <span class="o">=</span> <span class="p">(</span><span class="n">ImageResponse</span><span class="p">)</span> <span class="n">message</span><span class="p">;</span>
+        <span class="n">imageListener</span><span class="o">.</span><span class="n">onImages</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">getImage1</span><span class="p">(),</span> <span class="n">response</span><span class="o">.</span><span class="n">getImage2</span><span class="p">());</span>
+    <span class="p">}</span>
+    <span class="o">...</span>
+</pre></div>
+
+
+<p>For completeness, I will add the code for the server-side IoHandler:</p>
+<div class="codehilite"><pre><span class="n">public</span> <span class="n">class</span> <span class="n">ImageServerIoHandler</span> <span class="n">extends</span> <span class="n">IoHandlerAdapter</span> <span class="p">{</span>
+
+    <span class="n">private</span> <span class="n">final</span> <span class="n">static</span> <span class="n">String</span> <span class="n">characters</span> <span class="o">=</span> <span class="s">&quot;mina rocks abcdefghijklmnopqrstuvwxyz0123456789&quot;</span><span class="p">;</span>
+
+    <span class="n">public</span> <span class="n">static</span> <span class="n">final</span> <span class="n">String</span> <span class="n">INDEX_KEY</span> <span class="o">=</span> <span class="n">ImageServerIoHandler</span><span class="o">.</span><span class="n">class</span><span class="o">.</span><span class="n">getName</span><span class="p">()</span> <span class="o">+</span> <span class="s">&quot;.INDEX&quot;</span><span class="p">;</span>
+
+    <span class="n">private</span> <span class="n">Logger</span> <span class="n">logger</span> <span class="o">=</span> <span class="n">LoggerFactory</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="n">this</span><span class="o">.</span><span class="n">getClass</span><span class="p">());</span>
+
+    <span class="n">public</span> <span class="n">void</span> <span class="n">sessionOpened</span><span class="p">(</span><span class="n">IoSession</span> <span class="n">session</span><span class="p">)</span> <span class="n">throws</span> <span class="n">Exception</span> <span class="p">{</span>
+        <span class="n">session</span><span class="o">.</span><span class="n">setAttribute</span><span class="p">(</span><span class="n">INDEX_KEY</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
+    <span class="p">}</span>
+
+    <span class="n">public</span> <span class="n">void</span> <span class="n">exceptionCaught</span><span class="p">(</span><span class="n">IoSession</span> <span class="n">session</span><span class="p">,</span> <span class="n">Throwable</span> <span class="n">cause</span><span class="p">)</span> <span class="n">throws</span> <span class="n">Exception</span> <span class="p">{</span>
+        <span class="n">IoSessionLogger</span> <span class="n">sessionLogger</span> <span class="o">=</span> <span class="n">IoSessionLogger</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="n">session</span><span class="p">,</span> <span class="n">logger</span><span class="p">);</span>
+        <span class="n">sessionLogger</span><span class="o">.</span><span class="nb">warn</span><span class="p">(</span><span class="n">cause</span><span class="o">.</span><span class="n">getMessage</span><span class="p">(),</span> <span class="n">cause</span><span class="p">);</span>
+    <span class="p">}</span>
+
+    <span class="n">public</span> <span class="n">void</span> <span class="n">messageReceived</span><span class="p">(</span><span class="n">IoSession</span> <span class="n">session</span><span class="p">,</span> <span class="n">Object</span> <span class="n">message</span><span class="p">)</span> <span class="n">throws</span> <span class="n">Exception</span> <span class="p">{</span>
+        <span class="n">ImageRequest</span> <span class="n">request</span> <span class="o">=</span> <span class="p">(</span><span class="n">ImageRequest</span><span class="p">)</span> <span class="n">message</span><span class="p">;</span>
+        <span class="n">String</span> <span class="n">text1</span> <span class="o">=</span> <span class="n">generateString</span><span class="p">(</span><span class="n">session</span><span class="p">,</span> <span class="n">request</span><span class="o">.</span><span class="n">getNumberOfCharacters</span><span class="p">());</span>
+        <span class="n">String</span> <span class="n">text2</span> <span class="o">=</span> <span class="n">generateString</span><span class="p">(</span><span class="n">session</span><span class="p">,</span> <span class="n">request</span><span class="o">.</span><span class="n">getNumberOfCharacters</span><span class="p">());</span>
+        <span class="n">BufferedImage</span> <span class="n">image1</span> <span class="o">=</span> <span class="n">createImage</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">text1</span><span class="p">);</span>
+        <span class="n">BufferedImage</span> <span class="n">image2</span> <span class="o">=</span> <span class="n">createImage</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">text2</span><span class="p">);</span>
+        <span class="n">ImageResponse</span> <span class="n">response</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ImageResponse</span><span class="p">(</span><span class="n">image1</span><span class="p">,</span> <span class="n">image2</span><span class="p">);</span>
+        <span class="n">session</span><span class="o">.</span><span class="nb">write</span><span class="p">(</span><span class="n">response</span><span class="p">);</span>
+    <span class="p">}</span>
+
+    <span class="n">private</span> <span class="n">BufferedImage</span> <span class="n">createImage</span><span class="p">(</span><span class="n">ImageRequest</span> <span class="n">request</span><span class="p">,</span> <span class="n">String</span> <span class="n">text</span><span class="p">)</span> <span class="p">{</span>
+        <span class="n">BufferedImage</span> <span class="n">image</span> <span class="o">=</span> <span class="k">new</span> <span class="n">BufferedImage</span><span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">getWidth</span><span class="p">(),</span> <span class="n">request</span><span class="o">.</span><span class="n">getHeight</span><span class="p">(),</span> <span class="n">BufferedImage</span><span class="o">.</span><span class="n">TYPE_BYTE_INDEXED</span><span class="p">);</span>
+        <span class="n">Graphics</span> <span class="n">graphics</span> <span class="o">=</span> <span class="n">image</span><span class="o">.</span><span class="n">createGraphics</span><span class="p">();</span>
+        <span class="n">graphics</span><span class="o">.</span><span class="n">setColor</span><span class="p">(</span><span class="n">Color</span><span class="o">.</span><span class="n">YELLOW</span><span class="p">);</span>
+        <span class="n">graphics</span><span class="o">.</span><span class="n">fillRect</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">image</span><span class="o">.</span><span class="n">getWidth</span><span class="p">(),</span> <span class="n">image</span><span class="o">.</span><span class="n">getHeight</span><span class="p">());</span>
+        <span class="n">Font</span> <span class="n">serif</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Font</span><span class="p">(</span><span class="s">&quot;serif&quot;</span><span class="p">,</span> <span class="n">Font</span><span class="o">.</span><span class="n">PLAIN</span><span class="p">,</span> <span class="mi">30</span><span class="p">);</span>
+        <span class="n">graphics</span><span class="o">.</span><span class="n">setFont</span><span class="p">(</span><span class="n">serif</span><span class="p">);</span>
+        <span class="n">graphics</span><span class="o">.</span><span class="n">setColor</span><span class="p">(</span><span class="n">Color</span><span class="o">.</span><span class="n">BLUE</span><span class="p">);</span>
+        <span class="n">graphics</span><span class="o">.</span><span class="n">drawString</span><span class="p">(</span><span class="n">text</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">50</span><span class="p">);</span>
+        <span class="k">return</span> <span class="n">image</span><span class="p">;</span>
+    <span class="p">}</span>
+
+    <span class="n">private</span> <span class="n">String</span> <span class="n">generateString</span><span class="p">(</span><span class="n">IoSession</span> <span class="n">session</span><span class="p">,</span> <span class="nb">int</span> <span class="nb">length</span><span class="p">)</span> <span class="p">{</span>
+        <span class="n">Integer</span> <span class="nb">index</span> <span class="o">=</span> <span class="p">(</span><span class="n">Integer</span><span class="p">)</span> <span class="n">session</span><span class="o">.</span><span class="n">getAttribute</span><span class="p">(</span><span class="n">INDEX_KEY</span><span class="p">);</span>
+        <span class="n">StringBuffer</span> <span class="n">buffer</span> <span class="o">=</span> <span class="k">new</span> <span class="n">StringBuffer</span><span class="p">(</span><span class="nb">length</span><span class="p">);</span>
+
+        <span class="k">while</span> <span class="p">(</span><span class="n">buffer</span><span class="o">.</span><span class="nb">length</span><span class="p">()</span> <span class="o">&lt;</span> <span class="nb">length</span><span class="p">)</span> <span class="p">{</span>
+            <span class="n">buffer</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">characters</span><span class="o">.</span><span class="n">charAt</span><span class="p">(</span><span class="nb">index</span><span class="p">));</span>
+            <span class="nb">index</span><span class="o">++</span><span class="p">;</span>
+            <span class="k">if</span> <span class="p">(</span><span class="nb">index</span> <span class="o">&gt;=</span> <span class="n">characters</span><span class="o">.</span><span class="nb">length</span><span class="p">())</span> <span class="p">{</span>
+                <span class="nb">index</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
+            <span class="p">}</span>
+        <span class="p">}</span>
+        <span class="n">session</span><span class="o">.</span><span class="n">setAttribute</span><span class="p">(</span><span class="n">INDEX_KEY</span><span class="p">,</span> <span class="nb">index</span><span class="p">);</span>
+        <span class="k">return</span> <span class="n">buffer</span><span class="o">.</span><span class="n">toString</span><span class="p">();</span>
+    <span class="p">}</span>
+<span class="p">}</span>
+</pre></div>
+
+
+<p><img alt="" src="../../../staticresources/images/mina/codec-filter.jpeg" /></p>
+<h2 id="conclusion">Conclusion</h2>
+<p>There is a lot more to tell about encoding and decoding. But I hope this tutorial already gets you started.
+I will try to add something about the DemuxingProtocolCodecFactory in the near future.
+And then we will also have a look at how to use a delimiter instead of a length prefix.</p>
+
+
+    <div class="nav">
+        <div class="nav_prev">
+        
+            <a href="../ch8-iobuffer/ch8-iobuffer.html">Chapter 8 - IoBuffer</a>
+		
+        </div>
+        <div class="nav_up">
+        
+            <a href="../user-guide-toc.html">User Guide</a>
+		
+        </div>
+        <div class="nav_next">
+        
+            <a href="../ch10-executor-filter/ch10-executor-filter.html">Chapter 10 - Executor Filter</a>
+		
+        </div>
+        <div class="clearfix"></div>
+    </div>
+
+
+                </div><!-- rightColumn -->
+                <div id="endContent"></div>
+            </div><!-- content -->
+            <div id="footer">&copy; 2003-2012, <a href="http://www.apache.org">The Apache Software Foundation</a> - <a href="privacy-policy.html">Privacy Policy</a><br />
+                Apache MINA, MINA, Apache Vysper, Vysper, Apache SSHd, SSHd, Apache FtpServer, FtpServer, Apache AsyncWeb, AsyncWeb,
+                Apache, the Apache feather logo, and the Apache Mina project logos are trademarks of The Apache Software Foundation.
+            </div>
+        </div><!-- container -->
+    </body>
+</html>
+



Mime
View raw message