+ * The maintained byte stream is kept in a decoded form.
+ *
+ * @param
+ * Encodes the wrapped value to produce a string.
+ *
+ * @return the base64 encoded value
+ */
+ @Override
+ public String asString(Object encodedBuffer) {
+ byte[] encodedBytes = bufferToBytes((ByteBuffer) encodedBuffer, false);
+ return new String(encodedBytes, StandardCharsets.UTF_8);
+ // return bytesToString(encodedBytes);
+
+ // byte[] decodedBytes = bufferToBytes((ByteBuffer) decodedBuffer, false);
+ // byte[] encodedBytes = encode(decodedBytes);
+ // return bytesToString(encodedBytes);
+ }
+
+ @Override
+ public JsonFormatTypes getJsonRawType() {
+ return JsonFormatTypes.STRING;
+ }
+
+ @Override
+ public ByteBuffer copy(Object obj) {
+ ByteBuffer buffer = (ByteBuffer) obj;
+ ByteBuffer clone = buffer.isDirect()
+ ? ByteBuffer.allocateDirect(buffer.capacity())
+ : ByteBuffer.allocate(buffer.capacity());
+ ByteBuffer readOnlyCopy = buffer.asReadOnlyBuffer();
+ readOnlyCopy.flip();
+ clone.put(readOnlyCopy);
+ return clone;
+ }
+
+ @NonNull
+ public static byte[] bufferToBytes(@NonNull ByteBuffer buffer, boolean copy) {
+ byte[] array;
+ if (buffer.hasArray()) {
+ array = buffer.array();
+ if (copy) {
+ array = Arrays.copyOf(array, array.length);
+ }
+ } else {
+ // Handle direct buffers
+ array = new byte[buffer.remaining()];
+ buffer.mark();
+ try {
+ buffer.get(array);
+ } finally {
+ buffer.reset();
+ }
+ }
+ return ObjectUtils.notNull(array);
+ }
+}
diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/Base64Adapter.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/Base64Adapter.java
index fc006d11b..0724903a9 100644
--- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/Base64Adapter.java
+++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/Base64Adapter.java
@@ -5,33 +5,31 @@
package gov.nist.secauto.metaschema.core.datatype.adapter;
-import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatTypes;
-
-import gov.nist.secauto.metaschema.core.datatype.AbstractDataTypeAdapter;
import gov.nist.secauto.metaschema.core.metapath.MetapathConstants;
import gov.nist.secauto.metaschema.core.metapath.item.atomic.IBase64BinaryItem;
import gov.nist.secauto.metaschema.core.qname.EQNameFactory;
import gov.nist.secauto.metaschema.core.qname.IEnhancedQName;
import gov.nist.secauto.metaschema.core.util.ObjectUtils;
+import org.apache.commons.codec.BinaryDecoder;
+import org.apache.commons.codec.BinaryEncoder;
+import org.apache.commons.codec.binary.Base64;
+
import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.Base64;
import java.util.List;
import edu.umd.cs.findbugs.annotations.NonNull;
/**
- * Maintains a byte buffer backed representation of a byte stream parsed from a base64 encoded
- * string.
+ * Maintains a byte buffer backed representation of a byte stream parsed from a
+ * BASE64 encoded string.
*
- * Provides support for the Metaschema
- * base64 data
- * type.
+ * Provides support for the Metaschema BASE64
+ * data type.
*/
public class Base64Adapter
- extends AbstractDataTypeAdapter
+ * Provides support for the Metaschema base64
+ * data type.
+ */
+public class HexBinaryAdapter
+ extends AbstractBinaryAdapter
- * The provided buffer will be managed by this instance. Make a copy of the buffer to ensure that
- * the position, limit, and mark of the original are not affect by this.
+ * The provided buffer will be managed by this instance. Make a copy of the
+ * buffer to ensure that the position, limit, and mark of the original are not
+ * affect by this.
*
* @param buffer
* a byte buffer
@@ -99,7 +103,8 @@ static IBase64BinaryItem valueOf(@NonNull ByteBuffer buffer) {
*
* @param item
* the item to cast
- * @return the original item if it is already this type, otherwise a new item cast to this type
+ * @return the original item if it is already this type, otherwise a new item
+ * cast to this type
* @throws InvalidValueForCastFunctionException
* if the provided {@code item} cannot be cast to this type
*/
@@ -120,14 +125,6 @@ default IBase64BinaryItem castAsType(IAnyAtomicItem item) {
return cast(item);
}
- /**
- * Get the "wrapped" byte buffer value.
- *
- * @return the underlying byte buffer value
- */
- @NonNull
- ByteBuffer asByteBuffer();
-
@Override
default int compareTo(IAnyAtomicItem item) {
return compareTo(cast(item));
@@ -138,8 +135,8 @@ default int compareTo(IAnyAtomicItem item) {
*
* @param item
* the item to compare with this value
- * @return a negative integer, zero, or a positive integer if this value is less than, equal to, or
- * greater than the {@code item}.
+ * @return a negative integer, zero, or a positive integer if this value is less
+ * than, equal to, or greater than the {@code item}.
*/
default int compareTo(@NonNull IBase64BinaryItem item) {
return asByteBuffer().compareTo(item.asByteBuffer());
diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IHexBinaryItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IHexBinaryItem.java
new file mode 100644
index 000000000..0221aede8
--- /dev/null
+++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IHexBinaryItem.java
@@ -0,0 +1,122 @@
+/*
+ * SPDX-FileCopyrightText: none
+ * SPDX-License-Identifier: CC0-1.0
+ */
+
+package gov.nist.secauto.metaschema.core.metapath.item.atomic;
+
+import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider;
+import gov.nist.secauto.metaschema.core.metapath.function.InvalidValueForCastFunctionException;
+import gov.nist.secauto.metaschema.core.metapath.item.atomic.impl.HexBinaryItem;
+import gov.nist.secauto.metaschema.core.metapath.item.atomic.impl.IBinaryItem;
+import gov.nist.secauto.metaschema.core.metapath.type.IAtomicOrUnionType;
+import gov.nist.secauto.metaschema.core.metapath.type.InvalidTypeMetapathException;
+
+import java.nio.ByteBuffer;
+
+import edu.umd.cs.findbugs.annotations.NonNull;
+
+/**
+ * An atomic Metapath item containing a Base64 encoded data value.
+ */
+public interface IHexBinaryItem extends IBinaryItem {
+ /**
+ * Get the type information for this item.
+ *
+ * @return the type information
+ */
+ @NonNull
+ static IAtomicOrUnionType
+ * The provided buffer will be managed by this instance. Make a copy of the
+ * buffer to ensure that the position, limit, and mark of the original are not
+ * affect by this.
+ *
+ * @param buffer
+ * a byte buffer
+ * @return the new item
+ */
+ @NonNull
+ static IHexBinaryItem valueOf(@NonNull ByteBuffer buffer) {
+ return new HexBinaryItem(buffer);
+ }
+
+ /**
+ * Cast the provided type to this item type.
+ *
+ * @param item
+ * the item to cast
+ * @return the original item if it is already this type, otherwise a new item
+ * cast to this type
+ * @throws InvalidValueForCastFunctionException
+ * if the provided {@code item} cannot be cast to this type
+ */
+ @NonNull
+ static IHexBinaryItem cast(@NonNull IAnyAtomicItem item) {
+ try {
+ return item instanceof IHexBinaryItem
+ ? (IHexBinaryItem) item
+ : valueOf(item.asString());
+ } catch (IllegalStateException | InvalidTypeMetapathException ex) {
+ // asString can throw IllegalStateException exception
+ throw new InvalidValueForCastFunctionException(ex);
+ }
+ }
+
+ @Override
+ default IHexBinaryItem castAsType(IAnyAtomicItem item) {
+ return cast(item);
+ }
+
+ @Override
+ default int compareTo(IAnyAtomicItem item) {
+ return compareTo(cast(item));
+ }
+
+ /**
+ * Compares this value with the argument.
+ *
+ * @param item
+ * the item to compare with this value
+ * @return a negative integer, zero, or a positive integer if this value is less
+ * than, equal to, or greater than the {@code item}.
+ */
+ default int compareTo(@NonNull IHexBinaryItem item) {
+ return asByteBuffer().compareTo(item.asByteBuffer());
+ }
+}
diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IStringItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IStringItem.java
index 1760f1888..07ff0266d 100644
--- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IStringItem.java
+++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IStringItem.java
@@ -36,7 +36,8 @@ default IAtomicOrUnionType extends IStringItem> getType() {
* Construct a new item using the provided string {@code value}.
*
* @param value
- * a string value that must conform to Metaschema string validation rules
+ * a string value that must conform to Metaschema string validation
+ * rules
* @return the new item
* @throws InvalidTypeMetapathException
* if the value fails string validation
@@ -65,7 +66,8 @@ default IBase64BinaryItem encode() {
*
* @param item
* the item to cast
- * @return the original item if it is already this type, otherwise a new item cast to this type
+ * @return the original item if it is already this type, otherwise a new item
+ * cast to this type
* @throws InvalidValueForCastFunctionException
* if the provided {@code item} cannot be cast to this type
*/
@@ -92,12 +94,13 @@ default IStringItem castAsType(IAnyAtomicItem item) {
}
/**
- * Compares this value with the argument. Ordering is in lexical dictionary order.
+ * Compares this value with the argument. Ordering is in lexical dictionary
+ * order.
*
* @param other
* the item to compare with this value
- * @return a negative integer, zero, or a positive integer if this value is less than, equal to, or
- * greater than the {@code item}.
+ * @return a negative integer, zero, or a positive integer if this value is less
+ * than, equal to, or greater than the {@code item}.
*/
default int compareTo(@NonNull IStringItem other) {
return asString().compareTo(other.asString());
diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/AbstractBinaryItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/AbstractBinaryItem.java
new file mode 100644
index 000000000..84f15eabb
--- /dev/null
+++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/AbstractBinaryItem.java
@@ -0,0 +1,40 @@
+/*
+ * SPDX-FileCopyrightText: none
+ * SPDX-License-Identifier: CC0-1.0
+ */
+
+package gov.nist.secauto.metaschema.core.metapath.item.atomic.impl;
+
+import gov.nist.secauto.metaschema.core.metapath.item.atomic.AbstractAnyAtomicItem;
+
+import java.nio.ByteBuffer;
+
+import edu.umd.cs.findbugs.annotations.NonNull;
+
+/**
+ * An implementation of a Metapath atomic item containing a binary data value.
+ */
+public abstract class AbstractBinaryItem
+ extends AbstractAnyAtomicItem