vid_us_data_stream_reader.dart 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. import 'dart:typed_data';
  2. //Raised when data is not ready.
  3. class NotReadyException implements Exception {}
  4. class StreamErrorException implements Exception {
  5. String _msg;
  6. StreamErrorException(this._msg);
  7. @override
  8. String toString() {
  9. return _msg;
  10. }
  11. }
  12. class VidUsDataStreamReader {
  13. late final List<int> _data = [];
  14. late int _index;
  15. late ByteBuffer _buffer;
  16. late bool _error;
  17. late String _errorMsg;
  18. VidUsDataStreamReader(Stream<Uint8List> stream, [int offset = 0]) {
  19. _error = false;
  20. _errorMsg = '';
  21. _buffer = Uint8List.fromList(_data).buffer;
  22. stream.listen(onDataArrived, onError: onStreamError, onDone: onStreamDone);
  23. _index = offset;
  24. }
  25. void onDataArrived(Uint8List data) {
  26. _data.addAll(data);
  27. _buffer = Uint8List.fromList(_data).buffer;
  28. }
  29. void onStreamError(msg) {
  30. _error = true;
  31. _errorMsg = msg.toString();
  32. }
  33. void onStreamDone() {
  34. //Update the last data into the buffer.
  35. _buffer = Uint8List.fromList(_data).buffer;
  36. }
  37. ///Read int value from binary data(little endian),
  38. int readInt([int index = -1]) {
  39. if (_error) {
  40. throw StreamErrorException(_errorMsg);
  41. }
  42. if (index == -1) {
  43. if ((_buffer.lengthInBytes - _index) < 4) {
  44. throw NotReadyException();
  45. }
  46. var intData = _buffer.asByteData(_index, 4);
  47. _index += 4;
  48. return intData.getInt32(0, Endian.little);
  49. } else {
  50. if ((_buffer.lengthInBytes - index) < 4) {
  51. throw NotReadyException();
  52. }
  53. var intData = _buffer.asByteData(index, 4);
  54. _index = index + 4;
  55. return intData.getInt32(0, Endian.little);
  56. }
  57. }
  58. ///Read string from the binary data, the string format is utf-16, which is unicode in C#
  59. String readString([int index = -1]) {
  60. if (_error) {
  61. throw StreamErrorException(_errorMsg);
  62. }
  63. int dataLength;
  64. if (index == -1) {
  65. dataLength = readInt();
  66. if ((_buffer.lengthInBytes - _index) < dataLength) {
  67. throw NotReadyException();
  68. }
  69. } else {
  70. dataLength = readInt(index);
  71. if ((_buffer.lengthInBytes - index) < dataLength) {
  72. throw NotReadyException();
  73. }
  74. }
  75. var stringData = _buffer.asUint8List(_index, dataLength);
  76. _index += dataLength;
  77. var unicodeStringData = Uint8List.fromList(stringData.toList()).buffer.asUint16List();
  78. return String.fromCharCodes(unicodeStringData);
  79. }
  80. ///Read int16 value from binary data(little endian)
  81. int readInt16([int index = -1]) {
  82. if (_error) {
  83. throw StreamErrorException(_errorMsg);
  84. }
  85. if (index == -1) {
  86. if ((_buffer.lengthInBytes - _index) < 2) {
  87. throw NotReadyException();
  88. }
  89. var intData = _buffer.asByteData(_index, 2);
  90. _index += 2;
  91. return intData.getInt16(0, Endian.little);
  92. } else {
  93. if ((_buffer.lengthInBytes - index) < 2) {
  94. throw NotReadyException();
  95. }
  96. var intData = _buffer.asByteData(index, 2);
  97. _index = index + 2;
  98. return intData.getInt16(0, Endian.little);
  99. }
  100. }
  101. ///Read int64 value from binary data(little endian)
  102. ///this method is not support in web platform use readInt64V2 instead.
  103. int readInt64([int index = -1]) {
  104. if (_error) {
  105. throw StreamErrorException(_errorMsg);
  106. }
  107. if (index == -1) {
  108. if ((_buffer.lengthInBytes - _index) < 8) {
  109. throw NotReadyException();
  110. }
  111. var intData = _buffer.asByteData(_index, 8);
  112. _index += 8;
  113. return intData.getInt64(0, Endian.little);
  114. } else {
  115. if ((_buffer.lengthInBytes - index) < 8) {
  116. throw NotReadyException();
  117. }
  118. var intData = _buffer.asByteData(index, 8);
  119. _index = index + 8;
  120. return intData.getInt64(0, Endian.little);
  121. }
  122. }
  123. ///Read int64 value from binary data(little endian)
  124. ///this method use two int32 to support read int64 on web platform
  125. int readInt64V2([int index = -1]) {
  126. if (_error) {
  127. throw StreamErrorException(_errorMsg);
  128. }
  129. if (index == -1) {
  130. if ((_buffer.lengthInBytes - _index) < 8) {
  131. throw NotReadyException();
  132. }
  133. int low = readInt();
  134. int high = readInt();
  135. int value = high >> 32;
  136. value |= low;
  137. return value;
  138. } else {
  139. if ((_buffer.lengthInBytes - index) < 8) {
  140. throw NotReadyException();
  141. }
  142. int low = readInt(index);
  143. //Read the next int.
  144. int high = readInt();
  145. int value = high >> 32;
  146. value |= low;
  147. return value;
  148. }
  149. }
  150. ///Read float value from binary data(little endian)
  151. double readFloat([int index = -1]) {
  152. if (_error) {
  153. throw StreamErrorException(_errorMsg);
  154. }
  155. if (index == -1) {
  156. if ((_buffer.lengthInBytes - _index) < 4) {
  157. throw NotReadyException();
  158. }
  159. var floatData = _buffer.asByteData(_index, 4);
  160. _index += 4;
  161. return floatData.getFloat32(0, Endian.little);
  162. } else {
  163. if ((_buffer.lengthInBytes - index) < 4) {
  164. throw NotReadyException();
  165. }
  166. var floatData = _buffer.asByteData(index, 4);
  167. _index = index + 4;
  168. return floatData.getFloat32(0, Endian.little);
  169. }
  170. }
  171. ///Read double value from binary data(little endian)
  172. double readDouble([int index = -1]) {
  173. if (_error) {
  174. throw StreamErrorException(_errorMsg);
  175. }
  176. if (index == -1) {
  177. if ((_buffer.lengthInBytes - _index) < 8) {
  178. throw NotReadyException();
  179. }
  180. var floatData = _buffer.asByteData(_index, 8);
  181. _index += 8;
  182. return floatData.getFloat64(0, Endian.little);
  183. } else {
  184. if ((_buffer.lengthInBytes - index) < 8) {
  185. throw NotReadyException();
  186. }
  187. var floatData = _buffer.asByteData(index, 8);
  188. _index = index + 8;
  189. return floatData.getFloat64(0, Endian.little);
  190. }
  191. }
  192. ///Read bool value from binary data
  193. bool readBool([int index = -1]) {
  194. if (_error) {
  195. throw StreamErrorException(_errorMsg);
  196. }
  197. if (index == -1) {
  198. if ((_buffer.lengthInBytes - _index) < 1) {
  199. throw NotReadyException();
  200. }
  201. var boolData = _buffer.asByteData(_index, 1);
  202. _index++;
  203. return boolData.getInt8(0) == 1;
  204. } else {
  205. if ((_buffer.lengthInBytes - index) < 1) {
  206. throw NotReadyException();
  207. }
  208. var boolData = _buffer.asByteData(index, 1);
  209. _index = index + 1;
  210. return boolData.getInt8(0) == 1;
  211. }
  212. }
  213. ///Read byte value from binary data
  214. int readByte([int index = -1]) {
  215. if (_error) {
  216. throw StreamErrorException(_errorMsg);
  217. }
  218. if (index == -1) {
  219. if ((_buffer.lengthInBytes - _index) < 1) {
  220. throw NotReadyException();
  221. }
  222. var byteData = _buffer.asByteData(_index, 1);
  223. _index++;
  224. return byteData.getInt8(0);
  225. } else {
  226. if ((_buffer.lengthInBytes - index) < 1) {
  227. throw NotReadyException();
  228. }
  229. var byteData = _buffer.asByteData(index, 1);
  230. _index = index + 1;
  231. return byteData.getInt8(0);
  232. }
  233. }
  234. ///Read bytes from the binary data.
  235. Uint8List readBytes([int index = -1]) {
  236. if (_error) {
  237. throw StreamErrorException(_errorMsg);
  238. }
  239. var dataLength = readInt(index);
  240. if ((_buffer.lengthInBytes - _index) < dataLength) {
  241. throw NotReadyException();
  242. }
  243. var bytes = _buffer.asUint8List(_index, dataLength);
  244. _index += dataLength;
  245. return bytes;
  246. }
  247. }