diff --git a/src/main/kotlin/de/gmuth/ipp/core/IppMessage.kt b/src/main/kotlin/de/gmuth/ipp/core/IppMessage.kt index 38d24ec6..126d3f83 100644 --- a/src/main/kotlin/de/gmuth/ipp/core/IppMessage.kt +++ b/src/main/kotlin/de/gmuth/ipp/core/IppMessage.kt @@ -10,6 +10,7 @@ import java.util.logging.Level import java.util.logging.Level.INFO import java.util.logging.Logger import java.util.logging.Logger.getLogger +import java.util.zip.GZIPOutputStream import java.nio.charset.Charset as javaCharset abstract class IppMessage() { @@ -126,7 +127,7 @@ abstract class IppMessage() { try { IppInputStream(bufferedInputStream).readMessage(this) if (bufferedInputStream.available() > 0) documentInputStream = bufferedInputStream - else logger.finest { "No document bytes available from bufferedInputStream after readMessage" } + else logger.fine { "No document bytes available from bufferedInputStream after readMessage()" } } finally { rawBytes = byteArrayOutputStream.toByteArray() } @@ -146,17 +147,30 @@ abstract class IppMessage() { // DOCUMENT and IPP-MESSAGE // ------------------------ - fun writeDocument(outputStream: OutputStream) { + fun writeDocument(notCompressingOutputStream: OutputStream) { if (documentInputStreamIsConsumed) { - if (keepDocumentCopy) outputStream.use { it.write(documentBytes!!) } - else throw IppException( - "DocumentInputStream is consumed. Enable IppMessage.keepDocumentCopy in order to keep documentBytes." - ) + throw IppException("documentInputStream is consumed") + // write documentBytes? take care of compression! } else { + val outputStream = if (operationGroup.containsKey("compression")) { + getCompressingOutputStream(notCompressingOutputStream) + } else { + notCompressingOutputStream + } + logger.fine { "Write document using ${outputStream.javaClass.simpleName}" } copyUnconsumedDocumentInputStream(outputStream) + outputStream.close() // starts optional compression } } + private fun getCompressingOutputStream(uncompressedOutputStream: OutputStream) = + with(operationGroup.getValueAsString("compression")) { + when (this) { + "gzip" -> GZIPOutputStream(uncompressedOutputStream) + else -> throw NotImplementedError("compression '$this'") + } + } + private fun copyUnconsumedDocumentInputStream(outputStream: OutputStream): Long { if (hasDocument() && documentInputStreamIsConsumed) { throw IppException("documentInputStream is consumed") @@ -175,8 +189,9 @@ abstract class IppMessage() { } } - fun saveDocument(file: File) = file.run { - writeDocument(outputStream()) + fun saveDocumentBytes(file: File) = file.run { + if (documentBytes == null || documentBytes!!.isEmpty()) throw IppException("No documentBytes available") + ByteArrayInputStream(documentBytes).copyTo(outputStream()) logger.info { "Saved ${length()} document bytes to $path" } } @@ -217,12 +232,6 @@ abstract class IppMessage() { // LOGGING // ------- - override fun toString() = "%s %s%s".format( - codeDescription, - attributesGroups.map { "${it.values.size} ${it.tag}" }, - if (rawBytes == null) "" else " (${rawBytes!!.size} bytes)" - ) - @JvmOverloads open fun log(logger: Logger, level: Level = INFO, prefix: String = "") { if (rawBytes != null) logger.log(level) { "${prefix}${rawBytes!!.size} raw ipp bytes" } diff --git a/src/test/kotlin/de/gmuth/ipp/core/IppMessageTests.kt b/src/test/kotlin/de/gmuth/ipp/core/IppMessageTests.kt index 00db2463..b6542a7c 100644 --- a/src/test/kotlin/de/gmuth/ipp/core/IppMessageTests.kt +++ b/src/test/kotlin/de/gmuth/ipp/core/IppMessageTests.kt @@ -74,14 +74,17 @@ class IppMessageTests { requestId = 7 code = 0 documentInputStream = "Lorem ipsum dolor sit amet".byteInputStream() + val tmpFile0 = createTempFile("test", null) val tmpFile1 = createTempFile("test", null) val tmpFile2 = createTempFile("test", null) try { IppMessage.keepDocumentCopy = true + write(tmpFile0.outputStream()) assertTrue(hasDocument()) - saveDocument(tmpFile1) + saveDocumentBytes(tmpFile1) assertEquals(26, tmpFile1.length()) - encode(appendDocumentIfAvailable = true) // save raw bytes + val ippBytes = encode(appendDocumentIfAvailable = false) // trigger saving raw bytes + assertEquals(38, ippBytes.size) saveBytes(tmpFile2) assertEquals(38, tmpFile2.length()) } finally { @@ -94,7 +97,6 @@ class IppMessageTests { @Test fun withoutRawBytes() { - assertEquals("codeDescription []", message.toString()) message.log(logger) assertFailsWith { // missing raw bytes message.saveBytes(createTempFile("rawbytes", null))