PageRenderTime 57ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/src/main/java/com/alibaba/fastjson/asm/ByteVector.java

https://bitbucket.org/xiejuntao/xdesktop
Java | 223 lines | 104 code | 13 blank | 106 comment | 13 complexity | 3ab003f0ec4ec349b0df840dd08d69de MD5 | raw file
  1. /***
  2. * ASM: a very small and fast Java bytecode manipulation framework
  3. * Copyright (c) 2000-2007 INRIA, France Telecom
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * 3. Neither the name of the copyright holders nor the names of its
  15. * contributors may be used to endorse or promote products derived from
  16. * this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  19. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  20. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  21. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  22. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  23. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  24. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  25. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  26. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  27. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  28. * THE POSSIBILITY OF SUCH DAMAGE.
  29. */
  30. package com.alibaba.fastjson.asm;
  31. /**
  32. * A dynamically extensible vector of bytes. This class is roughly equivalent to a DataOutputStream on top of a
  33. * ByteArrayOutputStream, but is more efficient.
  34. *
  35. * @author Eric Bruneton
  36. */
  37. public class ByteVector {
  38. /**
  39. * The content of this vector.
  40. */
  41. byte[] data;
  42. /**
  43. * Actual number of bytes in this vector.
  44. */
  45. int length;
  46. /**
  47. * Constructs a new {@link ByteVector ByteVector} with a default initial size.
  48. */
  49. public ByteVector(){
  50. data = new byte[64];
  51. }
  52. /**
  53. * Constructs a new {@link ByteVector ByteVector} with the given initial size.
  54. *
  55. * @param initialSize the initial size of the byte vector to be constructed.
  56. */
  57. public ByteVector(final int initialSize){
  58. data = new byte[initialSize];
  59. }
  60. /**
  61. * Puts a byte into this byte vector. The byte vector is automatically enlarged if necessary.
  62. *
  63. * @param b a byte.
  64. * @return this byte vector.
  65. */
  66. public ByteVector putByte(final int b) {
  67. int length = this.length;
  68. if (length + 1 > data.length) {
  69. enlarge(1);
  70. }
  71. data[length++] = (byte) b;
  72. this.length = length;
  73. return this;
  74. }
  75. /**
  76. * Puts two bytes into this byte vector. The byte vector is automatically enlarged if necessary.
  77. *
  78. * @param b1 a byte.
  79. * @param b2 another byte.
  80. * @return this byte vector.
  81. */
  82. ByteVector put11(final int b1, final int b2) {
  83. int length = this.length;
  84. if (length + 2 > data.length) {
  85. enlarge(2);
  86. }
  87. byte[] data = this.data;
  88. data[length++] = (byte) b1;
  89. data[length++] = (byte) b2;
  90. this.length = length;
  91. return this;
  92. }
  93. /**
  94. * Puts a short into this byte vector. The byte vector is automatically enlarged if necessary.
  95. *
  96. * @param s a short.
  97. * @return this byte vector.
  98. */
  99. public ByteVector putShort(final int s) {
  100. int length = this.length;
  101. if (length + 2 > data.length) {
  102. enlarge(2);
  103. }
  104. byte[] data = this.data;
  105. data[length++] = (byte) (s >>> 8);
  106. data[length++] = (byte) s;
  107. this.length = length;
  108. return this;
  109. }
  110. /**
  111. * Puts a byte and a short into this byte vector. The byte vector is automatically enlarged if necessary.
  112. *
  113. * @param b a byte.
  114. * @param s a short.
  115. * @return this byte vector.
  116. */
  117. ByteVector put12(final int b, final int s) {
  118. int length = this.length;
  119. if (length + 3 > data.length) {
  120. enlarge(3);
  121. }
  122. byte[] data = this.data;
  123. data[length++] = (byte) b;
  124. data[length++] = (byte) (s >>> 8);
  125. data[length++] = (byte) s;
  126. this.length = length;
  127. return this;
  128. }
  129. /**
  130. * Puts an int into this byte vector. The byte vector is automatically enlarged if necessary.
  131. *
  132. * @param i an int.
  133. * @return this byte vector.
  134. */
  135. public ByteVector putInt(final int i) {
  136. int length = this.length;
  137. if (length + 4 > data.length) {
  138. enlarge(4);
  139. }
  140. byte[] data = this.data;
  141. data[length++] = (byte) (i >>> 24);
  142. data[length++] = (byte) (i >>> 16);
  143. data[length++] = (byte) (i >>> 8);
  144. data[length++] = (byte) i;
  145. this.length = length;
  146. return this;
  147. }
  148. /**
  149. * Puts an UTF8 string into this byte vector. The byte vector is automatically enlarged if necessary.
  150. *
  151. * @param s a String.
  152. * @return this byte vector.
  153. */
  154. public ByteVector putUTF8(final String s) {
  155. int charLength = s.length();
  156. int len = length;
  157. if (len + 2 + charLength > data.length) {
  158. enlarge(2 + charLength);
  159. }
  160. byte[] data = this.data;
  161. // optimistic algorithm: instead of computing the byte length and then
  162. // serializing the string (which requires two loops), we assume the byte
  163. // length is equal to char length (which is the most frequent case), and
  164. // we start serializing the string right away. During the serialization,
  165. // if we find that this assumption is wrong, we continue with the
  166. // general method.
  167. data[len++] = (byte) (charLength >>> 8);
  168. data[len++] = (byte) charLength;
  169. for (int i = 0; i < charLength; ++i) {
  170. char c = s.charAt(i);
  171. if (c >= '\001' && c <= '\177') {
  172. data[len++] = (byte) c;
  173. } else {
  174. throw new UnsupportedOperationException();
  175. }
  176. }
  177. length = len;
  178. return this;
  179. }
  180. /**
  181. * Puts an array of bytes into this byte vector. The byte vector is automatically enlarged if necessary.
  182. *
  183. * @param b an array of bytes. May be <tt>null</tt> to put <tt>len</tt> null bytes into this byte vector.
  184. * @param off index of the fist byte of b that must be copied.
  185. * @param len number of bytes of b that must be copied.
  186. * @return this byte vector.
  187. */
  188. public ByteVector putByteArray(final byte[] b, final int off, final int len) {
  189. if (length + len > data.length) {
  190. enlarge(len);
  191. }
  192. if (b != null) {
  193. System.arraycopy(b, off, data, length, len);
  194. }
  195. length += len;
  196. return this;
  197. }
  198. /**
  199. * Enlarge this byte vector so that it can receive n more bytes.
  200. *
  201. * @param size number of additional bytes that this byte vector should be able to receive.
  202. */
  203. private void enlarge(final int size) {
  204. int length1 = 2 * data.length;
  205. int length2 = length + size;
  206. byte[] newData = new byte[length1 > length2 ? length1 : length2];
  207. System.arraycopy(data, 0, newData, 0, length);
  208. data = newData;
  209. }
  210. }