Cross-platform INI read/write procedures!

Share your advanced PureBasic knowledge/code with the community.
dracflamloc
Addict
Addict
Posts: 1648
Joined: Mon Sep 20, 2004 3:52 pm
Contact:

Cross-platform INI read/write procedures!

Post 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  
Last edited by dracflamloc on Mon Mar 20, 2006 11:17 pm, edited 2 times in total.
Beach
Enthusiast
Enthusiast
Posts: 677
Joined: Mon Feb 02, 2004 3:16 am
Location: Beyond the sun...

Post by Beach »

Good stuff, thanks!
-Beach
dracflamloc
Addict
Addict
Posts: 1648
Joined: Mon Sep 20, 2004 3:52 pm
Contact:

Post by dracflamloc »

Np, make sure you get the edited version of WriteString up there. I found a slight bug.
Shannara
Addict
Addict
Posts: 1808
Joined: Thu Oct 30, 2003 11:19 pm
Location: Emerald Cove, Unformed

Post 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
dracflamloc
Addict
Addict
Posts: 1648
Joined: Mon Sep 20, 2004 3:52 pm
Contact:

Post by dracflamloc »

Cool. By the way this code works in any OS not just Linux.
Shannara
Addict
Addict
Posts: 1808
Joined: Thu Oct 30, 2003 11:19 pm
Location: Emerald Cove, Unformed

Post 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 ;)
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Post 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
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
dracflamloc
Addict
Addict
Posts: 1648
Joined: Mon Sep 20, 2004 3:52 pm
Contact:

Post 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.
Shannara
Addict
Addict
Posts: 1808
Joined: Thu Oct 30, 2003 11:19 pm
Location: Emerald Cove, Unformed

Post 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 :)
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Post by ts-soft »

ReadMe.html Beta4 wrote:added : ability to add/change/delete keys to existing prefs files.
At time, windows only, okay
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
dracflamloc
Addict
Addict
Posts: 1648
Joined: Mon Sep 20, 2004 3:52 pm
Contact:

Post by dracflamloc »

Thats good. Didnt read about pb4 much yet
Post Reply