DecoderError.h 3.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  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/ByteString.h>
  8. #include <AK/Error.h>
  9. #include <AK/Format.h>
  10. #include <AK/SourceLocation.h>
  11. #include <LibVideo/Forward.h>
  12. #include <errno.h>
  13. namespace Video {
  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. class 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<AK::AllowDebugOnlyFormatters::No, Parameters...> variadic_format_params { parameters... };
  39. return DecoderError::with_description(category, ByteString::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, ByteString description)
  58. : m_category(category)
  59. , m_description(move(description))
  60. {
  61. }
  62. DecoderErrorCategory m_category { DecoderErrorCategory::Unknown };
  63. ByteString 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. static_assert(!::AK::Detail::IsLvalueReference<decltype(_result.release_value())>, \
  74. "Do not return a reference from a fallible expression"); \
  75. _result.release_value(); \
  76. })
  77. #define DECODER_TRY_ALLOC(expression) DECODER_TRY(DecoderErrorCategory::Memory, expression)
  78. }