blob: ccefa36ebc33c772aa52e9ac9472f68d618183e9 [file] [log] [blame]
package org.bouncycastle.util.io.pem;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.Iterator;
import org.bouncycastle.util.encoders.Base64;
/**
* A generic PEM writer, based on RFC 1421
*/
public class PemWriter
extends BufferedWriter
{
private static final int LINE_LENGTH = 64;
private final int nlLength;
private char[] buf = new char[LINE_LENGTH];
/**
* Base constructor.
*
* @param out output stream to use.
*/
public PemWriter(Writer out)
{
super(out);
String nl = System.getProperty("line.separator");
if (nl != null)
{
nlLength = nl.length();
}
else
{
nlLength = 2;
}
}
/**
* Return the number of bytes or characters required to contain the
* passed in object if it is PEM encoded.
*
* @param obj pem object to be output
* @return an estimate of the number of bytes
*/
public int getOutputSize(PemObject obj)
{
// BEGIN and END boundaries.
int size = (2 * (obj.getType().length() + 10 + nlLength)) + 6 + 4;
if (!obj.getHeaders().isEmpty())
{
for (Iterator it = obj.getHeaders().iterator(); it.hasNext();)
{
PemHeader hdr = (PemHeader)it.next();
size += hdr.getName().length() + ": ".length() + hdr.getValue().length() + nlLength;
}
size += nlLength;
}
// base64 encoding
int dataLen = ((obj.getContent().length + 2) / 3) * 4;
size += dataLen + (((dataLen + LINE_LENGTH - 1) / LINE_LENGTH) * nlLength);
return size;
}
public void writeObject(PemObjectGenerator objGen)
throws IOException
{
PemObject obj = objGen.generate();
writePreEncapsulationBoundary(obj.getType());
if (!obj.getHeaders().isEmpty())
{
for (Iterator it = obj.getHeaders().iterator(); it.hasNext();)
{
PemHeader hdr = (PemHeader)it.next();
this.write(hdr.getName());
this.write(": ");
this.write(hdr.getValue());
this.newLine();
}
this.newLine();
}
writeEncoded(obj.getContent());
writePostEncapsulationBoundary(obj.getType());
}
private void writeEncoded(byte[] bytes)
throws IOException
{
bytes = Base64.encode(bytes);
for (int i = 0; i < bytes.length; i += buf.length)
{
int index = 0;
while (index != buf.length)
{
if ((i + index) >= bytes.length)
{
break;
}
buf[index] = (char)bytes[i + index];
index++;
}
this.write(buf, 0, index);
this.newLine();
}
}
private void writePreEncapsulationBoundary(
String type)
throws IOException
{
this.write("-----BEGIN " + type + "-----");
this.newLine();
}
private void writePostEncapsulationBoundary(
String type)
throws IOException
{
this.write("-----END " + type + "-----");
this.newLine();
}
}