Minor improvement
[xy_vsfilter.git] / src / thirdparty / VirtualDub / system / source / Error.cpp
blobdce1af287e27a4904a674b5627dc029fc1cd18ce
1 // VirtualDub - Video processing and capture application
2 // System library component
3 // Copyright (C) 1998-2004 Avery Lee, All Rights Reserved.
4 //
5 // Beginning with 1.6.0, the VirtualDub system library is licensed
6 // differently than the remainder of VirtualDub. This particular file is
7 // thus licensed as follows (the "zlib" license):
8 //
9 // This software is provided 'as-is', without any express or implied
10 // warranty. In no event will the authors be held liable for any
11 // damages arising from the use of this software.
13 // Permission is granted to anyone to use this software for any purpose,
14 // including commercial applications, and to alter it and redistribute it
15 // freely, subject to the following restrictions:
17 // 1. The origin of this software must not be misrepresented; you must
18 // not claim that you wrote the original software. If you use this
19 // software in a product, an acknowledgment in the product
20 // documentation would be appreciated but is not required.
21 // 2. Altered source versions must be plainly marked as such, and must
22 // not be misrepresented as being the original software.
23 // 3. This notice may not be removed or altered from any source
24 // distribution.
26 #include "stdafx.h"
27 #include <stdio.h>
28 #include <stdarg.h>
29 #include <crtdbg.h>
30 #include <windows.h>
31 #include <vfw.h>
33 #include <vd2/system/vdtypes.h>
34 #include <vd2/system/Error.h>
35 #include <vd2/system/log.h>
37 MyError::MyError() {
38 buf = NULL;
41 MyError::MyError(const MyError& err) {
42 buf = _strdup(err.buf);
45 MyError::MyError(const char *f, ...)
46 : buf(NULL)
48 va_list val;
50 va_start(val, f);
51 vsetf(f, val);
52 va_end(val);
55 MyError::~MyError() {
56 free(buf);
59 void MyError::clear() {
60 if (buf) // we do this check because debug free() always does a heapchk even if buf==NULL
61 free(buf);
62 buf = NULL;
65 void MyError::assign(const MyError& e) {
66 if (buf)
67 free(buf);
68 buf = _strdup(e.buf);
71 void MyError::assign(const char *s) {
72 if (buf)
73 free(buf);
74 buf = _strdup(s);
77 void MyError::setf(const char *f, ...) {
78 va_list val;
80 va_start(val, f);
81 vsetf(f,val);
82 va_end(val);
85 void MyError::vsetf(const char *f, va_list val) {
86 for(int size = 1024; size <= 32768; size += size) {
87 free(buf);
88 buf = NULL;
90 buf = (char *)malloc(size);
91 if (!buf)
92 return;
94 if ((unsigned)_vsnprintf(buf, size, f, val) < (unsigned)size)
95 return;
98 free(buf);
99 buf = NULL;
102 void MyError::post(HWND hWndParent, const char *title) const {
103 if (!buf || !*buf)
104 return;
106 VDDEBUG("*** %s: %s\n", title, buf);
107 VDLog(kVDLogError, VDswprintf(L"Error: %hs", 1, &buf));
109 MessageBox(hWndParent, buf, title, MB_OK | MB_ICONERROR | MB_SETFOREGROUND);
112 void MyError::discard() {
113 free(buf);
114 buf = NULL;
117 void MyError::swap(MyError& err) {
118 char *s = err.buf;
119 err.buf = buf;
120 buf = s;
123 void MyError::TransferFrom(MyError& err) {
124 if (buf)
125 free(buf);
127 buf = err.buf;
128 err.buf = NULL;
131 /////////////////////////////////////////////////////////////////////////////
133 static const char *GetVCMErrorString(uint32 icErr) {
134 const char *err = "(unknown)";
136 // Does anyone have the *real* text strings for this?
138 switch(icErr) {
139 case ICERR_OK: err = "The operation completed successfully."; break; // sorry, couldn't resist....
140 case ICERR_UNSUPPORTED: err = "The operation is not supported."; break;
141 case ICERR_BADFORMAT: err = "The source image format is not acceptable."; break;
142 case ICERR_MEMORY: err = "Not enough memory."; break;
143 case ICERR_INTERNAL: err = "An internal error occurred."; break;
144 case ICERR_BADFLAGS: err = "An invalid flag was specified."; break;
145 case ICERR_BADPARAM: err = "An invalid parameter was specified."; break;
146 case ICERR_BADSIZE: err = "An invalid size was specified."; break;
147 case ICERR_BADHANDLE: err = "The handle is invalid."; break;
148 case ICERR_CANTUPDATE: err = "Cannot update the destination image."; break;
149 case ICERR_ABORT: err = "The operation was aborted by the user."; break;
150 case ICERR_ERROR: err = "An unknown error occurred (may be corrupt data)."; break;
151 case ICERR_BADBITDEPTH: err = "The source color depth is not acceptable."; break;
152 case ICERR_BADIMAGESIZE: err = "The source image size is not acceptable."; break;
153 default:
154 if (icErr <= ICERR_CUSTOM) err = "A codec-specific error occurred.";
155 break;
158 return err;
161 MyICError::MyICError(const char *s, uint32 icErr) {
162 setf("%s error: %s (error code %ld)", s, GetVCMErrorString(icErr), icErr);
165 MyICError::MyICError(uint32 icErr, const char *format, ...) {
166 char tmpbuf[1024];
168 va_list val;
169 va_start(val, format);
170 tmpbuf[(sizeof tmpbuf) - 1] = 0;
171 _vsnprintf(tmpbuf, (sizeof tmpbuf) - 1, format, val);
172 va_end(val);
174 setf(tmpbuf, GetVCMErrorString(icErr));
177 MyMMIOError::MyMMIOError(const char *s, uint32 mmioerr) {
178 const char *err = "(Unknown)";
180 switch(mmioerr) {
181 case MMIOERR_FILENOTFOUND: err = "file not found"; break;
182 case MMIOERR_OUTOFMEMORY: err = "out of memory"; break;
183 case MMIOERR_CANNOTOPEN: err = "couldn't open"; break;
184 case MMIOERR_CANNOTCLOSE: err = "couldn't close"; break;
185 case MMIOERR_CANNOTREAD: err = "couldn't read"; break;
186 case MMIOERR_CANNOTWRITE: err = "couldn't write"; break;
187 case MMIOERR_CANNOTSEEK: err = "couldn't seek"; break;
188 case MMIOERR_CANNOTEXPAND: err = "couldn't expand"; break;
189 case MMIOERR_CHUNKNOTFOUND: err = "chunk not found"; break;
190 case MMIOERR_UNBUFFERED: err = "unbuffered"; break;
191 case MMIOERR_PATHNOTFOUND: err = "path not found"; break;
192 case MMIOERR_ACCESSDENIED: err = "access denied"; break;
193 case MMIOERR_SHARINGVIOLATION: err = "sharing violation"; break;
194 case MMIOERR_NETWORKERROR: err = "network error"; break;
195 case MMIOERR_TOOMANYOPENFILES: err = "too many open files"; break;
196 case MMIOERR_INVALIDFILE: err = "invalid file"; break;
199 setf("%s error: %s (%ld)", s, err, mmioerr);
202 MyAVIError::MyAVIError(const char *s, uint32 avierr) {
203 const char *err = "(Unknown)";
205 switch(avierr) {
206 case AVIERR_UNSUPPORTED: err = "unsupported"; break;
207 case AVIERR_BADFORMAT: err = "bad format"; break;
208 case AVIERR_MEMORY: err = "out of memory"; break;
209 case AVIERR_INTERNAL: err = "internal error"; break;
210 case AVIERR_BADFLAGS: err = "bad flags"; break;
211 case AVIERR_BADPARAM: err = "bad parameters"; break;
212 case AVIERR_BADSIZE: err = "bad size"; break;
213 case AVIERR_BADHANDLE: err = "bad AVIFile handle"; break;
214 case AVIERR_FILEREAD: err = "file read error"; break;
215 case AVIERR_FILEWRITE: err = "file write error"; break;
216 case AVIERR_FILEOPEN: err = "file open error"; break;
217 case AVIERR_COMPRESSOR: err = "compressor error"; break;
218 case AVIERR_NOCOMPRESSOR: err = "compressor not available"; break;
219 case AVIERR_READONLY: err = "file marked read-only"; break;
220 case AVIERR_NODATA: err = "no data (?)"; break;
221 case AVIERR_BUFFERTOOSMALL: err = "buffer too small"; break;
222 case AVIERR_CANTCOMPRESS: err = "can't compress (?)"; break;
223 case AVIERR_USERABORT: err = "aborted by user"; break;
224 case AVIERR_ERROR: err = "error (?)"; break;
227 setf("%s error: %s (%08lx)", s, err, avierr);
230 MyMemoryError::MyMemoryError() {
231 setf("Out of memory");
234 MyMemoryError::MyMemoryError(size_t requestedSize) {
235 setf("Out of memory (unable to allocate %llu bytes)", (unsigned long long)requestedSize);
238 MyWin32Error::MyWin32Error(const char *format, uint32 err, ...)
239 : mWin32Error(err)
241 char szError[1024];
242 char szTemp[1024];
243 va_list val;
245 va_start(val, err);
246 szError[(sizeof szError)-1] = 0;
247 _vsnprintf(szError, (sizeof szError)-1, format, val);
248 va_end(val);
250 // Determine the position of the last %s, and escape everything else. This doesn't
251 // track escaped % signs properly, but it works for the strings that we receive (and at
252 // worst just produces a funny message).
253 const char *keep = strstr(szError, "%s");
254 if (keep) {
255 for(;;) {
256 const char *test = strstr(keep + 1, "%s");
258 if (!test)
259 break;
261 keep = test;
265 char *t = szTemp;
266 char *end = szTemp + (sizeof szTemp) - 1;
267 const char *s = szError;
269 while(char c = *s++) {
270 if (c == '%') {
271 // We allow one %s to go through. Everything else gets escaped.
272 if (s-1 != keep) {
273 if (t >= end)
274 break;
276 *t++ = '%';
280 if (t >= end)
281 break;
283 *t++ = c;
286 *t = 0;
288 if (!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
290 err,
291 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
292 szError,
293 sizeof szError,
294 NULL))
296 szError[0] = 0;
299 if (szError[0]) {
300 long l = strlen(szError);
302 if (l>1 && szError[l-2] == '\r')
303 szError[l-2] = 0;
304 else if (szError[l-1] == '\n')
305 szError[l-1] = 0;
308 setf(szTemp, szError);
311 MyCrashError::MyCrashError(const char *format, uint32 dwExceptionCode) {
312 const char *s = "(Unknown Exception)";
314 switch(dwExceptionCode) {
315 case EXCEPTION_ACCESS_VIOLATION:
316 s = "Access Violation";
317 break;
318 case EXCEPTION_PRIV_INSTRUCTION:
319 s = "Privileged Instruction";
320 break;
321 case EXCEPTION_INT_DIVIDE_BY_ZERO:
322 s = "Integer Divide By Zero";
323 break;
324 case EXCEPTION_BREAKPOINT:
325 s = "User Breakpoint";
326 break;
329 setf(format, s);
332 MyUserAbortError::MyUserAbortError() {
333 buf = _strdup("");
336 MyInternalError::MyInternalError(const char *format, ...) {
337 char buf[1024];
338 va_list val;
340 va_start(val, format);
341 _vsnprintf(buf, (sizeof buf) - 1, format, val);
342 buf[1023] = 0;
343 va_end(val);
345 setf("Internal error: %s", buf);