Skip to content

Commit

Permalink
using byte reader/writer
Browse files Browse the repository at this point in the history
  • Loading branch information
liplum committed Oct 18, 2023
1 parent 81666f5 commit edca1a4
Show file tree
Hide file tree
Showing 2 changed files with 214 additions and 42 deletions.
55 changes: 13 additions & 42 deletions lib/timetable/entity/platte.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'dart:ui';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:sit/utils/byte_io.dart';

part 'platte.g.dart';

Expand Down Expand Up @@ -58,29 +59,14 @@ class TimetablePalette {
}

static decodeFromByteList(Uint8List bytes) {
final ByteData byteData = bytes.buffer.asByteData();
int index = 0;

int nameLength = byteData.getUint8(index);
index++;

List<int> nameCodeUnits = [];
for (int i = 0; i < nameLength; i++) {
nameCodeUnits.add(byteData.getUint8(index));
index++;
}

String name = String.fromCharCodes(nameCodeUnits);

int colorsLength = byteData.getUint8(index);
index++;
final reader = ByteReader(bytes);
final name = reader.strUtf8();
final colorLen = reader.uint32();

List<Color2Mode> colors = [];
for (int i = 0; i < colorsLength; i++) {
Color light = Color(byteData.getUint32(index));
index += 4;
Color dark = Color(byteData.getUint32(index));
index += 4;
for (int i = 0; i < colorLen; i++) {
Color light = Color(reader.uint32());
Color dark = Color(reader.uint32());
colors.add((light: light, dark: dark));
}

Expand All @@ -102,30 +88,15 @@ extension TimetablePaletteX on TimetablePalette {
}

List<int> encodeByteList() {
final buffer = Uint8List(1024);
final ByteData byteData = buffer.buffer.asByteData();
int index = 0;

List<int> nameBytes = utf8.encode(name);
byteData.setUint8(index, nameBytes.length);
index++;

for (int i = 0; i < nameBytes.length; i++) {
byteData.setUint8(index, nameBytes[i]);
index++;
}

byteData.setUint8(index, colors.length);
index++;

final writer = ByteWriter(1024);
writer.strUtf8(name);
writer.uint32(colors.length);
for (var color in colors) {
byteData.setUint32(index, color.light.value);
index += 4;
byteData.setUint32(index, color.dark.value);
index += 4;
writer.uint32(color.light.value);
writer.uint32(color.dark.value);
}

return buffer.sublist(0, index);
return writer.build();
}
}

Expand Down
201 changes: 201 additions & 0 deletions lib/utils/byte_io.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
import 'dart:convert';
import 'dart:typed_data';

class ByteWriter {
late ByteData _view;
Uint8List _buffer;
int _offset = 0;

ByteWriter(int initialCapacity) : _buffer = Uint8List(initialCapacity) {
_view = _buffer.buffer.asByteData();
}

int get size => _offset + 1;

int get capacity => _buffer.length;

void _checkCapacity({required int requireBytes}) {
if (_offset + 1 + requireBytes > _buffer.length) {
_grow(size + requireBytes);
}
}

void _grow(int required) {
// We will create a list in the range of 2-4 times larger than
// required.
int newSize = required * 2;
if (newSize < _buffer.length) {
newSize = _buffer.length;
} else {
newSize = _pow2roundup(newSize);
}
var newBuffer = Uint8List(newSize);
newBuffer.setRange(0, _buffer.length, _buffer);
_buffer = newBuffer;
_view = newBuffer.buffer.asByteData();
}

void int8(int value) {
_checkCapacity(requireBytes: 1);
_view.setInt8(_offset, value);
_offset += 1;
}

void int16(int value, [Endian endian = Endian.big]) {
_checkCapacity(requireBytes: 2);
_view.setInt16(_offset, value, endian);
_offset += 2;
}

void int32(int value, [Endian endian = Endian.big]) {
_checkCapacity(requireBytes: 4);
_view.setInt32(_offset, value, endian);
_offset += 4;
}

void int64(int value, [Endian endian = Endian.big]) {
_checkCapacity(requireBytes: 8);
_view.setInt64(_offset, value, endian);
_offset += 8;
}

void uint8(int value) {
_checkCapacity(requireBytes: 1);
_view.setUint8(_offset, value);
_offset += 1;
}

void uint16(int value, [Endian endian = Endian.big]) {
_checkCapacity(requireBytes: 2);
_view.setUint16(_offset, value, endian);
_offset += 2;
}

void uint32(int value, [Endian endian = Endian.big]) {
_checkCapacity(requireBytes: 4);
_view.setUint32(_offset, value, endian);
_offset += 4;
}

void uint64(int value, [Endian endian = Endian.big]) {
_checkCapacity(requireBytes: 8);
_view.setUint64(_offset, value, endian);
_offset += 8;
}

void float32(double value, [Endian endian = Endian.big]) {
_checkCapacity(requireBytes: 4);
_view.setFloat32(_offset, value, endian);
_offset += 4;
}

void float64(double value, [Endian endian = Endian.big]) {
_checkCapacity(requireBytes: 8);
_view.setFloat64(_offset, value, endian);
_offset += 8;
}

void strUtf8(String str, [Endian endian = Endian.big]) {
List<int> nameBytes = utf8.encode(str);
uint64(nameBytes.length, endian);
_checkCapacity(requireBytes: nameBytes.length);
for (int i = 0; i < nameBytes.length; i++) {
uint8(nameBytes[i]);
}
}

Uint8List build() {
return _buffer.sublist(0, _offset);
}
}

int _pow2roundup(int x) {
assert(x > 0);
--x;
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
return x + 1;
}

class ByteReader {
final Uint8List data;
late final ByteData _view;
int _offset = 0;

ByteReader(this.data) {
_view = data.buffer.asByteData();
}

int int8() {
final value = _view.getInt8(_offset);
_offset += 1;
return value;
}

int int16([Endian endian = Endian.big]) {
final value = _view.getInt16(_offset, endian);
_offset += 2;
return value;
}

int int32([Endian endian = Endian.big]) {
final value = _view.getInt32(_offset, endian);
_offset += 4;
return value;
}

int int64([Endian endian = Endian.big]) {
final value = _view.getInt64(_offset, endian);
_offset += 8;
return value;
}

int uint8() {
final value = _view.getUint8(_offset);
_offset += 1;
return value;
}

int uint16([Endian endian = Endian.big]) {
final value = _view.getUint16(_offset, endian);
_offset += 2;
return value;
}

int uint32([Endian endian = Endian.big]) {
final value = _view.getUint32(_offset, endian);
_offset += 4;
return value;
}

int uint64([Endian endian = Endian.big]) {
final value = _view.getUint64(_offset, endian);
_offset += 8;
return value;
}

double float32([Endian endian = Endian.big]) {
final value = _view.getFloat32(_offset, endian);
_offset += 4;
return value;
}

double float64([Endian endian = Endian.big]) {
final value = _view.getFloat64(_offset, endian);
_offset += 8;
return value;
}

String strUtf8([Endian endian = Endian.big]) {
final length = uint64(endian);
List<int> charCodes = [];
for (int i = 0; i < length; i++) {
final code = uint8();
charCodes.add(code);
}
return String.fromCharCodes(charCodes);
}
}

0 comments on commit edca1a4

Please sign in to comment.