seaweedfs/weed-fs/src/pkg/storage/needle.go

68 lines
1.7 KiB
Go
Raw Normal View History

package storage
import (
"io"
"io/ioutil"
"http"
"log"
"strconv"
"strings"
)
type Needle struct{
Cookie uint8 "random number to mitigate brute force lookups"
Key uint64 "file id"
AlternateKey uint32 "supplemental id"
Size uint32 "Data size"
Data []byte "The actual file data"
Checksum int32 "CRC32 to check integrity"
Padding []byte "Aligned to 8 bytes"
}
func NewNeedle(r *http.Request)(n *Needle){
n = new(Needle)
form,fe:=r.MultipartReader()
if fe!=nil {
log.Fatalf("MultipartReader [ERROR] %s\n", fe)
}
part,_:=form.NextPart()
data,_:=ioutil.ReadAll(part)
n.Data = data
n.ParsePath(r.URL.Path[1:strings.LastIndex(r.URL.Path,".")])
return
}
func (n *Needle) ParsePath(path string){
a := strings.Split(path,"_")
log.Println("cookie",a[0],"key",a[1],"altKey",a[2])
cookie,_ := strconv.Atoi(a[0])
n.Cookie = uint8(cookie)
n.Key,_ = strconv.Atoui64(a[1])
altKey,_ := strconv.Atoui64(a[2])
n.AlternateKey = uint32(altKey)
}
func (n *Needle) Append(w io.Writer){
header := make([]byte,17)
header[0] = n.Cookie
uint64toBytes(header[1:9],n.Key)
uint32toBytes(header[9:13],n.AlternateKey)
n.Size = uint32(len(n.Data))
uint32toBytes(header[13:17],n.Size)
w.Write(header)
w.Write(n.Data)
rest := 8-((n.Size+17+4)%8)
uint32toBytes(header[0:4],uint32(n.Checksum))
w.Write(header[0:rest+4])
}
func (n *Needle) Read(r io.Reader, size uint32){
bytes := make([]byte,size+17+4)
r.Read(bytes)
n.Cookie = bytes[0]
n.Key = bytesToUint64(bytes[1:9])
n.AlternateKey = bytesToUint32(bytes[9:13])
n.Size = bytesToUint32(bytes[13:17])
n.Data = bytes[17:17+size]
n.Checksum = int32(bytesToUint32(bytes[17+size:17+size+4]))
}