file_container.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. package basefs
  2. import (
  3. "fmt"
  4. "log"
  5. "os"
  6. "strings"
  7. "sync"
  8. "github.com/jacobsa/fuse/fuseops"
  9. )
  10. type FileContainer struct {
  11. fileEntries map[fuseops.InodeID]*FileEntry
  12. //fs *GDriveFS
  13. //client *drive.Service // Wrong should be common
  14. uid uint32
  15. gid uint32
  16. inodeMU *sync.Mutex
  17. }
  18. // Pass config core somehow?
  19. func NewFileContainer(config *Config) *FileContainer {
  20. fc := &FileContainer{
  21. fileEntries: map[fuseops.InodeID]*FileEntry{},
  22. //fs: fs,
  23. //client: client,
  24. inodeMU: &sync.Mutex{},
  25. uid: config.UID,
  26. gid: config.GID,
  27. }
  28. rootEntry := fc.FileEntry("", nil, fuseops.RootInodeID)
  29. rootEntry.Attr.Mode = os.FileMode(0755) | os.ModeDir
  30. return fc
  31. }
  32. func (fc *FileContainer) FileEntry(Name string, gfile interface{}, inodeOps ...fuseops.InodeID) *FileEntry {
  33. fc.inodeMU.Lock()
  34. defer fc.inodeMU.Unlock()
  35. var inode fuseops.InodeID
  36. if len(inodeOps) > 0 {
  37. inode = inodeOps[0]
  38. if fe, ok := fc.fileEntries[inode]; ok {
  39. return fe
  40. }
  41. } else { // generate new inode
  42. // Max Inode Number
  43. for inode = 2; inode < 99999; inode++ {
  44. _, ok := fc.fileEntries[inode]
  45. if !ok {
  46. break
  47. }
  48. }
  49. }
  50. name := ""
  51. if gfile != nil {
  52. name = Name //Add Name in param?
  53. count := 1
  54. nameParts := strings.Split(name, ".")
  55. for {
  56. // We find if we have a GFile in same parent with same name
  57. var entry *FileEntry
  58. // Check parent somehow maybe with inode
  59. //for _, p := range gfile.Parents {
  60. // entry = fc.LookupByGID(p, name)
  61. // if entry != nil {
  62. // break
  63. // }
  64. //}
  65. if entry == nil { // Not found return
  66. break
  67. }
  68. count++
  69. if len(nameParts) > 1 {
  70. name = fmt.Sprintf("%s(%d).%s", nameParts[0], count, strings.Join(nameParts[1:], "."))
  71. } else {
  72. name = fmt.Sprintf("%s(%d)", nameParts[0], count)
  73. }
  74. log.Printf("Conflicting name generated new '%s' as '%s'", Name, name)
  75. }
  76. }
  77. fe := &FileEntry{
  78. //GFile: gfile,
  79. Inode: inode,
  80. container: fc,
  81. Name: name,
  82. //children: []*FileEntry{},
  83. Attr: fuseops.InodeAttributes{
  84. Uid: fc.uid,
  85. Gid: fc.gid,
  86. },
  87. }
  88. // fe.SetGFile(gfile) // Somehow get necessary information from here
  89. fc.fileEntries[inode] = fe
  90. return fe
  91. }
  92. func (fc *FileContainer) FindByInode(inode fuseops.InodeID) *FileEntry {
  93. return nil // Not implemented
  94. }
  95. func (fc *FileContainer) ListByParent(parent *FileEntry) []*FileEntry {
  96. return nil
  97. }
  98. func (fc *FileContainer) LookupByParent(parent *FileEntry, name string) *FileEntry {
  99. return nil
  100. }