1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage org.bouncycastle.util.encoders;
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * a buffering class to allow translation from one format to another to
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * be done in discrete chunks.
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic class BufferedDecoder
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected byte[]        buf;
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected int           bufOff;
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected Translator    translator;
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param translator the translator to use.
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param bufSize amount of input to buffer for each chunk.
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public BufferedDecoder(
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Translator  translator,
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int         bufSize)
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.translator = translator;
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if ((bufSize % translator.getEncodedBlockSize()) != 0)
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException("buffer size not multiple of input block size");
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        buf = new byte[bufSize];
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        bufOff = 0;
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int processByte(
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        byte        in,
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        byte[]      out,
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int         outOff)
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int         resultLen = 0;
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        buf[bufOff++] = in;
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (bufOff == buf.length)
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            resultLen = translator.decode(buf, 0, buf.length, out, outOff);
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            bufOff = 0;
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return resultLen;
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int processBytes(
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        byte[]      in,
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int         inOff,
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int         len,
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        byte[]      out,
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int         outOff)
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (len < 0)
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException("Can't have a negative input length!");
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int resultLen = 0;
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int gapLen = buf.length - bufOff;
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (len > gapLen)
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            System.arraycopy(in, inOff, buf, bufOff, gapLen);
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            resultLen += translator.decode(buf, 0, buf.length, out, outOff);
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            bufOff = 0;
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            len -= gapLen;
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            inOff += gapLen;
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            outOff += resultLen;
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int chunkSize = len - (len % buf.length);
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            resultLen += translator.decode(in, inOff, chunkSize, out, outOff);
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            len -= chunkSize;
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            inOff += chunkSize;
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (len != 0)
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            System.arraycopy(in, inOff, buf, bufOff, len);
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            bufOff += len;
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return resultLen;
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
97