.
It was quick, dirty and nasty but it works a treat for reading and writing parameters off an SD card. At least it may be a useful jumping off point.
Code: Select all
{
*****************************************************************************
* Name : FileWriter.BAS *
* Author : Rangerbob *
* Notice : Copyright (c) 2011 *
* : All Rights Reserved *
* Date : 02/09/2011 *
* Version : 1.0 *
* Notes : SD card must *
* : be mounted first before calling functions. *
* : Reads and writes a simplied XML structure and debug
*****************************************************************************
}
Module File
Include "String.bas"
Include "Convert.bas"
Include "SDFileSystem.bas"
Dim XMLString As String(200)
Dim Header As String(15)
Const Tab = $09 ' Tab
{
********************************************************************************
* Name : XMLWriteParam *
* Purpose : Writes the given string to the parameter in the declared file. *
* Note : "XML" is used here as a loose term! *
********************************************************************************
}
Public Function XMLWriteParam(pFileName As String, pParam As String, pPayload As String) As Byte
// Note:
// Due to limitations of the PIC/SD system, the easiest way for this to work is to
// create a new file to work on, stream across the old file line by line until reaching paramter to be adjusted.
// If not found, append to end. Then rename old file to backup and name new file to current.
// Also prevents corruption of the original file if the proceedure is interrupted for any reason.
Dim index As Byte
Dim i As Byte
Dim TestByte As Byte
Dim InString As Boolean
Dim FoundTarget As Boolean
Dim Source As TSDName
result = null
FoundTarget = False
index = SD.OpenFile(0,pFileName)
// Found Source file ok, no problem, otherwise will return error
If index = errOK Then
// Create the new file to modify
Repeat
index = SD.NewFile(1,"modify.bak")
If index = errExists Then // if there is already a file, it blocks - can happen due to crash/interruption
SD.DeleteFile("modify.bak")
EndIf
Until index = errOK
If index = errOK Then
Repeat
// Put line from file into memory
index = 0
Repeat
TestByte = SD.ReadByte(0)
If index < SizeOf(XMLString) Then
XMLString(index) = TestByte
Inc(index)
EndIf
Until SD.EOF(0) Or TestByte = 10
XMLString(index) = null
// Search line for header, extract into Header string
index = 0
i = 0
InString = false
Repeat
If XMLString(index) = "<" Then // Find start of header string
InString = true
EndIf
If InString = true Then
If i < SizeOf(Header) Then // Stop buffer overflow
Header(i) = XMLString(index)
Inc(i)
EndIf
EndIf
Inc(index)
Until XMLString(index -1)= null Or XMLString(index -1) = ">"
Header(i) = null
Header = Uppercase(Header)
// Check if target header
If Compare(Header,Uppercase(pParam)) = 0 Then
//It is our target: lazy, memory efficient way, recreate entire line rather than modify existing
SD.Write(1, pParam)
SD.Write(1, pPayload)
Insert("/", pParam, 1)
SD.Write(1, pParam)
SD.Write(1,13)
SD.Write(1,10)
FoundTarget = true
Else
// Write out line as is
index = 0
While XMLString(index) <> null
SD.Write(1, XMLString(index))
Inc(index)
Wend
EndIf
Until SD.EOF(0)
// Parameter does not exist in file, append to end
If foundtarget = false Then
SD.Write(1,13)
SD.Write(1,10)
SD.Write(1,pParam) // Write param name
SD.Write(1,pPayload) // write payload
Insert("/", pParam, 1) // insert param closing slash
SD.Write(1,pParam) // write param close
SD.Write(1,13)
SD.Write(1,10)
EndIf
SD.CloseFile(0)
SD.CloseFile(1)
// Rename and replace
// Using TSD structure to work around bug in rename
If result = errOK Then
SD.DeleteFile(pFileName)
Source.Name = "MODIFY"
Source.extension = "BAK"
result = SD.Rename(Source, pFileName, sdFile)
EndIf
EndIf
SD.CloseFile(0)
EndIf
End Function
{
********************************************************************************
* Name : XMLReadParam *
* Purpose : Writes the given string to the parameter in the declared file. *
********************************************************************************
}
Public Function XMLReadParam(pFileNumber As ShortInt, pFileName As String, pString As String) As String
Dim XMLString As String(15)
Dim Payload As String(20)
Dim index As Byte
Dim InString As Boolean
Dim FoundTarget As Boolean
result = null
FoundTarget = False
// Open the file
index = SD.OpenFile(pFileNumber,pFileName)
// Found file ok, no problem, otherwise will return error
If index = errOK Then
Repeat
// Find XML Header
InString = false
index = 0
Repeat
XMLString(index) = SD.ReadByte(pFileNumber)
If XMLString(index) = "<" Then // Find start of param string header
InString = true
EndIf
If InString = true Then
If index < SizeOf(XMLString) Then // Stop buffer overflow
Inc(index)
Else
XMLString(index - 1) = ">"
EndIf
EndIf
Until SD.EOF(pFileNumber) Or XMLString(index - 1) = ">"
// Pull out data
If SD.EOF(pFileNumber) = false Then
XMLString(index) = NULL // terminate string
XMLString = Uppercase(XMLString)
// Is it our target?
pString = Uppercase(pString)
// Pull out payload
If Compare(XMLString,pString) = 0 Then
index = 0
Repeat
Payload(index) = SD.ReadByte(pFileNumber)
Inc(index)
Until SD.EOF(pFileNumber) Or Payload(index - 1) = "<"
Payload(index - 1) = null
result = Payload
FoundTarget = true
EndIf
EndIf
Until SD.EOF(pFileNumber) Or FoundTarget = true
SD.CloseFile(pFileNumber)
EndIf
End Function
{
********************************************************************************
* Name : PrintDebug *
* Purpose : Writes a debug string to file "Debug.log" *
* Note : Cannot call during a file 1 read / write operation! *
********************************************************************************
}
Public Function PrintDebug(pFileNumber As ShortInt, pDebugString As String) As Byte
// Open File for Writing
result = SD.AppendFile(pFileNumber,"Debug.log")
If result = errNotFound Then
result = SD.NewFile(pFileNumber,"Debug.log")
SD.Write(pFileNumber, "> No debug log found, starting new file", 13, 10)
EndIf
If result = errOK Then
SD.Write(pFileNumber, "> ", pDebugString, 13, 10)
SD.CloseFile(pFileNumber)
EndIf
End Function
{
********************************************************************************
* Name : CreateSettings *
* Purpose : Creates a default settings.xml file *
* Note : *
********************************************************************************
}
Public Function CreateSettings(pFileNumber As ShortInt,pFileName As String) As Byte
result = SD.NewFile(pFileNumber,pFileName)
If result = errOK Then // Write out header
SD.Write(pFileNumber, "// Reverse Geocache Settings.xml file", 13, 10)
SD.Write(pFileNumber, "// Edit me to make changes! Do not touch comments or headings (<heading>)", 13, 10)
SD.Write(pFileNumber, 13, 10)
SD.Write(pFileNumber, "// This is the name the box will use to greet the player", 13, 10)
SD.Write(pFileNumber, "<Greetname>Player</Greetname>", 13, 10)
SD.Write(pFileNumber, 13, 10)
SD.Write(pFileNumber, "// Number of Attempts to open the box remaining to the player", 13, 10)
SD.Write(pFileNumber, "<Attempts>50</Attempts>", 13, 10)
SD.Write(pFileNumber, 13, 10)
SD.Write(pFileNumber, "// Targets must be entered in order, last (Target0) to first (TargetN)", 13, 10)
SD.Write(pFileNumber, "// Co-ordinates should be entered in Decimal degrees (dd.dddd and ddd.dddd)", 13, 10)
SD.Write(pFileNumber, "<Target0>01.1234,567.8910</Target>", 13, 10)
SD.Write(pFileNumber, "<Target1>01.1234,567.8910</Target>", 13, 10)
SD.Write(pFileNumber, "<Target2>01.1234,567.8910</Target>", 13, 10)
SD.Write(pFileNumber, 13, 10)
SD.Write(pFileNumber, "// Current Target to find", 13, 10)
SD.Write(pFileNumber, "<Current>2</Current>", 13, 10)
SD.Write(pFileNumber, 13, 10)
SD.Write(pFileNumber, "// Precision needed to call a target solved", 13, 10)
SD.Write(pFileNumber, "// Default 500. Do not set to less than 500!", 13, 10)
SD.Write(pFileNumber, "<Precision>500</Precision>", 13, 10)
SD.Write(pFileNumber, 13, 10)
SD.Write(pFileNumber, "// Set this parameter to true on first running to box to ensure", 13, 10)
SD.Write(pFileNumber, "// first line from taunts file is used. Usually an introduction for user.", 13, 10)
SD.Write(pFileNumber, "// Will automatically be set to false once the first message has been displayed.", 13, 10)
SD.Write(pFileNumber, "<Firstrun>true</Firstrun>", 13, 10)
SD.Write(pFileNumber, 13, 10)
SD.Write(pFileNumber, "// User Password. Set this to something memorable so you can", 13, 10)
SD.Write(pFileNumber, "// Override the box via USB if necessary!", 13, 10)
SD.Write(pFileNumber, "<Password>TEST</Password>", 13, 10)
SD.Write(pFileNumber, 13, 10)
SD.Write(pFileNumber, "// Unlock the Box? Set to true if the box is solved", 13, 10)
SD.Write(pFileNumber, "// Delete me or set to false to lock box and start puzzle", 13, 10)
SD.Write(pFileNumber, "<Unlock>true</Unlock>", 13, 10)
SD.CloseFile(pFileNumber)
result = errOK
EndIf
End Function