Skip to content

Commit 72d644f

Browse files
committed
first commit
0 parents  commit 72d644f

15 files changed

+715
-0
lines changed

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# rwfs - WIP
2+
3+
`rwfs` is a Go library for an in-memory file system with optional persistence to disk and compression.
4+
5+
## Features
6+
7+
In-memory file system
8+
Persistent storage to disk
9+
Optional gzip compression
10+
11+
**NOTE:** This library is still in the process of being developed and many features are still being added.
12+
13+
## Installation
14+
15+
```bash
16+
go get github.com/DanielcoderX/rwfs
17+
```

example/main.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package main
2+
3+
import (
4+
// "io"
5+
"io"
6+
"log"
7+
8+
"github.com/DanielcoderX/rwfs/pkg/rwfs"
9+
)
10+
11+
func main() {
12+
config := rwfs.FileSystemConfig{
13+
Filepath: "data.rwfs",
14+
Compression: false,
15+
CompressLevel: 9, // Compression level between 1 (best speed) and 9 (best compression)
16+
Encryption: false,
17+
EncryptionKey: "your-secret-key-here",
18+
}
19+
20+
fs, err := rwfs.NewLocalFileSystem(config)
21+
if err != nil {
22+
log.Fatalf("Failed to initialize filesystem: %v", err)
23+
}
24+
25+
// Example usage with predefined file modes
26+
file, err := fs.Create("example.txt", "owner1", rwfs.ReadWrite)
27+
if err != nil {
28+
log.Fatalf("Failed to create file: %v", err)
29+
}
30+
_, err = file.Write([]byte("Hello, RWFS with encryption and extended metadata!"))
31+
if err != nil {
32+
log.Fatalf("Failed to write to file: %v", err)
33+
}
34+
file.Close()
35+
36+
// Save the file system state
37+
if err := fs.SaveToFile(config.Filepath); err != nil {
38+
log.Fatalf("Failed to save file system: %v", err)
39+
}
40+
// Load the file system state
41+
loadedFS, err := rwfs.NewLocalFileSystem(config)
42+
if err != nil {
43+
log.Fatalf("Failed to load file system: %v", err)
44+
}
45+
46+
loadedFile, err := loadedFS.Open("example.txt")
47+
if err != nil {
48+
log.Fatalf("Failed to open file: %v", err)
49+
}
50+
data := make([]byte, 1024)
51+
n, err := loadedFile.Read(data)
52+
if err != nil && err != io.EOF {
53+
log.Fatalf("Failed to read from file: %v", err)
54+
}
55+
log.Printf("Read data: %s", data[:n])
56+
log.Println(loadedFile.Stat())
57+
loadedFile.Close()
58+
log.Println(loadedFile.Stat())
59+
}

go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module github.com/DanielcoderX/rwfs
2+
3+
go 1.22.3

pkg/rwfs/compression.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package rwfs
2+
3+
import (
4+
"bytes"
5+
"compress/gzip"
6+
"io"
7+
)
8+
9+
// CompressData compresses the given data using gzip with the specified compression level
10+
func CompressData(data []byte, level int) ([]byte, error) {
11+
var buf bytes.Buffer
12+
writer, err := gzip.NewWriterLevel(&buf, level)
13+
if err != nil {
14+
return nil, err
15+
}
16+
defer writer.Close()
17+
18+
_, err = writer.Write(data)
19+
if err != nil {
20+
return nil, err
21+
}
22+
23+
if err := writer.Close(); err != nil {
24+
return nil, err
25+
}
26+
27+
return buf.Bytes(), nil
28+
}
29+
30+
// DecompressData decompresses the given gzip-compressed data
31+
func DecompressData(data []byte) ([]byte, error) {
32+
reader, err := gzip.NewReader(bytes.NewReader(data))
33+
if err != nil {
34+
return nil, err
35+
}
36+
defer reader.Close()
37+
38+
return io.ReadAll(reader)
39+
}

pkg/rwfs/config.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package rwfs
2+
3+
// FileSystemConfig holds the configuration options for initializing a LocalFileSystem
4+
type FileSystemConfig struct {
5+
Filepath string
6+
Compression bool
7+
CompressLevel int
8+
Encryption bool
9+
EncryptionKey string
10+
}

pkg/rwfs/errors.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package rwfs
2+
3+
import "errors"
4+
5+
// Define custom error types here if needed
6+
var (
7+
ErrFileNotFound = errors.New("file not found")
8+
ErrFileAlreadyExist = errors.New("file already exists")
9+
ErrPermissionDenied = errors.New("permission denied")
10+
)

pkg/rwfs/file.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package rwfs
2+
3+
import (
4+
"os"
5+
)
6+
7+
// File interface to be implemented by MemFile for file operations.
8+
type File interface {
9+
Read(p []byte) (int, error)
10+
Write(p []byte) (int, error)
11+
Close() error
12+
Stat() (os.FileInfo, error)
13+
Seek(offset int64, whence int) (int64, error)
14+
}

pkg/rwfs/file_modes.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package rwfs
2+
3+
import "os"
4+
5+
// Predefined file modes for convenience
6+
const (
7+
ReadOnly = os.FileMode(0444)
8+
WriteOnly = os.FileMode(0222)
9+
ReadWrite = os.FileMode(0666)
10+
Exec = os.FileMode(0777)
11+
)

pkg/rwfs/filesystem.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package rwfs
2+
3+
import "os"
4+
5+
// FileSystem defines the interface for a read-write file system
6+
type FileSystem interface {
7+
Open(name string) (File, error)
8+
Create(name string) (File, error)
9+
Remove(name string) error
10+
Stat(name string) (os.FileInfo, error)
11+
ListFiles() ([]File, error)
12+
Rename(oldName, newName string) error
13+
}

pkg/rwfs/gob.go

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package rwfs
2+
3+
import (
4+
"bytes"
5+
"encoding/gob"
6+
)
7+
8+
// Custom Gob Encode method for MemFile
9+
func (f *MemFile) GobEncode() ([]byte, error) {
10+
f.mu.Lock()
11+
defer f.mu.Unlock()
12+
13+
var buf bytes.Buffer
14+
encoder := gob.NewEncoder(&buf)
15+
16+
// Encode the simple fields
17+
if err := encoder.Encode(f.Name); err != nil {
18+
return nil, err
19+
}
20+
if err := encoder.Encode(f.mode); err != nil {
21+
return nil, err
22+
}
23+
if err := encoder.Encode(f.modTime); err != nil {
24+
return nil, err
25+
}
26+
if err := encoder.Encode(f.accessTime); err != nil {
27+
return nil, err
28+
}
29+
if err := encoder.Encode(f.changeTime); err != nil {
30+
return nil, err
31+
}
32+
if err := encoder.Encode(f.owner); err != nil {
33+
return nil, err
34+
}
35+
if err := encoder.Encode(f.position); err != nil {
36+
return nil, err
37+
}
38+
if err := encoder.Encode(f.closed); err != nil {
39+
return nil, err
40+
}
41+
42+
// Encode the Data field as a byte slice
43+
if err := encoder.Encode(f.Data.Bytes()); err != nil {
44+
return nil, err
45+
}
46+
47+
return buf.Bytes(), nil
48+
}
49+
50+
// Custom Gob Decode method for MemFile
51+
func (f *MemFile) GobDecode(data []byte) error {
52+
f.mu.Lock()
53+
defer f.mu.Unlock()
54+
55+
buf := bytes.NewBuffer(data)
56+
decoder := gob.NewDecoder(buf)
57+
58+
// Decode the simple fields
59+
if err := decoder.Decode(&f.Name); err != nil {
60+
return err
61+
}
62+
if err := decoder.Decode(&f.mode); err != nil {
63+
return err
64+
}
65+
if err := decoder.Decode(&f.modTime); err != nil {
66+
return err
67+
}
68+
if err := decoder.Decode(&f.accessTime); err != nil {
69+
return err
70+
}
71+
if err := decoder.Decode(&f.changeTime); err != nil {
72+
return err
73+
}
74+
if err := decoder.Decode(&f.owner); err != nil {
75+
return err
76+
}
77+
if err := decoder.Decode(&f.position); err != nil {
78+
return err
79+
}
80+
if err := decoder.Decode(&f.closed); err != nil {
81+
return err
82+
}
83+
84+
// Decode the Data field as a byte slice
85+
var dataBytes []byte
86+
if err := decoder.Decode(&dataBytes); err != nil {
87+
return err
88+
}
89+
f.Data = bytes.NewBuffer(dataBytes)
90+
91+
return nil
92+
}

0 commit comments

Comments
 (0)