View Javadoc

1   /*
2    *   Copyright 2004 The Apache Software Foundation
3    *
4    *   Licensed under the Apache License, Version 2.0 (the "License");
5    *   you may not use this file except in compliance with the License.
6    *   You may obtain a copy of the License at
7    *
8    *       http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *   Unless required by applicable law or agreed to in writing, software
11   *   distributed under the License is distributed on an "AS IS" BASIS,
12   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *   See the License for the specific language governing permissions and
14   *   limitations under the License.
15   *
16   */
17  package org.apache.asn1.codec.stateful.examples;
18  
19  import java.nio.ByteBuffer;
20  
21  import org.apache.asn1.codec.DecoderException;
22  import org.apache.asn1.codec.stateful.AbstractStatefulDecoder;
23  
24  /***
25   * Document me.
26   * 
27   * @author <a href="mailto:dev@directory.apache.org"> Apache Directory
28   *         Project</a> $Rev: 161723 $
29   */
30  public class HexDecoder extends AbstractStatefulDecoder
31  {
32      private ByteBuffer decoded = ByteBuffer.allocate( 128 ) ;
33      private byte lsn ;
34      private byte msn ;
35      private boolean expectingMsn = true ;
36  
37  
38      public void decode( Object chunk ) throws DecoderException
39      {
40          ByteBuffer encoded = ( ByteBuffer ) chunk;
41  
42          if ( encoded == null || !encoded.hasRemaining() )
43          {
44              return;
45          }
46  
47          while ( encoded.hasRemaining() )
48          {
49              if ( ! decoded.hasRemaining() )
50              {
51                  decoded.flip();
52                  super.decodeOccurred( decoded );
53                  decoded.clear();
54              }
55  
56              if ( expectingMsn )
57              {
58                  msn = encoded.get();
59                  expectingMsn = false;
60              }
61              else
62              {
63                  lsn = encoded.get();
64                  expectingMsn = true;
65              }
66  
67              /* if we've hit the most significant nibble then we have two hex
68               * characters as bytes so we need to compute and add the byte to
69               * the buffer
70               */
71              if ( expectingMsn )
72              {
73                  byte bite = getNibble( lsn );
74                  bite |= ( getNibble( msn ) << 4 );
75                  decoded.put( bite );
76              }
77          }
78  
79          /* only trigger a decode callback if we have seen an even number of
80           * hex character bytes in which case we're in the expectingMsn state
81           * this will flush out what's siting in the buffer automatically
82           */
83          if ( expectingMsn )
84          {
85              decoded.flip();
86              super.decodeOccurred( decoded );
87              decoded.clear();
88          }
89      }
90  
91  
92  
93      private byte getNibble( byte ch ) throws DecoderException
94      {
95          // lowercase the character if it is in upper case
96          if ( ch > 64 && ch < 91 )
97          {
98              ch -= 32;
99          }
100 
101         switch(ch)
102         {
103             case 48:
104                 return 0 ;
105             case 49:
106                 return 1 ;
107             case 50:
108                 return 2 ;
109             case 51:
110                 return 3 ;
111             case 52:
112                 return 4 ;
113             case 53:
114                 return 5 ;
115             case 54:
116                 return 6 ;
117             case 55:
118                 return 7 ;
119             case 56:
120                 return 8 ;
121             case 57:
122                 return 9 ;
123             case 97:
124                 return 10 ;
125             case 98:
126                 return 11 ;
127             case 99:
128                 return 12 ;
129             case 100:
130                 return 13 ;
131             case 101:
132                 return 14 ;
133             case 102:
134                 return 15 ;
135             default:
136                 throw new DecoderException( "non-hex character '" + (char) ch
137                     + "' encountered" );
138         }
139     }
140 }