On split
function split(str, delim, maxNb)
if maxNB==nil then maxNB=9999999 end
The first line has no effect inside the function. Even worse, it has an unadverted global effect. Did you write it? It’s not in the referenced link. You didn’t read the rest of the function, right?
Also, the function has two warts you don’t need. One is the aforementioned maxNb
that you make no use of, the second one is the “bad case”, which is at the most a special case, but upon examining it more closely it is not even that.
Let me present you a more concise split function:
function split(str, delim)
local result = {}
local pat = "(.-)" .. delim .. "()"
local lastPos = 1
for part, pos in string.gfind(str, pat) do
table.insert(result, part)
lastPos = pos
end
-- Handle the last field
table.insert(result, string.sub(str, lastPos))
return result
end
Why don’t you need maxNb? Either you get the full result or it will be of no use for you.
Why don’t you need the special case? Firstly, let me tell you the the special case is still handled, just not as the very special case that was mention in the original code. Secondly, I assume you will always have at least “end” in a tab.
On your file format encoding
At this point I’ll just accept the your format looks like this:
- original contents
- 10 hash signs that act as some sort of your “format specifier”
- as much padding with character “0” as you need to get a length that is a multiple of 3
Your encoding, taken from Backup:Store
:
txt=origTxt..string.rep("#",10)
local n=3-string.len(txt)%3
if n>0 then txt=txt..string.sub("0000",1,n) end
n=string.len(txt)
local s=math.floor((n/3)^.5)+1
img=image(s,s)
The extra padding with "0"s is awkward. Better you remember the length of the text after adding your format specifier, then add “enough” padding so that the string reaches at least the next 3-byte-boundary.
-- add format specifier
txt=origTxt..string.rep("#",10)
-- |n| is the length of the txt to encode
local n=string.len(txt)
-- padding so that accessing "a few more chars" results in a legal char, not nil
txt=txt.."0000"
local s=math.floor((n/3)^.5)+1
img=image(s,s)
The key is to remember the length of the string you want to encode, then the length of the padding only matters so much that it shall not be too short. You can get rid of the padding at all if you modify the string access in the loop:
-- original, requires padding of |txt|
for j=1,3 do
e[j]=string.byte(string.sub(txt,i+j,i+j))
end
-- without padding of |txt|
for j=1,3 do
-- pad with "0" if string.sub reads beyond the end of |txt|
e[j] = string.byte(string.sub(txt,i+j,i+j)) or "0"
end
On your file format
Essentially, you have no file format. Instead you split the code into tabs by scanning it for class definitions. That’s not very elegant but I aknowledge the effort to try to implement this system. I suggest to use something the the Codea project format for future file formats. Perhaps keep your class splitter so you can rearrange foreign code to your liking.
Expanding your file format anyway
Just an idea. You could use the string space after “##########” to store some mata data, e.g. the names and byte positions of the tabs.
“##########Main,1,125;Other,126,659;Extra,660,1011##########”
By scanning the meta data you could recreate the tabs’ contents.
Finally
A great and useful project despite all my ramblings above. Especially the automatic backup when you change the version string is feature to steal.