Class BaseDataType<T>
- java.lang.Object
-
- com.automation_pros.odva.cip.data.BaseDataType<T>
-
- Type Parameters:
T
- The java type stored and retrieved by set() and get() methods.
- Direct Known Subclasses:
BaseDate
,BaseString
,BaseTimestamp
,CipBOOL
,CipDT
,CipEPATH
,CipLREAL
,CipREAL
,CipSTRINGI
,CipStruct
,CipUDINT
,CipUINT
,CipULINT
,CipUSINT
public abstract class BaseDataType<T> extends java.lang.Object
Implementation of core functionality of all CIP data types:- Multi-dimensional arrays
- Shared-storage slices of arrays
- Non-zero first subscripts of arrays
- Payload get and set operations across multiple array elements
- Type code helpers for CIP and Logix
-
-
Field Summary
Fields Modifier and Type Field Description protected int[]
dimensions
protected int[]
memberOffsets
static org.slf4j.Logger
sLogger
protected DataContext
variantContext
When dimensions are driven by external values, they are looked up when needed in a given context.protected CipPath
varyingDimension
-
Constructor Summary
Constructors Modifier Constructor Description protected
BaseDataType()
Implementing instances must set 'dimensions' in their constructor, as all other methods will reference it.protected
BaseDataType(BaseDataType<?> data, int[] indices)
Constructor for wrapped or derived instances.
-
Method Summary
All Methods Static Methods Instance Methods Abstract Methods Concrete Methods Modifier and Type Method Description int
alignment()
Obtain the natural alignment of this data type.java.util.List<PathSegment>
browseInner()
Arrays and complex data types are traversed with path following segments in theDataResolver
class.java.util.List<PathSegment>
browseInnerImpl()
Complex types that have nested data understood by the DataResolver must enumerate the path segments that are appropriate for the current instance's content.int
bytes(int... indices)
Retrieve the entire bytes size of this object's payload, or a slice of it.abstract int
bytesEach()
Obtain the bytes-per-element of this object's payload encoding.protected abstract int
bytesImpl(int[] indices)
Retrieve the bytes payload size of a single array element (or sole element).protected boolean
checkDimensions(int[] newDimensions)
Helper for use in setDimensions() implementations.void
chkAbbrevType(java.nio.ByteBuffer source)
protected int[]
concatIndices(int[] indices)
Wrapped instances must combine their nesting indices with given indices to produce the indices of their parent.static java.lang.String
conditionalSuffix(int[] dims, int[] offsets)
abstract BaseDataType<?>
copy()
Produce a deep clone of the object.void
copyTo(BaseDataType<?> dest, int... indices)
Deep copy the content of this object into a new one, or a slice of it, possibly into a new type.protected abstract void
copyToImpl(BaseDataType<?> dest, int[] indices)
Support deep copy operations one element at a time.protected abstract void
copyToImpl(BaseDataType<?> dest, int[] toIndices, int[] fromIndices)
Support slice copy operations one element at a time.static int
CRC16(int crc, byte[] data)
Compute a CRC per CIP Volume 1 Appendix C using a pre-computed table.static int
CRC16(int crc, java.lang.String s)
static int
CRC16(int crc, java.nio.ByteBuffer source)
Compute a CRC per CIP Volume 1 Appendix C using a pre-computed table.java.lang.String
crcName()
Obtain the name of this type as used for computing structure CRCs.int
dim2linear(int[] indices)
static int
dim2linear(int[] dims, int[] indices)
static int
dim2qty(int[] dims)
static java.lang.String
dim2suffix(int[] dims)
protected java.lang.String
dimensionToString(int... indices)
double
doubleValue(int... indices)
For floating point types, upscale as needed to 64-bits.static int[]
extendIntArray(int[] indices, int index)
protected void
fillIntArray(int[] buffer, int offset, int[] partial)
Recursive helper for intArray().T
get()
abstract T
get(int[] indices)
Application-side value retrieval.DecoratedDefSeg
getCompleteDef()
int[]
getDimensions()
Return the current array shape of this data item.int[]
getMemberOffsets()
abstract DataDefinitionSeg
getNestingDef()
Return the element (not including array) type definition as a Path Segment, using the abbreviated form if a composite data type.short
getSymbolType()
Many subclasses will be data elements supported by Logix processors.byte
getTypeCode()
Retrieve the code used in tag read/write services.DataContext
getVariantContext()
When this data element has a dynamic definition or related operations, its containing type or other object can set a variant context to be used for such indirection.CipPath
getVaryingDimension()
static boolean
hasOffset(int[] dims, int[] offsets)
int[]
incIdx(int[] indices)
int[]
intArray(int... indices)
Convenience function for extracting values into a linear primitive array.int
intValue(int... indices)
For data types 32-bits wide or less, return the best available 32-bit representation.int[]
linear2dim(int subscript)
static int[]
linear2dim(int[] dims, int subscript)
java.math.BigInteger
longValue(int... indices)
For data types 64-bits wide or less, return the best available 64-bit representation.static BaseDataType<?>
makeInstance(java.lang.Class<? extends BaseDataType<?>> tclass, int... dims)
int
maxEach()
Obtain the largest number of bytes a single item can occupy in encoded form.int
minEach()
Obtain the smallest number of bytes a single item can occupy in encoded form.int
nestedBytes(boolean asStruct, int... indices)
Certain types (Omron strings and booleans) can have different encodings when packed into structures.int
nestedBytesEach()
Certain types (Omron strings and booleans) can have different encodings when packed into structures.protected int
nestedBytesImpl(int[] indices)
Certain types (Omron strings and booleans) can have different encodings when packed into structures.void
nestedPutPayload(boolean asStruct, java.nio.ByteBuffer dest, int... indices)
Variable-length types (Omron strings) can have different encodings when members of structures or arrays.protected void
nestedPutPayloadImpl(java.nio.ByteBuffer dest, int[] indices)
Variable-length types (Omron strings) can have different encodings when members of structures or arrays.void
nestedSetPayload(int startpos, boolean asStruct, java.nio.ByteBuffer source, int... indices)
Certain types (Omron strings and booleans) can have different encodings when packed into structures.protected void
nestedSetPayloadImpl(java.nio.ByteBuffer source, int[] indices)
Certain types (Omron strings and booleans) can have different encodings when packed into structures.void
putAbbrevType(java.nio.ByteBuffer dest)
Many subclasses will be data elements supported by Logix processors.void
putPayload(java.nio.ByteBuffer dest, int... indices)
All CIP datatypes must provide bytestream payloads.protected abstract void
putPayloadImpl(java.nio.ByteBuffer dest, int[] indices)
All concrete implementations must supply their per-element encoder here.static java.lang.String
range2suffix(int[] dims, int[] offsets)
static int
rawCRC16(int crc, byte b)
Compute a CRC per CIP Volume 1 Appendix C (reflected algorithm with polynomial x^16 + x^15 + x^13 + x) in bitwise fashion.abstract void
set(int[] indices, T val)
Application-side value storage.void
set(T val)
void
setDimensions(int[] newDimensions)
Update the lengths of the array dimensions to the given values.protected void
setFromTokenImpl(java.lang.String token, int[] indices)
Override this if single elements can be set from single tokens.void
setFromTokenizer(java.io.StreamTokenizer st, int... indices)
Common implementation for setting values from a potentially customized string tokenizer.protected void
setFromTokenizerImpl(java.io.StreamTokenizer st, int[] indices)
Override this if the data type is complex and will need multiple tokens per element.void
setFromTokenString(java.lang.String tokens, int... indices)
Common implementation for setting values from a token string.void
setInt(int val, int... indices)
For data types 32-bits wide or less, set the appropriate bits from a 32-bit representation.void
setLong(long val, int... indices)
For data types 64-bits wide or less, set the appropriate bits from a 64-bit representation.void
setMemberOffsets(int[] offsets)
void
setPayload(java.nio.ByteBuffer source, int... indices)
Decode a value from specification wire format to instance storage.protected abstract void
setPayloadImpl(java.nio.ByteBuffer source, int[] indices)
All concrete implementations must supply their per-element decoder here.void
setupTokenizer(java.io.StreamTokenizer st)
When setting values from string tokens, custom tokenization may be required.void
setVariantContext(DataContext variantContext)
Establish an external source for the size of the outermost dimension of this array data.void
setVariantDimension()
Convenience function to establish a varying outer dimension by payload limit.void
setVariantDimension(CipPath varyingDimension)
Establish an external source for the size of the outermost dimension of this array data.protected java.lang.String
singleToString(int[] indices)
void
sliceTo(BaseDataType<?> dest, int[] indices, int[] offsets)
Copy a slice, inner rectangle, or cube from this object into a destination.java.lang.String
structCRCString()
Logix processors don't follow CIP Volume 1 Table C-6.9 in their tag read/write routines for structures.java.lang.String
toString()
abstract BaseDataType<T>
wrap(int[] indices)
Application-side wrapper for inner dimensions.
-
-
-
Field Detail
-
sLogger
public static final org.slf4j.Logger sLogger
-
dimensions
protected int[] dimensions
-
memberOffsets
protected int[] memberOffsets
-
variantContext
protected DataContext variantContext
When dimensions are driven by external values, they are looked up when needed in a given context. The varying dimension may have an empty Path, meaning the outermost dimension will be determined by the payload limit during .setPayload(). In this case, variantContext will not be used.
-
varyingDimension
protected CipPath varyingDimension
-
-
Constructor Detail
-
BaseDataType
protected BaseDataType()
Implementing instances must set 'dimensions' in their constructor, as all other methods will reference it. A non-array instance should have a zero-length dimensions array.
-
BaseDataType
protected BaseDataType(BaseDataType<?> data, int[] indices)
Constructor for wrapped or derived instances. This instance will have dimensions and possibly memberOffsets for the indices *not* specified.- Parameters:
data
- The parent data instance.indices
- The indices into the parent array that are the root of this instance, if an array.
-
-
Method Detail
-
rawCRC16
public static int rawCRC16(int crc, byte b)
Compute a CRC per CIP Volume 1 Appendix C (reflected algorithm with polynomial x^16 + x^15 + x^13 + x) in bitwise fashion. Used to populate the optimized table.- Parameters:
crc
- Zero to start, or previous return value.b
- Byte value to process.- Returns:
- Result, or intermediate value for further calls.
-
CRC16
public static int CRC16(int crc, byte[] data)
Compute a CRC per CIP Volume 1 Appendix C using a pre-computed table.- Parameters:
crc
- Zero to start, or previous return value.data
- Byte values to process.- Returns:
- Result, or intermediate value for further calls.
-
CRC16
public static int CRC16(int crc, java.nio.ByteBuffer source)
Compute a CRC per CIP Volume 1 Appendix C using a pre-computed table.- Parameters:
crc
- Zero to start, or previous return value.source
- Byte values to process from a ByteBuffer.- Returns:
- Result, or intermediate value for further calls.
-
CRC16
public static int CRC16(int crc, java.lang.String s)
-
extendIntArray
public static int[] extendIntArray(int[] indices, int index)
-
makeInstance
public static BaseDataType<?> makeInstance(java.lang.Class<? extends BaseDataType<?>> tclass, int... dims)
-
dim2suffix
public static java.lang.String dim2suffix(int[] dims)
-
range2suffix
public static java.lang.String range2suffix(int[] dims, int[] offsets)
-
hasOffset
public static boolean hasOffset(int[] dims, int[] offsets)
-
conditionalSuffix
public static java.lang.String conditionalSuffix(int[] dims, int[] offsets)
-
dim2qty
public static int dim2qty(int[] dims)
-
dim2linear
public static int dim2linear(int[] dims, int[] indices)
-
linear2dim
public static int[] linear2dim(int[] dims, int subscript)
-
concatIndices
protected int[] concatIndices(int[] indices)
Wrapped instances must combine their nesting indices with given indices to produce the indices of their parent.- Parameters:
indices
- Given indices for an instance method.- Returns:
- Concatenated indices for the method on the parent.
-
getTypeCode
public byte getTypeCode()
Retrieve the code used in tag read/write services. Will be 0xa0 for abbreviated structures, which then need to use a length byte and structure handle.- Returns:
- This data's USINT tag type code
-
getNestingDef
public abstract DataDefinitionSeg getNestingDef()
Return the element (not including array) type definition as a Path Segment, using the abbreviated form if a composite data type.
-
getCompleteDef
public DecoratedDefSeg getCompleteDef()
-
crcName
public java.lang.String crcName()
Obtain the name of this type as used for computing structure CRCs. Can be different from the name(s) used by the CipPath parser.- Returns:
-
getDimensions
public int[] getDimensions()
Return the current array shape of this data item. If not an array, the return will have zero length.- Returns:
- Current array dimensions as an array of integers, outermost first.
-
getMemberOffsets
public int[] getMemberOffsets()
-
getVaryingDimension
public CipPath getVaryingDimension()
-
setVariantDimension
public void setVariantDimension()
Convenience function to establish a varying outer dimension by payload limit. This is only applied when .setPayload() is called at the outermost level.
-
setVariantDimension
public void setVariantDimension(CipPath varyingDimension)
Establish an external source for the size of the outermost dimension of this array data. It will only be applied when .setPayload() is called at the outermost level. The caller is responsible for any other use, including setting the creation size of the dimension.- Parameters:
varyingDimension
- The path to the integer data element. It can point at any datatype that implements the .intValue() method.
-
getVariantContext
public DataContext getVariantContext()
When this data element has a dynamic definition or related operations, its containing type or other object can set a variant context to be used for such indirection.- Returns:
-
setVariantContext
public void setVariantContext(DataContext variantContext)
Establish an external source for the size of the outermost dimension of this array data. It will only be applied when .setPayload() or .setFromTokenizer() is called at the outermost level. The caller is responsible for any other use, including setting the creation size of the dimension.- Parameters:
variantContext
- The environment in which to look up the varying dimension path. Typically the container of this array data object itself.
-
checkDimensions
protected boolean checkDimensions(int[] newDimensions)
Helper for use in setDimensions() implementations. Returns true when dimensions match previous dimensions, and no change is required. Also verifies that the number of dimensions is not changing, and that inner dimensions, if any, are not changing.- Parameters:
newDimensions
- The desired dimensions passed to setDimensions.- Returns:
- True if setDimensions() may exit early.
-
setDimensions
public void setDimensions(int[] newDimensions)
Update the lengths of the array dimensions to the given values. The number of subscripts must match the current number of subscripts. The operation must be data-preserving.This implementation handles pure Object storage types. Anything else must override.
- Parameters:
newDimensions
-
-
setMemberOffsets
public void setMemberOffsets(int[] offsets)
-
browseInner
public java.util.List<PathSegment> browseInner()
Arrays and complex data types are traversed with path following segments in theDataResolver
class. This abstract base type method enumerates arrays and bits of integral types. It delegates tobrowseInnerImpl()
otherwise.- Returns:
- A list of currently valid path selector segments.
-
browseInnerImpl
public java.util.List<PathSegment> browseInnerImpl()
Complex types that have nested data understood by the DataResolver must enumerate the path segments that are appropriate for the current instance's content. This is typically static for structure members, but dynamic for international string languages.- Returns:
- A list of currently valid path selector segments.
-
intValue
public int intValue(int... indices)
For data types 32-bits wide or less, return the best available 32-bit representation. If the subscripts are incomplete, return the element with the remaining subscripts set to zero.- Parameters:
indices
- Array subscripts.- Returns:
-
fillIntArray
protected void fillIntArray(int[] buffer, int offset, int[] partial)
Recursive helper for intArray().- Parameters:
buffer
-offset
-partial
-
-
intArray
public int[] intArray(int... indices)
Convenience function for extracting values into a linear primitive array. Returns all elements or a slice depending on the number of indices provided.- Parameters:
indices
-- Returns:
-
setInt
public void setInt(int val, int... indices)
For data types 32-bits wide or less, set the appropriate bits from a 32-bit representation. If the subscripts are incomplete, set the element with the remaining subscripts set to zero.- Parameters:
val
- New value, truncated to 8 or 16 bits if needed.indices
- Array subscripts.
-
longValue
public java.math.BigInteger longValue(int... indices)
For data types 64-bits wide or less, return the best available 64-bit representation. If the subscripts are incomplete, return the element with the remaining subscripts set to zero.- Parameters:
indices
- Array subscripts.- Returns:
-
doubleValue
public double doubleValue(int... indices)
For floating point types, upscale as needed to 64-bits. Otherwise convert from the corresponding integer type.- Parameters:
indices
-- Returns:
-
setLong
public void setLong(long val, int... indices)
For data types 64-bits wide or less, set the appropriate bits from a 64-bit representation. If the subscripts are incomplete, set the element with the remaining subscripts set to zero.- Parameters:
val
- New value, truncated to 8, 16, or 32 bits if needed.indices
- Array subscripts.
-
dim2linear
public int dim2linear(int[] indices)
-
linear2dim
public int[] linear2dim(int subscript)
-
incIdx
public int[] incIdx(int[] indices)
-
get
public T get()
-
get
public abstract T get(int[] indices)
Application-side value retrieval. Subclasses must implement this function to retrieve elements of the storage array in the application data type.- Parameters:
indices
- Array subscripts. Missing subscripts not allowed.- Returns:
-
set
public void set(T val)
-
set
public abstract void set(int[] indices, T val)
Application-side value storage. Subclasses must implement this function to store one value or complex element into the storage array.- Parameters:
indices
- Array subscripts. Missing subscripts not allowed.val
-
-
wrap
public abstract BaseDataType<T> wrap(int[] indices)
Application-side wrapper for inner dimensions. Implementations must update memberOffsets if not not using the protected constructor.- Parameters:
indices
- Array subscripts. Missing subscripts are allowed.
-
bytesEach
public abstract int bytesEach()
Obtain the bytes-per-element of this object's payload encoding. Objects with variable length encodings must return zero and implement the bytesImpl(), minEach(), maxEach(), and alignment() methods instead.- Returns:
- encoded bytes per element
-
nestedBytesEach
public int nestedBytesEach()
Certain types (Omron strings and booleans) can have different encodings when packed into structures. CipStruct will use this method instead ofbytesEach()
when computing its own bytesEach.The supplied
nestedBytes(boolean, int...)
implementation will also call this version for arrays.- Returns:
-
minEach
public int minEach()
Obtain the smallest number of bytes a single item can occupy in encoded form. Used in structures to compute min/max offset and total structure size range.Types where bytesEach is a constant should override this to return that constant too, as a performance optimization.
- Returns:
-
maxEach
public int maxEach()
Obtain the largest number of bytes a single item can occupy in encoded form. Used in structures to compute min/max offset and total structure size range.Types where bytesEach is a constant should override this to return that constant too, as a performance optimization.
- Returns:
-
alignment
public int alignment()
Obtain the natural alignment of this data type. Used in structures to compute min/max offset and alignment.Types where bytesEach is a constant should override this to return a suitable constant too, as a performance optimization.
- Returns:
-
bytes
public int bytes(int... indices)
Retrieve the entire bytes size of this object's payload, or a slice of it.- Returns:
-
nestedBytes
public int nestedBytes(boolean asStruct, int... indices)
Certain types (Omron strings and booleans) can have different encodings when packed into structures. CipStruct will always call this method with asStruct set true so that such types can report the correct size.- Returns:
-
bytesImpl
protected abstract int bytesImpl(int[] indices)
Retrieve the bytes payload size of a single array element (or sole element). Objects with fixed element sizes may simply return bytesEach() here.- Parameters:
indices
-- Returns:
-
nestedBytesImpl
protected int nestedBytesImpl(int[] indices)
Certain types (Omron strings and booleans) can have different encodings when packed into structures. Such types must override this method to substitute the correct encoding length for that case.- Parameters:
indices
-- Returns:
-
setPayload
public void setPayload(java.nio.ByteBuffer source, int... indices)
Decode a value from specification wire format to instance storage.- Parameters:
source
-indices
-
-
nestedSetPayload
public void nestedSetPayload(int startpos, boolean asStruct, java.nio.ByteBuffer source, int... indices)
Certain types (Omron strings and booleans) can have different encodings when packed into structures. CipStruct will always call this method with asStruct set true so that such types can perform the correct decoding.- Parameters:
asStruct
- True to invoke nestedSetPayloadImpl for each member.source
-indices
-
-
setPayloadImpl
protected abstract void setPayloadImpl(java.nio.ByteBuffer source, int[] indices)
All concrete implementations must supply their per-element decoder here.- Parameters:
source
-indices
-
-
nestedSetPayloadImpl
protected void nestedSetPayloadImpl(java.nio.ByteBuffer source, int[] indices)
Certain types (Omron strings and booleans) can have different encodings when packed into structures. Such types must override this method to perform the correct decoding for that case.- Parameters:
source
-indices
-
-
setupTokenizer
public void setupTokenizer(java.io.StreamTokenizer st)
When setting values from string tokens, custom tokenization may be required. The default tokenization is broken out here to form the basis of custom tokenizers.- Parameters:
st
-
-
setFromTokenString
public void setFromTokenString(java.lang.String tokens, int... indices)
Common implementation for setting values from a token string.- Parameters:
tokens
-indices
-
-
setFromTokenizer
public void setFromTokenizer(java.io.StreamTokenizer st, int... indices)
Common implementation for setting values from a potentially customized string tokenizer.- Parameters:
st
-indices
-
-
setFromTokenizerImpl
protected void setFromTokenizerImpl(java.io.StreamTokenizer st, int[] indices) throws java.io.IOException
Override this if the data type is complex and will need multiple tokens per element.- Parameters:
st
-indices
-- Throws:
java.io.IOException
-
setFromTokenImpl
protected void setFromTokenImpl(java.lang.String token, int[] indices)
Override this if single elements can be set from single tokens. The default decodes as Long and uses setLong().- Parameters:
token
- The single token obtained from the tokenizer for this one element.indices
- The complete set of subscripts
-
putPayload
public void putPayload(java.nio.ByteBuffer dest, int... indices)
All CIP datatypes must provide bytestream payloads. When an array, and fewer indices are supplied than dimensions, multiple consecutive payloads are to be written from the array into the destination buffer.- Parameters:
dest
-indices
-
-
nestedPutPayload
public void nestedPutPayload(boolean asStruct, java.nio.ByteBuffer dest, int... indices)
Variable-length types (Omron strings) can have different encodings when members of structures or arrays. CipStruct will always call this method with asStruct set true so that such types can perform the correct encoding.- Parameters:
asStruct
- True to invoke structPutPayloadImpl for each member.dest
-indices
-
-
putPayloadImpl
protected abstract void putPayloadImpl(java.nio.ByteBuffer dest, int[] indices)
All concrete implementations must supply their per-element encoder here.- Parameters:
dest
-indices
-
-
nestedPutPayloadImpl
protected void nestedPutPayloadImpl(java.nio.ByteBuffer dest, int[] indices)
Variable-length types (Omron strings) can have different encodings when members of structures or arrays. Such types must override this method to perform the correct encoding for that case.- Parameters:
dest
-indices
-
-
putAbbrevType
public void putAbbrevType(java.nio.ByteBuffer dest)
Many subclasses will be data elements supported by Logix processors. The LogixTagType interface requires this routine, which is identical for all types with a compact representation.- Parameters:
dest
-
-
chkAbbrevType
public void chkAbbrevType(java.nio.ByteBuffer source)
-
getSymbolType
public short getSymbolType()
Many subclasses will be data elements supported by Logix processors. The LogixTagType interface requires this routine, which is identical for all types with a one-byte compact representation.
-
structCRCString
public java.lang.String structCRCString()
Logix processors don't follow CIP Volume 1 Table C-6.9 in their tag read/write routines for structures. Instead, they run the CRC over comma-separated ASCII type strings that make up the structure. This is referred to in the Logix Data Access Programming Manual as the "Structure Handle".- Returns:
-
copy
public abstract BaseDataType<?> copy()
Produce a deep clone of the object.
-
copyTo
public void copyTo(BaseDataType<?> dest, int... indices)
Deep copy the content of this object into a new one, or a slice of it, possibly into a new type. The destination must have the same number of dimensions, but may have different size dimensions. Only elements that exist in both source and destination will be copied.
-
copyToImpl
protected abstract void copyToImpl(BaseDataType<?> dest, int[] indices)
Support deep copy operations one element at a time.- Parameters:
indices
-
-
sliceTo
public void sliceTo(BaseDataType<?> dest, int[] indices, int[] offsets)
Copy a slice, inner rectangle, or cube from this object into a destination. The offsets are applied to the source's trailing dimensions and correspond to the zero indices in the destination.The destination may have fewer dimensions than the source, given the supplied indices as a prefix for the source. The subscripts of the concatenated indices+offsets is the beginning of the copy source.
The destination must have the same number of dimensions as the number of offsets supplied.
- Parameters:
dest
- A destination of a compatible type as this object.indices
- The fixed subscripts for the part of the source to copy.offsets
- The starting values for the varying subscripts for the part of the source to copy.
-
copyToImpl
protected abstract void copyToImpl(BaseDataType<?> dest, int[] toIndices, int[] fromIndices)
Support slice copy operations one element at a time.- Parameters:
dest
-toIndices
-fromIndices
-
-
singleToString
protected java.lang.String singleToString(int[] indices)
-
dimensionToString
protected java.lang.String dimensionToString(int... indices)
-
toString
public java.lang.String toString()
- Overrides:
toString
in classjava.lang.Object
-
-