-
-
Save mraleph/4eb5ccbb38904075141e to your computer and use it in GitHub Desktop.
library writer; | |
import 'dart:typed_data'; | |
/// Writer wraps a fixed size Uint8List and writes values into it using | |
/// big-endian byte order. | |
class Writer { | |
/// Output buffer. | |
final Uint8List out; | |
/// Current position within [out]. | |
var position = 0; | |
Writer._create(this.out); | |
factory Writer(size) { | |
final out = new Uint8List(size); | |
if (Endianness.HOST_ENDIAN == Endianness.LITTLE_ENDIAN) { | |
return new _WriterForLEHost._create(out); | |
} else { | |
return new _WriterForBEHost._create(out); | |
} | |
} | |
writeFloat64(double v); | |
writeFloat32(double v); | |
writeInt32(int v) { | |
out[position + 3] = v; | |
out[position + 2] = (v >> 8); | |
out[position + 1] = (v >> 16); | |
out[position + 0] = (v >> 24); | |
position += 4; | |
} | |
writeInt16(int v) { | |
out[position + 1] = v; | |
out[position + 0] = (v >> 8); | |
position += 2; | |
} | |
writeInt8(int v) { | |
out[position] = v; | |
position++; | |
} | |
writeString(String str) { | |
out.setAll(position, str.codeUnits); | |
position += str.codeUnits.length; | |
} | |
} | |
/// Lists used for data convertion (alias each other). | |
final Uint8List _convU8 = new Uint8List(8); | |
final Float32List _convF32 = new Float32List.view(_convU8.buffer); | |
final Float64List _convF64 = new Float64List.view(_convU8.buffer); | |
/// Writer used on little-endian host. | |
class _WriterForLEHost extends Writer { | |
_WriterForLEHost._create(out) : super._create(out); | |
writeFloat64(double v) { | |
_convF64[0] = v; | |
out[position + 7] = _convU8[0]; | |
out[position + 6] = _convU8[1]; | |
out[position + 5] = _convU8[2]; | |
out[position + 4] = _convU8[3]; | |
out[position + 3] = _convU8[4]; | |
out[position + 2] = _convU8[5]; | |
out[position + 1] = _convU8[6]; | |
out[position + 0] = _convU8[7]; | |
position += 8; | |
} | |
writeFloat32(double v) { | |
_convF32[0] = v; | |
out[position + 3] = _convU8[0]; | |
out[position + 2] = _convU8[1]; | |
out[position + 1] = _convU8[2]; | |
out[position + 0] = _convU8[3]; | |
position += 4; | |
} | |
} | |
/// Writer used on the big-endian host. | |
class _WriterForBEHost extends Writer { | |
_WriterForBEHost._create(out) : super._create(out); | |
writeFloat64(double v) { | |
_convF64[0] = v; | |
out[position + 0] = _convU8[0]; | |
out[position + 1] = _convU8[1]; | |
out[position + 2] = _convU8[2]; | |
out[position + 3] = _convU8[3]; | |
out[position + 4] = _convU8[4]; | |
out[position + 5] = _convU8[5]; | |
out[position + 6] = _convU8[6]; | |
out[position + 7] = _convU8[7]; | |
position += 8; | |
} | |
writeFloat32(double v) { | |
_convF32[0] = v; | |
out[position + 0] = _convU8[0]; | |
out[position + 1] = _convU8[1]; | |
out[position + 2] = _convU8[2]; | |
out[position + 3] = _convU8[3]; | |
position += 4; | |
} | |
} |
@devfelipereis Well, good answer to your question depends on where and how you get this hex from. Are you getting hex value or are you getting a sequence of bytes from somewhere?
Well, 1615217400
is 604642f8
in hex, so F8424660
is a big endian version of this. You can reverse byte order manually, e.g.
final value = int.parse('F8424660', radix: 16);
final timestamp = (value & 0xFF) << 24 | (value & 0xFF00) << 8 | (value & 0xFF0000) >> 8 | (value & 0xFF000000) >> 24;
print(timestamp); // => 1615217400
There is nothing too Dart specific here.
@mraleph I'm getting something like this:
534D627480650300A201F84246600000F0420000F2420000F4420000803F000000400000404000007A4400002041005043470050C3466666663FCDCC4C3F3333333F00007042333333333333E33F9A9999999999D93F40016001200100E700E700E700E700E700E7B803BD03B30332
this data comes from a bluetooth device. Then I need to break this in parts and extract some informations.
Timestamp is in the position 20-28. Some values are float, some are int. What I need to do is get this values and parse to the correct type.
What should I study do understand how this conversions work? Thank you!
If you want to understand fundamentals then you should study how different types are represented in memory and have a grasp of things like big/little endian byte orders.
For parsing you can use ByteData class, it allows you to extract specific types from a sequence of bytes.
If data arrives to you as hex string you can convert it into a List<int>
using hex
codec from package:convert
, after that you can create ByteData
from it, e.g.
import 'dart:typed_data';
import 'package:convert/convert.dart';
void parse(String s) {
// Convert hex from the given string to a sequence of bytes (first two characters become first byte and so on).
final bd = ByteData.sublistView(Uint8List.fromList(hex.decode(s)));
print(bd.getInt32(10, Endian.little)); // print timestamp (should print 1615217400)
}
void main() {
parse('534D627480650300A201F84246600000F0420000F2420000F4420000803F000000400000404000007A4400002041005043470050C3466666663FCDCC4C3F3333333F00007042333333333333E33F9A9999999999D93F40016001200100E700E700E700E700E700E7B803BD03B30332');
}
@mraleph thank you so much!
I'm trying to convert this hex "F8424660" to timestamp but without success. Can you give me some advice?
The expected value is: 1615217400
In fact I need to convert some hex values to int, float and so on. Using little endian.
I'm a beginner in dart and I'm little confused on how to do this.