2 Copyright © 1995-2012, The AROS Development Team. All rights reserved.
6 #define USE_BOOPSI_STUBS
7 #include <aros/macros.h>
8 #include <datatypes/datatypes.h>
9 #include <proto/alib.h>
10 #include <proto/utility.h>
11 #include <proto/dos.h>
12 #include <proto/iffparse.h>
13 #include <proto/intuition.h>
14 #include <proto/locale.h>
15 #include <utility/name.h>
16 #include <intuition/cghooks.h>
17 #include <libraries/locale.h>
18 #include <datatypes/datatypesclass.h>
19 #include "datatypes_intern.h"
20 #include <clib/boopsistubs.h>
22 #include <aros/debug.h>
24 /************************** ASCII/BINARY RECOGNITION *************************/
26 UBYTE
const ASCIITable
[256]=
28 0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,1,0,1,0,0,0,0,0,0,0,1,0,0,0,0,
29 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
30 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
31 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
32 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
33 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
34 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
35 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
39 UBYTE
const BinaryTable
[256]=
41 1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,0,1,0,1,1,1,1,1,1,1,0,1,1,1,1,
42 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
43 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
44 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
45 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,
46 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
47 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
48 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
53 struct DataTypesList
*GetDataTypesList(struct DataTypesBase
*DataTypesBase
)
55 struct NamedObject
*no
;
56 struct DataTypesList
*dtl
= NULL
;
58 if((no
= FindNamedObject(NULL
, DATATYPESLIST
, NULL
)))
60 dtl
= (struct DataTypesList
*)no
->no_Object
;
65 struct TagItem tags
[] =
67 {ANO_NameSpace
, TRUE
},
68 {ANO_UserSpace
, sizeof(struct DataTypesList
) },
69 {ANO_Flags
, NSF_NODUPS
| NSF_CASE
},
73 if((no
= AllocNamedObjectA(DATATYPESLIST
, tags
)))
75 if(!(dtl
= (struct DataTypesList
*)no
->no_Object
))
84 InitSemaphore(&dtl
->dtl_Lock
);
85 NewList(&dtl
->dtl_SortedList
);
86 NewList(&dtl
->dtl_BinaryList
);
87 NewList(&dtl
->dtl_ASCIIList
);
88 NewList(&dtl
->dtl_IFFList
);
89 NewList(&dtl
->dtl_MiscList
);
91 if(!AddNamedObject(NULL
, no
))
101 ReleaseNamedObject(no
);
107 struct Node
*FindNameNoCase(struct Library
*DataTypesBase
, struct List
*list
,
111 struct Node
*result
= NULL
;
113 for (node
= list
->lh_Head
; node
->ln_Succ
; node
= node
->ln_Succ
)
115 if (!Stricmp(node
->ln_Name
, name
))
127 BPTR
NewOpen(struct Library
*DataTypesBase
, STRPTR name
, ULONG SourceType
,
130 BPTR returnfh
= BNULL
;
131 // struct XpkFib *xpkfib=NULL;
134 D(bug("datatypes.library/NewOpen: name = %s\n", name
));
136 if((dosfile
= Open(name
, MODE_OLDFILE
)))
138 D(bug("datatypes.library/NewOpen: open okay\n"));
145 if(xpkfib
= AllocVec(sizeof(struct XpkFib
),
146 MEMF_PUBLIC
|MEMF_CLEAR
))
148 if(!xpkexaminetags(DataTypesBase
, xpkfib
, XPK_InFH
, dosfile
,
151 switch (xpkfib
->Type
)
153 case XPKTYPE_UNPACKED
:
158 Message(DataTypesBase
,"file is XPK packed","okay");
160 if (xpkfib
->Flags
&XPKFLAGS_PASSWORD
)
161 Message(DataTypesBase
,"file needs password","okay");
163 if (xpkfib
->Flags
&XPKFLAGS_NOSEEK
)
164 Message(DataTypesBase
,"file does not support seeking",
166 if (xpkfib
->Flags
&XPKFLAGS_NONSTD
)
167 Message(DataTypesBase
,"file is non standard","okay");
169 SetIoErr(ERROR_NOT_IMPLEMENTED
);
172 case XPKTYPE_ARCHIVE
:
173 SetIoErr(ERROR_NOT_IMPLEMENTED
);
180 if (returnfh
!= dosfile
)
194 #define getDTLIST (GPB(DataTypesBase)->dtb_DTList)
196 struct CompoundDataType
*ExamineLock(BPTR lock
, struct FileInfoBlock
*fib
,
197 struct Library
*DataTypesBase
)
199 struct CompoundDataType
*cdt
= NULL
;
201 D(bug("datatypes.library/ExamineLock\n"));
203 ObtainSemaphoreShared(&getDTLIST
->dtl_Lock
);
205 if(Examine(lock
, fib
))
207 D(bug("datatypes.library/ExamineLock: Examine okay\n"));
208 if (fib
->fib_DirEntryType
> 0)
210 D(bug("datatypes.library/ExamineLock: is a directory\n"));
211 cdt
= (struct CompoundDataType
*)FindNameNoCase(DataTypesBase
,
212 &getDTLIST
->dtl_MiscList
,
217 if (fib
->fib_DirEntryType
< 0)
221 D(bug("datatypes.library/ExamineLock: is a file\n"));
223 if (NameFromLock(lock
, namebuf
, sizeof(namebuf
)))
227 D(bug("datatypes.library/ExamineLock: NameFromLock okay. Name = \"%s\"\n", namebuf
));
229 if((file
= NewOpen(DataTypesBase
, namebuf
, DTST_FILE
, 0)))
232 UWORD CheckSize
= (getDTLIST
->dtl_LongestMask
> 64) ?
233 getDTLIST
->dtl_LongestMask
: 64;
235 D(bug("datatypes.library/ExamineLock: NewOpen okay\n"));
237 if((CheckArray
= AllocVec((ULONG
)(CheckSize
)+1,
240 D(bug("datatypes.library/ExamineLock: Alloced CheckArray\n"));
242 if((CheckSize
= Read(file
, CheckArray
,
243 (ULONG
)CheckSize
)) > 0)
245 struct DTHookContext dthc
;
246 struct IFFHandle
*iff
;
248 D(bug("datatypes.library/ExamineLock: Read in CheckArray size = %d\n", CheckSize
));
250 Seek(file
, 0, OFFSET_BEGINNING
);
252 dthc
.dthc_SysBase
= (struct Library
*)SysBase
;
253 dthc
.dthc_DOSBase
= (struct Library
*)DOSBase
;
254 dthc
.dthc_IFFParseBase
= IFFParseBase
;
255 dthc
.dthc_UtilityBase
= (struct Library
*)UtilityBase
;
256 dthc
.dthc_Lock
= lock
;
258 dthc
.dthc_FileHandle
= file
;
259 dthc
.dthc_Buffer
= CheckArray
;
260 dthc
.dthc_BufferLength
= CheckSize
;
262 if(!(iff
=dthc
.dthc_IFF
= AllocIFF()))
263 SetIoErr(ERROR_NO_FREE_STORE
);
266 D(bug("datatypes.library/ExamineLock: AllocIFF okay: iff = %x\n", iff
));
268 iff
->iff_Stream
= (IPTR
)file
; /* Hmm? */
271 if (!OpenIFF(iff
, IFFF_READ
))
273 D(bug("datatypes.library/ExamineLock: OpenIFF okay. Now calling ExamineData\n"));
275 cdt
= ExamineData(DataTypesBase
,
282 D(bug("datatypes.library/ExamineLock: ExamineData() returned %x\n", cdt
));
288 FreeIFF(iff
); /* AROS BUG FIX: was dthc.dthc_IFF) */
290 } /* AllocIFF okay */
292 } /* if (CheckSize = Read(... */
296 } /* if (CheckArray = AllocVec(... */
300 } /* if file opened */
302 } /* if I got the name from the lock */
306 } /* it is not a directory */
308 } /* if(Examine(lock, fib)) */
310 ReleaseSemaphore(&getDTLIST
->dtl_Lock
);
316 struct CompoundDataType
*FindDtInList(struct Library
*DataTypesBase
,
317 struct DTHookContext
*dthc
,
323 struct CompoundDataType
*cdt
= NULL
;
328 struct CompoundDataType
*cur
;
330 for(cur
= (struct CompoundDataType
*)list
->lh_Head
;
331 cur
->DT
.dtn_Node1
.ln_Succ
;
332 cur
= (struct CompoundDataType
*)cur
->DT
.dtn_Node1
.ln_Succ
)
334 if (!(cur
->DTH
.dth_MaskLen
) && (cur
->Function
))
336 found
= (cur
->Function
)(dthc
);
338 else if(CheckSize
>= cur
->DTH
.dth_MaskLen
)
340 WORD
*msk
= cur
->DTH
.dth_Mask
;
341 UBYTE
*cmp
= CheckArray
;
346 for(count
= cur
->DTH
.dth_MaskLen
; count
--; msk
++, cmp
++)
350 if(cur
->DTH
.dth_Flags
& DTF_CASE
)
361 *msk
!= ToUpper((ULONG
)*cmp
) &&
362 *msk
!= ToLower((ULONG
)*cmp
))
373 if((!(cur
->FlagLong
& CFLGF_PATTERN_UNUSED
)) &&
374 cur
->DTH
.dth_Pattern
)
376 if(cur
->FlagLong
& CFLGF_IS_WILD
)
380 if(!MatchPatternNoCase(cur
->ParsePatMem
,
389 if(Stricmp(cur
->DTH
.dth_Pattern
, Filename
))
400 found
= (cur
->Function
)(dthc
);
404 CloseIFF(dthc
->dthc_IFF
);
405 OpenIFF(dthc
->dthc_IFF
, IFFF_READ
);
409 Seek(dthc
->dthc_FileHandle
, 0,
427 struct CompoundDataType
*ExamineData(struct Library
*DataTypesBase
,
428 struct DTHookContext
*dthc
,
429 UBYTE
*CheckArray
, UWORD CheckSize
,
430 UBYTE
*Filename
, ULONG Size
)
432 struct CompoundDataType
*cdt
= NULL
;
433 struct CompoundDataType
*cdt_bin
= NULL
;
434 struct CompoundDataType
*cdt_asc
= NULL
;
438 ULONG IFF_ID
= AROS_BE2LONG(*((ULONG
*)CheckArray
));
439 ULONG IFF_Size
= AROS_BE2LONG(*((ULONG
*)(CheckArray
+4)));
441 if(((!dthc
->dthc_FileHandle
) && (dthc
->dthc_IFF
)) ||
442 (((IFF_Size
+ 8 == Size
) && (Size
> 21)) &&
443 (IFF_ID
==ID_FORM
|| IFF_ID
==ID_CAT
|| IFF_ID
==ID_LIST
)) )
445 D(bug("[ExamineData] IFF detected\n"));
447 cdt
= FindDtInList(DataTypesBase
, dthc
, &getDTLIST
->dtl_IFFList
, CheckArray
, CheckSize
, Filename
);
455 dthc
->dthc_IFF
= NULL
;
457 for (ptr
=CheckArray
,count
=CheckSize
,ascii
=0 ; count
-- ; ptr
++)
459 if (ASCIITable
[*ptr
])
463 if (BinaryTable
[*ptr
])
471 D(bug("[ExamineData] ASCII characters: %u of %u\n", ascii
, CheckSize
));
472 if (ascii
> CheckSize
*3/4)
474 D(bug("[ExamineData] Recognized as ASCII\n"));
476 cdt_asc
= FindDtInList(DataTypesBase
, dthc
, &getDTLIST
->dtl_ASCIIList
, CheckArray
, CheckSize
, Filename
);
477 D(bug("[ExamineData] ASCII datatype: 0x%p\n", cdt_asc
));
479 /* if the found datatype is 'only' ascii we have to look additionally in the binary list */
480 if (cdt_asc
&& !strcmp(cdt_asc
->DTH
.dth_Name
, "ascii"))
482 D(bug("[ExamineData] Trying binary list\n"));
483 cdt_bin
= FindDtInList(DataTypesBase
, dthc
, &getDTLIST
->dtl_BinaryList
, CheckArray
, CheckSize
, Filename
);
484 D(bug("[[ExamineData] Binary datatype: 0x%p\n"));
485 /* if we find in the binary list something which is better than just 'binary' we use it */
486 if (cdt_bin
&& strcmp(cdt_bin
->DTH
.dth_Name
, "binary"))
494 D(bug("[ExamineData] Recognized as binary\n"));
495 D(type
= DTF_BINARY
);
496 cdt
= FindDtInList(DataTypesBase
, dthc
, &getDTLIST
->dtl_BinaryList
, CheckArray
, CheckSize
, Filename
);
500 D(bug("[ExamineData] Found datatype 0x%p, type 0x%u\n", cdt
, type
));
508 /* Putchar procedure needed by RawDoFmt() */
510 AROS_UFH2(void, putchr
,
511 AROS_UFHA(UBYTE
, chr
, D0
),
512 AROS_UFHA(STRPTR
*, p
, A3
))
520 /* FIXME: these work only with stack growing downwards and should therefore be fixed to use macros in utility/tagitem.h */
522 ULONG
setattrs(struct Library
*DataTypesBase
, Object
*object
, Tag firstTag
,...)
524 AROS_SLOWSTACKTAGS_PRE_AS(firstTag
, ULONG
)
525 retval
= SetAttrsA(object
, (struct TagItem
*)&firstTag
);
526 AROS_SLOWSTACKTAGS_POST
529 ULONG
Do_OM_NOTIFY(struct Library
*DataTypesBase
, Object
*object
,
530 struct GadgetInfo
*ginfo
, ULONG flags
, Tag firstTag
,...)
532 /* struct opUpdate opu;
534 opu.MethodID = OM_NOTIFY;
535 opu.opu_AttrList = (struct TagItem *)&firstTag;
536 opu.opu_GInfo = ginfo;
537 opu.opu_Flags = flags;
539 return DoMethodA(object, (Msg)&opu); */
541 AROS_SLOWSTACKTAGS_PRE_AS(firstTag
, ULONG
)
542 retval
= DoMethod(object
, OM_NOTIFY
, (IPTR
)AROS_SLOWSTACKTAGS_ARG(firstTag
), (IPTR
)ginfo
, (IPTR
)flags
);
543 AROS_SLOWSTACKTAGS_POST
547 ULONG
DoGad_OM_NOTIFY(struct Library
*DataTypesBase
, Object
*object
,
548 struct Window
*win
, struct Requester
*req
,
549 ULONG flags
, Tag firstTag
, ...)
551 // return(dogadgetmethod(DataTypesBase, (struct Gadget*)object, win, req, OM_NOTIFY,
552 // &firstTag, NULL, flags));
553 AROS_SLOWSTACKTAGS_PRE_AS(firstTag
, ULONG
)
554 retval
= DoGadgetMethod((struct Gadget
*)object
, win
, req
, OM_NOTIFY
, AROS_SLOWSTACKTAGS_ARG(firstTag
), NULL
, flags
);
555 AROS_SLOWSTACKTAGS_POST
559 //ULONG dogadgetmethod(struct Library *DataTypesBase, struct Gadget *gad,
560 // struct Window *win, struct Requester *req,
561 // ULONG MethodID, ...)
563 // return(DoGadgetMethodA(gad, win, req, (Msg)&MethodID));
566 struct Catalog
*opencatalog(struct Library
*DataTypesBase
, struct Locale
*locale
,
567 STRPTR name
, Tag firstTag
, ...)
569 // return(OpenCatalogA(locale, name, (struct TagItem *)&firstTag));
570 AROS_SLOWSTACKTAGS_PRE_AS(firstTag
, struct Catalog
*)
571 retval
= OpenCatalogA(locale
, name
, AROS_SLOWSTACKTAGS_ARG(firstTag
));
572 AROS_SLOWSTACKTAGS_POST