~brian-thomason/+junk/bouncycastle

« back to all changes in this revision

Viewing changes to src/org/bouncycastle/openpgp/PGPLiteralDataGenerator.java

  • Committer: Brian Thomason
  • Date: 2011-12-20 17:20:32 UTC
  • Revision ID: brian.thomason@canonical.com-20111220172032-rdtm13jgdxtksacr
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package org.bouncycastle.openpgp;
 
2
 
 
3
import java.io.File;
 
4
import java.io.IOException;
 
5
import java.io.OutputStream;
 
6
import java.util.Date;
 
7
 
 
8
import org.bouncycastle.bcpg.BCPGOutputStream;
 
9
import org.bouncycastle.bcpg.PacketTags;
 
10
import org.bouncycastle.util.Strings;
 
11
 
 
12
/**
 
13
 * Class for producing literal data packets.
 
14
 */
 
15
public class PGPLiteralDataGenerator implements StreamGenerator
 
16
{    
 
17
    public static final char    BINARY = PGPLiteralData.BINARY;
 
18
    public static final char    TEXT = PGPLiteralData.TEXT;
 
19
    public static final char    UTF8 = PGPLiteralData.UTF8;
 
20
    
 
21
    /**
 
22
     * The special name indicating a "for your eyes only" packet.
 
23
     */
 
24
    public static final String  CONSOLE = PGPLiteralData.CONSOLE;
 
25
    
 
26
    /**
 
27
     * The special time for a modification time of "now" or
 
28
     * the present time.
 
29
     */
 
30
    public static final Date    NOW = PGPLiteralData.NOW;
 
31
    
 
32
    private BCPGOutputStream    pkOut;
 
33
    private boolean             oldFormat = false;
 
34
    
 
35
    public PGPLiteralDataGenerator()
 
36
    {        
 
37
    }
 
38
    
 
39
    /**
 
40
     * Generates literal data objects in the old format, this is
 
41
     * important if you need compatability with  PGP 2.6.x.
 
42
     * 
 
43
     * @param oldFormat
 
44
     */
 
45
    public PGPLiteralDataGenerator(
 
46
        boolean    oldFormat)
 
47
    {
 
48
        this.oldFormat = oldFormat;
 
49
    }
 
50
    
 
51
    private void writeHeader(
 
52
        OutputStream    out,
 
53
        char            format,
 
54
        String          name,
 
55
        long            modificationTime) 
 
56
        throws IOException
 
57
    {
 
58
        out.write(format);
 
59
 
 
60
        byte[] encName = Strings.toUTF8ByteArray(name);
 
61
 
 
62
        out.write((byte)encName.length);
 
63
 
 
64
        for (int i = 0; i != encName.length; i++)
 
65
        {
 
66
            out.write(encName[i]);
 
67
        }
 
68
 
 
69
        long    modDate = modificationTime / 1000;
 
70
 
 
71
        out.write((byte)(modDate >> 24));
 
72
        out.write((byte)(modDate >> 16));
 
73
        out.write((byte)(modDate >> 8));
 
74
        out.write((byte)(modDate));
 
75
    }
 
76
    
 
77
    /**
 
78
     * Open a literal data packet, returning a stream to store the data inside
 
79
     * the packet.
 
80
     * <p>
 
81
     * The stream created can be closed off by either calling close()
 
82
     * on the stream or close() on the generator. Closing the returned
 
83
     * stream does not close off the OutputStream parameter out.
 
84
     * 
 
85
     * @param out the stream we want the packet in
 
86
     * @param format the format we are using
 
87
     * @param name the name of the "file"
 
88
     * @param length the length of the data we will write
 
89
     * @param modificationTime the time of last modification we want stored.
 
90
     */
 
91
    public OutputStream open(
 
92
        OutputStream    out,
 
93
        char            format,
 
94
        String          name,
 
95
        long            length,
 
96
        Date            modificationTime)
 
97
        throws IOException
 
98
    {
 
99
        if (pkOut != null)
 
100
        {
 
101
            throw new IllegalStateException("generator already in open state");
 
102
        }
 
103
 
 
104
        pkOut = new BCPGOutputStream(out, PacketTags.LITERAL_DATA, length + 2 + name.length() + 4, oldFormat);
 
105
        
 
106
        writeHeader(pkOut, format, name, modificationTime.getTime());
 
107
 
 
108
        return new WrappedGeneratorStream(pkOut, this);
 
109
    }
 
110
    
 
111
    /**
 
112
     * Open a literal data packet, returning a stream to store the data inside
 
113
     * the packet as an indefinite length stream. The stream is written out as a 
 
114
     * series of partial packets with a chunk size determined by the size of the
 
115
     * passed in buffer.
 
116
     * <p>
 
117
     * The stream created can be closed off by either calling close()
 
118
     * on the stream or close() on the generator. Closing the returned
 
119
     * stream does not close off the OutputStream parameter out.
 
120
     * <p>
 
121
     * <b>Note</b>: if the buffer is not a power of 2 in length only the largest power of 2
 
122
     * bytes worth of the buffer will be used.
 
123
     * 
 
124
     * @param out the stream we want the packet in
 
125
     * @param format the format we are using
 
126
     * @param name the name of the "file"
 
127
     * @param modificationTime the time of last modification we want stored.
 
128
     * @param buffer the buffer to use for collecting data to put into chunks.
 
129
     */
 
130
    public OutputStream open(
 
131
        OutputStream    out,
 
132
        char            format,
 
133
        String          name,
 
134
        Date            modificationTime,
 
135
        byte[]          buffer)
 
136
        throws IOException
 
137
    {
 
138
        if (pkOut != null)
 
139
        {
 
140
            throw new IllegalStateException("generator already in open state");
 
141
        }
 
142
 
 
143
        pkOut = new BCPGOutputStream(out, PacketTags.LITERAL_DATA, buffer);
 
144
        
 
145
        writeHeader(pkOut, format, name, modificationTime.getTime());
 
146
 
 
147
        return new WrappedGeneratorStream(pkOut, this);
 
148
    }
 
149
    
 
150
    /**
 
151
     * Open a literal data packet for the passed in File object, returning
 
152
     * an output stream for saving the file contents.
 
153
     * <p>
 
154
     * The stream created can be closed off by either calling close()
 
155
     * on the stream or close() on the generator. Closing the returned
 
156
     * stream does not close off the OutputStream parameter out.
 
157
     * 
 
158
     * @param out
 
159
     * @param format
 
160
     * @param file
 
161
     * @return OutputStream
 
162
     * @throws IOException
 
163
     */
 
164
    public OutputStream open(
 
165
        OutputStream    out,
 
166
        char            format,
 
167
        File            file)
 
168
        throws IOException
 
169
    {
 
170
        if (pkOut != null)
 
171
        {
 
172
            throw new IllegalStateException("generator already in open state");
 
173
        }
 
174
 
 
175
        pkOut = new BCPGOutputStream(out, PacketTags.LITERAL_DATA, file.length() + 2 + file.getName().length() + 4, oldFormat);
 
176
        
 
177
        writeHeader(pkOut, format, file.getName(), file.lastModified());
 
178
 
 
179
        return new WrappedGeneratorStream(pkOut, this);
 
180
    }
 
181
    
 
182
    /**
 
183
     * Close the literal data packet - this is equivalent to calling close on the stream
 
184
     * returned by the open() method.
 
185
     * 
 
186
     * @throws IOException
 
187
     */
 
188
    public void close()
 
189
        throws IOException
 
190
    {
 
191
        if (pkOut != null)
 
192
        {
 
193
            pkOut.finish();
 
194
            pkOut.flush();
 
195
            pkOut = null;
 
196
        }
 
197
    }
 
198
}