--- /dev/null
+/*\r
+ * Derby - class org.apache.derby.impl.drda.DRDAString\r
+ *\r
+ * Licensed to the Apache Software Foundation (ASF) under one or more\r
+ * contributor license agreements. See the NOTICE file distributed with\r
+ * this work for additional information regarding copyright ownership.\r
+ * The ASF licenses this file to You under the Apache License, Version 2.0\r
+ * (the "License"); you may not use this file except in compliance with\r
+ * the License. You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\r
+ * implied. See the License for the specific language governing\r
+ * permissions and limitations under the License.\r
+ *\r
+ */\r
+\r
+package org.apache.derby.impl.drda;\r
+\r
+/**\r
+ * This class provides functionality for reusing buffers and strings\r
+ * when parsing DRDA packets. A byte array representing a string is\r
+ * stored internally. When the string is requested as a\r
+ * <code>String</code> object, the byte array is converted to a\r
+ * string, and the string is cached to avoid unnecessary conversion\r
+ * later.\r
+ */\r
+final class DRDAString {\r
+ /** Buffer representing the string. */\r
+ private byte[] buffer;\r
+ /** Object used to convert byte buffer to string. */\r
+ private final CcsidManager ccsidManager;\r
+\r
+ /** True if the contents were modified in the previous call to\r
+ * <code>setBytes</code>. */\r
+ private boolean modified;\r
+\r
+ /** The previously generated string. */\r
+ private String cachedString;\r
+\r
+ /**\r
+ * Create a new <code>DRDAString</code> instance.\r
+ *\r
+ * @param m a <code>CcsidManager</code> value specifying\r
+ * which encoding is used\r
+ */\r
+ DRDAString(CcsidManager m) {\r
+ this.buffer = new byte[0];\r
+ this.ccsidManager = m;\r
+ this.cachedString = null;\r
+ }\r
+\r
+ /**\r
+ * Check whether the internal buffer contains the same data as\r
+ * another byte buffer.\r
+ *\r
+ * @param buf a byte array\r
+ * @param offset start position in the byte array\r
+ * @param size how many bytes to read from the byte array\r
+ * @return <code>true</code> if the internal buffer contains the\r
+ * same data as the specified byte array\r
+ */\r
+ private boolean equalTo(byte[] buf, int offset, int size) {\r
+ int len = buffer.length;\r
+ if (len != size) return false;\r
+ for (int i = 0; i < len; ++i) {\r
+ if (buffer[i] != buf[i+offset]) return false;\r
+ }\r
+ return true;\r
+ }\r
+\r
+ /**\r
+ * Modify the internal byte buffer. If the new data is equal to\r
+ * the old data, the cached values are not cleared.\r
+ *\r
+ * @param src the new bytes\r
+ * @param offset start offset\r
+ * @param size number of bytes to use\r
+ */\r
+ public void setBytes(byte[] src, int offset, int size) {\r
+ if (equalTo(src, offset, size)) {\r
+ modified = false;\r
+ return;\r
+ }\r
+ if (buffer.length != size) {\r
+ buffer = new byte[size];\r
+ }\r
+ System.arraycopy(src, offset, buffer, 0, size);\r
+ modified = true;\r
+ cachedString = null;\r
+ }\r
+\r
+ /**\r
+ * Check whether the contents of the <code>DRDAString</code> were\r
+ * modified in the previous call to <code>setBytes()</code>.\r
+ *\r
+ * @return <code>true</code> if the contents were modified\r
+ */\r
+ public boolean wasModified() {\r
+ return modified;\r
+ }\r
+\r
+ /**\r
+ * Convert the internal byte array to a string. The string value\r
+ * is cached.\r
+ *\r
+ * @return a <code>String</code> value\r
+ */\r
+ public String toString() {\r
+ if (cachedString == null) {\r
+ cachedString =\r
+ ccsidManager.convertToUCS2(buffer);\r
+ }\r
+ return cachedString;\r
+ }\r
+\r
+ /**\r
+ * Return the length in bytes of the internal string\r
+ * representation.\r
+ *\r
+ * @return length of internal representation\r
+ */\r
+ public int length() {\r
+ return buffer.length;\r
+ }\r
+\r
+ /**\r
+ * Return the internal byte array. The returned array should not\r
+ * be modified, as it is used internally in\r
+ * <code>DRDAString</code>. The value of the array might be\r
+ * modified by subsequent calls to\r
+ * <code>DRDAString.setBytes()</code>.\r
+ *\r
+ * @return internal buffer\r
+ */\r
+ public byte[] getBytes() {\r
+ return buffer;\r
+ }\r
+}\r