شائع شدہ سورس
سورس ZIP ڈاؤن لوڈ کریں
CH-J SM Mobile
ایپلیکیشن کی کسی مخصوص ریلیز کی ڈائریکٹریز اور فائلیں دیکھیں۔
CH-J / SM Mobile
175 فائلیں
sm-mobile-20261016T185235Z-8e93ecc1b59a
شامل کیا گیا: · بلڈ کیا گیا:
1
import 'dart:convert';2
import 'dart:isolate';3
import 'dart:typed_data';4
import 'charset_tables.dart';6
/// Text encodings the editor can read and write without loss.7
enum TextEncoding {8
utf8('UTF-8'),9
utf8Bom('UTF-8 BOM'),10
utf16le('UTF-16 LE'),11
utf16be('UTF-16 BE'),12
windows1250('Windows-1250'),13
windows1252('Windows-1252'),14
iso88592('ISO-8859-2'),15
latin1('ISO-8859-1');17
final String label;18
const TextEncoding(this.label);20
/// The byte order mark written before the text, if any.21
List<int> get bom => switch (this) {22
utf8Bom => const [0xef, 0xbb, 0xbf],23
utf16le => const [0xff, 0xfe],24
utf16be => const [0xfe, 0xff],25
_ => const [],26
};27
}29
enum LineBreak {30
lf('LF', '\n'),31
crlf('CRLF', '\r\n'),32
cr('CR', '\r');34
final String label, value;35
const LineBreak(this.label, this.value);36
}38
/// A character the target encoding cannot represent.39
class UnencodableText implements Exception {40
final TextEncoding encoding;41
final String sample;42
final int count;43
const UnencodableText(this.encoding, this.sample, this.count);44
@override45
String toString() => 'UnencodableText(${encoding.label}, $sample ×$count)';46
}48
/// Line breaks used in a text.49
class LineBreakInfo {50
final int lf, crlf, cr;51
const LineBreakInfo(this.lf, this.crlf, this.cr);52
bool get mixed => [lf, crlf, cr].where((n) => n > 0).length > 1;53
LineBreak get dominant {54
if (crlf >= lf && crlf >= cr && crlf > 0) return LineBreak.crlf;55
if (cr > lf && cr > 0) return LineBreak.cr;56
return LineBreak.lf;57
}59
static LineBreakInfo of(String text) {60
var lf = 0, crlf = 0, cr = 0;61
for (var i = 0; i < text.length; i++) {62
final c = text.codeUnitAt(i);63
if (c == 0x0d) {64
if (i + 1 < text.length && text.codeUnitAt(i + 1) == 0x0a) {65
crlf++;66
i++;67
} else {68
cr++;69
}70
} else if (c == 0x0a) {71
lf++;72
}73
}74
return LineBreakInfo(lf, crlf, cr);75
}76
}78
/// The result of reading a file as text.79
class DecodedText {80
final String text;81
final TextEncoding encoding;82
final LineBreakInfo lineBreaks;83
final bool finalNewline;85
/// True when the bytes come back unchanged if the text is saved86
/// unchanged with [encoding] and the dominant line break.87
final bool exact;88
const DecodedText(89
this.text,90
this.encoding,91
this.lineBreaks,92
this.finalNewline, {93
required this.exact,94
});95
}97
/// Whether [bytes] are most likely not text: NUL bytes or many control98
/// characters, unless the data is UTF-16.99
bool looksBinary(Uint8List bytes) {100
final n = bytes.length < 8192 ? bytes.length : 8192;101
if (n == 0) return false;102
if (_utf16Guess(bytes) != null) return false;103
var control = 0;104
for (var i = 0; i < n; i++) {105
final b = bytes[i];106
if (b == 0) return true;107
if (b < 0x09 || (b > 0x0d && b < 0x20)) control++;108
}109
return control * 10 > n;110
}112
bool _startsWith(Uint8List b, List<int> prefix) {113
if (b.length < prefix.length) return false;114
for (var i = 0; i < prefix.length; i++) {115
if (b[i] != prefix[i]) return false;116
}117
return true;118
}120
/// UTF-16 without a byte order mark, recognised by NUL bytes in every121
/// other position (mostly ASCII text).122
TextEncoding? _utf16Guess(Uint8List b) {123
final n = (b.length < 4096 ? b.length : 4096) & ~1;124
if (n < 4) return null;125
var evenZero = 0, oddZero = 0;126
for (var i = 0; i < n; i += 2) {127
if (b[i] == 0) evenZero++;128
if (b[i + 1] == 0) oddZero++;129
}130
final pairs = n ~/ 2;131
if (oddZero > pairs * 0.4 && evenZero < pairs * 0.05) {132
return TextEncoding.utf16le;133
}134
if (evenZero > pairs * 0.4 && oddZero < pairs * 0.05) {135
return TextEncoding.utf16be;136
}137
return null;138
}140
/// Detects the encoding: a byte order mark, then valid UTF-8, then UTF-16141
/// without BOM. Returns null when the encoding cannot be known (legacy142
/// 8-bit text); the user then chooses, nothing is converted silently.143
TextEncoding? detectEncoding(Uint8List bytes) {144
if (_startsWith(bytes, TextEncoding.utf8Bom.bom)) return TextEncoding.utf8Bom;145
if (_startsWith(bytes, TextEncoding.utf16le.bom)) return TextEncoding.utf16le;146
if (_startsWith(bytes, TextEncoding.utf16be.bom)) return TextEncoding.utf16be;147
final utf16 = _utf16Guess(bytes);148
if (utf16 != null) return utf16;149
try {150
utf8.decode(bytes);151
return TextEncoding.utf8;152
} on FormatException {153
return null;154
}155
}157
String _decodeSingleByte(Uint8List b, List<int>? high) {158
final units = Uint16List(b.length);159
for (var i = 0; i < b.length; i++) {160
final v = b[i];161
if (v < 0x80 || high == null) {162
units[i] = v;163
} else {164
final c = high[v - 0x80];165
if (c < 0) {166
throw FormatException('Byte 0x${v.toRadixString(16)} undefined', b, i);167
}168
units[i] = c;169
}170
}171
return String.fromCharCodes(units);172
}174
List<int>? _table(TextEncoding e) => switch (e) {175
TextEncoding.windows1250 => windows1250High,176
TextEncoding.windows1252 => windows1252High,177
TextEncoding.iso88592 => iso88592High,178
_ => null,179
};181
/// Decodes [bytes] as [encoding]. Throws [FormatException] for bytes that182
/// are not valid in that encoding.183
String decodeText(Uint8List bytes, TextEncoding encoding) {184
final bom = encoding.bom;185
final body = _startsWith(bytes, bom)186
? Uint8List.sublistView(bytes, bom.length)187
: bytes;188
switch (encoding) {189
case TextEncoding.utf8:190
case TextEncoding.utf8Bom:191
return utf8.decode(body);192
case TextEncoding.utf16le:193
case TextEncoding.utf16be:194
if (body.length.isOdd) {195
throw const FormatException('UTF-16 data has an odd length');196
}197
final le = encoding == TextEncoding.utf16le;198
final units = Uint16List(body.length ~/ 2);199
for (var i = 0; i < units.length; i++) {200
final a = body[2 * i], b = body[2 * i + 1];201
units[i] = le ? a | (b << 8) : (a << 8) | b;202
}203
// Unpaired surrogates would not survive a round trip.204
for (var i = 0; i < units.length; i++) {205
final u = units[i];206
if (u >= 0xd800 && u <= 0xdbff) {207
if (i + 1 >= units.length ||208
units[i + 1] < 0xdc00 ||209
units[i + 1] > 0xdfff) {210
throw FormatException('Unpaired surrogate', body, 2 * i);211
}212
i++;213
} else if (u >= 0xdc00 && u <= 0xdfff) {214
throw FormatException('Unpaired surrogate', body, 2 * i);215
}216
}217
return String.fromCharCodes(units);218
case TextEncoding.latin1:219
return _decodeSingleByte(body, null);220
case TextEncoding.windows1250:221
case TextEncoding.windows1252:222
case TextEncoding.iso88592:223
return _decodeSingleByte(body, _table(encoding));224
}225
}227
/// Encodes [text] as [encoding], including its byte order mark. Throws228
/// [UnencodableText] when a character cannot be represented, instead of229
/// replacing it.230
Uint8List encodeText(String text, TextEncoding encoding) {231
final out = BytesBuilder(copy: false)..add(encoding.bom);232
switch (encoding) {233
case TextEncoding.utf8:234
case TextEncoding.utf8Bom:235
out.add(utf8.encode(text));236
case TextEncoding.utf16le:237
case TextEncoding.utf16be:238
final le = encoding == TextEncoding.utf16le;239
final b = Uint8List(text.length * 2);240
for (var i = 0; i < text.length; i++) {241
final u = text.codeUnitAt(i);242
b[2 * i] = le ? u & 0xff : u >> 8;243
b[2 * i + 1] = le ? u >> 8 : u & 0xff;244
}245
out.add(b);246
case TextEncoding.latin1:247
case TextEncoding.windows1250:248
case TextEncoding.windows1252:249
case TextEncoding.iso88592:250
final table = _table(encoding);251
final reverse = <int, int>{252
if (table != null)253
for (var i = 0; i < 128; i++)254
if (table[i] >= 0) table[i]: 0x80 + i,255
};256
final b = Uint8List(text.length);257
String? sample;258
var bad = 0;259
for (var i = 0; i < text.length; i++) {260
final u = text.codeUnitAt(i);261
int? v;262
if (u < 0x80) {263
v = u;264
} else if (table == null) {265
v = u <= 0xff ? u : null;266
} else {267
v = reverse[u];268
}269
if (v == null) {270
bad++;271
sample ??= String.fromCharCode(u);272
v = 0x3f;273
}274
b[i] = v;275
}276
if (bad > 0) throw UnencodableText(encoding, sample!, bad);277
out.add(b);278
}279
return out.takeBytes();280
}282
bool _sameBytes(Uint8List a, Uint8List b) {283
if (a.length != b.length) return false;284
for (var i = 0; i < a.length; i++) {285
if (a[i] != b[i]) return false;286
}287
return true;288
}290
/// Decodes [bytes] for editing and records everything needed to write them291
/// back unchanged. Throws [FormatException] when [encoding] (or the292
/// detected one) does not fit, and [UnknownEncoding] when no encoding293
/// could be detected.294
DecodedText decodeDocument(Uint8List bytes, {TextEncoding? encoding}) {295
final enc = encoding ?? detectEncoding(bytes);296
if (enc == null) throw const UnknownEncoding();297
final text = decodeText(bytes, enc);298
final breaks = LineBreakInfo.of(text);299
final finalNewline = text.endsWith('\n') || text.endsWith('\r');300
bool exact;301
try {302
exact = !breaks.mixed && _sameBytes(encodeText(text, enc), bytes);303
} on UnencodableText {304
exact = false;305
}306
return DecodedText(text, enc, breaks, finalNewline, exact: exact);307
}309
class UnknownEncoding implements Exception {310
const UnknownEncoding();311
}313
/// Joins editor lines (already split on any line break) with [lineBreak].314
String withLineBreaks(String text, LineBreak lineBreak) {315
final normalized = text.replaceAll('\r\n', '\n').replaceAll('\r', '\n');316
return lineBreak == LineBreak.lf317
? normalized318
: normalized.replaceAll('\n', lineBreak.value);319
}321
/// [decodeDocument] on a background isolate for large files. Top-level so322
/// that the closure sent to the isolate captures only its arguments.323
Future<DecodedText> decodeInBackground(324
Uint8List bytes, {325
TextEncoding? encoding,326
}) => bytes.length > 256 * 1024327
? Isolate.run(() => decodeDocument(bytes, encoding: encoding))328
: Future.value(decodeDocument(bytes, encoding: encoding));330
/// [encodeText] on a background isolate for large texts.331
Future<Uint8List> encodeInBackground(String text, TextEncoding encoding) =>332
text.length > 256 * 1024333
? Isolate.run(() => encodeText(text, encoding))334
: Future.value(encodeText(text, encoding));SHA-256
0ad2c36cdc055a4dc3f5f3b416914869e48835e95b7f570e55adbf1188fc33daCH-J Proprietary Software License 1.14 · سورس CH-J Proprietary Software License 1.14 کے تحت فراہم کیا جاتا ہے۔ اس کی دستیابی لائسنس کی شرائط نہیں بدلتی اور نہ ہی اضافی حقوق دیتی ہے۔
آرکائیو کا SHA-256
46e427a43e87af091004f36145590bda8fe90086dfb0f631afeb5029fb0b5655