Page 1 of 1

Cross-platform INI read/write procedures!

Posted: Thu Mar 24, 2005 6:06 pm
by dracflamloc
Code updated For 5.20+

[Edit] Found a slight bug in WriteString. Fixed. (Wasnt checking if sec2pos was 0)

These aren't the most efficient and they could be optimized a lot but they work, and you don't have to read in every key and rewrite them like you do with the builtin Preferences library. If you improve upon this code you must post the changes here, thats all I ask.

Code: Select all

;INI PROCEDURES
Procedure Pref_WriteString(Section.s,Key.s,Value.s,FileName.s)
  ;Equivalent of WritePrivateProfileString_ (Section, Key, Value,FileName) Win32 API
  fid=ReadFile(#PB_Any,FileName)
  fileout.s=""
  If IsFile(fid)
    While Eof(fid)=0
      fileout.s=fileout.s+ReadString(fid)+Chr(13)+Chr(10)
    Wend
    CloseFile(fid)
  EndIf
  
  secpos=FindString(fileout,"["+Section+"]",1)
  sec2pos=FindString(fileout,"[",secpos+Len(Section))
  If sec2pos=0
    sec2pos=Len(fileout)+1
  EndIf
  If secpos>0
    varpos=FindString(fileout,Chr(10)+Key,secpos)
    If varpos=0
      varpos=FindString(fileout,Chr(13)+Key,secpos)
    EndIf
    
    If varpos>0 And varpos<sec2pos
      leftstr.s=Left(fileout,varpos+1+Len(Key))
      nlpos=FindString(fileout,Chr(13),varpos+1)
      If nlpos=0
        nlpos=Len(fileout)
      EndIf
      rightstr.s=Right(fileout,Len(fileout)-nlpos)
      ;recombine
      fileout=leftstr+value+rightstr
    Else
      leftstr.s=Left(fileout,secpos+2+Len(Section))
      rightstr.s=Right(fileout,Len(fileout)-secpos-Len(Section)-2)
      If Left(rightstr,1)<>Chr(13) And Left(rightstr,1)<>Chr(10)
        fileout=leftstr+Key+"="+Value+Chr(13)+Chr(10)+rightstr
      Else
        fileout=leftstr+Key+"="+Value+rightstr
      EndIf
    EndIf
  Else
    fileout=fileout+Chr(13)+Chr(10)+"["+Section+"]"+Chr(13)+Chr(10)
    fileout=fileout+Key+"="+Value
  EndIf
  
  fid=CreateFile(#PB_Any,FileName)
  If fid>0
    While Right(fileout,1)=Chr(13) Or Right(fileout,1)=Chr(10)
      fileout=Left(fileout,Len(fileout)-1)
    Wend
    WriteString(fid,Trim(fileout))
    CloseFile(fid)
  EndIf
  
EndProcedure

Procedure.s Pref_ReadString(Section.s,Key.s,FileName.s)
  Value.s = ""
  ;Equivalent of GetPrivateProfileString_ (Section, Key, "", Value, Len(Value), FileName) Win32 API
  fid=ReadFile(#PB_Any,FileName)
  If IsFile(fid)
    While Eof(fid)=0
      mystr.s=ReadString(fid)
      If FindString(mystr,"["+Section+"]",1)>0
        While Eof(fid)=0
          mystr=ReadString(fid)
          If Left(mystr,1)="["
            Break 2
          EndIf
          If Left(mystr,Len(Key))=Key
            Value.s=Right(mystr,Len(mystr)-Len(Key)-1)
            Break 2
          EndIf
        Wend
      EndIf
    Wend
  EndIf
  
  ProcedureReturn Value.s
EndProcedure  

Posted: Thu Mar 24, 2005 6:19 pm
by Beach
Good stuff, thanks!

Posted: Thu Mar 24, 2005 6:26 pm
by dracflamloc
Np, make sure you get the edited version of WriteString up there. I found a slight bug.

Posted: Mon Mar 20, 2006 11:12 pm
by Shannara
4.0 version below

Code: Select all

;INI PROCEDURES
Procedure Pref_WriteString(Section.s,Key.s,Value.s,FileName.s)
  ;Equivalent of WritePrivateProfileString_ (Section, Key, Value,FileName) Win32 API
  fid=ReadFile(#PB_Any,FileName)
  fileout.s=""
  If IsFile(fid)
    While Eof(fid)=0
      fileout.s=fileout.s+ReadString(fid)+Chr(13)+Chr(10)
    Wend
    CloseFile(fid)
  EndIf
  
  secpos=FindString(fileout,"["+Section+"]",1)
  sec2pos=FindString(fileout,"[",secpos+Len(Section))
  If sec2pos=0
    sec2pos=Len(fileout)+1
  EndIf
  If secpos>0
    varpos=FindString(fileout,Chr(10)+Key,secpos)
    If varpos=0
      varpos=FindString(fileout,Chr(13)+Key,secpos)
    EndIf
    
    If varpos>0 And varpos<sec2pos
      leftstr.s=Left(fileout,varpos+1+Len(Key))
      nlpos=FindString(fileout,Chr(13),varpos+1)
      If nlpos=0
        nlpos=Len(fileout)
      EndIf
      rightstr.s=Right(fileout,Len(fileout)-nlpos)
      ;recombine
      fileout=leftstr+Value+rightstr
    Else
      leftstr.s=Left(fileout,secpos+2+Len(Section))
      rightstr.s=Right(fileout,Len(fileout)-secpos-Len(Section)-2)
      If Left(rightstr,1)<>Chr(13) And Left(rightstr,1)<>Chr(10)
        fileout=leftstr+Key+"="+Value+Chr(13)+Chr(10)+rightstr
      Else
        fileout=leftstr+Key+"="+Value+rightstr
      EndIf
    EndIf
  Else
    fileout=fileout+Chr(13)+Chr(10)+"["+Section+"]"+Chr(13)+Chr(10)
    fileout=fileout+Key+"="+Value
  EndIf
  
  fid=CreateFile(#PB_Any,FileName)
  If fid>0
    While Right(fileout,1)=Chr(13) Or Right(fileout,1)=Chr(10)
      fileout=Left(fileout,Len(fileout)-1)
    Wend
    WriteString(fid,Trim(fileout))
    CloseFile(fid)
  EndIf
  
EndProcedure

Procedure.s Pref_ReadString(Section.s,Key.s,FileName.s)
  Value.s = ""
  ;Equivalent of GetPrivateProfileString_ (Section, Key, "", Value, Len(Value), FileName) Win32 API
  fid=ReadFile(#PB_Any,FileName)
  If IsFile(fid)
    While Eof(fid)=0
      mystr.s=ReadString(fid)
      If FindString(mystr,"["+Section+"]",1)>0
        While Eof(fid)=0
          mystr=ReadString(fid)
          If Left(mystr,1)="["
            Break 2
          EndIf
          If Left(mystr,Len(Key))=Key
            Value.s=Right(mystr,Len(mystr)-Len(Key)-1)
            Break 2
          EndIf
        Wend
      EndIf
    Wend
  EndIf
  
  ProcedureReturn Value.s
EndProcedure

Posted: Mon Mar 20, 2006 11:13 pm
by dracflamloc
Cool. By the way this code works in any OS not just Linux.

Posted: Fri Mar 24, 2006 12:49 am
by Shannara
It looks like only two people uses this code, dracflamloc and myself. I found a rather nasty bug and am working on fixing it. Basically, you can read ini files but cannot write to them... ... ouch! At least in the PB4 version. And since nobody reported this bug ... it's just you and I, drac ;)

Posted: Fri Mar 24, 2006 1:05 am
by ts-soft
Why not use the preferences-lib in pb 4?

Code: Select all

Procedure Pref_WriteString(Section.s,Key.s,Value.s,FileName.s)
  If OpenPreferences(FileName)
    PreferenceGroup(Section)
    WritePreferenceString(Key, Value)
    ClosePreferences()
  EndIf
EndProcedure

Procedure.s Pref_ReadString(Section.s,Key.s,FileName.s)
  Protected Result.s
  If OpenPreferences(FileName)
    PreferenceGroup(Section)
    Result = ReadPreferenceString(Key, "")
    ClosePreferences()
  EndIf
  ProcedureReturn Result
EndProcedure

Posted: Fri Mar 24, 2006 2:30 am
by dracflamloc
Preferences lib you need to write every value, you cant just write one at a time. And since I didnt convert the pb4 version I wont touch it until PB4 beta is out for linux. But I know the 3.94 version should work.

Posted: Fri Mar 24, 2006 3:24 am
by Shannara
Exactly what Drac said. At least for myself, Im used to be able to just write a value that I changed. Not having to rewrite the whole INI file everytime I wanted to change just one small value :)

Posted: Fri Mar 24, 2006 3:44 am
by ts-soft
ReadMe.html Beta4 wrote:added : ability to add/change/delete keys to existing prefs files.
At time, windows only, okay

Posted: Fri Mar 24, 2006 5:03 am
by dracflamloc
Thats good. Didnt read about pb4 much yet