1. /*
  2. * @(#)Direct-X-Buffer.java 1.45 03/04/23
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. // -- This file was mechanically generated: Do not edit! -- //
  8. package java.nio;
  9. import sun.misc.Cleaner;
  10. import sun.misc.Unsafe;
  11. import sun.nio.ch.DirectBuffer;
  12. import sun.nio.ch.FileChannelImpl;
  13. class DirectByteBuffer
  14. extends MappedByteBuffer
  15. implements DirectBuffer
  16. {
  17. // Cached unsafe-access object
  18. protected static final Unsafe unsafe = Bits.unsafe();
  19. // Cached unaligned-access capability
  20. protected static final boolean unaligned = Bits.unaligned();
  21. // Base address, used in all indexing calculations
  22. // NOTE: moved up to Buffer.java for speed in JNI GetDirectBufferAddress
  23. // protected long address;
  24. // If this buffer is a view of another buffer then we keep a reference to
  25. // that buffer so that its memory isn't freed before we're done with it
  26. protected Object viewedBuffer = null;
  27. public Object viewedBuffer() {
  28. return viewedBuffer;
  29. }
  30. private static class Deallocator
  31. implements Runnable
  32. {
  33. private static Unsafe unsafe = Unsafe.getUnsafe();
  34. private long address;
  35. private int capacity;
  36. private Deallocator(long address, int capacity) {
  37. assert (address != 0);
  38. this.address = address;
  39. this.capacity = capacity;
  40. }
  41. public void run() {
  42. if (address == 0) {
  43. // Paranoia
  44. return;
  45. }
  46. unsafe.freeMemory(address);
  47. address = 0;
  48. Bits.unreserveMemory(capacity);
  49. }
  50. }
  51. private final Cleaner cleaner;
  52. public Cleaner cleaner() { return cleaner; }
  53. // Primary constructor
  54. //
  55. DirectByteBuffer(int cap) { // package-private
  56. super(-1, 0, cap, cap, false);
  57. Bits.reserveMemory(cap);
  58. int ps = Bits.pageSize();
  59. long base = 0;
  60. try {
  61. base = unsafe.allocateMemory(cap + ps);
  62. } catch (OutOfMemoryError x) {
  63. Bits.unreserveMemory(cap);
  64. throw x;
  65. }
  66. unsafe.setMemory(base, cap + ps, (byte) 0);
  67. if (base % ps != 0) {
  68. // Round up to page boundary
  69. address = base + ps - (base & (ps - 1));
  70. } else {
  71. address = base;
  72. }
  73. cleaner = Cleaner.create(this, new Deallocator(base, cap));
  74. }
  75. // Invoked only by JNI: NewDirectByteBuffer(void*, long)
  76. //
  77. private DirectByteBuffer(long addr, int cap) {
  78. super(-1, 0, cap, cap, false);
  79. address = addr;
  80. cleaner = null;
  81. }
  82. // For memory-mapped buffers -- invoked by FileChannelImpl via reflection
  83. //
  84. protected DirectByteBuffer(int cap, long addr, Runnable unmapper) {
  85. super(-1, 0, cap, cap, true);
  86. address = addr;
  87. viewedBuffer = null;
  88. cleaner = Cleaner.create(this, unmapper);
  89. }
  90. // For duplicates and slices
  91. //
  92. DirectByteBuffer(DirectBuffer db, // package-private
  93. int mark, int pos, int lim, int cap,
  94. int off)
  95. {
  96. super(mark, pos, lim, cap);
  97. address = db.address() + off;
  98. viewedBuffer = db;
  99. cleaner = null;
  100. }
  101. public ByteBuffer slice() {
  102. int pos = this.position();
  103. int lim = this.limit();
  104. assert (pos <= lim);
  105. int rem = (pos <= lim ? lim - pos : 0);
  106. int off = (pos << 0);
  107. return new DirectByteBuffer(this, -1, 0, rem, rem, off);
  108. }
  109. public ByteBuffer duplicate() {
  110. return new DirectByteBuffer(this,
  111. this.markValue(),
  112. this.position(),
  113. this.limit(),
  114. this.capacity(),
  115. 0);
  116. }
  117. public ByteBuffer asReadOnlyBuffer() {
  118. return new DirectByteBufferR(this,
  119. this.markValue(),
  120. this.position(),
  121. this.limit(),
  122. this.capacity(),
  123. 0);
  124. }
  125. public long address() {
  126. return address;
  127. }
  128. private long ix(int i) {
  129. return address + (i << 0);
  130. }
  131. public byte get() {
  132. return ((unsafe.getByte(ix(nextGetIndex()))));
  133. }
  134. public byte get(int i) {
  135. return ((unsafe.getByte(ix(checkIndex(i)))));
  136. }
  137. public ByteBuffer get(byte[] dst, int offset, int length) {
  138. if ((length << 0) > Bits.JNI_COPY_TO_ARRAY_THRESHOLD) {
  139. checkBounds(offset, length, dst.length);
  140. int pos = position();
  141. int lim = limit();
  142. assert (pos <= lim);
  143. int rem = (pos <= lim ? lim - pos : 0);
  144. if (length > rem)
  145. throw new BufferUnderflowException();
  146. if (order() != ByteOrder.nativeOrder())
  147. Bits.copyToByteArray(ix(pos), dst,
  148. offset << 0,
  149. length << 0);
  150. else
  151. Bits.copyToByteArray(ix(pos), dst,
  152. offset << 0,
  153. length << 0);
  154. position(pos + length);
  155. } else {
  156. super.get(dst, offset, length);
  157. }
  158. return this;
  159. }
  160. public ByteBuffer put(byte x) {
  161. unsafe.putByte(ix(nextPutIndex()), ((x)));
  162. return this;
  163. }
  164. public ByteBuffer put(int i, byte x) {
  165. unsafe.putByte(ix(checkIndex(i)), ((x)));
  166. return this;
  167. }
  168. public ByteBuffer put(ByteBuffer src) {
  169. if (src instanceof DirectByteBuffer) {
  170. if (src == this)
  171. throw new IllegalArgumentException();
  172. DirectByteBuffer sb = (DirectByteBuffer)src;
  173. int spos = sb.position();
  174. int slim = sb.limit();
  175. assert (spos <= slim);
  176. int srem = (spos <= slim ? slim - spos : 0);
  177. int pos = position();
  178. int lim = limit();
  179. assert (pos <= lim);
  180. int rem = (pos <= lim ? lim - pos : 0);
  181. if (srem > rem)
  182. throw new BufferOverflowException();
  183. unsafe.copyMemory(sb.ix(spos), ix(pos), srem << 0);
  184. sb.position(spos + srem);
  185. position(pos + srem);
  186. } else if (!src.isDirect()) {
  187. int spos = src.position();
  188. int slim = src.limit();
  189. assert (spos <= slim);
  190. int srem = (spos <= slim ? slim - spos : 0);
  191. put(src.hb, src.offset + spos, srem);
  192. src.position(spos + srem);
  193. } else {
  194. super.put(src);
  195. }
  196. return this;
  197. }
  198. public ByteBuffer put(byte[] src, int offset, int length) {
  199. if ((length << 0) > Bits.JNI_COPY_FROM_ARRAY_THRESHOLD) {
  200. checkBounds(offset, length, src.length);
  201. int pos = position();
  202. int lim = limit();
  203. assert (pos <= lim);
  204. int rem = (pos <= lim ? lim - pos : 0);
  205. if (length > rem)
  206. throw new BufferOverflowException();
  207. if (order() != ByteOrder.nativeOrder())
  208. Bits.copyFromByteArray(src, offset << 0,
  209. ix(pos), length << 0);
  210. else
  211. Bits.copyFromByteArray(src, offset << 0,
  212. ix(pos), length << 0);
  213. position(pos + length);
  214. } else {
  215. super.put(src, offset, length);
  216. }
  217. return this;
  218. }
  219. public ByteBuffer compact() {
  220. int pos = position();
  221. int lim = limit();
  222. assert (pos <= lim);
  223. int rem = (pos <= lim ? lim - pos : 0);
  224. unsafe.copyMemory(ix(pos), ix(0), rem << 0);
  225. position(rem);
  226. limit(capacity());
  227. return this;
  228. }
  229. public boolean isDirect() {
  230. return true;
  231. }
  232. public boolean isReadOnly() {
  233. return false;
  234. }
  235. byte _get(int i) { // package-private
  236. return unsafe.getByte(address + i);
  237. }
  238. void _put(int i, byte b) { // package-private
  239. unsafe.putByte(address + i, b);
  240. }
  241. private char getChar(long a) {
  242. if (unaligned) {
  243. char x = unsafe.getChar(a);
  244. return (nativeByteOrder ? x : Bits.swap(x));
  245. }
  246. return Bits.getChar(a, bigEndian);
  247. }
  248. public char getChar() {
  249. return getChar(ix(nextGetIndex((1 << 1))));
  250. }
  251. public char getChar(int i) {
  252. return getChar(ix(checkIndex(i, (1 << 1))));
  253. }
  254. private ByteBuffer putChar(long a, char x) {
  255. if (unaligned) {
  256. char y = (x);
  257. unsafe.putChar(a, (nativeByteOrder ? y : Bits.swap(y)));
  258. } else {
  259. Bits.putChar(a, x, bigEndian);
  260. }
  261. return this;
  262. }
  263. public ByteBuffer putChar(char x) {
  264. putChar(ix(nextPutIndex((1 << 1))), x);
  265. return this;
  266. }
  267. public ByteBuffer putChar(int i, char x) {
  268. putChar(ix(checkIndex(i, (1 << 1))), x);
  269. return this;
  270. }
  271. public CharBuffer asCharBuffer() {
  272. int off = this.position();
  273. int lim = this.limit();
  274. assert (off <= lim);
  275. int rem = (off <= lim ? lim - off : 0);
  276. int size = rem >> 1;
  277. if (!unaligned && ((address + off) % (1 << 1) != 0)) {
  278. return (bigEndian
  279. ? (CharBuffer)(new ByteBufferAsCharBufferB(this,
  280. -1,
  281. 0,
  282. size,
  283. size,
  284. off))
  285. : (CharBuffer)(new ByteBufferAsCharBufferL(this,
  286. -1,
  287. 0,
  288. size,
  289. size,
  290. off)));
  291. } else {
  292. return (nativeByteOrder
  293. ? (CharBuffer)(new DirectCharBufferU(this,
  294. -1,
  295. 0,
  296. size,
  297. size,
  298. off))
  299. : (CharBuffer)(new DirectCharBufferS(this,
  300. -1,
  301. 0,
  302. size,
  303. size,
  304. off)));
  305. }
  306. }
  307. private short getShort(long a) {
  308. if (unaligned) {
  309. short x = unsafe.getShort(a);
  310. return (nativeByteOrder ? x : Bits.swap(x));
  311. }
  312. return Bits.getShort(a, bigEndian);
  313. }
  314. public short getShort() {
  315. return getShort(ix(nextGetIndex((1 << 1))));
  316. }
  317. public short getShort(int i) {
  318. return getShort(ix(checkIndex(i, (1 << 1))));
  319. }
  320. private ByteBuffer putShort(long a, short x) {
  321. if (unaligned) {
  322. short y = (x);
  323. unsafe.putShort(a, (nativeByteOrder ? y : Bits.swap(y)));
  324. } else {
  325. Bits.putShort(a, x, bigEndian);
  326. }
  327. return this;
  328. }
  329. public ByteBuffer putShort(short x) {
  330. putShort(ix(nextPutIndex((1 << 1))), x);
  331. return this;
  332. }
  333. public ByteBuffer putShort(int i, short x) {
  334. putShort(ix(checkIndex(i, (1 << 1))), x);
  335. return this;
  336. }
  337. public ShortBuffer asShortBuffer() {
  338. int off = this.position();
  339. int lim = this.limit();
  340. assert (off <= lim);
  341. int rem = (off <= lim ? lim - off : 0);
  342. int size = rem >> 1;
  343. if (!unaligned && ((address + off) % (1 << 1) != 0)) {
  344. return (bigEndian
  345. ? (ShortBuffer)(new ByteBufferAsShortBufferB(this,
  346. -1,
  347. 0,
  348. size,
  349. size,
  350. off))
  351. : (ShortBuffer)(new ByteBufferAsShortBufferL(this,
  352. -1,
  353. 0,
  354. size,
  355. size,
  356. off)));
  357. } else {
  358. return (nativeByteOrder
  359. ? (ShortBuffer)(new DirectShortBufferU(this,
  360. -1,
  361. 0,
  362. size,
  363. size,
  364. off))
  365. : (ShortBuffer)(new DirectShortBufferS(this,
  366. -1,
  367. 0,
  368. size,
  369. size,
  370. off)));
  371. }
  372. }
  373. private int getInt(long a) {
  374. if (unaligned) {
  375. int x = unsafe.getInt(a);
  376. return (nativeByteOrder ? x : Bits.swap(x));
  377. }
  378. return Bits.getInt(a, bigEndian);
  379. }
  380. public int getInt() {
  381. return getInt(ix(nextGetIndex((1 << 2))));
  382. }
  383. public int getInt(int i) {
  384. return getInt(ix(checkIndex(i, (1 << 2))));
  385. }
  386. private ByteBuffer putInt(long a, int x) {
  387. if (unaligned) {
  388. int y = (x);
  389. unsafe.putInt(a, (nativeByteOrder ? y : Bits.swap(y)));
  390. } else {
  391. Bits.putInt(a, x, bigEndian);
  392. }
  393. return this;
  394. }
  395. public ByteBuffer putInt(int x) {
  396. putInt(ix(nextPutIndex((1 << 2))), x);
  397. return this;
  398. }
  399. public ByteBuffer putInt(int i, int x) {
  400. putInt(ix(checkIndex(i, (1 << 2))), x);
  401. return this;
  402. }
  403. public IntBuffer asIntBuffer() {
  404. int off = this.position();
  405. int lim = this.limit();
  406. assert (off <= lim);
  407. int rem = (off <= lim ? lim - off : 0);
  408. int size = rem >> 2;
  409. if (!unaligned && ((address + off) % (1 << 2) != 0)) {
  410. return (bigEndian
  411. ? (IntBuffer)(new ByteBufferAsIntBufferB(this,
  412. -1,
  413. 0,
  414. size,
  415. size,
  416. off))
  417. : (IntBuffer)(new ByteBufferAsIntBufferL(this,
  418. -1,
  419. 0,
  420. size,
  421. size,
  422. off)));
  423. } else {
  424. return (nativeByteOrder
  425. ? (IntBuffer)(new DirectIntBufferU(this,
  426. -1,
  427. 0,
  428. size,
  429. size,
  430. off))
  431. : (IntBuffer)(new DirectIntBufferS(this,
  432. -1,
  433. 0,
  434. size,
  435. size,
  436. off)));
  437. }
  438. }
  439. private long getLong(long a) {
  440. if (unaligned) {
  441. long x = unsafe.getLong(a);
  442. return (nativeByteOrder ? x : Bits.swap(x));
  443. }
  444. return Bits.getLong(a, bigEndian);
  445. }
  446. public long getLong() {
  447. return getLong(ix(nextGetIndex((1 << 3))));
  448. }
  449. public long getLong(int i) {
  450. return getLong(ix(checkIndex(i, (1 << 3))));
  451. }
  452. private ByteBuffer putLong(long a, long x) {
  453. if (unaligned) {
  454. long y = (x);
  455. unsafe.putLong(a, (nativeByteOrder ? y : Bits.swap(y)));
  456. } else {
  457. Bits.putLong(a, x, bigEndian);
  458. }
  459. return this;
  460. }
  461. public ByteBuffer putLong(long x) {
  462. putLong(ix(nextPutIndex((1 << 3))), x);
  463. return this;
  464. }
  465. public ByteBuffer putLong(int i, long x) {
  466. putLong(ix(checkIndex(i, (1 << 3))), x);
  467. return this;
  468. }
  469. public LongBuffer asLongBuffer() {
  470. int off = this.position();
  471. int lim = this.limit();
  472. assert (off <= lim);
  473. int rem = (off <= lim ? lim - off : 0);
  474. int size = rem >> 3;
  475. if (!unaligned && ((address + off) % (1 << 3) != 0)) {
  476. return (bigEndian
  477. ? (LongBuffer)(new ByteBufferAsLongBufferB(this,
  478. -1,
  479. 0,
  480. size,
  481. size,
  482. off))
  483. : (LongBuffer)(new ByteBufferAsLongBufferL(this,
  484. -1,
  485. 0,
  486. size,
  487. size,
  488. off)));
  489. } else {
  490. return (nativeByteOrder
  491. ? (LongBuffer)(new DirectLongBufferU(this,
  492. -1,
  493. 0,
  494. size,
  495. size,
  496. off))
  497. : (LongBuffer)(new DirectLongBufferS(this,
  498. -1,
  499. 0,
  500. size,
  501. size,
  502. off)));
  503. }
  504. }
  505. private float getFloat(long a) {
  506. if (unaligned) {
  507. int x = unsafe.getInt(a);
  508. return Float.intBitsToFloat(nativeByteOrder ? x : Bits.swap(x));
  509. }
  510. return Bits.getFloat(a, bigEndian);
  511. }
  512. public float getFloat() {
  513. return getFloat(ix(nextGetIndex((1 << 2))));
  514. }
  515. public float getFloat(int i) {
  516. return getFloat(ix(checkIndex(i, (1 << 2))));
  517. }
  518. private ByteBuffer putFloat(long a, float x) {
  519. if (unaligned) {
  520. int y = Float.floatToRawIntBits(x);
  521. unsafe.putInt(a, (nativeByteOrder ? y : Bits.swap(y)));
  522. } else {
  523. Bits.putFloat(a, x, bigEndian);
  524. }
  525. return this;
  526. }
  527. public ByteBuffer putFloat(float x) {
  528. putFloat(ix(nextPutIndex((1 << 2))), x);
  529. return this;
  530. }
  531. public ByteBuffer putFloat(int i, float x) {
  532. putFloat(ix(checkIndex(i, (1 << 2))), x);
  533. return this;
  534. }
  535. public FloatBuffer asFloatBuffer() {
  536. int off = this.position();
  537. int lim = this.limit();
  538. assert (off <= lim);
  539. int rem = (off <= lim ? lim - off : 0);
  540. int size = rem >> 2;
  541. if (!unaligned && ((address + off) % (1 << 2) != 0)) {
  542. return (bigEndian
  543. ? (FloatBuffer)(new ByteBufferAsFloatBufferB(this,
  544. -1,
  545. 0,
  546. size,
  547. size,
  548. off))
  549. : (FloatBuffer)(new ByteBufferAsFloatBufferL(this,
  550. -1,
  551. 0,
  552. size,
  553. size,
  554. off)));
  555. } else {
  556. return (nativeByteOrder
  557. ? (FloatBuffer)(new DirectFloatBufferU(this,
  558. -1,
  559. 0,
  560. size,
  561. size,
  562. off))
  563. : (FloatBuffer)(new DirectFloatBufferS(this,
  564. -1,
  565. 0,
  566. size,
  567. size,
  568. off)));
  569. }
  570. }
  571. private double getDouble(long a) {
  572. if (unaligned) {
  573. long x = unsafe.getLong(a);
  574. return Double.longBitsToDouble(nativeByteOrder ? x : Bits.swap(x));
  575. }
  576. return Bits.getDouble(a, bigEndian);
  577. }
  578. public double getDouble() {
  579. return getDouble(ix(nextGetIndex((1 << 3))));
  580. }
  581. public double getDouble(int i) {
  582. return getDouble(ix(checkIndex(i, (1 << 3))));
  583. }
  584. private ByteBuffer putDouble(long a, double x) {
  585. if (unaligned) {
  586. long y = Double.doubleToRawLongBits(x);
  587. unsafe.putLong(a, (nativeByteOrder ? y : Bits.swap(y)));
  588. } else {
  589. Bits.putDouble(a, x, bigEndian);
  590. }
  591. return this;
  592. }
  593. public ByteBuffer putDouble(double x) {
  594. putDouble(ix(nextPutIndex((1 << 3))), x);
  595. return this;
  596. }
  597. public ByteBuffer putDouble(int i, double x) {
  598. putDouble(ix(checkIndex(i, (1 << 3))), x);
  599. return this;
  600. }
  601. public DoubleBuffer asDoubleBuffer() {
  602. int off = this.position();
  603. int lim = this.limit();
  604. assert (off <= lim);
  605. int rem = (off <= lim ? lim - off : 0);
  606. int size = rem >> 3;
  607. if (!unaligned && ((address + off) % (1 << 3) != 0)) {
  608. return (bigEndian
  609. ? (DoubleBuffer)(new ByteBufferAsDoubleBufferB(this,
  610. -1,
  611. 0,
  612. size,
  613. size,
  614. off))
  615. : (DoubleBuffer)(new ByteBufferAsDoubleBufferL(this,
  616. -1,
  617. 0,
  618. size,
  619. size,
  620. off)));
  621. } else {
  622. return (nativeByteOrder
  623. ? (DoubleBuffer)(new DirectDoubleBufferU(this,
  624. -1,
  625. 0,
  626. size,
  627. size,
  628. off))
  629. : (DoubleBuffer)(new DirectDoubleBufferS(this,
  630. -1,
  631. 0,
  632. size,
  633. size,
  634. off)));
  635. }
  636. }
  637. }