24.04.2017, 21:44
(
Last edited by IllidanS4; 03/10/2017 at 10:58 AM.
)
i_lstr
Download
AboutDownload
This include introduces a new type of string, internally called an "lstring". This kind of a string contains along the character data also the string's length, which means it can store the '\0' character and obtaining its length is done in constant time. This include also contains functions to manipulate lstrings like normal strings, deleting, inserting and file manipulation. Due to the way the length is stored in the string, it can be passed to normal SA-MP natives without any issue (although it will be cropped after the first null character in it).
Introduction
Null-terminated strings (using the '\0' character to mark the end of a string) are a relic from the old days where memory was scarce. Although they are able to store potentially unlimited number of characters, the null character cannot be used in them, creating a potential security issue.
Pawn arrays are formed from cells, each 4 bytes wide. However, most of you use unpacked strings, which simply fill only the lower 8 bits (1 byte) in a string cell, making your script size 4 times larger than it should be. In contrast, packed strings can stuff 4 characters into a single cell (starting from the most significant byte in the cell). You can prefix any string with '!' (like !"Hello world") and it will denote a packed string.
You can pass both packed and unpacked strings to functions in SA-MP and they will work as usual. How does the server know what type string you've provided? By looking at the most significant byte in a cell. As packed strings start character data from this position, it will always be non-zero and contain valid character (or null character if the string is empty).
However, if the top byte is empty, the server recognizes an unpacked string and ignores the two bytes in the middle of the cell. This leaves us with 65536 possible additional "metadata" values for a single character. I have decided to store the length of the string starting at the position of the character there, but other values can be placed there too. Because the server simply ignores the additional data when calling native functions, they will work normally when given an lstring (it is still terminated with a null character for compatibility reasons). Because the length is inserted at all positions in the string, passing a substring to a function (indexing the string) is also an lstring. Thanks to this, you can instantly know the end of the string from any place in it.
Functions
Code:
lstrnew(string[], length=-1)
Code:
strc(string[], pos)
Code:
lstrgetc(const lstring[], pos)
Code:
lstrsetc(lstring[], pos, value)
Code:
lstrsetlen(lstring[], newlength, padding='\0')
Code:
strtype(const string[])
Code:
lstrlen(const lstring[])
Code:
stranylen(const string[])
Code:
lstrdel(lstring[], start, end)
Code:
lstrins(lstring[], const substr[], pos, maxlength=sizeof(lstring))
Code:
lstrcat(ldest[], const source[], maxlength=sizeof(ldest))
Code:
lfwrite(File:handle, lstring[])
Code:
lfread(File:handle, lstring[], size=sizeof(lstring))
Example
Code:
new text[] = "Hello 1 2 3"; lstrnew(text); //Initializes an lstring strc(text, 5) = '\0'; //Changes the space at text[5] to '\0' lstrdel(text, 0, 4); //Deletes the first 5 characters lstrins(text, "Hi", 0); //Inserts "Hi" at their place printf("%d %d %s", lstrlen(text), lstrgetc(text, 2), text);
Download
At the top of this topic.