state.go 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. package lz4
  2. import (
  3. "errors"
  4. "fmt"
  5. "io"
  6. )
  7. //go:generate go run golang.org/x/tools/cmd/stringer -type=aState -output state_gen.go
  8. const (
  9. noState aState = iota // uninitialized reader
  10. errorState // unrecoverable error encountered
  11. newState // instantiated object
  12. readState // reading data
  13. writeState // writing data
  14. closedState // all done
  15. )
  16. type (
  17. aState uint8
  18. _State struct {
  19. states []aState
  20. state aState
  21. err error
  22. }
  23. )
  24. func (s *_State) init(states []aState) {
  25. s.states = states
  26. s.state = states[0]
  27. }
  28. // next sets the state to the next one unless it is passed a non nil error.
  29. // It returns whether or not it is in error.
  30. func (s *_State) next(err error) bool {
  31. if err != nil {
  32. s.err = fmt.Errorf("%s: %w", s.state, err)
  33. s.state = errorState
  34. return true
  35. }
  36. s.state = s.states[s.state]
  37. return false
  38. }
  39. // check sets s in error if not already in error and if the error is not nil or io.EOF,
  40. func (s *_State) check(errp *error) {
  41. if s.state == errorState || errp == nil {
  42. return
  43. }
  44. if err := *errp; err != nil {
  45. s.err = fmt.Errorf("%w[%s]", err, s.state)
  46. if !errors.Is(err, io.EOF) {
  47. s.state = errorState
  48. }
  49. }
  50. }
  51. func (s *_State) fail() error {
  52. s.state = errorState
  53. s.err = fmt.Errorf("%w[%s]", ErrInternalUnhandledState, s.state)
  54. return s.err
  55. }