Follow Techotopia on Twitter

On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
System/Network Admin
Programming
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Databases
Mail Systems
openSolaris
Eclipse Documentation
Techotopia.com
Virtuatopia.com

How To Guides
Virtualization
General System Admin
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Windows
Problem Solutions

  




 

 

Thinking in Java
Prev Contents / Index Next

Buffer details

A Buffer consists of data and four indexes to access and manipulate this data efficiently: mark, position, limit and capacity. There are methods to set and reset these indexes and to query their value.

capacity( )

Returns the buffer’s capacity

clear( )

Clears the buffer, sets the position to zero, and limit to capacity. You call this method to overwrite an existing buffer.

flip( )

Sets limit to position and position to zero. This method is used to prepare the buffer for a read after data has been written into it.

limit( )

Returns the value of limit.

limit(int lim)

Sets the value of limit.

mark( )

Sets mark at position.

position( )

Returns the value of position.

position(int pos)

Sets the value of position.

remaining( )

Returns (limit - position).

hasRemaining( )

Returns true if there are any elements between position and limit.

Methods that insert and extract data from the buffer update these indexes to reflect the changes.

This example uses a very simple algorithm (swapping adjacent characters) to scramble and unscramble characters in a CharBuffer:

//: c12:UsingBuffers.java
import java.nio.*;
import com.bruceeckel.simpletest.*;

public class UsingBuffers {
  private static Test monitor = new Test();
  private static void symmetricScramble(CharBuffer buffer){
    while(buffer.hasRemaining()) {
      buffer.mark();
      char c1 = buffer.get();
      char c2 = buffer.get();
      buffer.reset();
      buffer.put(c2).put(c1);
    }
  }
  public static void main(String[] args) {
    char[] data = "UsingBuffers".toCharArray();
    ByteBuffer bb = ByteBuffer.allocate(data.length * 2);
    CharBuffer cb = bb.asCharBuffer();
    cb.put(data);
    System.out.println(cb.rewind());
    symmetricScramble(cb);
    System.out.println(cb.rewind());
    symmetricScramble(cb);
    System.out.println(cb.rewind());
    monitor.expect(new String[] {
      "UsingBuffers",
      "sUniBgfuefsr",
      "UsingBuffers"
    });
  }
} ///:~


Although you could produce a CharBuffer directly by calling wrap( ) with a char array, an underlying ByteBuffer is allocated instead, and a CharBuffer is produced as a view on the ByteBuffer. This emphasizes that fact that the goal is always to manipulate a ByteBuffer, since that is what interacts with a channel.

Here’s what the buffer looks like after the put( ):

TIJ330.png

The position points to the first element in the buffer, and the capacity and limit point to the last element.

In symmetricScramble( ), the while loop iterates until position is equivalent to limit. The position of the buffer changes when a relative get( ) or put( ) function is called on it. You can also call absolute get( ) and put( ) methods that include an index argument, which is the location where the get( ) or put( ) takes place. These methods do not modify the value of the buffer’s position.

When the control enters the while loop, the value of mark is set using mark( ) call. The state of the buffer then:

TIJ331.png

The two relative get( ) calls save the value of the first two characters in variables c1 and c2. After these two calls, the buffer looks like this:

TIJ332.png

To perform the swap, we need to write c2 at position = 0 and c1 at position = 1. We can either use the absolute put method to achieve this, or set the value of position to mark, which is what reset( ) does:

TIJ333.png

The two put( ) methods write c2 and then c1:

TIJ334.png

During the next iteration of the loop, mark is set to the current value of position:

TIJ335.png

The process continues until the entire buffer is traversed. At the end of the while loop, position is at the end of the buffer. If you print the buffer, only the characters between the position and limit are printed. Thus, if you want to show the entire contents of the buffer you must set position to the start of the buffer using rewind( ). Here is the state of buffer after the rewind( ) call (the value of mark becomes undefined):

TIJ336.png

When the function symmetricScramble( ) is called again, the CharBuffer undergoes the same process and is restored to its original state.
Thinking in Java
Prev Contents / Index Next


 
 
   Reproduced courtesy of Bruce Eckel, MindView, Inc. Design by Interspire