MemoryManager.java

/*
** Module   : MemoryManager.java
** Abstract : low-level memory buffer functions backed by JNI
**
** Copyright (c) 2013-2024, Golden Code Development Corporation.
**
** -#- -I- --Date-- --------------------------------Description---------------------------------
** 001 GES 20130429 First version. The idea is to provide the minimum set of low level memory
**                  functions to enable the full set of memptr features to be implemented in
**                  pure Java. For security purposes, this class is intentionally package
**                  private.
** 002 EVL 20140117 The native library call is performing now in dedicated place and only once.
**                  See the ClientCore class.
** 003 GES 20180322 Added word size native function.
** 004 GBB 20240826 Moving MemoryDaemon to osresource package.
*/
 
/*
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as
** published by the Free Software Foundation, either version 3 of the
** License, or (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU Affero General Public License for more details.
**
** You may find a copy of the GNU Affero GPL version 3 at the following
** location: https://www.gnu.org/licenses/agpl-3.0.en.html
** 
** Additional terms under GNU Affero GPL version 3 section 7:
** 
**   Under Section 7 of the GNU Affero GPL version 3, the following additional
**   terms apply to the works covered under the License.  These additional terms
**   are non-permissive additional terms allowed under Section 7 of the GNU
**   Affero GPL version 3 and may not be removed by you.
** 
**   0. Attribution Requirement.
** 
**     You must preserve all legal notices or author attributions in the covered
**     work or Appropriate Legal Notices displayed by works containing the covered
**     work.  You may not remove from the covered work any author or developer
**     credit already included within the covered work.
** 
**   1. No License To Use Trademarks.
** 
**     This license does not grant any license or rights to use the trademarks
**     Golden Code, FWD, any Golden Code or FWD logo, or any other trademarks
**     of Golden Code Development Corporation. You are not authorized to use the
**     name Golden Code, FWD, or the names of any author or contributor, for
**     publicity purposes without written authorization.
** 
**   2. No Misrepresentation of Affiliation.
** 
**     You may not represent yourself as Golden Code Development Corporation or FWD.
** 
**     You may not represent yourself for publicity purposes as associated with
**     Golden Code Development Corporation, FWD, or any author or contributor to
**     the covered work, without written authorization.
** 
**   3. No Misrepresentation of Source or Origin.
** 
**     You may not represent the covered work as solely your work.  All modified
**     versions of the covered work must be marked in a reasonable way to make it
**     clear that the modified work is not originating from Golden Code Development
**     Corporation or FWD.  All modified versions must contain the notices of
**     attribution required in this license.
*/

package com.goldencode.p2j.util;

/**
 * Provides access to buffers implemented by platform-specific memory buffers instead of the
 * Java heap.  The backing functions for this class are implemented via JNI.  No real error
 * handling or checking is implemented in these functions.  It is expected that the caller
 * will handle all such boundary checking and safety code.
 */
public class MemoryManager
{
   /**
    * Reports on the native byte-ordering of the platform on which this library is
    * running. 
    *
    * @return   <code>true</code> if the platform uses little-endian byte-ordering,
    *           <code>false</code> if the platform is big-endian.
    */
   public static native boolean isLittleEndian();

   /**
    * Returns the word size (the size of a pointer) for the native code as compiled. This may be
    * different than the word size of the operating system in the case where 32-bit code is run
    * on a 64-bit system.
    *
    * @return   This value will be either 32 or 64 depending on how the native library was
    *           compiled.
    */
   public static native int compiledWordSize();

   /**
    * Allocate the given number of bytes as a new memory block and return the 64-bit address. All
    * bytes in the memory region will be initialized to 0x00. 
    * <p>
    * To duplicate the permissiveness of the 4GL memptr allocation (where certain operations
    * often can read or write past the end of the allocated buffer without an access violation),
    * the buffer allocated by this function will always be 16 bytes larger than the requested
    * size. 
    *
    * @param    len
    *           The size in bytes of the memory region to allocate.
    *
    * @return   The address of the allocated memory region or 0 if memory could not be allocated.
    */
   public static native long allocate(long len);
   
   /**
    * De-allocate the memory block at the given 64-bit address.  Memory in this region MUST NOT
    * be accessed after this call. 
    *
    * @param    addr
    *           The 64-bit pointer to a memory region previously allocated using this module.
    *           DO NOT pass in an invalid pointer.  DO NOT deallocate the same pointer more than
    *           once.
    */
   public static native void deallocate(long addr);
   
   /**
    * Returns the next index position into the array which is the <code>null</code> byte, starting
    * at the given index position.
    *
    * @param    addr
    *           The 64-bit pointer to a memory region previously allocated using this module.
    *           DO NOT pass in an invalid pointer.
    * @param    idx
    *           The index position at which to start the search.
    * @param    size
    *           The length of the buffer. If the search reaches this byte without finding a
    *           null byte, then this value will be returned. If this is given as -1, then the
    *           caller has no size information and we operate in unsafe mode.  In this mode
    *           the code will read until it finds a <code>null</code> or gets an access
    *           violation.  This is how the 4GL does it too.
    *
    * @return   The index of the next byte position which contains the <code>null</code> byte or
    *           the length of the array if no <code>null</code> byte is contained.
    */
   public static native long findNextNull(long addr, long idx, long size);
   
   /**
    * Read the specified range of contents from the memory block at the given 64-bit address.
    *
    * @param    addr
    *           The 64-bit pointer to a memory region previously allocated using this module.
    *           DO NOT pass in an invalid pointer.
    * @param    offset
    *           The 0-based index position from the beginning of the buffer, from which to start
    *           reading.
    * @param    len
    *           The number of bytes to read. Must be greater than 0 and must NOT extend past the
    *           end of the buffer.
    *
    * @return   The range of bytes read or <code>null</code> if there is any problem allocating
    *           the array.
    */
   public static native byte[] read(long addr, long offset, long len);
   
   /**
    * Write the specified contents to the memory block at the given 64-bit address plus offset.
    *
    * @param    addr
    *           The 64-bit pointer to a memory region previously allocated using this module.
    *           DO NOT pass in an invalid pointer.
    * @param    offset
    *           The 0-based index position from the beginning of the buffer, at which to start
    *           writing.
    * @param    data
    *           The bytes to write.  The entire contents of the array will be written. The length
    *           of the array must not be bigger than the number of bytes between the offset and
    *           the end of the buffer.
    */
   public static native void write(long addr, long offset, byte[] data);
   
   /**
    * Copy the specified range of contents from the source memory block to the destination memory
    * block.
    *
    * @param    source
    *           The 64-bit pointer to a memory region previously allocated using this module.
    *           DO NOT pass in an invalid pointer.
    * @param    dest
    *           The 64-bit pointer to a memory region previously allocated using this module.
    *           DO NOT pass in an invalid pointer.
    * @param    offset
    *           The 0-based index position from the beginning of the buffer, at which to start
    *           writing.
    * @param    len
    *           The number of bytes to write. Must be greater than 0 and must NOT extend past the
    *           end of the destination buffer.
    */
   public static native void copy(long source, long dest, long offset, long len); 
}