]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/i18n/unicode/sortkey.h
ICU-511.25.tar.gz
[apple/icu.git] / icuSources / i18n / unicode / sortkey.h
index 28fbfb0bb7212832f5a9c9731a0a88fdaeb51c40..94b459a0c4e9c3456ea31fc1cd551018eb6a5d3c 100644 (file)
@@ -1,29 +1,33 @@
 /*
-* Copyright (C) {1996-2003}, International Business Machines Corporation and others. All Rights Reserved.
-*****************************************************************************************
-*/
-//===============================================================================
-//
-// File sortkey.h
-//
-//
-//
-// Created by: Helena Shih
-//
-// Modification History:
-//
-//  Date         Name          Description
-//
-//  6/20/97     helena      Java class name change.
-//  8/18/97     helena      Added internal API documentation.
-//  6/26/98     erm         Changed to use byte arrays and memcmp.
-//===============================================================================
+ *****************************************************************************
+ * Copyright (C) 1996-2013, International Business Machines Corporation and others.
+ * All Rights Reserved.
+ *****************************************************************************
+ *
+ * File sortkey.h
+ *
+ * Created by: Helena Shih
+ *
+ * Modification History:
+ *
+ *  Date         Name          Description
+ *
+ *  6/20/97     helena      Java class name change.
+ *  8/18/97     helena      Added internal API documentation.
+ *  6/26/98     erm         Changed to use byte arrays and memcmp.
+ *****************************************************************************
+ */
 
 #ifndef SORTKEY_H
 #define SORTKEY_H
 
 #include "unicode/utypes.h"
 
+/**
+ * \file 
+ * \brief C++ API: Keys for comparing strings multiple times. 
+ */
 #if !UCONFIG_NO_COLLATION
 
 #include "unicode/uobject.h"
@@ -36,6 +40,7 @@ U_NAMESPACE_BEGIN
 class RuleBasedCollator;
 
 /**
+ *
  * Collation keys are generated by the Collator class.  Use the CollationKey objects
  * instead of Collator to compare strings multiple times.  A CollationKey
  * preprocesses the comparison information from the Collator object to
@@ -86,6 +91,7 @@ class RuleBasedCollator;
  * @see          RuleBasedCollator
  * @version      1.3 12/18/96
  * @author       Helena Shih
+ * @stable ICU 2.0
  */
 class U_I18N_API CollationKey : public UObject {
 public:
@@ -103,7 +109,6 @@ public:
     * Creates a collation key based on the collation key values.
     * @param values the collation key values
     * @param count number of collation key values, including trailing nulls.
-    * @see #createBits
     * @stable ICU 2.0
     */
     CollationKey(const  uint8_t*    values,
@@ -120,7 +125,7 @@ public:
     * Sort key destructor.
     * @stable ICU 2.0
     */
-    ~CollationKey();
+    virtual ~CollationKey();
 
     /**
     * Assignment operator
@@ -176,6 +181,7 @@ public:
     uint8_t*                toByteArray(int32_t& count) const;
 #endif
 
+#ifndef U_HIDE_DEPRECATED_API 
     /**
     * Convenience method which does a string(bit-wise) comparison of the
     * two collation keys.
@@ -186,6 +192,7 @@ public:
     * @deprecated ICU 2.6 use the overload with error code
     */
     Collator::EComparisonResult compareTo(const CollationKey& target) const;
+#endif  /* U_HIDE_DEPRECATED_API */
 
     /**
     * Convenience method which does a string(bit-wise) comparison of the
@@ -195,7 +202,7 @@ public:
     * @return Returns UCOL_LESS if sourceKey < targetKey,
     * UCOL_GREATER if sourceKey > targetKey and UCOL_EQUAL
     * otherwise.
-    * @draft ICU 2.6
+    * @stable ICU 2.6
     */
     UCollationResult compareTo(const CollationKey& target, UErrorCode &status) const;
 
@@ -223,91 +230,87 @@ public:
 
     /**
      * ICU "poor man's RTTI", returns a UClassID for the actual class.
-     *
-     * @draft ICU 2.2
+     * @stable ICU 2.2
      */
-    virtual inline UClassID getDynamicClassID() const;
+    virtual UClassID getDynamicClassID() const;
 
     /**
      * ICU "poor man's RTTI", returns a UClassID for this class.
-     *
-     * @draft ICU 2.2
+     * @stable ICU 2.2
      */
-    static inline UClassID getStaticClassID();
+    static UClassID U_EXPORT2 getStaticClassID();
 
 private:
     /**
-    * Returns an array of the collation key values as 16-bit integers.
-    * The caller owns the storage and must delete it.
-    * @param values Output param of the collation key values.
-    * @param count output parameter of the number of collation key values
-    * @return a pointer to an array of 16-bit collation key values.
-    */
-    void adopt(uint8_t *values, int32_t count);
+     * Replaces the current bytes buffer with a new one of newCapacity
+     * and copies length bytes from the old buffer to the new one.
+     * @return the new buffer, or NULL if the allocation failed
+     */
+    uint8_t *reallocate(int32_t newCapacity, int32_t length);
+    /**
+     * Set a new length for a new sort key in the existing fBytes.
+     */
+    void setLength(int32_t newLength);
+
+    uint8_t *getBytes() {
+        return (fFlagAndLength >= 0) ? fUnion.fStackBuffer : fUnion.fFields.fBytes;
+    }
+    const uint8_t *getBytes() const {
+        return (fFlagAndLength >= 0) ? fUnion.fStackBuffer : fUnion.fFields.fBytes;
+    }
+    int32_t getCapacity() const {
+        return (fFlagAndLength >= 0) ? (int32_t)sizeof(fUnion) : fUnion.fFields.fCapacity;
+    }
+    int32_t getLength() const { return fFlagAndLength & 0x7fffffff; }
 
-    /*
-    * Creates a collation key with a string.
+    /**
+    * Set the CollationKey to a "bogus" or invalid state
+    * @return this CollationKey
     */
-
-       /**
-       * If this CollationKey has capacity less than newSize,
-       * its internal capacity will be increased to newSize.
-       * @param newSize minimum size this CollationKey has to have
-       * @return this CollationKey
-       */
-    CollationKey&           ensureCapacity(int32_t newSize);
-       /**
-       * Set the CollationKey to a "bogus" or invalid state
-       * @return this CollationKey
-       */
     CollationKey&           setToBogus(void);
-       /**
-       * Resets this CollationKey to an empty state
-       * @return this CollationKey
-       */
+    /**
+    * Resets this CollationKey to an empty state
+    * @return this CollationKey
+    */
     CollationKey&           reset(void);
-       
-       /**
-       * Allow private access to RuleBasedCollator
-       */
+
+    /**
+    * Allow private access to RuleBasedCollator
+    */
     friend  class           RuleBasedCollator;
-       /**
-       * Bogus status
-       */
-    UBool                   fBogus;
-       /**
-       * Size of fBytes used to store the sortkey. i.e. up till the 
-       * null-termination.
-       */
-    int32_t                 fCount;
-       /**
-       * Full size of the fBytes
-       */
-    int32_t                 fCapacity;
-       /**
-       * Unique hash value of this CollationKey
-       */
-    int32_t                 fHashCode;
-       /**
-       * Array to store the sortkey
-       */
-    uint8_t*                fBytes;
+    friend  class           CollationKeyByteSink;
+
+    // Class fields. sizeof(CollationKey) is intended to be 48 bytes
+    // on a machine with 64-bit pointers.
+    // We use a union to maximize the size of the internal buffer,
+    // similar to UnicodeString but not as tight and complex.
 
+    // (implicit) *vtable;
     /**
-     * The address of this static class variable serves as this class's ID
-     * for ICU "poor man's RTTI".
+     * Sort key length and flag.
+     * Bit 31 is set if the buffer is heap-allocated.
+     * Bits 30..0 contain the sort key length.
      */
-    static const char fgClassID;
+    int32_t fFlagAndLength;
+    /**
+    * Unique hash value of this CollationKey.
+    * Special value 2 if the key is bogus.
+    */
+    mutable int32_t fHashCode;
+    /**
+     * fUnion provides 32 bytes for the internal buffer or for
+     * pointer+capacity.
+     */
+    union StackBufferOrFields {
+        /** fStackBuffer is used iff fFlagAndLength>=0, else fFields is used */
+        uint8_t fStackBuffer[32];
+        struct {
+            uint8_t *fBytes;
+            int32_t fCapacity;
+        } fFields;
+    } fUnion;
 };
 
-inline UClassID
-CollationKey::getStaticClassID()
-{ return (UClassID)&fgClassID; }
-
-inline UClassID
-CollationKey::getDynamicClassID() const
-{ return CollationKey::getStaticClassID(); }
-
 inline UBool
 CollationKey::operator!=(const CollationKey& other) const
 {
@@ -317,14 +320,14 @@ CollationKey::operator!=(const CollationKey& other) const
 inline UBool
 CollationKey::isBogus() const
 {
-    return fBogus;
+    return fHashCode == 2;  // kBogusHashCode
 }
 
 inline const uint8_t*
 CollationKey::getByteArray(int32_t &count) const
 {
-    count = fCount;
-    return fBytes;
+    count = getLength();
+    return getBytes();
 }
 
 U_NAMESPACE_END