String.inl.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. // Copyright (C) 2009-2015, Panagiotis Christopoulos Charitos.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. namespace anki {
  6. //==============================================================================
  7. template<typename TAllocator>
  8. inline void String::create(TAllocator alloc, const CStringType& cstr)
  9. {
  10. auto len = cstr.getLength();
  11. if(len > 0)
  12. {
  13. auto size = len + 1;
  14. m_data.create(alloc, size);
  15. std::memcpy(&m_data[0], &cstr[0], sizeof(Char) * size);
  16. }
  17. }
  18. //==============================================================================
  19. template<typename TAllocator>
  20. inline void String::create(
  21. TAllocator alloc, ConstIterator first, ConstIterator last)
  22. {
  23. ANKI_ASSERT(first != 0 && last != 0);
  24. auto length = last - first;
  25. m_data.create(alloc, length + 1);
  26. std::memcpy(&m_data[0], first, length);
  27. m_data[length] = '\0';
  28. }
  29. //==============================================================================
  30. template<typename TAllocator>
  31. inline void String::create(TAllocator alloc, Char c, PtrSize length)
  32. {
  33. ANKI_ASSERT(c != '\0');
  34. m_data.create(alloc, length + 1);
  35. std::memset(&m_data[0], c, length);
  36. m_data[length] = '\0';
  37. }
  38. //==============================================================================
  39. template<typename TAllocator>
  40. inline void String::appendInternal(
  41. TAllocator alloc, const Char* str, PtrSize strSize)
  42. {
  43. ANKI_ASSERT(str != nullptr);
  44. ANKI_ASSERT(strSize > 1);
  45. auto size = m_data.getSize();
  46. // Fix empty string
  47. if(size == 0)
  48. {
  49. size = 1;
  50. }
  51. DArray<Char> newData;
  52. newData.create(alloc, size + strSize - 1);
  53. if(!m_data.isEmpty())
  54. {
  55. std::memcpy(&newData[0], &m_data[0], sizeof(Char) * size);
  56. }
  57. std::memcpy(&newData[size - 1], str, sizeof(Char) * strSize);
  58. m_data.destroy(alloc);
  59. m_data = std::move(newData);
  60. }
  61. //==============================================================================
  62. template<typename TAllocator>
  63. inline void String::sprintf(TAllocator alloc, CString fmt, ...)
  64. {
  65. Array<Char, 512> buffer;
  66. va_list args;
  67. va_start(args, fmt);
  68. I len = std::vsnprintf(&buffer[0], sizeof(buffer), &fmt[0], args);
  69. va_end(args);
  70. if(len < 0)
  71. {
  72. ANKI_LOGF("vsnprintf() failed");
  73. }
  74. else if(static_cast<PtrSize>(len) >= sizeof(buffer))
  75. {
  76. I size = len + 1;
  77. m_data.create(alloc, size);
  78. va_start(args, fmt);
  79. len = std::vsnprintf(&m_data[0], size, &fmt[0], args);
  80. va_end(args);
  81. (void)len;
  82. ANKI_ASSERT((len + 1) == size);
  83. }
  84. else
  85. {
  86. // buffer was enough
  87. create(alloc, CString(&buffer[0]));
  88. }
  89. }
  90. //==============================================================================
  91. template<typename TAllocator, typename TNumber>
  92. inline void String::toString(TAllocator alloc, TNumber number)
  93. {
  94. destroy(alloc);
  95. Array<Char, 512> buff;
  96. I ret = std::snprintf(
  97. &buff[0], buff.size(), detail::toStringFormat<TNumber>(), number);
  98. if(ret < 0 || ret > static_cast<I>(buff.getSize()))
  99. {
  100. ANKI_LOGF("To small intermediate buffer");
  101. }
  102. else
  103. {
  104. create(alloc, &buff[0]);
  105. }
  106. }
  107. } // end namespace anki