Hey! That crummy file downloader written in Vala doesn't work with the Rathole Radio Ogg feed. What gives?
I'm glad you asked. In higher level programming languages, it is quite common to have the ability to read chunks of data from an HTTP stream when using a module or library designed to handle HTTP traffic. However, since the Vala based downloader uses low-level sockets to read from the stream, it is up to the developer to implement reading of Chunked HTTP data.
In parsing terms, the format is quite simple:
- Read a line from the steam. This will be a number and it represents the number of bytes of data in the chunk. We'll call it "x"
- Read "x" number of bytes from the next line. This is a "chunk" of data.
- repeat until "x" is equal to 0
While that should be nice and easy, the number of bytes that are supposed to be read is in hexadecimal and I couldn't find a Vala function to convert a hexadecimal string into an integer value. After spending way too much time searching for a solution, I took the DIY approach and hacked together a few functions to do exactly what I needed to do.
So without further ado, here is my Vala code to convert a hexadecimal string to an integer.
Enter the Vala
switch(c) {
case "a":
return 10;
case "b":
return 11;
case "c":
return 12;
case "d":
return 13;
case "e":
return 14;
case "f":
return 15;
default:
return int.parse(c);
}
}
public int64 hextoint(string hex){
//convert the string to lowercase
string hexdown = hex.down();
//get the length of the hex string
int hexlen = hex.length;
int64 ret_val = 0;
string chr;
int chr_int;
int multiplier;
//loop through the string
for (int i = 0; i < hexlen ; i++) {
//get the string chars from right to left
int inv = (hexlen-1)-i;
chr = hexdown[inv:inv+1];
chr_int = hexval(chr);
//how are we going to multiply the current characters value?
multiplier = 1;
for(int j = 0 ; j < i ; j++) {
multiplier *= 16;
}
ret_val += chr_int * multiplier;
}
return ret_val;
}
public static void main() {
string[] hexvals = {"9AC3","1234","b525","abcdef","bbb"};
int64 i;
foreach( string hexval in hexvals) {
i = hextoint(hexval);
stdout.printf(@"$hexval = $i\n");
}
}
Only the hextoint and hexval functions are needed, but I though it would be nice to add a bit of code to use the fuctions.
Alright, now that that is done, it's time to implement the reading of Chunked data in the downloader so that eventually I will be able to add audcatching functionality to MuttonChop.
c'est plus concis
<code>
public int hexval(string c)
{
string ref = "0123456789abcdef";
return ref.index_of(c);
}
</code>
I hope there will be a substitute before the deprecated version vanishes.