Posts: 20
Threads: 8
Joined: Sep 2019
Hello I am currently reading a file in binary mode.
I do the reading with
1 2 |
with open (args.rom_path, 'rb' ) as file :
rom_bytes = file .read ()
|
Then part of these rom_bytes are transferred to another variable with:
1 |
self .header = rom_bytes [ 0 :HEADER_SIZE]
|
and finally, one of the bytes stored in the header are transferred to a variable:
1 |
self .temp = self .header [ 4 ]
|
This value it is "2" in unsigned 8 bit, as a hexadecimal editor informs me.
However, the above line of code causes:
Quote:TypeError: 'int' does not support the buffer interface
So I need to convert into an int, a value that it is what, a byte?
How can I do it?
Posts: 817
Threads: 1
Joined: Mar 2018
Take a look at the struct module.
1 2 3 |
import struct
four_bytes = b 'abcd'
struct.unpack( "I" , four_bytes)
|
Posts: 4,802
Threads: 77
Joined: Jan 2018
Oct-06-2019, 06:38 AM
(This post was last modified: Oct-06-2019, 06:39 AM by Gribouillis.)
colt Wrote:However, the above line of code causes: Are you sure it's this line that causes this error message? If 'header' is a bytes string (which you can check by printing the type of the variable) there should be no problem accessing header[4] , and it must be an integer. In the worst case it could raise an IndexError.
Posts: 20
Threads: 8
Joined: Sep 2019
Oct-08-2019, 11:13 PM
(This post was last modified: Oct-08-2019, 11:14 PM by colt.)
(Oct-06-2019, 05:25 AM)scidam Wrote: Take a look at the struct module.
1 2 3 |
import struct
four_bytes = b 'abcd'
struct.unpack( "I" , four_bytes)
|
From what I see the difference is that you used "I" instead my "h". I changed it and didn't change the error message.
(Oct-06-2019, 06:38 AM)Gribouillis Wrote: Are you sure it's this line that causes this error message? If 'header' is a bytes string (which you can check by printing the type of the variable) there should be no problem accessing header[4] , and it must be an integer. In the worst case it could raise an IndexError.
It says line 11, which is the one that uses struct.unpack. I checked the type and it shows Quote:<class 'bytes'>
Posts: 4,802
Threads: 77
Joined: Jan 2018
Oct-09-2019, 05:51 AM
(This post was last modified: Oct-09-2019, 06:49 AM by Gribouillis.)
colt Wrote:It says line 11, which is the one that uses struct.unpack There is no struct.unpack in the original post. It will be much easier if you post the whole code that throws the exception, so that we can run it by ourselves.
Posts: 20
Threads: 8
Joined: Sep 2019
(Oct-09-2019, 05:51 AM)Gribouillis Wrote: colt Wrote:It says line 11, which is the one that uses struct.unpack There is no struct.unpack in the original post. It will be much easier if you post the whole code that throws the exception, so that we can run it by ourselves.
Ok here it is:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
from abc import ABCMeta, abstractmethod
import argparse
HEADER_SIZE = 16
KB_SIZE = 16384
class Instruction ( object ):
__metaclass_ = ABCMeta
def __init__ ( self ,identification_byte):
identity_byte = identification_byte
def test ( self ):
print ( "BOTO" )
@abstractmethod
def process ( self ):
print ( "Identifier Byte: {}" . format ( self .identity_byte))
@abstractmethod
def process2 ( self ):
print ( "Identifier Byte2: " , self .identity_byte)
class LDAInstruction (Instruction):
def process ( self ):
super .process ()
def process2 ( self ):
super .process()
class ROM ( object ) :
def __init__ ( self , rom_bytes):
self .header = rom_bytes [ 0 :HEADER_SIZE]
self .temp = self .header [ 4 ]
print ( type ( self .header))
self .num_prg_blocks = struct.unpack ( "I" , self .temp)
print ( type ( self .num_prg_blocks))
self .data_bytes = rom_bytes [HEADER_SIZE:HEADER_SIZE + ( 16 + KB_SIZE * int ( self .num_prg_blocks))]
self .total_size = 16 + KB_SIZE * self .num_prg_blocks
def get_byte ( self , pc):
return ( self .data_bytes [pc])
class CPU ( object ):
def __init__( self , rom_bytes):
self .registers = []
self .rom = ROM (rom_bytes)
self .pc = 0
def process_instructions ( self ):
for byte in self .rom.data_bytes:
byte = self .rom.get_byte ( self .pc)
self .pc + = 1
print (byte)
if (byte = = 169 ):
instruction = Instruction (byte)
instruction.process ()
instruction.process2 ()
if ( self .pc = = 3 ):
break
def main ():
parser = argparse.ArgumentParser (description = 'NES EMULATOR' );
parser.add_argument ( 'rom_path' ,metavar = 'R' , type = str , help = 'path to the rom' )
args = parser.parse_args()
with open (args.rom_path, 'rb' ) as file :
rom_bytes = file .read ()
cpu = CPU(rom_bytes)
cpu.process_instructions ()
if __name__ = = '__main__' :
main ()
|
However, this will not run because it needs a file as a command line argument.
Posts: 4,802
Threads: 77
Joined: Jan 2018
Could it be an error similar to this one ?
1 2 3 4 5 6 7 8 |
>>> rom_bytes = b 'hello world'
>>> import struct
>>> struct.unpack( "I" , rom_bytes[ 4 ])
Traceback (most recent call last):
File "<stdin>" , line 1 , in <module>
TypeError: a bytes - like object is required, not 'int'
>>> struct.unpack( "I" , rom_bytes[: 4 ])
( 1819043176 ,)
|
Posts: 20
Threads: 8
Joined: Sep 2019
(Oct-09-2019, 05:59 PM)Gribouillis Wrote: Could it be an error similar to this one ?
1 2 3 4 5 6 7 8 |
>>> rom_bytes = b 'hello world'
>>> import struct
>>> struct.unpack( "I" , rom_bytes[ 4 ])
Traceback (most recent call last):
File "<stdin>" , line 1 , in <module>
TypeError: a bytes - like object is required, not 'int'
>>> struct.unpack( "I" , rom_bytes[: 4 ])
( 1819043176 ,)
|
I don't understand why would be, since is a different error message.
Anyway, I don't know why, but now the code is working on python 3.2, since it converts the values to int. However in 2.6 where the type is 'str', first I receive
Quote:self.data_bytes = rom_bytes [HEADER_SIZE:HEADER_SIZE + (16 + KB_SIZE *(self.num_prg_blocks))]
TypeError: unsupported operand type(s) for +: 'int' and 'str'
Then adding a int before with:
1 |
self .data_bytes = rom_bytes [HEADER_SIZE:HEADER_SIZE + ( 16 + KB_SIZE * int ( self .num_prg_blocks))]
|
I receive:
Quote:ValueError: invalid literal for int() with base 10: '\x02'
finally doing this:
1 2 3 |
self .temp = self .num_prg_blocks
struct.unpack ( "I" , self .temp)
self .data_bytes = rom_bytes [HEADER_SIZE:HEADER_SIZE + ( 16 + KB_SIZE * self .temp)]
|
makes me receive on python 2.6
Quote:struct.error: unpack requires a string argument of length 4
and on python 3.2
Quote:TypeError: 'int' does not support the buffer interface
What shall be my next step?
Posts: 4,802
Threads: 77
Joined: Jan 2018
Oct-12-2019, 10:39 PM
(This post was last modified: Oct-12-2019, 10:39 PM by Gribouillis.)
colt Wrote:I don't know why, but now the code is working on python 3.2, since it converts the values to int. That's because in python 3 a bytes string is a sequence of small integers:
1 2 3 4 |
>>>
>>> x = b '\x02'
>>> x[ 0 ]
2
|
in python 2
1 2 3 4 |
>>>
>>> x = '\x02'
>>> x[ 0 ]
'\x02'
|
In python 2 you can convert a one character string to int by using the ord function
But when calling struct.unpack ("I", self.temp) , make sure self.temp is a 4 bytes string.
Finally, do you have to use python 2? Don't use it, it's dead.
Posts: 20
Threads: 8
Joined: Sep 2019
(Oct-12-2019, 10:39 PM)Gribouillis Wrote: colt Wrote:I don't know why, but now the code is working on python 3.2, since it converts the values to int. That's because in python 3 a bytes string is a sequence of small integers:
1 2 3 4 |
>>>
>>> x = b '\x02'
>>> x[ 0 ]
2
|
in python 2
1 2 3 4 |
>>>
>>> x = '\x02'
>>> x[ 0 ]
'\x02'
|
In python 2 you can convert a one character string to int by using the ord function
But when calling struct.unpack ("I", self.temp) , make sure self.temp is a 4 bytes string.
Finally, do you have to use python 2? Don't use it, it's dead.
Tried
1 |
self .num_prg_blocks = ord ( self .header [ 4 ])
|
and it solved this issue with old python, but with the new python I receive: Quote:TypeError: ord() expected string of length 1, but int found
To answer, I do not HAVE to use it, as mandatory
|