Removed unused experimental PA_FASTCALL port type.
[AROS.git] / workbench / libs / datatypes / helpfuncs.c
blob9825d23e8633ab92933fdac97789cd81ede17a2b
1 /*
2 Copyright © 1995-2012, The AROS Development Team. All rights reserved.
3 $Id$
4 */
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;
63 if(!dtl)
65 struct TagItem tags[] =
67 {ANO_NameSpace , TRUE },
68 {ANO_UserSpace , sizeof(struct DataTypesList) },
69 {ANO_Flags , NSF_NODUPS | NSF_CASE },
70 {TAG_DONE }
73 if((no = AllocNamedObjectA(DATATYPESLIST, tags)))
75 if(!(dtl = (struct DataTypesList*)no->no_Object))
77 FreeNamedObject(no);
78 no = NULL;
82 if(dtl)
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))
93 FreeNamedObject(no);
94 no = NULL;
95 dtl = NULL;
100 if (no)
101 ReleaseNamedObject(no);
103 return(dtl);
107 struct Node *FindNameNoCase(struct Library *DataTypesBase, struct List *list,
108 STRPTR name)
110 struct Node *node;
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))
117 result = node;
118 break;
122 return result;
127 BPTR NewOpen(struct Library *DataTypesBase, STRPTR name, ULONG SourceType,
128 ULONG Length)
130 BPTR returnfh = BNULL;
131 // struct XpkFib *xpkfib=NULL;
132 BPTR dosfile;
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"));
140 returnfh = dosfile;
142 #if 0
143 if(XpkBase)
145 if(xpkfib = AllocVec(sizeof(struct XpkFib),
146 MEMF_PUBLIC|MEMF_CLEAR))
148 if(!xpkexaminetags(DataTypesBase, xpkfib, XPK_InFH, dosfile,
149 TAG_DONE))
151 switch (xpkfib->Type)
153 case XPKTYPE_UNPACKED:
154 returnfh=dosfile;
155 break;
157 case XPKTYPE_PACKED:
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",
165 "okay");
166 if (xpkfib->Flags&XPKFLAGS_NONSTD)
167 Message(DataTypesBase,"file is non standard","okay");
169 SetIoErr(ERROR_NOT_IMPLEMENTED);
170 break;
172 case XPKTYPE_ARCHIVE:
173 SetIoErr(ERROR_NOT_IMPLEMENTED);
174 break;
177 FreeVec(xpkfib);
180 if (returnfh != dosfile)
182 Close(dosfile);
184 #endif
188 return returnfh;
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,
213 "directory");
215 else
217 if (fib->fib_DirEntryType < 0)
219 UBYTE namebuf[510];
221 D(bug("datatypes.library/ExamineLock: is a file\n"));
223 if (NameFromLock(lock, namebuf, sizeof(namebuf)))
225 BPTR file;
227 D(bug("datatypes.library/ExamineLock: NameFromLock okay. Name = \"%s\"\n", namebuf));
229 if((file = NewOpen(DataTypesBase, namebuf, DTST_FILE, 0)))
231 UBYTE *CheckArray;
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,
238 MEMF_CLEAR)))
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;
257 dthc.dthc_FIB = fib;
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);
264 else
266 D(bug("datatypes.library/ExamineLock: AllocIFF okay: iff = %x\n", iff));
268 iff->iff_Stream = (IPTR)file; /* Hmm? */
269 InitIFFasDOS(iff);
271 if (!OpenIFF(iff, IFFF_READ))
273 D(bug("datatypes.library/ExamineLock: OpenIFF okay. Now calling ExamineData\n"));
275 cdt = ExamineData(DataTypesBase,
276 &dthc,
277 CheckArray,
278 CheckSize,
279 fib->fib_FileName,
280 fib->fib_Size);
282 D(bug("datatypes.library/ExamineLock: ExamineData() returned %x\n", cdt));
284 CloseIFF(iff);
286 } /* OpenIFF okay */
288 FreeIFF(iff); /* AROS BUG FIX: was dthc.dthc_IFF) */
290 } /* AllocIFF okay */
292 } /* if (CheckSize = Read(... */
294 FreeVec(CheckArray);
296 } /* if (CheckArray = AllocVec(... */
298 Close(file);
300 } /* if file opened */
302 } /* if I got the name from the lock */
304 } /* it is a file */
306 } /* it is not a directory */
308 } /* if(Examine(lock, fib)) */
310 ReleaseSemaphore(&getDTLIST->dtl_Lock);
312 return cdt;
316 struct CompoundDataType *FindDtInList(struct Library *DataTypesBase,
317 struct DTHookContext *dthc,
318 struct List *list,
319 UBYTE *CheckArray,
320 UWORD CheckSize,
321 UBYTE *Filename)
323 struct CompoundDataType *cdt = NULL;
324 BOOL found = FALSE;
326 if (list)
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;
338 UWORD count;
340 found=TRUE;
342 for(count = cur->DTH.dth_MaskLen; count--; msk++, cmp++)
344 if(*msk >= 0)
346 if(cur->DTH.dth_Flags & DTF_CASE)
348 if (*msk != *cmp)
350 found=FALSE;
351 break;
354 else
356 if(*msk != *cmp &&
357 *msk != ToUpper((ULONG)*cmp) &&
358 *msk != ToLower((ULONG)*cmp))
360 found=FALSE;
361 break;
367 if(found)
369 if((!(cur->FlagLong & CFLGF_PATTERN_UNUSED)) &&
370 cur->DTH.dth_Pattern)
372 if(cur->FlagLong & CFLGF_IS_WILD)
374 if(cur->ParsePatMem)
376 if(!MatchPatternNoCase(cur->ParsePatMem,
377 Filename))
379 found = FALSE;
383 else
385 if(Stricmp(cur->DTH.dth_Pattern, Filename))
387 found = FALSE;
392 if(found)
394 if(cur->Function)
396 found = (cur->Function)(dthc);
398 if (dthc->dthc_IFF)
400 CloseIFF(dthc->dthc_IFF);
401 OpenIFF(dthc->dthc_IFF, IFFF_READ);
403 else
405 Seek(dthc->dthc_FileHandle, 0,
406 OFFSET_BEGINNING);
412 if(found)
414 cdt = cur;
415 break;
419 return cdt;
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;
432 D(UWORD type);
434 ULONG IFF_ID = AROS_BE2LONG(*((ULONG*)CheckArray));
435 ULONG IFF_Size = AROS_BE2LONG(*((ULONG*)(CheckArray+4)));
437 if(((!dthc->dthc_FileHandle) && (dthc->dthc_IFF)) ||
438 (((IFF_Size + 8 == Size) && (Size > 21)) &&
439 (IFF_ID==ID_FORM || IFF_ID==ID_CAT || IFF_ID==ID_LIST)) )
441 D(bug("[ExamineData] IFF detected\n"));
442 D(type = DTF_IFF);
443 cdt = FindDtInList(DataTypesBase, dthc, &getDTLIST->dtl_IFFList, CheckArray, CheckSize, Filename);
445 else
447 UBYTE *ptr;
448 UWORD count;
449 UWORD ascii;
451 dthc->dthc_IFF = NULL;
453 for (ptr=CheckArray,count=CheckSize,ascii=0 ; count-- ; ptr++)
455 if (ASCIITable[*ptr])
456 ascii++;
457 else
459 if (BinaryTable[*ptr])
461 ascii=0;
462 break;
467 D(bug("[ExamineData] ASCII characters: %u of %u\n", ascii, CheckSize));
468 if (ascii > CheckSize*3/4)
470 D(bug("[ExamineData] Recognized as ASCII\n"));
471 D(type = DTF_ASCII);
472 cdt_asc = FindDtInList(DataTypesBase, dthc, &getDTLIST->dtl_ASCIIList, CheckArray, CheckSize, Filename);
473 D(bug("[ExamineData] ASCII datatype: 0x%p\n", cdt_asc));
474 cdt = cdt_asc;
475 /* if the found datatype is 'only' ascii we have to look additionally in the binary list */
476 if (cdt_asc && !strcmp(cdt_asc->DTH.dth_Name, "ascii"))
478 D(bug("[ExamineData] Trying binary list\n"));
479 cdt_bin = FindDtInList(DataTypesBase, dthc, &getDTLIST->dtl_BinaryList, CheckArray, CheckSize, Filename);
480 D(bug("[[ExamineData] Binary datatype: 0x%p\n"));
481 /* if we find in the binary list something which is better than just 'binary' we use it */
482 if (cdt_bin && strcmp(cdt_bin->DTH.dth_Name, "binary"))
484 cdt = cdt_bin;
488 else
490 D(bug("[ExamineData] Recognized as binary\n"));
491 D(type = DTF_BINARY);
492 cdt = FindDtInList(DataTypesBase, dthc, &getDTLIST->dtl_BinaryList, CheckArray, CheckSize, Filename);
496 D(bug("[ExamineData] Found datatype 0x%p, type 0x%u\n", cdt, type));
497 return cdt;
501 #undef getDTLIST
504 /* Putchar procedure needed by RawDoFmt() */
506 AROS_UFH2(void, putchr,
507 AROS_UFHA(UBYTE, chr, D0),
508 AROS_UFHA(STRPTR *, p, A3))
510 AROS_USERFUNC_INIT
511 *(*p)++=chr;
512 AROS_USERFUNC_EXIT
516 /* FIXME: these work only with stack growing downwards and should therefore be fixed to use macros in utility/tagitem.h */
518 ULONG setattrs(struct Library *DataTypesBase, Object *object, Tag firstTag,...)
520 AROS_SLOWSTACKTAGS_PRE_AS(firstTag, ULONG)
521 retval = SetAttrsA(object, (struct TagItem *)&firstTag);
522 AROS_SLOWSTACKTAGS_POST
525 ULONG Do_OM_NOTIFY(struct Library *DataTypesBase, Object *object,
526 struct GadgetInfo *ginfo, ULONG flags, Tag firstTag,...)
528 /* struct opUpdate opu;
530 opu.MethodID = OM_NOTIFY;
531 opu.opu_AttrList = (struct TagItem *)&firstTag;
532 opu.opu_GInfo = ginfo;
533 opu.opu_Flags = flags;
535 return DoMethodA(object, (Msg)&opu); */
537 AROS_SLOWSTACKTAGS_PRE_AS(firstTag, ULONG)
538 retval = DoMethod(object, OM_NOTIFY, (IPTR)AROS_SLOWSTACKTAGS_ARG(firstTag), (IPTR)ginfo, (IPTR)flags);
539 AROS_SLOWSTACKTAGS_POST
543 ULONG DoGad_OM_NOTIFY(struct Library *DataTypesBase, Object *object,
544 struct Window *win, struct Requester *req,
545 ULONG flags, Tag firstTag, ...)
547 // return(dogadgetmethod(DataTypesBase, (struct Gadget*)object, win, req, OM_NOTIFY,
548 // &firstTag, NULL, flags));
549 AROS_SLOWSTACKTAGS_PRE_AS(firstTag, ULONG)
550 retval = DoGadgetMethod((struct Gadget*)object, win, req, OM_NOTIFY, AROS_SLOWSTACKTAGS_ARG(firstTag), NULL, flags);
551 AROS_SLOWSTACKTAGS_POST
555 //ULONG dogadgetmethod(struct Library *DataTypesBase, struct Gadget *gad,
556 // struct Window *win, struct Requester *req,
557 // ULONG MethodID, ...)
559 // return(DoGadgetMethodA(gad, win, req, (Msg)&MethodID));
562 struct Catalog *opencatalog(struct Library *DataTypesBase, struct Locale *locale,
563 STRPTR name, Tag firstTag, ...)
565 // return(OpenCatalogA(locale, name, (struct TagItem *)&firstTag));
566 AROS_SLOWSTACKTAGS_PRE_AS(firstTag, struct Catalog *)
567 retval = OpenCatalogA(locale, name, AROS_SLOWSTACKTAGS_ARG(firstTag));
568 AROS_SLOWSTACKTAGS_POST