...

Source file src/vendor/golang.org/x/crypto/cryptobyte/string.go

     1	// Copyright 2017 The Go Authors. All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	// Package cryptobyte contains types that help with parsing and constructing
     6	// length-prefixed, binary messages, including ASN.1 DER. (The asn1 subpackage
     7	// contains useful ASN.1 constants.)
     8	//
     9	// The String type is for parsing. It wraps a []byte slice and provides helper
    10	// functions for consuming structures, value by value.
    11	//
    12	// The Builder type is for constructing messages. It providers helper functions
    13	// for appending values and also for appending length-prefixed submessages –
    14	// without having to worry about calculating the length prefix ahead of time.
    15	//
    16	// See the documentation and examples for the Builder and String types to get
    17	// started.
    18	package cryptobyte // import "golang.org/x/crypto/cryptobyte"
    19	
    20	// String represents a string of bytes. It provides methods for parsing
    21	// fixed-length and length-prefixed values from it.
    22	type String []byte
    23	
    24	// read advances a String by n bytes and returns them. If less than n bytes
    25	// remain, it returns nil.
    26	func (s *String) read(n int) []byte {
    27		if len(*s) < n {
    28			return nil
    29		}
    30		v := (*s)[:n]
    31		*s = (*s)[n:]
    32		return v
    33	}
    34	
    35	// Skip advances the String by n byte and reports whether it was successful.
    36	func (s *String) Skip(n int) bool {
    37		return s.read(n) != nil
    38	}
    39	
    40	// ReadUint8 decodes an 8-bit value into out and advances over it.
    41	// It reports whether the read was successful.
    42	func (s *String) ReadUint8(out *uint8) bool {
    43		v := s.read(1)
    44		if v == nil {
    45			return false
    46		}
    47		*out = uint8(v[0])
    48		return true
    49	}
    50	
    51	// ReadUint16 decodes a big-endian, 16-bit value into out and advances over it.
    52	// It reports whether the read was successful.
    53	func (s *String) ReadUint16(out *uint16) bool {
    54		v := s.read(2)
    55		if v == nil {
    56			return false
    57		}
    58		*out = uint16(v[0])<<8 | uint16(v[1])
    59		return true
    60	}
    61	
    62	// ReadUint24 decodes a big-endian, 24-bit value into out and advances over it.
    63	// It reports whether the read was successful.
    64	func (s *String) ReadUint24(out *uint32) bool {
    65		v := s.read(3)
    66		if v == nil {
    67			return false
    68		}
    69		*out = uint32(v[0])<<16 | uint32(v[1])<<8 | uint32(v[2])
    70		return true
    71	}
    72	
    73	// ReadUint32 decodes a big-endian, 32-bit value into out and advances over it.
    74	// It reports whether the read was successful.
    75	func (s *String) ReadUint32(out *uint32) bool {
    76		v := s.read(4)
    77		if v == nil {
    78			return false
    79		}
    80		*out = uint32(v[0])<<24 | uint32(v[1])<<16 | uint32(v[2])<<8 | uint32(v[3])
    81		return true
    82	}
    83	
    84	func (s *String) readUnsigned(out *uint32, length int) bool {
    85		v := s.read(length)
    86		if v == nil {
    87			return false
    88		}
    89		var result uint32
    90		for i := 0; i < length; i++ {
    91			result <<= 8
    92			result |= uint32(v[i])
    93		}
    94		*out = result
    95		return true
    96	}
    97	
    98	func (s *String) readLengthPrefixed(lenLen int, outChild *String) bool {
    99		lenBytes := s.read(lenLen)
   100		if lenBytes == nil {
   101			return false
   102		}
   103		var length uint32
   104		for _, b := range lenBytes {
   105			length = length << 8
   106			length = length | uint32(b)
   107		}
   108		if int(length) < 0 {
   109			// This currently cannot overflow because we read uint24 at most, but check
   110			// anyway in case that changes in the future.
   111			return false
   112		}
   113		v := s.read(int(length))
   114		if v == nil {
   115			return false
   116		}
   117		*outChild = v
   118		return true
   119	}
   120	
   121	// ReadUint8LengthPrefixed reads the content of an 8-bit length-prefixed value
   122	// into out and advances over it. It reports whether the read was successful.
   123	func (s *String) ReadUint8LengthPrefixed(out *String) bool {
   124		return s.readLengthPrefixed(1, out)
   125	}
   126	
   127	// ReadUint16LengthPrefixed reads the content of a big-endian, 16-bit
   128	// length-prefixed value into out and advances over it. It reports whether the
   129	// read was successful.
   130	func (s *String) ReadUint16LengthPrefixed(out *String) bool {
   131		return s.readLengthPrefixed(2, out)
   132	}
   133	
   134	// ReadUint24LengthPrefixed reads the content of a big-endian, 24-bit
   135	// length-prefixed value into out and advances over it. It reports whether
   136	// the read was successful.
   137	func (s *String) ReadUint24LengthPrefixed(out *String) bool {
   138		return s.readLengthPrefixed(3, out)
   139	}
   140	
   141	// ReadBytes reads n bytes into out and advances over them. It reports
   142	// whether the read was successful.
   143	func (s *String) ReadBytes(out *[]byte, n int) bool {
   144		v := s.read(n)
   145		if v == nil {
   146			return false
   147		}
   148		*out = v
   149		return true
   150	}
   151	
   152	// CopyBytes copies len(out) bytes into out and advances over them. It reports
   153	// whether the copy operation was successful
   154	func (s *String) CopyBytes(out []byte) bool {
   155		n := len(out)
   156		v := s.read(n)
   157		if v == nil {
   158			return false
   159		}
   160		return copy(out, v) == n
   161	}
   162	
   163	// Empty reports whether the string does not contain any bytes.
   164	func (s String) Empty() bool {
   165		return len(s) == 0
   166	}
   167	

View as plain text