matchAnyClassAndTag = false
}
+ if !params.explicit && params.private && params.tag != nil {
+ expectedClass = ClassPrivate
+ expectedTag = *params.tag
+ matchAnyClassAndTag = false
+ }
+
// We have unwrapped any explicit tagging at this point.
if !matchAnyClassAndTag && (t.class != expectedClass || t.tag != expectedTag) ||
(!matchAny && t.isCompound != compoundType) {
// The following tags on struct fields have special meaning to Unmarshal:
//
// application specifies that an APPLICATION tag is used
+// private specifies that a PRIVATE tag is used
// default:x sets the default value for optional integer fields (only used if optional is also present)
// explicit specifies that an additional, explicit tag wraps the implicit one
// optional marks the field as ASN.1 OPTIONAL
{"optional", fieldParameters{optional: true}},
{"explicit", fieldParameters{explicit: true, tag: new(int)}},
{"application", fieldParameters{application: true, tag: new(int)}},
+ {"private", fieldParameters{private: true, tag: new(int)}},
{"optional,explicit", fieldParameters{optional: true, explicit: true, tag: new(int)}},
{"default:42", fieldParameters{defaultValue: newInt64(42)}},
{"tag:17", fieldParameters{tag: newInt(17)}},
{"optional,explicit,default:42,tag:17", fieldParameters{optional: true, explicit: true, defaultValue: newInt64(42), tag: newInt(17)}},
- {"optional,explicit,default:42,tag:17,rubbish1", fieldParameters{true, true, false, newInt64(42), newInt(17), 0, 0, false, false}},
+ {"optional,explicit,default:42,tag:17,rubbish1", fieldParameters{optional: true, explicit: true, application: false, defaultValue: newInt64(42), tag: newInt(17), stringType: 0, timeType: 0, set: false, omitEmpty: false}},
{"set", fieldParameters{set: true}},
}
{true, []byte{0x30, 3, (ClassContextSpecific << 6) | tag, 1, 1}},
{true, []byte{0x30, 3, (ClassContextSpecific << 6) | tag | isCompound, 1, 1}},
{false, []byte{0x30, 3, (ClassApplication << 6) | tag | isCompound, 1, 1}},
+ {false, []byte{0x30, 3, (ClassPrivate << 6) | tag | isCompound, 1, 1}},
}
for i, test := range tests {
optional bool // true iff the field is OPTIONAL
explicit bool // true iff an EXPLICIT tag is in use.
application bool // true iff an APPLICATION tag is in use.
+ private bool // true iff a PRIVATE tag is in use.
defaultValue *int64 // a default value for INTEGER typed fields (maybe nil).
tag *int // the EXPLICIT or IMPLICIT tag (maybe nil).
stringType int // the string tag to use when marshaling.
if ret.tag == nil {
ret.tag = new(int)
}
+ case part == "private":
+ ret.private = true
+ if ret.tag == nil {
+ ret.tag = new(int)
+ }
case part == "omitempty":
ret.omitEmpty = true
}
if params.tag != nil {
if params.application {
class = ClassApplication
+ } else if params.private {
+ class = ClassPrivate
} else {
class = ClassContextSpecific
}
B int `asn1:"application,tag:1,explicit"`
}
+type privateTest struct {
+ A int `asn1:"private,tag:0"`
+ B int `asn1:"private,tag:1,explicit"`
+ C int `asn1:"private,tag:31"` // tag size should be 2 octet
+ D int `asn1:"private,tag:128"` // tag size should be 3 octet
+}
+
type numericStringTest struct {
A string `asn1:"numeric"`
}
{defaultTest{1}, "3000"},
{defaultTest{2}, "3003020102"},
{applicationTest{1, 2}, "30084001016103020102"},
+ {privateTest{1, 2, 3, 4}, "3011c00101e103020102df1f0103df81000104"},
{numericStringTest{"1 9"}, "30051203312039"},
}
var marshalWithParamsTests = []marshalWithParamsTest{
{intStruct{10}, "set", "310302010a"},
{intStruct{10}, "application", "600302010a"},
+ {intStruct{10}, "private", "e00302010a"},
}
func TestMarshalWithParams(t *testing.T) {