// parses: // "<size_u32> <big-blobref> <big-offset>" func parseMetaRow(v []byte) (m meta, err error) { row := v sp := bytes.IndexByte(v, ' ') if sp < 1 || sp == len(v)-1 { return meta{}, fmt.Errorf("invalid metarow %q", v) } m.exists = true size, err := strutil.ParseUintBytes(v[:sp], 10, 32) if err != nil { return meta{}, fmt.Errorf("invalid metarow size %q", v) } m.size = uint32(size) v = v[sp+1:] // remains: "<big-blobref> <big-offset>" if bytes.Count(v, singleSpace) != 1 { return meta{}, fmt.Errorf("invalid metarow %q: wrong number of spaces", row) } sp = bytes.IndexByte(v, ' ') largeRef, ok := blob.ParseBytes(v[:sp]) if !ok { return meta{}, fmt.Errorf("invalid metarow %q: bad blobref %q", row, v[:sp]) } m.largeRef = largeRef off, err := strutil.ParseUintBytes(v[sp+1:], 10, 32) if err != nil { return meta{}, fmt.Errorf("invalid metarow %q: bad offset: %v", row, err) } m.largeOff = uint32(off) return m, nil }
func (ns *nsto) EnumerateBlobs(ctx context.Context, dest chan<- blob.SizedRef, after string, limit int) error { defer close(dest) done := ctx.Done() it := ns.inventory.Find(after, "") first := true for limit > 0 && it.Next() { if first { first = false if after != "" && it.Key() == after { continue } } br, ok := blob.ParseBytes(it.KeyBytes()) size, err := strutil.ParseUintBytes(it.ValueBytes(), 10, 32) if !ok || err != nil { log.Printf("Bogus namespace key %q / value %q", it.Key(), it.Value()) continue } select { case dest <- blob.SizedRef{br, uint32(size)}: case <-done: return ctx.Err() } limit-- } if err := it.Close(); err != nil { return err } return nil }
// v is "width|height" func kvImageInfo(v []byte) (ii camtypes.ImageInfo, ok bool) { pipei := bytes.IndexByte(v, '|') if pipei < 0 { return } w, err := strutil.ParseUintBytes(v[:pipei], 10, 16) if err != nil { return } h, err := strutil.ParseUintBytes(v[pipei+1:], 10, 16) if err != nil { return } ii.Width = uint16(w) ii.Height = uint16(h) return ii, true }
func ParseFields(v []byte, dst ...interface{}) error { for i, dv := range dst { thisv := v if i < len(dst)-1 { sp := bytes.IndexByte(v, ' ') if sp == -1 { return fmt.Errorf("missing space following field index %d", i) } thisv = v[:sp] v = v[sp+1:] } switch dv := dv.(type) { case *blob.Ref: br, ok := blob.ParseBytes(thisv) if !ok { } *dv = br case *uint32: n, err := strutil.ParseUintBytes(thisv, 10, 32) if err != nil { return err } *dv = uint32(n) case *uint64: n, err := strutil.ParseUintBytes(thisv, 10, 64) if err != nil { return err } *dv = n case *int64: n, err := strutil.ParseUintBytes(thisv, 10, 64) if err != nil { return err } if int64(n) < 0 { return errors.New("conv: negative numbers not accepted with int64 dest type") } *dv = int64(n) default: return fmt.Errorf("conv: unsupported target pointer type %T", dv) } } return nil }
func parseMetaRowSizeOnly(v []byte) (size uint32, err error) { sp := bytes.IndexByte(v, ' ') if sp < 1 || sp == len(v)-1 { return 0, fmt.Errorf("invalid metarow %q", v) } size64, err := strutil.ParseUintBytes(v[:sp], 10, 32) if err != nil { return 0, fmt.Errorf("invalid metarow size %q", v) } return uint32(size64), nil }
// readHeader parses "[sha1-fooooo 1234]" from r and returns the // number of bytes read (including the starting '[' and ending ']'), // the blobref bytes (not necessarily valid) and the number as a // uint32. // The consumed count returned is only valid if err == nil. // The returned digest slice is only valid until the next read from br. func readHeader(br *bufio.Reader) (consumed int, digest []byte, size uint32, err error) { line, err := br.ReadSlice(']') if err != nil { return } const minSize = len("[b-c 0]") sp := bytes.IndexByte(line, ' ') size64, err := strutil.ParseUintBytes(line[sp+1:len(line)-1], 10, 32) if len(line) < minSize || line[0] != '[' || line[len(line)-1] != ']' || sp < 0 || err != nil { return 0, nil, 0, errors.New("diskpacked: invalid header reader") } return len(line), line[1:sp], uint32(size64), nil }
// GoroutineID returns the current goroutine's ID. // Use of this function is almost always a terrible idea. // It is also very slow. // GoroutineID is intended only for debugging. // In particular, it is used by syncutil. func GoroutineID() int64 { b := getBuf() defer putBuf(b) b = b[:runtime.Stack(b, false)] // Parse the 4707 out of "goroutine 4707 [" b = bytes.TrimPrefix(b, goroutineSpace) i := bytes.IndexByte(b, ' ') if i < 0 { panic(fmt.Sprintf("No space found in %q", b)) } b = b[:i] n, err := strutil.ParseUintBytes(b, 10, 64) if err != nil { panic(fmt.Sprintf("Failed to parse goroutine ID out of %q: %v", b, err)) } return int64(n) }
func kvBlobMeta_bytes(k, v []byte) (bm camtypes.BlobMeta, ok bool) { ref := k[len("meta:"):] br, ok := blob.ParseBytes(ref) if !ok { return } pipe := bytes.IndexByte(v, '|') if pipe < 0 { return } size, err := strutil.ParseUintBytes(v[:pipe], 10, 32) if err != nil { return } return camtypes.BlobMeta{ Ref: br, Size: uint32(size), CamliType: camliTypeFromMIME_bytes(v[pipe+1:]), }, true }