001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018 package org.apache.geronimo.util.encoders;
019
020
021 /**
022 * a buffering class to allow translation from one format to another to
023 * be done in discrete chunks.
024 */
025 public class BufferedDecoder
026 {
027 protected byte[] buf;
028 protected int bufOff;
029
030 protected Translator translator;
031
032 /**
033 * @param translator the translator to use.
034 * @param bufSize amount of input to buffer for each chunk.
035 */
036 public BufferedDecoder(
037 Translator translator,
038 int bufSize)
039 {
040 this.translator = translator;
041
042 if ((bufSize % translator.getEncodedBlockSize()) != 0)
043 {
044 throw new IllegalArgumentException("buffer size not multiple of input block size");
045 }
046
047 buf = new byte[bufSize];
048 bufOff = 0;
049 }
050
051 public int processByte(
052 byte in,
053 byte[] out,
054 int outOff)
055 {
056 int resultLen = 0;
057
058 buf[bufOff++] = in;
059
060 if (bufOff == buf.length)
061 {
062 resultLen = translator.decode(buf, 0, buf.length, out, outOff);
063 bufOff = 0;
064 }
065
066 return resultLen;
067 }
068
069 public int processBytes(
070 byte[] in,
071 int inOff,
072 int len,
073 byte[] out,
074 int outOff)
075 {
076 if (len < 0)
077 {
078 throw new IllegalArgumentException("Can't have a negative input length!");
079 }
080
081 int resultLen = 0;
082 int gapLen = buf.length - bufOff;
083
084 if (len > gapLen)
085 {
086 System.arraycopy(in, inOff, buf, bufOff, gapLen);
087
088 resultLen += translator.decode(buf, 0, buf.length, out, outOff);
089
090 bufOff = 0;
091
092 len -= gapLen;
093 inOff += gapLen;
094 outOff += resultLen;
095
096 int chunkSize = len - (len % buf.length);
097
098 resultLen += translator.decode(in, inOff, chunkSize, out, outOff);
099
100 len -= chunkSize;
101 inOff += chunkSize;
102 }
103
104 if (len != 0)
105 {
106 System.arraycopy(in, inOff, buf, bufOff, len);
107
108 bufOff += len;
109 }
110
111 return resultLen;
112 }
113 }