stream.h - エンジンの C API リファレンス

stream.h
  1. #pragma once
  2. #include "array.h"
  3. #include <string.h>
  4. namespace stingray_plugin_foundation {
  5. // Functions for treating a Array<char> or a char * as a memory stream that can be written to
  6. // and read from.
  7. namespace stream {
  8. // Packs the data in t to the stream.
  9. template <class T> void pack(char *&v, const T &t)
  10. {
  11. memmove(v, &t, sizeof(T));
  12. v += sizeof(T);
  13. }
  14. // Packs the data in t to the stream, resizing it if necessary.
  15. template <class T> void pack(Array<char> &v, const T &t)
  16. {
  17. v.resize(v.size() + sizeof(T));
  18. memmove(&v[0] + v.size() - sizeof(T), &t, sizeof(T));
  19. }
  20. // Patches already packed data at the specified location.
  21. template <class T> void patch(char *&v, const T &t)
  22. {
  23. memmove(v, &t, sizeof(T));
  24. v += sizeof(T);
  25. }
  26. // Patches already packed data at the specified offset.
  27. template <class T> void patch(Array<char> &v, unsigned &offset, const T &t)
  28. {
  29. memmove(&v[0] + offset, &t, sizeof(T));
  30. offset += sizeof(T);
  31. }
  32. // Packs `count` bytes from `p` to the stream.
  33. inline void pack_bytes(char *&v, const void *p, unsigned count)
  34. {
  35. memmove(v, p, count);
  36. v += count;
  37. }
  38. // Packs `count` bytes from `p` to the stream, resizing it if necessary.
  39. inline void pack_bytes(Array<char> &v, const void *p, unsigned count)
  40. {
  41. v.resize(v.size() + count);
  42. memmove(&v[0] + v.size() - count, p, count);
  43. }
  44. // Packs `count` zero bytes to the stream.
  45. inline void pack_zeroes(char *&v, unsigned count)
  46. {
  47. memset(v, 0, count);
  48. v += count;
  49. }
  50. // Packs `count` zero bytes to the stream, resizing it if necessary.
  51. inline void pack_zeroes(Array<char> &v, unsigned count)
  52. {
  53. v.resize(v.size() + count);
  54. memset(&v[0] + v.size() - count, 0, count);
  55. }
  56. // Aligns the stream to the specified alignment.
  57. inline void pack_align(Array<char> &v, unsigned align) {
  58. while (v.size() % align != 0)
  59. v.push_back(0);
  60. }
  61. // Unpacks an object of type T from the stream and returns it. The stream
  62. // pointer is advanced to the next object. Note that since this operation
  63. // only casts the pointer, it can have alignment problems if objects in the
  64. // stream are not aligned. To unpack potentially unaligned objects, use the
  65. // call unpack(stream, t) instead.
  66. template <class T> const T &unpack(const char *&stream)
  67. {
  68. const T* t = (const T *)stream;
  69. stream += sizeof(T);
  70. return *t;
  71. }
  72. template <class T> T &unpack(char *&stream)
  73. {
  74. T* t = (T *)stream;
  75. stream += sizeof(T);
  76. return *t;
  77. }
  78. // Unpacks an object of type T from the stream into the varaible t.
  79. template <class T> void unpack(const char *&stream, T &t)
  80. {
  81. memmove(&t, stream, sizeof(T));
  82. stream += sizeof(T);
  83. }
  84. template <class T> void unpack(char *&stream, T &t)
  85. {
  86. memmove(&t, stream, sizeof(T));
  87. stream += sizeof(T);
  88. }
  89. // Unpacks count raw bytes from the stream into `p` and returns them.
  90. // The stream pionter is advanced to beyond the bytes.
  91. inline void unpack_bytes(char *&stream, void *p, unsigned count)
  92. {
  93. memmove(p, stream, count);
  94. stream += count;
  95. }
  96. // Aligns the stream to the specified alignment.
  97. inline void unpack_align(char *&stream, unsigned align)
  98. {
  99. unsigned skip = (align - (uintptr_t)stream % align) % align;
  100. stream += skip;
  101. }
  102. } // namespace stream
  103. } // namespace stingray_plugin_foundation