Open clee opened 13 years ago
I want to get this feature added, however, I haven't been able to find a (good enough) explanation of the file format. I've even found a few open source implementations, and I still haven't figured out the format quite right.
If you know of any good explanation of the format, I'd be glad to try and implement it.
sigh, I had a gist a long time ago that somebody wrote that implemented this in node. I Starred the gist, but the original person deleted it :(
In any case, here's some reference files to base a parser implementation off of: http://opensource.apple.com/source/CF/CF-550/CFBinaryPList.c https://github.com/ckruse/CFPropertyList/blob/master/lib/rbBinaryCFPropertyList.rb
I think you may be talking about a gist I put up... https://gist.github.com/1007217 has the code I was able to get working.
However, this code:
Ya, that's the one! It's a good starting point at least. Do you know what the actual problems are with it?
On Fri, Jun 3, 2011 at 2:38 PM, clee < reply@reply.github.com>wrote:
I think you may be talking about a gist I put up... https://gist.github.com/1007217 has the code I was able to get working.
However, this code:
- Doesn't handle floats correctly
- Doesn't handle dates correctly
Reply to this email directly or view it on GitHub: https://github.com/TooTallNate/node-plist/issues/2#comment_1299623
From what I understand, all Javascript implementations store numbers internally as double
s (even what appear to be integers!)[1]. There are two problems; the first one is that bplists can contain 32-bit float
s as well as 64-bit double
s, and so you need two separate code paths for decoding them into the native JS Number type. The other problem is that decoding them is not exactly straightforward - there's no simple way I've found yet to unpack a 4-byte buffer into a float
, or an 8-byte buffer into a double
.
The good news is, solving the double
case also solves the date case - all dates in bplists are stored as a 64-bit double
value, which is an offset since the epoch (although I think Apple uses a different epoch than the usual UNIX one). Anyway, once we can parse double
s correctly, dates should be trivial to implement.
[1]: See http://www.jwz.org/blog/2010/10/every-day-i-learn-something-new-and-stupid/
:+1:
Though i might help you out with the date parsing.
as @clee mention above, Apple isn't using UNIX epoch for dates, rather using it's own epoch which is relative to Jan 1 2001 00:00:00 GMT in seconds. Check CoreFoundation's CFDateGetAbsoluteTime(theDate)
for more information.
function toDate(absoluteTime){
var time = 978307200000; // relation to unix epoc in millisecounds (should be correct).
time = time + (absoluteTime * 1000);
return new Date(time);
}
I have a working binary plist parser I created this weekend written in node. https://github.com/nearinfinity/node-bplist-parser
It would probably make sense to merge my module into yours or just call my module from yours when you detect that it's a binary plist.
@joeferner That's awesome!
+1!
@TooTallNate if I submit this integration as a pull request does it have a reasonable chance at inclusion?
@joeferner @mreinstein @clee @raweden @goshakkk Guys, to be honest, since I don't actively use this module anymore, I don't have much interest in maintaining it. It would be really killer if somebody wanted to accept commit rights to this repo, and give it some love. Any takers?
@TooTallNate I'm not opposed to maintaining it. I'm actively using this in my project, and will be for the near future. I'm happy to try to work with everyone to get submitted patches in, especially the plist builder and binary plist support. Let me know what I need to do and I'll pick up on this right away.
Thanks Nate!
@mreinstein Cool, good enough for me! I've just added you as a committer. :+1: for plist builder and binary plist support! Also, what's your npm username so you can publish new versions? Thanks!
@TooTallNate nice, thanks. my username on npm is mreinstein
@joeferner I noticed you're still maintaining your bplist parser. I'm interested in merging or calling your bplist package. May also make sense to include your bplist-creator module. Wondering what you consider a viable strategy for detecting binary plists? I was thinking something along these lines:
// detect if a file is ascii by looking for an octet with a val > 127
// @param plist the content of the plist file as a string
function fileIsAscii(plist) {
// as soon as we hit an octet > 127, we prob have binary
for (var i=0, len=plist.length; i<len; i++) {
if (plist[i] > 127) { return false; }
}
return true;
}
@mreinstein You are free to call or merge bplist-parser or bplist-creator. In trying to keep with substacks philosophy I've been trying to keep my modules small and focused on a single task so I would lean towards just calling my modules but it's your call.
As far as detecting binary plists, all binary plists start with the string "bplist" so you could check for that.
@joeferner I agree with the unix tooling philosophy you mentioned. So "bplist" is basically the magic header found in other file formats like gif etc. Very cool.
probably useful for writing binary plists, need to investigate this in more detail: https://github.com/nearinfinity/node-bplist-creator
Any news on merging the binary parser in? Or are you keeping the packages separate?
@matiassingers not opposed to adding binary parser support. can you provide some tests/sample binary file for this?
@mreinstein I was actually about to write a wrapper around plist.js
and bplist-parser
, but found wollardj/node-simple-plist - which does pretty much exactly that.
Wraps both libraries and calls the appropriate one based on the type of .plist
file.
Would the easiest path here be to converting the plist files with a callout to the "plutil" executable that should be available on any Mac that also has Xcode?
@tsanidas The problem with that is that these libraries work on other non-OS X systems like Linux that don't have plutil by default.
It would be really handy.