You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ri...@apache.org on 2008/02/25 04:22:42 UTC
svn commit: r630723 - in /incubator/qpid/branches/M2.1/java/common/src:
main/java/org/apache/qpid/framing/AMQShortString.java
test/java/org/apache/qpid/framing/AMQShortStringTest.java
Author: ritchiem
Date: Sun Feb 24 19:22:39 2008
New Revision: 630723
URL: http://svn.apache.org/viewvc?rev=630723&view=rev
Log:
QPID-806 : Added startsWith and endsWith methods to AMQShortString, including test.
Added:
incubator/qpid/branches/M2.1/java/common/src/test/java/org/apache/qpid/framing/AMQShortStringTest.java
Modified:
incubator/qpid/branches/M2.1/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java
Modified: incubator/qpid/branches/M2.1/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/M2.1/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java?rev=630723&r1=630722&r2=630723&view=diff
==============================================================================
--- incubator/qpid/branches/M2.1/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java (original)
+++ incubator/qpid/branches/M2.1/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java Sun Feb 24 19:22:39 2008
@@ -1,620 +1,692 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-package org.apache.qpid.framing;
-
-import org.apache.mina.common.ByteBuffer;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.*;
-import java.lang.ref.WeakReference;
-
-/**
- * A short string is a representation of an AMQ Short String
- * Short strings differ from the Java String class by being limited to on ASCII characters (0-127)
- * and thus can be held more effectively in a byte buffer.
- *
- */
-public final class AMQShortString implements CharSequence, Comparable<AMQShortString>
-{
- private static final byte MINUS = (byte)'-';
- private static final byte ZERO = (byte) '0';
-
-
-
- private final class TokenizerImpl implements AMQShortStringTokenizer
- {
- private final byte _delim;
- private int _count = -1;
- private int _pos = 0;
-
- public TokenizerImpl(final byte delim)
- {
- _delim = delim;
- }
-
- public int countTokens()
- {
- if(_count == -1)
- {
- _count = 1 + AMQShortString.this.occurences(_delim);
- }
- return _count;
- }
-
- public AMQShortString nextToken()
- {
- if(_pos <= AMQShortString.this.length())
- {
- int nextDelim = AMQShortString.this.indexOf(_delim, _pos);
- if(nextDelim == -1)
- {
- nextDelim = AMQShortString.this.length();
- }
-
- AMQShortString nextToken = AMQShortString.this.substring(_pos, nextDelim++);
- _pos = nextDelim;
- return nextToken;
- }
- else
- {
- return null;
- }
- }
-
- public boolean hasMoreTokens()
- {
- return _pos <= AMQShortString.this.length();
- }
- }
-
- private AMQShortString substring(final int from, final int to)
- {
- return new AMQShortString(_data, from, to);
- }
-
-
- private static final ThreadLocal<Map<AMQShortString, WeakReference<AMQShortString>>> _localInternMap =
- new ThreadLocal<Map<AMQShortString, WeakReference<AMQShortString>>>()
- {
- protected Map<AMQShortString, WeakReference<AMQShortString>> initialValue()
- {
- return new WeakHashMap<AMQShortString, WeakReference<AMQShortString>>();
- };
- };
-
- private static final Map<AMQShortString, WeakReference<AMQShortString>> _globalInternMap =
- new WeakHashMap<AMQShortString, WeakReference<AMQShortString>>();
-
- private static final Logger _logger = LoggerFactory.getLogger(AMQShortString.class);
-
- private final byte[] _data;
- private final int _offset;
- private int _hashCode;
- private final int _length;
- private static final char[] EMPTY_CHAR_ARRAY = new char[0];
-
- public static final AMQShortString EMPTY_STRING = new AMQShortString((String)null);
-
- public AMQShortString(byte[] data)
- {
-
- _data = data.clone();
- _length = data.length;
- _offset = 0;
- }
-
- public AMQShortString(byte[] data, int pos)
- {
- final int size = data[pos++];
- final byte[] dataCopy = new byte[size];
- System.arraycopy(data,pos,dataCopy,0,size);
- _length = size;
- _data = dataCopy;
- _offset = 0;
- }
-
- public AMQShortString(String data)
- {
- this((data == null) ? EMPTY_CHAR_ARRAY : data.toCharArray());
-
- }
-
- public AMQShortString(char[] data)
- {
- if (data == null)
- {
- throw new NullPointerException("Cannot create AMQShortString with null char[]");
- }
-
- final int length = data.length;
- final byte[] stringBytes = new byte[length];
- int hash = 0;
- for (int i = 0; i < length; i++)
- {
- stringBytes[i] = (byte) (0xFF & data[i]);
- hash = (31 * hash) + stringBytes[i];
- }
- _hashCode = hash;
- _data = stringBytes;
-
- _length = length;
- _offset = 0;
-
- }
-
- public AMQShortString(CharSequence charSequence)
- {
- final int length = charSequence.length();
- final byte[] stringBytes = new byte[length];
- int hash = 0;
- for (int i = 0; i < length; i++)
- {
- stringBytes[i] = ((byte) (0xFF & charSequence.charAt(i)));
- hash = (31 * hash) + stringBytes[i];
-
- }
-
- _data = stringBytes;
- _hashCode = hash;
- _length = length;
- _offset = 0;
-
- }
-
- private AMQShortString(ByteBuffer data, final int length)
- {
- byte[] dataBytes = new byte[length];
- data.get(dataBytes);
- _data = dataBytes;
- _length = length;
- _offset = 0;
-
- }
-
- private AMQShortString(final byte[] data, final int from, final int to)
- {
- _offset = from;
- _length = to - from;
- _data = data;
- }
-
-
- /**
- * Get the length of the short string
- * @return length of the underlying byte array
- */
- public int length()
- {
- return _length;
- }
-
- public char charAt(int index)
- {
-
- return (char) _data[_offset + index];
-
- }
-
- public CharSequence subSequence(int start, int end)
- {
- return new CharSubSequence(start, end);
- }
-
- public int writeToByteArray(byte[] encoding, int pos)
- {
- final int size = length();
- encoding[pos++] = (byte) size;
- System.arraycopy(_data,_offset,encoding,pos,size);
- return pos+size;
- }
-
- public static AMQShortString readFromByteArray(byte[] byteEncodedDestination, int pos)
- {
-
-
- final AMQShortString shortString = new AMQShortString(byteEncodedDestination, pos);
- if(shortString.length() == 0)
- {
- return null;
- }
- else
- {
- return shortString;
- }
- }
-
- public static AMQShortString readFromBuffer(ByteBuffer buffer)
- {
- final short length = buffer.getUnsigned();
- if (length == 0)
- {
- return null;
- }
- else
- {
-
- return new AMQShortString(buffer, length);
- }
- }
-
- public byte[] getBytes()
- {
- if(_offset == 0 && _length == _data.length)
- {
- return _data.clone();
- }
- else
- {
- byte[] data = new byte[_length];
- System.arraycopy(_data,_offset,data,0,_length);
- return data;
- }
- }
-
- public void writeToBuffer(ByteBuffer buffer)
- {
-
- final int size = length();
- //buffer.setAutoExpand(true);
- buffer.put((byte) size);
- buffer.put(_data, _offset, size);
-
- }
-
- private final class CharSubSequence implements CharSequence
- {
- private final int _sequenceOffset;
- private final int _end;
-
- public CharSubSequence(final int offset, final int end)
- {
- _sequenceOffset = offset;
- _end = end;
- }
-
- public int length()
- {
- return _end - _sequenceOffset;
- }
-
- public char charAt(int index)
- {
- return AMQShortString.this.charAt(index + _sequenceOffset);
- }
-
- public CharSequence subSequence(int start, int end)
- {
- return new CharSubSequence(start + _sequenceOffset, end + _sequenceOffset);
- }
- }
-
- public char[] asChars()
- {
- final int size = length();
- final char[] chars = new char[size];
-
- for (int i = 0; i < size; i++)
- {
- chars[i] = (char) _data[i + _offset];
- }
-
- return chars;
- }
-
- public String asString()
- {
- return new String(asChars());
- }
-
- public boolean equals(Object o)
- {
-
-
- if(o instanceof AMQShortString)
- {
- return equals((AMQShortString)o);
- }
- if(o instanceof CharSequence)
- {
- return equals((CharSequence)o);
- }
-
- if (o == null)
- {
- return false;
- }
-
- if (o == this)
- {
- return true;
- }
-
-
- return false;
-
- }
-
- public boolean equals(final AMQShortString otherString)
- {
- if (otherString == this)
- {
- return true;
- }
-
- if (otherString == null)
- {
- return false;
- }
-
- if ((_hashCode != 0) && (otherString._hashCode != 0) && (_hashCode != otherString._hashCode))
- {
- return false;
- }
-
- return (_offset == 0 && otherString._offset == 0 && _length == _data.length && otherString._length == otherString._data.length && Arrays.equals(_data,otherString._data))
- || Arrays.equals(getBytes(),otherString.getBytes());
-
- }
-
- public boolean equals(CharSequence s)
- {
- if(s instanceof AMQShortString)
- {
- return equals((AMQShortString)s);
- }
-
- if (s == null)
- {
- return false;
- }
-
- if (s.length() != length())
- {
- return false;
- }
-
- for (int i = 0; i < length(); i++)
- {
- if (charAt(i) != s.charAt(i))
- {
- return false;
- }
- }
-
- return true;
- }
-
- public int hashCode()
- {
- int hash = _hashCode;
- if (hash == 0)
- {
- final int size = length();
-
- for (int i = 0; i < size; i++)
- {
- hash = (31 * hash) + _data[i+_offset];
- }
-
- _hashCode = hash;
- }
-
- return hash;
- }
-
- public void setDirty()
- {
- _hashCode = 0;
- }
-
- public String toString()
- {
- return asString();
- }
-
- public int compareTo(AMQShortString name)
- {
- if (name == null)
- {
- return 1;
- }
- else
- {
-
- if (name.length() < length())
- {
- return -name.compareTo(this);
- }
-
- for (int i = 0; i < length(); i++)
- {
- final byte d = _data[i+_offset];
- final byte n = name._data[i+name._offset];
- if (d < n)
- {
- return -1;
- }
-
- if (d > n)
- {
- return 1;
- }
- }
-
- return (length() == name.length()) ? 0 : -1;
- }
- }
-
-
- public AMQShortStringTokenizer tokenize(byte delim)
- {
- return new TokenizerImpl(delim);
- }
-
-
- public AMQShortString intern()
- {
-
- hashCode();
-
- Map<AMQShortString, WeakReference<AMQShortString>> localMap =
- _localInternMap.get();
-
- WeakReference<AMQShortString> ref = localMap.get(this);
- AMQShortString internString;
-
- if(ref != null)
- {
- internString = ref.get();
- if(internString != null)
- {
- return internString;
- }
- }
-
-
- synchronized(_globalInternMap)
- {
-
- ref = _globalInternMap.get(this);
- if((ref == null) || ((internString = ref.get()) == null))
- {
- internString = new AMQShortString(getBytes());
- ref = new WeakReference(internString);
- _globalInternMap.put(internString, ref);
- }
-
- }
- localMap.put(internString, ref);
- return internString;
-
- }
-
- private int occurences(final byte delim)
- {
- int count = 0;
- final int end = _offset + _length;
- for(int i = _offset ; i < end ; i++ )
- {
- if(_data[i] == delim)
- {
- count++;
- }
- }
- return count;
- }
-
- private int indexOf(final byte val, final int pos)
- {
-
- for(int i = pos; i < length(); i++)
- {
- if(_data[_offset+i] == val)
- {
- return i;
- }
- }
- return -1;
- }
-
-
- public static AMQShortString join(final Collection<AMQShortString> terms,
- final AMQShortString delim)
- {
- if(terms.size() == 0)
- {
- return EMPTY_STRING;
- }
-
- int size = delim.length() * (terms.size() - 1);
- for(AMQShortString term : terms)
- {
- size += term.length();
- }
-
- byte[] data = new byte[size];
- int pos = 0;
- final byte[] delimData = delim._data;
- final int delimOffset = delim._offset;
- final int delimLength = delim._length;
-
-
- for(AMQShortString term : terms)
- {
-
- if(pos!=0)
- {
- System.arraycopy(delimData, delimOffset,data,pos, delimLength);
- pos+=delimLength;
- }
- System.arraycopy(term._data,term._offset,data,pos,term._length);
- pos+=term._length;
- }
-
-
-
- return new AMQShortString(data,0,size);
- }
-
- public int toIntValue()
- {
- int pos = 0;
- int val = 0;
-
-
- boolean isNegative = (_data[pos] == MINUS);
- if(isNegative)
- {
- pos++;
- }
- while(pos < _length)
- {
- int digit = (int) (_data[pos++] - ZERO);
- if((digit < 0) || (digit > 9))
- {
- throw new NumberFormatException("\""+toString()+"\" is not a valid number");
- }
- val = val * 10;
- val += digit;
- }
- if(isNegative)
- {
- val = val * -1;
- }
- return val;
- }
-
- public boolean contains(final byte b)
- {
- for(int i = 0; i < _length; i++)
- {
- if(_data[i] == b)
- {
- return true;
- }
- }
- return false; //To change body of created methods use File | Settings | File Templates.
- }
-
-}
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.framing;
+
+import org.apache.mina.common.ByteBuffer;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.*;
+import java.lang.ref.WeakReference;
+
+/**
+ * A short string is a representation of an AMQ Short String
+ * Short strings differ from the Java String class by being limited to on ASCII characters (0-127)
+ * and thus can be held more effectively in a byte buffer.
+ *
+ */
+public final class AMQShortString implements CharSequence, Comparable<AMQShortString>
+{
+ private static final byte MINUS = (byte)'-';
+ private static final byte ZERO = (byte) '0';
+
+
+
+ private final class TokenizerImpl implements AMQShortStringTokenizer
+ {
+ private final byte _delim;
+ private int _count = -1;
+ private int _pos = 0;
+
+ public TokenizerImpl(final byte delim)
+ {
+ _delim = delim;
+ }
+
+ public int countTokens()
+ {
+ if(_count == -1)
+ {
+ _count = 1 + AMQShortString.this.occurences(_delim);
+ }
+ return _count;
+ }
+
+ public AMQShortString nextToken()
+ {
+ if(_pos <= AMQShortString.this.length())
+ {
+ int nextDelim = AMQShortString.this.indexOf(_delim, _pos);
+ if(nextDelim == -1)
+ {
+ nextDelim = AMQShortString.this.length();
+ }
+
+ AMQShortString nextToken = AMQShortString.this.substring(_pos, nextDelim++);
+ _pos = nextDelim;
+ return nextToken;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public boolean hasMoreTokens()
+ {
+ return _pos <= AMQShortString.this.length();
+ }
+ }
+
+ private AMQShortString substring(final int from, final int to)
+ {
+ return new AMQShortString(_data, from, to);
+ }
+
+
+ private static final ThreadLocal<Map<AMQShortString, WeakReference<AMQShortString>>> _localInternMap =
+ new ThreadLocal<Map<AMQShortString, WeakReference<AMQShortString>>>()
+ {
+ protected Map<AMQShortString, WeakReference<AMQShortString>> initialValue()
+ {
+ return new WeakHashMap<AMQShortString, WeakReference<AMQShortString>>();
+ };
+ };
+
+ private static final Map<AMQShortString, WeakReference<AMQShortString>> _globalInternMap =
+ new WeakHashMap<AMQShortString, WeakReference<AMQShortString>>();
+
+ private static final Logger _logger = LoggerFactory.getLogger(AMQShortString.class);
+
+ private final byte[] _data;
+ private final int _offset;
+ private int _hashCode;
+ private final int _length;
+ private static final char[] EMPTY_CHAR_ARRAY = new char[0];
+
+ public static final AMQShortString EMPTY_STRING = new AMQShortString((String)null);
+
+ public AMQShortString(byte[] data)
+ {
+
+ _data = data.clone();
+ _length = data.length;
+ _offset = 0;
+ }
+
+ public AMQShortString(byte[] data, int pos)
+ {
+ final int size = data[pos++];
+ final byte[] dataCopy = new byte[size];
+ System.arraycopy(data,pos,dataCopy,0,size);
+ _length = size;
+ _data = dataCopy;
+ _offset = 0;
+ }
+
+ public AMQShortString(String data)
+ {
+ this((data == null) ? EMPTY_CHAR_ARRAY : data.toCharArray());
+
+ }
+
+ public AMQShortString(char[] data)
+ {
+ if (data == null)
+ {
+ throw new NullPointerException("Cannot create AMQShortString with null char[]");
+ }
+
+ final int length = data.length;
+ final byte[] stringBytes = new byte[length];
+ int hash = 0;
+ for (int i = 0; i < length; i++)
+ {
+ stringBytes[i] = (byte) (0xFF & data[i]);
+ hash = (31 * hash) + stringBytes[i];
+ }
+ _hashCode = hash;
+ _data = stringBytes;
+
+ _length = length;
+ _offset = 0;
+
+ }
+
+ public AMQShortString(CharSequence charSequence)
+ {
+ final int length = charSequence.length();
+ final byte[] stringBytes = new byte[length];
+ int hash = 0;
+ for (int i = 0; i < length; i++)
+ {
+ stringBytes[i] = ((byte) (0xFF & charSequence.charAt(i)));
+ hash = (31 * hash) + stringBytes[i];
+
+ }
+
+ _data = stringBytes;
+ _hashCode = hash;
+ _length = length;
+ _offset = 0;
+
+ }
+
+ private AMQShortString(ByteBuffer data, final int length)
+ {
+ byte[] dataBytes = new byte[length];
+ data.get(dataBytes);
+ _data = dataBytes;
+ _length = length;
+ _offset = 0;
+
+ }
+
+ private AMQShortString(final byte[] data, final int from, final int to)
+ {
+ _offset = from;
+ _length = to - from;
+ _data = data;
+ }
+
+
+ /**
+ * Get the length of the short string
+ * @return length of the underlying byte array
+ */
+ public int length()
+ {
+ return _length;
+ }
+
+ public char charAt(int index)
+ {
+
+ return (char) _data[_offset + index];
+
+ }
+
+ public CharSequence subSequence(int start, int end)
+ {
+ return new CharSubSequence(start, end);
+ }
+
+ public int writeToByteArray(byte[] encoding, int pos)
+ {
+ final int size = length();
+ encoding[pos++] = (byte) size;
+ System.arraycopy(_data,_offset,encoding,pos,size);
+ return pos+size;
+ }
+
+ public static AMQShortString readFromByteArray(byte[] byteEncodedDestination, int pos)
+ {
+
+
+ final AMQShortString shortString = new AMQShortString(byteEncodedDestination, pos);
+ if(shortString.length() == 0)
+ {
+ return null;
+ }
+ else
+ {
+ return shortString;
+ }
+ }
+
+ public static AMQShortString readFromBuffer(ByteBuffer buffer)
+ {
+ final short length = buffer.getUnsigned();
+ if (length == 0)
+ {
+ return null;
+ }
+ else
+ {
+
+ return new AMQShortString(buffer, length);
+ }
+ }
+
+ public byte[] getBytes()
+ {
+ if(_offset == 0 && _length == _data.length)
+ {
+ return _data.clone();
+ }
+ else
+ {
+ byte[] data = new byte[_length];
+ System.arraycopy(_data,_offset,data,0,_length);
+ return data;
+ }
+ }
+
+ public void writeToBuffer(ByteBuffer buffer)
+ {
+
+ final int size = length();
+ //buffer.setAutoExpand(true);
+ buffer.put((byte) size);
+ buffer.put(_data, _offset, size);
+
+ }
+
+ public boolean endsWith(String s)
+ {
+ return endsWith(new AMQShortString(s));
+ }
+
+
+ public boolean endsWith(AMQShortString otherString)
+ {
+
+ if (otherString.length() > length())
+ {
+ return false;
+ }
+
+
+ int thisLength = length();
+ int otherLength = otherString.length();
+
+ for (int i = 1; i <= otherLength; i++)
+ {
+ if (charAt(thisLength - i) != otherString.charAt(otherLength - i))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public boolean startsWith(String s)
+ {
+ return startsWith(new AMQShortString(s));
+ }
+
+ public boolean startsWith(AMQShortString otherString)
+ {
+
+ if (otherString.length() > length())
+ {
+ return false;
+ }
+
+ for (int i = 0; i < otherString.length(); i++)
+ {
+ if (_data[i] != otherString._data[i])
+ {
+ return false;
+ }
+ }
+
+ return true;
+
+ }
+
+ public boolean startsWith(CharSequence otherString)
+ {
+ if (otherString.length() > length())
+ {
+ return false;
+ }
+
+ for (int i = 0; i < otherString.length(); i++)
+ {
+ if (charAt(i) != otherString.charAt(i))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+
+ private final class CharSubSequence implements CharSequence
+ {
+ private final int _sequenceOffset;
+ private final int _end;
+
+ public CharSubSequence(final int offset, final int end)
+ {
+ _sequenceOffset = offset;
+ _end = end;
+ }
+
+ public int length()
+ {
+ return _end - _sequenceOffset;
+ }
+
+ public char charAt(int index)
+ {
+ return AMQShortString.this.charAt(index + _sequenceOffset);
+ }
+
+ public CharSequence subSequence(int start, int end)
+ {
+ return new CharSubSequence(start + _sequenceOffset, end + _sequenceOffset);
+ }
+ }
+
+ public char[] asChars()
+ {
+ final int size = length();
+ final char[] chars = new char[size];
+
+ for (int i = 0; i < size; i++)
+ {
+ chars[i] = (char) _data[i + _offset];
+ }
+
+ return chars;
+ }
+
+ public String asString()
+ {
+ return new String(asChars());
+ }
+
+ public boolean equals(Object o)
+ {
+
+
+ if(o instanceof AMQShortString)
+ {
+ return equals((AMQShortString)o);
+ }
+ if(o instanceof CharSequence)
+ {
+ return equals((CharSequence)o);
+ }
+
+ if (o == null)
+ {
+ return false;
+ }
+
+ if (o == this)
+ {
+ return true;
+ }
+
+
+ return false;
+
+ }
+
+ public boolean equals(final AMQShortString otherString)
+ {
+ if (otherString == this)
+ {
+ return true;
+ }
+
+ if (otherString == null)
+ {
+ return false;
+ }
+
+ if ((_hashCode != 0) && (otherString._hashCode != 0) && (_hashCode != otherString._hashCode))
+ {
+ return false;
+ }
+
+ return (_offset == 0 && otherString._offset == 0 && _length == _data.length && otherString._length == otherString._data.length && Arrays.equals(_data,otherString._data))
+ || Arrays.equals(getBytes(),otherString.getBytes());
+
+ }
+
+ public boolean equals(CharSequence s)
+ {
+ if(s instanceof AMQShortString)
+ {
+ return equals((AMQShortString)s);
+ }
+
+ if (s == null)
+ {
+ return false;
+ }
+
+ if (s.length() != length())
+ {
+ return false;
+ }
+
+ for (int i = 0; i < length(); i++)
+ {
+ if (charAt(i) != s.charAt(i))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public int hashCode()
+ {
+ int hash = _hashCode;
+ if (hash == 0)
+ {
+ final int size = length();
+
+ for (int i = 0; i < size; i++)
+ {
+ hash = (31 * hash) + _data[i+_offset];
+ }
+
+ _hashCode = hash;
+ }
+
+ return hash;
+ }
+
+ public void setDirty()
+ {
+ _hashCode = 0;
+ }
+
+ public String toString()
+ {
+ return asString();
+ }
+
+ public int compareTo(AMQShortString name)
+ {
+ if (name == null)
+ {
+ return 1;
+ }
+ else
+ {
+
+ if (name.length() < length())
+ {
+ return -name.compareTo(this);
+ }
+
+ for (int i = 0; i < length(); i++)
+ {
+ final byte d = _data[i+_offset];
+ final byte n = name._data[i+name._offset];
+ if (d < n)
+ {
+ return -1;
+ }
+
+ if (d > n)
+ {
+ return 1;
+ }
+ }
+
+ return (length() == name.length()) ? 0 : -1;
+ }
+ }
+
+
+ public AMQShortStringTokenizer tokenize(byte delim)
+ {
+ return new TokenizerImpl(delim);
+ }
+
+
+ public AMQShortString intern()
+ {
+
+ hashCode();
+
+ Map<AMQShortString, WeakReference<AMQShortString>> localMap =
+ _localInternMap.get();
+
+ WeakReference<AMQShortString> ref = localMap.get(this);
+ AMQShortString internString;
+
+ if(ref != null)
+ {
+ internString = ref.get();
+ if(internString != null)
+ {
+ return internString;
+ }
+ }
+
+
+ synchronized(_globalInternMap)
+ {
+
+ ref = _globalInternMap.get(this);
+ if((ref == null) || ((internString = ref.get()) == null))
+ {
+ internString = new AMQShortString(getBytes());
+ ref = new WeakReference(internString);
+ _globalInternMap.put(internString, ref);
+ }
+
+ }
+ localMap.put(internString, ref);
+ return internString;
+
+ }
+
+ private int occurences(final byte delim)
+ {
+ int count = 0;
+ final int end = _offset + _length;
+ for(int i = _offset ; i < end ; i++ )
+ {
+ if(_data[i] == delim)
+ {
+ count++;
+ }
+ }
+ return count;
+ }
+
+ private int indexOf(final byte val, final int pos)
+ {
+
+ for(int i = pos; i < length(); i++)
+ {
+ if(_data[_offset+i] == val)
+ {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+
+ public static AMQShortString join(final Collection<AMQShortString> terms,
+ final AMQShortString delim)
+ {
+ if(terms.size() == 0)
+ {
+ return EMPTY_STRING;
+ }
+
+ int size = delim.length() * (terms.size() - 1);
+ for(AMQShortString term : terms)
+ {
+ size += term.length();
+ }
+
+ byte[] data = new byte[size];
+ int pos = 0;
+ final byte[] delimData = delim._data;
+ final int delimOffset = delim._offset;
+ final int delimLength = delim._length;
+
+
+ for(AMQShortString term : terms)
+ {
+
+ if(pos!=0)
+ {
+ System.arraycopy(delimData, delimOffset,data,pos, delimLength);
+ pos+=delimLength;
+ }
+ System.arraycopy(term._data,term._offset,data,pos,term._length);
+ pos+=term._length;
+ }
+
+
+
+ return new AMQShortString(data,0,size);
+ }
+
+ public int toIntValue()
+ {
+ int pos = 0;
+ int val = 0;
+
+
+ boolean isNegative = (_data[pos] == MINUS);
+ if(isNegative)
+ {
+ pos++;
+ }
+ while(pos < _length)
+ {
+ int digit = (int) (_data[pos++] - ZERO);
+ if((digit < 0) || (digit > 9))
+ {
+ throw new NumberFormatException("\""+toString()+"\" is not a valid number");
+ }
+ val = val * 10;
+ val += digit;
+ }
+ if(isNegative)
+ {
+ val = val * -1;
+ }
+ return val;
+ }
+
+ public boolean contains(final byte b)
+ {
+ for(int i = 0; i < _length; i++)
+ {
+ if(_data[i] == b)
+ {
+ return true;
+ }
+ }
+ return false; //To change body of created methods use File | Settings | File Templates.
+ }
+
+}
Added: incubator/qpid/branches/M2.1/java/common/src/test/java/org/apache/qpid/framing/AMQShortStringTest.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/M2.1/java/common/src/test/java/org/apache/qpid/framing/AMQShortStringTest.java?rev=630723&view=auto
==============================================================================
--- incubator/qpid/branches/M2.1/java/common/src/test/java/org/apache/qpid/framing/AMQShortStringTest.java (added)
+++ incubator/qpid/branches/M2.1/java/common/src/test/java/org/apache/qpid/framing/AMQShortStringTest.java Sun Feb 24 19:22:39 2008
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.framing;
+
+import junit.framework.TestCase;
+public class AMQShortStringTest extends TestCase
+{
+
+ AMQShortString Hello = new AMQShortString("Hello");
+ AMQShortString Hell = new AMQShortString("Hell");
+ AMQShortString Goodbye = new AMQShortString("Goodbye");
+ AMQShortString Good = new AMQShortString("Good");
+ AMQShortString Bye = new AMQShortString("Bye");
+
+ public void testStartsWith()
+ {
+ assertTrue(Hello.startsWith(Hell));
+
+ assertFalse(Hell.startsWith(Hello));
+
+ assertTrue(Goodbye.startsWith(Good));
+
+ assertFalse(Good.startsWith(Goodbye));
+ }
+
+ public void testEndWith()
+ {
+ assertFalse(Hell.endsWith(Hello));
+
+ assertTrue(Goodbye.endsWith(new AMQShortString("bye")));
+
+ assertFalse(Goodbye.endsWith(Bye));
+ }
+
+
+ public void testEquals()
+ {
+ assertEquals(Goodbye, new AMQShortString("Goodbye"));
+ assertEquals(new AMQShortString("A"), new AMQShortString("A"));
+ assertFalse(new AMQShortString("A").equals(new AMQShortString("a")));
+ }
+
+
+}