Adopt changes from Kiwix JS for MIME type map

Former-commit-id: f8f1f27226d73ebd6ad158d8ce99235e73fe11f1 [formerly 8f8c60e1f9aefada72a7fb81522f8599aef7d18d]
Former-commit-id: 8c1d6f14aa2d8cfb5dea16ee98a5274dc05a7353
This commit is contained in:
Jaifroid 2019-05-17 18:37:00 +01:00
parent 40f3db56e4
commit cb15c17438
5 changed files with 63 additions and 60 deletions

View File

@ -3173,7 +3173,7 @@ define(['jquery', 'zimArchiveLoader', 'util', 'uiUtil', 'cookies', 'q', 'module'
selectedArchive.getDirEntryByTitle(title).then(function (dirEntry) {
selectedArchive.readBinaryFile(dirEntry, function (fileDirEntry, content) {
var url = fileDirEntry.url;
var mimetype = selectedArchive.getMimetype(dirEntry.mimetype);
var mimetype = dirEntry.getMimetype();
if (!dataRequested) {
uiUtil.feedNodeWithBlob(image, 'src', content, mimetype, params.allowHTMLExtraction);
}

View File

@ -58,7 +58,7 @@ define(['q', 'jquery'], function(q, jQuery) {
};
// We try to match both a standalone ZIM file (.zim) or
// the first file of a splitted ZIM files collection (.zimaa)
// the first file of a split ZIM files collection (.zimaa)
var regexpZIMFileName = /\.zim(aa)?$/i;
/**

View File

@ -115,16 +115,6 @@ define(['zimfile', 'zimDirEntry', 'util', 'utf8'],
return this._file !== null;
};
/**
* Looks up the dirEntry's mimetype number in the ZIM file's MIME type list, and returns the corresponding MIME type
*
* @param {Integer} mimetype The mimetype number stored in dirEntry.mimetype, used as a lookup value
* @return {String} The MIME type corresponding to mimetype in the ZIM file's MIME type list
*/
ZIMArchive.prototype.getMimetype = function(mimetype) {
return this._file.mimeTypes.get(mimetype);
};
/**
* Looks for the DirEntry of the main page
* @param {callbackDirEntry} callback

View File

@ -31,7 +31,7 @@ define([], function() {
* @property {File} _zimfile The ZIM file
* @property {Boolean} redirect
* @property {Integer} offset
* @property {Integer} mimetype MIME type number as defined in the MIME type list
* @property {Integer} mimetypeInteger MIME type number as defined in the MIME type list
* @property {String} namespace defines to which namespace this directory entry belongs
* @property {Integer} redirectTarget
* @property {Integer} cluster cluster number in which the data of this directory entry is stored
@ -49,7 +49,7 @@ define([], function() {
this._zimfile = zimfile;
this.redirect = dirEntryData.redirect;
this.offset = dirEntryData.offset;
this.mimetype = dirEntryData.mimetype;
this.mimetypeInteger = dirEntryData.mimetypeInteger;
this.namespace = dirEntryData.namespace;
this.redirectTarget = dirEntryData.redirectTarget;
this.cluster = dirEntryData.cluster;
@ -66,7 +66,7 @@ define([], function() {
*/
DirEntry.prototype.toStringId = function() {
//@todo also store isRedirect and redirectTarget
return this.offset + '|' + this.mimetype + '|' + this.namespace + '|' + this.cluster + '|' +
return this.offset + '|' + this.mimetypeInteger + '|' + this.namespace + '|' + this.cluster + '|' +
this.blob + '|' + this.url + '|' + this.title + '|' + this.redirect + '|' + this.redirectTarget;
};
@ -96,7 +96,7 @@ define([], function() {
var data = {};
var idParts = stringId.split("|");
data.offset = parseInt(idParts[0], 10);
data.mimetype = parseInt(idParts[1], 10);
data.mimetypeInteger = parseInt(idParts[1], 10);
data.namespace = idParts[2];
data.cluster = parseInt(idParts[3], 10);
data.blob = parseInt(idParts[4], 10);
@ -117,6 +117,15 @@ define([], function() {
return this.title ? this.title : this.url;
};
/**
* Looks up the dirEntry's mimetype number in the ZIM file's MIME type list, and returns the corresponding MIME type
*
* @return {String} The MIME type corresponding to mimetypeInteger in the ZIM file's MIME type list
*/
DirEntry.prototype.getMimetype = function() {
return this._zimfile.mimeTypes.get(this.mimetypeInteger);
};
/**
* Functions and classes exposed by this module
*/

View File

@ -110,42 +110,6 @@ define(['xzdec_wrapper', 'util', 'utf8', 'q', 'zimDirEntry'], function(xz, util,
}
};
/**
* Reads the whole MIME type list and returns it as a populated Map
* The mimeTypeMap is extracted once after the user has picked the ZIM file
* and is stored as ZIMFile.mimetypes.
*
* @returns {Promise} A promise for the MIME Type list as a Map
*/
ZIMFile.prototype._mimeTypeMap = function() {
var typeMap = new Map;
return this._readSlice(this.mimeListPos, 256).then(function(data) {
// DEV: We have read 256 bytes: increase this if you encounter longer MIME type lists
// also change "while (pos < 255)" below
if (data.subarray) {
var i = 1;
var pos = -1;
var mimeString;
while (pos < 255) {
pos++;
mimeString = utf8.parse(data.subarray(pos), true);
// If the parsed data is an empty string, we have reached the end of the MIME type list, so break
if (!mimeString) break;
// Store the parsed string in the Map
typeMap.set(i, mimeString);
i++;
while (data[pos]) {
pos++;
}
}
}
return typeMap;
}).fail(function(err) {
console.errror('Unable to read MIME type list: ' + err);
return new Map;
});
};
/**
*
* @param {Integer} offset
@ -159,10 +123,10 @@ define(['xzdec_wrapper', 'util', 'utf8', 'q', 'zimDirEntry'], function(xz, util,
var dirEntry =
{
offset: offset,
mimetype: readInt(data, 0, 2),
mimetypeInteger: readInt(data, 0, 2),
namespace: String.fromCharCode(data[3])
};
dirEntry.redirect = (dirEntry.mimetype === 0xffff);
dirEntry.redirect = (dirEntry.mimetypeInteger === 0xffff);
if (dirEntry.redirect)
dirEntry.redirectTarget = readInt(data, 8, 4);
else
@ -244,6 +208,45 @@ define(['xzdec_wrapper', 'util', 'utf8', 'q', 'zimDirEntry'], function(xz, util,
});
};
/**
* Reads the whole MIME type list and returns it as a populated Map
* The mimeTypeMap is extracted once after the user has picked the ZIM file
* and is stored as ZIMFile.mimeTypes
*
* @param {File} file The ZIM file (or first file in array of files) from which the MIME type list
* is to be extracted
* @param {Integer} mimeListPos The offset in <file> at which the MIME type list is found
* @param {Integer} urlPtrPos The offset of the byte after the end of the MIME type list in <file>
* @returns {Promise} A promise for the MIME Type list as a Map
*/
function readMimetypeMap(file, mimeListPos, urlPtrPos) {
var typeMap = new Map;
var size = urlPtrPos - mimeListPos;
return util.readFileSlice(file, mimeListPos, size).then(function(data) {
if (data.subarray) {
var i = 1;
var pos = -1;
var mimeString;
while (pos < size) {
pos++;
mimeString = utf8.parse(data.subarray(pos), true);
// If the parsed data is an empty string, we have reached the end of the MIME type list, so break
if (!mimeString) break;
// Store the parsed string in the Map
typeMap.set(i, mimeString);
i++;
while (data[pos]) {
pos++;
}
}
}
return typeMap;
}).fail(function(err) {
console.error('Unable to read MIME type list', err);
return new Map;
});
}
return {
/**
*
@ -263,21 +266,22 @@ define(['xzdec_wrapper', 'util', 'utf8', 'q', 'zimDirEntry'], function(xz, util,
}
return 0;
});
return util.readFileSlice(fileArray[0], 0, 80).then(function(header)
{
return util.readFileSlice(fileArray[0], 0, 80).then(function(header) {
var mimeListPos = readInt(header, 56, 8);
var urlPtrPos = readInt(header, 32, 8);
return readMimetypeMap(fileArray[0], mimeListPos, urlPtrPos).then(function(data) {
var zf = new ZIMFile(fileArray);
zf.articleCount = readInt(header, 24, 4);
zf.clusterCount = readInt(header, 28, 4);
zf.urlPtrPos = readInt(header, 32, 8);
zf.urlPtrPos = urlPtrPos;
zf.titlePtrPos = readInt(header, 40, 8);
zf.clusterPtrPos = readInt(header, 48, 8);
zf.mimeListPos = readInt(header, 56, 8);
zf.mimeListPos = mimeListPos;
zf.mainPage = readInt(header, 64, 4);
zf.layoutPage = readInt(header, 68, 4);
zf._mimeTypeMap().then(function(data) {
zf.mimeTypes = data;
return zf;
});
return zf;
});
}
};