forked from cerc-io/ipld-eth-server
89 lines
2.2 KiB
Go
89 lines
2.2 KiB
Go
package chunk
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
var (
|
|
ErrRabinMin = errors.New("rabin min must be greater than 16")
|
|
ErrSize = errors.New("chunker size muster greater than 0")
|
|
)
|
|
|
|
// FromString returns a Splitter depending on the given string:
|
|
// it supports "default" (""), "size-{size}", "rabin", "rabin-{blocksize}" and
|
|
// "rabin-{min}-{avg}-{max}".
|
|
func FromString(r io.Reader, chunker string) (Splitter, error) {
|
|
switch {
|
|
case chunker == "" || chunker == "default":
|
|
return DefaultSplitter(r), nil
|
|
|
|
case strings.HasPrefix(chunker, "size-"):
|
|
sizeStr := strings.Split(chunker, "-")[1]
|
|
size, err := strconv.Atoi(sizeStr)
|
|
if err != nil {
|
|
return nil, err
|
|
} else if size <= 0 {
|
|
return nil, ErrSize
|
|
}
|
|
return NewSizeSplitter(r, int64(size)), nil
|
|
|
|
case strings.HasPrefix(chunker, "rabin"):
|
|
return parseRabinString(r, chunker)
|
|
|
|
default:
|
|
return nil, fmt.Errorf("unrecognized chunker option: %s", chunker)
|
|
}
|
|
}
|
|
|
|
func parseRabinString(r io.Reader, chunker string) (Splitter, error) {
|
|
parts := strings.Split(chunker, "-")
|
|
switch len(parts) {
|
|
case 1:
|
|
return NewRabin(r, uint64(DefaultBlockSize)), nil
|
|
case 2:
|
|
size, err := strconv.Atoi(parts[1])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return NewRabin(r, uint64(size)), nil
|
|
case 4:
|
|
sub := strings.Split(parts[1], ":")
|
|
if len(sub) > 1 && sub[0] != "min" {
|
|
return nil, errors.New("first label must be min")
|
|
}
|
|
min, err := strconv.Atoi(sub[len(sub)-1])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if min < 16 {
|
|
return nil, ErrRabinMin
|
|
}
|
|
sub = strings.Split(parts[2], ":")
|
|
if len(sub) > 1 && sub[0] != "avg" {
|
|
log.Error("sub == ", sub)
|
|
return nil, errors.New("second label must be avg")
|
|
}
|
|
avg, err := strconv.Atoi(sub[len(sub)-1])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
sub = strings.Split(parts[3], ":")
|
|
if len(sub) > 1 && sub[0] != "max" {
|
|
return nil, errors.New("final label must be max")
|
|
}
|
|
max, err := strconv.Atoi(sub[len(sub)-1])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return NewRabinMinMax(r, uint64(min), uint64(avg), uint64(max)), nil
|
|
default:
|
|
return nil, errors.New("incorrect format (expected 'rabin' 'rabin-[avg]' or 'rabin-[min]-[avg]-[max]'")
|
|
}
|
|
}
|