2024-04-07 17:32:44 +00:00
|
|
|
package prog8.code.target.encodings
|
2022-01-19 00:08:24 +00:00
|
|
|
|
|
|
|
import com.github.michaelbull.result.Err
|
2022-02-05 02:50:54 +00:00
|
|
|
import com.github.michaelbull.result.Ok
|
|
|
|
import com.github.michaelbull.result.Result
|
2022-01-19 00:08:24 +00:00
|
|
|
import java.io.CharConversionException
|
2022-01-19 19:45:24 +00:00
|
|
|
import java.nio.charset.Charset
|
2022-01-19 00:08:24 +00:00
|
|
|
|
2024-04-07 17:32:44 +00:00
|
|
|
open class IsoEncodingBase(charsetName: String) {
|
|
|
|
val charset: Charset = Charset.forName(charsetName)
|
2022-01-19 19:45:24 +00:00
|
|
|
|
2022-01-19 00:08:24 +00:00
|
|
|
fun encode(str: String): Result<List<UByte>, CharConversionException> {
|
|
|
|
return try {
|
2022-03-24 23:17:41 +00:00
|
|
|
val mapped = str.map { chr ->
|
|
|
|
when (chr) {
|
|
|
|
'\u0000' -> 0u
|
|
|
|
in '\u8000'..'\u80ff' -> {
|
|
|
|
// special case: take the lower 8 bit hex value directly
|
|
|
|
(chr.code - 0x8000).toUByte()
|
|
|
|
}
|
|
|
|
else -> charset.encode(chr.toString())[0].toUByte()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(mapped)
|
2022-01-19 00:08:24 +00:00
|
|
|
} catch (ce: CharConversionException) {
|
|
|
|
Err(ce)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-07 14:25:33 +00:00
|
|
|
fun decode(bytes: Iterable<UByte>): Result<String, CharConversionException> {
|
2022-01-19 00:27:28 +00:00
|
|
|
return try {
|
2022-01-19 19:45:24 +00:00
|
|
|
Ok(String(bytes.map { it.toByte() }.toByteArray(), charset))
|
2022-01-19 00:27:28 +00:00
|
|
|
} catch (ce: CharConversionException) {
|
|
|
|
Err(ce)
|
|
|
|
}
|
2022-01-19 00:08:24 +00:00
|
|
|
}
|
|
|
|
}
|
2024-04-07 17:32:44 +00:00
|
|
|
|
|
|
|
|
|
|
|
object IsoEncoding: IsoEncodingBase("ISO-8859-15")
|
|
|
|
object IsoCyrillicEncoding: IsoEncodingBase("ISO-8859-5")
|
|
|
|
object IsoEasternEncoding: IsoEncodingBase("ISO-8859-16")
|