package sip import ( "github.com/jart/gosip/util" "strconv" "strings" "time" ) func duration(ms *int) time.Duration { return time.Duration(*ms) * time.Millisecond } func or5060(port uint16) uint16 { if port == 0 { return 5060 } return port } func portstr(port uint16) string { return strconv.FormatInt(int64(port), 10) } func extractHostPort(s string) (s2, host string, port uint16, err error) { if s == "" { err = URIMissingHost } else { if s[0] == '[' { // quoted/ipv6: sip:[dead:beef::666]:5060 n := strings.Index(s, "]") if n < 0 { err = URIMissingHost } host, s = s[1:n], s[n+1:] if s != "" && s[0] == ':' { // we has a port too s = s[1:] s, port, err = extractPort(s) } } else { // non-quoted host: sip:1.2.3.4:5060 switch n := strings.IndexAny(s, delims); { case n < 0: host, s = s, "" case s[n] == ':': // host:port host, s = s[0:n], s[n+1:] s, port, err = extractPort(s) default: host, s = s[0:n], s[n:] } } } return s, host, port, err } func parseParams(s string) (res Params) { items := strings.Split(s, ";") if items == nil || len(items) == 0 || items[0] == "" { return } res = make(Params, len(items)) for _, item := range items { if item == "" { continue } n := strings.Index(item, "=") var k, v string if n > 0 { k, v = item[0:n], item[n+1:] } else { k, v = item, "" } k, kerr := util.URLUnescape(k, false) v, verr := util.URLUnescape(v, false) if kerr != nil || verr != nil { continue } res[k] = v } return res } func extractPort(s string) (s2 string, port uint16, err error) { if n := strings.IndexAny(s, delims); n > 0 { port, err = parsePort(s[0:n]) s = s[n:] } else { port, err = parsePort(s) s = "" } return s, port, err } func parsePort(s string) (port uint16, err error) { i, err := strconv.ParseUint(s, 10, 16) port = uint16(i) return } func unhex(b byte) byte { switch { case '0' <= b && b <= '9': return b - '0' case 'a' <= b && b <= 'f': return b - 'a' + 10 case 'A' <= b && b <= 'F': return b - 'A' + 10 } return 0 } func appendCollapse(buf []byte, amt int, fc byte) int { switch fc { case ' ', '\t', '\r', '\n': if amt == 0 || buf[amt-1] != ' ' { buf[amt] = ' ' amt++ } default: buf[amt] = fc amt++ } return amt } func appendLower(buf []byte, amt int, fc byte) int { if 'A' <= fc && fc <= 'Z' { buf[amt] = fc + 0x20 } else { buf[amt] = fc } return amt + 1 }