Skip to content

Commit 7097194

Browse files
committed
added Iconv-lite based parser
1 parent 98800c5 commit 7097194

File tree

3 files changed

+54
-6
lines changed

3 files changed

+54
-6
lines changed

lib/packets/packet.js

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ var ErrorCodeToName = require('../constants/errors.js');
33
var NativeBuffer = require('buffer').Buffer;
44
var Buffer = require('safe-buffer').Buffer;
55
var Long = require('long');
6+
var StringParser = require('../parsers/string.js');
67

78
function Packet (id, buffer, start, end)
89
{
@@ -348,7 +349,10 @@ Packet.prototype.readLengthCodedString = function () {
348349
return null;
349350
}
350351
this.offset += len;
351-
return this.buffer.utf8Slice(this.offset - len, this.offset);
352+
353+
// becuase MySQL utf8 is actually cesu8
354+
// https://github.com/sidorares/node-mysql2/pull/374
355+
return StringParser.decode(this.buffer.slice(this.offset - len, this.offset), 'cesu8');
352356
};
353357

354358
Packet.prototype.readLengthCodedBuffer = function () {
@@ -736,9 +740,12 @@ Packet.prototype.writeString = function (s) {
736740
return;
737741
}
738742

739-
var bytes = Buffer.byteLength(s, 'utf8');
740-
this.buffer.write(s, this.offset, bytes, 'utf8');
741-
this.offset += bytes;
743+
// var bytes = Buffer.byteLength(s, 'utf8');
744+
// this.buffer.write(s, this.offset, bytes, 'utf8');
745+
// this.offset += bytes;
746+
747+
var buf = StringParser.encode(s, 'cesu8');
748+
this.offset += buf.copy(this.buffer, this.offset);
742749
};
743750

744751
Packet.prototype.writeLengthCodedString = function (s) {

lib/packets/query.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
var Buffer = require('safe-buffer').Buffer;
22
var Packet = require('../packets/packet.js');
33
var CommandCode = require('../constants/commands.js');
4+
var StringParser = require('../parsers/string.js');
45

5-
function Query (sql)
6+
function Query (sql, charsetNumber)
67
{
78
this.query = sql;
9+
this.charsetNumber = charsetNumber;
810
}
911

1012
Query.prototype.toPacket = function ()
1113
{
12-
var length = 5 + Buffer.byteLength(this.query, 'utf8');
14+
var buf = StringParser.encode(this.query, 'cesu8');
15+
var length = 5 + buf.length;
1316
var buffer = Buffer.allocUnsafe(length);
1417
var packet = new Packet(0, buffer, 0, length);
1518
packet.offset = 4;

lib/parsers/string.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
var Iconv = require('iconv-lite');
2+
var ParserCache = {};
3+
4+
function StringParser (encoding, options) {
5+
options = options || {};
6+
this.encoding = encoding;
7+
this.encoder = Iconv.getEncoder(encoding, options);
8+
this.decoder = Iconv.getDecoder(encoding, options);
9+
}
10+
11+
var prepareParser = function (encoding, options) {
12+
// if available use existing parser
13+
if (ParserCache[encoding]) {
14+
return ParserCache[encoding];
15+
}
16+
17+
// other wise prepare, cache and return
18+
ParserCache[encoding] = new StringParser(encoding, options);
19+
return ParserCache[encoding];
20+
};
21+
22+
exports.decode = function (buffer, encoding) {
23+
var parser = prepareParser(encoding);
24+
25+
var res = parser.decoder.write(buffer);
26+
var trail = parser.decoder.end();
27+
28+
return trail ? (res + trail) : res;
29+
};
30+
31+
exports.encode = function (string, encoding) {
32+
var parser = prepareParser(encoding);
33+
34+
var res = parser.encoder.write(string);
35+
var trail = parser.encoder.end();
36+
37+
return (trail && trail.length > 0) ? Buffer.concat([res, trail]) : res;
38+
};

0 commit comments

Comments
 (0)