1. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  2. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still havn't received your rank award? Then please contact the administration.
    Dismiss Notice
  3. The Lich King demands your service! We've reached the 19th edition of the Icon Contest. Come along and make some chilling servants for the one true king.
    Dismiss Notice
  4. The 4th SFX Contest has started. Be sure to participate and have a fun factor in it.
    Dismiss Notice
  5. The poll for the 21st Terraining Contest is LIVE. Be sure to check out the entries and vote for one.
    Dismiss Notice
  6. The results are out! Check them out.
    Dismiss Notice
  7. Don’t forget to sign up for the Hive Cup. There’s a 555 EUR prize pool. Sign up now!
    Dismiss Notice
  8. The Hive Workshop Cup contest results have been announced! See the maps that'll be featured in the Hive Workshop Cup tournament!
    Dismiss Notice
  9. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

[Snippet] StringIterator

Discussion in 'JASS Resources' started by edo494, Dec 29, 2013.

  1. edo494

    edo494

    Joined:
    Apr 16, 2012
    Messages:
    3,855
    Resources:
    5
    Spells:
    1
    JASS:
    4
    Resources:
    5
    pretty simple, wrote in under hour, but I wanted to share this piece for anyone that does something like I did with chat modes and dont want to write 100 additional lines of code

    Code (vJASS):

    library StringIterator
    /*
        Made by: edo494
        Version: 1.0
       
        Description:
           
            This piece of code allows you to forward iterate over words in strings,
            reading them out from the "container" depending on the delimiter.
           
        API:
           
            struct StringIterator
               
                static method create takes string container returns thistype
                    - creates new instance
                   
                method setDelims takes string delimiters returns nothing
                    - sets the delimiters to characters in "delimiters"
                    - example: "abc" will make the instance treat any
                      a, b or c inside the string as delimiter
                     
                method read takes nothing returns string
                    - returns string containing charaters from "position"
                      up to "end" or until any delimiter is found
                     
                method peek takes nothing returns string
                    - returns string containing charaters from "position"
                      up to "end" or until any delimiter is found
                    - does not move "position" forward
                   
                method nextDelim takes nothing returns string
                    - returns upcomming delimiter pack
                    - so if 2 or more delimiters after each other occur
                      this function returns all of them
                     
                method operator string= takes string newContainer returns nothing
                    - sets internal container to "newContainer"
                    - call to this function resets position
                     
                method operator start takes nothing returns boolean
                    - returns whether the iterator is at the start or not
                   
                method operator end takes nothing returns boolean
                    - returns whether the iterator is at the end or not
                   
                method operator size takes nothing returns integer
                    - returns number of charaters inside the container
               
                method operator position takes nothing returns integer
                    - returns the current position of the iterator inside container
                   
                method operator position= takes integer newPos returns boolean
                    - sets the position to the "newPos"
                    - in debug mode, if <0 or >size, returns false
                      otherwise true
                    - outside of debug mode, returns true
                   
                method reset takes nothing returns nothing
                    - returns the iterator to start
                   
    */

        struct StringIterator
            private string myStr
            private string myDelims
            private integer pointer
            private integer sSize
            private integer dSize
           
            static method create takes string s returns thistype
                local thistype this = allocate()
                set this.myStr = s
                set this.myDelims = " "
                set this.pointer = 0
                set this.dSize = StringLength(this.myDelims)
                set this.sSize = StringLength(s)
                return this
            endmethod

            static method createEx takes string container, string delims returns thistype
                local thistype this = allocate()
                set this.myStr = container
                set this.myDelims = delims
                set this.pointer = 0
                set this.dSize = StringLength(delims)
                set this.sSize = StringLength(container)
                return this
            endmethod
           
            method setDelims takes string s returns nothing
                set this.myDelims = s
                set this.dSize = StringLength(s)
            endmethod
           
            method operator start takes nothing returns boolean
                return this.pointer <= 0
            endmethod
           
            method operator end takes nothing returns boolean
                return this.pointer >= this.sSize
            endmethod
           
            method operator size takes nothing returns integer
                return this.sSize
            endmethod
           
            method operator position takes nothing returns integer
                return this.pointer
            endmethod
           
            private method isDelim takes string s returns boolean
                local integer i = this.dSize
                local string delims = this.myDelims
                if s == null then
                    return true
                endif
                loop
                    exitwhen i == 0
                    if s == SubString(delims, i-1, i) then
                        return true
                    endif
                    set i = i - 1
                endloop
                return false
            endmethod
           
            private method readBool takes boolean b returns string
                local string helper = ""
                local string ths = this.myStr
                local integer size = this.sSize
                local integer current = this.pointer
                local string cont = ""
                //evade all remaining delimiters from the last read
                loop
                    if current == size then
                        exitwhen true
                    endif
                    exitwhen not isDelim(SubString(ths, current, current+1))
                    set current = current + 1
                endloop
                //fill up the string
                loop
                    exitwhen current == size
                    set helper = SubString(ths, current, current+1)
                    exitwhen isDelim(helper)
                    set cont = cont + helper
                    set current = current + 1
                endloop
                if b then
                    set this.pointer = current
                endif
                //return the string
                return cont
            endmethod
           
            method read takes nothing returns string
                return readBool(true)
            endmethod
           
            method peek takes nothing returns string
                return readBool(false)
            endmethod
           
            method nextDelim takes nothing returns string
                local string ths = this.myStr
                local integer size = this.sSize
                local integer current = this.pointer
                local string s = ""
                local string q = ""
                if current == size then
                    return ""
                endif
                //evade all non delimiters
                loop
                    set q = SubString(ths, current, current+1)
                    exitwhen current == size or not isDelim(q)
                    set current = current + 1
                endloop
                //read next delimiters
                loop
                    set q = SubString(ths, current, current+1)
                    exitwhen current == size or not isDelim(q)
                    set s = s + q
                    set current = current + 1
                endloop
                //return them
                return s
            endmethod
           
            method operator position= takes integer newPosition returns boolean
                debug if newPosition > this.size or newPosition < 0 then
                    debug return false
                debug endif
                set this.pointer = newPosition
                return true
            endmethod
           
            method reset takes nothing returns nothing
                set this.pointer = 0
            endmethod
           
            method operator string= takes string s returns nothing
                set this.myStr = s
                set this.sSize = StringLength(s)
                set this.pointer = 0
            endmethod
        endstruct
    endlibrary
     


    Example:

    Code (vJASS):

    scope example initializer init
       
        private function t takes nothing returns boolean
            local string s = GetEventPlayerChatString()
            local StringIterator iter = StringIterator.create(s)
            call iter.setDelims(" ")
            call BJDebugMsg("Message inserted by player:\n")
            loop
                exitwhen iter.end
                call BJDebugMsg(iter.read())
            endloop
            return false
        endfunction
       
        private function init takes nothing returns nothing
            local trigger tr = CreateTrigger()
            call TriggerRegisterPlayerChatEvent(tr, Player(0), "", false)
            call TriggerAddCondition(tr, Condition(function t))
            set tr = null
        endfunction
    endscope
     
     
    Last edited: Jan 6, 2014
  2. Cokemonkey11

    Cokemonkey11

    Wurst Reviewer

    Joined:
    May 9, 2006
    Messages:
    3,240
    Resources:
    18
    Tools:
    1
    Maps:
    5
    Spells:
    3
    Tutorials:
    2
    JASS:
    7
    Resources:
    18
    I didn't check the code in detail, but nothing jumps out at me as bad. API is nice. I suggest approval.
     
  3. edo494

    edo494

    Joined:
    Apr 16, 2012
    Messages:
    3,855
    Resources:
    5
    Spells:
    1
    JASS:
    4
    Resources:
    5
    Updated

    • create now initializes delimiter list to " " instead of " -"
    • new method: static createEx(string container, string delimiters) returns thistype
     
  4. TriggerHappy

    TriggerHappy

    Code Moderator

    Joined:
    Jun 23, 2007
    Messages:
    3,665
    Resources:
    22
    Spells:
    11
    Tutorials:
    2
    JASS:
    9
    Resources:
    22
    Approved.