InternalString.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  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 "CommonDataStructuresPch.h"
  6. #include "DataStructures/CharacterBuffer.h"
  7. #include "DataStructures/InternalString.h"
  8. namespace Js
  9. {
  10. InternalString::InternalString(const char16* content, charcount_t length, unsigned char offset):
  11. m_content(content),
  12. m_charLength(length),
  13. m_offset(offset)
  14. {
  15. AssertMsg(length < INT_MAX, "Length should be a valid string length");
  16. }
  17. InternalString::InternalString(const char16* content, _no_write_barrier_tag, charcount_t length, unsigned char offset) :
  18. m_content(NO_WRITE_BARRIER_TAG(content)),
  19. m_charLength(length),
  20. m_offset(offset)
  21. {
  22. AssertMsg(length < INT_MAX, "Length should be a valid string length");
  23. }
  24. // This will make a copy of the entire buffer
  25. InternalString *InternalString::New(ArenaAllocator* alloc, const char16* content, charcount_t length)
  26. {
  27. size_t bytelength = sizeof(char16) * length;
  28. DWORD* allocbuffer = (DWORD*)alloc->Alloc(sizeof(DWORD) + bytelength + sizeof(char16));
  29. allocbuffer[0] = (DWORD) bytelength;
  30. char16* buffer = (char16*)(allocbuffer+1);
  31. js_memcpy_s(buffer, bytelength, content, bytelength);
  32. buffer[length] = _u('\0');
  33. InternalString* newInstance = Anew(alloc, InternalString, buffer, length);
  34. return newInstance;
  35. }
  36. // This will make a copy of the entire buffer
  37. // Allocated using recycler memory
  38. InternalString *InternalString::New(Recycler* recycler, const char16* content, charcount_t length)
  39. {
  40. size_t bytelength = sizeof(char16) * length;
  41. // Allocate 3 extra bytes, two for the first DWORD with the size, the third for the null character
  42. // This is so that we can pretend that internal strings are BSTRs for purposes of clients who want to use
  43. // it as thus
  44. const unsigned char offset = sizeof(DWORD)/sizeof(char16);
  45. InternalString* newInstance = RecyclerNewPlusLeaf(recycler, bytelength + (sizeof(DWORD) + sizeof(char16)), InternalString, nullptr, length, offset);
  46. DWORD* allocbuffer = (DWORD*) (newInstance + 1);
  47. allocbuffer[0] = (DWORD) bytelength;
  48. char16* buffer = (char16*)(allocbuffer + 1);
  49. js_memcpy_s(buffer, bytelength, content, bytelength);
  50. buffer[length] = _u('\0');
  51. newInstance->m_content = (const char16*) allocbuffer;
  52. return newInstance;
  53. }
  54. // This will only store the pointer and length, not making a copy of the buffer
  55. InternalString *InternalString::NewNoCopy(ArenaAllocator* alloc, const char16* content, charcount_t length)
  56. {
  57. InternalString* newInstance = Anew(alloc, InternalString, const_cast<char16*> (content), length);
  58. return newInstance;
  59. }
  60. }