// SPDX-FileCopyrightText: 2024 Paul Schaub // // SPDX-License-Identifier: Apache-2.0 package org.pgpainless.sop import java.io.BufferedOutputStream import java.io.InputStream import java.io.OutputStream import kotlin.jvm.Throws import org.bouncycastle.util.io.Streams import org.pgpainless.decryption_verification.OpenPgpInputStream import org.pgpainless.util.ArmoredOutputStreamFactory import sop.Ready import sop.enums.ArmorLabel import sop.exception.SOPGPException import sop.operation.Armor /** Implementation of the `armor` operation using PGPainless. */ class ArmorImpl : Armor { @Throws(SOPGPException.BadData::class) override fun data(data: InputStream): Ready { return object : Ready() { override fun writeTo(outputStream: OutputStream) { // By buffering the output stream, we can improve performance drastically val bufferedOutputStream = BufferedOutputStream(outputStream) // Determine the nature of the given data val openPgpIn = OpenPgpInputStream(data) openPgpIn.reset() if (openPgpIn.isAsciiArmored) { // armoring already-armored data is an idempotent operation Streams.pipeAll(openPgpIn, bufferedOutputStream) bufferedOutputStream.flush() openPgpIn.close() return } val armor = ArmoredOutputStreamFactory.get(bufferedOutputStream) Streams.pipeAll(openPgpIn, armor) bufferedOutputStream.flush() armor.close() openPgpIn.close() } } } @Deprecated("Setting custom labels is not supported.") override fun label(label: ArmorLabel): Armor { throw SOPGPException.UnsupportedOption("Setting custom Armor labels not supported.") } }