# 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);
    }