View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  
28  package org.apache.http;
29  
30  import java.io.IOException;
31  import java.nio.ByteBuffer;
32  import java.nio.channels.ClosedChannelException;
33  import java.nio.channels.WritableByteChannel;
34  import java.nio.charset.Charset;
35  
36  import org.apache.http.nio.util.ExpandableBuffer;
37  import org.apache.http.nio.util.HeapByteBufferAllocator;
38  
39  public class WritableByteChannelMock implements WritableByteChannel {
40  
41      static class InternalBuffer extends ExpandableBuffer {
42  
43          private final int capacityLimit;
44          private int curCapacity;
45  
46          public InternalBuffer(final int bufferSize, final int capacityLimit) {
47              super(bufferSize, HeapByteBufferAllocator.INSTANCE);
48              this.capacityLimit = capacityLimit;
49              this.curCapacity = capacityLimit;
50          }
51  
52          public int write(final ByteBuffer src) {
53              if (src == null) {
54                  return 0;
55              }
56              setInputMode();
57              if (this.capacityLimit > 0) {
58                  if (this.curCapacity > 0) {
59                      final int requiredCapacity = this.buffer.position() + this.curCapacity;
60                      ensureCapacity(requiredCapacity);
61                      int count = 0;
62                      while (src.hasRemaining() && this.curCapacity > 0) {
63                          this.buffer.put(src.get());
64                          count++;
65                          this.curCapacity--;
66                      }
67                      return count;
68                  } else {
69                      return 0;
70                  }
71              } else {
72                  final int chunk = src.remaining();
73                  final int requiredCapacity = this.buffer.position() + src.remaining();
74                  ensureCapacity(requiredCapacity);
75                  this.buffer.put(src);
76                  return chunk;
77              }
78          }
79  
80          @Override
81          protected void clear() {
82              super.clear();
83          }
84  
85          public void resetCapacity() {
86              this.curCapacity = this.capacityLimit;
87          }
88  
89          private static String toString(
90              final byte[] b, final int off, final int len, final Charset charset) {
91              return new String(b, off, len, charset);
92          }
93  
94          public String dump(final Charset charset) {
95              setOutputMode();
96              if (this.buffer.hasArray()) {
97                  return toString(this.buffer.array(), this.buffer.position(), this.buffer.limit(),
98                      charset);
99              } else {
100                 final ByteBuffer dup = this.buffer.duplicate();
101                 final byte[] b = new byte[dup.remaining()];
102                 int i = 0;
103                 while (dup.hasRemaining()) {
104                     b[i] = dup.get();
105                     i++;
106                 }
107                 return toString(b, 0, b.length, charset);
108             }
109         }
110 
111     }
112 
113     private final InternalBuffer buf;
114     private boolean closed;
115 
116     public WritableByteChannelMock(final int size, final int capacityLimit) {
117         super();
118         this.buf = new InternalBuffer(size, capacityLimit);
119     }
120 
121     public WritableByteChannelMock(final int size) {
122         this(size, 0);
123     }
124 
125     @Override
126     public int write(final ByteBuffer src) throws IOException {
127         if (this.closed) {
128             throw new ClosedChannelException();
129         }
130         return this.buf.write(src);
131     }
132 
133     @Override
134     public boolean isOpen() {
135         return !this.closed;
136     }
137 
138     @Override
139     public void close() throws IOException {
140         this.closed = true;
141     }
142 
143     public void flush() {
144         this.buf.resetCapacity();
145     }
146 
147     public void reset() {
148         this.buf.resetCapacity();
149         this.buf.clear();
150     }
151 
152     public String dump(final Charset charset){
153         return this.buf.dump(charset);
154     }
155 
156 }