-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature/ktxio #164
base: development
Are you sure you want to change the base?
Feature/ktxio #164
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
partial review pending partial rewrite
(children?.fold(Buffer()) { acc, extendedTlv -> acc.apply { write(extendedTlv.derEncoded) } } | ||
?.let { | ||
Buffer().apply { write(tlv.tag.encodedTag); encodeLength(it.size); it.transferTo(this) } | ||
}?.readByteArray() | ||
?: Buffer().apply { write(tlv.tag.encodedTag); write(encodedLength);write(tlv.content) }.readByteArray()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i suggest an if expression (or improved indentation)
children?.fold(byteArrayOf()) { acc, extendedTlv -> acc + extendedTlv.derEncoded } | ||
?.let { byteArrayOf(*tlv.tag.encodedTag, *it.size.encodeLength(), *it) } | ||
?: byteArrayOf(*tlv.tag.encodedTag, *encodedLength, *tlv.content) | ||
(children?.fold(Buffer()) { acc, extendedTlv -> acc.apply { write(extendedTlv.derEncoded) } } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
consider Buffer.writeDerEncoded
or similar to avoid copying to bytearray at every layer of the hierarchy
@@ -120,11 +122,9 @@ sealed class Asn1Element( | |||
/** | |||
* Convenience method to directly produce an HEX string of this element's ANS.1 representation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* Convenience method to directly produce an HEX string of this element's ANS.1 representation | |
* Convenience method to directly produce an HEX string of this element's ASN.1 representation |
fun toDerHexString(lineLen: Byte? = null) = @OptIn(ExperimentalStdlibApi::class) | ||
derEncoded.toHexString(HexFormat.UpperCase) | ||
.let { if (lineLen == null) it else it.chunked(lineLen.toInt()).joinToString("\n") } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
broken indentation
@@ -240,8 +240,12 @@ sealed class Asn1Element( | |||
@Serializable(with = ByteArrayBase64Serializer::class) val encodedTag: ByteArray | |||
) : Comparable<Tag> { | |||
private constructor(values: Triple<ULong, Int, ByteArray>) : this(values.first, values.second, values.third) | |||
|
|||
//TODO this CTOR is internally called only using already validated inputs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
outstanding todo
@@ -312,7 +317,7 @@ sealed class Asn1Element( | |||
|
|||
override fun toString(): String = | |||
"${tagClass.let { if (it == TagClass.UNIVERSAL) "" else it.name + " " }}${tagValue}${if (isConstructed) " CONSTRUCTED" else ""}" + | |||
(" (=${encodedTag.encodeToString(Base16)})") | |||
(" (=${@OptIn(ExperimentalStdlibApi::class) encodedTag.toHexString(HexFormat.UpperCase)})") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we just get a @file:OptIn
for this marker
@@ -578,8 +583,7 @@ class Asn1CustomStructure private constructor( | |||
|
|||
|
|||
override val content: ByteArray by lazy { | |||
if (!tag.isConstructed) | |||
children.fold(byteArrayOf()) { acc, asn1Element -> acc + asn1Element.derEncoded } | |||
if (!tag.isConstructed) Buffer().apply { children.forEach { write(it.derEncoded) } }.readByteArray() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should also avoid constant bytearray punning
@@ -16,11 +19,13 @@ internal data class TLV(val tag: Asn1Element.Tag, val content: ByteArray) { | |||
val encodedTag get() = tag.encodedTag | |||
|
|||
override fun equals(other: Any?): Boolean { | |||
if (other is TLV.Shallow || this is TLV.Shallow) throw IllegalStateException("Shallow TLVs may neve be compared") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (other is TLV.Shallow || this is TLV.Shallow) throw IllegalStateException("Shallow TLVs may neve be compared") | |
if (other is TLV.Shallow || this is TLV.Shallow) throw IllegalStateException("Shallow TLVs may never be compared") |
* @see parse | ||
*/ | ||
@Throws(Asn1Exception::class) | ||
fun Asn1Element.Companion.parseFirst(source: ByteArray): Pair<Asn1Element, ByteArray> = | ||
source.iterator().doParseSingle().let { Pair(it, source.copyOfRange(it.overallLength, source.size)) } | ||
Buffer().apply { write(source) }.let { it.readAsn1Element() to it.snapshot().toByteArray() } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how is Buffer().apply { write(source) }
(used here) different from source.copyToSource()
(used elsewhere)?
if (tlv.isSequence()) Asn1Sequence(tlv.content.doParseAll()) | ||
else if (tlv.isSet()) Asn1Set.fromPresorted(tlv.content.doParseAll()) | ||
else if (tlv.isExplicitlyTagged()) | ||
Asn1ExplicitlyTagged(tlv.tag.tagValue, tlv.content.doParseAll()) | ||
else if (tlv.tag == Asn1Element.Tag.OCTET_STRING) catching { | ||
val expected = tlv.content.size | ||
Asn1EncapsulatingOctetString(tlv.content.peek().doParseAll()).also { | ||
if (it.length != expected) throw Asn1StructuralException("The contents contain a valid structure and garbage.") | ||
} as Asn1Element | ||
}.getOrElse { Asn1PrimitiveOctetString(tlv.content.readByteArray()) as Asn1Element } | ||
else if (tlv.tag.isConstructed) { //custom tags, we don't know if it is a SET OF, SET, SEQUENCE, … so we default to sequence semantics | ||
Asn1CustomStructure(tlv.content.doParseAll(), tlv.tag.tagValue, tlv.tagClass) | ||
} else Asn1Primitive(tlv.tag, tlv.content.readByteArray()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please indent:
if (a)
A
else if (b)
B
right now it's very hard to follow
8e9da88
to
4784b65
Compare
use Kotlinx-io for decoding to avoid unneeded byte copying