A Node structure is divided into three parts: linkage, information, and content. The linkage part contains memory pointers to the node's successor and predecessor nodes. The information part contains the node type, the priority, and a name pointer. The content part stores the actual data structure of interest.
For nodes that require linkage only, a small MinListNode& structure is used: DefSTRUCTURE MinListNode&, 0& DefGPMPTR mln_Succ& DefGPMPTR mln_Pred& DefLABEL MinListNode_SizeOf& mln_Succ& points to the next node in the list (successor) mln_Pred& points to the previous node in the list (predecessor)
When a type, priority, or name is required, a full-featured ListNode& structure is used: DefSTRUCTURE ListNode&, 0& DefGPMPTR ln_Succ& DefGPMPTR ln_Pred& DefUBYTE ln_Type& DefBYTE ln_Pri& DefGPMSTR ln_Name& DefLABEL ListNode_SizeOf& ln_Succ& points to the next node in the list (successor) ln_Pred& points to the previous node in the list (predecessor) ln_Type& defines the type of the node ("NT_" types) ln_Pri& specifies the priority of the node (+127 (highest) to -128 (lowest)) ln_Name& points to a printable name for the node (a zero terminated string)
The MinListNode& and/or ListNode& structures are often incorporated into larger structures, so groups of the larger structures can easily be linked together. For example, an addressbook entry could be defined as follows: DefSTRUCTURE Person&,MinListNode_SizeOf& 'the carrier MinListNode& for content data DefGPMSTR p_FirstName& DefGPMSTR p_LastName& DefGPMSTR p_Street& DefGPMSTR p_City& DefULONG p_ZIP& DefGPMSTR p_State& DefGPMSTR p_Phone& DefGPMSTR p_Fax& DefLABEL p_SizeOf& Here the p_FirstName& to p_Fax& fields represent the useful content of the node. Because the Person& structure begins with a (Min)ListNode& structure, it may directly be passed to any of the list handling SUBs and FUNCTIONs in place of the required node argument. Before linking a node into a list, certain fields may need initialization. Initialization consists of setting the ln_Type&, ln_Pri&, and ln_Name& fields to their appropriate values (A MinListNode& structure does not have these fields). The successor and predecessor fields do not require initialization.
Description of all fields and its possible initialization values: The ln_Type& field contains the data type of the node. This indicates the type, and hence the structure, of the content portion of the node (the extra data after the ListNode& structure). The standard types are defined in the lists.bi include file. If you do not need a type, but just a priority and/or name, then initialize the type field to NT_UNKNOWN& (zero). The ln_Pri& field uses a signed numerical value ranging from +127 to -128 to indicate the priority of the node. Higher-priority nodes have greater values: for example, 127 is the highest priority, zero is nominal priority, and -128 is the lowest priority. Some lists may need to be kept sorted by priority order. In such lists, the highest-priority node is at the head of the list, and the lowest-priority node is at the tail of the list. If you do not need a priority, but just a type and/or name, then initialize the priority field to zero. The ln_Name& field is a pointer to a zero terminated string of characters. Node names are used to find and identify list-bound objects, and to bind symbolic names to actual nodes. Names are also useful for debugging. Take care to provide a valid name pointer, best one created with the FUNCTION CreateGPMString&, which is part of the memory.bm include file. Don't use a VARPTR pointer of a QB64 string variable here, first regular strings are not usually zero terminated and second these pointers may get invalid at any time due to the internal operations of QB64. If you do not need a name, but just a type and/or priority, then initialize the name field to zero, but note in this case the node can never be found using the FUNCTION FindName& from the lists.bm include file. This code fragment shows the initialization of a ListNode& structure: np& = CreateGPMString&("sample.node") IF np& = 0 THEN PRINT "not enough memory for node name..." ' 'you must handle this situation ' ELSE PokeB node&, ln_Type&, NT_...& PokeB node&, ln_Pri&, -10& PokeL node&, ln_Name&, np& END IF Whenever you unlink and free a named node initialized this way, then always make sure to dispose the created name string prior to freeing the memory occupied by the node structure itself: first: DisposeGPMString PeekL&(node&, ln_Name&) then: _ FreeGPMVec node& \ depends on the used or: / allocation method FreeGPMem node&, size& / Back to List Overview