DecoderError.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /*
  2. * Copyright (c) 2022, Gregory Bertilson <zaggy1024@gmail.com>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Error.h>
  8. #include <AK/Format.h>
  9. #include <AK/SourceLocation.h>
  10. #include <AK/String.h>
  11. #include <errno.h>
  12. namespace Video {
  13. struct DecoderError;
  14. template<typename T>
  15. using DecoderErrorOr = ErrorOr<T, DecoderError>;
  16. enum class DecoderErrorCategory : u32 {
  17. Unknown,
  18. IO,
  19. NeedsMoreInput,
  20. EndOfStream,
  21. Memory,
  22. // The input is corrupted.
  23. Corrupted,
  24. // Invalid call.
  25. Invalid,
  26. // The input uses features that are not yet implemented.
  27. NotImplemented,
  28. };
  29. struct DecoderError {
  30. public:
  31. static DecoderError with_description(DecoderErrorCategory category, StringView description)
  32. {
  33. return DecoderError(category, description);
  34. }
  35. template<typename... Parameters>
  36. static DecoderError format(DecoderErrorCategory category, CheckedFormatString<Parameters...>&& format_string, Parameters const&... parameters)
  37. {
  38. AK::VariadicFormatParams variadic_format_params { parameters... };
  39. return DecoderError::with_description(category, String::vformatted(format_string.view(), variadic_format_params));
  40. }
  41. static DecoderError from_source_location(DecoderErrorCategory category, StringView description, SourceLocation location = SourceLocation::current())
  42. {
  43. return DecoderError::format(category, "[{} @ {}:{}]: {}", location.function_name(), location.filename(), location.line_number(), description);
  44. }
  45. static DecoderError corrupted(StringView description, SourceLocation location = SourceLocation::current())
  46. {
  47. return DecoderError::from_source_location(DecoderErrorCategory::Corrupted, description, location);
  48. }
  49. static DecoderError not_implemented(SourceLocation location = SourceLocation::current())
  50. {
  51. return DecoderError::format(DecoderErrorCategory::NotImplemented, "{} is not implemented", location.function_name());
  52. }
  53. DecoderErrorCategory category() const { return m_category; }
  54. StringView description() const { return m_description; }
  55. StringView string_literal() const { return m_description; }
  56. private:
  57. DecoderError(DecoderErrorCategory category, String description)
  58. : m_category(category)
  59. , m_description(move(description))
  60. {
  61. }
  62. DecoderErrorCategory m_category { DecoderErrorCategory::Unknown };
  63. String m_description;
  64. };
  65. #define DECODER_TRY(category, expression) \
  66. ({ \
  67. auto _result = ((expression)); \
  68. if (_result.is_error()) [[unlikely]] { \
  69. auto _error_string = _result.release_error().string_literal(); \
  70. return DecoderError::from_source_location( \
  71. ((category)), _error_string, SourceLocation::current()); \
  72. } \
  73. _result.release_value(); \
  74. })
  75. #define DECODER_TRY_ALLOC(expression) DECODER_TRY(DecoderErrorCategory::Memory, expression)
  76. }