|
PaddingSingleBuffer |
|
1 /* $RCSfile: PaddingSingleBuffer.java,v $
2 * $Revision: 1.8 $
3 * $Date: 2002/01/17 19:24:55 $
4 * $Author: uwe $
5 * $State: Exp $
6 *
7 * Created on August 20, 2001 1:58 PM
8 *
9 * Copyright (C) 2001 Uwe Guenther <uwe@cscc.de>
10 *
11 * This file is part of the jhbci JCE-ServiceProvider. The jhbci JCE-
12 * ServiceProvider is a library, written in JavaTM, that should be
13 * used in HBCI banking applications (clients and may be servers),
14 * to do cryptographic operations.
15 *
16 * The jhbci library is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU Lesser General Public
18 * License as published by the Free Software Foundation; either
19 * version 2.1 of the License, or (at your option) any later version.
20 *
21 * The jhbci library is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 * Lesser General Public License for more details.
25 *
26 * You should have received a copy of the GNU Lesser General Public
27 * License along with this library; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 *
30 */
31
32 package de.cscc.crypto.provider;
33
34 import java.util.Arrays;
35
36 import javax.crypto.IllegalBlockSizeException;
37
38 import de.cscc.crypto.util.ByteUtil;
39
40 /**
41 * PaddingSingleBuffer Class.
42 *
43 * @author <a href=mailto:uwe@cscc.de>Uwe Günther</a>
44 * @version $Revision: 1.8 $
45 */
46 class PaddingSingleBuffer implements Cloneable {
47
48 /** The internal buffer. */
49 private byte[] buffer;
50
51 /** The internal buffer counter. */
52 private int bufferCounter;
53
54 /** Don't create PaddingSingleBuffer with default constructor. */
55 private PaddingSingleBuffer() {}
56
57 /**
58 * Create a new buffer with size bytes.
59 * @param size the buffer length in bytes.
60 */
61 public PaddingSingleBuffer(int size) {
62
63 this.buffer = new byte[size];
64 this.bufferCounter = 0;
65 }
66
67 /**
68 * Create a new buffer from an existing buffer.
69 * @param buffer the existing buffer.
70 */
71 public PaddingSingleBuffer(PaddingSingleBuffer buffer) {
72
73 this.buffer = new byte[buffer.buffer.length];
74 System.arraycopy(buffer.buffer, 0, this.buffer, 0, buffer.buffer.length);
75
76 this.bufferCounter = buffer.bufferCounter;
77 }
78
79 /**
80 * Creates and returns a deep copy of this object.
81 *
82 * @return a clone of this instance.
83 * @see java.lang.Cloneable
84 * @exception CloneNotSupportedException if the object's class does not
85 * support the <code>Cloneable</code> interface. Subclasses
86 * that override the <code>clone</code> method can also
87 * throw this exception to indicate that an instance cannot
88 * be cloned.
89 */
90 public Object clone() throws CloneNotSupportedException {
91 PaddingSingleBuffer result = (PaddingSingleBuffer) super.clone();
92 result.buffer = (byte[]) this.buffer.clone();
93 return result;
94 }
95
96 /**
97 * Indicates whether some other object is "equal to" this one.
98 *
99 * @param obj the reference object with which to compare.
100 * @return <code>true</code> if this object is the same as the obj
101 * argument; <code>false</code> otherwise.
102 * @see #hashCode()
103 * @see java.util.Hashtable
104 */
105 public boolean equals(Object obj) {
106
107 //Only for performance.
108 if (this == obj) {
109 return true;
110 }
111
112 //If obj == null then instanceof returns false, see JLS 15.20.2
113 if (!(obj instanceof PaddingSingleBuffer)) {
114 return false;
115 }
116
117 PaddingSingleBuffer other = (PaddingSingleBuffer) obj;
118 return this.bufferCounter == other.bufferCounter &&
119 Arrays.equals(this.buffer, other.buffer) ;
120 }
121
122 /**
123 * Returns a hash code value for the object.
124 *
125 * @return a hash code value for this object.
126 * @see #equals(java.lang.Object)
127 * @see java.util.Hashtable
128 */
129 public int hashCode() {
130
131 int result = 17;
132
133 result = 37*result + bufferCounter;
134
135 for (int i = 0; i < this.buffer.length; i++) {
136 result = 37*result + buffer[i];
137 }
138
139 return result;
140 }
141
142 /**
143 * Returns a string representation of the object.
144 *
145 * @return a string representation of the object.
146 */
147 public String toString() {
148
149 return "buffer: [" + ByteUtil.toHex(this.buffer) + "] " +
150 "bufferCounter: [" + this.bufferCounter + "]";
151 }
152
153 /**
154 * Add a byte to the buffer.
155 * @param b the byte to add.
156 * @throws IllegalArgumentException if the internal buffer is full.
157 */
158 public void add(byte b) throws IllegalArgumentException {
159
160 if (isFull()) {
161 throw new IllegalArgumentException("Buffer is full.");
162 }
163
164 this.buffer[this.bufferCounter] = b;
165 this.bufferCounter++;
166 }
167
168 /**
169 * Returns the internal buffer and create an new internal buffer.
170 * This means we will return the internal byte array and will reset it.
171 *
172 * @return the number off bytes that stored in output.
173 * @param output the output buffer.
174 * @param outputOffset the offset in output where output starts.
175 * @throws IllegalBlockSizeException if the usable range is lesser than the
176 * initial size with this buffer was constructed.
177 */
178 public int fetch(byte[] output, int outputOffset)
179 throws IllegalBlockSizeException {
180
181 if (output.length-outputOffset < this.buffer.length) {
182 throw new IllegalBlockSizeException("The input block range is "
183 + (output.length-outputOffset)
184 + " bytes long, but it should be " + this.buffer.length
185 + " or longer.");
186 }
187
188 // Copy the content to output and reset buffer with (byte)0x00.
189 for (int i = 0; i < this.buffer.length; i++) {
190 output[outputOffset+i] = this.buffer[i];
191 this.buffer[i] = (byte) 0x00;
192 }
193
194 // Reset the bufferCounter.
195 this.bufferCounter = 0;
196
197 //Returns the buffer content.
198 return this.buffer.length;
199 }
200
201 /**
202 * Returns true if the internal buffer is full.
203 *
204 * @return true if the buffer is full, false otherwise.
205 */
206 public boolean isFull() {
207 return this.bufferCounter == this.buffer.length;
208 }
209
210 /**
211 * Write the number of free bytes in the last byte,
212 * and set the bufferCounter to end of buffer.
213 * @throws IllegalStateException if the buffer is full.
214 */
215 public void doISO10126OctetPadding() throws IllegalStateException {
216
217 //If the buffer is full, we can pad the buffer, becaus
218 //we would lose the last byte in the buffer.
219 if (isFull()){
220 throw new IllegalStateException("The buffer is full, you can not "
221 + "pad a full buffer, fetch the data with fetch(), "
222 + "and invoke reset().");
223 }
224
225 //Write the number of free bytes in the last byte.
226 this.buffer[this.buffer.length-1] =
227 (byte) ((this.buffer.length-this.bufferCounter) & 0x000000ff);
228
229 //set the bufferCounter to end of buffer.
230 this.bufferCounter = this.buffer.length;
231 }
232
233 /**
234 * Returns the length of the buffer in bytes.
235 *
236 * @return the length of the buffer in bytes.
237 */
238 public int getLength() {
239 return this.buffer.length;
240 }
241
242 /**
243 * Returns the number of bytes that the buffer contains.
244 * @return the number of bytes that the buffer contains.
245 */
246 public int hasBytes() {
247 return this.bufferCounter;
248 }
249 }
250
|
PaddingSingleBuffer |
|