Lecture des fichier confs.

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Heis Spiter
Messages : 1092
Inscription : mer. 28/janv./2004 16:22
Localisation : 76
Contact :

Lecture des fichier confs.

Message par Heis Spiter »

Première classe de Bird Chat 3 !!! Qui sera déjà dans le 2, mais bon, c'est pas grave.
Cette classe est très simple, et dérivée du tuto de mon site. Elle permet de lire un fichier conf dans le style de ceux d'Apache (j'ai même pas testé la classe dessus). Elle lit tout. Même les commentaires. Et les valeurs des paramêtres sont changeables. Et j'ai prévu d'ajouter les fonctions pour rajouter un paramêtre, et changer un commentaire.
Bon, assez de blabla, le code !

Code : Tout sélectionner

;- Class Conf
Interface Conf
  Conf_init(file.s)
  Conf_read()
  Conf_getlistparams(out.l)
  Conf_getvalue(param.s, def.s, out.l)
  Conf_getcomm(param.s, out.l)
  Conf_setvalue(param.s, value.s)
  Conf_addvalue(param.s, value.s, comm.s, pos.l)
  Conf_update()
  Conf_free()
EndInterface

Structure Conf_Functions
  Conf_init.l
  Conf_read.l
  Conf_getlistparams.l
  Conf_getvalue.l
  Conf_getcomm.l
  Conf_setvalue.l
  Conf_addvalue.l
  Conf_update.l
  Conf_free.l
EndStructure

Structure Conf_Vars
  *VirtualTable.Conf_Functions
  ID.l
  file.s
EndStructure

Structure Conf_Params
  ID.l
  line.l
  param.s
  value.s
  comm.s
EndStructure
NewList Conf_Params.Conf_Params()

Procedure Conf_read(*this.Conf_Vars)

  succes = 0
  ID = OpenFile(#PB_Any, *this\file)
  *this\ID = ID
  If ID
    Repeat
      ligne.s = ReadString()
      If Left(ligne, 1) <> "#"
        space = FindString(ligne, " ", 0)
        comment = FindString(ligne, "#", space)
        If comment
          tcomment.s = Trim(Right(ligne, Len(ligne)-comment))
          ligne = Left(ligne, comment-1)
        EndIf
        If space
          tvalue.s = Trim(Right(ligne, Len(ligne)-space))
          ligne = Left(ligne, space-1)
        EndIf
        tparam.s = Trim(ligne.s)
        succes = succes + 1
        AddElement(Conf_Params())
        Conf_Params()\ID = ID
        Conf_Params()\line = succes
        Conf_Params()\param = tparam
        Conf_Params()\value = tvalue
        Conf_Params()\comm = tcomment
      EndIf
    Until Eof(ID)
    CloseFile(ID)
    ProcedureReturn ID
  EndIf
  
EndProcedure

Procedure Conf_getlistparams(*this.Conf_Vars, out.l)
  
  params.s = ""
  ResetList(Conf_Params())
  For k=0 To CountList(Conf_Params())-1
    NextElement(Conf_Params())
    If Conf_Params()\ID = *this\ID
      ;params.s = RTrim(params+Conf_Params()\param+" ")
      params.s = params+Conf_Params()\param+" "
    EndIf
  Next k
  PokeS(out, params)
  ProcedureReturn out.l
  
EndProcedure

Procedure Conf_getvalue(*this.Conf_Vars, param.s, def.s, out.l)
  
  value.s = ""
  ResetList(Conf_Params())
  For k=0 To CountList(Conf_Params())
    NextElement(Conf_Params())
    If Conf_Params()\ID = *this\ID And Conf_Params()\param = param
      value.s = Conf_Params()\value
      Break
    Else
      value.s = def.s
    EndIf
  Next k
  PokeS(out, value)
  ProcedureReturn out.l
  
EndProcedure

Procedure Conf_getcomm(*this.Conf_Vars, param.s, out.l)
  
  comm.s = ""
  ResetList(Conf_Params())
  For k=0 To CountList(Conf_Params())
    NextElement(Conf_Params())
    If Conf_Params()\ID = *this\ID And Conf_Params()\param = param
      comm.s = Conf_Params()\comm
      Break
    EndIf
  Next k
  PokeS(out, comm)
  ProcedureReturn out.l
  
EndProcedure

Procedure Conf_setvalue(*this.Conf_Vars, param.s, value.s)

  ResetList(Conf_Params())
  For k=0 To CountList(Conf_Params())
    NextElement(Conf_Params())
    If Conf_Params()\ID = *this\ID And Conf_Params()\param = param
      Conf_Params()\value = value
      Break
    EndIf
  Next k

EndProcedure

Procedure Conf_addvalue(*this.Conf_Vars, param.s, value.s, comm.s, pos.l)
  
  If pos > 0
    SelectElement(Conf_Params(), pos-1)
  Else
    ResetList(Conf_Params())
  EndIf
  AddElement(Conf_Params())
  Conf_Params()\ID = *this\ID
  Conf_Params()\param = param
  Conf_Params()\value = value
  Conf_Params()\comm = comm
  
EndProcedure

Procedure Conf_update(*this.Conf_Vars)

  DeleteFile(*this\file)
  ID = CreateFile(#PB_Any, *this\file)
  ResetList(Conf_Params())
  For k=0 To CountList(Conf_Params())
    NextElement(Conf_Params())
    line.s = ""
    If Conf_Params()\ID = *this\ID
      line.s = Conf_Params()\param+" "+Conf_Params()\value
      If Conf_Params()\comm <> ""
        line.s = line+" #"+Conf_Params()\comm
      EndIf
      Conf_Params()\ID = ID
      WriteStringN(line)
    EndIf
  Next k
  CloseFile(ID)
  *this\ID = ID

EndProcedure

Structure Conf_Holder
  VT.Conf_Functions
  Impl.Conf_Vars
EndStructure
NewList Instances.Conf_Holder()

Procedure Conf_free(*this.Conf_Vars)

  ResetList(Conf_Params())
  For k=0 To CountList(Conf_Params())
    NextElement(Conf_Params())
    If Conf_Params()\ID = *this\ID
      DeleteElement(Conf_Params())
    EndIf
  Next k
  *this\ID = 0
  *this\file = ""

EndProcedure

Procedure Conf_init(file.s)

  AddElement(Instances())
  Instances()\VT\Conf_read = @Conf_read()
  Instances()\VT\Conf_getlistparams = @Conf_getlistparams()
  Instances()\VT\Conf_getvalue = @Conf_getvalue()
  Instances()\VT\Conf_getcomm = @Conf_getcomm()
  Instances()\VT\Conf_setvalue = @Conf_setvalue()
  Instances()\VT\Conf_addvalue = @Conf_addvalue()
  Instances()\VT\Conf_update = @Conf_update()
  Instances()\VT\Conf_free = @Conf_free()
  Instances()\Impl\VirtualTable = Instances()\VT
  Instances()\Impl\ID = 0
  Instances()\Impl\File = file
  ProcedureReturn @Instances()\Impl

EndProcedure
Heis Spiter, webmaster du site http://www.heisspiter.net
Développeur principal et administrateur du projet Bird Chat
Parti courir au bonheur du dév. public et GPL :D
Heis Spiter
Messages : 1092
Inscription : mer. 28/janv./2004 16:22
Localisation : 76
Contact :

Message par Heis Spiter »

Grosse mise-à-jour, j'ai rajouté la fonction qui permet d'ajouter un paramêtre. J'ai modifié la fonction qui retourne la valeur, maintenant, il faut préciser une valeur par défaut qui sera utilisée en cas de problème, et pour finir, j'ai un modifié la fonction de lecture, pour qu'elle gère mieux les diverses erreurs.
Heis Spiter, webmaster du site http://www.heisspiter.net
Développeur principal et administrateur du projet Bird Chat
Parti courir au bonheur du dév. public et GPL :D
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

coucou,
juste un petit conseil si je peux me permettre,
tu utilises souvent cette structure de boucle pour parser tes listes :

Code : Tout sélectionner

ResetList(Conf_Params())
For k=0 To CountList(Conf_Params())-1
  NextElement(Conf_Params())
  [...]
Next
mais

Code : Tout sélectionner

ForEach Conf_Params()
  [...]
Next
c'est beaucoup plus claire et rapide à l'usage. En plus, CountList(Conf_Params()) est appelé à chaque itération dans ton cas.
Image
lionel_om
Messages : 1500
Inscription : jeu. 25/mars/2004 11:23
Localisation : Sophia Antipolis (Nice)
Contact :

Message par lionel_om »

C'est pas grave pour le CountList(), car c'ets une valeur précalculée, donc non recalculée à chaque fois. :wink:
Webmestre de Basic-univers
Participez à son extension: ajouter vos programmes et partagez vos codes !
Heis Spiter
Messages : 1092
Inscription : mer. 28/janv./2004 16:22
Localisation : 76
Contact :

Message par Heis Spiter »

Flype a écrit :coucou,
juste un petit conseil si je peux me permettre,
tu utilises souvent cette structure de boucle pour parser tes listes :

Code : Tout sélectionner

ResetList(Conf_Params())
For k=0 To CountList(Conf_Params())-1
  NextElement(Conf_Params())
  [...]
Next
mais

Code : Tout sélectionner

ForEach Conf_Params()
  [...]
Next
c'est beaucoup plus claire et rapide à l'usage. En plus, CountList(Conf_Params()) est appelé à chaque itération dans ton cas.
C'est pour ça qu'Oliv l'utilisait tout le temps :). M'en vais corriger ça ;). Merci !
Heis Spiter, webmaster du site http://www.heisspiter.net
Développeur principal et administrateur du projet Bird Chat
Parti courir au bonheur du dév. public et GPL :D
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message par Dr. Dri »

lionel_om a écrit :C'est pas grave pour le CountList(), car c'ets une valeur précalculée, donc non recalculée à chaque fois. :wink:
Y'a quand même un appel de fonction donc une utilisation de la pile
Sinon si le faudrait faire des tests mais à mon avis le ForEach ne se contente pas que d'être plus lisible

Dri ;)
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

Si je me souviens bien le ForEach est une écriture qui se transforme en asm en ResetList suivi d'une boucle avec NextElement ce qui est il me semlble l'équivalent de

Code : Tout sélectionner

ResetList 

while NextElement ()
  ...
wend
Heis Spiter
Messages : 1092
Inscription : mer. 28/janv./2004 16:22
Localisation : 76
Contact :

Message par Heis Spiter »

Ce qui serait de toute façon plus optimisé que ce que je faisais jusqu'à maintenant.
Heis Spiter, webmaster du site http://www.heisspiter.net
Développeur principal et administrateur du projet Bird Chat
Parti courir au bonheur du dév. public et GPL :D
Répondre