AVPKit
Error.cpp
1 /*******************************************************************************
2  * Copyright (c) 2024, 2026, Olivier Ayache. All rights reserved.
3  *
4  * This file is part of AVPKit.
5  *
6  * AVPKit is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * AVPKit is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with AVPKit. If not, see <http://www.gnu.org/licenses/>.
18  *******************************************************************************/
19 
20 /*
21  * Error.cpp
22  *
23  * Created on: Mar 20, 2009
24  * Author: aclarke
25  */
26 
27 #include <com/avpkit/ferry/Logger.h>
28 #include <com/avpkit/core/Error.h>
29 #include <com/avpkit/core/FfmpegIncludes.h>
30 
31 #include <cstring>
32 #include <stdexcept>
33 
34 VS_LOG_SETUP(VS_CPP_PACKAGE);
35 
36 namespace com { namespace avpkit { namespace core
37 {
38 
39 struct ErrorMappingTable {
40  int32_t mFfmpegError;
41  IError::Type mAVPKitError;
42 } ;
43 
44 static struct ErrorMappingTable sErrorMappingTable[] = {
45  { AVERROR(EIO), IError::ERROR_IO },
46  { AVERROR(EDOM), IError::ERROR_NUMEXPECTED },
47  { AVERROR(EINVAL), IError::ERROR_INVALIDDATA },
48  { AVERROR(ENOMEM), IError::ERROR_NOMEM },
49  { AVERROR(EILSEQ), IError::ERROR_NOFMT },
50  { AVERROR(ENOSYS), IError::ERROR_NOTSUPPORTED },
51  { AVERROR(ENOENT), IError::ERROR_NOENT },
52  { AVERROR(EPIPE), IError::ERROR_EOF },
53  { AVERROR_PATCHWELCOME, IError::ERROR_PATCHWELCOME },
54  { AVERROR(EAGAIN), IError::ERROR_AGAIN },
55  { AVERROR(ERANGE), IError::ERROR_RANGE },
56  { AVERROR(EINTR), IError::ERROR_INTERRUPTED },
57  { AVERROR_EOF, IError::ERROR_EOF },
58  { AVERROR_DECODER_NOT_FOUND, IError::ERROR_NOFMT },
59  { AVERROR_DEMUXER_NOT_FOUND, IError::ERROR_NOFMT },
60  { AVERROR_ENCODER_NOT_FOUND, IError::ERROR_NOFMT },
61  { AVERROR_MUXER_NOT_FOUND, IError::ERROR_NOFMT },
62  { AVERROR_OPTION_NOT_FOUND, IError::ERROR_NOFMT },
63 };
64 static int32_t sErrorMappingTableSize = sizeof(sErrorMappingTable)/sizeof(struct ErrorMappingTable);
65 
66 Error :: Error()
67 {
68  mType = IError::ERROR_UNKNOWN;
69  mErrorNo = 0;
70  *mErrorStr = 0;
71  mErrorStr[sizeof(mErrorStr)-1]=0;
72 }
73 
74 Error :: ~Error()
75 {
76 
77 }
78 
79 const char*
81 {
82  const char* retval = 0;
83  if (!*mErrorStr && mErrorNo != 0)
84  {
85 #ifdef HAVE_STRERROR_R
86 #ifdef STRERROR_R_CHAR_P
87  retval = strerror_r(AVUNERROR(mErrorNo), mErrorStr, sizeof(mErrorStr));
88 #else
89  strerror_r(AVUNERROR(mErrorNo), mErrorStr, sizeof(mErrorStr));
90  retval = mErrorStr;
91 #endif
92 #else
93  retval = strerror(AVUNERROR(mErrorNo));
94 #endif // HAVE_STRERROR_R
95  if (retval != (const char*) mErrorStr)
96  strncpy(mErrorStr, retval, sizeof(mErrorStr)-1);
97  }
98  return *mErrorStr ? mErrorStr : 0;
99 }
100 
101 int32_t
103 {
104  return mErrorNo;
105 }
108 {
109  return mType;
110 }
111 
112 Error*
113 Error :: make(int32_t aErrorNo)
114 {
115  if (aErrorNo >= 0)
116  return 0;
117 
118  return make(aErrorNo, errorNumberToType(aErrorNo));
119 }
120 
121 Error*
122 Error :: make(Type aType)
123 {
124  return make(typeToErrorNumber(aType), aType);
125 }
126 
127 Error*
128 Error :: make(int32_t aErrorNo, Type aType)
129 {
130  Error* retval = 0;
131  try
132  {
133  retval = make();
134  if (!retval)
135  throw std::bad_alloc();
136  retval->mErrorNo = aErrorNo;
137  retval->mType = aType;
138  // null out and don't fill unless description is asked for
139  *(retval->mErrorStr) = 0;
140  }
141  catch (std::bad_alloc & e)
142  {
143  VS_REF_RELEASE(retval);
144  throw e;
145  }
146  catch (std::exception & e)
147  {
148  VS_LOG_TRACE("Error: %s", e.what());
149  VS_REF_RELEASE(retval);
150  }
151  return retval;
152 
153 }
154 
156 Error :: errorNumberToType(int32_t errNo)
157 {
158  IError::Type retval = IError::ERROR_UNKNOWN;
159  int i = 0;
160  for(; i < sErrorMappingTableSize; i++)
161  {
162  if (sErrorMappingTable[i].mFfmpegError == errNo)
163  {
164  retval = sErrorMappingTable[i].mAVPKitError;
165  break;
166  }
167  }
168  if (i >= sErrorMappingTableSize) {
169  retval = IError::ERROR_UNKNOWN;
170  }
171  return retval;
172 }
173 
174 int32_t
175 Error :: typeToErrorNumber(Type type)
176 {
177  int32_t retval = AVERROR(EINVAL);
178  int i = 0;
179  for(; i < sErrorMappingTableSize; i++)
180  {
181  if (sErrorMappingTable[i].mAVPKitError == type)
182  {
183  retval = sErrorMappingTable[i].mFfmpegError;
184  break;
185  }
186  }
187  if (i >= sErrorMappingTableSize) {
188  retval = AVERROR(EINVAL);
189  }
190  return retval;
191 }
192 
193 }}}
virtual int32_t getErrorNumber()
Return the raw integer value that AVPKit returned and was used to create this IError.
Definition: Error.cpp:102
virtual Type getType()
Get the OS-independent AVPKit type for this error.
Definition: Error.cpp:107
virtual const char * getDescription()
Get a text description for this error.
Definition: Error.cpp:80
Type
A set of errors that AVPKit knows about.
Definition: IError.h:65
WARNING: Do not use logging in this class, and do not set any static file variables to values other t...