Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit fdd3bdb

Browse files
committedNov 22, 2024·
feat: remove iconv from lite connection.
Reduces a minified code size from ~850kb to ~580kb.
1 parent 6d49eb5 commit fdd3bdb

File tree

6 files changed

+79
-10
lines changed

6 files changed

+79
-10
lines changed
 

‎src/connection.ts

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import iconv from 'iconv-lite';
12
import { once } from 'events';
23

34
import {
@@ -31,6 +32,7 @@ import Message from './message';
3132
import NTLMResponsePayload from './ntlm-payload';
3233
import { Login7TokenHandler } from './token/handler';
3334
import { createNTLMRequest } from './ntlm';
35+
import { setCodec } from './conv';
3436

3537
export type InternalConnectionOptions = LiteInternalConnectionOptions;
3638
export type ConnectionConfiguration = LiteConnectionConfiguration;
@@ -506,3 +508,5 @@ class Connection extends LiteConnection {
506508

507509
export default Connection;
508510
module.exports = Connection;
511+
512+
setCodec(iconv);

‎src/conv.ts

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
const cp1252 = Buffer.from('\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~€�‚ƒ„…†‡ˆ‰Š‹Œ�Ž��‘’“”•–—˜™š›œ�žŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ', 'ucs2');
2+
const invCp1212 = new Map([[129, 129], [141, 141], [143, 143], [144, 144], [157, 157], [160, 160], [161, 161], [162, 162], [163, 163], [164, 164], [165, 165], [166, 166], [167, 167], [168, 168], [169, 169], [170, 170], [171, 171], [172, 172], [173, 173], [174, 174], [175, 175], [176, 176], [177, 177], [178, 178], [179, 179], [180, 180], [181, 181], [182, 182], [183, 183], [184, 184], [185, 185], [186, 186], [187, 187], [188, 188], [189, 189], [190, 190], [191, 191], [192, 192], [193, 193], [194, 194], [195, 195], [196, 196], [197, 197], [198, 198], [199, 199], [200, 200], [201, 201], [202, 202], [203, 203], [204, 204], [205, 205], [206, 206], [207, 207], [208, 208], [209, 209], [210, 210], [211, 211], [212, 212], [213, 213], [214, 214], [215, 215], [216, 216], [217, 217], [218, 218], [219, 219], [220, 220], [221, 221], [222, 222], [223, 223], [224, 224], [225, 225], [226, 226], [227, 227], [228, 228], [229, 229], [230, 230], [231, 231], [232, 232], [233, 233], [234, 234], [235, 235], [236, 236], [237, 237], [238, 238], [239, 239], [240, 240], [241, 241], [242, 242], [243, 243], [244, 244], [245, 245], [246, 246], [247, 247], [248, 248], [249, 249], [250, 250], [251, 251], [252, 252], [253, 253], [254, 254], [255, 255], [338, 140], [339, 156], [352, 138], [353, 154], [376, 159], [381, 142], [382, 158], [402, 131], [710, 136], [732, 152], [8211, 150], [8212, 151], [8216, 145], [8217, 146], [8218, 130], [8220, 147], [8221, 148], [8222, 132], [8224, 134], [8225, 135], [8226, 149], [8230, 133], [8240, 137], [8249, 139], [8250, 155], [8364, 128], [8482, 153]]);
3+
4+
let decoder = (buffer: Buffer, encoding: string): string => {
5+
if (encoding === 'WINDOWS-1252' || encoding === 'CP1252') {
6+
let pureAscii = true;
7+
for (let i = 0; i !== buffer.length; ++i) {
8+
if (0x7F < buffer[i]) {
9+
pureAscii = false;
10+
break;
11+
}
12+
}
13+
if (pureAscii) {
14+
return buffer.toString('ascii');
15+
}
16+
const ucs2Buffer = Buffer.alloc(buffer.length * 2);
17+
for (let i = 0, idx1 = 0, idx2 = 0; i !== buffer.length; ++i) {
18+
idx1 = buffer[i] * 2; idx2 = i * 2;
19+
ucs2Buffer[idx2] = cp1252[idx1];
20+
ucs2Buffer[idx2 + 1] = cp1252[idx1 + 1];
21+
}
22+
return ucs2Buffer.toString('ucs2');
23+
}
24+
return buffer.toString(encoding as BufferEncoding);
25+
};
26+
27+
let encoder = (content: string, encoding: string): Buffer => {
28+
if (encoding === 'WINDOWS-1252' || encoding === 'CP1252') {
29+
let pureAscii = true;
30+
for (let i = 0; i !== content.length; ++i) {
31+
if (content[i].charCodeAt(0) >= 128) {
32+
pureAscii = false;
33+
break;
34+
}
35+
}
36+
if (pureAscii) {
37+
return Buffer.from(content, 'ascii');
38+
}
39+
const length = content.length;
40+
const result = new Uint16Array(length);
41+
for (let index = 0; index < length; index++) {
42+
const codePoint = content.charCodeAt(index);
43+
if (codePoint <= 0x7F) {
44+
result[index] = codePoint;
45+
continue;
46+
}
47+
result[index] = invCp1212.get(codePoint) ?? 0xFFFD;
48+
}
49+
return Buffer.from(result);
50+
}
51+
return Buffer.from(content, encoding as BufferEncoding);
52+
};
53+
54+
export function setCodec(codec: {
55+
decode: (buffer: Buffer, encoding: string) => string;
56+
encode: (content: string, encoding: string) => Buffer;
57+
}): void {
58+
decoder = codec.decode;
59+
encoder = codec.encode;
60+
}
61+
62+
export function decode(buffer: Buffer, encoding: string): string {
63+
return decoder(buffer, encoding);
64+
}
65+
export function encode(content: string, encoding: string): Buffer {
66+
return encoder(content, encoding);
67+
}

‎src/data-types/char.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import iconv from 'iconv-lite';
21
import { type DataType } from '../data-type';
2+
import { encode } from '../conv';
33

44
const NULL_LENGTH = Buffer.from([0xFF, 0xFF]);
55

@@ -92,7 +92,7 @@ const Char: { maximumLength: number } & DataType = {
9292
throw new Error('The collation set by the server has no associated encoding.');
9393
}
9494

95-
return iconv.encode(value, collation.codepage);
95+
return encode(value, collation.codepage);
9696
}
9797
};
9898

‎src/data-types/text.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import iconv from 'iconv-lite';
2-
31
import { type DataType } from '../data-type';
2+
import { encode } from '../conv';
43

54
const NULL_LENGTH = Buffer.from([0xFF, 0xFF, 0xFF, 0xFF]);
65

@@ -76,7 +75,7 @@ const Text: DataType = {
7675
throw new Error('The collation set by the server has no associated encoding.');
7776
}
7877

79-
return iconv.encode(value, collation.codepage);
78+
return encode(value, collation.codepage);
8079
}
8180
};
8281

‎src/data-types/varchar.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import iconv from 'iconv-lite';
2-
31
import { type DataType } from '../data-type';
2+
import { encode } from '../conv';
43

54
const MAX = (1 << 16) - 1;
65
const UNKNOWN_PLP_LEN = Buffer.from([0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]);
@@ -124,7 +123,7 @@ const VarChar: { maximumLength: number } & DataType = {
124123
throw new Error('The collation set by the server has no associated encoding.');
125124
}
126125

127-
return iconv.encode(value, collation.codepage);
126+
return encode(value, collation.codepage);
128127
}
129128
};
130129

‎src/value-parser.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ import Parser, { type ParserOptions } from './token/stream-parser';
22
import { type Metadata, readCollation } from './metadata-parser';
33
import { TYPE } from './data-type';
44

5-
import iconv from 'iconv-lite';
65
import { sprintf } from 'sprintf-js';
76
import { bufferToLowerCaseGuid, bufferToUpperCaseGuid } from './guid-parser';
87
import { NotEnoughDataError, Result, readBigInt64LE, readDoubleLE, readFloatLE, readInt16LE, readInt32LE, readUInt16LE, readUInt32LE, readUInt8, readUInt24LE, readUInt40LE, readUNumeric64LE, readUNumeric96LE, readUNumeric128LE } from './token/helpers';
8+
import { decode } from './conv';
99

1010
const NULL = (1 << 16) - 1;
1111
const MAX = (1 << 16) - 1;
@@ -573,7 +573,7 @@ function readChars(buf: Buffer, offset: number, dataLength: number, codepage: st
573573
throw new NotEnoughDataError(offset + dataLength);
574574
}
575575

576-
return new Result(iconv.decode(buf.slice(offset, offset + dataLength), codepage ?? DEFAULT_ENCODING), offset + dataLength);
576+
return new Result(decode(buf.slice(offset, offset + dataLength), codepage ?? DEFAULT_ENCODING), offset + dataLength);
577577
}
578578

579579
function readNChars(buf: Buffer, offset: number, dataLength: number): Result<string> {

0 commit comments

Comments
 (0)
Please sign in to comment.