Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

saveGlobalData

dave1707dave1707 Mod
edited September 2012 in Bugs Posts: 9,590

@Simeon

This isn't working like I expect it to. I was playing around with save and read global data and I ran into a problem. Here is an example I set up to show the problem. It looks like the string of digits (a) is treated as a number and not a string. (b) (c) and (d) are working as expected. I added the program output as a comment at the end. I expected (a) to print as 1234567890 and not 1.23457e+09 . Local and Project data also do the same thing.


function setup()          a="1234567890"    -- string of digits     b= 1234567890     -- a number     c="a123456789"    -- string of digits with leading letter     d="qwertyuiop"    -- string of letters          saveGlobalData("a",a)     saveGlobalData("b",b)     saveGlobalData("c",c)     saveGlobalData("d",d)              for x,y in pairs(listGlobalData()) do         print(x,y)     end          print()     a=readGlobalData("a")     print("a",a)          b=readGlobalData("b")     print("b",b)          c=readGlobalData("c")     print("c",c)      d=readGlobalData("d")     print("d",d)           end --[[    Here is the output from this program 1    d 2    b 3    c 4    a a    1.23457e+09 b    1.23457e+09 c    a123456789 d    qwertyuiop --]]

Comments

  • edited September 2012 Posts: 563

    .@dave1707 - that is interesting I hadn't noticed this. I whipped out iExplorer and had a look at what is actually stored in the pList. For the number string you get:

    <real>1234567936</real>
    

    So the automatic cast happens when you save the data.

  • SimeonSimeon Admin Mod
    Posts: 5,714

    It's not really a bug, this is just the way that Lua handles numbers and strings. If a string is convertible to a number, Lua will convert it.

    When you read it back, you can convert it back to a string (for printing, for example) by using tostring(a).

  • dave1707dave1707 Mod
    Posts: 9,590

    @Simeon

    If I do a print(tostring(a)) I get 1.23457e+09 printed out, not 1234567890. If that's the case then an all numeric string can't be saved and read back as global, local or project data. The numeric string will be shown as scientific notation unless it's 6 digits or less, provided it doesn't begin with zeros. If I save the string "000001" and read it back I get a 1 even if I do a tostring. If what I save isn't what I read back then I can't rely on that function for saving data.

  • SimeonSimeon Admin Mod
    Posts: 5,714

    Thanks for reporting this, @dave. I've looked into it some more and it does indeed appear to be a bug with save*Data

    It asks Lua if the value is a number, before checking if it is a string. This causes Lua to attempt the conversion.

    I have fixed this bug for the next version of Codea (saving a string representation of a number will keep it as a string).

  • Jmv38Jmv38 Mod
    Posts: 3,297

    @dave1707 as a temporary hack you could implement your save/load functions by adding systematically to the beginning of your strings a character (like '_') when saving and removing it when you read. Of course you already know that, i said it just in case...

  • edited September 2012 Posts: 140

    Removed after reading other comments.

  • dave1707dave1707 Mod
    edited September 2012 Posts: 9,590

    Here is a program that will allow a string containing any values (0x00 to 0xff) to be saved in Global, Local, or Project data and read it back. The original problem with saving strings is that certain hex values would cause an error message or cause Codea to close when using the saveGlobalData etc commands. The 2 routines here (hexToAscii and asciiToHex) gets around that problem. hexToAscii will take 1 hex byte and convert it to 2 ASCII bytes. asciiToHex will take 2 ASCII bytes and convert them back to 1 hex byte. By converting 1 hex byte to 2 ASCII bytes allows you to save the string without problems. The only down side is the string being saved is twice the size of the original. When this program is run, it will show examples of the steps taken to convert the original string to ASCII, save the string, read it back, and convert it from ASCII back to the original. Slide the output pane all the way up to show more of the output. I added the command saveGlobalData("str2",nil) at the end to remove my example of str2 from your iPad.


    function setup()        asciiTab={"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"}          str1=""     str2=""     str3=""     str4=""          --create string str1 with values from 0 to 255 (0x00 to 0xff)     for a = 0x00,0xff do         str1=str1..string.char(a)     end          --show the values and length of string str1     print("str1",string.byte(str1,1,string.len(str1)))     print("\nstr1 length",string.len(str1))          --convert 1 hex byte to 2 ascii bytes     print("\nConvert 1 hex byte (str1)\nto 2 ascii bytes (str2)")     str2=hexToAscii(str1)          --show values and length of string str2     print("\nstr2",str2)     print("\nstr2 length",string.len(str2))     --save string str2 as global data     print("\nsaving str2 as global data")     saveGlobalData("str2",str2)          --list global data     print("listing global data")     for x,y in pairs(listGlobalData()) do         print(x,y)     end          --read saved data into string str4     print("\nread global data into str4")     str4=readGlobalData("str2")          --show values and length of string str4     print("\nstr4",str4)     print("\nstr4 length",string.len(str4))          --convert 2 ascii bytes to 1 hex byte     print("\nConvert 2 ascii bytes (str4)\nto 1 hex byte (str3)")     str3=asciiToHex(str4)          --show values and length of string str3     print("\nstr3",string.byte(str3,1,string.len(str3)))     print("\nstr3 length",string.len(str3))     saveGlobalData("str2",nil) -- remove str2 from global data          end function hexToAscii(in1)    --convert 1 hex byte to 2 ascii bytes     local out1=""     for x=1,string.len(in1) do         z=string.byte(in1,x,x)         a=math.floor(z/16)         a1=asciiTab[a+1]         b=z%16         b1=asciiTab[b+1]         out1=out1..a1..b1     end     return(out1) end function asciiToHex(in1)    --convert 2 ascii bytes to 1 hex byte     local out1=""     for x=1,string.len(in1),2 do         a=string.sub(in1,x,x)         a1=string.byte(a)         if a1>57 then             a1 = a1 - 87         else             a1 = a1 - 48         end                  b=string.sub(in1,x+1,x+1)              b1=string.byte(b)            if b1>57 then             b1 = b1 - 87         else             b1 = b1 - 48         end              z=a1*16+b1         out1=out1..string.char(z)     end     return(out1) end function draw()     background(40,40,50)    end

        

  • Posts: 79

    @Simeon

    when I start this program on my iPad1 , I get in print (x, y) 30 other entries from other projects. How can I delete these entries Global?

  • Jmv38Jmv38 Mod
    Posts: 3,297

    @dave1707 thanks for sharing. What i really need is the ability to save/read a table of bytes. So i have modified your code to include this functionnality. See below.

    function setup()   
        asciiTab={"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"}
        
        str1=""
        table1={}
        table2={}
        str2=""
        str3=""
        str4=""
        
        --create string the table with values from 0 to 255 (0x00 to 0xff)
        for a = 0x00,0xff do
            table1[a]=a
        end
        
        --show the values of table1
        str1=""
        for i=0,#table1 do
            str1= str1.."-"..table1[i]
        end
        print("table1 = ",str1)
        
        --convert 1 hex byte to 2 ascii bytes
        print("\nConvert a table of bytes \nto a string in hex format")
        str2=byteTableToAsciiHex(table1)
        
        --show values and length of string str2
        print("\nstr2",str2)
        print("\nstr2 length",string.len(str2))
    
        --save string str2 as global data
        print("\nsaving str2 as global data")
        saveGlobalData("str2",str2)
            
        --list global data
        print("listing global data")
        for x,y in pairs(listGlobalData()) do
            print(x,y)
        end
        
        --read saved data into string str4
        print("\nread global data into str4")
        str4=readGlobalData("str2")
    
        --show values and length of string str4
        print("\nstr4",str4)
        print("\nstr4 length",string.len(str4))
        
        --convert 2 ascii bytes to 1 hex byte
        print("\nConvert 2 ascii bytes (str4)\nto 1 hex byte (str3)")
        str3=asciiToHex(str4)
    
        -- convert hex string to byte table
        table2 = asciiHexToByteTable(str4)  
    
        -- check all the values are there
        str3=""
        for i=0,#table2 do
            str3= str3.."-"..table2[i]
        end
        print(str3)
    
        saveGlobalData("str2",nil)   -- remove str2 from global data
            
    end
    
    function byteTableToAsciiHex(in1)    --convert table of bytes to hex ascii string
        local out1=""
        for x=0,#in1 do
            z=x
            a=math.floor(z/16)
            a1=asciiTab[a+1]
            b=z%16
            b1=asciiTab[b+1]
            out1=out1..a1..b1
        end
        return(out1)
    end
    
    function asciiHexToByteTable(in1)    --convert 2 ascii bytes to a table of bytes
        local out1={}
        local i=0
        for x=1,string.len(in1),2 do
            a=string.sub(in1,x,x)
            a1=string.byte(a)
            if a1>57 then
                a1 = a1 - 87
            else
                a1 = a1 - 48
            end
            
            b=string.sub(in1,x+1,x+1)     
            b1=string.byte(b)   
            if b1>57 then
                b1 = b1 - 87
            else
                b1 = b1 - 48
            end
        
            z=a1*16+b1
            out1[i]=z
            i = i + 1
        end
        return(out1)
    end
    
    function hexToAscii(in1)    --convert 1 hex byte to 2 ascii bytes
        local out1=""
        for x=1,string.len(in1) do
            z=string.byte(in1,x,x)
            a=math.floor(z/16)
            a1=asciiTab[a+1]
            b=z%16
            b1=asciiTab[b+1]
            out1=out1..a1..b1
        end
        return(out1)
    end
    
    function asciiToHex(in1)    --convert 2 ascii bytes to 1 hex byte
        local out1=""
        for x=1,string.len(in1),2 do
            a=string.sub(in1,x,x)
            a1=string.byte(a)
            if a1>57 then
                a1 = a1 - 87
            else
                a1 = a1 - 48
            end
            
            b=string.sub(in1,x+1,x+1)     
            b1=string.byte(b)   
            if b1>57 then
                b1 = b1 - 87
            else
                b1 = b1 - 48
            end
        
            z=a1*16+b1
            out1=out1..string.char(z)
        end
        return(out1)
    end
    
    function draw()
        background(40,40,50)   
    end
    
  • Posts: 79

    @Jmv30

    when I start your codeon my iPad 1, I get following output:

    saving str2 as global data
    listing global data
    1 Aquarius
    2 car1
    3 1-Capricorn
    4 c
    5 SpritelyKeys
    6 Spritely24
    7 d
    8 b
    9 1-Aries
    10 Libra
    11 1-Leo
    12 str2
    13 Wing
    14 Ampel
    15 Pisces
    16 1-Cancer
    17 1-Sagittarius
    18 1-Libra
    19 Spritely2
    20 1-Scorpio
    21 B0
    22 Spritely18
    23 Capricorn
    24 1-Aquarius
    25 1-Pisces
    26 Scorpio
    27 1-Gemini
    28 1-Virgo
    29 scorpio
    30 1-Taurus
    31 0
    32 globalDataKey
    33 Sagittarius
    34 a
    35 Copy of Spritely2

    what can I do to clean GlobalData?

  • Posts: 2,161

    By the way, there's a family of tools for manipulating binary, decimal, and hexadecimal data in lua that can be easily found on the internet. I added octal and put it in my library which is at http://www.math.ntnu.no/~stacey/code/CodeaLibrary

  • .@matox - you can use my simple file manager class to manually delete items in global data (and local and project data). Use with care though - there is no undo! http://codeatuts.blogspot.com.au/2012/09/tutorial-17-simple-file-manager-for.html

  • Posts: 79

    @Reefwing
    Thanks for help. But I got errors - Nil bei Version -
    So I have stored all my Code in Notizen and then delete Codea and load it again.
    Now globalData is clean

  • Two questions 1 what is the point in having table.concat if you can't use it to convert a table and all its values into a string?

    -AND-

    2 where is the extended documentation on how to use it in conjunction with saveGlobalData?

  • dave1707dave1707 Mod
    Posts: 9,590

    @pioyugb

    Here are 2 examples of table.concat . Can't help with question 2.


    function setup()     tab={1,"one",2,"two",3,"three",4,"four",5,"five"}          str=table.concat(tab,"*") -- put an * between all entries     print(str)          print()          str=table.concat(tab,"\n") -- put a carriage return between all entries     print(str) end function draw()     background(40, 40, 50) end
Sign In or Register to comment.