A very strange CopyBank problem...

BlitzMax Forums/BlitzMax Programming/A very strange CopyBank problem...

Fry Crayola(Posted 2006) [#1]
I didn't post this in Bugs, because I haven't a clue what exactly the problem is... other than weird stuff happening that I don't understand. I'll see if I can explain.

Ok, I'm using a Bank in which to store a lot of data, in a simple database structure - each record consists of data to be held in a number of groups, and each group is dynamic to provide greater flexibility and space saving. For example, if you were to use the database to store a CD collection, each record could be a CD and in a single group you can store each song on the CD - the group's size changes according to the number of songs on the CD. Simple stuff. You can have more than one group as well. Let's say you used another database to store your DVD collection - in each record, one group could store the special features on disc one, and the other could store the features on disc two. You know, if you really cared about stuff like that. If you found another feature on Disc One, you can then go to the database and add the feature - and the group size for the record will dynamically expand, and shift all the data in front of it forward.

Sorry if that's a bit waffly, but I hope it gets across what I'm trying to do. That's the theory, now here comes the problem. In my current project, there are two groups for a particular database table. But for some reason, when I add an item to the first group in the table, it manages to overwrite everything in the entire bank - but only if there are items in the second group.

An example will best explain it. The two groups are "First Names" and "Surnames", storing as you would expect a list of first names and surnames, with each whole record applying to a nationality (i.e. a list of English names, a list of Dutch names, and so forth). Each group contains two fields - "Name" and "Total", the latter being a running total of how people use the name. When the program starts, it gives each record one of each - a default value. Say "First Name" is "New", and Surname is "Person". This works fine, as it fills out the first names before the surnames.

However, when I try to add another First Name to Record 0, the following code kicks in as it should...



tbl.Offsets[] contains the offset of each record in the table (a single bank serves one table).
grp.Record is the current record being written
grp.Offset is the offset of that group, from the start of the table
grp.EntryOffset is the offset of the particular entry in the group that I'm creating - i.e. the offset of this new name.
grp.Size is the size of one particular Name + Total combination (in this case, 32 bytes - 30 bytes for the name, 2 bytes for the total)


The DebugLog statements indicate that the correct offsets are used and that the bytes that I need to move, in order to make room for the new entry, are perfect. Not a problem.

DebugBank is a function which will output the bank to a file, so that I can see its state before and afterwards. It looks as follows:

Function DebugBank(str:String = "Requested")

	Local file:TStream = OpenFile ("DebugBank "+str+".txt", False, True)
	
	Local tbl:DBTable
	
	For tbl:DBTable = EachIn DBase.TableList
		If tbl.Id = 42000 Then Exit
	Next
	
	WriteBank(tbl.DataBank, file, 0, 1000)
	
	CloseStream file
	
End Function


The resulting file is opened in Notepad, as a 1KB file (the full bank takes up 10MB, so I only write the first 1000 bytes).

The file "DebugBank Before.txt" is created before the copying has been done. It looks like this:



followed by spaces. Which is perfect, as it contains the defaults I write to the table earlier in the program, for two records, each record having one first name ("New") and one surname ("Person"). The totals are zero, so they get written as spaces.

However, the "DebugBank After.txt" file looks like this....



And so on throughout the entire bank (please ignore the whitespace in the box above, that's a codebox problem - only the first line counts). For some reason, it has decided to overwrite every single entry with the default surname. Because the game has code to remember how many first names and surnames is supposed to be in each record, the end result appears that adding a new first name to a record overwrites everything in the database from that point on. Which isn't good for me.

Sorry for it being terribly wordy, but I don't know how best to explain it other than an example. Its been driving me nuts for the past week and has probably killed more brain cells than the new year alcohol... after days of fiddling I've narrowed it down to that CopyBank statement. It's definitely the cause of the problem somehow - yet it doesn't cause any problems if there aren't any surnames already attached... perhaps it is copying a 32 byte section of the bank over and over again?

It's not CopyBank's fault explicitly, neither, because I replaced it with a simple Poking and Peeking, and that has the exact same result.

Please, if anyone can shed light on what's going on here I'd be incredibly grateful.

Cheers.


Edit: I have changed the two outputs from codeboxes to code, as they don't look properly in codebox mode (too much whitespace gives a wrong impression of what's happened).

And then I changed it again back to codebox because it stretches the screen,


Fry Crayola(Posted 2006) [#2]
No matter. In an enlightening moment on the place of all man's greatest thoughts - the toilet - I realised I'm an idiot, and that the CopyBank function was overwriting the stuff it had yet to copy.

D'oh!