Initial commit (code only without large binaries)
This commit is contained in:
112
EdgeNode/internal/utils/bfs/file_writer.go
Normal file
112
EdgeNode/internal/utils/bfs/file_writer.go
Normal file
@@ -0,0 +1,112 @@
|
||||
// Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package bfs
|
||||
|
||||
import "errors"
|
||||
|
||||
// FileWriter file writer
|
||||
// not thread-safe
|
||||
type FileWriter struct {
|
||||
bFile *BlocksFile
|
||||
hasMeta bool
|
||||
hash string
|
||||
|
||||
bodySize int64
|
||||
originOffset int64
|
||||
|
||||
realHeaderSize int64
|
||||
realBodySize int64
|
||||
isPartial bool
|
||||
}
|
||||
|
||||
func NewFileWriter(bFile *BlocksFile, hash string, bodySize int64, isPartial bool) (*FileWriter, error) {
|
||||
if isPartial && bodySize <= 0 {
|
||||
return nil, errors.New("invalid body size for partial content")
|
||||
}
|
||||
|
||||
return &FileWriter{
|
||||
bFile: bFile,
|
||||
hash: hash,
|
||||
bodySize: bodySize,
|
||||
isPartial: isPartial,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (this *FileWriter) WriteMeta(status int, expiresAt int64, expectedFileSize int64) error {
|
||||
this.hasMeta = true
|
||||
return this.bFile.mFile.WriteMeta(this.hash, status, expiresAt, expectedFileSize)
|
||||
}
|
||||
|
||||
func (this *FileWriter) WriteHeader(b []byte) (n int, err error) {
|
||||
if !this.isPartial && !this.hasMeta {
|
||||
err = errors.New("no meta found")
|
||||
return
|
||||
}
|
||||
|
||||
n, err = this.bFile.Write(this.hash, BlockTypeHeader, b, -1)
|
||||
this.realHeaderSize += int64(n)
|
||||
return
|
||||
}
|
||||
|
||||
func (this *FileWriter) WriteBody(b []byte) (n int, err error) {
|
||||
if !this.isPartial && !this.hasMeta {
|
||||
err = errors.New("no meta found")
|
||||
return
|
||||
}
|
||||
|
||||
n, err = this.bFile.Write(this.hash, BlockTypeBody, b, this.originOffset)
|
||||
this.originOffset += int64(n)
|
||||
this.realBodySize += int64(n)
|
||||
return
|
||||
}
|
||||
|
||||
func (this *FileWriter) WriteBodyAt(b []byte, offset int64) (n int, err error) {
|
||||
if !this.hasMeta {
|
||||
err = errors.New("no meta found")
|
||||
return
|
||||
}
|
||||
|
||||
if !this.isPartial {
|
||||
err = errors.New("can not write body at specified offset: it is not a partial file")
|
||||
return
|
||||
}
|
||||
|
||||
// still 'Write()' NOT 'WriteAt()'
|
||||
this.originOffset = offset
|
||||
n, err = this.bFile.Write(this.hash, BlockTypeBody, b, offset)
|
||||
this.originOffset += int64(n)
|
||||
return
|
||||
}
|
||||
|
||||
func (this *FileWriter) Close() error {
|
||||
defer func() {
|
||||
this.bFile.removeWritingFile(this.hash)
|
||||
}()
|
||||
|
||||
if !this.isPartial && !this.hasMeta {
|
||||
return errors.New("no meta found")
|
||||
}
|
||||
|
||||
if this.isPartial {
|
||||
if this.originOffset > this.bodySize {
|
||||
return errors.New("unexpected body size")
|
||||
}
|
||||
this.realBodySize = this.bodySize
|
||||
} else {
|
||||
if this.bodySize > 0 && this.bodySize != this.realBodySize {
|
||||
return errors.New("unexpected body size")
|
||||
}
|
||||
}
|
||||
|
||||
err := this.bFile.mFile.WriteClose(this.hash, this.realHeaderSize, this.realBodySize)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return this.bFile.Sync()
|
||||
}
|
||||
|
||||
func (this *FileWriter) Discard() error {
|
||||
// TODO 需要测试
|
||||
return this.bFile.mFile.RemoveFile(this.hash)
|
||||
}
|
||||
Reference in New Issue
Block a user