1 // [AsmJit] 2 // Machine Code Generation for C++. 3 // 4 // [License] 5 // Zlib - See LICENSE.md file in the package. 6 7 #ifndef _ASMJIT_CORE_SMALLSTRING_H 8 #define _ASMJIT_CORE_SMALLSTRING_H 9 10 #include "../core/globals.h" 11 #include "../core/zone.h" 12 13 ASMJIT_BEGIN_NAMESPACE 14 15 //! \addtogroup asmjit_zone 16 //! \{ 17 18 // ============================================================================ 19 // [asmjit::ZoneStringBase] 20 // ============================================================================ 21 22 struct ZoneStringBase { 23 union { 24 struct { 25 uint32_t _size; 26 char _embedded[sizeof(void*) * 2 - 4]; 27 }; 28 struct { 29 void* _dummy; 30 char* _external; 31 }; 32 }; 33 resetZoneStringBase34 inline void reset() noexcept { 35 _dummy = nullptr; 36 _external = nullptr; 37 } 38 setDataZoneStringBase39 Error setData(Zone* zone, uint32_t maxEmbeddedSize, const char* str, size_t size) noexcept { 40 if (size == SIZE_MAX) 41 size = strlen(str); 42 43 if (size <= maxEmbeddedSize) { 44 memcpy(_embedded, str, size); 45 _embedded[size] = '\0'; 46 } 47 else { 48 char* external = static_cast<char*>(zone->dup(str, size, true)); 49 if (ASMJIT_UNLIKELY(!external)) 50 return DebugUtils::errored(kErrorOutOfMemory); 51 _external = external; 52 } 53 54 _size = uint32_t(size); 55 return kErrorOk; 56 } 57 }; 58 59 // ============================================================================ 60 // [asmjit::ZoneString<N>] 61 // ============================================================================ 62 63 //! Small string is a template that helps to create strings that can be either 64 //! statically allocated if they are small, or externally allocated in case 65 //! their size exceeds the limit. The `N` represents the size of the whole 66 //! `ZoneString` structure, based on that size the maximum size of the internal 67 //! buffer is determined. 68 template<size_t N> 69 class ZoneString { 70 public: 71 static constexpr uint32_t kWholeSize = 72 (N > sizeof(ZoneStringBase)) ? uint32_t(N) : uint32_t(sizeof(ZoneStringBase)); 73 static constexpr uint32_t kMaxEmbeddedSize = kWholeSize - 5; 74 75 union { 76 ZoneStringBase _base; 77 char _wholeData[kWholeSize]; 78 }; 79 80 //! \name Construction & Destruction 81 //! \{ 82 ZoneString()83 inline ZoneString() noexcept { reset(); } reset()84 inline void reset() noexcept { _base.reset(); } 85 86 //! \} 87 88 //! \name Accessors 89 //! \{ 90 data()91 inline const char* data() const noexcept { return _base._size <= kMaxEmbeddedSize ? _base._embedded : _base._external; } empty()92 inline bool empty() const noexcept { return _base._size == 0; } size()93 inline uint32_t size() const noexcept { return _base._size; } 94 isEmbedded()95 inline bool isEmbedded() const noexcept { return _base._size <= kMaxEmbeddedSize; } 96 setData(Zone * zone,const char * data,size_t size)97 inline Error setData(Zone* zone, const char* data, size_t size) noexcept { 98 return _base.setData(zone, kMaxEmbeddedSize, data, size); 99 } 100 101 //! \} 102 }; 103 104 //! \} 105 106 ASMJIT_END_NAMESPACE 107 108 #endif // _ASMJIT_CORE_SMALLSTRING_H 109