View Javadoc
1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License.
18   *
19   */
20  package org.apache.directory.mavibot.btree.serializer;
21  
22  
23  import java.io.EOFException;
24  import java.io.IOException;
25  import java.nio.ByteBuffer;
26  import java.nio.channels.FileChannel;
27  
28  
29  /**
30   * A class used to hide the buffer read from the underlying file.
31   * 
32   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
33   */
34  public class BufferHandler
35  {
36      /** The channel we read bytes from */
37      private FileChannel channel;
38  
39      /** The buffer containing the bytes we read from the channel */
40      private ByteBuffer buffer;
41  
42  
43      /**
44       * Create a new BufferHandler 
45       * @param buffer The buffer used to transfer data
46       */
47      public BufferHandler( byte[] buffer )
48      {
49          this.buffer = ByteBuffer.allocate( buffer.length );
50          this.buffer.put( buffer );
51          this.buffer.flip();
52      }
53  
54  
55      /**
56       * Create a new BufferHandler 
57       * @param channel The channel to read
58       * @param buffer The buffer used to transfer data
59       */
60      public BufferHandler( FileChannel channel, ByteBuffer buffer )
61      {
62          this.channel = channel;
63          this.buffer = buffer;
64  
65          try
66          {
67              // Initial read
68              channel.read( buffer );
69              buffer.flip();
70          }
71          catch ( IOException ioe )
72          {
73  
74          }
75      }
76  
77  
78      public byte[] getBuffer()
79      {
80          byte[] bytes = new byte[buffer.capacity()];
81  
82          buffer.get( bytes );
83  
84          return bytes;
85      }
86  
87  
88      /**
89       * Read a buffer containing the given number of bytes
90       * @param len The number of bytes to read
91       * @return
92       */
93      public byte[] read( int len ) throws IOException
94      {
95          byte[] result = new byte[len];
96  
97          if ( len <= buffer.remaining() )
98          {
99              buffer.get( result );
100 
101             return result;
102         }
103 
104         int requested = len;
105         int position = 0;
106 
107         while ( requested != 0 )
108         {
109             int nbRemainingRead = buffer.limit() - buffer.position();
110 
111             if ( nbRemainingRead > requested )
112             {
113                 buffer.get( result, position, requested );
114                 break;
115             }
116             else
117             {
118                 System.arraycopy( buffer.array(), buffer.position(), result, position, nbRemainingRead );
119                 position += nbRemainingRead;
120             }
121 
122             buffer.clear();
123 
124             if ( channel != null )
125             {
126                 int nbReads = channel.read( buffer );
127                 buffer.flip();
128 
129                 if ( nbReads <= 0 )
130                 {
131                     throw new EOFException();
132                 }
133             }
134             else
135             {
136                 throw new IOException( "Not enough bytes in the buffer" );
137             }
138 
139             requested -= nbRemainingRead;
140         }
141 
142         return result;
143     }
144 }