func replacePathElement()

in encoding/httpbinding/path_replace.go [24:79]


func replacePathElement(path, fieldBuf []byte, key, val string, escape bool) ([]byte, []byte, error) {
	// search for "{<key>}". If not found, search for the greedy version "{<key>+}". If none are found, return error
	fieldBuf = bufCap(fieldBuf, len(key)+2) // { <key> }
	fieldBuf = append(fieldBuf, uriTokenStart)
	fieldBuf = append(fieldBuf, key...)
	fieldBuf = append(fieldBuf, uriTokenStop)

	start := bytes.Index(path, fieldBuf)
	encodeSep := true
	if start < 0 {
		fieldBuf = bufCap(fieldBuf, len(key)+3) // { <key> [+] }
		fieldBuf = append(fieldBuf, uriTokenStart)
		fieldBuf = append(fieldBuf, key...)
		fieldBuf = append(fieldBuf, uriTokenSkip)
		fieldBuf = append(fieldBuf, uriTokenStop)

		start = bytes.Index(path, fieldBuf)
		if start < 0 {
			return path, fieldBuf, fmt.Errorf("invalid path index, start=%d. %s", start, path)
		}
		encodeSep = false
	}
	end := start + len(fieldBuf)

	if escape {
		val = EscapePath(val, encodeSep)
	}

	fieldBuf = bufCap(fieldBuf, len(val))
	fieldBuf = append(fieldBuf, val...)

	keyLen := end - start
	valLen := len(fieldBuf)

	if keyLen == valLen {
		copy(path[start:], fieldBuf)
		return path, fieldBuf, nil
	}

	newLen := len(path) + (valLen - keyLen)
	if len(path) < newLen {
		path = path[:cap(path)]
	}
	if cap(path) < newLen {
		newURI := make([]byte, newLen)
		copy(newURI, path)
		path = newURI
	}

	// shift
	copy(path[start+valLen:], path[end:])
	path = path[:newLen]
	copy(path[start:], fieldBuf)

	return path, fieldBuf, nil
}