-
Notifications
You must be signed in to change notification settings - Fork 36
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
olme04
committed
Mar 10, 2022
1 parent
4a7bedb
commit b7c7db9
Showing
30 changed files
with
365 additions
and
419 deletions.
There are no files selected for viewing
129 changes: 129 additions & 0 deletions
129
rsocket-core/src/commonMain/kotlin/io/rsocket/kotlin/CompactType.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
package io.rsocket.kotlin | ||
|
||
import io.ktor.utils.io.core.* | ||
import io.rsocket.kotlin.frame.io.* | ||
import kotlin.experimental.* | ||
|
||
//used for MimeType, AuthType and later in LeaseStrategy | ||
public interface CompactType { | ||
public interface WithId : CompactType { | ||
public val identifier: Byte | ||
} | ||
|
||
public interface WithName : CompactType { | ||
public val text: String | ||
} | ||
|
||
public interface WellKnown : CompactType, WithId, WithName | ||
} | ||
|
||
@Suppress("UNCHECKED_CAST") | ||
//TODO: type relations | ||
public abstract class CompactTypeFactory< | ||
Type : CompactType, | ||
WithId : CompactType.WithId, | ||
WithName : CompactType.WithName, | ||
WellKnown, | ||
> internal constructor( | ||
private val withIdConstructor: (identifier: Byte) -> WithId, | ||
private val withNameConstructor: (text: String) -> WithName, | ||
wellKnownValues: Array<WellKnown>, | ||
) where WellKnown : CompactType.WellKnown, WellKnown : Enum<WellKnown> { | ||
private val wellKnownByIdentifier: Array<Any?> = arrayOfNulls<Any?>(128) | ||
private val wellKnownByName: MutableMap<String, WellKnown> = HashMap(128) | ||
|
||
init { | ||
wellKnownValues.forEach { | ||
wellKnownByIdentifier[it.identifier.toInt()] = it | ||
wellKnownByName[it.text] = it | ||
} | ||
} | ||
|
||
//TODO is it needed? | ||
public fun WellKnown(text: String): WellKnown? = wellKnownByName[text] | ||
public fun WellKnown(identifier: Byte): WellKnown? = wellKnownByIdentifier[identifier.toInt()] as WellKnown? | ||
public fun WellKnown(identifier: Int): WellKnown? = wellKnownByIdentifier[identifier] as WellKnown? | ||
|
||
public fun WithName(text: String): WithName = (WellKnown(text) ?: withNameConstructor(text)) as WithName | ||
public fun WithId(identifier: Byte): WithId = (WellKnown(identifier) ?: withIdConstructor(identifier)) as WithId | ||
public fun WithId(identifier: Int): WithId = WithId(identifier.toByte()) | ||
|
||
public operator fun invoke(text: String): WithName = WithName(text) | ||
public operator fun invoke(identifier: Byte): WithId = WithId(identifier) | ||
public operator fun invoke(identifier: Int): WithId = WithId(identifier) | ||
} | ||
|
||
internal fun CompactType.WellKnown.toString(typeName: String): String = "$typeName(id=$identifier, text=$text)" | ||
internal fun CompactType.WithId.toString(typeName: String): String = "$typeName(id=$identifier)" | ||
internal fun CompactType.WithName.toString(typeName: String): String = "$typeName(text=$text)" | ||
|
||
internal abstract class AbstractCompactTypeWithId(final override val identifier: Byte) : CompactType.WithId { | ||
init { | ||
require(identifier > 0) { "Mime-type identifier must be positive but was '${identifier}'" } | ||
} | ||
|
||
final override fun equals(other: Any?): Boolean { | ||
if (this === other) return true | ||
if (other == null || this::class != other::class) return false | ||
|
||
other as AbstractCompactTypeWithId | ||
|
||
if (identifier != other.identifier) return false | ||
|
||
return true | ||
} | ||
|
||
final override fun hashCode(): Int { | ||
return identifier.hashCode() | ||
} | ||
|
||
abstract override fun toString(): String | ||
} | ||
|
||
internal abstract class AbstractCompactTypeWithName(final override val text: String) : CompactType.WithName { | ||
init { | ||
require(text.all { it.code <= 0x7f }) { "String should be an ASCII encodded string" } | ||
require(text.length in 1..128) { "Mime-type text length must be in range 1..128 but was '${text.length}'" } | ||
} | ||
|
||
final override fun equals(other: Any?): Boolean { | ||
if (this === other) return true | ||
if (other == null || this::class != other::class) return false | ||
|
||
other as AbstractCompactTypeWithName | ||
|
||
if (text != other.text) return false | ||
|
||
return true | ||
} | ||
|
||
final override fun hashCode(): Int { | ||
return text.hashCode() | ||
} | ||
|
||
abstract override fun toString(): String | ||
} | ||
|
||
private const val KnownTypeFlag: Byte = Byte.MIN_VALUE | ||
|
||
internal fun BytePacketBuilder.writeCompactType(type: CompactType) { | ||
when (type) { | ||
is CompactType.WithId -> writeByte(type.identifier or KnownTypeFlag) | ||
is CompactType.WithName -> { | ||
val typeBytes = type.text.encodeToByteArray() | ||
writeByte(typeBytes.size.toByte()) //write length | ||
writeFully(typeBytes) //write type | ||
} | ||
} | ||
} | ||
|
||
internal fun <T : CompactType> ByteReadPacket.readCompactType(factory: CompactTypeFactory<T, *, *, *>): T { | ||
val byte = readByte() | ||
return if (byte check KnownTypeFlag) { | ||
val identifier = byte xor KnownTypeFlag | ||
factory(identifier) | ||
} else { | ||
val stringType = readTextExactBytes(byte.toInt()) | ||
factory(stringType) | ||
} as T | ||
} |
89 changes: 89 additions & 0 deletions
89
rsocket-core/src/commonMain/kotlin/io/rsocket/kotlin/MimeType.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
/* | ||
* Copyright 2015-2020 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package io.rsocket.kotlin | ||
|
||
public sealed interface MimeType : CompactType { | ||
public companion object : CompactTypeFactory<MimeType, WithId, WithName, WellKnown>(::WithIdImpl, ::WithNameImpl, enumValues()) | ||
|
||
public sealed interface WithId : MimeType, CompactType.WithId | ||
public sealed interface WithName : MimeType, CompactType.WithName | ||
public enum class WellKnown( | ||
public override val text: String, | ||
public override val identifier: Byte, | ||
) : MimeType, CompactType.WellKnown, WithId, WithName { | ||
ApplicationAvro("application/avro", 0x00), | ||
ApplicationCbor("application/cbor", 0x01), | ||
ApplicationGraphql("application/graphql", 0x02), | ||
ApplicationGzip("application/gzip", 0x03), | ||
ApplicationJavascript("application/javascript", 0x04), | ||
ApplicationJson("application/json", 0x05), | ||
ApplicationOctetStream("application/octet-stream", 0x06), | ||
ApplicationPdf("application/pdf", 0x07), | ||
ApplicationThrift("application/vnd.apache.thrift.binary", 0x08), | ||
ApplicationProtoBuf("application/vnd.google.protobuf", 0x09), | ||
ApplicationXml("application/xml", 0x0A), | ||
ApplicationZip("application/zip", 0x0B), | ||
AudioAac("audio/aac", 0x0C), | ||
AudioMp3("audio/mp3", 0x0D), | ||
AudioMp4("audio/mp4", 0x0E), | ||
AudioMpeg3("audio/mpeg3", 0x0F), | ||
AudioMpeg("audio/mpeg", 0x10), | ||
AudioOgg("audio/ogg", 0x11), | ||
AudioOpus("audio/opus", 0x12), | ||
AudioVorbis("audio/vorbis", 0x13), | ||
ImageBmp("image/bmp", 0x14), | ||
ImageGif("image/gif", 0x15), | ||
ImageHeicSequence("image/heic-sequence", 0x16), | ||
ImageHeic("image/heic", 0x17), | ||
ImageHeifSequence("image/heif-sequence", 0x18), | ||
ImageHeif("image/heif", 0x19), | ||
ImageJpeg("image/jpeg", 0x1A), | ||
ImagePng("image/png", 0x1B), | ||
ImageTiff("image/tiff", 0x1C), | ||
MultipartMixed("multipart/mixed", 0x1D), | ||
TextCss("text/css", 0x1E), | ||
TextCsv("text/csv", 0x1F), | ||
TextHtml("text/html", 0x20), | ||
TextPlain("text/plain", 0x21), | ||
TextXml("text/xml", 0x22), | ||
VideoH264("video/H264", 0x23), | ||
VideoH265("video/H265", 0x24), | ||
VideoVp8("video/VP8", 0x25), | ||
ApplicationHessian("application/x-hessian", 0x26), | ||
ApplicationJavaObject("application/x-java-object", 0x27), | ||
ApplicationCloudeventsJson("application/cloudevents+json", 0x28), | ||
ApplicationCapnProto("application/x-capnp", 0x29), | ||
ApplicationFlatBuffers("application/x-flatbuffers", 0x2A), | ||
|
||
MessageRSocketMimeType("message/x.rsocket.mime-type.v0", 0x7A), | ||
MessageRSocketAcceptMimeTypes("message/x.rsocket.accept-mime-types.v0", 0x7b), | ||
MessageRSocketAuthentication("message/x.rsocket.authentication.v0", 0x7C), | ||
MessageRSocketTracingZipkin("message/x.rsocket.tracing-zipkin.v0", 0x7D), | ||
MessageRSocketRouting("message/x.rsocket.routing.v0", 0x7E), | ||
MessageRSocketCompositeMetadata("message/x.rsocket.composite-metadata.v0", 0x7F); | ||
|
||
override fun toString(): String = toString("MimeType") | ||
} | ||
|
||
private class WithIdImpl(identifier: Byte) : WithId, AbstractCompactTypeWithId(identifier) { | ||
override fun toString(): String = toString("MimeType") | ||
} | ||
|
||
private class WithNameImpl(text: String) : WithName, AbstractCompactTypeWithName(text) { | ||
override fun toString(): String = toString("MimeType") | ||
} | ||
} |
22 changes: 11 additions & 11 deletions
22
rsocket-core/src/commonMain/kotlin/io/rsocket/kotlin/configuration/MimeTypeConfiguration.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,41 +1,41 @@ | ||
package io.rsocket.kotlin.configuration | ||
|
||
import io.rsocket.kotlin.core.* | ||
import io.rsocket.kotlin.* | ||
|
||
public sealed interface MimeTypeConfiguration { | ||
public val metadata: MimeTypeWithName | ||
public val data: MimeTypeWithName | ||
public val metadata: MimeType.WithName | ||
public val data: MimeType.WithName | ||
} | ||
|
||
public sealed interface MimeTypeConnectConfiguration : MimeTypeConfiguration, ConnectConfiguration | ||
|
||
public sealed interface MimeTypeClientConnectConfiguration : MimeTypeConnectConfiguration { | ||
public fun metadata(mimeType: MimeTypeWithName) | ||
public fun data(mimeType: MimeTypeWithName) | ||
public fun metadata(mimeType: MimeType.WithName) | ||
public fun data(mimeType: MimeType.WithName) | ||
} | ||
|
||
public sealed interface MimeTypeServerConnectConfiguration : MimeTypeConnectConfiguration | ||
|
||
internal class MimeTypeClientConnectConfigurationImpl( | ||
private val configurationState: ConfigurationState, | ||
) : MimeTypeClientConnectConfiguration { | ||
override var metadata: MimeTypeWithName = WellKnownMimeType.ApplicationOctetStream | ||
override var metadata: MimeType.WithName = MimeType.WellKnown.ApplicationOctetStream | ||
private set | ||
override var data: MimeTypeWithName = WellKnownMimeType.ApplicationOctetStream | ||
override var data: MimeType.WithName = MimeType.WellKnown.ApplicationOctetStream | ||
private set | ||
|
||
override fun metadata(mimeType: MimeTypeWithName) { | ||
override fun metadata(mimeType: MimeType.WithName) { | ||
configurationState.checkNotConfigured() | ||
metadata = mimeType | ||
} | ||
|
||
override fun data(mimeType: MimeTypeWithName) { | ||
override fun data(mimeType: MimeType.WithName) { | ||
configurationState.checkNotConfigured() | ||
data = mimeType | ||
} | ||
} | ||
|
||
internal class MimeTypeServerConnectConfigurationImpl( | ||
override val metadata: MimeTypeWithName, | ||
override val data: MimeTypeWithName, | ||
override val metadata: MimeType.WithName, | ||
override val data: MimeType.WithName, | ||
) : MimeTypeServerConnectConfiguration |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
46 changes: 0 additions & 46 deletions
46
rsocket-core/src/commonMain/kotlin/io/rsocket/kotlin/core/MimeType.kt
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.