Builder class that allows JNI layer access CharSequence without copying memory. It is typically used to create file system paths for files and directories and passing them to Files static methods, those that accept @link LPSZ as input. Instances of this class can be re-cycled for
| 49 | * must be closed when no longer required. |
| 50 | */ |
| 51 | public class Path implements Utf8Sink, DirectUtf8Sequence, Closeable { |
| 52 | private static final byte NULL = (byte) 0; |
| 53 | private static final int OVERHEAD = 4; |
| 54 | private static final boolean PARANOIA_MODE = false; |
| 55 | private static final AtomicInteger threadLocalInstanceCounter = new AtomicInteger(); |
| 56 | public static final ThreadLocal<Path> PATH = new ThreadLocal<>(Path::newTLPath); |
| 57 | public static final ThreadLocal<Path> PATH2 = new ThreadLocal<>(Path::newTLPath); |
| 58 | public static final Closeable THREAD_LOCAL_CLEANER = Path::clearThreadLocals; |
| 59 | private static final ThreadLocal<StringSink> tlSink = new ThreadLocal<>(StringSink::new); |
| 60 | private final AsciiCharSequence asciiCharSequence = new AsciiCharSequence(); |
| 61 | private final Exception creationStackTrace; |
| 62 | private final int initialCapacity; |
| 63 | private final LPSZ lpsz = new PathLPSZ(); |
| 64 | private final int memoryTag; |
| 65 | private boolean ascii; |
| 66 | private int capacity; |
| 67 | private long headPtr; |
| 68 | private long tailPtr; |
| 69 | |
| 70 | public Path() { |
| 71 | this(255); |
| 72 | } |
| 73 | |
| 74 | public Path(int capacity) { |
| 75 | this(capacity, MemoryTag.NATIVE_PATH); |
| 76 | } |
| 77 | |
| 78 | public Path(int capacity, int memoryTag) { |
| 79 | this(capacity, memoryTag, null); |
| 80 | } |
| 81 | |
| 82 | public Path(int capacity, int memoryTag, Exception stackTrace) { |
| 83 | assert capacity > 0; |
| 84 | this.capacity = capacity; |
| 85 | this.initialCapacity = capacity; |
| 86 | this.memoryTag = memoryTag; |
| 87 | headPtr = tailPtr = Unsafe.malloc(capacity + 1, memoryTag); |
| 88 | if (PARANOIA_MODE) { |
| 89 | randomSeed(); |
| 90 | } |
| 91 | ascii = true; |
| 92 | creationStackTrace = stackTrace; |
| 93 | } |
| 94 | |
| 95 | |
| 96 | public static void clearThreadLocals() { |
| 97 | // It could be PATH.get.close(); but this would generated JDK failures on MacOS (SIGABRT) |
| 98 | // when running tests. Despite all the effort to find the exact cause, it was not possible |
| 99 | // and this is the best solution so far. This approach will remove the thread local |
| 100 | // on close and the next time a new object is created. |
| 101 | PATH.close(); |
| 102 | PATH2.close(); |
| 103 | SecurePath.clearThreadLocals(); |
| 104 | } |
| 105 | |
| 106 | public static Path getThreadLocal(CharSequence root) { |
| 107 | return PATH.get().of(root); |
| 108 | } |
nothing calls this directly
no outgoing calls
no test coverage detected
searching dependent graphs…