Skip to content

Commit

Permalink
support sending GZIP compressed document
Browse files Browse the repository at this point in the history
  • Loading branch information
gmuth committed Oct 2, 2024
1 parent 6e858ee commit 96a7613
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 17 deletions.
37 changes: 23 additions & 14 deletions src/main/kotlin/de/gmuth/ipp/core/IppMessage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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()
}
Expand All @@ -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")
Expand All @@ -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" }
}

Expand Down Expand Up @@ -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" }
Expand Down
8 changes: 5 additions & 3 deletions src/test/kotlin/de/gmuth/ipp/core/IppMessageTests.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -94,7 +97,6 @@ class IppMessageTests {

@Test
fun withoutRawBytes() {
assertEquals("codeDescription []", message.toString())
message.log(logger)
assertFailsWith<IppException> { // missing raw bytes
message.saveBytes(createTempFile("rawbytes", null))
Expand Down

0 comments on commit 96a7613

Please sign in to comment.