Added spaceToPlus parameter to decode function

This commit is contained in:
Erik C. Thauvin 2023-01-06 15:57:22 -08:00
parent 7c8a4358b6
commit 4b746ba75c
6 changed files with 32 additions and 11 deletions

View file

@ -41,6 +41,7 @@ UrlEncoder.endode("foo bar", spaceToPlus = true) // -> foo+bar
UrlEncoder.decode("a%20test%20%26") // -> a test & UrlEncoder.decode("a%20test%20%26") // -> a test &
UrlEncoder.decode("%25%23ok%C3%A9k%C3%89%C8%A2%20smile%21%F0%9F%98%81") // -> %#okékÉȢ smile!😁 UrlEncoder.decode("%25%23ok%C3%A9k%C3%89%C8%A2%20smile%21%F0%9F%98%81") // -> %#okékÉȢ smile!😁
UrlEncoder.decode("foo+bar", plusToSpace = true) // -> foo bar
``` ```
## Gradle, Maven, etc. ## Gradle, Maven, etc.
@ -54,7 +55,7 @@ repositories {
} }
dependencies { dependencies {
implementation("net.thauvin.erik:urlencoder:1.0.1") implementation("net.thauvin.erik:urlencoder:1.3.0")
} }
``` ```

View file

@ -23,7 +23,7 @@ plugins {
description = "A simple defensive library to encode/decode URL components" description = "A simple defensive library to encode/decode URL components"
group = "net.thauvin.erik" group = "net.thauvin.erik"
version = "1.2.1-SNAPSHOT" version = "1.3.0-SNAPSHOT"
val mavenName = "UrlEncoder" val mavenName = "UrlEncoder"

View file

@ -10,5 +10,6 @@
<ID>MagicNumber:UrlEncoder.kt$UrlEncoder$4</ID> <ID>MagicNumber:UrlEncoder.kt$UrlEncoder$4</ID>
<ID>MaxLineLength:UrlEncoder.kt$UrlEncoder$*</ID> <ID>MaxLineLength:UrlEncoder.kt$UrlEncoder$*</ID>
<ID>NestedBlockDepth:UrlEncoder.kt$UrlEncoder$@JvmStatic @JvmOverloads fun encode(source: String, allow: String = "", spaceToPlus: Boolean = false): String</ID> <ID>NestedBlockDepth:UrlEncoder.kt$UrlEncoder$@JvmStatic @JvmOverloads fun encode(source: String, allow: String = "", spaceToPlus: Boolean = false): String</ID>
<ID>NestedBlockDepth:UrlEncoder.kt$UrlEncoder$@JvmStatic fun decode(source: String, plusToSpace: Boolean = false): String</ID>
</CurrentIssues> </CurrentIssues>
</SmellBaseline> </SmellBaseline>

View file

@ -8,7 +8,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>net.thauvin.erik</groupId> <groupId>net.thauvin.erik</groupId>
<artifactId>urlencoder</artifactId> <artifactId>urlencoder</artifactId>
<version>1.2.1-SNAPSHOT</version> <version>1.3.0-SNAPSHOT</version>
<name>UrlEncoder for Kotlin</name> <name>UrlEncoder for Kotlin</name>
<description>A simple defensive library to encode/decode URL components</description> <description>A simple defensive library to encode/decode URL components</description>
<url>https://github.com/ethauvin/urlencoder</url> <url>https://github.com/ethauvin/urlencoder</url>

View file

@ -84,23 +84,24 @@ object UrlEncoder {
* encoding. * encoding.
*/ */
@JvmStatic @JvmStatic
fun decode(source: String): String { fun decode(source: String, plusToSpace: Boolean = false): String {
if (source.isEmpty()) { if (source.isEmpty()) {
return source return source
} }
val length = source.length val length = source.length
var out: StringBuilder? = null val out: StringBuilder by lazy { StringBuilder(length) }
var ch: Char var ch: Char
var bytesBuffer: ByteArray? = null var bytesBuffer: ByteArray? = null
var bytesPos = 0 var bytesPos = 0
var i = 0 var i = 0
var start = false
while (i < length) { while (i < length) {
ch = source[i] ch = source[i]
if (ch == '%') { if (ch == '%') {
if (out == null) { if (!start) {
out = StringBuilder(length)
out.append(source, 0, i) out.append(source, 0, i)
start = true
} }
if (bytesBuffer == null) { if (bytesBuffer == null) {
// the remaining characters divided by the length of the encoding format %xx, is the maximum number // the remaining characters divided by the length of the encoding format %xx, is the maximum number
@ -119,20 +120,30 @@ object UrlEncoder {
} }
} else { } else {
if (bytesBuffer != null) { if (bytesBuffer != null) {
out!!.append(String(bytesBuffer, 0, bytesPos, StandardCharsets.UTF_8)) out.append(String(bytesBuffer, 0, bytesPos, StandardCharsets.UTF_8))
start = true
bytesBuffer = null bytesBuffer = null
bytesPos = 0 bytesPos = 0
} }
out?.append(ch) if (plusToSpace && ch == '+') {
if (!start) {
out.append(source, 0, i)
}
out.append(" ")
start = true
} else if (start) {
out.append(ch)
start = true
}
i++ i++
} }
} }
if (bytesBuffer != null) { if (bytesBuffer != null) {
out!!.append(String(bytesBuffer, 0, bytesPos, StandardCharsets.UTF_8)) out.append(String(bytesBuffer, 0, bytesPos, StandardCharsets.UTF_8))
} }
return out?.toString() ?: source return if (!start) source else out.toString()
} }
/** /**

View file

@ -73,6 +73,14 @@ class UrlEncoderTest {
assertEquals(" ", decode(" "), "decode(' ')") assertEquals(" ", decode(" "), "decode(' ')")
} }
@Test
fun `Decode with Plus to Space`() {
assertEquals("foo bar", decode("foo+bar", true))
assertEquals("foo bar foo", decode("foo+bar++foo", true))
assertEquals("foo bar foo", decode("foo+%20bar%20+foo", true))
assertEquals("foo + bar", decode("foo+%2B+bar", plusToSpace = true))
}
@ParameterizedTest(name = "encode({0}) should be {1}") @ParameterizedTest(name = "encode({0}) should be {1}")
@MethodSource("validMap") @MethodSource("validMap")
fun `Encode URL`(source: String, expected: String) { fun `Encode URL`(source: String, expected: String) {