1 /*
  2  *  Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
  3  *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  *  This code is free software; you can redistribute it and/or modify it
  6  *  under the terms of the GNU General Public License version 2 only, as
  7  *  published by the Free Software Foundation.  Oracle designates this
  8  *  particular file as subject to the "Classpath" exception as provided
  9  *  by Oracle in the LICENSE file that accompanied this code.
 10  *
 11  *  This code is distributed in the hope that it will be useful, but WITHOUT
 12  *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  *  version 2 for more details (a copy is included in the LICENSE file that
 15  *  accompanied this code).
 16  *
 17  *  You should have received a copy of the GNU General Public License version
 18  *  2 along with this work; if not, write to the Free Software Foundation,
 19  *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  *  or visit www.oracle.com if you need additional information or have any
 23  *  questions.
 24  */
 25 package jdk.internal.foreign;
 26 
 27 import java.lang.foreign.MemoryLayout;
 28 import java.lang.foreign.MemorySegment;
 29 import java.lang.foreign.ValueLayout;
 30 import java.nio.Buffer;
 31 import java.util.function.BiFunction;
 32 import java.util.stream.Stream;
 33 
 34 import static java.util.Objects.requireNonNull;
 35 import static jdk.internal.foreign.MemoryInspectionUtil.*;
 36 
 37 /**
 38  * Class that supports inspection of MemorySegments through MemoryLayouts.
 39  * <p>
 40  * Memory abstractions such as ByteBuffers and byte arrays can be inspected via wrapping methods
 41  * such as {@link MemorySegment#ofArray(byte[])} and {@link MemorySegment#ofBuffer(Buffer)}.
 42  *
 43  * @since 20
 44  */
 45 public final class MemoryInspection {
 46 
 47     // Suppresses default constructor, ensuring non-instantiability.
 48     private MemoryInspection() {
 49     }
 50 
 51     /**
 52      * Returns a human-readable view of the provided {@linkplain MemorySegment memory} viewed
 53      * through the provided {@linkplain MemoryLayout layout} using the provided {@code renderer}.
 54      * <p>
 55      * The exact format of the returned view is unspecified and should not
 56      * be acted upon programmatically.
 57      * <p>
 58      * As an example, a MemorySegment viewed though the following memory layout
 59      * {@snippet lang = java:
 60      * var layout = MemoryLayout.structLayout(
 61      *         ValueLayout.JAVA_INT.withName("x"),
 62      *         ValueLayout.JAVA_INT.withName("y")
 63      * ).withName("Point");
 64      *
 65      * MemoryInspection.inspect(segment, layout, ValueLayoutRenderer.standard())
 66      *     .forEach(System.out::println);
 67      *
 68      *}
 69      * might be rendered to something like this:
 70      * {@snippet lang = text:
 71      * Point {
 72      *   x=1,
 73      *   y=2
 74      * }
 75      *}
 76      * <p>
 77      * This method is intended to view memory segments through small and medium-sized memory layouts.
 78      *
 79      * @param segment  to be viewed
 80      * @param layout   to use as a layout when viewing the memory segment
 81      * @param renderer to apply when rendering value layouts
 82      * @return a view of the memory abstraction viewed through the memory layout
 83      */
 84     public static Stream<String> inspect(MemorySegment segment,
 85                                          MemoryLayout layout,
 86                                          BiFunction<ValueLayout, Object, String> renderer) {
 87         requireNonNull(segment);
 88         requireNonNull(layout);
 89         requireNonNull(renderer);
 90         return MemoryInspectionUtil.inspect(segment, layout, renderer);
 91     }
 92 
 93     /**
 94      * {@return a standard value layout renderer that will render numeric values into decimal form and where
 95      * other value types are rendered to a reasonable "natural" form}
 96      * <p>
 97      * More specifically, values types are rendered as follows:
 98      * <ul>
 99      *     <li>Numeric values are rendered in decimal form (e.g 1 or 1.2).</li>
100      *     <li>Boolean values are rendered as {@code true} or {@code false}.</li>
101      *     <li>Character values are rendered as {@code char}.</li>
102      *     <li>Address values are rendered in hexadecimal form e.g. {@code 0x0000000000000000} (on 64-bit platforms) or
103      *     {@code 0x00000000} (on 32-bit platforms)</li>
104      * </ul>
105      */
106     public static BiFunction<ValueLayout, Object, String> standardRenderer() {
107         return STANDARD_VALUE_LAYOUT_RENDERER;
108     }
109 
110 }