mirror of
https://github.com/TeaOSLab/EdgeNode.git
synced 2025-11-03 23:20:25 +08:00
113 lines
2.6 KiB
Go
113 lines
2.6 KiB
Go
// Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cloud .
|
|
|
|
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)
|
|
}
|