Skip to content

Commit

Permalink
feat: add app_archive gzip utilities
Browse files Browse the repository at this point in the history
  • Loading branch information
alextekartik committed Oct 13, 2024
1 parent 5ee0854 commit 2047def
Show file tree
Hide file tree
Showing 9 changed files with 223 additions and 0 deletions.
11 changes: 11 additions & 0 deletions app_archive/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Files and directories created by pub
.dart_tool/
.packages
# Remove the following pattern if you wish to check in your lock file
pubspec.lock

# Conventional directory for build outputs
build/

# Directory created by dartdoc
doc/api/
17 changes: 17 additions & 0 deletions app_archive/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# archive utils

gzip, ungzip text and bytes


# Setup

In `pubspec.yaml`

```yaml
tekartik_app_archive:
git:
url: https://github.com/tekartik/app_common_utils.dart
ref: dart3a
path: app_archive
version: '>=0.1.0'
```
2 changes: 2 additions & 0 deletions app_archive/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# tekartik strict extension
include: package:tekartik_lints/package.yaml
4 changes: 4 additions & 0 deletions app_archive/dart_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
platforms:
- node
- chrome
- vm
1 change: 1 addition & 0 deletions app_archive/lib/gzip.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export 'src/gzip_impl.dart' show gzipText, ungzipText, gzipBytes, ungzipBytes;
42 changes: 42 additions & 0 deletions app_archive/lib/src/gzip_impl.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import 'dart:convert';
import 'dart:typed_data';

import 'package:archive/archive.dart';
import 'package:tekartik_common_utils/byte_utils.dart';

/// GZip some text
Uint8List gzipText(String text, {bool? noDate}) {
noDate ??= false;
var data = GZipEncoder().encode(utf8.encode(text))!;
if (noDate) {
data[4] = 0;
data[5] = 0;
data[6] = 0;
data[7] = 0;
}
return asUint8List(data);
}

/// Un Gzip some data into text
String ungzipText(Uint8List data) {
return utf8.decode(GZipDecoder().decodeBytes(data));
}

/// GZip some bytes
Uint8List gzipBytes(Uint8List bytes, {bool? noDate}) {
noDate ??= false;
var data = GZipEncoder().encode(bytes)!;
if (noDate) {
data[4] = 0;
data[5] = 0;
data[6] = 0;
data[7] = 0;
}
return asUint8List(data);
}

/// Un Gzip some data into bytes
/// Un Gzip some data into text
Uint8List ungzipBytes(Uint8List data) {
return asUint8List(GZipDecoder().decodeBytes(data));
}
23 changes: 23 additions & 0 deletions app_archive/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: tekartik_app_archive
description: Archive utility
version: 1.3.0
homepage: https://github.com/tekartik/app_common_utils.dart

publish_to: none

environment:
sdk: ^3.5.0

dependencies:
archive: ">=3.6.1"
tekartik_common_utils:
git:
url: https://github.com/tekartik/common_utils.dart
ref: dart3a
dev_dependencies:
path:
dev_build:
test: '>=1.6.0'
process_run:
build_runner:
build_test:
122 changes: 122 additions & 0 deletions app_archive/test/gzip_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
// ignore_for_file: avoid_print

import 'package:tekartik_app_archive/gzip.dart';
import 'package:tekartik_common_utils/byte_utils.dart';
import 'package:tekartik_common_utils/hex_utils.dart';
import 'package:tekartik_common_utils/list_utils.dart';
import 'package:tekartik_common_utils/string_utils.dart';
import 'package:test/test.dart';

extension Shuffle on String {
/// Strings are [immutable], so this getter returns a shuffled string
/// rather than modifying the original.
String get shuffled => (split('')..shuffle()).join('');
}

void main() {
group('gzip', () {
test('compress bigbytes', () {
var allBytes = List.generate(256, (index) => index);

var bigBytes = asUint8List(listFlatten(
List.generate(50000, (i) => allBytes..shuffle()).toList()));
print(
'bigUint8List ${bigBytes.length} ${toHexString(bigBytes.sublist(0, 128))}');
var sw = Stopwatch()..start();

var compressed = gzipBytes(bigBytes, noDate: true);
sw.stop();
print('compressed ${compressed.length} ${sw.elapsed}');
expect(gzipBytes(bigBytes, noDate: true), compressed);
//print('compressed ${compressed.length}');
expect(ungzipBytes(compressed), bigBytes);
});
test('compress bigtext', () {
var text = 'abcdedfghijklmnopqrstuvwxyz';
var bigText = List.generate(50000, (i) => text.shuffled).join();
print('bigText ${bigText.length} ${bigText.truncate(128)}');
var sw = Stopwatch()..start();
var compressed = gzipText(bigText, noDate: true);
sw.stop();
print('compressed ${compressed.length} ${sw.elapsed}');
expect(gzipText(bigText, noDate: true), compressed);
//print('compressed ${compressed.length}');
expect(ungzipText(compressed), bigText);
});
test('compress', () {
expect(gzipText('étoile', noDate: true), [
31,
139,
8,
0,
0,
0,
0,
0,
0,
255,
59,
188,
178,
36,
63,
51,
39,
21,
0,
199,
250,
11,
130,
7,
0,
0,
0,
]);

void roundTrip(String text) {
expect(ungzipText(gzipText(text)), text);
}

roundTrip('étoile');
var bigText =
String.fromCharCodes(List.generate(5000000, (index) => index % 255));
roundTrip(bigText);
expect(gzipText(bigText).length, 33103);
});

test('decompress', () {
expect(
ungzipText(asUint8List([
31,
139,
8,
0,
0,
0,
0,
0,
0,
255,
59,
188,
178,
36,
63,
51,
39,
21,
0,
199,
250,
11,
130,
7,
0,
0,
0
])),
'étoile');
});
});
}
1 change: 1 addition & 0 deletions repo_support/tool/run_ci.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Future main() async {
'app_sembast',
'app_sqflite',
'app_prefs',
'app_archive',
]) {
await packageRunCi(join('..', dir));
}
Expand Down

0 comments on commit 2047def

Please sign in to comment.