public class memptr extends BinaryData
MEMPTR
data type
which is backed by a native platform memory buffer (instead of being allocated on the Java
heap). The contents of the buffer are mutable. All Progress 4GL language features are
supported up to the 10.2B level.
Format string related processing is handled in method toString(String)
.
The following is the mapping of Progress language features to the corresponding feature in this class:
Progress Function Java Method ----------------------------- ----------------------- get-byte-ordergetByteOrder()
get-pointer-valuegetPointerValue()
get-sizeBinaryData.length(com.goldencode.p2j.util.BinaryData)
Progress Language Statement Java Method ----------------------------- ----------------------- set-byte-ordersetByteOrder(int)
set-pointer-valuesetPointerValue(com.goldencode.p2j.util.NumberType)
set-sizesetLength(long)
All of the above features are specific to the MEMPTR
type (they do not work for
RAW
variables in the 4GL, such attempted usage will cause a compiler error). All
other features are shared and are implemented in the common base class.
Modifier and Type | Class and Description |
---|---|
private static class |
memptr.WorkArea
Container for context-local data.
|
BinaryData.RangeCheck
Modifier and Type | Field and Description |
---|---|
private long |
addr
The actual platform-specific pointer to our memory region (on the client).
|
static int |
BIG_ENDIAN
Operations should use big endian byte order.
|
private int |
byteOrder
The byte order used for this instance.
|
private static ContextLocal<memptr.WorkArea> |
ctxt
Stores context local instances of the remote memory manager proxy.
|
static int |
HOST_BYTE_ORDER
Operations should use the native byte order on the current machine.
|
static int |
LITTLE_ENDIAN
Operations should use little endian byte order.
|
private static java.util.logging.Logger |
LOG
Logger
|
static int |
LOWER_BOUND
Smallest value accepted in SET-SIZE() without generating an error.
|
static int |
NO_BYTE_ORDER
No byte order has been explicitly requested.
|
private long |
size
Stores the size that was last set for querying and boundary checking.
|
static int |
UPPER_BOUND
Largest value accepted in SET-SIZE() without generating an error.
|
private memptr.WorkArea |
workArea
The working area where this instance was created.
|
unknown
Constructor and Description |
---|
memptr()
Default constructor, creates an instance that represents an uninitialized byte array (a
null array). |
memptr(BaseDataType value)
This is a special c'tor which should be used only when converting the
value returned by a function or method with polymorphic return type into the
expected type (i.e.
|
memptr(byte[] value)
Constructs an instance after copying the parameter's data into the internal representation
of this class.
|
memptr(memptr value)
Constructs an instance after copying the parameter's data into the internal representation
of this class.
|
Modifier and Type | Method and Description |
---|---|
protected byte[] |
asByteArray()
Return the entire contents of the current buffer as an array.
|
int |
compareTo(java.lang.Object obj)
Compares this instance with the specified instance and returns a -1 if this instance is less
than the specified, 0 if the two instances are equal and 1 if this instance is greater than
the specified instance.
|
protected static int |
compiledWordSize()
Returns the word size (the size of a pointer) for the native code as compiled.
|
protected void |
copyByteRange(memptr data,
long pos,
long len)
Copy the specified number of bytes from the source instance into the current instance at
the given location.
|
private void |
copyPointer(memptr m)
Copy the pointer details from the specified instance.
|
protected void |
deallocate()
Release any resources associated with the instance.
|
BaseDataType |
duplicate()
Does the same as standard
clone() method but returns an instance of
BaseDataType and doesn't throw the CloneNotSupportedException . |
protected void |
extendBytes(long len)
Helper to create a new byte array with the same contents as the given byte array and the
specified length.
|
protected long |
findNextNull(long pos)
Returns the next index position into the array which is the
null byte, starting at a
given index position. |
integer |
getByteOrder()
Reports the byte order mode configured in this instance.
|
int64 |
getPointerValue()
Method implementation of the GET-POINTER-VALUE 4GL built-in function which returns a 64-bit
integer value representing the pointer used by the instance.
|
BaseDataType |
instantiateUnknown()
Creates a new instance of the same type that is
unknown . |
protected long |
internalLength()
The actual size of the buffer (in bytes).
|
protected boolean |
isAutoExtend()
Determines if the array of binary data stored in an instance of this class must be
automatically extended in length when operations write past the current length.
|
protected boolean |
isLengthLimited()
Determines if the array of binary data stored in an instance of this class must be limited
in length.
|
private boolean |
isLittleEndian()
Report if the effective byte ordering mode is little endian.
|
protected static boolean |
isLittleEndianPlatform(memptr.WorkArea workArea)
Report if the byte ordering mode of the platform is little endian.
|
protected boolean |
isUndoable()
Check if this instance is undoable.
|
boolean |
isUninitialized()
Reports if this instance represents an uninitialized buffer.
|
protected long |
lengthLimit()
Determines the maximum length of the array of binary data stored in an instance of this
class.
|
private memptr.WorkArea |
locate()
Resolve the context-local
workArea variable (if not yet resolved) and return it. |
protected byte |
readByte(long pos)
Read the byte at the given location.
|
protected byte[] |
readByteRange(long pos,
long len,
boolean endian)
Read the bytes at the given location.
|
void |
readExternal(java.io.ObjectInput in)
Replacement for the default object reading method.
|
protected void |
replaceContents(byte[] value)
Replace the entire contents of the current buffer with the given array.
|
void |
setByteOrder(int order)
Defines the byte ordering scheme to use when reading/writing certain data types into the
memory buffer.
|
void |
setByteOrder(NumberType order)
Defines the byte ordering scheme to use when reading/writing certain data types into the
memory buffer.
|
BinaryData |
setLength(long len)
Sets the array to a given length.
|
memptr |
setPointerValue(long ptr)
Sets the binary data to point to a memory address.
|
memptr |
setPointerValue(NumberType ptr)
Sets the binary data to point to a memory address.
|
java.lang.String |
toString()
Creates a string representation of the instance data, since a memptr represents a 'pointer'
it doesn't have a real string representation.
|
java.lang.String |
toString(java.lang.String fmt)
Creates a string representation of the instance data using the given format string, since a
memptr represents a 'pointer' it doesn't have a real string representation and the format
string is meaningless.
|
java.lang.String |
toStringExport()
Creates a string representation of the instance data using the 'export' format.
|
java.lang.String |
toStringMessage()
Creates a string representation of the instance data in a form that is compatible with the
MESSAGE language statement. |
protected long |
visibleLength()
The the length of the buffer as reported to P4GL application.
|
protected void |
writeByte(byte val,
long pos)
Write the byte into the given location.
|
protected void |
writeByteRange(byte[] data,
long pos,
boolean endian)
Write the bytes at the given location.
|
void |
writeExternal(java.io.ObjectOutput out)
Replacement for the default object writing method.
|
assign, assign, assign, assign, clearUnknown, defaultFormatString, genLimitedLengthError, getByte, getByte, getByteArray, getBytes, getBytes, getBytes, getBytes, getDouble, getDouble, getFloat, getFloat, getInt64, getInt64, getLong, getLong, getShort, getShort, getString, getString, getString, getString, getString, getString, getUnprocessedDouble, getUnsignedLong, getUnsignedLong, getUnsignedShort, getUnsignedShort, hashCode, isUnknown, length, length, lengthOf, reverseBytes, setByte, setByte, setByte, setByte, setBytes, setBytes, setDouble, setDouble, setDouble, setDouble, setFloat, setFloat, setFloat, setFloat, setInt64, setInt64, setInt64, setInt64, setLength, setLong, setLong, setLong, setLong, setShort, setShort, setShort, setShort, setString, setString, setString, setString, setString, setString, setString, setString, setString, setString, setString, setString, setUnknown, setUnsignedLong, setUnsignedLong, setUnsignedLong, setUnsignedLong, setUnsignedShort, setUnsignedShort, setUnsignedShort, setUnsignedShort
calcFormatLength, deepCopy, elementsOfType, equals, formatLength, generateDefault, generateUnknown, getTypeName, incompatibleTypesOnConversion, initializeDefaultExtent, instantiateDefault, instantiateDefaultExtent, isUnknownValue, maximum, minimum, notUnknownValue, sameType
changed, checkUndoable, checkUndoable, checkUndoable, getTransLevel, isGlobal, markUndoable, popBlock, rollback, setGlobal
private static final java.util.logging.Logger LOG
public static final int NO_BYTE_ORDER
public static final int HOST_BYTE_ORDER
public static final int BIG_ENDIAN
public static final int LITTLE_ENDIAN
public static final int LOWER_BOUND
public static final int UPPER_BOUND
private static final ContextLocal<memptr.WorkArea> ctxt
private memptr.WorkArea workArea
locate()
as it can't be initialized by the c'tor - when
transported via the network, the Reader thread will not be able to access the context.private int byteOrder
private long addr
private long size
public memptr()
null
array).public memptr(BaseDataType value)
BinaryData.assign(BaseDataType)
).value
- The value to be used for this instance.public memptr(memptr value)
If the parameter is unknown
, this instance will be set to unknown
.
value
- The value to be used for this instance.public memptr(byte[] value)
If the parameter is null
, the instance will be unknown
.
value
- The value to be used for this instance.public int compareTo(java.lang.Object obj)
Comparable
interface.
The algorithm will fail to give meaningful results in the case where one tries to sort against other objects that do not represent compatible values.
compareTo
in interface java.lang.Comparable
compareTo
in class BinaryData
obj
- The instance to compare against.obj
.public BaseDataType duplicate()
clone()
method but returns an instance of
BaseDataType
and doesn't throw the CloneNotSupportedException
.duplicate
in class BaseDataType
public BaseDataType instantiateUnknown()
unknown
.instantiateUnknown
in class BaseDataType
unknown
.public int64 getPointerValue()
unknown
, the pointer will be unknown
. If
uninitialized, this will return 0.public memptr setPointerValue(NumberType ptr)
If the instance is unknown
, then this call silently fails. It does NOT change the
pointer value, the instance will still be unknown
. This is how the 4GL does it.
ptr
- The 64-bit value representing the pointer to the memory address. This may be
any value (negative, 0 or a positive number). Since the 4GL has no unsigned
64-bit data type, it is necessary negative numbers be supported since memory
addresses are typically unsigned values. Even though most systems do not
allocate valid memory at address 0 (so that 0 can be used as a well known
invalid memory address), the 4GL does allow 0 to be used (perhaps it is needed
on some systems). If this value is unknown
, the method will silently
return with no change to the pointer value. This is how the 4GL does it.public memptr setPointerValue(long ptr)
If the instance is unknown
, then this call silently fails. It does NOT change the
pointer value, the instance will still be unknown
. This is how the 4GL does it.
ptr
- The 64-bit value representing the pointer to the memory address. This may be
any value (negative, 0 or a positive number). Since the 4GL has no unsigned
64-bit data type, it is necessary negative numbers be supported since memory
addresses are typically unsigned values. Even though most systems do not
allocate valid memory at address 0 (so that 0 can be used as a well known
invalid memory address), the 4GL does allow 0 to be used (perhaps it is needed
on some systems).public integer getByteOrder()
setByteOrder(int)
is called. Since setByteOrder
can only ever be called with 3 values, those
are the only possible values that can be returned from here. The only exception to this
is that when the instance is unknown
, then unknown
will be
returned, no matter what has been previously configured.
The following are the possible return values:
4GL Constant Java Constant Value ------------------ ------------------ --------- n/a NO_BYTE_ORDER 0 HOST-BYTE-ORDER HOST_BYTE_ORDER 1 BIG-ENDIAN BIG_ENDIAN 2 LITTLE-ENDIAN LITTLE_ENDIAN 3
The fact that Progress returns 0 by default allows one can tell when this value has been
explicitly configured, since it is never possible to set it back to 0 via
setByteOrder
. When set to 0 or to HOST_BYTE_ORDER, the result is the same.
The native byte ordering of the current platform will be used.
This value is interesting in another way: it does not change when an instance is
de-allocated, re-allocated, set to unknown
or assigned. The configuration
value stays with the instance across all these events and thus it is not really
associated with a specific memory buffer, but rather with the variable instance itself.
Don't be fooled by the fact that this returns unknown
when the instance is
unknown
. The byte order is still properly set (or defaulted) and when the
instance is no longer unknown
, that value will be returned.
public void setByteOrder(int order)
DOUBLE FLOAT INT64 LONG SHORT UNSIGNED-LONG UNSIGNED-SHORT
For each of the above listed data types, both the get and the set will honor the byte ordering. This means that the only data types that do NOT honor byte ordering are BYTE (a single byte being read or written), BYTES (a sequence of bytes) and STRING (a sequence of characters).
Any valid value set through this method is retained for the lifetime of the instance,
even when it is set to unknown
and/or de-allocated and then re-allocated.
Interestingly, the value does not get copied to the target instance during assignment,
so it is instance-specific. This is all compatible with how the 4GL works.
The following are the only possible byte order modes that can be specified:
4GL Constant Java Constant Value ------------------ ------------------ --------- HOST-BYTE-ORDER HOST_BYTE_ORDER 1 BIG-ENDIAN BIG_ENDIAN 2 LITTLE-ENDIAN LITTLE_ENDIAN 3
This method returns without any changes if the instance is unknown
.
order
- The new byte order mode.public void setByteOrder(NumberType order)
DOUBLE FLOAT INT64 LONG SHORT UNSIGNED-LONG UNSIGNED-SHORT
For each of the above listed data types, both the get and the set will honor the byte ordering. This means that the only data types that do NOT honor byte ordering are BYTE (a single byte being read or written), BYTES (a sequence of bytes) and STRING (a sequence of characters).
Any valid value set through this method is retained for the lifetime of the instance,
even when it is set to unknown
and/or de-allocated and then re-allocated.
Interestingly, the value does not get copied to the target instance during assignment,
so it is instance-specific. This is all compatible with how the 4GL works.
The following are the only possible byte order modes that can be specified:
4GL Constant Java Constant Value ------------------ ------------------ --------- HOST-BYTE-ORDER HOST_BYTE_ORDER 1 BIG-ENDIAN BIG_ENDIAN 2 LITTLE-ENDIAN LITTLE_ENDIAN 3
If the parameter is unknown
, then the instance itself will be set to
unknown
and the byte order will NOT be changed. Subsequent allocation of
a new buffer will retain the same byte order setting. This is how the 4GL does it.
This method returns without any changes if the instance is unknown
.
order
- The new byte order mode.public BinaryData setLength(long len) throws ErrorConditionException
This method will try to emulate the allocation based on the current (-ly configured) OS.
See EnvironmentOps.isUnderWindowsFamily()
:
WIN32
platform will only accept positive values when allocating a new
native memory buffer. If the buffer is already allocated and a negative value is
passed then this is a no-op;UNIX
will accept and apparently allocate abs(len)
bytes.On 32-bit Linux platforms, the 4GL "real lower bound" is -7 and not 0 as one would expect. Since this is an obscure and platform-specific nonsense behavior which is unlikely to be needed in a real application, it is not honored at this time (which leaves this code simpler).
setLength
in class BinaryData
len
- New length of the array.ErrorConditionException
public boolean isUninitialized()
unknown
is also different from being uninitialized.isUninitialized
in class BinaryData
true
if this instance is uninitialized.public java.lang.String toString()
unknown
, a
'?' will be returned, otherwise the empty string will be returned.toString
in class java.lang.Object
unknown
.public java.lang.String toString(java.lang.String fmt)
unknown
, a '?' will be returned,
otherwise the empty string will be returned.toString
in class BaseDataType
fmt
- The format string to use.unknown
.public java.lang.String toStringMessage()
MESSAGE
language statement. If the instance represents unknown
, a '?' will
be returned.
This is equivalent to toString()
.
toStringMessage
in class BaseDataType
unknown
.public java.lang.String toStringExport()
unknown
, a '?' will be returned. Any other data is directly
output into the string and no formatting or conversion of binary data is done.toStringExport
in class BaseDataType
public void readExternal(java.io.ObjectInput in) throws java.io.IOException, java.lang.ClassNotFoundException
readExternal
in interface java.io.Externalizable
readExternal
in class BinaryData
in
- The input source from which fields will be restored.java.io.IOException
- In case of I/O errors.java.lang.ClassNotFoundException
- If payload can't be instantiated.public void writeExternal(java.io.ObjectOutput out) throws java.io.IOException
writeExternal
in interface java.io.Externalizable
writeExternal
in class BinaryData
out
- The output destination to which fields will be saved.java.io.IOException
- In case of I/O errors.protected static boolean isLittleEndianPlatform(memptr.WorkArea workArea)
workArea
- The optional context to obtain endian information. If not provided, the current
context is used.true
if the platform natively uses little endian byte ordering and
false
if it uses big endian.protected static int compiledWordSize()
protected void deallocate()
deallocate
in class BinaryData
protected boolean isLengthLimited()
isLengthLimited
in class BinaryData
true
if the length must be limited.protected long lengthLimit()
lengthLimit
in class BinaryData
protected boolean isAutoExtend()
null
bytes.isAutoExtend
in class BinaryData
true
if the length must automatically extended.protected void extendBytes(long len)
This is safe to use on 0 length arrays.
extendBytes
in class BinaryData
len
- The output array length.protected void replaceContents(byte[] value)
The BinaryData.unknown
flag is also cleared, only if value
is not
null
and if the length is greater than 0.
replaceContents
in class BinaryData
value
- The new contents.protected byte[] asByteArray()
asByteArray
in class BinaryData
unknown
or has an undefined size, then null
will be returned.protected long internalLength()
internalLength
in class BinaryData
protected long visibleLength()
visibleLength
in class BinaryData
protected long findNextNull(long pos)
null
byte, starting at a
given index position.findNextNull
in class BinaryData
pos
- The 0-based index into the array at which to start searching.null
byte or the length of the
array if no null
byte exists.protected byte readByte(long pos)
readByte
in class BinaryData
pos
- The 0-based index position at which to read the byte.protected void writeByte(byte val, long pos)
writeByte
in class BinaryData
val
- The byte to write.pos
- The 0-based index position at which to read the byte.protected byte[] readByteRange(long pos, long len, boolean endian)
readByteRange
in class BinaryData
pos
- The 0-based index position at which to read the bytes.len
- The number of bytes to read.endian
- true
to force the returned data to be ordered by the endian-ness of the
instance.protected void writeByteRange(byte[] data, long pos, boolean endian)
writeByteRange
in class BinaryData
data
- The bytes to write.pos
- The 0-based index position at which to start writing the bytes.endian
- true
to honor the endian-ness of the instance. The data
array MUST be ordered in little-endian order if the endian flag is on.protected boolean isUndoable()
memptr
case, these instances can never be
undoable.isUndoable
in class LazyUndoable
false
protected void copyByteRange(memptr data, long pos, long len)
This method is implemented completely on the client side to avoid multiple (costly) round trips.
data
- The source of data to copy.pos
- The 0-based index position in the destination at which to write the bytes.len
- The number of bytes to write.private boolean isLittleEndian()
true
if the instance should use little endian byte ordering and
false
if the instance should use big endian.private void copyPointer(memptr m)
m
- The memptr
instance which needs to be duplicated.private memptr.WorkArea locate()
workArea
variable (if not yet resolved) and return it.workArea
.