You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
194 lines
4.5 KiB
194 lines
4.5 KiB
12 years ago
|
define([
|
||
|
"backbone"
|
||
|
, "models/dmap-type"
|
||
|
, "collections/dmap"
|
||
|
]
|
||
|
, function (Backbone, DMAPType, DMAPCollection) {
|
||
|
var that
|
||
|
|
||
|
, Model = Backbone.Model.extend({
|
||
|
idAttribute: "_id"
|
||
|
|
||
|
, initialize: function (attributes, options) {
|
||
|
that = this;
|
||
|
|
||
|
this.contentCodes = options && options.contentCodes || null;
|
||
|
console.log("Initial", options, this.contentCodes);
|
||
|
|
||
|
if (options.buffer instanceof ArrayBuffer) {
|
||
|
attributes = parseWrapper(options.buffer);
|
||
|
delete options.buffer;
|
||
|
|
||
|
this.set(attributes);
|
||
|
}
|
||
|
|
||
|
return this;
|
||
|
}
|
||
|
/*
|
||
|
, set: function (attributes, options) {
|
||
|
console.log(attributes, options);
|
||
|
|
||
|
this._id = attributes["dmap.persistentid"] || attributes["dmap.itemid"] || attributes["dmap.containeritemid"];
|
||
|
|
||
|
Model.__super__.set(this, arguments);
|
||
|
|
||
|
return this;
|
||
|
}
|
||
|
*/
|
||
|
, update: function (attributes, options) {
|
||
|
that.trigger("dmap.model.update", this, arguments);
|
||
|
|
||
|
return that.apply(that, arguments);
|
||
|
}
|
||
|
|
||
|
, parse: function (reponse) {
|
||
|
return that.attributes;
|
||
|
}
|
||
|
|
||
|
, fetch: function (options) {
|
||
|
that.trigger("dmap.model.fetch", this, arguments);
|
||
|
|
||
|
return that;
|
||
|
}
|
||
|
|
||
|
, save: function (attributes, options) {
|
||
|
that.trigger("dmap.model.save", this, arguments);
|
||
|
|
||
|
return that;
|
||
|
}
|
||
|
|
||
|
, destroy: function (options) {
|
||
|
that.trigger("dmap.model.destroy", this, arguments);
|
||
|
|
||
|
return that;
|
||
|
}
|
||
|
|
||
|
, unset: function (options) {
|
||
|
that.trigger("dmap.model.unset", this, arguments);
|
||
|
|
||
|
return that;
|
||
|
}
|
||
|
|
||
|
, clear: function (options) {
|
||
|
that.trigger("dmap.model.unset", this, arguments);
|
||
|
|
||
|
return that;
|
||
|
}
|
||
|
})
|
||
|
|
||
|
, parseCodeDictionnary = function(dictChunk) {
|
||
|
var codeElement = {};
|
||
|
|
||
|
while (dictChunk.byteLength > 8) {
|
||
|
var contentCode = DMAPType.getType(dictChunk);
|
||
|
var contentLength = DMAPType.getInt32(dictChunk.slice(4,8));
|
||
|
//console.log(contentLength);
|
||
|
|
||
|
switch (contentCode) {
|
||
|
case 'mcnm':
|
||
|
codeElement.code = DMAPType.getString(dictChunk.slice(8, 8+contentLength));
|
||
|
break;
|
||
|
|
||
|
case 'mcna':
|
||
|
var codeName = DMAPType.getString(dictChunk.slice(8, 8+contentLength));
|
||
|
codeElement.name = codeName.replace(/\./g, '_');
|
||
|
//console.log(codeElement.name);
|
||
|
break;
|
||
|
|
||
|
case 'mcty':
|
||
|
var typeData = DMAPType.getInt16(dictChunk.slice(8, 8+contentLength));
|
||
|
codeElement.type = new DMAPType(typeData);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
dictChunk = dictChunk.slice(8+contentLength);
|
||
|
}
|
||
|
|
||
|
return codeElement;
|
||
|
}
|
||
|
|
||
|
, parseBinaryChunk = function (binaryChunk) {
|
||
|
var entry = {};
|
||
|
|
||
|
while (binaryChunk.byteLength > 8) {
|
||
|
var tagName = DMAPType.getType(binaryChunk);
|
||
|
var tagLength = DMAPType.getInt32(binaryChunk.slice(4,8));
|
||
|
//console.debug(codeInfo, tagName, tagLength);
|
||
|
|
||
|
if (that.contentCodes === null) {
|
||
|
switch (tagName) {
|
||
|
case 'mdcl':
|
||
|
var contentCode = parseCodeDictionnary(binaryChunk.slice(8, 8+tagLength));
|
||
|
var codeId = contentCode.code.toLowerCase();
|
||
|
|
||
|
entry[codeId] = _.extend({}, contentCode, contentCode.type);
|
||
|
break;
|
||
|
|
||
|
case 'mstt':
|
||
|
// Nothing to do with the status, skip it
|
||
|
break;
|
||
|
}
|
||
|
} else {
|
||
|
var codeInfo = that.contentCodes.get(tagName);
|
||
|
|
||
|
if (codeInfo) {
|
||
|
if (codeInfo.type === 12) {
|
||
|
if (typeof entry[codeInfo.name] === "undefined") {
|
||
|
// Here we might want to select different collection types depending on the tag
|
||
|
entry[codeInfo.name] = new DMAPCollection();
|
||
|
}
|
||
|
|
||
|
entry[codeInfo.name].add(binaryChunk.slice(8, tagLength), {silent: true});
|
||
|
} else {
|
||
|
//console.log(codeInfo);
|
||
|
entry[codeInfo.name] = codeInfo.unpack(binaryChunk.slice(8), tagLength);
|
||
|
}
|
||
|
} else {
|
||
|
// TODO: we should try to guess.
|
||
|
console.info("Unknown type: " + tagName + "(" + tagLength + ")");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
binaryChunk = binaryChunk.slice(8 + tagLength);
|
||
|
}
|
||
|
|
||
|
return entry;
|
||
|
}
|
||
|
|
||
|
, parseWrapper = function(binaryData) {
|
||
|
console.log(DMAPType);
|
||
|
var containerType = DMAPType.getType(binaryData);
|
||
|
//var binaryLength = DMAPType.getUint32(binaryData.slice(4,8));
|
||
|
var contentData = binaryData.slice(8);
|
||
|
|
||
|
switch (containerType) {
|
||
|
// Update
|
||
|
case "mupd":
|
||
|
// Unsupported
|
||
|
return;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
console.info("Unknown type: " + containerType/*, binaryLength*/, contentData);
|
||
|
// Content codes
|
||
|
case "mccr":
|
||
|
// Server Info
|
||
|
case "msrv":
|
||
|
// Login
|
||
|
case "mlog":
|
||
|
// Database
|
||
|
case "adbs":
|
||
|
// Database info
|
||
|
case "avdb":
|
||
|
// Playlist info
|
||
|
case "aply":
|
||
|
// List of songs
|
||
|
case "apso":
|
||
|
return parseBinaryChunk(contentData);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
;
|
||
|
|
||
|
return Model;
|
||
|
});
|