0022484: UNICODE characters support
[occt.git] / src / OSD / OSD_Error.cxx
1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #ifndef WNT
16
17 #include <OSD_Error.ixx>
18 #include <OSD_ErrorList.hxx>
19 #include <stdio.h>
20
21 /* Created by Stephan GARNAUD (ARM) 1992 for Matra Datavision */
22
23 OSD_Error::OSD_Error(){
24  myErrno = 0;
25 }
26
27
28 void OSD_Error::Reset(){
29  myErrno = 0;
30 }
31
32 Standard_Boolean OSD_Error::Failed()const{
33  if (myErrno == 0) return (Standard_False);
34               else return (Standard_True);
35 }
36
37
38
39 void OSD_Error::SetValue(const Standard_Integer errcode,
40                          const Standard_Integer from,
41                          const TCollection_AsciiString& message){
42  myErrno = errcode;
43  myCode  = (OSD_WhoAmI)from;
44  myMessage = message;
45 }
46
47
48
49 Standard_Integer OSD_Error::Error()const{
50  return(extCode);
51 }
52
53  
54 void OSD_Error::Perror() {
55  TCollection_AsciiString buffer;
56
57  if (myErrno == 0) return;
58
59  buffer += " :\n ";
60  extCode = ERR_SURPRISE;
61
62  switch (myErrno){
63   case EBADF  :
64    switch (myCode){
65     case OSD_WFile:
66       buffer += "Invalid file descriptor or bad mode";
67       extCode = ERR_FBADF;
68       break;
69     default:
70       break;
71     }
72     break;
73
74
75 #ifdef SUN
76   case EBADMSG:
77    switch (myCode){
78     case OSD_WFile:
79      buffer += 
80      "The message waiting to be read on stream is not a data message";
81      extCode = ERR_FBADMSG;
82      break;
83     default:
84       break;
85    }
86    break;
87 #endif
88
89   case EINVAL: 
90    switch (myCode){
91     case OSD_WFileNode:
92       buffer += "Can't unlink '.' or '..'";
93       extCode = ERR_FNINVAL;
94       break;
95     case OSD_WFile:
96       buffer += "Invalid file descriptor";
97       extCode = ERR_FINVAL;
98       break;
99     default :
100       buffer += "User error : Bad parameter";
101       extCode = ERR_INVAL;
102       break;
103    }
104    break;
105 #if !defined(sun) && !defined(SOLARIS)
106   case EDQUOT :
107    switch (myCode){
108     case OSD_WDirectory:
109     case OSD_WFileNode:
110     case OSD_WFile :
111      buffer += "Exceed quota of disk blocks";
112      extCode = ERR_QUOT;
113      break;
114     default:
115       break;
116    }
117    break;
118 #endif
119
120 #ifdef SUN
121   case EDEADLK:
122    switch (myCode){
123     case OSD_WFile:
124      buffer += "Lock is already blocked by another process";
125      extCode = ERR_FDEADLK;
126      break;
127     default:
128       break;
129    }
130    break;
131 #endif
132
133   case ENOLCK:
134    switch (myCode){
135     case OSD_WFile:
136      buffer += "No more file lock entries available";
137      extCode = ERR_FNOLCK;
138      break;
139     default:
140       break;
141    }
142    break;
143   case EOPNOTSUPP:
144    switch (myCode){
145     case OSD_WFile:
146      buffer += "File descriptor doesn't refer to a file";
147      extCode = ERR_FWFD;
148      break;
149     default:
150      break;
151    }
152    break;
153   case EACCES: 
154     buffer += "Permission denied";
155     extCode = ERR_ACCESS;
156     break;
157   case EBUSY:
158    switch (myCode){
159     case OSD_WFileNode:
160      buffer += "Still used by system or a process";
161      extCode = ERR_FNBUSY;
162      break;
163     default:
164       break;
165    }
166    break;
167   case ERANGE:
168    switch (myCode){
169     case OSD_WFile:
170      buffer += "Not enough or too many bytes written";
171      extCode = ERR_FRANGE;
172      break;
173     default:
174       break;
175    }
176    break;
177   case EPERM: 
178    switch (myCode){
179     case OSD_WPackage:
180      buffer += "Permission denied";
181      extCode = ERR_PPERM;
182      break;
183     case OSD_WFileNode:
184      buffer += "Permission denied or can't unlink directory";
185      extCode = ERR_FPERM;
186      break;
187     default : 
188      buffer += "abnormal error : you modified OSD library";
189      extCode = ERR_PERM;
190      break;
191     }
192     break;
193   case EROFS:
194    switch (myCode){
195     case OSD_WFileNode:
196     case OSD_WFile:
197      buffer += "Read only file system";
198      extCode = ERR_ROFS;
199      break;
200     default:
201      break;
202    }
203    break;
204   case ENXIO:
205   case EIO :
206    switch (myCode){
207     case OSD_WDirectory:
208     case OSD_WFileNode:
209      buffer += "I/O error";
210      extCode = ERR_IO;
211      break;
212     case OSD_WFile :
213      buffer += "I/O error or Hang up from terminal";
214      extCode = ERR_FIO;
215      break;
216     default:
217      break;
218    }
219    break;
220   case EISDIR :
221    switch (myCode){
222     case OSD_WFileNode:
223     case OSD_WFile :
224      buffer += "The File is a Directory";
225      extCode = ERR_ISDIR;
226      break;
227     default:
228      break;
229     }
230     break;
231
232 #ifdef SUN
233   case EWOULDBLOCK:
234    switch (myCode){
235     case OSD_WFile:
236      buffer += "File is locked";
237      extCode = ERR_FLOCKED;
238      break;
239     default:
240      break;
241    }
242    break;
243 #endif
244
245 #ifdef IRIX4
246   case EWOULDBLOCK:
247    switch (myCode){
248     case OSD_WFile:
249      buffer += "File is locked";
250      extCode = ERR_FLOCKED;
251      break;
252     default:
253      break;
254    }
255    break;
256 #endif
257
258   case EAGAIN:
259    switch (myCode){
260     case OSD_WFile:
261      buffer += "No data ready to be read/written";
262      extCode = ERR_FAGAIN;
263      break;
264     default:
265      break;
266    }
267    break;
268   case ENOTDIR:
269    switch(myCode){
270     case OSD_WDirectory:
271     case OSD_WFileNode:
272     case OSD_WFile:
273      buffer += "A component of path is not a Directory";
274      extCode = ERR_NOTDIR;
275      break;
276     default:
277      break;
278    }
279    break;
280   case EMLINK:
281    switch (myCode){
282     case OSD_WDirectory:
283     buffer += "Too many links";
284     extCode = ERR_DMLINK;
285     break;
286     default:
287      break;
288    }
289    break;
290   case ELOOP :
291    switch (myCode){
292     case OSD_WDirectory:
293     case OSD_WFileNode:
294     case OSD_WFile :
295      buffer += "Too many symbolic links";
296      break;
297     default:
298      break;
299    }
300    break;
301   case EFAULT:
302    buffer += "User error : arguments point to an illegal address";
303    extCode = ERR_FAULT;
304    break;
305   case EFBIG:
306    switch (myCode){
307     case OSD_WFile:
308      buffer += "Exceed process's file size limit or the maximum file size";
309      extCode = ERR_FFBIG; 
310      break;
311     default:
312      break;
313    }
314    break;
315   case EINTR:
316    buffer += "operation breaked by a signal";
317    extCode = ERR_INTR;
318    break;
319   case ENOMEM: 
320    buffer += "Not enough memory";
321    extCode = ERR_NOMEM;
322    break;
323   case EMFILE : 
324    switch(myCode){   
325     case OSD_WFile :
326        buffer += "Too many file descriptors are currently in use by this process";
327        extCode = ERR_FMFILE;
328        break;
329     default:
330      break;
331     }
332     break;
333   case ENAMETOOLONG :
334    buffer += "File name too long";
335    extCode = ERR_NAMETOOLONG;
336    break;
337   case ENFILE :
338    switch (myCode){
339     case OSD_WFile:
340      buffer += "Too many files are currently open in the system";
341      extCode = ERR_FNFILE;
342      break;
343     default:
344      break;
345    }
346    break;
347   case EXDEV:
348    switch (myCode){
349     case OSD_WFileNode:
350      buffer += "The link named by path2 and the file named by path1 are\n";
351      buffer += "on different logical devices (file systems)";
352      extCode = ERR_FNXDEV;
353      break;
354     default:
355      break;
356    }
357    break;
358   case ENOENT:
359    switch (myCode){
360     case OSD_WFileNode:
361     case OSD_WFile:
362      if (myMessage != "Open") buffer += "File doesn't exist or";
363       buffer += "Invalid path (empty string)";
364      extCode = ERR_NOENT;
365      break;
366     case OSD_WDirectory:
367      buffer += "A component of the path prefix of path does not exist";
368      extCode = ERR_DNOENT;
369      break;
370     default:
371      break;
372     }
373     break;
374   case ENOSPC: {
375    switch (myCode){
376     case OSD_WDirectory:
377     case OSD_WFile:
378      buffer += "No more free space on file system";
379      extCode = ERR_FNOSPC;
380      break;
381     default:
382      break;
383    }
384    break;
385  }
386
387 //
388 // AIX maps ENOTEMPTY to EEXIST.  Move this case block to
389 // the EEXIST case block.
390 //
391 #if (!defined(_AIX)) && (!defined(AIX))
392   case ENOTEMPTY:
393    switch (myCode){
394     case OSD_WFileNode:
395      buffer += "Directory not empty";
396      extCode = ERR_FNNOTEMPTY;
397      break;
398     default:
399      break;
400    }
401    break;
402 #endif
403
404   case EEXIST: 
405    switch(myCode){
406     case OSD_WFileNode:
407      buffer += "Directory not empty";
408      extCode = ERR_FNNOTEMPTY;
409      break;
410     case OSD_WFile:
411      buffer += "OSD_Create and OSD_Exclude are set and the named file exists";
412      extCode = ERR_FEXIST;
413      break;
414     default:
415      buffer += "Identifier already exists for this key";
416      extCode = ERR_EXIST;
417      break;
418    }
419    break;
420   case E2BIG: 
421    buffer += "Too many Semaphore/Shared memory for a process.";
422    buffer += "Reconfigure Kernel with greater values";
423    extCode = ERR_TOOBIG;
424    break;
425    default: {
426      Standard_Character buf[255];
427      //
428      sprintf(buf,"%sUnknowm error #%d",buffer.ToCString(),myErrno);
429      TCollection_AsciiString interm(buf);
430      buffer = interm;
431      extCode = ERR_UNKNOWN;
432    }
433  }
434  buffer += ".\n\n";
435  OSD_OSDError::Raise (buffer.ToCString());
436 }
437
438 #else
439
440 //------------------------------------------------------------------------
441 //-------------------  Windows NT sources for OSD_Error ------------------
442 //------------------------------------------------------------------------
443
444 #define STRICT
445 #include <OSD_Error.hxx>
446 #include <OSD_ErrorList.hxx>
447 #include <TCollection_ExtendedString.hxx>
448
449 #include <windows.h>
450
451 typedef struct _error_table {
452
453                 DWORD            wnt_error;
454                 Standard_Integer csf_error;
455
456                } ERROR_TABLE;
457
458 static int      fPrefix     = 1;
459 static ostream* errorStream = &cerr;
460
461 static ERROR_TABLE commErrorTable [] = {
462
463  { ERROR_INVALID_FUNCTION,      ERR_INVAL       },
464  { ERROR_FILE_NOT_FOUND,        ERR_NOENT       },
465  { ERROR_PATH_NOT_FOUND,        ERR_NOENT       },
466  { ERROR_ACCESS_DENIED,         ERR_ACCESS      },
467  { ERROR_ARENA_TRASHED,         ERR_NOMEM       },
468  { ERROR_NOT_ENOUGH_MEMORY,     ERR_NOMEM       },
469  { ERROR_INVALID_BLOCK,         ERR_NOMEM       },
470  { ERROR_BAD_ENVIRONMENT,       ERR_TOOBIG      },
471  { ERROR_INVALID_ACCESS,        ERR_INVAL       },
472  { ERROR_INVALID_DATA,          ERR_INVAL       },
473  { ERROR_INVALID_DRIVE,         ERR_NOENT       },
474  { ERROR_CURRENT_DIRECTORY,     ERR_ACCESS      },
475  { ERROR_NO_MORE_FILES,         ERR_NOENT       },
476  { ERROR_LOCK_VIOLATION,        ERR_ACCESS      },
477  { ERROR_SHARING_VIOLATION,     ERR_ACCESS      },
478  { ERROR_BAD_NETPATH,           ERR_NOENT       },
479  { ERROR_NETWORK_ACCESS_DENIED, ERR_ACCESS      },
480  { ERROR_BAD_NET_NAME,          ERR_NOENT       },
481  { ERROR_FILE_EXISTS,           ERR_EXIST       },
482  { ERROR_CANNOT_MAKE,           ERR_ACCESS      },
483  { ERROR_FAIL_I24,              ERR_ACCESS      },
484  { ERROR_INVALID_PARAMETER,     ERR_INVAL       },
485  { ERROR_DRIVE_LOCKED,          ERR_ACCESS      },
486  { ERROR_INVALID_HANDLE,        ERR_INVAL       },
487  { ERROR_NEGATIVE_SEEK,         ERR_INVAL       },
488  { ERROR_SEEK_ON_DEVICE,        ERR_ACCESS      },
489  { ERROR_NOT_LOCKED,            ERR_ACCESS      },
490  { ERROR_BAD_PATHNAME,          ERR_NOENT       },
491  { ERROR_LOCK_FAILED,           ERR_ACCESS      },
492  { ERROR_ALREADY_EXISTS,        ERR_EXIST       },
493  { ERROR_FILENAME_EXCED_RANGE,  ERR_NOENT       },
494  { ERROR_NOT_ENOUGH_QUOTA,      ERR_QUOT        },
495  { ERROR_IO_DEVICE,             ERR_IO          },
496  { ERROR_INVALID_BLOCK,         ERR_FAULT       },
497  { ERROR_BAD_THREADID_ADDR,     ERR_FAULT       },
498  { ERROR_INVALID_ADDRESS,       ERR_FAULT       },
499  { ERROR_MAPPED_ALIGNMENT,      ERR_FAULT       },
500  { ERROR_BUFFER_OVERFLOW,       ERR_NAMETOOLONG }
501
502 };
503
504 #define COMM_ERR_TABLE_SIZE (int)(sizeof(commErrorTable) / sizeof(commErrorTable[0]))
505
506 static ERROR_TABLE dirErrorTable[] = {
507
508  { ERROR_FILE_NOT_FOUND,       ERR_NOENT },
509  { ERROR_PATH_NOT_FOUND,       ERR_NOENT },
510  { ERROR_INVALID_DRIVE,        ERR_NOENT },
511  { ERROR_NO_MORE_FILES,        ERR_NOENT },
512  { ERROR_BAD_NETPATH,          ERR_NOENT },
513  { ERROR_BAD_NET_NAME,         ERR_NOENT },
514  { ERROR_BAD_PATHNAME,         ERR_NOENT },
515  { ERROR_FILENAME_EXCED_RANGE, ERR_NOENT }
516
517 };
518
519 #define DIR_ERR_TABLE_SIZE (int)(sizeof(dirErrorTable) / sizeof(dirErrorTable[0]))
520
521 static ERROR_TABLE fileErrorTable[] = {
522
523  { ERROR_INVALID_HANDLE,        ERR_FBADF   },
524  { ERROR_INVALID_TARGET_HANDLE, ERR_FBADF   },
525  { ERROR_DIRECT_ACCESS_HANDLE,  ERR_FBADF   },
526  { ERROR_FILE_EXISTS,           ERR_EXIST   },
527  { ERROR_ALREADY_EXISTS,        ERR_EXIST   },
528  { ERROR_TOO_MANY_OPEN_FILES,   ERR_FMFILE  },
529  { ERROR_INVALID_FUNCTION,      ERR_FINVAL  },
530  { ERROR_INVALID_ACCESS,        ERR_FINVAL  },
531  { ERROR_INVALID_DATA,          ERR_FINVAL  },
532  { ERROR_INVALID_PARAMETER,     ERR_FINVAL  },
533  { ERROR_INVALID_HANDLE,        ERR_FINVAL  },
534  { ERROR_NEGATIVE_SEEK,         ERR_FINVAL  },
535  { ERROR_IO_PENDING,            ERR_FAGAIN  },
536  { ERROR_WRITE_FAULT,           ERR_FIO     },
537  { ERROR_READ_FAULT,            ERR_FIO     },
538  { ERROR_NET_WRITE_FAULT,       ERR_FIO     },
539  { ERROR_IO_DEVICE,             ERR_FIO     },
540  { ERROR_LOCK_VIOLATION,        ERR_FLOCKED },
541  { ERROR_LOCK_FAILED,           ERR_FLOCKED }
542
543 };
544
545 #define FILE_ERR_TABLE_SIZE (int)(sizeof(fileErrorTable) / sizeof(fileErrorTable[0]))
546
547 static ERROR_TABLE fileNodeErrorTable[] = {
548
549  { ERROR_INVALID_FUNCTION,      ERR_FNINVAL    },
550  { ERROR_INVALID_ACCESS,        ERR_FNINVAL    },
551  { ERROR_INVALID_DATA,          ERR_FNINVAL    },
552  { ERROR_INVALID_PARAMETER,     ERR_FNINVAL    },
553  { ERROR_INVALID_HANDLE,        ERR_FNINVAL    },
554  { ERROR_NEGATIVE_SEEK,         ERR_FNINVAL    },
555  { ERROR_DISK_FULL,             ERR_FNOSPC     },
556  { ERROR_DIR_NOT_EMPTY,         ERR_FNNOTEMPTY },
557  { ERROR_NOT_SAME_DEVICE,       ERR_FNXDEV     }
558
559 };
560
561 #define FILE_NODE_ERR_TABLE_SIZE (int)(sizeof(fileNodeErrorTable) / sizeof(fileNodeErrorTable[0]))
562
563 static Standard_Integer _get_comm_error ( DWORD );
564
565 OSD_Error :: OSD_Error () : 
566    myCode((OSD_WhoAmI)0),
567    extCode(0)
568 {
569  Reset ();
570 }  // end constructor ( 1 )
571
572 void OSD_Error :: Perror () {
573
574   if (errorStream == NULL)
575     return;
576
577  Standard_Character buff[ 32 ];
578  Standard_CString   ptr;
579
580  if ( fPrefix ) {
581  
582   lstrcpy (  buff, "Error ( "  );
583
584   switch ( myCode ) {
585   
586    case OSD_WDirectoryIterator:
587
588     ptr = "OSD_DirectoryIterator";
589
590    break;
591
592    case OSD_WDirectory:
593
594     ptr = "OSD_Directory";
595
596    break;
597
598    case OSD_WFileIterator:
599
600     ptr = "OSD_FileIterator";
601
602    break;
603
604    case OSD_WFile:
605   
606     ptr = "OSD_File";
607
608    break;
609
610    case OSD_WFileNode:
611
612     ptr = "OSD_FileNode";
613
614    break;
615
616    case OSD_WHost:
617
618     ptr = "OSD_Host";
619
620    break;
621
622    case OSD_WProcess:
623
624     ptr = "OSD_Environment";
625
626    break;
627
628    case OSD_WEnvironmentIterator:
629
630     ptr = "OSD_EnvironmentIterator";
631
632    break;
633
634    case OSD_WEnvironment:
635
636     ptr = "OSD_Environment";
637
638    break;
639
640    case OSD_WDisk:
641
642     ptr = "OSD_Disk";
643
644    break;
645
646    default:
647
648     ptr = "Unknown";
649
650   }  // end switch
651
652   lstrcat ( buff, ptr );
653   lstrcat (  buff, " )"  );
654   ( *errorStream ) << buff;
655  
656  }  // end if ( fPrefix . . . )
657
658  TCollection_ExtendedString aMessageW(myMessage);
659  ( *errorStream ) << L": " << (const wchar_t*)aMessageW.ToExtString () << endl << flush;
660
661 }  // end OSD_Error :: Perror
662
663 void OSD_Error :: SetValue (
664                    const Standard_Integer Errcode,
665                    const Standard_Integer From,
666                    const TCollection_AsciiString& Message
667                   ) {
668
669  int i;
670
671  myErrno   = Errcode;
672  myCode    = ( OSD_WhoAmI )From;
673  myMessage = Message;
674
675  switch ( From ) {
676  
677   case OSD_WDirectory:
678
679    for ( i = 0; i < DIR_ERR_TABLE_SIZE; ++i )
680
681     if ( dirErrorTable[ i ].wnt_error == ( DWORD )Errcode ) {
682
683      extCode = dirErrorTable[ i ].csf_error;
684      break;
685
686    }  // end if
687
688   if ( i == DIR_ERR_TABLE_SIZE ) extCode = _get_comm_error ( Errcode );
689
690   break;
691
692   case OSD_WFile:
693
694    for ( i = 0; i < FILE_ERR_TABLE_SIZE; ++i )
695
696     if ( fileErrorTable[ i ].wnt_error == ( DWORD )Errcode ) {
697
698      extCode = fileErrorTable[ i ].csf_error;
699      break;
700
701    }  // end if
702
703   if ( i == FILE_ERR_TABLE_SIZE ) extCode = _get_comm_error ( Errcode );
704
705   break;
706  
707   case OSD_WFileNode:
708
709    for ( i = 0; i < FILE_NODE_ERR_TABLE_SIZE; ++i )
710
711     if ( fileNodeErrorTable[ i ].wnt_error == ( DWORD )Errcode ) {
712
713      extCode = fileNodeErrorTable[ i ].csf_error;
714      break;
715
716    }  // end if
717
718   if ( i == FILE_NODE_ERR_TABLE_SIZE ) extCode = _get_comm_error ( Errcode );
719
720   break;
721
722   default:
723
724    extCode = _get_comm_error ( Errcode );
725
726  }  // end switch
727
728 }  // end OSD_Error :: SetValue
729
730 Standard_Integer OSD_Error :: Error () const {
731
732  return extCode;
733
734 }  // end OSD_Error :: Error
735
736 Standard_Boolean OSD_Error :: Failed () const {
737
738  return myErrno == ERROR_SUCCESS ? Standard_False : Standard_True;
739
740 }  // end OSD_Error :: Failed
741
742 void OSD_Error :: Reset () {
743
744  myErrno = ERROR_SUCCESS; 
745  if (errorStream != NULL)
746  {
747    ( *errorStream ).clear ();
748    ( *errorStream ).seekp ( 0 );
749    ( *errorStream ).clear ();
750  }
751
752 }  // end OSD_Error :: Reset
753
754 void SetErrorStream ( ostream* errStream ) {
755
756  errorStream = errStream;
757
758 }  // end SetErrorStream
759
760 void EnablePrefix ( int fEnable ) {
761
762  fPrefix = fEnable;
763
764 }  // end EnablePrefix
765
766 int ErrorPrefix ( void ) {
767
768  return fPrefix;
769
770 }  // end ErrorPrefix
771
772 ostream* ErrorStream ( void ) {
773
774  return errorStream;
775
776 }  // end ErrorStream
777
778 static Standard_Integer _get_comm_error ( DWORD dwCode ) {
779
780  int              i;
781  Standard_Integer retVal = ERR_SURPRISE;
782
783  for ( i = 0; i < COMM_ERR_TABLE_SIZE; ++i )
784
785   if ( commErrorTable[ i ].wnt_error == ( DWORD )dwCode ) {
786
787    retVal = commErrorTable[ i ].csf_error;
788    break;
789
790   }  // end if
791
792  return retVal;
793
794 }  // end _get_comm_error
795
796 #endif