memfiler.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  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. // A memory-only implementation of Filer.
  5. package lldb
  6. import (
  7. "fmt"
  8. "io"
  9. "github.com/cznic/internal/file"
  10. )
  11. const (
  12. pgBits = 16
  13. pgSize = 1 << pgBits
  14. pgMask = pgSize - 1
  15. )
  16. var _ Filer = &MemFiler{}
  17. // MemFiler is a memory backed Filer. It implements BeginUpdate, EndUpdate and
  18. // Rollback as no-ops. MemFiler is not automatically persistent, but it has
  19. // ReadFrom and WriteTo methods.
  20. type MemFiler struct {
  21. fi file.Interface
  22. nest int
  23. }
  24. // NewMemFiler returns a new MemFiler.
  25. func NewMemFiler() *MemFiler {
  26. fi, err := file.OpenMem("")
  27. if err != nil {
  28. return nil
  29. }
  30. return &MemFiler{fi: fi}
  31. }
  32. // BeginUpdate implements Filer.
  33. func (f *MemFiler) BeginUpdate() error {
  34. f.nest++
  35. return nil
  36. }
  37. // Close implements Filer.
  38. func (f *MemFiler) Close() (err error) {
  39. if f.nest != 0 {
  40. return &ErrPERM{(f.Name() + ":Close")}
  41. }
  42. return f.fi.Close()
  43. }
  44. // EndUpdate implements Filer.
  45. func (f *MemFiler) EndUpdate() (err error) {
  46. if f.nest == 0 {
  47. return &ErrPERM{(f.Name() + ": EndUpdate")}
  48. }
  49. f.nest--
  50. return
  51. }
  52. // Name implements Filer.
  53. func (f *MemFiler) Name() string { return fmt.Sprintf("%p.memfiler", f) }
  54. // PunchHole implements Filer.
  55. func (f *MemFiler) PunchHole(off, size int64) (err error) { return nil }
  56. // ReadAt implements Filer.
  57. func (f *MemFiler) ReadAt(b []byte, off int64) (n int, err error) { return f.fi.ReadAt(b, off) }
  58. // ReadFrom is a helper to populate MemFiler's content from r. 'n' reports the
  59. // number of bytes read from 'r'.
  60. func (f *MemFiler) ReadFrom(r io.Reader) (n int64, err error) { return f.fi.ReadFrom(r) }
  61. // Rollback implements Filer.
  62. func (f *MemFiler) Rollback() (err error) { return nil }
  63. // Size implements Filer.
  64. func (f *MemFiler) Size() (int64, error) {
  65. info, err := f.fi.Stat()
  66. if err != nil {
  67. return 0, err
  68. }
  69. return info.Size(), nil
  70. }
  71. // Sync implements Filer.
  72. func (f *MemFiler) Sync() error { return nil }
  73. // Truncate implements Filer.
  74. func (f *MemFiler) Truncate(size int64) (err error) { return f.fi.Truncate(size) }
  75. // WriteAt implements Filer.
  76. func (f *MemFiler) WriteAt(b []byte, off int64) (n int, err error) { return f.fi.WriteAt(b, off) }
  77. // WriteTo is a helper to copy/persist MemFiler's content to w. If w is also
  78. // an io.WriterAt then WriteTo may attempt to _not_ write any big, for some
  79. // value of big, runs of zeros, i.e. it will attempt to punch holes, where
  80. // possible, in `w` if that happens to be a freshly created or to zero length
  81. // truncated OS file. 'n' reports the number of bytes written to 'w'.
  82. func (f *MemFiler) WriteTo(w io.Writer) (n int64, err error) { return f.fi.WriteTo(w) }