2 Copyright © 1995-2003, 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
= NULL
;
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(CheckSize
>= cur
->DTH
.dth_MaskLen
)
336 WORD
*msk
= cur
->DTH
.dth_Mask
;
337 UBYTE
*cmp
= CheckArray
;
342 for(count
= cur
->DTH
.dth_MaskLen
; count
--; msk
++, cmp
++)
346 if(cur
->DTH
.dth_Flags
& DTF_CASE
)
357 *msk
!= ToUpper((ULONG
)*cmp
) &&
358 *msk
!= ToLower((ULONG
)*cmp
))
369 if((!(cur
->FlagLong
& CFLGF_PATTERN_UNUSED
)) &&
370 cur
->DTH
.dth_Pattern
)
372 if(cur
->FlagLong
& CFLGF_IS_WILD
)
376 if(!MatchPatternNoCase(cur
->ParsePatMem
,
385 if(Stricmp(cur
->DTH
.dth_Pattern
, Filename
))
396 found
= (cur
->Function
)(dthc
);
400 CloseIFF(dthc
->dthc_IFF
);
401 OpenIFF(dthc
->dthc_IFF
, IFFF_READ
);
405 Seek(dthc
->dthc_FileHandle
, 0,
423 struct CompoundDatatype
*ExamineData(struct Library
*DataTypesBase
,
424 struct DTHookContext
*dthc
,
425 UBYTE
*CheckArray
, UWORD CheckSize
,
426 UBYTE
*Filename
, ULONG Size
)
428 struct CompoundDatatype
*cdt
= NULL
;
429 struct CompoundDatatype
*cdt_bin
= NULL
;
430 struct CompoundDatatype
*cdt_asc
= NULL
;
433 struct List
*list
= NULL
;
435 ULONG IFF_ID
= AROS_BE2LONG(*((ULONG
*)CheckArray
));
436 ULONG IFF_Size
= AROS_BE2LONG(*((ULONG
*)(CheckArray
+4)));
438 if(((!dthc
->dthc_FileHandle
) && (dthc
->dthc_IFF
)) ||
439 (((Size
*3/4 < IFF_Size
) && (Size
*4/3 > IFF_Size
)) &&
440 (IFF_ID
==ID_FORM
|| IFF_ID
==ID_CAT
|| IFF_ID
==ID_LIST
)) )
443 cdt
= FindDtInList(DataTypesBase
, dthc
, &getDTLIST
->dtl_IFFList
, CheckArray
, CheckSize
, Filename
);
451 dthc
->dthc_IFF
= NULL
;
453 for (ptr
=CheckArray
,count
=CheckSize
,ascii
=0 ; count
-- ; ptr
++)
455 if (ASCIITable
[*ptr
])
459 if (BinaryTable
[*ptr
])
467 if (ascii
> CheckSize
*3/4)
470 cdt_asc
= FindDtInList(DataTypesBase
, dthc
, &getDTLIST
->dtl_ASCIIList
, CheckArray
, CheckSize
, Filename
);
472 /* if the found datatype is 'only' ascii we have to look additionally in the binary list */
473 if (cdt_asc
&& !strcmp(cdt_asc
->DTH
.dth_Name
, "ascii"))
475 cdt_bin
= FindDtInList(DataTypesBase
, dthc
, &getDTLIST
->dtl_BinaryList
, CheckArray
, CheckSize
, Filename
);
476 /* if we find in the binary list something which is better than just 'binary' we use it */
477 if (cdt_bin
&& strcmp(cdt_bin
->DTH
.dth_Name
, "binary"))
486 cdt
= FindDtInList(DataTypesBase
, dthc
, &getDTLIST
->dtl_BinaryList
, CheckArray
, CheckSize
, Filename
);
495 cdt
= (struct CompoundDatatype
*)FindNameNoCase(DataTypesBase
, list
,
500 cdt
= (struct CompoundDatatype
*)FindNameNoCase(DataTypesBase
, list
,
505 cdt
= (struct CompoundDatatype
*)FindNameNoCase(DataTypesBase
, list
,
517 /* Putchar procedure needed by RawDoFmt() */
519 AROS_UFH2(void, putchr
,
520 AROS_UFHA(UBYTE
, chr
, D0
),
521 AROS_UFHA(STRPTR
*, p
, A3
))
529 #warning these work only with stack growing downwards and should therefore be fixed to use macros in utility/tagitem.h
531 #define AROS_TAGRETURNTYPE ULONG
532 ULONG
setattrs(struct Library
*DataTypesBase
, Object
*object
, Tag firstTag
,...)
534 AROS_SLOWSTACKTAGS_PRE(firstTag
)
535 retval
= SetAttrsA(object
, (struct TagItem
*)&firstTag
);
536 AROS_SLOWSTACKTAGS_POST
538 #undef AROS_TAGRETURNTYPE
540 #define AROS_TAGRETURNTYPE ULONG
541 ULONG
Do_OM_NOTIFY(struct Library
*DataTypesBase
, Object
*object
,
542 struct GadgetInfo
*ginfo
, ULONG flags
, Tag firstTag
,...)
544 /* struct opUpdate opu;
546 opu.MethodID = OM_NOTIFY;
547 opu.opu_AttrList = (struct TagItem *)&firstTag;
548 opu.opu_GInfo = ginfo;
549 opu.opu_Flags = flags;
551 return DoMethodA(object, (Msg)&opu); */
553 AROS_SLOWSTACKTAGS_PRE(firstTag
)
554 retval
= DoMethod(object
, OM_NOTIFY
, AROS_SLOWSTACKTAGS_ARG(firstTag
), ginfo
, flags
);
555 AROS_SLOWSTACKTAGS_POST
557 #undef AROS_TAGRETURNTYPE
560 #define AROS_TAGRETURNTYPE ULONG
561 ULONG
DoGad_OM_NOTIFY(struct Library
*DataTypesBase
, Object
*object
,
562 struct Window
*win
, struct Requester
*req
,
563 ULONG flags
, Tag firstTag
, ...)
565 // return(dogadgetmethod(DataTypesBase, (struct Gadget*)object, win, req, OM_NOTIFY,
566 // &firstTag, NULL, flags));
567 AROS_SLOWSTACKTAGS_PRE(firstTag
)
568 retval
= DoGadgetMethod((struct Gadget
*)object
, win
, req
, OM_NOTIFY
, AROS_SLOWSTACKTAGS_ARG(firstTag
), NULL
, flags
);
569 AROS_SLOWSTACKTAGS_POST
571 #undef AROS_TAGRETURNTYPE
574 //ULONG dogadgetmethod(struct Library *DataTypesBase, struct Gadget *gad,
575 // struct Window *win, struct Requester *req,
576 // ULONG MethodID, ...)
578 // return(DoGadgetMethodA(gad, win, req, (Msg)&MethodID));
581 #define AROS_TAGRETURNTYPE struct Catalog *
582 struct Catalog
*opencatalog(struct Library
*DataTypesBase
, struct Locale
*locale
,
583 STRPTR name
, Tag firstTag
, ...)
585 // return(OpenCatalogA(locale, name, (struct TagItem *)&firstTag));
586 AROS_SLOWSTACKTAGS_PRE(firstTag
)
587 retval
= OpenCatalogA(locale
, name
, AROS_SLOWSTACKTAGS_ARG(firstTag
));
588 AROS_SLOWSTACKTAGS_POST
590 #undef AROS_TAGRETURNTYPE