; PB 4.0
;**
;* Coded by Remi_Meier@gmx.ch in 2006
; If you want to be a thief, just remove this comment.
Structure FPREFELEM
*prev.FPREFELEM
*next.FPREFELEM
*name ; Ptr to String
*value ; Ptr to Data
EndStructure
Interface iFPref
addData.l(key.s, *mem, len.l) ; Adds data identified with a key
addString.l(key.s, string.s) ; Adds a string to the list
removeData.l(key.s) ; Removes the data identified with the key
getDataPtr.l(key.s) ; Gets a pointer to the data
getString.s(key.s) ; Returns the data as a string, be sure, that Data is a String!
clear.l() ; clears the list
saveToFile.l(file.s) ; Save data list to file
loadFromFile.l(file.s) ; Loads data from file (adds it to the list!)
; Iteration
examineData() ; Starts the iteration through the data pointers
nextData.l() ; Selects next data element, returns 0 if none exists
currentDataPtr.l() ; Returns a pointer to the data in the currently selected element
currentString.s() ; Returns the string of currentDataPtr(), be sure, that Data is a String!
currentKey.s() ; Returns the key of the currently selected element
EndInterface
Structure cFPref
*VT
*listHead.FPREFELEM ; Ptr to ListStart
*currentData.FPREFELEM ; for Iterator
EndStructure
Procedure FPref__freeElement(*this.cFPref, *elem.FPREFELEM)
If *elem
If *elem\Name
FreeMemory(*elem\Name)
EndIf
If *elem\Value
FreeMemory(*elem\Value)
EndIf
FreeMemory(*elem)
EndIf
EndProcedure
Procedure.l FPref__addElement(*this.cFPref, *elem.FPREFELEM)
Protected *list.FPREFELEM, found.l
If Not *elem Or Not *elem\Name
FPref__freeElement(*this, *elem)
Else
If *this\listHead
*list = *this\listHead
found = #False
While *list
If *list\Name And PeekS(*list\Name) = PeekS(*elem\Name)
; Modify Data
If *list\Value : FreeMemory(*list\Value) : EndIf
*list\Value = *elem\Value
found = #True
Break
EndIf
*list = *list\Next
Wend
If found
FreeMemory(*elem\Name)
FreeMemory(*elem)
ProcedureReturn #True
Else
; Else add at start
*elem\Next = *this\listHead
*elem\Prev = 0
*this\listHead\Prev = *elem
*this\listHead = *elem
EndIf
Else
; Else insert at start
*elem\Next = 0
*elem\Prev = 0
*this\listHead = *elem
EndIf
ProcedureReturn #True
EndIf
ProcedureReturn #False
EndProcedure
Procedure.l FPref__removeElement(*this.cFPref, *elem.FPREFELEM)
Protected *list.FPREFELEM
If Not *elem Or Not *elem\name Or Not *this\listHead
FPref__freeElement(*this, *elem)
Else
*list = *this\listHead
While *list
If *list\name And PeekS(*list\name) = PeekS(*elem\name)
; Remove it
If Not *list\Prev
*this\listHead = *list\Next
Else
*list\Prev\Next = *list\Next
EndIf
If *list\Next
*list\Next\Prev = *list\Prev
EndIf
ProcedureReturn #True
EndIf
*list = *list\Next
Wend
EndIf
ProcedureReturn #False
EndProcedure
Procedure.l FPref__createElement(*this.cFPref, key.s, *mem, len.l)
Protected *elem.FPREFELEM
*elem = AllocateMemory(SizeOf(FPREFELEM))
If Not *elem
FPref__freeElement(*this, *elem)
ProcedureReturn #False
EndIf
If Len(key) > 0
*elem\name = AllocateMemory(StringByteLength(key) + SizeOf(CHARACTER))
If Not *elem\name
FPref__freeElement(*this, *elem)
ProcedureReturn #False
EndIf
EndIf
If len > 0 And *mem
*elem\Value = AllocateMemory(len)
If Not *elem\Value
FPref__freeElement(*this, *elem)
ProcedureReturn #False
EndIf
EndIf
If Len(key) > 0
CopyMemory(@key, *elem\name, StringByteLength(key) + SizeOf(CHARACTER))
EndIf
If len > 0 And *mem
CopyMemory(*mem, *elem\Value, len)
EndIf
ProcedureReturn *elem
EndProcedure
;** fpref_addData
;* adds or modifies data of the key.
;** .key: a key to identify the data
;** .*mem: the memory from which to copy
;** .len: len to copy from *mem
Procedure.l FPref_addData(*this.cFPref, key.s, *mem, len.l)
Protected *elem.FPREFELEM
*elem = FPref__createElement(*this, key, *mem, len)
If FPref__addElement(*this, *elem)
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
EndProcedure
;** fpref_addstring
;* a simplyfied version of addData to add a string
Procedure.l FPref_addString(*this.cFPref, key.s, String.s)
ProcedureReturn FPref_addData(*this, key, @String, StringByteLength(String) + SizeOf(CHARACTER))
EndProcedure
;** fpref_removedata
;* removes the element identified by the key
Procedure.l FPref_removeData(*this.cFPref, key.s)
Protected *elem.FPREFELEM
*elem = FPref__createElement(*this, key, 0, 0)
If FPref__removeElement(*this, *elem)
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
EndProcedure
;** fpref_getdataptr
;* returns a pointer to the data of the key
Procedure.l FPref_getDataPtr(*this.cFPref, key.s)
Protected *list.FPREFELEM
If key And *this\listHead
*list = *this\listHead
While *list
If *list\Name And PeekS(*list\Name) = key
ProcedureReturn *list\Value
EndIf
*list = *list\Next
Wend
EndIf
ProcedureReturn #Null
EndProcedure
;** fpref_getstring
;* returns the string identified by the key_
;* simplified version of getdataptr() with PeekS()_
;* Only works if you really saved a string in this key!
Procedure.s FPref_getString(*this.cFPref, key.s)
Protected *mem
*mem = FPref_getDataPtr(*this, key)
If *mem
ProcedureReturn PeekS(*mem)
Else
ProcedureReturn ""
EndIf
EndProcedure
;** fpref_clear: deletes all keys
Procedure.l FPref_clear(*this.cFPref)
Protected *list.FPREFELEM, *nextelem.FPREFELEM
If *this\listHead
*list = *this\listHead
While *list
*nextelem = *list\Next
FPref__freeElement(*this, *list)
*list = *nextelem
Wend
*this\listHead = 0
EndIf
ProcedureReturn #True
EndProcedure
;** fpref_savetofile: saves all keys in the list
;* to a file (binary)
Procedure.l FPref_saveToFile(*this.cFPref, file.s)
Protected fileID.l, *list.FPREFELEM, len.l
fileID = CreateFile(#PB_Any, file)
If IsFile(fileID)
If *this\listHead
*list = *this\listHead
While *list
If *list\name
len = MemorySize(*list\name)
WriteLong(fileID, len)
WriteData(fileID, *list\name, len)
If *list\name
len = MemorySize(*list\Value)
Else
len = 0
EndIf
WriteLong(fileID, len)
If len
WriteData(fileID, *list\Value, len)
EndIf
EndIf
*list = *list\Next
Wend
EndIf
CloseFile(fileID)
ProcedureReturn #True
EndIf
ProcedureReturn #False
EndProcedure
;** fpref_loadfromfile: loads a previously saved list
;* from a file. If the list already contains some
;* keys, they will be overwritten (if the same Key.s used)
;* and the new keys will be added. No keys will be removed!
Procedure.l FPref_loadFromFile(*this.cFPref, file.s)
Protected fileID.l, *elem.FPREFELEM, len.l
fileID = ReadFile(#PB_Any, file)
If IsFile(fileID)
While Not Eof(fileID)
*elem = AllocateMemory(SizeOf(FPREFELEM))
If Not *elem
ProcedureReturn #False
EndIf
len = ReadLong(fileID)
*elem\name = AllocateMemory(len)
If *elem\name
ReadData(fileID, *elem\name, len)
Else
FreeMemory(*elem)
ProcedureReturn #False
EndIf
len = ReadLong(fileID)
If len
*elem\Value = AllocateMemory(len)
If Not *elem\Value
FreeMemory(*elem\name)
FreeMemory(*elem)
ProcedureReturn #False
EndIf
ReadData(fileID, *elem\Value, len)
EndIf
If Not FPref__addElement(*this, *elem)
ProcedureReturn #False
EndIf
Wend
CloseFile(fileID)
ProcedureReturn #True
EndIf
ProcedureReturn #False
EndProcedure
;** fpref_examinedata: Starts examination of all keys in the list
Procedure FPref_examineData(*this.cFPref)
*this\currentData = 0
EndProcedure
;** fpref_nextdata:
;* Goes to the next key (returns 0 if there is none)
Procedure.l FPref_nextData(*this.cFPref)
If *this\currentData = 0
*this\currentData = *this\listHead
Else
*this\currentData = *this\currentData\Next
EndIf
ProcedureReturn *this\currentData
EndProcedure
;** fpref_currentdataptr
;* returns the dataptr of the current element/key
Procedure.l FPref_currentDataPtr(*this.cFPref)
If *this\currentData
ProcedureReturn *this\currentData\Value
Else
ProcedureReturn #False
EndIf
EndProcedure
;** fpref_currentString
;* returns a string of the current element/key.
;* simplified version of currentDataPtr()._
;* Only valid if there is really a string
;* stored in this key!_
;* To be aware of this, you could i. c. add a
;* prefix to all of your keys that identifies
;* of which type the data in this key is. Like:_
;* Key.s = "s CancelButton"
Procedure.s FPref_currentString(*this.cFPref)
Protected *mem
*mem = FPref_currentDataPtr(*this)
If *mem
ProcedureReturn PeekS(*mem)
Else
ProcedureReturn ""
EndIf
EndProcedure
;** fpref_currentkey
;* returns the key/identifier of the current element/key.
Procedure.s FPref_currentKey(*this.cFPref)
If *this\currentData
ProcedureReturn PeekS(*this\currentData\name)
Else
ProcedureReturn ""
EndIf
EndProcedure
DataSection ;[
cFPref_VT:
Data.l @FPref_addData(), @FPref_addString(), @FPref_removeData()
Data.l @FPref_getDataPtr(), @FPref_getString(), @FPref_clear()
Data.l @FPref_saveToFile(), @FPref_loadFromFile(), @FPref_examineData()
Data.l @FPref_nextData(), @FPref_currentDataPtr(), @FPref_currentString()
Data.l @FPref_currentKey()
EndDataSection ;]
Procedure.l new_FPref()
Protected *this.cFPref
*this = AllocateMemory(SizeOf(cFPref))
If *this = 0 : ProcedureReturn 0 : EndIf
*this\vt = ?cFPref_VT
ProcedureReturn *this
EndProcedure
Procedure.l delete_FPref(*this.cFPref)
FPref_clear(*this)
FreeMemory(*this)
EndProcedure
; IDE Options = PureBasic v4.00 (Windows - x86)
; CursorPosition = 4
; FirstLine = 4
; Folding = ----
; EnableXP
; HideErrorLog