Skip to content

Commit

Permalink
Added documentation and junit tests for the adapter and item.
Browse files Browse the repository at this point in the history
  • Loading branch information
david-waltermire committed Jan 6, 2025
1 parent 0c8eafb commit a96290e
Show file tree
Hide file tree
Showing 6 changed files with 281 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,41 @@ protected AbstractBinaryAdapter(
super(ByteBuffer.class, itemClass, castExecutor);
}

/**
* Get the binary decoder to use to decode encoded data.
*
* @return the decoder
*/
@NonNull
protected abstract BinaryDecoder getDecoder();

/**
* Get the binary encoder to use to encode data.
*
* @return the encoder
*/
@NonNull
protected abstract BinaryEncoder getEncoder();

/**
* Get the raw bytes, encoded as UTF8, for the provided text string.
*
* @param text
* the text string to get the bytes for
* @return the UTF8 encoded bytes for the text string
*/
@NonNull
private static byte[] stringToBytes(@NonNull String text) {
return text.getBytes(StandardCharsets.UTF_8);
return ObjectUtils.notNull(text.getBytes(StandardCharsets.UTF_8));
}

/**
* Get a text string based on the provided raw bytes, encoded as UTF8.
*
* @param bytes
* a byte array encoded as UTF8
* @return the decoded text string
*/
@NonNull
private static String bytesToString(@NonNull byte[] bytes) {
return new String(bytes, StandardCharsets.UTF_8);
Expand All @@ -68,6 +92,14 @@ private static String elide(@NonNull String text, int length) {
return text.length() <= length ? text : text.substring(0, length) + "…";
}

/**
* Encode the provided bytes using the encoding supported by this class.
*
* @param decodedBytes
* the bytes to encode
* @return the encoded bytes
* @see #getEncoder()
*/
@NonNull
public byte[] encode(@NonNull byte[] decodedBytes) {
try {
Expand All @@ -79,24 +111,58 @@ public byte[] encode(@NonNull byte[] decodedBytes) {
}
}

/**
* Encode the provided bytes using the encoding supported by this class.
*
* @param decodedBuffer
* a buffer containing the bytes to encode
* @return a buffer containing the encoded bytes
* @see #getEncoder()
*/
@NonNull
public ByteBuffer encodeToByteBuffer(@NonNull ByteBuffer decodedBuffer) {
byte[] decodedBytes = bufferToBytes(decodedBuffer, false);
return encodeToByteBuffer(decodedBytes);
}

/**
* Encode the provided string using the encoding supported by this class.
* <p>
* The provided string is first encoded as a stream of UTF8 bytes.
*
* @param decodedText
* the string to encode
* @return a buffer containing the encoded bytes
* @see #getEncoder()
*/
@NonNull
public ByteBuffer encodeToByteBuffer(String decodedText) {
public ByteBuffer encodeToByteBuffer(@NonNull String decodedText) {
byte[] decodedBytes = stringToBytes(decodedText);
return encodeToByteBuffer(decodedBytes);
}

/**
* Encode the provided bytes using the encoding supported by this class.
*
* @param decodedBytes
* the bytes to encode
* @return a buffer containing the encoded bytes
* @see #getEncoder()
*/
@NonNull
public ByteBuffer encodeToByteBuffer(byte[] decodedBytes) {
public ByteBuffer encodeToByteBuffer(@NonNull byte[] decodedBytes) {
byte[] encodedBytes = encode(decodedBytes);
return ObjectUtils.notNull(ByteBuffer.wrap(encodedBytes));
}

/**
* Decode the provided bytes using the encoding supported by this class.
*
* @param enodedBytes
* the bytes to decode
* @return the decoded bytes
* @see #getDecoder()
*/
@NonNull
public byte[] decode(@NonNull byte[] enodedBytes) {
try {
Expand All @@ -108,13 +174,31 @@ public byte[] decode(@NonNull byte[] enodedBytes) {
}
}

/**
* Decode the provided bytes using the encoding supported by this class.
*
* @param encodedBuffer
* a buffer containing the the bytes to decode
* @return a buffer containing the decoded bytes
* @see #getDecoder()
*/
@NonNull
public ByteBuffer decode(@NonNull ByteBuffer encodedBuffer) {
byte[] encodedBytes = bufferToBytes(encodedBuffer, false);
byte[] decodedBytes = decode(encodedBytes);
return ObjectUtils.notNull(ByteBuffer.wrap(decodedBytes));
}

/**
* Decode the provided bytes using the encoding supported by this class.
* <p>
* The decoded bytes are decoded as a stream of UTF8 bytes to produce the string.
*
* @param encodedBytes
* the bytes to decode
* @return the decoded string
* @see #getDecoder()
*/
@NonNull
public String decodeToString(@NonNull byte[] encodedBytes) {
byte[] decodedBytes = decode(encodedBytes);
Expand Down Expand Up @@ -169,6 +253,15 @@ public ByteBuffer copy(Object obj) {
return clone;
}

/**
* Get the array of bytes stored in the buffer.
*
* @param buffer
* the buffer
* @param copy
* if {@code true} ensure the resulting array is a copy
* @return the array of bytes
*/
@NonNull
public static byte[] bufferToBytes(@NonNull ByteBuffer buffer, boolean copy) {
byte[] array;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* SPDX-FileCopyrightText: none
* SPDX-License-Identifier: CC0-1.0
*/

package gov.nist.secauto.metaschema.core.metapath.function.library;

import gov.nist.secauto.metaschema.core.metapath.DynamicContext;
import gov.nist.secauto.metaschema.core.metapath.MetapathConstants;
import gov.nist.secauto.metaschema.core.metapath.function.FunctionUtils;
import gov.nist.secauto.metaschema.core.metapath.function.IArgument;
import gov.nist.secauto.metaschema.core.metapath.function.IFunction;
import gov.nist.secauto.metaschema.core.metapath.item.IItem;
import gov.nist.secauto.metaschema.core.metapath.item.ISequence;
import gov.nist.secauto.metaschema.core.metapath.item.atomic.IBase64BinaryItem;
import gov.nist.secauto.metaschema.core.metapath.item.atomic.IStringItem;
import gov.nist.secauto.metaschema.core.util.ObjectUtils;

import java.util.List;

import edu.umd.cs.findbugs.annotations.NonNull;

/**
* Provides a new Metapath function that decodes provided encoded text using base64.
*
*/
public final class MpBase64Decode {
private static final String NAME = "base64-decode-text";

@NonNull
static final IFunction SIGNATURE_ONE_ARG = IFunction.builder()
.name(NAME)
.namespace(MetapathConstants.NS_METAPATH_FUNCTIONS_EXTENDED)
.deterministic()
.contextIndependent()
.focusIndependent()
.argument(IArgument.builder()
.name("encodedText")
.type(IBase64BinaryItem.type())
.one()
.build())
.returnType(IStringItem.type())
.returnOne()
.functionHandler(MpBase64Decode::executeOneArg)
.build();

private MpBase64Decode() {
// disable construction
}

@SuppressWarnings("unused")
@NonNull
private static ISequence<IStringItem> executeOneArg(
@NonNull IFunction function,
@NonNull List<ISequence<?>> arguments,
@NonNull DynamicContext dynamicContext,
IItem focus) {
IBase64BinaryItem encodedText
= FunctionUtils.asType(ObjectUtils.requireNonNull(arguments.get(0).getFirstItem(true)));
return ISequence.of(encodedText.decodeAsString());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@
import edu.umd.cs.findbugs.annotations.NonNull;

/**
* Provides new Metapath functions that evaluate a Metapath recursively over
* sequences generated by evaluating that expression.
* Provides a new Metapath function that encodes provided text using base64.
*/
public final class MpBase64Encode {
private static final String NAME = "base64-encode-text";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,31 +35,63 @@ default IAtomicOrUnionType<IBase64BinaryItem> getType() {
return type();
}

static IBase64BinaryItem encode(@NonNull String value) {
return valueOf(MetaschemaDataTypeProvider.BASE64.encodeToByteBuffer(value));
/**
* Base64 encode the provided string.
* <p>
* The provided string is first encoded as a stream of UTF8 bytes.
*
* @param text
* the string to encode
* @return a base64 item representing the encoded data
*/
static IBase64BinaryItem encode(@NonNull String text) {
return valueOf(MetaschemaDataTypeProvider.BASE64.encodeToByteBuffer(text));
}

/**
* Base64 encode the provided bytes.
*
* @param bytes
* the bytes to encode
* @return a base64 item representing the encoded data
*/
@NonNull
static IBase64BinaryItem encode(@NonNull byte[] bytes) {
return valueOf(MetaschemaDataTypeProvider.BASE64.encodeToByteBuffer(bytes));
}

/**
* Base64 encode the bytes from the provided buffer.
*
* @param buffer
* the bytes to encode
* @return a base64 item representing the encoded data
*/
@NonNull
static IBase64BinaryItem encode(@NonNull ByteBuffer buffer) {
return valueOf(MetaschemaDataTypeProvider.BASE64.encodeToByteBuffer(buffer));
}

/**
* Base64 decode this item as a new hex binary item.
*
* @return a new hex binary item containing the decoded bytes
*/
default IHexBinaryItem decode() {
return IHexBinaryItem.valueOf(MetaschemaDataTypeProvider.BASE64.decode(asByteBuffer()));
}

/**
* Base64 decode this item as a string.
*
* @return a new string item containing the decoded text
*/
default IStringItem decodeAsString() {
return IStringItem.valueOf(MetaschemaDataTypeProvider.BASE64.decodeToString(asBytes()));
}

/**
* Construct a new base64 byte sequence item using the provided base64 encoded
* string {@code value}.
* Construct a new base64 byte sequence item using the provided base64 encoded string {@code value}.
*
* @param value
* a string representing base64 encoded data
Expand All @@ -82,12 +114,11 @@ static IBase64BinaryItem valueOf(@NonNull String value) {
}

/**
* Construct a new URI base64 encoded byte sequence using the provided
* {@link ByteBuffer} {@code value}.
* Construct a new URI base64 encoded byte sequence using the provided {@link ByteBuffer}
* {@code value}.
* <p>
* 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
Expand All @@ -103,8 +134,7 @@ 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
*/
Expand Down Expand Up @@ -135,8 +165,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());
Expand Down
Loading

0 comments on commit a96290e

Please sign in to comment.