| package plist |
| |
| import ( |
| "errors" |
| "math" |
| "reflect" |
| "time" |
| ) |
| |
| type TestData struct { |
| Name string |
| Value interface{} |
| DecodeValue interface{} // used when the document cannot encode parts of Value |
| Documents map[int][]byte |
| SkipDecode map[int]bool |
| SkipEncode map[int]bool |
| } |
| |
| type SparseBundleHeader struct { |
| InfoDictionaryVersion string `plist:"CFBundleInfoDictionaryVersion"` |
| BandSize uint64 `plist:"band-size"` |
| BackingStoreVersion int `plist:"bundle-backingstore-version"` |
| DiskImageBundleType string `plist:"diskimage-bundle-type"` |
| Size uint64 `plist:"size"` |
| } |
| |
| type EmbedA struct { |
| EmbedC |
| EmbedB EmbedB |
| FieldA string |
| } |
| |
| type EmbedB struct { |
| FieldB string |
| *EmbedC |
| } |
| |
| type EmbedC struct { |
| FieldA1 string `plist:"FieldA"` |
| FieldA2 string |
| FieldB string |
| FieldC string |
| } |
| |
| type TextMarshalingBool struct { |
| b bool |
| } |
| |
| func (b TextMarshalingBool) MarshalText() ([]byte, error) { |
| if b.b { |
| return []byte("truthful"), nil |
| } |
| return []byte("non-factual"), nil |
| } |
| |
| func (b *TextMarshalingBool) UnmarshalText(text []byte) error { |
| if string(text) == "truthful" { |
| b.b = true |
| } |
| return nil |
| } |
| |
| type TextMarshalingBoolViaPointer struct { |
| b bool |
| } |
| |
| func (b *TextMarshalingBoolViaPointer) MarshalText() ([]byte, error) { |
| if b.b { |
| return []byte("plausible"), nil |
| } |
| return []byte("unimaginable"), nil |
| } |
| |
| func (b *TextMarshalingBoolViaPointer) UnmarshalText(text []byte) error { |
| if string(text) == "plausible" { |
| b.b = true |
| } |
| return nil |
| } |
| |
| type ArrayThatSerializesAsOneObject struct { |
| values []uint64 |
| } |
| |
| func (f ArrayThatSerializesAsOneObject) MarshalPlist() (interface{}, error) { |
| if len(f.values) == 1 { |
| return f.values[0], nil |
| } |
| return f.values, nil |
| } |
| |
| func (f *ArrayThatSerializesAsOneObject) UnmarshalPlist(unmarshal func(interface{}) error) error { |
| var ui uint64 |
| if err := unmarshal(&ui); err == nil { |
| f.values = []uint64{ui} |
| return nil |
| } |
| |
| return unmarshal(&f.values) |
| } |
| |
| type PlistMarshalingBoolByPointer struct { |
| b bool |
| } |
| |
| func (b *PlistMarshalingBoolByPointer) MarshalPlist() (interface{}, error) { |
| if b.b { |
| return int64(-1), nil |
| } |
| return int64(-2), nil |
| } |
| |
| func (b *PlistMarshalingBoolByPointer) UnmarshalPlist(unmarshal func(interface{}) error) error { |
| var val int64 |
| err := unmarshal(&val) |
| if err != nil { |
| return err |
| } |
| |
| b.b = val == -1 |
| return nil |
| } |
| |
| type BothMarshaler struct{} |
| |
| func (b *BothMarshaler) MarshalPlist() (interface{}, error) { |
| return map[string]string{"a": "b"}, nil |
| } |
| |
| func (b *BothMarshaler) MarshalText() ([]byte, error) { |
| return []byte("shouldn't see this"), nil |
| } |
| |
| type BothUnmarshaler struct { |
| Blah int64 `plist:"blah,omitempty"` |
| } |
| |
| func (b *BothUnmarshaler) UnmarshalPlist(unmarshal func(interface{}) error) error { |
| // no error |
| return nil |
| } |
| |
| func (b *BothUnmarshaler) UnmarshalText(text []byte) error { |
| return errors.New("shouldn't hit this") |
| } |
| |
| var xmlPreamble = `<?xml version="1.0" encoding="UTF-8"?> |
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
| ` |
| |
| var tests = []TestData{ |
| { |
| Name: "String", |
| Value: "Hello", |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`Hello`), |
| GNUStepFormat: []byte(`Hello`), |
| XMLFormat: []byte(xmlPreamble + `<plist version="1.0"><string>Hello</string></plist>`), |
| BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 85, 72, 101, 108, 108, 111, 8, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14}, |
| }, |
| }, |
| { |
| Name: "String containing apostrophe", |
| Value: "'", |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`"'"`), |
| GNUStepFormat: []byte(`"'"`), |
| XMLFormat: []byte(xmlPreamble + `<plist version="1.0"><string>'</string></plist>`), |
| BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 81, 39, 8, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10}, |
| }, |
| }, |
| { |
| Name: "Basic Structure", |
| Value: struct { |
| Name string |
| }{ |
| Name: "Dustin", |
| }, |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`{Name=Dustin;}`), |
| GNUStepFormat: []byte(`{Name=Dustin;}`), |
| XMLFormat: []byte(xmlPreamble + `<plist version="1.0"><dict><key>Name</key><string>Dustin</string></dict></plist>`), |
| BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 209, 1, 2, 84, 78, 97, 109, 101, 86, 68, 117, 115, 116, 105, 110, 8, 11, 16, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23}, |
| }, |
| }, |
| { |
| Name: "Basic Structure with non-exported fields", |
| Value: struct { |
| Name string |
| age int |
| }{ |
| Name: "Dustin", |
| age: 24, |
| }, |
| DecodeValue: struct { |
| Name string |
| age int |
| }{ |
| Name: "Dustin", |
| }, |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`{Name=Dustin;}`), |
| GNUStepFormat: []byte(`{Name=Dustin;}`), |
| XMLFormat: []byte(xmlPreamble + `<plist version="1.0"><dict><key>Name</key><string>Dustin</string></dict></plist>`), |
| BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 209, 1, 2, 84, 78, 97, 109, 101, 86, 68, 117, 115, 116, 105, 110, 8, 11, 16, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23}, |
| }, |
| }, |
| { |
| Name: "Basic Structure with omitted fields", |
| Value: struct { |
| Name string |
| Age int `plist:"-"` |
| }{ |
| Name: "Dustin", |
| Age: 24, |
| }, |
| DecodeValue: struct { |
| Name string |
| Age int `plist:"-"` |
| }{ |
| Name: "Dustin", |
| }, |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`{Name=Dustin;}`), |
| GNUStepFormat: []byte(`{Name=Dustin;}`), |
| XMLFormat: []byte(xmlPreamble + `<plist version="1.0"><dict><key>Name</key><string>Dustin</string></dict></plist>`), |
| BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 209, 1, 2, 84, 78, 97, 109, 101, 86, 68, 117, 115, 116, 105, 110, 8, 11, 16, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23}, |
| }, |
| }, |
| { |
| Name: "Basic Structure with empty omitempty fields", |
| Value: struct { |
| Name string |
| Age int `plist:"age,omitempty"` |
| Slice []int `plist:",omitempty"` |
| Bool bool `plist:",omitempty"` |
| Uint uint `plist:",omitempty"` |
| Float32 float32 `plist:",omitempty"` |
| Float64 float64 `plist:",omitempty"` |
| Stringptr *string `plist:",omitempty"` |
| Notempty uint `plist:",omitempty"` |
| }{ |
| Name: "Dustin", |
| Notempty: 10, |
| }, |
| DecodeValue: struct { |
| Name string |
| Age int `plist:"age,omitempty"` |
| Slice []int `plist:",omitempty"` |
| Bool bool `plist:",omitempty"` |
| Uint uint `plist:",omitempty"` |
| Float32 float32 `plist:",omitempty"` |
| Float64 float64 `plist:",omitempty"` |
| Stringptr *string `plist:",omitempty"` |
| Notempty uint `plist:",omitempty"` |
| }{ |
| Name: "Dustin", |
| Notempty: 10, |
| }, |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`{Name=Dustin;Notempty=10;}`), |
| GNUStepFormat: []byte(`{Name=Dustin;Notempty=<*I10>;}`), |
| XMLFormat: []byte(xmlPreamble + `<plist version="1.0"><dict><key>Name</key><string>Dustin</string><key>Notempty</key><integer>10</integer></dict></plist>`), |
| BinaryFormat: []byte{0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0xd2, 0x1, 0x2, 0x3, 0x4, 0x54, 0x4e, 0x61, 0x6d, 0x65, 0x58, 0x4e, 0x6f, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x56, 0x44, 0x75, 0x73, 0x74, 0x69, 0x6e, 0x10, 0xa, 0x8, 0xd, 0x12, 0x1b, 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x24}, |
| }, |
| }, |
| { |
| Name: "Structure with Anonymous Embeds", |
| Value: EmbedA{ |
| EmbedC: EmbedC{ |
| FieldA1: "", |
| FieldA2: "", |
| FieldB: "A.C.B", |
| FieldC: "A.C.C", |
| }, |
| EmbedB: EmbedB{ |
| FieldB: "A.B.B", |
| EmbedC: &EmbedC{ |
| FieldA1: "A.B.C.A1", |
| FieldA2: "A.B.C.A2", |
| FieldB: "", // Shadowed by A.B.B |
| FieldC: "A.B.C.C", |
| }, |
| }, |
| FieldA: "A.A", |
| }, |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`{EmbedB={FieldA="A.B.C.A1";FieldA2="A.B.C.A2";FieldB="A.B.B";FieldC="A.B.C.C";};FieldA="A.A";FieldA2="";FieldB="A.C.B";FieldC="A.C.C";}`), |
| GNUStepFormat: []byte(`{EmbedB={FieldA=A.B.C.A1;FieldA2=A.B.C.A2;FieldB=A.B.B;FieldC=A.B.C.C;};FieldA=A.A;FieldA2="";FieldB=A.C.B;FieldC=A.C.C;}`), |
| XMLFormat: []byte(xmlPreamble + `<plist version="1.0"><dict><key>EmbedB</key><dict><key>FieldA</key><string>A.B.C.A1</string><key>FieldA2</key><string>A.B.C.A2</string><key>FieldB</key><string>A.B.B</string><key>FieldC</key><string>A.B.C.C</string></dict><key>FieldA</key><string>A.A</string><key>FieldA2</key><string/><key>FieldB</key><string>A.C.B</string><key>FieldC</key><string>A.C.C</string></dict></plist>`), |
| BinaryFormat: []byte{0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0xd5, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0xb, 0xc, 0xd, 0xe, 0x56, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x42, 0x56, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x41, 0x57, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x41, 0x32, 0x56, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x42, 0x56, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x43, 0xd4, 0x2, 0x3, 0x4, 0x5, 0x7, 0x8, 0x9, 0xa, 0x58, 0x41, 0x2e, 0x42, 0x2e, 0x43, 0x2e, 0x41, 0x31, 0x58, 0x41, 0x2e, 0x42, 0x2e, 0x43, 0x2e, 0x41, 0x32, 0x55, 0x41, 0x2e, 0x42, 0x2e, 0x42, 0x57, 0x41, 0x2e, 0x42, 0x2e, 0x43, 0x2e, 0x43, 0x53, 0x41, 0x2e, 0x41, 0x50, 0x55, 0x41, 0x2e, 0x43, 0x2e, 0x42, 0x55, 0x41, 0x2e, 0x43, 0x2e, 0x43, 0x8, 0x13, 0x1a, 0x21, 0x29, 0x30, 0x37, 0x40, 0x49, 0x52, 0x58, 0x60, 0x64, 0x65, 0x6b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x71}, |
| }, |
| }, |
| { |
| Name: "Arbitrary Byte Data", |
| Value: []byte{'h', 'e', 'l', 'l', 'o'}, |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`<68656c6c 6f>`), |
| GNUStepFormat: []byte(`<[aGVsbG8=]>`), |
| XMLFormat: []byte(xmlPreamble + `<plist version="1.0"><data>aGVsbG8=</data></plist>`), |
| BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 69, 104, 101, 108, 108, 111, 8, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14}, |
| }, |
| // We are not encoding base64 for GNUstep yet |
| SkipEncode: map[int]bool{GNUStepFormat: true}, |
| }, |
| { |
| Name: "Arbitrary Byte Data (array)", |
| Value: [5]byte{'h', 'e', 'l', 'l', 'o'}, |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`<68656c6c 6f>`), |
| GNUStepFormat: []byte(`<[aGVsbG8=]>`), |
| XMLFormat: []byte(xmlPreamble + `<plist version="1.0"><data>aGVsbG8=</data></plist>`), |
| BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 69, 104, 101, 108, 108, 111, 8, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14}, |
| }, |
| // We are not encoding base64 for GNUstep yet |
| SkipEncode: map[int]bool{GNUStepFormat: true}, |
| }, |
| { |
| Name: "Arbitrary Integer Slice", |
| Value: []int{'h', 'e', 'l', 'l', 'o'}, |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`(104,101,108,108,111,)`), |
| GNUStepFormat: []byte(`(<*I104>,<*I101>,<*I108>,<*I108>,<*I111>,)`), |
| XMLFormat: []byte(xmlPreamble + `<plist version="1.0"><array><integer>104</integer><integer>101</integer><integer>108</integer><integer>108</integer><integer>111</integer></array></plist>`), |
| BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 165, 1, 2, 3, 3, 4, 16, 104, 16, 101, 16, 108, 16, 111, 8, 14, 16, 18, 20, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22}, |
| }, |
| }, |
| { |
| Name: "Arbitrary Integer Array", |
| Value: [3]int{'h', 'i', '!'}, |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`(104,105,33,)`), |
| GNUStepFormat: []byte(`(<*I104>,<*I105>,<*I33>,)`), |
| XMLFormat: []byte(xmlPreamble + `<plist version="1.0"><array><integer>104</integer><integer>105</integer><integer>33</integer></array></plist>`), |
| BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 163, 1, 2, 3, 16, 104, 16, 105, 16, 33, 8, 12, 14, 16, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18}, |
| }, |
| }, |
| { |
| Name: "Unsigned Integers of Increasing Size", |
| Value: []uint64{0xff, 0xfff, 0xffff, 0xfffff, 0xffffff, 0xfffffff, 0xffffffff, 0x7fffffffffffffff, 0xdeadbeeffacecafe}, |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`(255,4095,65535,1048575,16777215,268435455,4294967295,9223372036854775807,16045690985305262846,)`), |
| GNUStepFormat: []byte(`(<*I255>,<*I4095>,<*I65535>,<*I1048575>,<*I16777215>,<*I268435455>,<*I4294967295>,<*I9223372036854775807>,<*I16045690985305262846>,)`), |
| XMLFormat: []byte(xmlPreamble + `<plist version="1.0"><array><integer>255</integer><integer>4095</integer><integer>65535</integer><integer>1048575</integer><integer>16777215</integer><integer>268435455</integer><integer>4294967295</integer><integer>9223372036854775807</integer><integer>16045690985305262846</integer></array></plist>`), |
| BinaryFormat: []byte{0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0xa9, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0xff, 0x11, 0x0f, 0xff, 0x11, 0xff, 0xff, 0x12, 0x00, 0x0f, 0xff, 0xff, 0x12, 0x00, 0xff, 0xff, 0xff, 0x12, 0x0f, 0xff, 0xff, 0xff, 0x12, 0xff, 0xff, 0xff, 0xff, 0x13, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, 0xca, 0xfe, 0x08, 0x12, 0x14, 0x17, 0x1a, 0x1f, 0x24, 0x29, 0x2e, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48}, |
| }, |
| }, |
| { |
| Name: "Hexadecimal Integers", |
| Value: []int{'h', 'e', 'x', 'i', 'n', 't', -42}, |
| Documents: map[int][]byte{ |
| XMLFormat: []byte(xmlPreamble + `<plist version="1.0"><array><integer>0x68</integer><integer>0X65</integer><integer>0x78</integer><integer>0X69</integer><integer>0x6e</integer><integer>0X74</integer><integer>-0x2a</integer></array></plist>`), |
| }, |
| SkipEncode: map[int]bool{XMLFormat: true}, |
| }, |
| { |
| Name: "Octal Integers (treated as Decimal)", |
| Value: []int{'o', 'c', 't', 'i', 'n', 't', -42}, |
| Documents: map[int][]byte{ |
| XMLFormat: []byte(xmlPreamble + `<plist version="1.0"><array><integer>0111</integer><integer>099</integer><integer>0116</integer><integer>0105</integer><integer>0110</integer><integer>0116</integer><integer>-042</integer></array></plist>`), |
| }, |
| SkipEncode: map[int]bool{XMLFormat: true}, |
| }, |
| { |
| Name: "Floats of Increasing Bitness", |
| Value: []interface{}{float32(math.MaxFloat32), float64(math.MaxFloat64)}, |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`(3.4028234663852886e+38,1.7976931348623157e+308,)`), |
| GNUStepFormat: []byte(`(<*R3.4028234663852886e+38>,<*R1.7976931348623157e+308>,)`), |
| XMLFormat: []byte(xmlPreamble + `<plist version="1.0"><array><real>3.4028234663852886e+38</real><real>1.7976931348623157e+308</real></array></plist>`), |
| BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 162, 1, 2, 34, 127, 127, 255, 255, 35, 127, 239, 255, 255, 255, 255, 255, 255, 8, 11, 16, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25}, |
| }, |
| // We can't store varying bitness in text formats. |
| SkipDecode: map[int]bool{XMLFormat: true, OpenStepFormat: true, GNUStepFormat: true}, |
| }, |
| { |
| Name: "Boolean True", |
| Value: true, |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`1`), |
| GNUStepFormat: []byte(`<*BY>`), |
| XMLFormat: []byte(xmlPreamble + `<plist version="1.0"><true/></plist>`), |
| BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 9, 8, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9}, |
| }, |
| }, |
| { |
| Name: "Floating-Point Value", |
| Value: 3.14159265358979323846264338327950288, |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`3.141592653589793`), |
| GNUStepFormat: []byte(`<*R3.141592653589793>`), |
| XMLFormat: []byte(xmlPreamble + `<plist version="1.0"><real>3.141592653589793</real></plist>`), |
| BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 35, 64, 9, 33, 251, 84, 68, 45, 24, 8, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17}, |
| }, |
| }, |
| { |
| Name: "Map (containing arbitrary types)", |
| Value: map[string]interface{}{ |
| "float": 1.0, |
| "uint64": uint64(1), |
| }, |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`{float=1;uint64=1;}`), |
| GNUStepFormat: []byte(`{float=<*R1>;uint64=<*I1>;}`), |
| XMLFormat: []byte(xmlPreamble + `<plist version="1.0"><dict><key>float</key><real>1</real><key>uint64</key><integer>1</integer></dict></plist>`), |
| BinaryFormat: []byte{0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0xd2, 0x1, 0x2, 0x3, 0x4, 0x55, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x56, 0x75, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x23, 0x3f, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x1, 0x8, 0xd, 0x13, 0x1a, 0x23, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x25}, |
| }, |
| // Can't lax decode strings into numerics in a map (we don't know they want numbers) |
| SkipDecode: map[int]bool{OpenStepFormat: true}, |
| }, |
| { |
| Name: "Map (containing all variations of all types)", |
| Value: interface{}(map[string]interface{}{ |
| "intarray": []interface{}{ |
| int(1), |
| int8(8), |
| int16(16), |
| int32(32), |
| int64(64), |
| uint(2), |
| uint8(9), |
| uint16(17), |
| uint32(33), |
| uint64(65), |
| }, |
| "floats": []interface{}{ |
| float32(32.0), |
| float64(64.0), |
| }, |
| "booleans": []bool{ |
| true, |
| false, |
| }, |
| "strings": []string{ |
| "Hello, ASCII", |
| "Hello, 世界", |
| }, |
| "data": []byte{1, 2, 3, 4}, |
| "date": time.Date(2013, 11, 27, 0, 34, 0, 0, time.UTC), |
| }), |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`{booleans=(1,0,);data=<01020304>;date="2013-11-27 00:34:00 +0000";floats=(32,64,);intarray=(1,8,16,32,64,2,9,17,33,65,);strings=("Hello, ASCII","Hello, \U4e16\U754c",);}`), |
| GNUStepFormat: []byte(`{booleans=(<*BY>,<*BN>,);data=<01020304>;date=<*D2013-11-27 00:34:00 +0000>;floats=(<*R32>,<*R64>,);intarray=(<*I1>,<*I8>,<*I16>,<*I32>,<*I64>,<*I2>,<*I9>,<*I17>,<*I33>,<*I65>,);strings=("Hello, ASCII","Hello, \U4e16\U754c",);}`), |
| XMLFormat: []byte(xmlPreamble + `<plist version="1.0"><dict><key>booleans</key><array><true/><false/></array><key>data</key><data>AQIDBA==</data><key>date</key><date>2013-11-27T00:34:00Z</date><key>floats</key><array><real>32</real><real>64</real></array><key>intarray</key><array><integer>1</integer><integer>8</integer><integer>16</integer><integer>32</integer><integer>64</integer><integer>2</integer><integer>9</integer><integer>17</integer><integer>33</integer><integer>65</integer></array><key>strings</key><array><string>Hello, ASCII</string><string>Hello, 世界</string></array></dict></plist>`), |
| BinaryFormat: []byte{0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0xd6, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0xa, 0xb, 0xc, 0xf, 0x1a, 0x58, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x73, 0x54, 0x64, 0x61, 0x74, 0x61, 0x54, 0x64, 0x61, 0x74, 0x65, 0x56, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x73, 0x58, 0x69, 0x6e, 0x74, 0x61, 0x72, 0x72, 0x61, 0x79, 0x57, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, 0xa2, 0x8, 0x9, 0x9, 0x8, 0x44, 0x1, 0x2, 0x3, 0x4, 0x33, 0x41, 0xb8, 0x45, 0x75, 0x78, 0x0, 0x0, 0x0, 0xa2, 0xd, 0xe, 0x22, 0x42, 0x0, 0x0, 0x0, 0x23, 0x40, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xaa, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x10, 0x1, 0x10, 0x8, 0x10, 0x10, 0x10, 0x20, 0x10, 0x40, 0x10, 0x2, 0x10, 0x9, 0x10, 0x11, 0x10, 0x21, 0x10, 0x41, 0xa2, 0x1b, 0x1c, 0x5c, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x41, 0x53, 0x43, 0x49, 0x49, 0x69, 0x0, 0x48, 0x0, 0x65, 0x0, 0x6c, 0x0, 0x6c, 0x0, 0x6f, 0x0, 0x2c, 0x0, 0x20, 0x4e, 0x16, 0x75, 0x4c, 0x8, 0x15, 0x1e, 0x23, 0x28, 0x2f, 0x38, 0x40, 0x43, 0x44, 0x45, 0x4a, 0x53, 0x56, 0x5b, 0x64, 0x6f, 0x71, 0x73, 0x75, 0x77, 0x79, 0x7b, 0x7d, 0x7f, 0x81, 0x83, 0x86, 0x93, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa6}, |
| }, |
| SkipDecode: map[int]bool{OpenStepFormat: true, GNUStepFormat: true, XMLFormat: true, BinaryFormat: true}, |
| }, |
| { |
| Name: "Map (containing nil)", |
| Value: map[string]interface{}{ |
| "float": 1.5, |
| "uint64": uint64(1), |
| "nil": nil, |
| }, |
| DecodeValue: map[string]interface{}{ |
| "float": 1.5, |
| "uint64": uint64(1), |
| }, |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`{float=1.5;uint64=1;}`), |
| GNUStepFormat: []byte(`{float=<*R1.5>;uint64=<*I1>;}`), |
| XMLFormat: []byte(xmlPreamble + `<plist version="1.0"><dict><key>float</key><real>1.5</real><key>uint64</key><integer>1</integer></dict></plist>`), |
| BinaryFormat: []byte{0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0xd2, 0x1, 0x2, 0x3, 0x4, 0x55, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x56, 0x75, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x23, 0x3f, 0xf8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x1, 0x8, 0xd, 0x13, 0x1a, 0x23, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x25}, |
| }, |
| // Can't lax decode strings into numerics in a map (we don't know they want numbers) |
| SkipDecode: map[int]bool{OpenStepFormat: true}, |
| }, |
| { |
| Name: "Pointer to structure with plist tags", |
| Value: &SparseBundleHeader{ |
| InfoDictionaryVersion: "6.0", |
| BandSize: 8388608, |
| Size: 4 * 1048576 * 1024 * 1024, |
| DiskImageBundleType: "com.apple.diskimage.sparsebundle", |
| BackingStoreVersion: 1, |
| }, |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`{CFBundleInfoDictionaryVersion="6.0";"band-size"=8388608;"bundle-backingstore-version"=1;"diskimage-bundle-type"="com.apple.diskimage.sparsebundle";size=4398046511104;}`), |
| GNUStepFormat: []byte(`{CFBundleInfoDictionaryVersion=6.0;band-size=<*I8388608>;bundle-backingstore-version=<*I1>;diskimage-bundle-type=com.apple.diskimage.sparsebundle;size=<*I4398046511104>;}`), |
| XMLFormat: []byte(xmlPreamble + `<plist version="1.0"><dict><key>CFBundleInfoDictionaryVersion</key><string>6.0</string><key>band-size</key><integer>8388608</integer><key>bundle-backingstore-version</key><integer>1</integer><key>diskimage-bundle-type</key><string>com.apple.diskimage.sparsebundle</string><key>size</key><integer>4398046511104</integer></dict></plist>`), |
| BinaryFormat: []byte{0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0xd5, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0x5f, 0x10, 0x1d, 0x43, 0x46, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x44, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x72, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x59, 0x62, 0x61, 0x6e, 0x64, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x10, 0x1b, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2d, 0x62, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2d, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x10, 0x15, 0x64, 0x69, 0x73, 0x6b, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2d, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x54, 0x73, 0x69, 0x7a, 0x65, 0x53, 0x36, 0x2e, 0x30, 0x12, 0x0, 0x80, 0x0, 0x0, 0x10, 0x1, 0x5f, 0x10, 0x20, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x64, 0x69, 0x73, 0x6b, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x72, 0x73, 0x65, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x13, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x13, 0x33, 0x3d, 0x5b, 0x73, 0x78, 0x7c, 0x81, 0x83, 0xa6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xaf}, |
| }, |
| SkipDecode: map[int]bool{OpenStepFormat: true}, |
| }, |
| { |
| Name: "Array of byte arrays", |
| Value: [][]byte{ |
| []byte("Hello"), |
| []byte("World"), |
| }, |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`(<48656c6c 6f>,<576f726c 64>,)`), |
| GNUStepFormat: []byte(`(<48656c6c 6f>,<576f726c 64>,)`), |
| XMLFormat: []byte(xmlPreamble + `<plist version="1.0"><array><data>SGVsbG8=</data><data>V29ybGQ=</data></array></plist>`), |
| BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 162, 1, 2, 69, 72, 101, 108, 108, 111, 69, 87, 111, 114, 108, 100, 8, 11, 17, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23}, |
| }, |
| }, |
| { |
| Name: "Date", |
| Value: time.Date(2013, 11, 27, 0, 34, 0, 0, time.UTC), |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`"2013-11-27 00:34:00 +0000"`), |
| GNUStepFormat: []byte(`<*D2013-11-27 00:34:00 +0000>`), |
| XMLFormat: []byte(xmlPreamble + `<plist version="1.0"><date>2013-11-27T00:34:00Z</date></plist>`), |
| BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 51, 65, 184, 69, 117, 120, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17}, |
| }, |
| }, |
| { |
| Name: "Floating-Point NaN", |
| Value: math.NaN(), |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`NaN`), |
| GNUStepFormat: []byte(`<*RNaN>`), |
| XMLFormat: []byte(xmlPreamble + `<plist version="1.0"><real>nan</real></plist>`), |
| BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 35, 127, 248, 0, 0, 0, 0, 0, 1, 8, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17}, |
| }, |
| SkipDecode: map[int]bool{OpenStepFormat: true, GNUStepFormat: true, XMLFormat: true, BinaryFormat: true}, |
| }, |
| { |
| Name: "Floating-Point Infinity", |
| Value: math.Inf(1), |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`+Inf`), |
| GNUStepFormat: []byte(`<*R+Inf>`), |
| XMLFormat: []byte(xmlPreamble + `<plist version="1.0"><real>inf</real></plist>`), |
| BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 35, 127, 240, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17}, |
| }, |
| }, |
| { |
| Name: "Floating-Point Negative Infinity", |
| Value: math.Inf(-1), |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`-Inf`), |
| GNUStepFormat: []byte(`<*R-Inf>`), |
| XMLFormat: []byte(xmlPreamble + `<plist version="1.0"><real>-inf</real></plist>`), |
| BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 35, 255, 240, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17}, |
| }, |
| }, |
| { |
| Name: "UTF-8 string", |
| Value: []string{"Hello, ASCII", "Hello, 世界"}, |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`("Hello, ASCII","Hello, \U4e16\U754c",)`), |
| GNUStepFormat: []byte(`("Hello, ASCII","Hello, \U4e16\U754c",)`), |
| XMLFormat: []byte(xmlPreamble + `<plist version="1.0"><array><string>Hello, ASCII</string><string>Hello, 世界</string></array></plist>`), |
| BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 162, 1, 2, 92, 72, 101, 108, 108, 111, 44, 32, 65, 83, 67, 73, 73, 105, 0, 72, 0, 101, 0, 108, 0, 108, 0, 111, 0, 44, 0, 32, 78, 22, 117, 76, 8, 11, 24, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43}, |
| }, |
| }, |
| { |
| Name: "An array containing more than fifteen items", |
| Value: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,)`), |
| GNUStepFormat: []byte(`(<*I1>,<*I2>,<*I3>,<*I4>,<*I5>,<*I6>,<*I7>,<*I8>,<*I9>,<*I10>,<*I11>,<*I12>,<*I13>,<*I14>,<*I15>,<*I16>,)`), |
| XMLFormat: []byte(xmlPreamble + `<plist version="1.0"><array><integer>1</integer><integer>2</integer><integer>3</integer><integer>4</integer><integer>5</integer><integer>6</integer><integer>7</integer><integer>8</integer><integer>9</integer><integer>10</integer><integer>11</integer><integer>12</integer><integer>13</integer><integer>14</integer><integer>15</integer><integer>16</integer></array></plist>`), |
| BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 175, 16, 16, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16, 1, 16, 2, 16, 3, 16, 4, 16, 5, 16, 6, 16, 7, 16, 8, 16, 9, 16, 10, 16, 11, 16, 12, 16, 13, 16, 14, 16, 15, 16, 16, 8, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59}, |
| }, |
| }, |
| { |
| Name: "TextMarshaler/TextUnmarshaler", |
| Value: TextMarshalingBool{true}, |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`truthful`), |
| GNUStepFormat: []byte(`truthful`), |
| XMLFormat: []byte(xmlPreamble + `<plist version="1.0"><string>truthful</string></plist>`), |
| BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 88, 116, 114, 117, 116, 104, 102, 117, 108, 8, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17}, |
| }, |
| // We expect false here because the non-pointer version cannot mutate itself. |
| }, |
| { |
| Name: "TextMarshaler/TextUnmarshaler via Pointer", |
| Value: &TextMarshalingBoolViaPointer{false}, |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`unimaginable`), |
| GNUStepFormat: []byte(`unimaginable`), |
| XMLFormat: []byte(xmlPreamble + `<plist version="1.0"><string>unimaginable</string></plist>`), |
| BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 92, 117, 110, 105, 109, 97, 103, 105, 110, 97, 98, 108, 101, 8, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21}, |
| }, |
| DecodeValue: TextMarshalingBoolViaPointer{false}, |
| }, |
| { |
| Name: "Duplicated Values", |
| Value: []interface{}{ |
| "Hello", |
| float32(32.0), |
| float64(32.0), |
| []byte("data"), |
| float32(64.0), |
| float64(64.0), |
| uint64(100), |
| float32(32.0), |
| time.Date(2013, 11, 27, 0, 34, 0, 0, time.UTC), |
| float64(32.0), |
| float32(64.0), |
| float64(64.0), |
| "Hello", |
| []byte("data"), |
| uint64(100), |
| time.Date(2013, 11, 27, 0, 34, 0, 0, time.UTC), |
| }, |
| Documents: map[int][]byte{ |
| BinaryFormat: []byte{0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0xaf, 0x10, 0x10, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x2, 0x8, 0x3, 0x5, 0x6, 0x1, 0x4, 0x7, 0x8, 0x55, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x22, 0x42, 0x0, 0x0, 0x0, 0x23, 0x40, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x44, 0x64, 0x61, 0x74, 0x61, 0x22, 0x42, 0x80, 0x0, 0x0, 0x23, 0x40, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x64, 0x33, 0x41, 0xb8, 0x45, 0x75, 0x78, 0x0, 0x0, 0x0, 0x8, 0x1b, 0x21, 0x26, 0x2f, 0x34, 0x39, 0x42, 0x44, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4d}, |
| }, |
| }, |
| { |
| Name: "Funny Characters", |
| Value: map[string]string{ |
| "\a": "\b", |
| "\v": "\f", |
| "\\": "\"", |
| "\t\r": "\n", |
| "\u00C8": "wat", |
| "\u0100": "hundred", |
| }, |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`{"\a"="\b";` + "\"\t\r\"=\"\n\";" + `"\v"="\f";"\\"="\"";"\310"=wat;"\U0100"=hundred;}`), |
| GNUStepFormat: []byte(`{"\a"="\b";` + "\"\t\r\"=\"\n\";" + `"\v"="\f";"\\"="\"";"\310"=wat;"\U0100"=hundred;}`), |
| }, |
| }, |
| { |
| Name: "Signed Integers", |
| Value: []int64{-1, -127, -255, -32767, -65535, -9223372036854775808}, |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`(-1,-127,-255,-32767,-65535,-9223372036854775808,)`), |
| GNUStepFormat: []byte(`(<*I-1>,<*I-127>,<*I-255>,<*I-32767>,<*I-65535>,<*I-9223372036854775808>,)`), |
| XMLFormat: []byte(xmlPreamble + `<plist version="1.0"><array><integer>-1</integer><integer>-127</integer><integer>-255</integer><integer>-32767</integer><integer>-65535</integer><integer>-9223372036854775808</integer></array></plist>`), |
| BinaryFormat: []byte{0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0xa6, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x81, 0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x01, 0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x13, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0f, 0x18, 0x21, 0x2a, 0x33, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45}, |
| }, |
| }, |
| { |
| Name: "A map with a blank key", |
| Value: map[string]string{ |
| "": "Hello", |
| }, |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`{""=Hello;}`), |
| GNUStepFormat: []byte(`{""=Hello;}`), |
| XMLFormat: []byte(xmlPreamble + `<plist version="1.0"><dict><key/><string>Hello</string></dict></plist>`), |
| BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 209, 1, 2, 80, 85, 72, 101, 108, 108, 111, 8, 11, 12, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18}, |
| }, |
| }, |
| { |
| Name: "CF Keyed Archiver UIDs (interface{})", |
| Value: []UID{ |
| 0xff, |
| 0xffff, |
| 0xffffff, |
| 0xffffffff, |
| 0xffffffffff, |
| }, |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`({CF$UID=255;},{CF$UID=65535;},{CF$UID=16777215;},{CF$UID=4294967295;},{CF$UID=1099511627775;},)`), |
| GNUStepFormat: []byte(`({CF$UID=<*I255>;},{CF$UID=<*I65535>;},{CF$UID=<*I16777215>;},{CF$UID=<*I4294967295>;},{CF$UID=<*I1099511627775>;},)`), |
| XMLFormat: []byte(xmlPreamble + `<plist version="1.0"><array><dict><key>CF$UID</key><integer>255</integer></dict><dict><key>CF$UID</key><integer>65535</integer></dict><dict><key>CF$UID</key><integer>16777215</integer></dict><dict><key>CF$UID</key><integer>4294967295</integer></dict><dict><key>CF$UID</key><integer>1099511627775</integer></dict></array></plist>`), |
| BinaryFormat: []byte{0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0xa5, 0x01, 0x02, 0x03, 0x04, 0x05, 0x80, 0xff, 0x81, 0xff, 0xff, 0x83, 0x00, 0xff, 0xff, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0x87, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x08, 0x0e, 0x10, 0x13, 0x18, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26}, |
| }, |
| }, |
| { |
| Name: "CF Keyed Archiver UID (struct)", |
| Value: struct { |
| U UID `plist:"identifier"` |
| }{ |
| U: 1024, |
| }, |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`{identifier={CF$UID=1024;};}`), |
| GNUStepFormat: []byte(`{identifier={CF$UID=<*I1024>;};}`), |
| XMLFormat: []byte(xmlPreamble + `<plist version="1.0"><dict><key>identifier</key><dict><key>CF$UID</key><integer>1024</integer></dict></dict></plist>`), |
| BinaryFormat: []byte{0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0xd1, 0x01, 0x02, 0x5a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x81, 0x04, 0x00, 0x08, 0x0b, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19}, |
| }, |
| }, |
| { |
| Name: "CF Keyed Archiver UID as Legacy Int", |
| Value: struct { |
| U UID `plist:"identifier"` |
| }{ |
| U: 1024, |
| }, |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`{identifier={CF$UID=1024;};}`), |
| GNUStepFormat: []byte(`{identifier={CF$UID=<*I1024>;};}`), |
| XMLFormat: []byte(xmlPreamble + `<plist version="1.0"><dict><key>identifier</key><dict><key>CF$UID</key><integer>1024</integer></dict></dict></plist>`), |
| BinaryFormat: []byte{0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0xd1, 0x01, 0x02, 0x5a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x81, 0x04, 0x00, 0x08, 0x0b, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19}, |
| }, |
| DecodeValue: struct { |
| U uint64 `plist:"identifier"` |
| }{ |
| U: 1024, |
| }, |
| }, |
| { |
| Name: "Custom Marshaller/Unmarshaller by Value", |
| Value: []ArrayThatSerializesAsOneObject{ |
| ArrayThatSerializesAsOneObject{[]uint64{100}}, |
| ArrayThatSerializesAsOneObject{[]uint64{2, 4, 6, 8}}, |
| }, |
| Documents: map[int][]byte{ |
| GNUStepFormat: []byte(`(<*I100>,(<*I2>,<*I4>,<*I6>,<*I8>,),)`), |
| }, |
| }, |
| { |
| Name: "Custom Marshaller/Unmarshaller by Pointer", |
| Value: &PlistMarshalingBoolByPointer{true}, |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`-1`), |
| GNUStepFormat: []byte(`<*I-1>`), |
| }, |
| }, |
| { |
| Name: "Type implementing both Text and Plist Marshaler", |
| Value: &BothMarshaler{}, |
| Documents: map[int][]byte{ |
| GNUStepFormat: []byte(`{a=b;}`), |
| }, |
| }, |
| { |
| Name: "Type implementing both Text and Plist Unmarshaler", |
| Value: &BothUnmarshaler{int64(1024)}, |
| Documents: map[int][]byte{ |
| GNUStepFormat: []byte(`{blah=<*I1024>;}`), |
| }, |
| DecodeValue: &BothUnmarshaler{int64(0)}, |
| }, |
| { |
| Name: "Comments", |
| Value: struct { |
| A, B, C int |
| S, S2 string |
| }{ |
| 1, 2, 3, |
| "/not/a/comment/", "/not*a/*comm*en/t", |
| }, |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`{ |
| A=1 /* A is 1 because it is the first letter */; |
| B=2; // B is 2 because comment-to-end-of-line. |
| C=3; |
| S = /not/a/comment/; |
| S2 = /not*a/*comm*en/t; |
| }`), |
| }, |
| SkipEncode: map[int]bool{OpenStepFormat: true}, |
| }, |
| { |
| Name: "Escapes", |
| Value: struct { |
| W, A, B, V, F, T, R, N, Hex1, Unicode1, Unicode2, Octal1 string |
| }{ |
| "w", "\a", "\b", "\v", "\f", "\t", "\r", "\n", "\u00ab", "\u00ac", "\u00ad", "\033", |
| }, |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`{ |
| W="\w"; |
| A="\a"; |
| B="\b"; |
| V="\v"; |
| F="\f"; |
| T="\t"; |
| R="\r"; |
| N="\n"; |
| Hex1="\xAB"; |
| Unicode1="\u00AC"; |
| Unicode2="\U00AD"; |
| Octal1="\033"; |
| }`), |
| }, |
| SkipEncode: map[int]bool{OpenStepFormat: true}, |
| }, |
| { |
| Name: "Empty Strings in Arrays", |
| Value: []string{"A"}, |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`(A,,,"",)`), |
| }, |
| SkipEncode: map[int]bool{OpenStepFormat: true}, |
| }, |
| { |
| Name: "Empty Data", |
| Value: []byte{}, |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`<>`), |
| }, |
| SkipEncode: map[int]bool{OpenStepFormat: true}, |
| }, |
| { |
| Name: "UTF-8 with BOM", |
| Value: "Hello", |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte("\uFEFFHello"), |
| }, |
| SkipEncode: map[int]bool{OpenStepFormat: true}, |
| }, |
| { |
| Name: "UTF-16LE with BOM", |
| Value: "Hello", |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte{0xFF, 0xFE, 'H', 0, 'e', 0, 'l', 0, 'l', 0, 'o', 0}, |
| }, |
| SkipEncode: map[int]bool{OpenStepFormat: true}, |
| }, |
| { |
| Name: "UTF-16BE with BOM", |
| Value: "Hello", |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte{0xFE, 0xFF, 0, 'H', 0, 'e', 0, 'l', 0, 'l', 0, 'o'}, |
| }, |
| SkipEncode: map[int]bool{OpenStepFormat: true}, |
| }, |
| { |
| Name: "UTF-16LE without BOM", |
| Value: "Hello", |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte{'H', 0, 'e', 0, 'l', 0, 'l', 0, 'o', 0}, |
| }, |
| SkipEncode: map[int]bool{OpenStepFormat: true}, |
| }, |
| { |
| Name: "UTF-16BE without BOM", |
| Value: "Hello", |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte{0, 'H', 0, 'e', 0, 'l', 0, 'l', 0, 'o'}, |
| }, |
| SkipEncode: map[int]bool{OpenStepFormat: true}, |
| }, |
| { |
| Name: "UTF-16BE with High Characters", |
| Value: "Hello, 世界", |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte{0, '"', 0, 'H', 0, 'e', 0, 'l', 0, 'l', 0, 'o', 0, ',', 0, ' ', 0x4E, 0x16, 0x75, 0x4C, 0, '"'}, |
| }, |
| SkipEncode: map[int]bool{OpenStepFormat: true}, |
| }, |
| { |
| Name: "Legacy Strings File Format (No Dictionary)", |
| Value: map[string]string{ |
| "Key": "Value", |
| "Key2": "Value2", |
| }, |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`"Key" = "Value"; |
| "Key2" = "Value2";`), |
| }, |
| SkipEncode: map[int]bool{OpenStepFormat: true}, |
| }, |
| { |
| Name: "Strings File Shortcut Format (No Values)", |
| Value: map[string]string{ |
| "Key": "Key", |
| "Key2": "Key2", |
| }, |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`"Key"; |
| "Key2";`), |
| }, |
| SkipEncode: map[int]bool{OpenStepFormat: true}, |
| }, |
| { |
| Name: "Various Truncated Escapes", |
| Value: "\x01\x02\x03\x04\x057", |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`"\x1\u02\U003\4\0057"`), |
| }, |
| SkipEncode: map[int]bool{OpenStepFormat: true}, |
| }, |
| { |
| Name: "Various Case-Insensitive Escapes", |
| Value: "\u00AB\uCDEF", |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(`"\xaB\uCdEf"`), |
| }, |
| SkipEncode: map[int]bool{OpenStepFormat: true}, |
| }, |
| { |
| Name: "Text data long enough to trigger implementation-specific reallocation", // this is for coverage :( |
| Value: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte("<0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001>"), |
| }, |
| SkipEncode: map[int]bool{OpenStepFormat: true}, |
| }, |
| { |
| Name: "Empty Text Document", |
| Value: map[string]interface{}{}, // Defined to be an empty dictionary |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte{}, |
| }, |
| SkipEncode: map[int]bool{OpenStepFormat: true}, |
| }, |
| { |
| Name: "Text document consisting of only whitespace", |
| Value: map[string]interface{}{}, // Defined to be an empty dictionary |
| Documents: map[int][]byte{ |
| OpenStepFormat: []byte(" \n\t"), |
| }, |
| SkipEncode: map[int]bool{OpenStepFormat: true}, |
| }, |
| { |
| Name: "Sized integers at size boundaries", |
| Value: []interface{}{ |
| int8(-128), |
| int8(127), |
| int16(-32768), |
| int16(32767), |
| int32(-2147483648), |
| int32(2147483647), |
| int64(-9223372036854775808), |
| int64(9223372036854775807), |
| }, |
| DecodeValue: []interface{}{ |
| // interface decoding promotes all numbers to u/int64 |
| int64(-128), |
| uint64(127), |
| int64(-32768), |
| uint64(32767), |
| int64(-2147483648), |
| uint64(2147483647), |
| int64(-9223372036854775808), |
| uint64(9223372036854775807), |
| }, |
| Documents: map[int][]byte{ |
| BinaryFormat: []byte{0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0xa8, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x10, 0x7f, 0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x11, 0x7f, 0xff, 0x13, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x12, 0x7f, 0xff, 0xff, 0xff, 0x13, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x08, 0x11, 0x1a, 0x1c, 0x25, 0x28, 0x31, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48}, |
| }, |
| }, |
| { |
| Name: "Duplicate Dictionary Keys", |
| Value: map[string]interface{}{ |
| "key": "second value", |
| }, |
| Documents: map[int][]byte{ |
| XMLFormat: []byte(`<plist><dict><key>key</key><string>value</string><key>key</key><string>second value</string></dict></plist>`), |
| OpenStepFormat: []byte(`{"key" = "value"; "key" = "second value";}`), |
| GNUStepFormat: []byte(`{"key" = "value"; "key" = "second value";}`), |
| BinaryFormat: []byte{ |
| 'b', 'p', 'l', 'i', 's', 't', '0', '0', |
| |
| 0xD2, 0x01, 0x01, 0x02, 0x03, |
| 0x53, 'k', 'e', 'y', |
| 0x55, 'v', 'a', 'l', 'u', 'e', |
| 0x5C, 's', 'e', 'c', 'o', 'n', 'd', ' ', 'v', 'a', 'l', 'u', 'e', |
| |
| 0x08, 0x0D, 0x11, 0x17, |
| |
| 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, |
| 0x01, |
| 0x01, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, |
| }, |
| }, |
| SkipEncode: map[int]bool{XMLFormat: true, OpenStepFormat: true, GNUStepFormat: true, BinaryFormat: true}, |
| }, |
| { |
| Name: "GNUStep base64 data ignoring invalid chars", |
| Value: [][]byte{ |
| {'h', 'e', 'l', 'l', 'o'}, |
| {'h', 'e', 'l', 'l', 'o'}, |
| }, |
| Documents: map[int][]byte{ |
| GNUStepFormat: []byte(`(<[aGVs^^bG8=]>,<[ a G V s b G 8 = ]>)`), |
| }, |
| // We are not encoding base64 for GNUstep yet |
| SkipEncode: map[int]bool{GNUStepFormat: true}, |
| }, |
| { |
| Name: "Text document with quoted GNUstep values", |
| Value: []interface{}{uint64(1048576), uint64(1234), true}, |
| Documents: map[int][]byte{ |
| GNUStepFormat: []byte(`(<*I"1048576">, <*I"1234>, <*B"Y>)`), |
| }, |
| SkipEncode: map[int]bool{GNUStepFormat: true}, |
| }, |
| } |
| |
| type EverythingTestData struct { |
| Intarray []uint64 `plist:"intarray"` |
| Floats []float64 `plist:"floats"` |
| Booleans []bool `plist:"booleans"` |
| Strings []string `plist:"strings"` |
| Dat []byte `plist:"data"` |
| Date time.Time `plist:"date"` |
| } |
| |
| var plistValueTreeRawData = &EverythingTestData{ |
| Intarray: []uint64{1, 8, 16, 32, 64, 2, 9, 17, 33, 65}, |
| Floats: []float64{32.0, 64.0}, |
| Booleans: []bool{true, false}, |
| Strings: []string{"Hello, ASCII", "Hello, 世界"}, |
| Dat: []byte{1, 2, 3, 4}, |
| Date: time.Date(2013, 11, 27, 0, 34, 0, 0, time.UTC), |
| } |
| var plistValueTree cfValue |
| var plistValueTreeAsBplist = []byte{98, 112, 108, 105, 115, 116, 48, 48, 214, 1, 13, 17, 21, 25, 27, 2, 14, 18, 22, 26, 28, 88, 105, 110, 116, 97, 114, 114, 97, 121, 170, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 16, 1, 16, 8, 16, 16, 16, 32, 16, 64, 16, 2, 16, 9, 16, 17, 16, 33, 16, 65, 86, 102, 108, 111, 97, 116, 115, 162, 15, 16, 34, 66, 0, 0, 0, 35, 64, 80, 0, 0, 0, 0, 0, 0, 88, 98, 111, 111, 108, 101, 97, 110, 115, 162, 19, 20, 9, 8, 87, 115, 116, 114, 105, 110, 103, 115, 162, 23, 24, 92, 72, 101, 108, 108, 111, 44, 32, 65, 83, 67, 73, 73, 105, 0, 72, 0, 101, 0, 108, 0, 108, 0, 111, 0, 44, 0, 32, 78, 22, 117, 76, 84, 100, 97, 116, 97, 68, 1, 2, 3, 4, 84, 100, 97, 116, 101, 51, 65, 184, 69, 117, 120, 0, 0, 0, 8, 21, 30, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 68, 71, 76, 85, 94, 97, 98, 99, 107, 110, 123, 142, 147, 152, 157, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166} |
| var plistValueTreeAsXML = xmlPreamble + `<plist version="1.0"><dict><key>intarray</key><array><integer>1</integer><integer>8</integer><integer>16</integer><integer>32</integer><integer>64</integer><integer>2</integer><integer>9</integer><integer>17</integer><integer>33</integer><integer>65</integer></array><key>floats</key><array><real>32</real><real>64</real></array><key>booleans</key><array><true/><false/></array><key>strings</key><array><string>Hello, ASCII</string><string>Hello, 世界</string></array><key>data</key><data>AQIDBA==</data><key>date</key><date>2013-11-27T00:34:00Z</date></dict></plist>` |
| var plistValueTreeAsOpenStep = `{booleans=(1,0,);data=<01020304>;date="2013-11-27 00:34:00 +0000";floats=(32,64,);intarray=(1,8,16,32,64,2,9,17,33,65,);strings=("Hello, ASCII","Hello, \U4e16\U754c",);}` |
| var plistValueTreeAsGNUStep = `{booleans=(<*BY>,<*BN>,);data=<01020304>;date=<*D2013-11-27 00:34:00 +0000>;floats=(<*R32>,<*R64>,);intarray=(<*I1>,<*I8>,<*I16>,<*I32>,<*I64>,<*I2>,<*I9>,<*I17>,<*I33>,<*I65>,);strings=("Hello, ASCII","Hello, \U4e16\U754c",);}` |
| |
| type LaxTestData struct { |
| I64 int64 |
| U64 uint64 |
| F64 float64 |
| B bool |
| D time.Time |
| } |
| |
| var laxTestData = LaxTestData{1, 2, 3.0, true, time.Date(2013, 11, 27, 0, 34, 0, 0, time.UTC)} |
| |
| func setupPlistValues() { |
| plistValueTree = &cfDictionary{ |
| keys: []string{ |
| "intarray", |
| "floats", |
| "booleans", |
| "strings", |
| "data", |
| "date", |
| }, |
| values: []cfValue{ |
| &cfArray{ |
| values: []cfValue{ |
| &cfNumber{value: 1}, |
| &cfNumber{value: 8}, |
| &cfNumber{value: 16}, |
| &cfNumber{value: 32}, |
| &cfNumber{value: 64}, |
| &cfNumber{value: 2}, |
| &cfNumber{value: 8}, |
| &cfNumber{value: 17}, |
| &cfNumber{value: 33}, |
| &cfNumber{value: 65}, |
| }, |
| }, |
| &cfArray{ |
| values: []cfValue{ |
| &cfReal{wide: false, value: 32.0}, |
| &cfReal{wide: true, value: 64.0}, |
| }, |
| }, |
| &cfArray{ |
| values: []cfValue{ |
| cfBoolean(true), |
| cfBoolean(false), |
| }, |
| }, |
| &cfArray{ |
| values: []cfValue{ |
| cfString("Hello, ASCII"), |
| cfString("Hello, 世界"), |
| }, |
| }, |
| cfData{1, 2, 3, 4}, |
| cfDate(time.Date(2013, 11, 27, 0, 32, 0, 0, time.UTC)), |
| }, |
| } |
| } |
| |
| func init() { |
| setupPlistValues() |
| |
| // Pre-warm the type info struct to remove it from benchmarking |
| getTypeInfo(reflect.ValueOf(plistValueTreeRawData).Type()) |
| } |