package ber func lenLen(i int) int { n := 1 for ; i > 255; i >>= 8 { n++ } return n } func (s *state) marshalLen(val int) { if val < 0x80 { s.WriteByte(byte(val)) return } n := lenLen(val) s.WriteByte(byte(n) | 0x80) for ; n > 0; n-- { s.WriteByte(byte(val >> uint((n-1)*8))) } } func (s *state) marshalBool(val bool) { s.marshalLen(1) if val { s.WriteByte(0xff) } else { s.WriteByte(0) } } func intLen(i int) int { n := 1 for ; i > 127; i >>= 8 { n++ } for ; i < -128; i >>= 8 { n++ } return n } func (s *state) marshalInt(val int) { n := intLen(val) s.marshalLen(n) for ; n > 0; n-- { s.WriteByte(byte(val >> uint((n-1)*8))) } } func (s *state) marshalString(val string) { s.marshalLen(len(val)) s.Write([]byte(val)) } func (s *state) marshalBase128(val int) { if val == 0 { s.WriteByte(0) return } var l int for i := val; i > 0; i >>= 7 { l++ } for i := l - 1; i >= 0; i-- { o := byte(val >> uint(i*7) & 0x7f) if i != 0 { o |= 0x80 } s.WriteByte(o) } } func (s *state) marshalOID(val OID) { if len(val) < 2 || val[0] > 2 { return } if val[0] < 2 && val[1] > 39 { return } buf := &state{} buf.marshalBase128(val[0]*40 + val[1]) for _, v := range val[2:] { buf.marshalBase128(v) } s.marshalLen(buf.Len()) s.Write(buf.Bytes()) } func (s *state) marshalBitString(val BitString) { pad := (8 - len(val)%8) % 8 l := len(val) / 8 if pad != 0 { l++ } b := make([]byte, l) for i, v := range val { if v { x := i / 8 y := 7 - uint(i%8) b[x] |= 1 << y } } s.marshalLen(l + 1) s.WriteByte(byte(pad)) s.Write(b) } func (s *state) marshalClass(h Header) { head := byte(h.Class) | byte(h.Kind) if h.Tag < tagMask { s.WriteByte(head | byte(h.Tag)) } else { s.WriteByte(head | byte(tagMask)) s.marshalBase128(int(h.Tag)) } }