Login [Register]
Don't have an account? Register now to chat, post, use our tools, and much more.
This is a topic where I will cover some of the harder parts of ICE. If you want to contribute as well, be sure to contact me.

Part 1: Appvars - By PT_
How to read, write, create and delete appvars and other OS variables.

Appvars are variables that pretty much every program needs. It's used to store highscores, load spritedata from, save passwords (let's not do that), and much more. It's quite challenging though, to understand how to deal with appvars within ICE. Note that instead of appvars you can use every BASIC variable, but in this post I will talk about "appvars".

The first term I want to explain is slots. You see this in pretty much every FILEIOC function. But what are those? When working with files, you want to store some information of one file, such as the size, current offset (I will explain that later), the mode and much more. This is all packed into a "slot" (comparable with FILE * in C). Each slot holds some file information, which you can access with all the available FILEIOC functions.

It's quite important to say that slots are stored in RAM. This means that if you start the program, the slots might be empty, or not, so that's why you always need to close all slots with CloseAll before doing any file-related action! You have only 5 available slots, so if they're all filled with random bytes at the start of the program, you're out of luck when opening or creating a file. I will now explain all the possibilities when using with files, starting with the main one: creating files.

Creating appvars
Creating appvars is nothing more than opening them with a different mode. If you take a look at the commands list, Open, you can see a few modes which might be useful:
  • "w" - if the appvar doesn't exists, it creates a new, empty appvar with the specified name. If the appvar did exists, it deletes them and creates a new, empty appvar. This might be useful for programs which want to be sure that the content of an appvar is always the same: just delete the old appvar, create a new one and write the correct data to it. Note that in this mode you're not allowed to read anything from the appvar!
  • "a" - if the appvar doesn't exists, if creates a new appvar with the specified name. Otherwise, the file pointer will be set to the end of the appvar (I will explain that later). This might be useful if you want to count how many times your program is run, by just adding a byte to the appvar; who knows. Note that in this mode you're not allowed to read anything from the appvar!
  • "w+" - if the appvar doesn't exists, it creates a new, empty appvar with the specified name. If the appvar did exists, it deletes them and creates a new, empty appvar. This might be useful for programs which want to be sure that the content of an appvar is always the same: just delete the old appvar, create a new one and write the correct data to it. With this mode you're allowed to write to and read from the appvar (notice the difference with mode "w").
  • "a+" - if the appvar doesn't exists, if creates a new appvar with the specified name. Otherwise, the file pointer will be set to the end of the appvar (I will explain that later). This might be useful if you want to count how many times your program is run, by just adding a byte to the appvar; who knows. With this mode you're allowed to write to and read from the appvar (notice the difference with mode "a").


If you have no idea which mode to use, I would recommend using "w+" if you want to read from it and "w" if you want it to be secret, as in not allowed to read. Know you hopefully know how to create an appvar. You can check it if it did, because the command Open returns the slot variable, or 0 if any failure. If it returns 0, there went something wrong, and it's up to you to figure out what is wrong. A likely situation is that you already opened 5 slots, or forgot to close them all before creating the appvar. Otherwise, it returns 1, 2, 3, 4 or 5, depending on the amount of opened slots.

Examples:

Code:
Open("SCORES","w") - this function tries to create (or empty) the appvar "SCORES". Because it is a new appvar, I do not want to read from it, so I just use mode "w".

Open("SCORES","w+") - this function tries to create (or empty) the appvar "SCORES". In this case we want to check if the write to the appvar was succesfully, so we want to read from it as well. Mode "w+" is useful in this case.

Open("ONLINE","a") - I want to append the timestamp of each time this program ran to the appvar. The appvar might not exists yet, and we do not need to know the previous timestamps, so mode "a" is fine.

Open("ONLINE","a+") - I want to append the timestamp of each time this program ran to the appvar. The appvar might not exists yet, but if it does we want to fetch the previous timestamp, so in this case you should use "a+"


Opening appvars
Yay, you managed to create an appvar! Note that if you (tried to) create an appvar, the appvar is already opened, so you don't need to open it again. But what if you're sure (or just assume) that the appvar already exists? There we have 4 modes I want to explain now. See Creating appvars for more information about the modes.
  • "r" - this function opens an appvar for reading only. The appvar must already exists. You can compare it with locked programs; you can execute them, but you're not allowed to edit.
  • "r+" - this function opens the appvar for both reading and writing.
  • "a" - this function opens the appvar for appending data to it (that is, the internal pointers points to the end of the file)
  • "a+" - this function opens the appvar for both appending data and reading.

If you have no idea which to choose, I would go for "r+". This mode is used for both reading and writing, and is probably what you need. "a+" does the job as well, but sets the pointer to the end of the appvar, which might be useful if you're logging things and want to add a timestamp to the appvar. As mentioned before, Open returns 0 if any failure occured, like not enough RAM, appvar doesn't exists or too much opened slots. Otherwise, it returns 1, 2, 3, 4 or 5.

Examples:

Code:
Open("ONLINE","r") - this function wants to read the appvar ONLINE. Since there are only timestamps in the appvar, I can count the amount of timestamps to see how many times the program ran.

Open("ONLINE","r+") - this function wants to read the appvar ONLINE. Since there are only timestamps in the appvar, I can count the amount of timestamps to see how many times the program ran. However, the user should be able to edit a timestamp as well, so that is why we need mode "r+".

Open("ONLINE","a") - I want to append the timestamp of each time this program ran to the appvar. The appvar might not exists yet, and we do not need to know the previous timestamps, so mode "a" is fine.

Open("ONLINE","a+") - I want to append the timestamp of each time this program ran to the appvar. The appvar might not exists yet, but if it does we want to fetch the previous timestamp, so in this case you should use "a+"


Reading appvars
Congratz! You managed to open the appvar, and now you want to read the data out of it. This is very easy to do, so let's take a look at Read, the function you need to use. Read reads a sequence of bytes from the appvar and copies that to a pointer. Simple? Yes. But this is where the internal file pointer is coming in, so let me try to explain that first.

The pointer keeps track of the current offset in the appvar. That is where the next character will be read from/written to. So if you set the offset to be 10, then Write will overwrite character 10 and so on. This pointer is quite useful, because it increments after each read/write; in other words, access to the file is normally sequential. When opening or creating an appvar the pointer (offset) is set to 0 (except when you open with mode "a" or "a+", then it's the appvar size). The main advantage of using a pointer above writing directly to the appvar is that you can overwrite random memory when doing it directly. If you use a pointer, you're protected against that. Besides that, because the pointer increases after each read/write, you can continuously read or write characters to/from the appvar without worrying about incrementing the pointer yourself.

So let's take a look at the function itself:

Code:
Read(PTR,SIZE,COUNT,SLOT) - Reads COUNT times SIZE bytes from the variable in slot SLOT and copies everything to PTR. If everything went right, this function returns SIZE or 0 if on failure. SIZE*COUNT is added to the variable offset.

SLOT is just the slot number returning from Open or OpenVar. SIZE is the amount of characters you want to read from the appvar. Warning: if you want to read too much characters, you will read random memory after the appvar!. COUNT is the amount of sequences you want to read. In normal cases, this is just 1, since you only need to read all the data once. However, if you want to use the data twice, without copying yourself, or even more times, you can change this to a higher number. PTR is the pointer where the data is written to. This can be either one of the OS variables, some allocated memory or program data. Note that this function doesn't magically allocate memory!

... In Progress...
  
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement