Copyright 2011 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.

package packet

import (
	
	
	
)
UserId contains text that is intended to represent the name and email address of the key holder. See RFC 4880, section 5.11. By convention, this takes the form "Full Name (Comment) <email@example.com>"
type UserId struct {
	Id string // By convention, this takes the form "Full Name (Comment) <email@example.com>" which is split out in the fields below.

	Name, Comment, Email string
}

func ( string) bool {
	for ,  := range  {
		switch  {
		case '(', ')', '<', '>', 0:
			return true
		}
	}
	return false
}
NewUserId returns a UserId or nil if any of the arguments contain invalid characters. The invalid characters are '\x00', '(', ')', '<' and '>'
RFC 4880 doesn't deal with the structure of userid strings; the name, comment and email form is just a convention. However, there's no convention about escaping the metacharacters and GPG just refuses to create user ids where, say, the name contains a '('. We mirror this behaviour.

	if hasInvalidCharacters() || hasInvalidCharacters() || hasInvalidCharacters() {
		return nil
	}

	 := new(UserId)
	.Name, .Comment, .Email = , , 
	.Id = 
	if len() > 0 {
		if len(.Id) > 0 {
			.Id += " "
		}
		.Id += "("
		.Id += 
		.Id += ")"
	}
	if len() > 0 {
		if len(.Id) > 0 {
			.Id += " "
		}
		.Id += "<"
		.Id += 
		.Id += ">"
	}
	return 
}

RFC 4880, section 5.11
	,  := ioutil.ReadAll()
	if  != nil {
		return
	}
	.Id = string()
	.Name, .Comment, .Email = parseUserId(.Id)
	return
}
Serialize marshals uid to w in the form of an OpenPGP packet, including header.
func ( *UserId) ( io.Writer) error {
	 := serializeHeader(, packetTypeUserId, len(.Id))
	if  != nil {
		return 
	}
	_,  = .Write([]byte(.Id))
	return 
}
parseUserId extracts the name, comment and email from a user id string that is formatted as "Full Name (Comment) <email@example.com>".
func ( string) (, ,  string) {
	var , ,  struct {
		,  int
	}
	var  int

	for ,  := range  {
		switch  {
Entering name
			. = 
			 = 1
			fallthrough
In name
			if  == '(' {
				 = 2
				. = 
			} else if  == '<' {
				 = 5
				. = 
			}
Entering comment
			. = 
			 = 3
			fallthrough
In comment
			if  == ')' {
				 = 4
				. = 
			}
Between comment and email
			if  == '<' {
				 = 5
			}
Entering email
			. = 
			 = 6
			fallthrough
In email
			if  == '>' {
				 = 7
				. = 
			}
After email
		}
	}
	switch  {
ended in the name
		. = len()
ended in comment
		. = len()
ended in email
		. = len()
	}

	 = strings.TrimSpace([.:.])
	 = strings.TrimSpace([.:.])
	 = strings.TrimSpace([.:.])
	return