Package storage offers generic (cloud) storage drivers. https://godoc.org/maze.io/x/storage
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

memory.go 3.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. package storage
  2. import (
  3. "bytes"
  4. "context"
  5. "errors"
  6. "io"
  7. "io/ioutil"
  8. "os"
  9. "path"
  10. "path/filepath"
  11. "time"
  12. )
  13. type memoryStorage struct {
  14. tree map[string]*memoryStored
  15. }
  16. type memoryStored struct {
  17. name string
  18. modTime time.Time
  19. data []byte
  20. }
  21. func (file memoryStored) IsDir() bool { return false }
  22. func (file memoryStored) Name() string { return file.name }
  23. func (file memoryStored) Mode() os.FileMode { return 0644 }
  24. func (file memoryStored) ModTime() time.Time { return file.modTime }
  25. func (file memoryStored) Size() int64 { return int64(len(file.data)) }
  26. func (file memoryStored) Sys() interface{} { return nil }
  27. // OpenMemory is an in-memory storage (for testing).
  28. func OpenMemory() Storage {
  29. return &memoryStorage{
  30. tree: make(map[string]*memoryStored),
  31. }
  32. }
  33. func (memoryStorage) Name() string { return "memory" }
  34. func (memoryStorage) Close() error { return nil }
  35. // Save a file to the storage.
  36. func (store *memoryStorage) Save(_ context.Context, name string, r io.Reader) error {
  37. now := time.Now().UTC()
  38. data, err := ioutil.ReadAll(r)
  39. if err != nil {
  40. return err
  41. }
  42. name = path.Clean("/" + name)
  43. store.tree[name] = &memoryStored{
  44. name: name,
  45. modTime: now,
  46. data: data,
  47. }
  48. return nil
  49. }
  50. // Open a file from storage for reading.
  51. func (store *memoryStorage) Open(ctx context.Context, name string) (io.ReadCloser, error) {
  52. name = path.Clean("/" + name)
  53. file, ok := store.tree[name]
  54. if !ok {
  55. return nil, NotExistError("Open", name)
  56. }
  57. return &readerCloser{bytes.NewBuffer(file.data)}, nil
  58. }
  59. func (store *memoryStorage) Create(ctx context.Context, name string) (io.WriteCloser, error) {
  60. return &bufferedWriter{
  61. onClose: func(b []byte) error {
  62. return store.Save(ctx, name, bytes.NewBuffer(b))
  63. },
  64. }, nil
  65. }
  66. // Readdir lists all files in a folder.
  67. func (store *memoryStorage) Readdir(ctx context.Context, name string) (infos []os.FileInfo, err error) {
  68. name = path.Clean("/" + name)
  69. var info os.FileInfo
  70. if info, err = store.Stat(ctx, name); err != nil {
  71. return
  72. } else if !info.IsDir() {
  73. return nil, &os.PathError{
  74. Path: name,
  75. Err: errors.New("not a directory"),
  76. }
  77. }
  78. for other, info := range store.tree {
  79. if path.Dir(other) == name {
  80. infos = append(infos, info)
  81. }
  82. }
  83. return
  84. }
  85. // Glob lists stored files.
  86. func (store *memoryStorage) Glob(ctx context.Context, pattern string) (names []string, err error) {
  87. pattern = path.Clean("/" + pattern)
  88. var matched bool
  89. for name := range store.tree {
  90. if matched, err = filepath.Match(pattern, name); err != nil {
  91. return
  92. } else if matched {
  93. names = append(names, name)
  94. }
  95. }
  96. return
  97. }
  98. // Stat a file in storage.
  99. func (store *memoryStorage) Stat(ctx context.Context, name string) (os.FileInfo, error) {
  100. name = path.Clean("/" + name)
  101. info, ok := store.tree[name]
  102. if ok {
  103. return info, nil
  104. }
  105. for other, info := range store.tree {
  106. if path.Dir(other) == name {
  107. return info, nil
  108. }
  109. }
  110. return nil, NotExistError("Stat", name)
  111. }
  112. // Remove a file from storage.
  113. func (store *memoryStorage) Remove(ctx context.Context, name string) error {
  114. if _, ok := store.tree[name]; !ok {
  115. return NotExistError("Remove", name)
  116. }
  117. delete(store.tree, name)
  118. return nil
  119. }
  120. type bufferedWriter struct {
  121. b []byte
  122. onClose func([]byte) error
  123. }
  124. func (b *bufferedWriter) Close() error {
  125. return b.onClose(b.b)
  126. }
  127. func (b *bufferedWriter) Write(p []byte) (n int, err error) {
  128. b.b = append(b.b, p...)
  129. return len(p), nil
  130. }