// SplitHostPort splits a network address of the form "host:port",// "host%zone:port", "[host]:port" or "[host%zone]:port" into host or// host%zone and port.//// A literal IPv6 address in hostport must be enclosed in square// brackets, as in "[::1]:80", "[::1%lo0]:80".//// See func Dial for a description of the hostport parameter, and host// and port results.funcSplitHostPort(hostportstring)(host,portstring,errerror){const(missingPort="missing port in address"tooManyColons="too many colons in address")addrErr:=func(addr,whystring)(host,portstring,errerror){return"","",&AddrError{Err:why,Addr:addr}}j,k:=0,0// The port starts after the last colon.i:=bytealg.LastIndexByteString(hostport,':')ifi<0{returnaddrErr(hostport,missingPort)}ifhostport[0]=='['{// Expect the first ']' just before the last ':'.end:=bytealg.IndexByteString(hostport,']')ifend<0{returnaddrErr(hostport,"missing ']' in address")}switchend+1{caselen(hostport):// There can't be a ':' behind the ']' now.returnaddrErr(hostport,missingPort)casei:// The expected result.default:// Either ']' isn't followed by a colon, or it is// followed by a colon that is not the last one.ifhostport[end+1]==':'{returnaddrErr(hostport,tooManyColons)}returnaddrErr(hostport,missingPort)}host=hostport[1:end]j,k=1,end+1// there can't be a '[' resp. ']' before these positions}else{host=hostport[:i]ifbytealg.IndexByteString(host,':')>=0{returnaddrErr(hostport,tooManyColons)}}ifbytealg.IndexByteString(hostport[j:],'[')>=0{returnaddrErr(hostport,"unexpected '[' in address")}ifbytealg.IndexByteString(hostport[k:],']')>=0{returnaddrErr(hostport,"unexpected ']' in address")}port=hostport[i+1:]returnhost,port,nil}