Edit C:\Program Files\Java\jdk1.8.0_121\com\sun\javafx\sg\prism\GrowableDataBuffer.java
/* * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * * * * * * * * * * * * * * * * * * * * */ package com.sun.javafx.sg.prism; import java.lang.ref.WeakReference; import java.nio.BufferOverflowException; import java.util.Arrays; /** * A growable buffer that can contain both byte-encoded primitive values * and a list of Objects stored for communication between a writer that fills * it with data and a reader that empties the data behind the writer. * * Both buffers (the byte-encoded array and the Object array) grow as needed * with no hard limits and the two are kept separately so it is up to the * reader and writer to read the two streams in a predetermined synchronicity * of the two streams. * * The methods on a given GrowableDataBuffer object are not synchronized or * thread-safe and writing to or reading from the object from more than one * thread at a time is unsupported. In particular, multiple writer threads * and/or multiple reader threads will definitely cause problems. * * The static getBuffer() factory methods and the static returnBuffer() method * are all synchronized so that they can be called from any thread at any * time, but any given buffer should only be returned to the pool once. */ public class GrowableDataBuffer { static final int VAL_GROW_QUANTUM = 1024; static final int MAX_VAL_GROW = 1024 * 1024; static final int MIN_OBJ_GROW = 32; static class WeakLink { WeakReference<GrowableDataBuffer> bufref; WeakLink next; } static WeakLink buflist = new WeakLink(); // Dummy "head" link object /** * Retrieve a buffer with an initial byte-encoding capacity of at least * {@code minsize} bytes. * The initial capacity of the object buffer will be the default size. * * @param minsize the minimum initial size of the byte-encoding buffer * @return a {@code GrowableDataBuffer} object of the requested size */ public static GrowableDataBuffer getBuffer(int minsize) { return getBuffer(minsize, MIN_OBJ_GROW); } /** * Retrieve a buffer with an initial byte-encoding capacity of at least * {@code minvals} bytes and an initial object buffer capacity of at * least {@code minobjs} Objects. * * @param minvals the minimum initial size of the byte-encoding buffer * @param minobjs the minimum initial size of the Object buffer * @return a {@code GrowableDataBuffer} object of the requested sizes */ public synchronized static GrowableDataBuffer getBuffer(int minvals, int minobjs) { WeakLink prev = buflist; WeakLink cur = buflist.next; while (cur != null) { GrowableDataBuffer curgdb = cur.bufref.get(); WeakLink next = cur.next; if (curgdb == null) { prev.next = cur = next; continue; } if (curgdb.valueCapacity() >= minvals && curgdb.objectCapacity() >= minobjs) { prev.next = next; return curgdb; } prev = cur; cur = next; } return new GrowableDataBuffer(minvals, minobjs); } /** * Return the indicated {@code GrowableDataBuffer} object to the pool * for reuse. * A given {@code GrowableDataBuffer} object should only be returned to * the pool once per retrieval from the {@code getBuffer()} methods. * * @param gdb the {@code GrowableDataBuffer} object to be reused. */ public synchronized static void returnBuffer(GrowableDataBuffer retgdb) { int retvlen = retgdb.valueCapacity(); int retolen = retgdb.objectCapacity(); retgdb.reset(); WeakLink prev = buflist; WeakLink cur = buflist.next; while (cur != null) { GrowableDataBuffer curgdb = cur.bufref.get(); WeakLink next = cur.next; if (curgdb == null) { prev.next = cur = next; continue; } int curvlen = curgdb.valueCapacity(); int curolen = curgdb.objectCapacity(); if (curvlen > retvlen || (curvlen == retvlen && curolen >= retolen)) { break; } prev = cur; cur = next; } WeakLink retlink = new WeakLink(); retlink.bufref = new WeakReference<>(retgdb); prev.next = retlink; retlink.next = cur; } byte vals[]; int writevalpos; // next vals location to write encoded values int readvalpos; // next vals location to read encoded values int savevalpos; // saved valpos for reading data multiple times Object objs[]; int writeobjpos; // next objs location to write data objects int readobjpos; // next objs location to read data objects int saveobjpos; // saved objpos for reading objects multiple times private GrowableDataBuffer(int initvalsize, int initobjsize) { vals = new byte[initvalsize]; objs = new Object[initobjsize]; } /** * The location of the next byte to be read from the encoded value * buffer. * This must always be less than or equal to the * {@code writeValuePosition()}. * * @return the byte position of the next byte data to be read. */ public int readValuePosition() { return readvalpos; } /** * The location of the next byte to be written to the encoded value * buffer. * * @return the byte position of the next byte data to be written. */ public int writeValuePosition() { return writevalpos; } /** * The location of the next object to be read from the object buffer. * This must always be less than or equal to the * {@code writeObjectPosition()}. * * @return the position of the next object to be read. */ public int readObjectPosition() { return readobjpos; } /** * The location of the next object to be written to the object buffer. * * @return the position of the next object to be written. */ public int writeObjectPosition() { return writeobjpos; } /** * The capacity, in bytes, of the byte-encoding buffer. * * @return the capacity of the byte-encoding buffer */ public int valueCapacity() { return vals.length; } /** * The capacity, in objects, of the {@code Object} buffer. * * @return the capacity of the {@code Object} buffer */ public int objectCapacity() { return objs.length; } /** * Save aside the current read positions of both the byte-encoding * buffer and the {@code Object} buffer for a later {@code restore()} * operation. */ public void save() { savevalpos = readvalpos; saveobjpos = readobjpos; } /** * Restore the read positions of both the byte-encoding buffer and * the {@code Object} buffer to their last saved positions. */ public void restore() { readvalpos = savevalpos; readobjpos = saveobjpos; } /** * Indicates whether or not there are values in the byte-encoding * buffer waiting to be read. * * @return true iff there are data values to be read */ public boolean hasValues() { return (readvalpos < writevalpos); } /** * Indicates whether or not there are objects in the object * buffer waiting to be read. * * @return true iff there are objects to be read */ public boolean hasObjects() { return (readobjpos < writeobjpos); } /** * Indicates whether the byte-encoding buffer is completely empty. * Note that this is different from whether or not there is unread * data in the byte-encoding buffer. A buffer which has been written * and then later fully emptied by reading is not considered "empty". * * @return true iff there is no data at all stored in the byte buffer */ public boolean isEmpty() { return (writevalpos == 0); } /** * Clears out all data and resets all positions to the start of the * buffers so that a new sequence of writing, then reading of data * and objects can begin. * Note that the {@code Object} array is cleared to nulls here and * those objects will finally become collectable by the garbage collector. */ public void reset() { readvalpos = savevalpos = writevalpos = 0; readobjpos = saveobjpos = 0; if (writeobjpos > 0) { Arrays.fill(objs, 0, writeobjpos, null); writeobjpos = 0; } } /** * Appends the contents of both the byte and {@code Object} buffers in * the indicated {@code GrowableDataBuffer} to this object. * The data in the other indicated {@code GrowableDataBuffer} object * is not disturbed in any way. * * @param gdb the {@code GrowableDataBuffer} to append to this object */ public void append(GrowableDataBuffer gdb) { ensureWriteCapacity(gdb.writevalpos); System.arraycopy(gdb.vals, 0, vals, writevalpos, gdb.writevalpos); writevalpos += gdb.writevalpos; if (writeobjpos + gdb.writeobjpos > objs.length) { objs = Arrays.copyOf(objs, writeobjpos + gdb.writeobjpos); } System.arraycopy(gdb.objs, 0, objs, writeobjpos, gdb.writeobjpos); writeobjpos += gdb.writeobjpos; } private void ensureWriteCapacity(int newbytes) { if (newbytes > vals.length - writevalpos) { newbytes = writevalpos + newbytes - vals.length; // Double in size up to MAX_VAL_GROW int growbytes = Math.min(vals.length, MAX_VAL_GROW); // And at least by the number of new bytes if (growbytes < newbytes) growbytes = newbytes; int newsize = vals.length + growbytes; newsize = (newsize + (VAL_GROW_QUANTUM - 1)) & ~(VAL_GROW_QUANTUM - 1); vals = Arrays.copyOf(vals, newsize); } } private void ensureReadCapacity(int bytesneeded) { if (readvalpos + bytesneeded > writevalpos) { throw new BufferOverflowException(); } } /** * Encode a boolean value and write it to the end of the byte-encoding array * * @param b the boolean value to be written */ public void putBoolean(boolean b) { putByte(b ? (byte) 1 : (byte) 0); } /** * Write a byte value to the end of the byte-encoding array * * @param b the byte value to be written */ public void putByte(byte b) { ensureWriteCapacity(1); vals[writevalpos++] = b; } /** * Encode a char value and write it to the end of the byte-encoding array * * @param c the char value to be written */ public void putChar(char c) { ensureWriteCapacity(2); vals[writevalpos++] = (byte) (c >> 8); vals[writevalpos++] = (byte) (c ); } /** * Encode a short value and write it to the end of the byte-encoding array * * @param s the short value to be written */ public void putShort(short s) { ensureWriteCapacity(2); vals[writevalpos++] = (byte) (s >> 8); vals[writevalpos++] = (byte) (s ); } /** * Encode an int value and write it to the end of the byte-encoding array * * @param i the int value to be written */ public void putInt(int i) { ensureWriteCapacity(4); vals[writevalpos++] = (byte) (i >> 24); vals[writevalpos++] = (byte) (i >> 16); vals[writevalpos++] = (byte) (i >> 8); vals[writevalpos++] = (byte) (i ); } /** * Encode a long value and write it to the end of the byte-encoding array * * @param l the long value to be written */ public void putLong(long l) { ensureWriteCapacity(8); vals[writevalpos++] = (byte) (l >> 56); vals[writevalpos++] = (byte) (l >> 48); vals[writevalpos++] = (byte) (l >> 40); vals[writevalpos++] = (byte) (l >> 32); vals[writevalpos++] = (byte) (l >> 24); vals[writevalpos++] = (byte) (l >> 16); vals[writevalpos++] = (byte) (l >> 8); vals[writevalpos++] = (byte) (l ); } /** * Encode a float value and write it to the end of the byte-encoding array * * @param f the float value to be written */ public void putFloat(float f) { putInt(Float.floatToIntBits(f)); } /** * Encode a double value and write it to the end of the byte-encoding array * * @param d the double value to be written */ public void putDouble(double d) { putLong(Double.doubleToLongBits(d)); } /** * Write an {@code Object} to the end of the object array * * @param o the {@code Object} to be written */ public void putObject(Object o) { if (writeobjpos >= objs.length) { objs = Arrays.copyOf(objs, writeobjpos+MIN_OBJ_GROW); } objs[writeobjpos++] = o; } /** * Read a single byte from the byte-encoded stream, ignoring any read * position, but honoring the current write position as a limit. * The read and saved positions are not used or modified in any way * by this method * * @param i the absolute byte location to return from the byte-encoding array * @return the byte stored at the indicated location in the byte array */ public byte peekByte(int i) { if (i >= writevalpos) { throw new BufferOverflowException(); } return vals[i]; } /** * Read a single {@code Object} from the object buffer, ignoring any read * position, but honoring the current write position as a limit. * The read and saved positions are not used or modified in any way * by this method * * @param i the absolute index to return from the {@code Object} array * @return the {@code Object} stored at the indicated index */ public Object peekObject(int i) { if (i >= writeobjpos) { throw new BufferOverflowException(); } return objs[i]; } /** * Decodes and returns a single boolean value from the current read * position in the byte-encoded stream and bumps the read position * past the decoded value. * * @return the decoded boolean value */ public boolean getBoolean() { ensureReadCapacity(1); return vals[readvalpos++] != 0; } /** * Returns a single byte value from the current read * position in the byte-encoded stream and bumps the read position * past the returned value. * * @return the decoded byte value */ public byte getByte() { ensureReadCapacity(1); return vals[readvalpos++]; } /** * Decodes a single unsigned byte value from the current read * position in the byte-encoded stream and returns the value cast to * an int and bumps the read position * past the decoded value. * * @return the decoded unsigned byte value as an int */ public int getUByte() { ensureReadCapacity(1); return vals[readvalpos++] & 0xff; } /** * Decodes and returns a single char value from the current read * position in the byte-encoded stream and bumps the read position * past the decoded value. * * @return the decoded char value */ public char getChar() { ensureReadCapacity(2); int c = vals[readvalpos++]; c = (c << 8) | (vals[readvalpos++] & 0xff); return (char) c; } /** * Decodes and returns a single short value from the current read * position in the byte-encoded stream and bumps the read position * past the decoded value. * * @return the decoded short value */ public short getShort() { ensureReadCapacity(2); int s = vals[readvalpos++]; s = (s << 8) | (vals[readvalpos++] & 0xff); return (short) s; } /** * Decodes and returns a single int value from the current read * position in the byte-encoded stream and bumps the read position * past the decoded value. * * @return the decoded int value */ public int getInt() { ensureReadCapacity(4); int i = vals[readvalpos++]; i = (i << 8) | (vals[readvalpos++] & 0xff); i = (i << 8) | (vals[readvalpos++] & 0xff); i = (i << 8) | (vals[readvalpos++] & 0xff); return i; } /** * Decodes and returns a single long value from the current read * position in the byte-encoded stream and bumps the read position * past the decoded value. * * @return the decoded long value */ public long getLong() { ensureReadCapacity(8); long l = vals[readvalpos++]; l = (l << 8) | (vals[readvalpos++] & 0xff); l = (l << 8) | (vals[readvalpos++] & 0xff); l = (l << 8) | (vals[readvalpos++] & 0xff); l = (l << 8) | (vals[readvalpos++] & 0xff); l = (l << 8) | (vals[readvalpos++] & 0xff); l = (l << 8) | (vals[readvalpos++] & 0xff); l = (l << 8) | (vals[readvalpos++] & 0xff); return l; } /** * Decodes and returns a single float value from the current read * position in the byte-encoded stream and bumps the read position * past the decoded value. * * @return the decoded float value */ public float getFloat() { return Float.intBitsToFloat(getInt()); } /** * Decodes and returns a single double value from the current read * position in the byte-encoded stream and bumps the read position * past the decoded value. * * @return the decoded double value */ public double getDouble() { return Double.longBitsToDouble(getLong()); } /** * Returns a single {@code Object} from the current object read * position in the {@code Object} stream and bumps the read position * past the returned value. * * @return the {@code Object} read from the buffer */ public Object getObject() { if (readobjpos >= objs.length) { throw new BufferOverflowException(); } return objs[readobjpos++]; } }
Ms-Dos/Windows
Unix
Write backup
jsp File Browser version 1.2 by
www.vonloesch.de