forked from openhab/openhab-core
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
UID: allow to encode arbitrary string (+decode) (openhab#864)
Signed-off-by: Markus Rathgeb <[email protected]> GitOrigin-RevId: fefbef5
- Loading branch information
Showing
2 changed files
with
141 additions
and
0 deletions.
There are no files selected for viewing
96 changes: 96 additions & 0 deletions
96
bundles/org.openhab.core/src/main/java/org/eclipse/smarthome/core/util/UIDUtils.java
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,96 @@ | ||
/** | ||
* Copyright (c) 2010-2019 Contributors to the openHAB project | ||
* | ||
* See the NOTICE file(s) distributed with this work for additional | ||
* information. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0 | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*/ | ||
package org.eclipse.smarthome.core.util; | ||
|
||
import java.nio.charset.StandardCharsets; | ||
|
||
import org.eclipse.jdt.annotation.NonNullByDefault; | ||
|
||
/** | ||
* Utilities for UIDs. | ||
* | ||
* @author Markus Rathgeb - Initial contribution | ||
*/ | ||
@NonNullByDefault | ||
public class UIDUtils { | ||
|
||
/** | ||
* Encodes a given string to an UID using only allowed characters. | ||
* | ||
* <p> | ||
* The generated UID can be given to the {@link #decode(String)} function and it will result into the given value. | ||
* | ||
* @param value the string that should be encoded to a valid UID | ||
* @return a string that if a valid UID (with respect to the allowed characters) | ||
*/ | ||
public static String encode(final String value) { | ||
if (value.isEmpty()) { | ||
return value; | ||
} | ||
|
||
final byte[] in = value.getBytes(StandardCharsets.UTF_8); | ||
final byte[] out = new byte[in.length * 3]; | ||
|
||
int opos = 0; | ||
for (int ipos = 0; ipos < in.length; ++ipos, ++opos) { | ||
final byte cur = in[ipos]; | ||
if (cur >= '0' && cur <= '9' || cur >= 'A' && cur <= 'Z' || cur >= 'a' && cur <= 'z') { | ||
out[opos] = cur; | ||
} else { | ||
out[opos++] = '_'; | ||
final byte[] hex = HexUtils.byteToHex(cur); | ||
out[opos++] = hex[0]; | ||
out[opos] = hex[1]; | ||
} | ||
} | ||
|
||
return new String(out, 0, opos, StandardCharsets.UTF_8); | ||
} | ||
|
||
/** | ||
* Decodes an UID that has been generated by the {@link #encode(String)} function. | ||
* | ||
* <p> | ||
* This function should only be used for UIDs generated by the {@link #encode(String)} function. For every other UID | ||
* the result is rather useless or could result into an {@link IllegalArgumentException}. | ||
* | ||
* @param value the UID to decode | ||
* @return the decoded UID string | ||
* @throws IllegalArgumentException if the given UID is not a valid encoded input | ||
*/ | ||
public static String decode(final String value) { | ||
if (value.isEmpty()) { | ||
return value; | ||
} | ||
|
||
final byte[] in = value.getBytes(StandardCharsets.UTF_8); | ||
final byte[] out = new byte[in.length]; | ||
|
||
int opos = 0; | ||
for (int ipos = 0; ipos < in.length; ++ipos, ++opos) { | ||
final byte cur = in[ipos]; | ||
if (cur >= '0' && cur <= '9' || cur >= 'A' && cur <= 'Z' || cur >= 'a' && cur <= 'z') { | ||
out[opos] = cur; | ||
} else if (cur == '_') { | ||
final byte curHigh = in[++ipos]; | ||
final byte curLow = in[++ipos]; | ||
out[opos] = HexUtils.hexToByte(curHigh, curLow); | ||
} else { | ||
throw new IllegalArgumentException("Invalid input"); | ||
} | ||
} | ||
|
||
return new String(out, 0, opos, StandardCharsets.UTF_8); | ||
} | ||
|
||
} |
45 changes: 45 additions & 0 deletions
45
bundles/org.openhab.core/src/test/java/org/eclipse/smarthome/core/common/UIDUtilsTest.java
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,45 @@ | ||
/** | ||
* Copyright (c) 2010-2019 Contributors to the openHAB project | ||
* | ||
* See the NOTICE file(s) distributed with this work for additional | ||
* information. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0 | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*/ | ||
package org.eclipse.smarthome.core.common; | ||
|
||
import java.util.function.Consumer; | ||
|
||
import org.eclipse.smarthome.core.util.UIDUtils; | ||
import org.hamcrest.core.IsEqual; | ||
import org.junit.Assert; | ||
import org.junit.Test; | ||
|
||
/** | ||
* Tests for {@link AbstractUID}. | ||
* | ||
* @author Markus Rathgeb - Initial contribution | ||
*/ | ||
public class UIDUtilsTest { | ||
|
||
@Test | ||
public void encodeDecode() { | ||
Consumer<String> test = in -> { | ||
final String encoded = UIDUtils.encode(in); | ||
final String decoded = UIDUtils.decode(encoded); | ||
System.out.printf("in: %s%n encoded: %s%n decoded: %s%n equals: %b%n", in, encoded, decoded, | ||
in.equals(decoded)); | ||
Assert.assertThat(decoded, IsEqual.equalTo(in)); | ||
}; | ||
test.accept("test"); | ||
test.accept("TEST"); | ||
test.accept("test123TEST"); | ||
test.accept("test_test-test%test"); | ||
test.accept("äöø€"); | ||
} | ||
|
||
} |