TooTallNate / plist.js

Mac OS X Plist parser/builder for Node.js and browsers
MIT License
593 stars 123 forks source link

feature request: binary plist support #2

Open clee opened 13 years ago

clee commented 13 years ago

It would be really handy.

TooTallNate commented 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.

TooTallNate commented 13 years ago

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

clee commented 13 years ago

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:

TooTallNate commented 13 years ago

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

clee commented 13 years ago

From what I understand, all Javascript implementations store numbers internally as doubles (even what appear to be integers!)[1]. There are two problems; the first one is that bplists can contain 32-bit floats as well as 64-bit doubles, 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 doubles correctly, dates should be trivial to implement.

[1]: See http://www.jwz.org/blog/2010/10/every-day-i-learn-something-new-and-stupid/

goshacmd commented 12 years ago

:+1:

raweden commented 12 years ago

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);
}
joeferner commented 12 years ago

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.

clee commented 12 years ago

@joeferner That's awesome!

mreinstein commented 12 years ago

+1!

@TooTallNate if I submit this integration as a pull request does it have a reasonable chance at inclusion?

TooTallNate commented 12 years ago

@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?

mreinstein commented 12 years ago

@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!

TooTallNate commented 12 years ago

@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!

mreinstein commented 12 years ago

@TooTallNate nice, thanks. my username on npm is mreinstein

mreinstein commented 12 years ago

@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;
}
joeferner commented 12 years ago

@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.

mreinstein commented 12 years ago

@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.

mreinstein commented 12 years ago

probably useful for writing binary plists, need to investigate this in more detail: https://github.com/nearinfinity/node-bplist-creator

matiassingers commented 9 years ago

Any news on merging the binary parser in? Or are you keeping the packages separate?

mreinstein commented 9 years ago

@matiassingers not opposed to adding binary parser support. can you provide some tests/sample binary file for this?

matiassingers commented 9 years ago

@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.

tsanidas commented 9 years ago

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?

clee commented 9 years ago

@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.