diff --git a/storage/unity_file.go b/storage/unity_file.go index acb3146..ab7cb2e 100644 --- a/storage/unity_file.go +++ b/storage/unity_file.go @@ -39,6 +39,23 @@ func CreateUnityFile(fileName string) (UnityFile, error) { return u, nil } +func OpenUnityFile(fileName, metadataName string) (UnityFile, error) { + var u UnityFile + + // Read the file + f, err := os.Open(fileName) + if err != nil { + return u, err + } + u.fd = f + + if err := u.ReadMetadataFile(metadataName); err != nil { + return u, err + } + + return u, nil +} + func (u UnityFile) Size() int { return u.fileSize } @@ -54,7 +71,7 @@ func (u *UnityFile) WriteChunk(data world.ChunkData) error { encodedSize := encoded.Len() // Go to the end of the file - u.fd.Seek(0, u.fileSize) + u.fd.Seek(int64(u.fileSize), io.SeekStart) // Write the encoded contents to the file if _, err := u.fd.Write(encoded.Bytes()); err != nil { return err @@ -100,7 +117,7 @@ func (u *UnityFile) ReadMetadataFile(fileName string) error { func (u UnityFile) ReadChunk(pos world.ChunkPos) (world.ChunkData, error) { m := u.metadata[pos] - u.fd.Seek(0, m.StartOffset) + u.fd.Seek(int64(m.StartOffset), io.SeekStart) fileReader := io.LimitReader(u.fd, int64(m.FileSize)) @@ -112,6 +129,20 @@ func (u UnityFile) ReadChunk(pos world.ChunkPos) (world.ChunkData, error) { return data, nil } +func (u UnityFile) ReadAllChunks() ([]world.ChunkData, error) { + chunks := []world.ChunkData{} + + for pos := range u.metadata { + chunk, err := u.ReadChunk(pos) + if err != nil { + return nil, err + } + chunks = append(chunks, chunk) + } + + return chunks, nil +} + func (u *UnityFile) Close() error { return u.fd.Close() } diff --git a/storage/unity_file_test.go b/storage/unity_file_test.go index 709e1ba..ae11cf9 100644 --- a/storage/unity_file_test.go +++ b/storage/unity_file_test.go @@ -1,6 +1,7 @@ package storage import ( + "fmt" "os" "path" "reflect" @@ -69,6 +70,7 @@ func TestWriteMultipleFiles(t *testing.T) { if err != nil { t.Fatalf("Error creating temporary directory: %v", err) } + fmt.Println(tempDir) defer os.RemoveAll(tempDir) u, err := CreateUnityFile(path.Join(tempDir, "test-unity")) @@ -119,3 +121,60 @@ func TestWriteMultipleFiles(t *testing.T) { } } } + +func TestReadAllChunks(t *testing.T) { + tempDir, err := os.MkdirTemp("", "unity") + if err != nil { + t.Fatalf("Error creating temporary directory: %v", err) + } + fmt.Println(tempDir) + defer os.RemoveAll(tempDir) + + u, err := CreateUnityFile(path.Join(tempDir, "test-unity")) + if err != nil { + t.Fatalf("Error creating unity file: %v", err) + } + + var ( + chunk1 world.ChunkData + chunk2 world.ChunkData + chunk3 world.ChunkData + ) + chunk1.Pos = world.ChunkPos{ + X: 0, + Z: 0, + } + chunk1.Sections[0].BlockStates[0] = 2 + chunk2.Sections[0].BlockStates[0] = 3 + chunk2.Pos = world.ChunkPos{ + X: 1, + Z: 0, + } + chunk3.Sections[0].BlockStates[0] = 4 + chunk3.Pos = world.ChunkPos{ + X: 2, + Z: 0, + } + + chunks := []world.ChunkData{chunk1, chunk2, chunk3} + + // Write all chunks + for _, data := range chunks { + if err := u.WriteChunk(data); err != nil { + t.Fatalf("Error writing chunk: %v", err) + } + } + + t.Log(chunks) + + readChunks, err := u.ReadAllChunks() + if err != nil { + t.Fatalf("Error reading chunks: %v", err) + } + + for index, chunk := range readChunks { + if !reflect.DeepEqual(chunk, chunks[index]) { + t.Fatalf("Chunks were not equal") + } + } +}