1. /*
  2. * @(#)Direct-X-Buffer.java 1.48 04/05/03
  3. *
  4. * Copyright 2004 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. assert (off >= 0);
  108. return new DirectByteBuffer(this, -1, 0, rem, rem, off);
  109. }
  110. public ByteBuffer duplicate() {
  111. return new DirectByteBuffer(this,
  112. this.markValue(),
  113. this.position(),
  114. this.limit(),
  115. this.capacity(),
  116. 0);
  117. }
  118. public ByteBuffer asReadOnlyBuffer() {
  119. return new DirectByteBufferR(this,
  120. this.markValue(),
  121. this.position(),
  122. this.limit(),
  123. this.capacity(),
  124. 0);
  125. }
  126. public long address() {
  127. return address;
  128. }
  129. private long ix(int i) {
  130. return address + (i << 0);
  131. }
  132. public byte get() {
  133. return ((unsafe.getByte(ix(nextGetIndex()))));
  134. }
  135. public byte get(int i) {
  136. return ((unsafe.getByte(ix(checkIndex(i)))));
  137. }
  138. public ByteBuffer get(byte[] dst, int offset, int length) {
  139. if ((length << 0) > Bits.JNI_COPY_TO_ARRAY_THRESHOLD) {
  140. checkBounds(offset, length, dst.length);
  141. int pos = position();
  142. int lim = limit();
  143. assert (pos <= lim);
  144. int rem = (pos <= lim ? lim - pos : 0);
  145. if (length > rem)
  146. throw new BufferUnderflowException();
  147. if (order() != ByteOrder.nativeOrder())
  148. Bits.copyToByteArray(ix(pos), dst,
  149. offset << 0,
  150. length << 0);
  151. else
  152. Bits.copyToByteArray(ix(pos), dst,
  153. offset << 0,
  154. length << 0);
  155. position(pos + length);
  156. } else {
  157. super.get(dst, offset, length);
  158. }
  159. return this;
  160. }
  161. public ByteBuffer put(byte x) {
  162. unsafe.putByte(ix(nextPutIndex()), ((x)));
  163. return this;
  164. }
  165. public ByteBuffer put(int i, byte x) {
  166. unsafe.putByte(ix(checkIndex(i)), ((x)));
  167. return this;
  168. }
  169. public ByteBuffer put(ByteBuffer src) {
  170. if (src instanceof DirectByteBuffer) {
  171. if (src == this)
  172. throw new IllegalArgumentException();
  173. DirectByteBuffer sb = (DirectByteBuffer)src;
  174. int spos = sb.position();
  175. int slim = sb.limit();
  176. assert (spos <= slim);
  177. int srem = (spos <= slim ? slim - spos : 0);
  178. int pos = position();
  179. int lim = limit();
  180. assert (pos <= lim);
  181. int rem = (pos <= lim ? lim - pos : 0);
  182. if (srem > rem)
  183. throw new BufferOverflowException();
  184. unsafe.copyMemory(sb.ix(spos), ix(pos), srem << 0);
  185. sb.position(spos + srem);
  186. position(pos + srem);
  187. } else if (!src.isDirect()) {
  188. int spos = src.position();
  189. int slim = src.limit();
  190. assert (spos <= slim);
  191. int srem = (spos <= slim ? slim - spos : 0);
  192. put(src.hb, src.offset + spos, srem);
  193. src.position(spos + srem);
  194. } else {
  195. super.put(src);
  196. }
  197. return this;
  198. }
  199. public ByteBuffer put(byte[] src, int offset, int length) {
  200. if ((length << 0) > Bits.JNI_COPY_FROM_ARRAY_THRESHOLD) {
  201. checkBounds(offset, length, src.length);
  202. int pos = position();
  203. int lim = limit();
  204. assert (pos <= lim);
  205. int rem = (pos <= lim ? lim - pos : 0);
  206. if (length > rem)
  207. throw new BufferOverflowException();
  208. if (order() != ByteOrder.nativeOrder())
  209. Bits.copyFromByteArray(src, offset << 0,
  210. ix(pos), length << 0);
  211. else
  212. Bits.copyFromByteArray(src, offset << 0,
  213. ix(pos), length << 0);
  214. position(pos + length);
  215. } else {
  216. super.put(src, offset, length);
  217. }
  218. return this;
  219. }
  220. public ByteBuffer compact() {
  221. int pos = position();
  222. int lim = limit();
  223. assert (pos <= lim);
  224. int rem = (pos <= lim ? lim - pos : 0);
  225. unsafe.copyMemory(ix(pos), ix(0), rem << 0);
  226. position(rem);
  227. limit(capacity());
  228. return this;
  229. }
  230. public boolean isDirect() {
  231. return true;
  232. }
  233. public boolean isReadOnly() {
  234. return false;
  235. }
  236. byte _get(int i) { // package-private
  237. return unsafe.getByte(address + i);
  238. }
  239. void _put(int i, byte b) { // package-private
  240. unsafe.putByte(address + i, b);
  241. }
  242. private char getChar(long a) {
  243. if (unaligned) {
  244. char x = unsafe.getChar(a);
  245. return (nativeByteOrder ? x : Bits.swap(x));
  246. }
  247. return Bits.getChar(a, bigEndian);
  248. }
  249. public char getChar() {
  250. return getChar(ix(nextGetIndex((1 << 1))));
  251. }
  252. public char getChar(int i) {
  253. return getChar(ix(checkIndex(i, (1 << 1))));
  254. }
  255. private ByteBuffer putChar(long a, char x) {
  256. if (unaligned) {
  257. char y = (x);
  258. unsafe.putChar(a, (nativeByteOrder ? y : Bits.swap(y)));
  259. } else {
  260. Bits.putChar(a, x, bigEndian);
  261. }
  262. return this;
  263. }
  264. public ByteBuffer putChar(char x) {
  265. putChar(ix(nextPutIndex((1 << 1))), x);
  266. return this;
  267. }
  268. public ByteBuffer putChar(int i, char x) {
  269. putChar(ix(checkIndex(i, (1 << 1))), x);
  270. return this;
  271. }
  272. public CharBuffer asCharBuffer() {
  273. int off = this.position();
  274. int lim = this.limit();
  275. assert (off <= lim);
  276. int rem = (off <= lim ? lim - off : 0);
  277. int size = rem >> 1;
  278. if (!unaligned && ((address + off) % (1 << 1) != 0)) {
  279. return (bigEndian
  280. ? (CharBuffer)(new ByteBufferAsCharBufferB(this,
  281. -1,
  282. 0,
  283. size,
  284. size,
  285. off))
  286. : (CharBuffer)(new ByteBufferAsCharBufferL(this,
  287. -1,
  288. 0,
  289. size,
  290. size,
  291. off)));
  292. } else {
  293. return (nativeByteOrder
  294. ? (CharBuffer)(new DirectCharBufferU(this,
  295. -1,
  296. 0,
  297. size,
  298. size,
  299. off))
  300. : (CharBuffer)(new DirectCharBufferS(this,
  301. -1,
  302. 0,
  303. size,
  304. size,
  305. off)));
  306. }
  307. }
  308. private short getShort(long a) {
  309. if (unaligned) {
  310. short x = unsafe.getShort(a);
  311. return (nativeByteOrder ? x : Bits.swap(x));
  312. }
  313. return Bits.getShort(a, bigEndian);
  314. }
  315. public short getShort() {
  316. return getShort(ix(nextGetIndex((1 << 1))));
  317. }
  318. public short getShort(int i) {
  319. return getShort(ix(checkIndex(i, (1 << 1))));
  320. }
  321. private ByteBuffer putShort(long a, short x) {
  322. if (unaligned) {
  323. short y = (x);
  324. unsafe.putShort(a, (nativeByteOrder ? y : Bits.swap(y)));
  325. } else {
  326. Bits.putShort(a, x, bigEndian);
  327. }
  328. return this;
  329. }
  330. public ByteBuffer putShort(short x) {
  331. putShort(ix(nextPutIndex((1 << 1))), x);
  332. return this;
  333. }
  334. public ByteBuffer putShort(int i, short x) {
  335. putShort(ix(checkIndex(i, (1 << 1))), x);
  336. return this;
  337. }
  338. public ShortBuffer asShortBuffer() {
  339. int off = this.position();
  340. int lim = this.limit();
  341. assert (off <= lim);
  342. int rem = (off <= lim ? lim - off : 0);
  343. int size = rem >> 1;
  344. if (!unaligned && ((address + off) % (1 << 1) != 0)) {
  345. return (bigEndian
  346. ? (ShortBuffer)(new ByteBufferAsShortBufferB(this,
  347. -1,
  348. 0,
  349. size,
  350. size,
  351. off))
  352. : (ShortBuffer)(new ByteBufferAsShortBufferL(this,
  353. -1,
  354. 0,
  355. size,
  356. size,
  357. off)));
  358. } else {
  359. return (nativeByteOrder
  360. ? (ShortBuffer)(new DirectShortBufferU(this,
  361. -1,
  362. 0,
  363. size,
  364. size,
  365. off))
  366. : (ShortBuffer)(new DirectShortBufferS(this,
  367. -1,
  368. 0,
  369. size,
  370. size,
  371. off)));
  372. }
  373. }
  374. private int getInt(long a) {
  375. if (unaligned) {
  376. int x = unsafe.getInt(a);
  377. return (nativeByteOrder ? x : Bits.swap(x));
  378. }
  379. return Bits.getInt(a, bigEndian);
  380. }
  381. public int getInt() {
  382. return getInt(ix(nextGetIndex((1 << 2))));
  383. }
  384. public int getInt(int i) {
  385. return getInt(ix(checkIndex(i, (1 << 2))));
  386. }
  387. private ByteBuffer putInt(long a, int x) {
  388. if (unaligned) {
  389. int y = (x);
  390. unsafe.putInt(a, (nativeByteOrder ? y : Bits.swap(y)));
  391. } else {
  392. Bits.putInt(a, x, bigEndian);
  393. }
  394. return this;
  395. }
  396. public ByteBuffer putInt(int x) {
  397. putInt(ix(nextPutIndex((1 << 2))), x);
  398. return this;
  399. }
  400. public ByteBuffer putInt(int i, int x) {
  401. putInt(ix(checkIndex(i, (1 << 2))), x);
  402. return this;
  403. }
  404. public IntBuffer asIntBuffer() {
  405. int off = this.position();
  406. int lim = this.limit();
  407. assert (off <= lim);
  408. int rem = (off <= lim ? lim - off : 0);
  409. int size = rem >> 2;
  410. if (!unaligned && ((address + off) % (1 << 2) != 0)) {
  411. return (bigEndian
  412. ? (IntBuffer)(new ByteBufferAsIntBufferB(this,
  413. -1,
  414. 0,
  415. size,
  416. size,
  417. off))
  418. : (IntBuffer)(new ByteBufferAsIntBufferL(this,
  419. -1,
  420. 0,
  421. size,
  422. size,
  423. off)));
  424. } else {
  425. return (nativeByteOrder
  426. ? (IntBuffer)(new DirectIntBufferU(this,
  427. -1,
  428. 0,
  429. size,
  430. size,
  431. off))
  432. : (IntBuffer)(new DirectIntBufferS(this,
  433. -1,
  434. 0,
  435. size,
  436. size,
  437. off)));
  438. }
  439. }
  440. private long getLong(long a) {
  441. if (unaligned) {
  442. long x = unsafe.getLong(a);
  443. return (nativeByteOrder ? x : Bits.swap(x));
  444. }
  445. return Bits.getLong(a, bigEndian);
  446. }
  447. public long getLong() {
  448. return getLong(ix(nextGetIndex((1 << 3))));
  449. }
  450. public long getLong(int i) {
  451. return getLong(ix(checkIndex(i, (1 << 3))));
  452. }
  453. private ByteBuffer putLong(long a, long x) {
  454. if (unaligned) {
  455. long y = (x);
  456. unsafe.putLong(a, (nativeByteOrder ? y : Bits.swap(y)));
  457. } else {
  458. Bits.putLong(a, x, bigEndian);
  459. }
  460. return this;
  461. }
  462. public ByteBuffer putLong(long x) {
  463. putLong(ix(nextPutIndex((1 << 3))), x);
  464. return this;
  465. }
  466. public ByteBuffer putLong(int i, long x) {
  467. putLong(ix(checkIndex(i, (1 << 3))), x);
  468. return this;
  469. }
  470. public LongBuffer asLongBuffer() {
  471. int off = this.position();
  472. int lim = this.limit();
  473. assert (off <= lim);
  474. int rem = (off <= lim ? lim - off : 0);
  475. int size = rem >> 3;
  476. if (!unaligned && ((address + off) % (1 << 3) != 0)) {
  477. return (bigEndian
  478. ? (LongBuffer)(new ByteBufferAsLongBufferB(this,
  479. -1,
  480. 0,
  481. size,
  482. size,
  483. off))
  484. : (LongBuffer)(new ByteBufferAsLongBufferL(this,
  485. -1,
  486. 0,
  487. size,
  488. size,
  489. off)));
  490. } else {
  491. return (nativeByteOrder
  492. ? (LongBuffer)(new DirectLongBufferU(this,
  493. -1,
  494. 0,
  495. size,
  496. size,
  497. off))
  498. : (LongBuffer)(new DirectLongBufferS(this,
  499. -1,
  500. 0,
  501. size,
  502. size,
  503. off)));
  504. }
  505. }
  506. private float getFloat(long a) {
  507. if (unaligned) {
  508. int x = unsafe.getInt(a);
  509. return Float.intBitsToFloat(nativeByteOrder ? x : Bits.swap(x));
  510. }
  511. return Bits.getFloat(a, bigEndian);
  512. }
  513. public float getFloat() {
  514. return getFloat(ix(nextGetIndex((1 << 2))));
  515. }
  516. public float getFloat(int i) {
  517. return getFloat(ix(checkIndex(i, (1 << 2))));
  518. }
  519. private ByteBuffer putFloat(long a, float x) {
  520. if (unaligned) {
  521. int y = Float.floatToRawIntBits(x);
  522. unsafe.putInt(a, (nativeByteOrder ? y : Bits.swap(y)));
  523. } else {
  524. Bits.putFloat(a, x, bigEndian);
  525. }
  526. return this;
  527. }
  528. public ByteBuffer putFloat(float x) {
  529. putFloat(ix(nextPutIndex((1 << 2))), x);
  530. return this;
  531. }
  532. public ByteBuffer putFloat(int i, float x) {
  533. putFloat(ix(checkIndex(i, (1 << 2))), x);
  534. return this;
  535. }
  536. public FloatBuffer asFloatBuffer() {
  537. int off = this.position();
  538. int lim = this.limit();
  539. assert (off <= lim);
  540. int rem = (off <= lim ? lim - off : 0);
  541. int size = rem >> 2;
  542. if (!unaligned && ((address + off) % (1 << 2) != 0)) {
  543. return (bigEndian
  544. ? (FloatBuffer)(new ByteBufferAsFloatBufferB(this,
  545. -1,
  546. 0,
  547. size,
  548. size,
  549. off))
  550. : (FloatBuffer)(new ByteBufferAsFloatBufferL(this,
  551. -1,
  552. 0,
  553. size,
  554. size,
  555. off)));
  556. } else {
  557. return (nativeByteOrder
  558. ? (FloatBuffer)(new DirectFloatBufferU(this,
  559. -1,
  560. 0,
  561. size,
  562. size,
  563. off))
  564. : (FloatBuffer)(new DirectFloatBufferS(this,
  565. -1,
  566. 0,
  567. size,
  568. size,
  569. off)));
  570. }
  571. }
  572. private double getDouble(long a) {
  573. if (unaligned) {
  574. long x = unsafe.getLong(a);
  575. return Double.longBitsToDouble(nativeByteOrder ? x : Bits.swap(x));
  576. }
  577. return Bits.getDouble(a, bigEndian);
  578. }
  579. public double getDouble() {
  580. return getDouble(ix(nextGetIndex((1 << 3))));
  581. }
  582. public double getDouble(int i) {
  583. return getDouble(ix(checkIndex(i, (1 << 3))));
  584. }
  585. private ByteBuffer putDouble(long a, double x) {
  586. if (unaligned) {
  587. long y = Double.doubleToRawLongBits(x);
  588. unsafe.putLong(a, (nativeByteOrder ? y : Bits.swap(y)));
  589. } else {
  590. Bits.putDouble(a, x, bigEndian);
  591. }
  592. return this;
  593. }
  594. public ByteBuffer putDouble(double x) {
  595. putDouble(ix(nextPutIndex((1 << 3))), x);
  596. return this;
  597. }
  598. public ByteBuffer putDouble(int i, double x) {
  599. putDouble(ix(checkIndex(i, (1 << 3))), x);
  600. return this;
  601. }
  602. public DoubleBuffer asDoubleBuffer() {
  603. int off = this.position();
  604. int lim = this.limit();
  605. assert (off <= lim);
  606. int rem = (off <= lim ? lim - off : 0);
  607. int size = rem >> 3;
  608. if (!unaligned && ((address + off) % (1 << 3) != 0)) {
  609. return (bigEndian
  610. ? (DoubleBuffer)(new ByteBufferAsDoubleBufferB(this,
  611. -1,
  612. 0,
  613. size,
  614. size,
  615. off))
  616. : (DoubleBuffer)(new ByteBufferAsDoubleBufferL(this,
  617. -1,
  618. 0,
  619. size,
  620. size,
  621. off)));
  622. } else {
  623. return (nativeByteOrder
  624. ? (DoubleBuffer)(new DirectDoubleBufferU(this,
  625. -1,
  626. 0,
  627. size,
  628. size,
  629. off))
  630. : (DoubleBuffer)(new DirectDoubleBufferS(this,
  631. -1,
  632. 0,
  633. size,
  634. size,
  635. off)));
  636. }
  637. }
  638. }