Is there an easy way to read a string from a file and read it in little endian format to convert to int? I have some old file formats that I want to convert, and header information is stored in little endian format. So far I have something like this for a WORD (2-bytes): Stdio.File fp;fp=Stdio.File(filename,"r");string str=fp->read(2);int res=array_sscanf(reverse(str),"%2c")[0]; Trying to find an easy way to make it variable, like 2 or 4 byte ints (there are some DWORDs in the file too). array_sscanf doesn't take parameters for the format, so I can't do "%*c",2 . Thanks..
Lance Dillon wrote:
Stdio.File fp;fp=Stdio.File(filename,"r");string str=fp->read(2);int res=array_sscanf(reverse(str),"%2c")[0];
Using %2c to read little endian probably only works on CPUs that are little endian to begin with.
Trying to find an easy way to make it variable, like 2 or 4 byte ints (there are some DWORDs in the file too).?? array_sscanf doesn't take parameters for the format, so I can't do "%*c",2 .
The best you can do at the moment, would be to read the whole file into a Stdio.Buffer, and then use read_int8() to pick it apart.
We could extend Stdio.Buffer.read_int() to support what has been discussed before, that when you specify n<0, it would do little endian instead of big endian.
On Thu, Nov 17, 2016 at 11:37 AM, Stephen R. van den Berg srb@cuci.nl wrote:
Lance Dillon wrote:
Stdio.File fp;fp=Stdio.File(filename,"r");string str=fp->read(2);int res=array_sscanf(reverse(str),"%2c")[0];
Using %2c to read little endian probably only works on CPUs that are little endian to begin with.
To quote from sscanf() documentation:
"%c" Reads one character and returns it as an integer ("0101" makes 48, or '0', leaving "101" for later directives). Using the field width and endianness modifiers, you can decode integers of any size and endianness. For example "%-2c" decodes "0101" into 12592, leaving "01" fot later directives. The sign modifiers can be used to modify the signature of the data, making "%+1c" decode "ä" into -28.
"-" Supplying a minus sign toggles the decoding to read the data encoded in little-endian byte order, rather than the default network (big-endian) byte order.
Ah, there we go. I tried to find sscanf, but it isn't on the Pike Reference Manual - namespace predef
| | | Pike Reference Manual - namespace predef | |
|
Module Tree Reference. I had to go to the main doc page and search for sscanf. printf also isn't listed. Is it missing, or am I just missing it? array_sscanf is present, and says it uses the same format specifiers as sscanf, but didn't have a link to sscanf. That does exactly what I need, thanks.
On Thursday, November 17, 2016 6:20 AM, Tobias S. Josefowitz t.josefowitz@gmail.com wrote:
On Thu, Nov 17, 2016 at 11:37 AM, Stephen R. van den Berg srb@cuci.nl wrote:
Lance Dillon wrote:
Stdio.File fp;fp=Stdio.File(filename,"r");string str=fp->read(2);int res=array_sscanf(reverse(str),"%2c")[0];
Using %2c to read little endian probably only works on CPUs that are little endian to begin with.
To quote from sscanf() documentation:
"%c" Reads one character and returns it as an integer ("0101" makes 48, or '0', leaving "101" for later directives). Using the field width and endianness modifiers, you can decode integers of any size and endianness. For example "%-2c" decodes "0101" into 12592, leaving "01" fot later directives. The sign modifiers can be used to modify the signature of the data, making "%+1c" decode "ä" into -28.
"-" Supplying a minus sign toggles the decoding to read the data encoded in little-endian byte order, rather than the default network (big-endian) byte order.
But, I found something even easier. It's been a while since I've used it, but I remembered ADT.Struct, and it has Drow() and Gnol() types, which are Intel (little-endian) versions of Word() and Long() types. Those do exactly what I need, so even easier. Basically I'm writing a program to convert old dos grasp .gl files, which contain Pictor PC Paint .pic files, into individual images, possibly gif or png format. I'm going to skip the actual automation or anything, just write out the individual files.
On Thursday, November 17, 2016 9:11 AM, Lance Dillon riffraff169@yahoo.com wrote:
Ah, there we go. I tried to find sscanf, but it isn't on the Pike Reference Manual - namespace predef
| | | Pike Reference Manual - namespace predef | |
|
Module Tree Reference. I had to go to the main doc page and search for sscanf. printf also isn't listed. Is it missing, or am I just missing it? array_sscanf is present, and says it uses the same format specifiers as sscanf, but didn't have a link to sscanf. That does exactly what I need, thanks.
On Thursday, November 17, 2016 6:20 AM, Tobias S. Josefowitz t.josefowitz@gmail.com wrote:
On Thu, Nov 17, 2016 at 11:37 AM, Stephen R. van den Berg srb@cuci.nl wrote:
Lance Dillon wrote:
Stdio.File fp;fp=Stdio.File(filename,"r");string str=fp->read(2);int res=array_sscanf(reverse(str),"%2c")[0];
Using %2c to read little endian probably only works on CPUs that are little endian to begin with.
To quote from sscanf() documentation:
"%c" Reads one character and returns it as an integer ("0101" makes 48, or '0', leaving "101" for later directives). Using the field width and endianness modifiers, you can decode integers of any size and endianness. For example "%-2c" decodes "0101" into 12592, leaving "01" fot later directives. The sign modifiers can be used to modify the signature of the data, making "%+1c" decode "ä" into -28.
"-" Supplying a minus sign toggles the decoding to read the data encoded in little-endian byte order, rather than the default network (big-endian) byte order.
Lance Dillon wrote:
But, I found something even easier.?? It's been a while since I've used it, but I remembered ADT.Struct, and it has Drow() and Gnol() types, which are Intel (little-endian) versions of Word() and Long() types.?? Those do exactly what I need, so even easier.
Indeed. Forgot about that one too.
Basically I'm writing a program to convert old dos grasp .gl files, which contain Pictor PC Paint .pic files, into individual images, possibly gif or png format.?? I'm going to skip the actual automation or anything, just write out the individual files.
I once wrote something for that, but it was in C (it took them apart and reconstructed them). Not quite sure where that source code ended up. That was even before CVS existed.
Tobias S. Josefowitz wrote:
On Thu, Nov 17, 2016 at 11:37 AM, Stephen R. van den Berg srb@cuci.nl wrote:
Lance Dillon wrote:
Stdio.File fp;fp=Stdio.File(filename,"r");string str=fp->read(2);int res=array_sscanf(reverse(str),"%2c")[0];
Using %2c to read little endian probably only works on CPUs that are little endian to begin with.
"%c"
...
"-" Supplying a minus sign toggles the decoding to read the data encoded in little-endian byte order, rather than the default network (big-endian) byte order.
RTFM, thanks. Well, in any case, using Stdio.Buffer.sscanf() then still is the recommended way.
Yeah, I found the ADT.Struct type with Gnol and Drow. However, the documentation on the website gave me trouble. I couldn't find an index to the left, just the modules themselves, so when I clicked on ADT, I couldn't see all the methods and click on them individually, I had to click on links at the top for next method, and so on until I found what I needed. I should also have thought of concatenating strings for the field width.
On Tuesday, November 22, 2016 11:46 PM, "Marcus Comstedt (ACROSS) (Hail Ilpalazzo!) @ Pike (-) developers forum" 10353@lyskom.lysator.liu.se wrote:
Using %2c to read little endian probably only works on CPUs that are little endian to begin with.
No, that would just be broken. %2c is well defined to be big endian, and %-2c is well defined to be little endian. Why would what CPU you have matter?
The index works for me. If you were unable to find Gnol and Drow in the list of methods that's probably because they are classes and not methods. :-) Click "MODULE REFERENCE" -> "ADT" -> "Struct" and both "Drow" and "Gnol" appear in the class list to the left.
Weird, I don't know what page I was getting then.. hmmm
Sent from Yahoo Mail on Android
On Wed, Nov 23, 2016 at 8:30 AM, Marcus Comstedt (ACROSS) (Hail Ilpalazzo!) @ Pike (-) developers forum10353@lyskom.lysator.liu.se wrote: The index works for me. If you were unable to find Gnol and Drow in the list of methods that's probably because they are classes and not methods. :-) Click "MODULE REFERENCE" -> "ADT" -> "Struct" and both "Drow" and "Gnol" appear in the class list to the left.
For starters, there is no need to call reverse. Just use "%-2c" in the sscanf format string for backwards endianness. Secondly, while you can't use "%*c",2 you _can_ use "%"+2+"c", if that is what you need. (Most headers have a fixed format where you know the sizes beforehand though, meaning you can just do something like 'sscanf(fp->read(10), "%-4c%-2c%-2c%-2c", a, b, c, d)'...)
You can also take a look at ADT.Struct, which supports backwards endians through the "Drow" and "Gnol" classes.
If someone could just come up with a good name, we should add little endian integers to Stdio.Buffer. read_int16_le()?
pike-devel@lists.lysator.liu.se