
commonMain.dev.atsushieno.ktmidi.UmpRetrieval.kt Maven / Gradle / Ivy
package dev.atsushieno.ktmidi
val Ump.groupByte: Int
get() = int1 shr 24
// First half of the 1st. byte
// 32bit: UMP message type 0 (NOP / Clock), 1 (System) and 2 (MIDI 1.0)
// 64bit: UMP message type 3 (SysEx7) and 4 (MIDI 2.0)
// 128bit: UMP message type 5 (SysEx8 and Mixed Data Set)
val Ump.messageType: Int
get() = (int1 shr 28) and 0xF
fun umpSizeInInts(messageType: Int) = when(messageType) {
MidiMessageType.SYSEX8_MDS, MidiMessageType.FLEX_DATA, MidiMessageType.UMP_STREAM -> 4
MidiMessageType.SYSEX7, MidiMessageType.MIDI2 -> 2
else -> 1
}
val Ump.sizeInInts
get() = umpSizeInInts(messageType)
val Ump.sizeInBytes
get() = sizeInInts * 4
private fun toPlatformBytes(bytes: ByteArray, value: Int, offset: Int, byteOrder: ByteOrder) {
if (byteOrder == ByteOrder.LITTLE_ENDIAN) {
bytes[offset + 3] = ((value shr 24) and 0xFF).toByte()
bytes[offset + 2] = ((value shr 16) and 0xFF).toByte()
bytes[offset + 1] = ((value shr 8) and 0xFF).toByte()
bytes[offset] = (value and 0xFF).toByte()
} else {
bytes[offset] = ((value shr 24) and 0xFF).toByte()
bytes[offset + 1] = ((value shr 16) and 0xFF).toByte()
bytes[offset + 2] = ((value shr 8) and 0xFF).toByte()
bytes[offset + 3] = (value and 0xFF).toByte()
}
}
fun Ump.toPlatformBytes(bytes: ByteArray, offset: Int, byteOrder: ByteOrder) {
val size = sizeInBytes
toPlatformBytes(bytes, int1, offset, byteOrder)
if (size != 4)
toPlatformBytes(bytes, int2, offset + 4, byteOrder)
if (size == 16) {
toPlatformBytes(bytes, int3, offset + 8, byteOrder)
toPlatformBytes(bytes, int4, offset + 12, byteOrder)
}
}
fun Ump.toPlatformBytes(bytes: ByteArray, offset: Int) = this.toPlatformBytes(bytes, offset, ByteOrder.nativeOrder())
fun Ump.toPlatformBytes(byteOrder: ByteOrder) : ByteArray {
val bytes = ByteArray(this.sizeInBytes) {0}
toPlatformBytes(bytes, int1, 0, byteOrder)
if (messageType > 2)
toPlatformBytes(bytes, int2, 4, byteOrder)
if (messageType > 4) {
toPlatformBytes(bytes, int3, 8, byteOrder)
toPlatformBytes(bytes, int4, 12, byteOrder)
}
return bytes
}
fun Ump.toPlatformNativeBytes() = this.toPlatformBytes(ByteOrder.nativeOrder())
fun Ump.toInts() = when (this.sizeInInts) {
4 -> listOf(int1, int2, int3, int4)
2 -> listOf(int1, int2)
1 -> listOf(int1)
else -> listOf()
}
// Second half of the 1st. byte
val Ump.group: Int
get() = (int1 shr 24) and 0xF
// 2nd. byte
val Ump.statusByte: Int
get() = (int1 shr 16) and 0xFF
// First half of the 2nd. byte. (for MIDI1, MIDI2, Sysex7, Sysex8, System Messages)
val Ump.statusCode: Int
get() = statusByte and 0xF0
// Second half of the 2nd. byte
val Ump.channelInGroup: Int // 0..15
get() = statusByte and 0xF
val Ump.groupAndChannel: Int // 0..255
get() = group shl 4 and channelInGroup
val Ump.isJRClock
get() = messageType == MidiMessageType.UTILITY && statusCode == MidiUtilityStatus.JR_CLOCK
val Ump.jrClock
get() = if (isJRClock) int1 and 0xFFFF else 0
val Ump.isJRTimestamp
get()= messageType == MidiMessageType.UTILITY && statusCode == MidiUtilityStatus.JR_TIMESTAMP
val Ump.jrTimestamp
get() = if(isJRTimestamp) int1 and 0xFFFF else 0
val Ump.isDCTPQ
get() = messageType == MidiMessageType.UTILITY && statusCode == MidiUtilityStatus.DCTPQ
val Ump.dctpq
get() = if(isDCTPQ) int1 and 0xFFFF else 0
val Ump.isDeltaClockstamp
get() = messageType == MidiMessageType.UTILITY && statusCode == MidiUtilityStatus.DELTA_CLOCKSTAMP
val Ump.deltaClockstamp
get() = if(isDeltaClockstamp) int1 and 0xFFFFF else 0
// 3rd. byte for MIDI 1.0 message
val Ump.midi1Msb: Int
get() = (int1 and 0xFF00) shr 8
// 4th. byte for MIDI 1.0 message
val Ump.midi1Lsb: Int
get() = int1 and 0xFF
val Ump.midi1Note
get() = midi1Msb
val Ump.midi1Velocity
get() = midi1Lsb
val Ump.midi1PAfData
get() = midi1Lsb
val Ump.midi1CCIndex
get() = midi1Msb
val Ump.midi1CCData
get() = midi1Lsb
val Ump.midi1Program
get() = midi1Msb
val Ump.midi1CAf
get() = midi1Msb
val Ump.midi1PitchBendData
get() = midi1Msb + midi1Lsb * 0x80
val Ump.sysex7Size
get() = channelInGroup // same bits
val Ump.midi2Note
get() = midi1Msb
val Ump.midi2NoteAttributeType
get() = midi1Lsb
val Ump.midi2Velocity16
get() = (int2.toUnsigned() / 0x10000).toInt()
val Ump.midi2NoteAttributeData
get() = (int2.toUnsigned() % 0x10000).toInt()
val Ump.midi2PAfData
get() = int2.toUInt()
val Ump.midi2PerNoteRCCIndex
get() = midi1Lsb
val Ump.midi2PerNoteRCCData
get() = int2.toUInt()
val Ump.midi2PerNoteACCIndex
get() = midi1Lsb
val Ump.midi2PerNoteACCData
get() = int2.toUInt()
val Ump.midi2PerNoteManagementOptions
get() = midi1Lsb
val Ump.midi2CCIndex
get() = midi1Msb
val Ump.midi2CCData
get() = int2.toUInt()
val Ump.midi2RpnMsb
get() = midi1Msb
val Ump.midi2RpnLsb
get() = midi1Lsb
val Ump.midi2RpnData
get() = int2.toUInt()
val Ump.midi2NrpnMsb
get() = midi1Msb
val Ump.midi2NrpnLsb
get() = midi1Lsb
val Ump.midi2NrpnData
get() = int2.toUInt()
val Ump.midi2ProgramOptions
get() = midi1Lsb
val Ump.midi2ProgramProgram
get() = (int2.toUnsigned() / 0x1000000).toInt()
val Ump.midi2ProgramBankMsb
get() = ((int2.toUnsigned() / 0x100) % 0x100).toInt()
val Ump.midi2ProgramBankLsb
get() = (int2.toUnsigned() % 0x100).toInt()
val Ump.midi2CAfData
get() = int2.toUInt()
val Ump.midi2PitchBendData
get() = int2.toUInt()
val Ump.sysex8Size
get() = channelInGroup // same bits
val Ump.sysex8StreamId
get() = midi1Msb
val Ump.mdsId
get() = channelInGroup // same bits
val Ump.mdsChunkByteSize
get() = (midi1Msb shl 8) + midi1Lsb
val Ump.mdsChunkCount
get() = (int2.toUnsigned() / 0x10000).toInt()
val Ump.mdsChunkIndex
get() = (int2.toUnsigned() % 0x10000).toInt()
val Ump.mdsManufacturerId
get() = (int3.toUnsigned() / 0x10000).toInt()
val Ump.mdsDeviceId
get() = (int3.toUnsigned() % 0x10000).toInt()
val Ump.mdsSubId1
get() = (int4.toUnsigned() / 0x10000).toInt()
val Ump.mdsSubId2
get() = (int4.toUnsigned() % 0x10000).toInt()
// Flex Data message properties
val Ump.isFlexData
get() = messageType == MidiMessageType.FLEX_DATA
val Ump.flexDataFormat: Int
get() = (int1 shr 22) and 3
val Ump.flexDataStatus: Byte
get() = (int1 and 0xFF).toByte()
val Ump.flexDataStatusBank: Byte
get() = ((int1 and 0xFF00) shr 8).toByte()
val Ump.isTempo
get() = messageType == MidiMessageType.FLEX_DATA && flexDataStatus == FlexDataStatus.TEMPO
val Ump.tempo
get() = int2
val Ump.isTimeSignature
get() = messageType == MidiMessageType.FLEX_DATA && flexDataStatus == FlexDataStatus.TIME_SIGNATURE
val Ump.timeSignatureNumerator
get() = (int2 shr 24) and 0xFF
val Ump.timeSignatureDenominator
get() = (int2 shr 16) and 0xFF
val Ump.timeSignatureNumberOf32thNotes
get() = (int2 shr 8) and 0xFF
val Ump.isMetronome
get() = messageType == MidiMessageType.FLEX_DATA && flexDataStatus == FlexDataStatus.METRONOME
val Ump.metronomeClocksPerPrimaryClick
get() = (int2 shr 24) and 0xFF
val Ump.metronomeBarAccent1
get() = (int2 shr 16) and 0xFF
val Ump.metronomeBarAccent2
get() = (int2 shr 8) and 0xFF
val Ump.metronomeBarAccent3
get() = int2 and 0xFF
val Ump.metronomeSubDivisionClick1
get() = (int3 shr 24) and 0xFF
val Ump.metronomeSubDivisionClick2
get() = (int3 shr 16) and 0xFF
private fun rawBitsToSharpsFlats(value: Int): Byte {
val v = value and 0xF
return (if (v > 7) -16 + v else v).toByte()
}
val Ump.isKeySignature
get() = messageType == MidiMessageType.FLEX_DATA && flexDataStatus == FlexDataStatus.KEY_SIGNATURE
val Ump.keySignatureSharpsFlats
get() = rawBitsToSharpsFlats(int2 shr 28) // Note that we have to return negative values for any value more than 0x8
val Ump.keySignatureTonicNote
get() = ((int2 shr 24) and 0xF).toByte()
val Ump.isChordName
get() = messageType == MidiMessageType.FLEX_DATA && flexDataStatus == FlexDataStatus.CHORD_NAME
val Ump.chordNameSharpsFlats
get() = rawBitsToSharpsFlats(int2 shr 28) // Note that we have to return negative values for any value more than 0x8
val Ump.chordNameChordTonic
get() = ((int2 shr 24) and 0xF).toByte()
val Ump.chordNameChordType
get() = ((int2 shr 16) and 0xFF).toByte()
val Ump.chordNameAlter1
get() = ((int2 shr 8) and 0xFF).toUInt()
val Ump.chordNameAlter2
get() = (int2 and 0xFF).toUInt()
val Ump.chordNameAlter3
get() = ((int3 shr 24) and 0xFF).toUInt()
val Ump.chordNameAlter4
get() = ((int3 shr 16) and 0xFF).toUInt()
val Ump.chordNameBassSharpsFlats
get() = rawBitsToSharpsFlats(int4 shr 28) // Note that we have to return negative values for any value more than 0x8
val Ump.chordNameBassNote
get() = ((int4 shr 24) and 0xF).toByte()
val Ump.chordNameBassChordType
get() = ((int4 shr 16) and 0xFF).toByte()
val Ump.chordNameBassAlter1
get() = ((int4 shr 8) and 0xFF).toUInt()
val Ump.chordNameBassAlter2
get() = (int4 and 0xFF).toUInt()
// Ump Stream message properties
val Ump.isUmpStream
get() = messageType == MidiMessageType.UMP_STREAM
val Ump.umpStreamFormat
get() = (int1 shr 26) and 3
val Ump.endpointDiscoveryUmpVersionMajor
get() = (int1 shr 8) and 0xFF
val Ump.endpointDiscoveryUmpVersionMinor
get() = int1 and 0xFF
val Ump.endpointDiscoveryFilterBitmap
get() = int2 and 0xFF
val Ump.endpointInfoUmpVersionMajor
get() = (int1 shr 8) and 0xFF
val Ump.endpointInfoUmpVersionMinor
get() = int1 and 0xFF
val Ump.endpointInfoStaticFunctionBlocks
get() = int2 < 0
val Ump.endpointInfoFunctionBlockCount
get() = (int2 shr 24) and 0x7F
val Ump.endpointInfoMidi2Capable
get() = (int2 and 0x200) != 0
val Ump.endpointInfoMidi1Capable
get() = (int2 and 0x100) != 0
val Ump.endpointInfoSupportsRxJR
get() = (int2 and 2) != 0
val Ump.endpointInfoSupportsTxJR
get() = (int2 and 1) != 0
val Ump.deviceIdentificationManufacturer
get() = int2 and 0xFFFFFF
val Ump.deviceIdentificationFamily
get() = ((int3 shr 16) and 0xFFFF).toShort()
val Ump.deviceIdentificationModelNumber
get() = (int3 and 0xFFFF).toShort()
val Ump.deviceIdentificationSoftwareRevisionLevel
get() = int4
val Ump.streamConfigProtocol
get() = (int1 shr 8) and 0xFF
val Ump.streamConfigSupportsRxJR
get() = (int1 and 2) != 0
val Ump.streamConfigSupportsTxJR
get() = (int1 and 1) != 0
val Ump.functionBlockCount
get() = (int1 shr 8) and 0x7F
val Ump.functionBlockDiscoveryFilter
get() = int1 and 0xFF
val Ump.functionBlockIndex: Byte
get() = ((int1 and 0x7F00) shr 8).toByte()
val Ump.functionBlockActive
get() = (int1 and 0x8000) != 0
val Ump.functionBlockUiHint: Byte
get() = ((int1 shr 4) and 0x3).toByte()
val Ump.functionBlockMidi1Port: Byte
get() = ((int1 shr 2) and 0x3).toByte()
val Ump.functionBlockDirection: Byte
get() = (int1 and 0x3).toByte()
val Ump.functionBlockFirstGroup: Byte
get() = ((int2 shr 24) and 0x7F).toByte()
val Ump.functionBlockGroupCount: Byte
get() = ((int2 shr 16) and 0x7F).toByte()
val Ump.functionBlockCIVersion: Byte
get() = ((int2 shr 8) and 0xFF).toByte()
val Ump.functionBlockMaxSysEx8: UByte
get() = (int2 and 0xFF).toUByte()
val Ump.isStartOfClip
get() = isUmpStream && ((int1 and 0xFF_0000) shr 16).toByte() == UmpStreamStatus.START_OF_CLIP
val Ump.isEndOfClip
get() = isUmpStream && ((int1 and 0xFF_0000) shr 16).toByte() == UmpStreamStatus.END_OF_CLIP
// Binary/Text chunk retrievers
enum class UmpBinaryRetrieverFallback {
Break,
Exception
}
@Deprecated("use UmpBinaryRetrieverFallback", ReplaceWith("UmpBinaryRetrieverFallback"))
typealias UmpSysexBinaryRetrieverFallback = UmpBinaryRetrieverFallback
object UmpRetriever {
// SysEx7
private fun takeSysex7Bytes(ump: Ump, outputter: (List) -> Unit, sysex7Size: Int) {
if (sysex7Size < 1)
return
// It is hack, but it just reuses toPlatformNativeBytes() and then pick up the appropriate parts per platform
val src = ump.toPlatformNativeBytes() // NOTE: memory consumptive
if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN)
outputter(src.drop(2).take(sysex7Size))
else {
outputter(listOf(src[1]))
if (sysex7Size > 1)
outputter(listOf(src[0]))
src.reverse()
if (sysex7Size > 2)
outputter(src.take(sysex7Size - 2))
}
}
fun getSysex7Data(iter: Iterator, fallback: UmpBinaryRetrieverFallback = UmpBinaryRetrieverFallback.Break) : List {
val ret = mutableListOf()
val output: (List) -> Unit = { ret.addAll(it) }
getSysex7Data(output, iter, fallback)
return ret
}
fun getSysex7Data(outputter: (List) -> Unit, input: Iterator, fallback: UmpBinaryRetrieverFallback = UmpBinaryRetrieverFallback.Break) {
if (!input.hasNext())
if (fallback == UmpBinaryRetrieverFallback.Break) return else throw UmpException("UMP iterator is empty")
val pStart = input.next()
takeSysex7Bytes(pStart, outputter, pStart.sysex7Size)
when (pStart.statusCode) {
Midi2BinaryChunkStatus.COMPLETE_PACKET -> return
Midi2BinaryChunkStatus.CONTINUE, Midi2BinaryChunkStatus.END ->
if (fallback == UmpBinaryRetrieverFallback.Break) return else throw UmpException("Unexpected sysex7 non-starter packet appeared")
}
while (input.hasNext()) {
val pCont = input.next()
takeSysex7Bytes(pCont, outputter, pCont.sysex7Size)
when (pCont.statusCode) {
Midi2BinaryChunkStatus.END -> break
Midi2BinaryChunkStatus.CONTINUE -> continue
else ->
if (fallback == UmpBinaryRetrieverFallback.Break) return else throw UmpException("Unexpected sysex7 non-continue packet appeared")
}
}
}
// SysEx8
private fun takeSysex8Bytes(ump: Ump, outputter: (List) -> Unit, sysex8Size: Int) {
if (sysex8Size < 2)
return
// It is hack, but it just reuses toPlatformNativeBytes() and then pick up the appropriate parts per platform
val src = ump.toPlatformNativeBytes() // NOTE: memory consumptive
// Note that sysex8Size always contains streamID which should NOT be part of the result.
if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN)
outputter(src.drop(3).take(sysex8Size))
else {
outputter(listOf(src[0]))
src.reverse()
if (sysex8Size > 2)
outputter(src.drop(8).take(if (sysex8Size > 6) 4 else sysex8Size - 2)) // NOTE: memory consumptive
if (sysex8Size > 6)
outputter(src.drop(4).take(if (sysex8Size > 10) 4 else sysex8Size - 6)) // NOTE: memory consumptive
if (sysex8Size > 10)
outputter(src.take(sysex8Size - 10)) // NOTE: memory consumptive
}
}
fun getSysex8Data(iter: Iterator, fallback: UmpBinaryRetrieverFallback = UmpBinaryRetrieverFallback.Break) : List {
val ret = mutableListOf()
val output: (List) -> Unit = { ret.addAll(it) }
getSysex8Data(output, iter, fallback)
return ret
}
fun getSysex8Data(outputter: (List) -> Unit, input: Iterator, fallback: UmpBinaryRetrieverFallback = UmpBinaryRetrieverFallback.Break) {
if (!input.hasNext())
if (fallback == UmpBinaryRetrieverFallback.Break) return else throw UmpException("UMP iterator is empty")
val pStart = input.next()
takeSysex8Bytes(pStart, outputter, pStart.sysex8Size)
when (pStart.statusCode) {
Midi2BinaryChunkStatus.COMPLETE_PACKET -> return
Midi2BinaryChunkStatus.CONTINUE, Midi2BinaryChunkStatus.END ->
if (fallback == UmpBinaryRetrieverFallback.Break) return else throw UmpException("Unexpected sysex8 non-starter packet appeared")
}
while (input.hasNext()) {
val pCont = input.next()
takeSysex8Bytes(pCont, outputter, pCont.sysex8Size)
when (pCont.statusCode) {
Midi2BinaryChunkStatus.END -> break
Midi2BinaryChunkStatus.CONTINUE -> continue
else ->
if (fallback == UmpBinaryRetrieverFallback.Break) return else throw UmpException("Unexpected sysex8 non-continue packet appeared")
}
}
}
// Flex Data Text
private fun takeFlexDataText(ump: Ump, outputter: (List) -> Unit) {
// It is hack, but it just reuses toPlatformNativeBytes() and then pick up the appropriate parts per platform
// Note that unlike other binary messages we have to treat the bytes in BIG ENDIAN.
val src = ump.toPlatformBytes(ByteOrder.BIG_ENDIAN) // NOTE: memory consumptive
// CONTINUE packets may contain \0 as "melisma".
// When they appear in format 3 then it indicates the end of text.
//
// LAMESPEC: There is no description on what happens if a lyric could fit in 12 bytes *and* contains melisma.
// Therefore, this implementation assumes that a format 0 packet may contain melisma.
val bytes = src.drop(4).takeWhile { it != 0.toByte() || ump.flexDataFormat != Midi2BinaryChunkFormat.CONTINUE }
// If it is a complete packet then those '\0's are non-data (i.e. not melisma).
if (ump.flexDataFormat != Midi2BinaryChunkFormat.CONTINUE)
outputter(bytes.dropLastWhile { it == 0.toByte() })
else
outputter(bytes)
}
fun getFlexDataTextBytes(input: Iterator, fallback: UmpBinaryRetrieverFallback = UmpBinaryRetrieverFallback.Break) : List {
val ret = mutableListOf()
val output: (List) -> Unit = { ret.addAll(it) }
getFlexDataTextBytes(output, input, fallback)
return ret
}
fun getFlexDataText(input: Iterator, fallback: UmpBinaryRetrieverFallback = UmpBinaryRetrieverFallback.Break) : String =
getFlexDataTextBytes(input, fallback).toByteArray().decodeToString()
fun getFlexDataTextBytes(outputter: (List) -> Unit, input: Iterator, fallback: UmpBinaryRetrieverFallback = UmpBinaryRetrieverFallback.Break) {
if (!input.hasNext())
if (fallback == UmpBinaryRetrieverFallback.Break) return else throw UmpException("UMP iterator is empty")
val pStart = input.next()
takeFlexDataText(pStart, outputter)
when (pStart.flexDataFormat) {
Midi2BinaryChunkFormat.COMPLETE_PACKET -> return
Midi2BinaryChunkFormat.CONTINUE, Midi2BinaryChunkFormat.END ->
if (fallback == UmpBinaryRetrieverFallback.Break) return else throw UmpException("Unexpected flex data text non-starter packet appeared")
}
while (input.hasNext()) {
val pCont = input.next()
takeFlexDataText(pCont, outputter)
when (pCont.flexDataFormat) {
Midi2BinaryChunkFormat.END -> break
Midi2BinaryChunkFormat.CONTINUE -> continue
else ->
if (fallback == UmpBinaryRetrieverFallback.Break) return else throw UmpException("Unexpected flex data text non-continue packet appeared")
}
}
}
// UMP Stream Text
private fun takeUmpStreamText(ump: Ump, outputter: (List) -> Unit, dropSize: Int) {
// It is hack, but it just reuses toPlatformNativeBytes() and then pick up the appropriate parts per platform
// Note that unlike other binary messages we have to treat the bytes in BIG ENDIAN.
val src = ump.toPlatformBytes(ByteOrder.BIG_ENDIAN) // NOTE: memory consumptive
val bytes = src.drop(dropSize).takeWhile { it != 0.toByte() }
outputter(bytes)
}
private fun getUmpStreamTextBytes(input: Iterator, dropSize: Int, fallback: UmpBinaryRetrieverFallback = UmpBinaryRetrieverFallback.Break) : List {
val ret = mutableListOf()
val output: (List) -> Unit = { ret.addAll(it) }
getUmpStreamTextBytes(output, input, dropSize, fallback)
return ret
}
private fun getUmpStreamTextBytes(outputter: (List) -> Unit, input: Iterator, dropSize: Int, fallback: UmpBinaryRetrieverFallback = UmpBinaryRetrieverFallback.Break) {
if (!input.hasNext())
if (fallback == UmpBinaryRetrieverFallback.Break) return else throw UmpException("UMP iterator is empty")
val pStart = input.next()
takeUmpStreamText(pStart, outputter, dropSize)
when (pStart.umpStreamFormat) {
Midi2BinaryChunkFormat.COMPLETE_PACKET -> return
Midi2BinaryChunkFormat.CONTINUE, Midi2BinaryChunkFormat.END ->
if (fallback == UmpBinaryRetrieverFallback.Break) return else throw UmpException("Unexpected flex data text non-starter packet appeared")
}
while (input.hasNext()) {
val pCont = input.next()
takeUmpStreamText(pCont, outputter, dropSize)
when (pCont.umpStreamFormat) {
Midi2BinaryChunkFormat.END -> break
Midi2BinaryChunkFormat.CONTINUE -> continue
else ->
if (fallback == UmpBinaryRetrieverFallback.Break) return else throw UmpException("Unexpected flex data text non-continue packet appeared")
}
}
}
fun getEndpointNameBytes(input: Iterator, fallback: UmpBinaryRetrieverFallback = UmpBinaryRetrieverFallback.Break) =
getUmpStreamTextBytes(input, 2, fallback)
fun getEndpointName(input: Iterator, fallback: UmpBinaryRetrieverFallback = UmpBinaryRetrieverFallback.Break) : String =
getUmpStreamTextBytes(input, 2, fallback).toByteArray().decodeToString()
fun getProductInstanceIdBytes(input: Iterator, fallback: UmpBinaryRetrieverFallback = UmpBinaryRetrieverFallback.Break) =
getUmpStreamTextBytes(input, 2, fallback)
fun getProductInstanceId(input: Iterator, fallback: UmpBinaryRetrieverFallback = UmpBinaryRetrieverFallback.Break) : String =
getUmpStreamTextBytes(input, 2, fallback).toByteArray().decodeToString()
fun getFunctionBlockNameBytes(input: Iterator, fallback: UmpBinaryRetrieverFallback = UmpBinaryRetrieverFallback.Break) =
getUmpStreamTextBytes(input, 3, fallback)
fun getFunctionBlockName(input: Iterator, fallback: UmpBinaryRetrieverFallback = UmpBinaryRetrieverFallback.Break) : String =
getUmpStreamTextBytes(input, 3, fallback).toByteArray().decodeToString()
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy