| #pragma once |
| |
| #ifndef GEODE_GFCPP_CACHEABLESTRING_H_ |
| #define GEODE_GFCPP_CACHEABLESTRING_H_ |
| |
| /* |
| * 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. |
| */ |
| |
| #include "gfcpp_globals.hpp" |
| #include "gf_types.hpp" |
| #include "CacheableKey.hpp" |
| #include "GeodeTypeIds.hpp" |
| #include "ExceptionTypes.hpp" |
| |
| /** @file |
| */ |
| |
| namespace apache { |
| namespace geode { |
| namespace client { |
| |
| #define GF_STRING (int8_t) GeodeTypeIds::CacheableASCIIString |
| #define GF_STRING_HUGE (int8_t) GeodeTypeIds::CacheableASCIIStringHuge |
| #define GF_WIDESTRING (int8_t) GeodeTypeIds::CacheableString |
| #define GF_WIDESTRING_HUGE (int8_t) GeodeTypeIds::CacheableStringHuge |
| |
| /** |
| * Implement a immutable C string wrapper that can serve as a distributable |
| * key object for caching as well as being a string value. |
| */ |
| class CPPCACHE_EXPORT CacheableString : public CacheableKey { |
| protected: |
| void* m_str; |
| int8_t m_type; |
| uint32_t m_len; |
| mutable int m_hashcode; |
| |
| public: |
| /** |
| *@brief serialize this object |
| **/ |
| virtual void toData(DataOutput& output) const; |
| |
| /** |
| *@brief deserialize this object |
| * Throw IllegalArgumentException if the packed CacheableString is not less |
| * than 64K bytes. |
| **/ |
| virtual Serializable* fromData(DataInput& input); |
| |
| /** creation function for strings */ |
| static Serializable* createDeserializable(); |
| |
| /** creation function for strings > 64K length */ |
| static Serializable* createDeserializableHuge(); |
| |
| /** creation function for wide strings */ |
| static Serializable* createUTFDeserializable(); |
| |
| /** creation function for wide strings > 64K length in UTF8 encoding */ |
| static Serializable* createUTFDeserializableHuge(); |
| |
| /** |
| *@brief Return the classId of the instance being serialized. |
| * This is used by deserialization to determine what instance |
| * type to create and deserialize into. |
| */ |
| virtual int32_t classId() const; |
| |
| /** |
| * Return the typeId byte of the instance being serialized. |
| * This is used by deserialization to determine what instance |
| * type to create and deserialize into. |
| * |
| * For a <code>CacheableString</code> this shall return |
| * <code>GeodeTypeIds::CacheableNullString</code> if the underlying |
| * string is null, <code>GeodeTypeIds::CacheableASCIIString</code> |
| * if the underlying string is a char*, and |
| * <code>GeodeTypeIds::CacheableString</code> if it is a wchar_t*. |
| * For strings larger than 64K it will return |
| * <code>GeodeTypeIds::CacheableASCIIStringHuge</code> and |
| * <code>GeodeTypeIds::CacheableStringHuge</code> for char* and wchar_t* |
| * respectively. |
| */ |
| virtual int8_t typeId() const; |
| |
| /** return true if this key matches other. */ |
| virtual bool operator==(const CacheableKey& other) const; |
| |
| /** return the hashcode for this key. */ |
| virtual uint32_t hashcode() const; |
| |
| /** |
| * Factory method for creating an instance of CacheableString from |
| * a null terminated C string optionally giving the length. |
| * |
| * This should be used only for ASCII strings. |
| */ |
| static CacheableStringPtr create(const char* value, int32_t len = 0) { |
| CacheableStringPtr str = NULLPTR; |
| if (value != NULL) { |
| str = new CacheableString(); |
| str->initString(value, len); |
| } |
| return str; |
| } |
| |
| /** |
| * Factory method for creating an instance of CacheableString from |
| * a C string of given length by taking ownership of the string without |
| * making a copy. The string should have been allocated using |
| * the standard C++ new operator. |
| * |
| * This should be used only for ASCII strings. |
| * |
| * CAUTION: use this only when you really know what you are doing. |
| */ |
| static CacheableStringPtr createNoCopy(char* value, int32_t len = 0) { |
| CacheableStringPtr str = NULLPTR; |
| if (value != NULL) { |
| str = new CacheableString(); |
| str->initStringNoCopy(value, len); |
| } |
| return str; |
| } |
| |
| /** |
| * Factory method for creating an instance of CacheableString from a |
| * wide-character null terminated C string optionally giving the length. |
| * |
| * This should be used for non-ASCII strings. |
| */ |
| static CacheableStringPtr create(const wchar_t* value, int32_t len = 0) { |
| CacheableStringPtr str = NULLPTR; |
| if (value != NULL) { |
| str = new CacheableString(); |
| str->initString(value, len); |
| } |
| return str; |
| } |
| |
| /** |
| * Factory method for creating an instance of CacheableString from a |
| * wide-character C string of given length by taking ownership of the |
| * string without making a copy. The string should have been allocated |
| * using the standard C++ new operator. |
| * |
| * This should be used for non-ASCII strings. |
| * |
| * CAUTION: use this only when you really know what you are doing. |
| */ |
| static CacheableStringPtr createNoCopy(wchar_t* value, int32_t len = 0) { |
| CacheableStringPtr str = NULLPTR; |
| if (value != NULL) { |
| str = new CacheableString(); |
| str->initStringNoCopy(value, len); |
| } |
| return str; |
| } |
| |
| /** Returns true if the underlying string is a normal C string. */ |
| inline bool isCString() const { |
| return (m_type == GF_STRING || m_type == GF_STRING_HUGE); |
| } |
| |
| /** Returns true if the underlying string is a wide-character string. */ |
| inline bool isWideString() const { |
| return (m_type == GF_WIDESTRING || m_type == GF_WIDESTRING_HUGE); |
| } |
| |
| /** |
| * Return the string that backs this CacheableString as a char *. This |
| * shall throw an exception if the underlying string is a wchar_t* -- |
| * the caller should use <code>typeId</code> to determine the actual type, |
| * or <code>isWideString</code> to find whether this is a wide-character |
| * string. |
| * |
| * @throws IllegalStateException if the underlying string is a wchar_t * |
| */ |
| const char* asChar() const { |
| if (isWideString()) { |
| throw IllegalStateException( |
| "CacheableString::asChar: the string is a " |
| "wide character string; use asWChar() to obtain it."); |
| } |
| return reinterpret_cast<const char*>(m_str); |
| } |
| |
| /** |
| * Return the string that backs this CacheableString as a wchar_t *. This |
| * shall throw an exception if the underlying string is a char* -- |
| * the caller should use <code>typeId</code> to determine the actual type, |
| * or <code>isWideString</code> to find whether this is indeed a |
| * wide-character string. |
| * |
| * @throws IllegalStateException if the underlying string is a char * |
| */ |
| const wchar_t* asWChar() const { |
| if (isCString()) { |
| throw IllegalStateException( |
| "CacheableString::asWChar: the string is " |
| "not a wide character string; use asChar() to obtain it."); |
| } |
| return reinterpret_cast<const wchar_t*>(m_str); |
| } |
| |
| /** Return the length of the contained string. */ |
| inline uint32_t length() const { return m_len; } |
| |
| /** |
| * Display this object as c string. In this case, it returns the same |
| * value as asChar() when underlying type is a char* and returns the same |
| * value as asWChar() cast to char* when the underlying type is a wchar_t*. |
| * To handle this correctly the user should find the actual type by calling |
| * typeId() or isWideString() and cast to the correct type accordingly. |
| * Note: this is a debugging API, not intended for getting the exact value |
| * of the CacheableString. In a future release this may return a more |
| * summary representation. This is historical. It is preferred that the |
| * user call logString or asChar/asWChar, depending on the need. |
| */ |
| const char* toString() { return reinterpret_cast<const char*>(m_str); } |
| |
| virtual CacheableStringPtr toString() const { |
| return CacheableStringPtr(this); |
| } |
| |
| /** get the name of the class of this object for logging purpose */ |
| virtual const char* className() const { return "CacheableString"; } |
| |
| /** Destructor */ |
| virtual ~CacheableString(); |
| |
| /** used to render as a string for logging. */ |
| virtual int32_t logString(char* buffer, int32_t maxLength) const; |
| |
| virtual uint32_t objectSize() const; |
| |
| protected: |
| /** Private method to populate the <code>CacheableString</code>. */ |
| void copyString(const char* value, int32_t len); |
| /** Private method to populate the <code>CacheableString</code>. */ |
| void copyString(const wchar_t* value, int32_t len); |
| /** initialize the string, given a value and length. */ |
| void initString(const char* value, int32_t len); |
| /** |
| * Initialize the string without making a copy, given a C string |
| * and length. |
| */ |
| void initStringNoCopy(char* value, int32_t len); |
| /** initialize the string, given a wide-char string and length. */ |
| void initString(const wchar_t* value, int32_t len); |
| /** |
| * Initialize the string without making a copy, given a wide-char string |
| * and length. |
| */ |
| void initStringNoCopy(wchar_t* value, int32_t len); |
| /** Private method to get ASCII string for wide-string if possible. */ |
| char* getASCIIString(const wchar_t* value, int32_t& len, int32_t& encodedLen); |
| /** Default constructor. */ |
| inline CacheableString(int8_t type = GF_STRING) |
| : m_str(NULL), m_type(type), m_len(0), m_hashcode(0) {} |
| |
| private: |
| // never implemented. |
| void operator=(const CacheableString& other); |
| CacheableString(const CacheableString& other); |
| }; |
| |
| /** overload of apache::geode::client::createKeyArr to pass char* */ |
| inline CacheableKeyPtr createKeyArr(const char* value) { |
| return (value != NULL ? CacheableKeyPtr(CacheableString::create(value).ptr()) |
| : NULLPTR); |
| } |
| |
| /** overload of apache::geode::client::createKeyArr to pass wchar_t* */ |
| inline CacheableKeyPtr createKeyArr(const wchar_t* value) { |
| return (value != NULL ? CacheableKeyPtr(CacheableString::create(value).ptr()) |
| : NULLPTR); |
| } |
| |
| /** overload of apache::geode::client::createValueArr to pass char* */ |
| inline CacheablePtr createValueArr(const char* value) { |
| return (value != NULL ? CacheablePtr(CacheableString::create(value).ptr()) |
| : NULLPTR); |
| } |
| |
| /** overload of apache::geode::client::createValueArr to pass wchar_t* */ |
| inline CacheablePtr createValueArr(const wchar_t* value) { |
| return (value != NULL ? CacheablePtr(CacheableString::create(value).ptr()) |
| : NULLPTR); |
| } |
| } // namespace client |
| } // namespace geode |
| } // namespace apache |
| |
| #endif // GEODE_GFCPP_CACHEABLESTRING_H_ |