static void AddWriter ( struct AHIRequest *ioreq, struct AHIDevUnit *iounit, struct AHIBase *AHIBase ) { int channel; // Search for a free channel, and use if found for(channel = 0; channel < iounit->Channels; channel++) { if(iounit->Voices[channel].NextOffset == (ULONG) FREE) { Enqueue((struct List *) &iounit->PlayingList,(struct Node *) ioreq); PlayRequest(channel, ioreq, iounit, AHIBase); break; } } if(channel == iounit->Channels) { struct AHIRequest *ioreq2; // No free channel found. Check if we can kick the last one out... // There is at least on node in the list, and the last one has lowest priority. ioreq2 = (struct AHIRequest *) iounit->PlayingList.mlh_TailPred; if(ioreq->ahir_Std.io_Message.mn_Node.ln_Pri > ioreq2->ahir_Std.io_Message.mn_Node.ln_Pri) { // Let's steal his place! RemTail((struct List *) &iounit->PlayingList); channel = GetExtras(ioreq2)->Channel; GetExtras(ioreq2)->Channel = NOCHANNEL; Enqueue((struct List *) &iounit->SilentList,(struct Node *) ioreq2); Enqueue((struct List *) &iounit->PlayingList,(struct Node *) ioreq); PlayRequest(channel, ioreq, iounit, AHIBase); } else { // Let's be quiet for a while. GetExtras(ioreq)->Channel = NOCHANNEL; Enqueue((struct List *) &iounit->SilentList,(struct Node *) ioreq); } } }
ULONG POPUPMENU_DISPOSE_Gadget(piClass *cl,piObject *o,Msg msg) { struct TagItem *ti; struct List *l; struct Node *n; piGetAttr(o,GAOBJ_Tags,(ULONG *)&ti); l=(struct List *)FindTagItem(PUMG_Labels,ti)->ti_Data; while(n=RemTail(l)) { if(n->ln_Name) MyFreeVec(n->ln_Name); MyFreeVec(n); } MyFreeVec(l); return piDoSuperMethodA(cl,o,msg); }
BOOL ReadStruct ( /* SYNOPSIS */ struct Hook * hook, APTR * dataptr, void * stream, const IPTR * sd) /* FUNCTION Reads one big endian structure from a streamhook. INPUTS hook - Streamhook dataptr - Put the data here stream - Read from this stream sd - Description of the structure to be read. The first element is the size of the structure. RESULT The function returns TRUE on success. On success, the value read is written into dataptr. On failure, FALSE is returned and the contents of dataptr are not changed. NOTES This function reads big endian values from a streamhook even on little endian machines. EXAMPLE See below. BUGS SEE ALSO ReadByte(), ReadWord(), ReadLong(), ReadFloat(), ReadDouble(), ReadString(), ReadStruct(), WriteByte(), WriteWord(), WriteLong(), WriteFloat(), WriteDouble(), WriteString(), WriteStruct() HISTORY ******************************************************************************/ { struct MinList _list; struct ReadLevel * curr; # define list ((struct List *)&_list) NEWLIST(list); if (!(curr = AllocMem (sizeof (struct ReadLevel), MEMF_ANY)) ) return FALSE; AddTail (list, (struct Node *)curr); curr->sd = sd; curr->pos = 0; curr->s = NULL; # define DESC curr->sd[curr->pos] # define IDESC curr->sd[curr->pos ++] for (;;) { if (!curr->pos) { if (!(curr->s = AllocMem (IDESC, MEMF_CLEAR)) ) goto error; } if (DESC == SDT_END) break; switch (IDESC) { case SDT_UBYTE: /* Read one 8bit byte */ if (!ReadByte (hook, (UBYTE *)(curr->s + IDESC), stream)) goto error; break; case SDT_UWORD: /* Read one 16bit word */ if (!ReadWord (hook, (UWORD *)(curr->s + IDESC), stream)) goto error; break; case SDT_ULONG: /* Read one 32bit long */ if (!ReadLong (hook, (ULONG *)(curr->s + IDESC), stream)) goto error; break; case SDT_FLOAT: /* Read one 32bit IEEE */ if (!ReadFloat (hook, (FLOAT *)(curr->s + IDESC), stream)) goto error; break; case SDT_DOUBLE: /* Read one 64bit IEEE */ if (!ReadDouble (hook, (DOUBLE *)(curr->s + IDESC), stream)) goto error; break; case SDT_STRING: { /* Read a string */ UBYTE valid_ptr; STRPTR * sptr; sptr = (STRPTR *)(curr->s + IDESC); if (!ReadByte (hook, &valid_ptr, stream)) goto error; if (valid_ptr) { if (!ReadString (hook, sptr, stream)) goto error; } else { *sptr = NULL; } break; } case SDT_STRUCT: { /* Read a structure */ struct ReadLevel * next; IPTR * desc; APTR aptr; aptr = (APTR)(curr->s + IDESC); desc = (IPTR *)IDESC; curr->pos -= 3; /* Go back to type */ if (!(next = AllocMem (sizeof (struct ReadLevel), MEMF_ANY)) ) goto error; AddTail (list, (struct Node *)next); next->sd = desc; next->pos = 1; next->s = aptr; curr = next; break; } case SDT_PTR: { /* Follow a pointer */ struct ReadLevel * next; UBYTE valid_ptr; IPTR * desc; APTR * aptr; aptr = ((APTR *)(curr->s + IDESC)); desc = (IPTR *)IDESC; if (!ReadByte (hook, &valid_ptr, stream)) goto error; if (valid_ptr) { curr->pos -= 3; if (!(next = AllocMem (sizeof (struct ReadLevel), MEMF_ANY)) ) goto error; AddTail (list, (struct Node *)next); next->sd = desc; next->pos = 0; curr = next; } else { *aptr = NULL; } break; } case SDT_IGNORE: { /* Ignore x bytes */ struct BEIOM_Ignore ig = {BEIO_IGNORE, IDESC}; if (CallHookA (hook, stream, &ig) == EOF) goto error; break; } case SDT_FILL_BYTE: { /* Fill x bytes */ IPTR offset; UBYTE value; IPTR count; offset = IDESC; value = IDESC; count = IDESC; memset (curr->s + offset, value, count); break; } case SDT_FILL_LONG: { /* Fill x longs */ ULONG * ulptr; ULONG value; IPTR count; ulptr = (ULONG *)(curr->s + IDESC); value = IDESC; count = IDESC; while (count --) *ulptr ++ = value; break; } case SDT_IFILL_BYTE: { /* Fill x bytes */ IPTR offset; UBYTE value; IPTR count; offset = IDESC; value = IDESC; count = IDESC; struct BEIOM_Ignore ig = {BEIO_IGNORE, count}; if (CallHookA (hook, stream, &ig) == EOF) goto error; memset (curr->s + offset, value, count); break; } case SDT_IFILL_LONG: { /* Fill x longs */ ULONG * ulptr; ULONG value; IPTR count; ulptr = (ULONG *)(curr->s + IDESC); value = IDESC; count = IDESC; struct BEIOM_Ignore ig = {BEIO_IGNORE, count << 2}; if (CallHookA (hook, stream, &ig) == EOF) goto error; while (count --) *ulptr ++ = value; break; } case SDT_SPECIAL: { /* Call user hook */ struct Hook * uhook; struct SDData data; data.sdd_Dest = ((APTR)(curr->s + IDESC)); data.sdd_Mode = SDV_SPECIALMODE_READ; data.sdd_Stream = stream; uhook = (struct Hook *)IDESC; if (!CallHookA (uhook, hook, &data)) goto error; break; } default: goto error; } /* switch */ /* End of the description list ? */ if (DESC == SDT_END) { struct ReadLevel * last; /* Remove the current level */ last = curr; Remove ((struct Node *)last); /* Get the last level */ if ((curr = (struct ReadLevel *)GetTail (list))) { switch (IDESC) { case SDT_STRUCT: curr->pos += 2; /* Skip 2 parameters */ break; case SDT_PTR: { APTR * aptr; aptr = ((APTR *)(curr->s + IDESC)); curr->pos ++; /* Skip description parameter */ /* Now put the result of the current level in the struct of the previous level. */ *aptr = last->s; break; } } FreeMem (last, sizeof (struct ReadLevel)); } else { curr = last; } } } /* while */ *dataptr = curr->s; FreeMem (curr, sizeof (struct ReadLevel)); return TRUE; error: curr = (struct ReadLevel *)GetHead (list); if (curr && curr->s) FreeStruct (curr->s, curr->sd); while ((curr = (struct ReadLevel *)RemTail (list))) FreeMem (curr, sizeof (struct ReadLevel)); return FALSE; } /* ReadStruct */