Reputation: 11
I have encode the attachment InfoPath following the document from Microsoft attactment-infopath to Kotlin. The class produces different Strings from the C# code. I think because of the InfoPath signature. I want it the same String from C#.
Here is my class.
class InfoPathAttachmentEncoder(private val fullyQualifiedFileName: String) {
private var base64EncodedFile = ""
// Creates an encoder to create an InfoPath attachment string.
init {
if (fullyQualifiedFileName == "")
throw IllegalArgumentException("Must specify file name")
if (!File(fullyQualifiedFileName).exists())
throw FileNotFoundException("File does not exist: $fullyQualifiedFileName")
}
// Returns a Base64 encoded string.
fun toBase64String(): String {
if (base64EncodedFile != "")
return base64EncodedFile
// This memory stream will hold the InfoPath file attachment buffer before Base64 encoding.
val ms = ByteArrayOutputStream()
// Get the file information.
val f = File(fullyQualifiedFileName)
DataInputStream(f.inputStream()).use { br ->
val fileName = File(fullyQualifiedFileName).name
val fileNameLength = fileName.length + 1
val fileNameBytes = fileName.toByteArray(Charsets.UTF_16LE)
DataOutputStream(ms).use { bw ->
// Write the InfoPath attachment signature.
bw.write(byteArrayOf(0xC7.toByte(), 0x49.toByte(), 0x46.toByte(), 0x41.toByte()))
// Write the default header information.
bw.writeInt(0x14)// size
bw.writeInt(0x01)// version
bw.writeInt(0x00)// reserved
// Write the file size.
bw.writeInt(f.length().toInt())
// Write the size of the file name.
bw.writeInt(fileNameLength)
// Write the file name (Unicode encoded).
bw.write(fileNameBytes)
// Write the file name terminator. This is two nulls in Unicode.
bw.write(byteArrayOf(0, 0))
// Iterate through the file reading data and writing it to the outbuffer.
val data = ByteArray(64 * 1024)
var bytesRead: Int
while (br.read(data, 0, data.size).also { bytesRead = it } > 0) {
bw.write(data, 0, bytesRead)
}
}
}
val encodedBytes = Base64.getEncoder().encode(ms.toByteArray())
return String(encodedBytes, Charsets.US_ASCII)
}
}
val i = InfoPathAttachmentEncoder(path)
println(">>>Endcoding {} ${i.toBase64String()}")
The result from C#: x0lGQRQAAAABAAAAAAAAAB8uAAAdAAAAQQB0AHQALQAyADAAMgAzAC0AMAA2AC0AMgA4ACAAMQA0AC0AMQAzAC0AMwA1AC4AZABvAGMAeAAAAFBLAwQUAAYACAAAACEA36TSbFoBAAAgBQAAEwAIAltDb250ZW50X1R5cGVzXS54bWwgogQCKK...
The result from Kotlin: x0lGQQAAABQAAAABAAAAAAAALh8AAAAdQQB0AHQALQAyADAAMgAzAC0AMAA2AC0AMgA4ACAAMQA0AC0AMQAzAC0AMwA1AC4AZABvAGMAeAAAAFBLAwQUAAYACAAAACEA36TSbFoBAAAgBQAAEwAIAltDb250ZW50X1R5cGVzXS54bWwgogQCKK...
The bolded characters here is the different String.
Upvotes: 1
Views: 90