140 lines
2.0 KiB
Go
140 lines
2.0 KiB
Go
package plist
|
|
|
|
import (
|
|
"hash/crc32"
|
|
"sort"
|
|
"time"
|
|
)
|
|
|
|
type cfValue interface {
|
|
typeName() string
|
|
hash() interface{}
|
|
}
|
|
|
|
type cfDictionary struct {
|
|
keys sort.StringSlice
|
|
values []cfValue
|
|
}
|
|
|
|
func (*cfDictionary) typeName() string {
|
|
return "dictionary"
|
|
}
|
|
|
|
func (p *cfDictionary) hash() interface{} {
|
|
return p
|
|
}
|
|
|
|
func (p *cfDictionary) Len() int {
|
|
return len(p.keys)
|
|
}
|
|
|
|
func (p *cfDictionary) Less(i, j int) bool {
|
|
return p.keys.Less(i, j)
|
|
}
|
|
|
|
func (p *cfDictionary) Swap(i, j int) {
|
|
p.keys.Swap(i, j)
|
|
p.values[i], p.values[j] = p.values[j], p.values[i]
|
|
}
|
|
|
|
func (p *cfDictionary) sort() {
|
|
sort.Sort(p)
|
|
}
|
|
|
|
type cfArray struct {
|
|
values []cfValue
|
|
}
|
|
|
|
func (*cfArray) typeName() string {
|
|
return "array"
|
|
}
|
|
|
|
func (p *cfArray) hash() interface{} {
|
|
return p
|
|
}
|
|
|
|
type cfString string
|
|
|
|
func (cfString) typeName() string {
|
|
return "string"
|
|
}
|
|
|
|
func (p cfString) hash() interface{} {
|
|
return string(p)
|
|
}
|
|
|
|
type cfNumber struct {
|
|
signed bool
|
|
value uint64
|
|
}
|
|
|
|
func (*cfNumber) typeName() string {
|
|
return "integer"
|
|
}
|
|
|
|
func (p *cfNumber) hash() interface{} {
|
|
if p.signed {
|
|
return int64(p.value)
|
|
}
|
|
return p.value
|
|
}
|
|
|
|
type cfReal struct {
|
|
wide bool
|
|
value float64
|
|
}
|
|
|
|
func (cfReal) typeName() string {
|
|
return "real"
|
|
}
|
|
|
|
func (p *cfReal) hash() interface{} {
|
|
if p.wide {
|
|
return p.value
|
|
}
|
|
return float32(p.value)
|
|
}
|
|
|
|
type cfBoolean bool
|
|
|
|
func (cfBoolean) typeName() string {
|
|
return "boolean"
|
|
}
|
|
|
|
func (p cfBoolean) hash() interface{} {
|
|
return bool(p)
|
|
}
|
|
|
|
type cfUID UID
|
|
|
|
func (cfUID) typeName() string {
|
|
return "UID"
|
|
}
|
|
|
|
func (p cfUID) hash() interface{} {
|
|
return p
|
|
}
|
|
|
|
type cfData []byte
|
|
|
|
func (cfData) typeName() string {
|
|
return "data"
|
|
}
|
|
|
|
func (p cfData) hash() interface{} {
|
|
// Data are uniqued by their checksums.
|
|
// Todo: Look at calculating this only once and storing it somewhere;
|
|
// crc32 is fairly quick, however.
|
|
return crc32.ChecksumIEEE([]byte(p))
|
|
}
|
|
|
|
type cfDate time.Time
|
|
|
|
func (cfDate) typeName() string {
|
|
return "date"
|
|
}
|
|
|
|
func (p cfDate) hash() interface{} {
|
|
return time.Time(p)
|
|
}
|