osfiler.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. // Copyright 2014 The lldb Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package lldb
  5. import (
  6. "io"
  7. "os"
  8. "github.com/cznic/mathutil"
  9. )
  10. var _ Filer = (*OSFiler)(nil)
  11. // OSFile is an os.File like minimal set of methods allowing to construct a
  12. // Filer.
  13. type OSFile interface {
  14. Name() string
  15. Stat() (fi os.FileInfo, err error)
  16. Sync() (err error)
  17. Truncate(size int64) (err error)
  18. io.Closer
  19. io.Reader
  20. io.ReaderAt
  21. io.Seeker
  22. io.Writer
  23. io.WriterAt
  24. }
  25. // OSFiler is like a SimpleFileFiler but based on an OSFile.
  26. type OSFiler struct {
  27. f OSFile
  28. nest int
  29. size int64 // not set if < 0
  30. }
  31. // NewOSFiler returns a Filer from an OSFile. This Filer is like the
  32. // SimpleFileFiler, it does not implement the transaction related methods.
  33. func NewOSFiler(f OSFile) (r *OSFiler) {
  34. return &OSFiler{
  35. f: f,
  36. size: -1,
  37. }
  38. }
  39. // BeginUpdate implements Filer.
  40. func (f *OSFiler) BeginUpdate() (err error) {
  41. f.nest++
  42. return nil
  43. }
  44. // Close implements Filer.
  45. func (f *OSFiler) Close() (err error) {
  46. if f.nest != 0 {
  47. return &ErrPERM{(f.Name() + ":Close")}
  48. }
  49. return f.f.Close()
  50. }
  51. // EndUpdate implements Filer.
  52. func (f *OSFiler) EndUpdate() (err error) {
  53. if f.nest == 0 {
  54. return &ErrPERM{(f.Name() + ":EndUpdate")}
  55. }
  56. f.nest--
  57. return
  58. }
  59. // Name implements Filer.
  60. func (f *OSFiler) Name() string {
  61. return f.f.Name()
  62. }
  63. // PunchHole implements Filer.
  64. func (f *OSFiler) PunchHole(off, size int64) (err error) {
  65. return
  66. }
  67. // ReadAt implements Filer.
  68. func (f *OSFiler) ReadAt(b []byte, off int64) (n int, err error) {
  69. return f.f.ReadAt(b, off)
  70. }
  71. // Rollback implements Filer.
  72. func (f *OSFiler) Rollback() (err error) { return }
  73. // Size implements Filer.
  74. func (f *OSFiler) Size() (n int64, err error) {
  75. if f.size < 0 { // boot
  76. fi, err := f.f.Stat()
  77. if err != nil {
  78. return 0, err
  79. }
  80. f.size = fi.Size()
  81. }
  82. return f.size, nil
  83. }
  84. // Sync implements Filer.
  85. func (f *OSFiler) Sync() (err error) {
  86. return f.f.Sync()
  87. }
  88. // Truncate implements Filer.
  89. func (f *OSFiler) Truncate(size int64) (err error) {
  90. if size < 0 {
  91. return &ErrINVAL{"Truncate size", size}
  92. }
  93. f.size = size
  94. return f.f.Truncate(size)
  95. }
  96. // WriteAt implements Filer.
  97. func (f *OSFiler) WriteAt(b []byte, off int64) (n int, err error) {
  98. if f.size < 0 { // boot
  99. fi, err := os.Stat(f.f.Name())
  100. if err != nil {
  101. return 0, err
  102. }
  103. f.size = fi.Size()
  104. }
  105. f.size = mathutil.MaxInt64(f.size, int64(len(b))+off)
  106. return f.f.WriteAt(b, off)
  107. }