Adding struct and func documentation

This commit is contained in:
justin 2015-03-07 12:34:39 -05:00
parent 878efd05bb
commit c391d7b0c9

49
bmap.go
View File

@ -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 {
return BMap{}, err
}
blockMap, total := getBlockMap(fd, blockSize) 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}} 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)