Beispiel #1
0
// 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
}
Beispiel #2
0
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
}
Beispiel #3
0
// 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
}
Beispiel #4
0
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
}
Beispiel #5
0
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
}
Beispiel #6
0
// 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
}
Beispiel #7
0
// 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)
}
Beispiel #8
0
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
}