-
Notifications
You must be signed in to change notification settings - Fork 0
/
dauria.js
96 lines (86 loc) · 2.97 KB
/
dauria.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
var iconv = require('iconv-lite');
var Dauria = function(){
if (!(this instanceof Dauria)) return new Dauria();
};
var urldecodeBuffer = urlencoded => Buffer.concat(
// an Array of Buffers is generated from various parts of `urlencoded`:
urlencoded.split(
/(%[0-9A-Fa-f]{2})/
).map((fragment, idx) => {
if( idx % 2 === 0 ){ // simple string fragment's index: 0, 2, 4...
return Buffer.from(fragment, 'binary');
} else { // regex-captured fragment's index: 1, 3, 5...
return Buffer.from(fragment.replace(/%/g, ''), 'hex');
}
})
);
Dauria.prototype.getBase64DataURI = function(sourceBuffer, MIME){
if( typeof MIME === 'undefined' ) MIME = 'application/octet-stream';
return 'data:' + MIME + ';base64,' + sourceBuffer.toString('base64');
};
Dauria.prototype.parseDataURI = function(dataURI){
if(!( dataURI.startsWith('data:') )) throw new Error(
this.errors.MISSING_PREFIX
);
var commaSplit = dataURI.slice('data:'.length).split(',');
if( commaSplit.length < 2 ) throw new Error(this.errors.MISSING_COMMA);
var beforeData = commaSplit.shift();
var encodedData = commaSplit.join(',');
var semicolonSplit = beforeData.split(/;\s*/);
var base64 = false;
if(
semicolonSplit.length >= 2 &&
semicolonSplit[semicolonSplit.length - 1] === 'base64'
){
base64 = true;
semicolonSplit.pop();
}
var decodedBuffer;
if( base64 ){
decodedBuffer = Buffer.from(encodedData, 'base64');
} else { // not base64, i.e. urlencoded
decodedBuffer = urldecodeBuffer(encodedData);
}
if( semicolonSplit.length === 1 && semicolonSplit[0] === '' ){
semicolonSplit = [ 'text/plain', 'charset=US-ASCII' ];
}
var MIME = semicolonSplit[0];
var mediaType = semicolonSplit.join(';');
if(!( MIME.toLowerCase().startsWith('text/') )){ // not a text
return {
'MIME': MIME,
'mediaType': mediaType,
'buffer': decodedBuffer,
'text': null,
'charset': null
};
}
// we have a text; determine its encoding:
semicolonSplit.shift();
semicolonSplit = semicolonSplit.map(urlparam => {
if(!( urlparam.toLowerCase().startsWith('charset=') )){
return null; // not a charset parameter, drop it
}
var charset = urlparam.slice('charset='.length);
return charset;
}).filter(charset => charset !== null);
if( semicolonSplit.length === 0 ) semicolonSplit = ['US-ASCII'];
var decodedText;
if( iconv.encodingExists(semicolonSplit[0]) ){
decodedText = iconv.decode(decodedBuffer, semicolonSplit[0]);
} else {
decodedText = null;
}
return {
'MIME': MIME,
'mediaType': mediaType,
'buffer': decodedBuffer,
'charset': semicolonSplit[0],
'text': decodedText
};
};
Dauria.prototype.errors = {
MISSING_PREFIX: 'Cannot find "data:" in the beginning of the URL!',
MISSING_COMMA: 'Cannot find a comma in the given URL!'
};
module.exports = new Dauria();