jaulib v1.3.0
Jau Support Library (C++, Java, ..)
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
Utility methods allowing easy java.nio.Buffer manipulations.
Definition: Buffers.java:43
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.
Definition: UnsafeUtil.java:41
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.