github.com/bhojpur/cache@v0.0.4/pkg/file/types/file.go (about) 1 package types 2 3 // Copyright (c) 2018 Bhojpur Consulting Private Limited, India. All rights reserved. 4 5 // Permission is hereby granted, free of charge, to any person obtaining a copy 6 // of this software and associated documentation files (the "Software"), to deal 7 // in the Software without restriction, including without limitation the rights 8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 // copies of the Software, and to permit persons to whom the Software is 10 // furnished to do so, subject to the following conditions: 11 12 // The above copyright notice and this permission notice shall be included in 13 // all copies or substantial portions of the Software. 14 15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 // THE SOFTWARE. 22 23 import ( 24 "encoding/json" 25 "errors" 26 "os" 27 28 "github.com/bhojpur/cache/pkg/file/crypto" 29 "github.com/bhojpur/cache/pkg/file/models" 30 ) 31 32 var ( 33 // ErrNilFilename is returned when the fileame to construct a new file is nil. 34 ErrNilFilename = errors.New("filename to construct file must not be nil") 35 36 // ErrNilShardCount is returned when the shard counnt to cosntruct a new file is nil. 37 ErrNilShardCount = errors.New("shard count to cosntruct file must not be nil") 38 39 // ErrNilFileSize is returned when the file size to construct a new file is nil. 40 ErrNilFileSize = errors.New("file size to construct file must not be nil") 41 ) 42 43 // File contains the (important) metadata of a file stored in a database. 44 type File struct { 45 Filename string `json:"filename"` // The file's filename 46 ShardCount int `json:"shard_count"` // The number of shards hosting the file 47 Size uint32 `json:"size"` // Total size of the file 48 ShardDB *shardDB `json:"shard_db"` // Pointer to this file's shardDb 49 Hash crypto.Hash `json:"hash"` // The hash of the file 50 } 51 52 // NewFile constructs a new file from a file in memory. 53 func NewFile(filename string) (*File, error) { 54 // Check that the filename is not nil 55 if filename == "" { 56 return nil, ErrNilFilename 57 } 58 59 // Open the file 60 f, err := os.Open(filename) 61 if err != nil { 62 return nil, err 63 } 64 defer f.Close() 65 66 // Get the file length and bytes 67 fileStat, err := f.Stat() 68 if err != nil { 69 return nil, err 70 } 71 size := uint32(fileStat.Size()) 72 if size == 0 { 73 return nil, ErrNilFileSize 74 } 75 76 // Read from the file 77 bytes := make([]byte, size) 78 _, err = f.Read(bytes) 79 if err != nil { 80 return nil, err 81 } 82 83 shardCount := models.ShardCount 84 85 // Create a new file pointer 86 file := &File{ 87 Filename: filename, // The filename 88 ShardCount: shardCount, // The total amount of shards hostinng the file 89 Size: size, // The total size of the file 90 ShardDB: nil, // nil for now 91 } 92 93 // Compute the hash of the file 94 (*file).Hash = crypto.Sha3(file.Bytes()) 95 return file, nil 96 } 97 98 // FileFromBytes constructs a *File from a []byte. 99 func FileFromBytes(b []byte) (*File, error) { 100 if b == nil { 101 return nil, errors.New("cannot construct file from nil []byte") 102 } 103 buffer := &File{} // Init buffer 104 err := json.Unmarshal(b, buffer) // Unmarshal json 105 return buffer, err 106 } 107 108 /* ----- BEGIN HELPER FUNCTIONS ----- */ 109 110 // Bytes converts the database header to bytes. 111 func (file *File) Bytes() []byte { 112 json, _ := json.MarshalIndent(*file, "", " ") 113 return json 114 } 115 116 // String converts the database to a string. 117 func (file *File) String() string { 118 json, _ := json.MarshalIndent(*file, "", " ") 119 return string(json) 120 } 121 122 /* ----- END HELPER FUNCTIONS ----- */