jaulib v1.3.8
Jau Support Library (C++, Java, ..)
Loading...
Searching...
No Matches
Buffers.java
Go to the documentation of this file.
1/**
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright (c) 2021 Gothel Software e.K.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24package org.jau.io;
25
26import java.nio.Buffer;
27import java.nio.ByteBuffer;
28import java.nio.ByteOrder;
29import java.nio.CharBuffer;
30import java.nio.DoubleBuffer;
31import java.nio.FloatBuffer;
32import java.nio.IntBuffer;
33import java.nio.LongBuffer;
34import java.nio.ShortBuffer;
35
36import org.jau.lang.UnsafeUtil;
37import org.jau.sys.Debug;
38import org.jau.sys.PlatformProps;
39
40/**
41 * Utility methods allowing easy {@link java.nio.Buffer} manipulations.
42 */
43public class Buffers {
44 static final boolean DEBUG = Debug.debug("NioUtil");
45
46 public static final int SIZEOF_BYTE = 1;
47 public static final int SIZEOF_SHORT = 2;
48 public static final int SIZEOF_CHAR = 2;
49 public static final int SIZEOF_INT = 4;
50 public static final int SIZEOF_FLOAT = 4;
51 public static final int SIZEOF_LONG = 8;
52 public static final int SIZEOF_DOUBLE = 8;
53
54 private Buffers() {}
55
56 /**
57 * Allocates a new direct ByteBuffer with the specified number of
58 * elements. The returned buffer will have its byte order set to
59 * the host platform's native byte order.
60 */
61 public static ByteBuffer newDirectByteBuffer(final int size) {
62 return ByteBuffer.allocateDirect( size ).order( ByteOrder.nativeOrder() );
63 }
64
65 /**
66 * Helper routine to set a ByteBuffer to the native byte order, if
67 * that operation is supported by the underlying NIO
68 * implementation.
69 */
70 public static ByteBuffer nativeOrder(final ByteBuffer buf) {
71 return buf.order(ByteOrder.nativeOrder());
72 }
73
74 /**
75 * Helper routine to tell whether a buffer is direct or not. Null
76 * pointers <b>are</b> considered direct.
77 */
78 public static boolean isDirect(final Object buf) {
79 if (buf == null) {
80 return true;
81 }
82 if (buf instanceof Buffer) {
83 return ((Buffer) buf).isDirect();
84 }
85 throw new IllegalArgumentException("Unexpected buffer type " + buf.getClass().getName());
86 }
87
88 /**
89 * Helper routine to get the Buffer byte offset by taking into
90 * account the Buffer position and the underlying type.
91 * This is the total offset for Direct Buffers.
92 *
93 * Return value is of type `long` only to cover the `int` multiple of the position and element type size.<br/>
94 * For ByteBuffer, the return value can be safely cast to `int`.
95 */
96 public static long getDirectBufferByteOffset(final Object buf) {
97 if (buf == null) {
98 return 0;
99 }
100 if (buf instanceof Buffer) {
101 final long pos = ((Buffer) buf).position();
102 if (buf instanceof ByteBuffer) {
103 return pos;
104 } else if (buf instanceof FloatBuffer) {
105 return pos * SIZEOF_FLOAT;
106 } else if (buf instanceof IntBuffer) {
107 return pos * SIZEOF_INT;
108 } else if (buf instanceof ShortBuffer) {
109 return pos * SIZEOF_SHORT;
110 } else if (buf instanceof DoubleBuffer) {
111 return pos * SIZEOF_DOUBLE;
112 } else if (buf instanceof LongBuffer) {
113 return pos * SIZEOF_LONG;
114 } else if (buf instanceof CharBuffer) {
115 return pos * SIZEOF_CHAR;
116 }
117 }
118 throw new IllegalArgumentException("Disallowed array backing store type in buffer " + buf.getClass().getName());
119 }
120
121 /**
122 * Helper routine to get the Buffer byte limit by taking into
123 * account the Buffer limit and the underlying type.
124 * This is the total limit for Direct Buffers.
125 *
126 * Return value is of type `long` only to cover the `int` multiple of the position and element type size.<br/>
127 * For ByteBuffer, the return value can be safely cast to `int`.
128 */
129 public static long getDirectBufferByteLimit(final Object buf) {
130 if (buf == null) {
131 return 0;
132 }
133 if (buf instanceof Buffer) {
134 final long limit = ((Buffer) buf).limit();
135 if (buf instanceof ByteBuffer) {
136 return limit;
137 } else if (buf instanceof FloatBuffer) {
138 return limit * SIZEOF_FLOAT;
139 } else if (buf instanceof IntBuffer) {
140 return limit * SIZEOF_INT;
141 } else if (buf instanceof ShortBuffer) {
142 return limit * SIZEOF_SHORT;
143 } else if (buf instanceof DoubleBuffer) {
144 return limit * SIZEOF_DOUBLE;
145 } else if (buf instanceof LongBuffer) {
146 return limit * SIZEOF_LONG;
147 } else if (buf instanceof CharBuffer) {
148 return limit * SIZEOF_CHAR;
149 }
150 }
151 throw new IllegalArgumentException("Disallowed array backing store type in buffer " + buf.getClass().getName());
152 }
153
154 /**
155 * Access to NIO {@link sun.misc.Cleaner}, allowing caller to deterministically clean a given {@link sun.nio.ch.DirectBuffer}.
156 */
157 public static class Cleaner {
158 private static final boolean hasCleaner;
159 /** OK to be lazy on thread synchronization, just for early out **/
160 private static volatile boolean cleanerError;
161 static {
162 hasCleaner = UnsafeUtil.hasInvokeCleaner();
163 cleanerError = !hasCleaner;
164 if( DEBUG ) {
165 System.err.println("Buffers.Cleaner.init: hasCleaner: "+hasCleaner+", cleanerError "+cleanerError);
166 }
167 }
168
169 /**
170 * If {@code b} is an direct NIO buffer, i.e {@link sun.nio.ch.DirectBuffer},
171 * calls it's {@link sun.misc.Cleaner} instance {@code clean()} method once.
172 * @return {@code true} if successful, otherwise {@code false}.
173 */
174 public static boolean clean(final ByteBuffer bb) {
175 if( !hasCleaner && ( cleanerError || !bb.isDirect() ) ) {
176 return false;
177 }
178 if( PlatformProps.JAVA_9 ) {
180 } else {
181 return false;
182 }
183 return true;
184 }
185 }
186
187}
Access to NIO sun.misc.Cleaner, allowing caller to deterministically clean a given sun....
Definition Buffers.java:157
static boolean clean(final ByteBuffer bb)
If b is an direct NIO buffer, i.e sun.nio.ch.DirectBuffer, calls it's sun.misc.Cleaner instance clean...
Definition Buffers.java:174
static final int SIZEOF_CHAR
Definition Buffers.java:48
static final int SIZEOF_FLOAT
Definition Buffers.java:50
static final int SIZEOF_INT
Definition Buffers.java:49
static final int SIZEOF_BYTE
Definition Buffers.java:46
static ByteBuffer nativeOrder(final ByteBuffer buf)
Helper routine to set a ByteBuffer to the native byte order, if that operation is supported by the un...
Definition Buffers.java:70
static ByteBuffer newDirectByteBuffer(final int size)
Allocates a new direct ByteBuffer with the specified number of elements.
Definition Buffers.java:61
static final int SIZEOF_SHORT
Definition Buffers.java:47
static boolean isDirect(final Object buf)
Helper routine to tell whether a buffer is direct or not.
Definition Buffers.java:78
static final int SIZEOF_LONG
Definition Buffers.java:51
static final int SIZEOF_DOUBLE
Definition Buffers.java:52
static long getDirectBufferByteOffset(final Object buf)
Helper routine to get the Buffer byte offset by taking into account the Buffer position and the under...
Definition Buffers.java:96
static long getDirectBufferByteLimit(final Object buf)
Helper routine to get the Buffer byte limit by taking into account the Buffer limit and the underlyin...
Definition Buffers.java:129
Utility methods allowing easy access to certain sun.misc.Unsafe functionality.
static boolean hasInvokeCleaner()
Returns true if sun.misc.Unsafe.invokeCleaner(java.nio.ByteBuffer) is available and has not caused an...
static boolean invokeCleaner(final ByteBuffer bb)
Access to sun.misc.Unsafe.invokeCleaner(java.nio.ByteBuffer).
Helper routines for logging and debugging.
Definition Debug.java:35
static final boolean debug(final String subcomponent)
Definition Debug.java:63
Platform Properties derived from Java properties.
static final boolean JAVA_9
True only if being compatible w/ language level 9, e.g.