pascal.hpp 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. #pragma once
  2. namespace nall {
  3. struct string_pascal {
  4. using type = string_pascal;
  5. string_pascal(const char* text = nullptr) {
  6. if(text && *text) {
  7. uint size = strlen(text);
  8. _data = memory::allocate<char>(sizeof(uint) + size + 1);
  9. ((uint*)_data)[0] = size;
  10. memory::copy(_data + sizeof(uint), text, size);
  11. _data[sizeof(uint) + size] = 0;
  12. }
  13. }
  14. string_pascal(const string& text) {
  15. if(text.size()) {
  16. _data = memory::allocate<char>(sizeof(uint) + text.size() + 1);
  17. ((uint*)_data)[0] = text.size();
  18. memory::copy(_data + sizeof(uint), text.data(), text.size());
  19. _data[sizeof(uint) + text.size()] = 0;
  20. }
  21. }
  22. string_pascal(const string_pascal& source) { operator=(source); }
  23. string_pascal(string_pascal&& source) { operator=(move(source)); }
  24. ~string_pascal() {
  25. if(_data) memory::free(_data);
  26. }
  27. explicit operator bool() const { return _data; }
  28. operator const char*() const { return _data ? _data + sizeof(uint) : nullptr; }
  29. operator string() const { return _data ? string{_data + sizeof(uint)} : ""; }
  30. auto operator=(const string_pascal& source) -> type& {
  31. if(this == &source) return *this;
  32. if(_data) { memory::free(_data); _data = nullptr; }
  33. if(source._data) {
  34. uint size = source.size();
  35. _data = memory::allocate<char>(sizeof(uint) + size);
  36. memory::copy(_data, source._data, sizeof(uint) + size);
  37. }
  38. return *this;
  39. }
  40. auto operator=(string_pascal&& source) -> type& {
  41. if(this == &source) return *this;
  42. if(_data) memory::free(_data);
  43. _data = source._data;
  44. source._data = nullptr;
  45. return *this;
  46. }
  47. auto operator==(string_view source) const -> bool {
  48. return size() == source.size() && memory::compare(data(), source.data(), size()) == 0;
  49. }
  50. auto operator!=(string_view source) const -> bool {
  51. return size() != source.size() || memory::compare(data(), source.data(), size()) != 0;
  52. }
  53. auto data() const -> char* {
  54. if(!_data) return nullptr;
  55. return _data + sizeof(uint);
  56. }
  57. auto size() const -> uint {
  58. if(!_data) return 0;
  59. return ((uint*)_data)[0];
  60. }
  61. protected:
  62. char* _data = nullptr;
  63. };
  64. }