Page 1 of 1

cLANGUAGEARRAY.pb

Posted: Tue Nov 07, 2006 10:35 pm
by Hroudtwolf
This class is a little tool for creating multilingual applications.
With it, you can load a languagefile into an associative-array.

Example ('cause my english is very bad):

Code: Select all

  If CreateMenu (1 , *g_MainWindow\l)
     MenuTitle (*LANGARRAY\Get ("User" , "User"))
     MenuItem  (#MENU_LOGIN , *LANGARRAY\Get ("User_Login" , "Login"))
     MenuItem  (#MENU_LOGOUT , *LANGARRAY\Get ("User_Logout" , "Logout"))
     MenuBar ()
     MenuItem  (#MENU_RIGHTS , *LANGARRAY\Get ("User_Rights" , "Rights"))
     MenuBar ()
     MenuItem  (#MENU_EXIT , *LANGARRAY\Get ("User_ExitSession" , "Exit"))
  EndIf

A languagefile have to be in this format:

Code: Select all

User		 		 = User menu
User_Login   	  = Login
User_Logout  	  = Logout
User_Rights       = Your rights
User_ExitSession  = Exit
You can place %cr% for linebreak.


I wish a lot of fun. :-)

Code: Select all

 ; ###############################################
; # LANGUAGEARRAY - Template                    #
; ###############################################
; # 2006 By Hroudtwolf                          #
; # Last Update: 02.11.2006                     #
; ###############################################

; ###############################################
; # Temporary Structs                           #
; ###############################################

Structure tLANGUAGEARRAY
   *association
   *expression
EndStructure

Structure tCHAR
   c.c
EndStructure

; ###############################################
; # Interface & DataStruct                      #
; ###############################################

Interface IcLANGUAGEARRAY
   Load     (LanguageFile.s)
   Get.s    (association.s , DefaultExpression.s)
   Set      (association.s , expression.s)
   Free     ()
   Done     ()
EndInterface

Structure cLANGUAGEARRAY
   *VTcLANGUAGEARRAY
   *Array
EndStructure




; ###############################################
; # Methodes                                    #
; ###############################################

; Eine Sprachdatei in das Array laden
; Falls eine Sprachdatei mit dem Constructor geladen wurde.
; so wird diese im Array überschrieben.
Procedure cLANGUAGEARRAY_Load (*Self.IcLANGUAGEARRAY , LanguageFile.s)
   Protected *SelfVar        .cLANGUAGEARRAY = *Self
   Protected FileID          .l
   Protected *Temp           .tCHAR
   Protected TempAssoc       .s
   Protected TempExprn       .s
   Protected IsAssoc         .b = 0
   Protected *ArrayTemp      .tLANGUAGEARRAY
   If *SelfVar\Array
      FreeMemory (*SelfVar\Array)
   EndIf
   FileID.l = ReadFile (#PB_Any , LanguageFile.s)
   If FileID.l
      If Lof(FileID.l) = 0
         CloseFile (FileID.l)
         ProcedureReturn #False
      EndIf
      *Temp = AllocateMemory (Lof(FileID.l))
      ReadData (FileID.l , *Temp , Lof(FileID.l))
      If PeekS (*Temp + Lof (FileID.l) - (2 * SizeOf(tCHAR))) <> #crlf$
        *Temp = ReAllocateMemory (*Temp , MemorySize (*Temp) + (2 * SizeOf(tCHAR)))
        PokeS (*Temp + (MemorySize (*Temp) - (2 * SizeOf(tCHAR))) , #crlf$)
      EndIf
      CloseFile (FileID.l)
      While *Temp\c
        Select *Temp\c
          Case '='
          IsAssoc.b = 1
          Case 13 , 10,9
          If *Temp\c = 13
              TempAssoc.s = Trim(TempAssoc.s)
              TempExprn.s = Trim(TempExprn.s)
              IsAssoc.b = 0
              If TempAssoc.s And TempExprn.s
                *SelfVar\Array = ReAllocateMemory (*SelfVar\Array , MemorySize (*SelfVar\Array) + SizeOf (tLANGUAGEARRAY))
                *ArrayTemp     = *SelfVar\Array + (MemorySize (*SelfVar\Array) - SizeOf (tLANGUAGEARRAY))
                *ArrayTemp\association = AllocateMemory (MemoryStringLength(@TempExprn.s) + 1)
                PokeS (*ArrayTemp\association , TempExprn.s)
                *ArrayTemp\expression  = AllocateMemory (MemoryStringLength(@TempAssoc.s) + 1)
                PokeS (*ArrayTemp\expression  , TempAssoc.s)
                TempAssoc.s    = ""
                TempExprn.s    = ""
             EndIf
          EndIf
          Default
          If IsAssoc.b
             TempAssoc.s + Chr(*Temp\c)
          Else
             TempExprn.s + Chr(*Temp\c)
          EndIf
        EndSelect
        *Temp + SizeOf (tCHAR)
      Wend
      FreeMemory (*Temp)
      ProcedureReturn #True
   EndIf
   ProcedureReturn #False
EndProcedure


; Die Entsprechung zu einer Assoziation ermitteln
; Wird keine Entsprechung gefunden oder das Array ist leer, wird DefaultExpression.s stattdessen ausgegeben.
Procedure.s cLANGUAGEARRAY_Get (*Self.IcLANGUAGEARRAY , association.s , DefaultExpression.s)
   Protected *SelfVar        .cLANGUAGEARRAY = *Self
   Protected *ArrayTemp      .tLANGUAGEARRAY
   If *SelfVar\Array = 0
       ProcedureReturn ""
   EndIf
   *ArrayTemp = *SelfVar\Array
   While *ArrayTemp < *SelfVar\Array + MemorySize (*SelfVar\Array)
     If PeekS (*ArrayTemp\association) = association.s
        ProcedureReturn ReplaceString (PeekS (*ArrayTemp\expression) , "%cr%" , #crlf$)
     EndIf
     *ArrayTemp + SizeOf (tLANGUAGEARRAY)
   Wend
   ProcedureReturn DefaultExpression.s
EndProcedure


; Die Entsprechung zu einer Assoziation ändern
Procedure cLANGUAGEARRAY_Set (*Self.IcLANGUAGEARRAY , association.s , expression.s)
   Protected *SelfVar        .cLANGUAGEARRAY = *Self
   Protected *ArrayTemp      .tLANGUAGEARRAY
   If *SelfVar\Array = 0
       ProcedureReturn #False
   EndIf
   *ArrayTemp = *SelfVar\Array
   While *ArrayTemp < *SelfVar\Array + MemorySize (*SelfVar\Array)
     If PeekS (*ArrayTemp\association) = association.s
        FreeMemory (*ArrayTemp\expression)
        *ArrayTemp\expression = AllocateMemory (MemoryStringLength(@expression.s) + 1)
        PokeS (*ArrayTemp\expression , expression.s)
        ProcedureReturn #True
     EndIf
     *ArrayTemp + SizeOf (tLANGUAGEARRAY)
   Wend
   ProcedureReturn #False
EndProcedure

   
; Den Inhalt des Arrays löschen
Procedure cLANGUAGEARRAY_Free (*Self.IcLANGUAGEARRAY)
   Protected *SelfVar        .cLANGUAGEARRAY = *Self
   Protected *ArrayTemp      .tLANGUAGEARRAY
   *ArrayTemp = *SelfVar\Array
   While *ArrayTemp < *SelfVar\Array + MemorySize (*SelfVar\Array)
      FreeMemory (*ArrayTemp\expression)
      FreeMemory (*ArrayTemp\association)
      *ArrayTemp + SizeOf (tLANGUAGEARRAY)
   Wend
   FreeMemory (*SelfVar\Array)
   *SelfVar\Array = 0
EndProcedure   

; Freigeben des gesamten Array-Objekts
Procedure cLANGUAGEARRAY_Done (*Self.IcLANGUAGEARRAY)
   *Self\Free ()
   FreeMemory (*Self)
EndProcedure
   
; ###############################################
; # Construct LANGUAGEARRAY                     #
; ###############################################


; Es kann optional die Sprachdatei direkt mit dem Constructor geladen werden.
Procedure CreateLANGUAGEARRAYClass (LanguageFile.s = "")
   Protected *ThisVar.cLANGUAGEARRAY  = AllocateMemory (SizeOf (cLANGUAGEARRAY))
   Protected *This   .IcLANGUAGEARRAY = *ThisVar
   *ThisVar\vtcLANGUAGEARRAY = ?VTable_cLANGUAGEARRAY
   If *This\Load (LanguageFile.s)
      ProcedureReturn *ThisVar
      Else
      ProcedureReturn 0
   EndIf
   DataSection
      VTable_cLANGUAGEARRAY:
         Data.l @cLANGUAGEARRAY_Load ()
         Data.l @cLANGUAGEARRAY_Get  ()
         Data.l @cLANGUAGEARRAY_Set  ()
         Data.l @cLANGUAGEARRAY_Free ()
         Data.l @cLANGUAGEARRAY_Done ()
   EndDataSection
EndProcedure



Posted: Wed Nov 08, 2006 1:18 am
by srod
Interesting method.

Similar to my own (without the oop though!) except your use of string identifiers is more flexible than my own hair-brained method. The only thing is, by storing the string identifiers in memory alongside the 'expressions', you could be eating up quite a bit of memory in a large application.

No big deal though I guess.

Nice.

It's also a good demonstration of how to use oop in Purebasic. :)

Thanks for sharing.

Posted: Wed Nov 08, 2006 6:29 pm
by Hroudtwolf
Thanks :-)


Updated:

- Bug fixed. End of file must be no longer a crlf.
- Changed. Now, invalid lines will be ignored.