// NewJSONSignature returns a new unsigned JWS from a json byte array. // JSONSignature will need to be signed before serializing or storing. // Optionally, one or more signatures can be provided as byte buffers, // containing serialized JWS signatures, to assemble a fully signed JWS // package. It is the callers responsibility to ensure uniqueness of the // provided signatures. func NewJSONSignature(content []byte, signatures ...[]byte) (*JSONSignature, error) { var dataMap map[string]interface{} err := json.Unmarshal(content, &dataMap) if err != nil { return nil, err } js := newJSONSignature() js.indent = detectJSONIndent(content) js.payload = joseBase64UrlEncode(content) // Find trailing } and whitespace, put in protected header closeIndex := bytes.LastIndexFunc(content, notSpace) if content[closeIndex] != '}' { return nil, ErrInvalidJSONContent } lastRuneIndex := bytes.LastIndexFunc(content[:closeIndex], notSpace) if content[lastRuneIndex] == ',' { return nil, ErrInvalidJSONContent } js.formatLength = lastRuneIndex + 1 js.formatTail = content[js.formatLength:] if len(signatures) > 0 { for _, signature := range signatures { var parsedJSig jsParsedSignature if err := json.Unmarshal(signature, &parsedJSig); err != nil { return nil, err } // TODO(stevvooe): A lot of the code below is repeated in // ParseJWS. It will require more refactoring to fix that. jsig := jsSignature{ Header: jsHeader{ Algorithm: parsedJSig.Header.Algorithm, }, Signature: parsedJSig.Signature, Protected: parsedJSig.Protected, } if parsedJSig.Header.Chain != nil { jsig.Header.Chain = parsedJSig.Header.Chain } if parsedJSig.Header.JWK != nil { publicKey, err := UnmarshalPublicKeyJWK([]byte(parsedJSig.Header.JWK)) if err != nil { return nil, err } jsig.Header.JWK = publicKey } js.signatures = append(js.signatures, jsig) } } return js, nil }
func main() { f1 := func(r rune) bool { return r == '7' } f2 := func(r rune) bool { return r == '9' } s := []byte("12345678") fmt.Println(bytes.LastIndexFunc(s, f1)) fmt.Println(bytes.LastIndexFunc(s, f2)) }
// NewJSONSignature returns a new unsigned JWS from a json byte array. // JSONSignature will need to be signed before serializing or storing. func NewJSONSignature(content []byte) (*JSONSignature, error) { var dataMap map[string]interface{} err := json.Unmarshal(content, &dataMap) if err != nil { return nil, err } js := newJSONSignature() js.indent = detectJSONIndent(content) js.payload = joseBase64UrlEncode(content) // Find trailing } and whitespace, put in protected header closeIndex := bytes.LastIndexFunc(content, notSpace) if content[closeIndex] != '}' { return nil, ErrInvalidJSONContent } lastRuneIndex := bytes.LastIndexFunc(content[:closeIndex], notSpace) if content[lastRuneIndex] == ',' { return nil, ErrInvalidJSONContent } js.formatLength = lastRuneIndex + 1 js.formatTail = content[js.formatLength:] return js, nil }
// TODO: func (f *File) OffsetLine(ln, start int) (offset int, e error) { if start < 0 || start > len(f.b) { return 0, memfile.OutOfBounds } if ln == 0 { i := bytes.LastIndex(f.b[:start], []byte("\n")) return i + 1, nil } if ln < 0 { i := 0 return bytes.LastIndexFunc(f.b[:start], func(r rune) bool { if r == '\n' { if i == ln { return true } i-- } return false }) + 1, nil } i := 0 va := bytes.IndexFunc(f.b[start:], func(r rune) bool { if r == '\n' { i++ if i == ln { return true } } return false }) if va != -1 { return va + start + 1, nil } return len(f.b), nil }
func lastIndexFunc(s []byte, f func(rune) bool) { if i := bytes.LastIndexFunc(s, f); i == -1 { log.Printf("Something controlled by %#v does NOT appear in %s", f, s) } else { log.Printf("Something controlled by %#v appears at index %d in %s", f, i, s) } }
func (lm *logMetrics) HandleLogfmt(key, val []byte) error { i := bytes.LastIndexFunc(val, isDigit) if i == -1 { lm.metrics[string(key)] = logValue{string(val), ""} } else { lm.metrics[string(key)] = logValue{string(val[:i+1]), string(val[i+1:])} } log.WithFields(log.Fields{ "key": string(key), "val": lm.metrics[string(key)].Val, "unit": lm.metrics[string(key)].Unit, }).Debug("logMetric") return nil }
func (mm *Measurements) HandleLogfmt(key, val []byte) error { if !bytes.HasPrefix(key, measurePrefix) { return nil } i := bytes.LastIndexFunc(val, isDigit) v, err := strconv.ParseFloat(string(val[:i+1]), 10) if err != nil { return err } m := &Measurement{ Key: string(key[len(measurePrefix):]), Val: v, Unit: string(val[i+1:]), } *mm = append(*mm, m) return nil }