REBOL [
title: "Codec: PLIST"
name: plist
type: module
options: [delay]
version: 1.0.0
file: https://raw.githubusercontent.com/Oldes/Rebol3/master/src/mezz/codec-plist.reb
author: "Oldes"
history: [
07-Apr-2022 "Oldes" {Initial version of the PLIST and Provisioning Profile decoder}
]
references: [
https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/PropertyLists/Introduction/Introduction.html
https://medium.com/@karaiskc/understanding-apples-binary-property-list-format-281e6da00dbd
]
todo: {
* Support binary PLIST version
* PLIST encoder
* Provision profile data validation?
}
]
system/options/log/plist: 1
stack: copy []
key: value: none
~spnl: system/catalog/bitsets/whitespace
~dict: [
any ~spnl
(
append append stack :key make map! 8
)
any [
~key
~value
(
put last stack :key :value
)
| any ~spnl
]
any ~comment
(
value: take/last stack
key: take/last stack
)
]
~key: [ any ~spnl copy key: to thru #">" (try [key: to word! key])]
~string: [ any ~spnl copy value: to thru #">" ]
~data: [ any ~spnl copy value: to thru #">" (value: debase value 64)]
~date: [ any ~spnl copy value: to thru #">" (value: to-date value)]
~integer: [ any ~spnl copy value: to thru #">" (value: to integer! value)]
~real: [ any ~spnl copy value: to thru #">" (value: to decimal! value)]
~true: [ (value: true )]
~false: [ (value: false)]
~array: [
(append/only stack copy [])
any [~value (append/only last stack :value) any ~spnl]
(value: take/last stack)
]
~comment: [any ~spnl opt [""]]
~value: [
any ~comment [
~string
| ~true
| ~false
| ~array
| ~dict
| ~date
| ~data
| ~integer
| ~real
]
]
register-codec [
name: 'plist
type: 'text
title: "Property List File Format"
suffixes: [%.plist]
decode: function [
{Extract content of the PLIST file}
data [binary! file! url!]
;return: [map!]
] [
verbose: system/options/log/plist
unless binary? data [ data: read data ]
if verbose > 0 [
log-info 'PLIST ["^[[1;32mDecode PLIST data^[[m (^[[1m" length? data "^[[mbytes )"]
]
unless parse to string! data [
thru ""
~dict
any ~comment
to end
][ return none ]
if verbose: system/options/log/plist > 0 [
foreach [k v] value [
switch to word! k [
DeveloperCertificates [
v: copy v
forall v [
try [
crt: codecs/crt/decode v/1
change/only v compose [
commonName: (crt/subject/commonName)
valid-to: (crt/valid-to)
fingerprint: (select crt 'fingerprint)
]
]
]
]
DER-Encoded-Profile [
log-debug 'PLIST ajoin [as-green k ": " mold v]
continue
]
]
log-warn 'PLIST ajoin [as-green k ": " mold v]
]
]
value
]
;encode: function [data [binary!]][ ]
identify: function [data [binary!]][
; just a simple test if there are key parts...
parse data [
thru "