Adding struct and func documentation
This commit is contained in:
parent
878efd05bb
commit
c391d7b0c9
53
bmap.go
53
bmap.go
@ -21,20 +21,23 @@ import (
|
|||||||
|
|
||||||
const defaultBMAPHash = "0000000000000000000000000000000000000000"
|
const defaultBMAPHash = "0000000000000000000000000000000000000000"
|
||||||
|
|
||||||
type Block struct {
|
// BlockRange represents a range of blocks of written data
|
||||||
|
type BlockRange struct {
|
||||||
XMLName xml.Name `xml:"Range"`
|
XMLName xml.Name `xml:"Range"`
|
||||||
Start int64
|
Start int64
|
||||||
End int64
|
End int64
|
||||||
Hash string `xml:"sha1,attr"`
|
Hash string `xml:"sha1,attr"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Range is an intermediate data type for xml conversion
|
||||||
type Range struct {
|
type Range struct {
|
||||||
XMLName xml.Name `xml:"Range"`
|
XMLName xml.Name `xml:"Range"`
|
||||||
Range string `xml:",chardata"`
|
Range string `xml:",chardata"`
|
||||||
Hash string `xml:"sha1,attr"`
|
Hash string `xml:"sha1,attr"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Block) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
// MarshalXML is used to convert BlockRange to a Range object for XML output
|
||||||
|
func (b *BlockRange) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
||||||
//fmt.Println(e)
|
//fmt.Println(e)
|
||||||
//fmt.Println(start)
|
//fmt.Println(start)
|
||||||
|
|
||||||
@ -50,7 +53,8 @@ func (b *Block) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Block) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
// UnmarshalXML is used to convert a Range object from XML input into a BlockRange object
|
||||||
|
func (b *BlockRange) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
||||||
|
|
||||||
r := Range{}
|
r := Range{}
|
||||||
err := d.DecodeElement(&r, &start)
|
err := d.DecodeElement(&r, &start)
|
||||||
@ -86,10 +90,12 @@ func (b *Block) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BlockMap represents a list of Block Ranges
|
||||||
type BlockMap struct {
|
type BlockMap struct {
|
||||||
Range []Block
|
Range []BlockRange
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BMap contains all of the information that needs to be represented in the bmap file
|
||||||
type BMap struct {
|
type BMap struct {
|
||||||
XMLName xml.Name `xml:"bmap"`
|
XMLName xml.Name `xml:"bmap"`
|
||||||
Version string `xml:"version,attr"`
|
Version string `xml:"version,attr"`
|
||||||
@ -101,19 +107,23 @@ type BMap struct {
|
|||||||
BlockMap BlockMap `xml:"BlockMap"`
|
BlockMap BlockMap `xml:"BlockMap"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBMap(filename string) BMap {
|
// NewBMap creates a new BMap representation by reading an image file
|
||||||
|
func NewBMap(filename string) (BMap, error) {
|
||||||
stat := syscall.Stat_t{}
|
stat := syscall.Stat_t{}
|
||||||
syscall.Stat(filename, &stat)
|
syscall.Stat(filename, &stat)
|
||||||
blockSize := stat.Blksize
|
blockSize := stat.Blksize
|
||||||
|
|
||||||
fd, _ := os.Open(filename)
|
fd, err := os.Open(filename)
|
||||||
|
|
||||||
defer fd.Close()
|
defer fd.Close()
|
||||||
|
if err != nil {
|
||||||
blockMap, total := getBlockMap(fd, blockSize)
|
return BMap{}, err
|
||||||
return BMap{Version: "1.3", ImageSize: stat.Size, BlockSize: blockSize, BlocksCount: stat.Size / blockSize, MappedBlocksCount: total, BmapFileSHA1: defaultBMAPHash, BlockMap: BlockMap{blockMap}}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
blockMap, total := getBlockMap(fd, blockSize)
|
||||||
|
return BMap{Version: "1.3", ImageSize: stat.Size, BlockSize: blockSize, BlocksCount: stat.Size / blockSize, MappedBlocksCount: total, BmapFileSHA1: defaultBMAPHash, BlockMap: BlockMap{blockMap}}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// XMLOutput converts a BMap object to it's corresponding XML output
|
||||||
func (b *BMap) XMLOutput() ([]byte, error) {
|
func (b *BMap) XMLOutput() ([]byte, error) {
|
||||||
output, err := xml.MarshalIndent(b, "", " ")
|
output, err := xml.MarshalIndent(b, "", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -122,6 +132,7 @@ func (b *BMap) XMLOutput() ([]byte, error) {
|
|||||||
return append([]byte(xml.Header), output...), err
|
return append([]byte(xml.Header), output...), err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Write generates initial XML output, takes the SHA signature, and writes updated XML to file
|
||||||
func (b *BMap) Write(outputFilename string) error {
|
func (b *BMap) Write(outputFilename string) error {
|
||||||
output, err := b.XMLOutput()
|
output, err := b.XMLOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -146,6 +157,7 @@ func (b *BMap) Write(outputFilename string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load reads and converts a bmap file to a BMap object
|
||||||
func Load(filename string) (BMap, error) {
|
func Load(filename string) (BMap, error) {
|
||||||
b := BMap{}
|
b := BMap{}
|
||||||
data, err := ioutil.ReadFile(filename)
|
data, err := ioutil.ReadFile(filename)
|
||||||
@ -178,6 +190,7 @@ func Load(filename string) (BMap, error) {
|
|||||||
return b, err
|
return b, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Copy copies an input file and uses the BMap data to create a new image file
|
||||||
func (b *BMap) Copy(input string, output string) error {
|
func (b *BMap) Copy(input string, output string) error {
|
||||||
inFile, err := os.Open(input)
|
inFile, err := os.Open(input)
|
||||||
defer inFile.Close()
|
defer inFile.Close()
|
||||||
@ -276,33 +289,35 @@ func getBZReader(reader io.Reader) (io.ReadSeeker, error) {
|
|||||||
return bytes.NewReader(data), nil
|
return bytes.NewReader(data), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getBlockMap(fd *os.File, blockSize int64) ([]Block, int64) {
|
// getBlockMap finds all of the ranges of written blocks in a file/image
|
||||||
|
func getBlockMap(fd *os.File, blockSize int64) ([]BlockRange, int64) {
|
||||||
//fd, _ := os.Open(filename)
|
//fd, _ := os.Open(filename)
|
||||||
f := fibmap.NewFibmapFile(fd)
|
f := fibmap.NewFibmapFile(fd)
|
||||||
|
|
||||||
holes := f.SeekDataHole()
|
holes := f.SeekDataHole()
|
||||||
blockMap := make([]Block, len(holes)/2)
|
blockMap := make([]BlockRange, len(holes)/2)
|
||||||
currentBlock := Block{}
|
currentBlockRange := BlockRange{}
|
||||||
mappedBlocks := int64(0)
|
mappedBlocks := int64(0)
|
||||||
for i, v := range holes {
|
for i, v := range holes {
|
||||||
if i%2 == 0 { //Block found @
|
if i%2 == 0 { //BlockRange found @
|
||||||
currentBlock = Block{Start: v / blockSize}
|
currentBlockRange = BlockRange{Start: v / blockSize}
|
||||||
} else { // Length of block
|
} else { // Length of block
|
||||||
length := v / blockSize
|
length := v / blockSize
|
||||||
currentBlock.End = currentBlock.Start + length - 1
|
currentBlockRange.End = currentBlockRange.Start + length - 1
|
||||||
|
|
||||||
h := sha1.New()
|
h := sha1.New()
|
||||||
fd.Seek(currentBlock.Start*blockSize, 0)
|
fd.Seek(currentBlockRange.Start*blockSize, 0)
|
||||||
io.CopyN(h, fd, v)
|
io.CopyN(h, fd, v)
|
||||||
currentBlock.Hash = hex.EncodeToString(h.Sum(nil))
|
currentBlockRange.Hash = hex.EncodeToString(h.Sum(nil))
|
||||||
|
|
||||||
blockMap[i/2] = currentBlock
|
blockMap[i/2] = currentBlockRange
|
||||||
mappedBlocks += length
|
mappedBlocks += length
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return blockMap, mappedBlocks
|
return blockMap, mappedBlocks
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getSHA1Hash returns a hex encoded hash from an io.Reader
|
||||||
func getSHA1Hash(r io.Reader) string {
|
func getSHA1Hash(r io.Reader) string {
|
||||||
h := sha1.New()
|
h := sha1.New()
|
||||||
io.Copy(h, r)
|
io.Copy(h, r)
|
||||||
|
Loading…
Reference in New Issue
Block a user