SubString.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #include "RuntimeLibraryPch.h"
  6. namespace Js
  7. {
  8. DEFINE_RECYCLER_TRACKER_PERF_COUNTER(SubString);
  9. inline SubString::SubString(void const * originalFullStringReference, const char16* subString, charcount_t length, ScriptContext *scriptContext) :
  10. JavascriptString(scriptContext->GetLibrary()->GetStringTypeStatic())
  11. {
  12. this->SetBuffer(subString);
  13. this->originalFullStringReference = originalFullStringReference;
  14. this->SetLength(length);
  15. #ifdef PROFILE_STRINGS
  16. StringProfiler::RecordNewString( scriptContext, this->UnsafeGetBuffer(), this->GetLength() );
  17. #endif
  18. }
  19. JavascriptString* SubString::New(JavascriptString* string, charcount_t start, charcount_t length)
  20. {
  21. AssertMsg( IsValidCharCount(start), "start is out of range" );
  22. AssertMsg( IsValidCharCount(length), "length is out of range" );
  23. ScriptContext *scriptContext = string->GetScriptContext();
  24. if (!length)
  25. {
  26. return scriptContext->GetLibrary()->GetEmptyString();
  27. }
  28. Recycler* recycler = scriptContext->GetRecycler();
  29. Assert(string->GetLength() >= start + length);
  30. const char16 * subString = string->GetString() + start;
  31. void const * originalFullStringReference = string->GetOriginalStringReference();
  32. return RecyclerNew(recycler, SubString, originalFullStringReference, subString, length, scriptContext);
  33. }
  34. JavascriptString* SubString::New(const char16* string, charcount_t start, charcount_t length, ScriptContext *scriptContext)
  35. {
  36. AssertMsg( IsValidCharCount(start), "start is out of range" );
  37. AssertMsg( IsValidCharCount(length), "length is out of range" );
  38. if (!length)
  39. {
  40. return scriptContext->GetLibrary()->GetEmptyString();
  41. }
  42. Recycler* recycler = scriptContext->GetRecycler();
  43. return RecyclerNew(recycler, SubString, string, string + start, length, scriptContext);
  44. }
  45. const char16* SubString::GetSz()
  46. {
  47. if (originalFullStringReference)
  48. {
  49. Recycler* recycler = this->GetScriptContext()->GetRecycler();
  50. char16 * newInstance = AllocateLeafAndCopySz(recycler, UnsafeGetBuffer(), GetLength());
  51. this->SetBuffer(newInstance);
  52. // We don't need the string reference anymore, set it to nullptr and use this to know our string is nullptr terminated
  53. originalFullStringReference = nullptr;
  54. }
  55. return UnsafeGetBuffer();
  56. }
  57. const void * SubString::GetOriginalStringReference()
  58. {
  59. if (originalFullStringReference != nullptr)
  60. {
  61. return originalFullStringReference;
  62. }
  63. return __super::GetOriginalStringReference();
  64. }
  65. size_t SubString::GetAllocatedByteCount() const
  66. {
  67. if (originalFullStringReference)
  68. {
  69. return 0;
  70. }
  71. return __super::GetAllocatedByteCount();
  72. }
  73. bool SubString::IsSubstring() const
  74. {
  75. if (originalFullStringReference)
  76. {
  77. return true;
  78. }
  79. return false;
  80. }
  81. }