About Monkey 2 › Forums › Monkey 2 Programming Help › Read data restore?
Tagged: array, bytes, file exists, file size, file system, file type, filesize, filesystem, filetype
This topic contains 11 replies, has 3 voices, and was last updated by
Gwenel
1 year ago.
-
AuthorPosts
-
April 10, 2018 at 11:34 am #14314
I like to use expressions with variables and mix datatypes in DATA statements when storing information, and to put labels here and there to remind myself and being able to skip portions early.
What are your favourite replacements of READ DATA RESTORE statements when you use Monkey2?
April 11, 2018 at 2:52 am #14319Maybe std.memory.DataBuffer class is what you need.
April 11, 2018 at 8:43 am #14320Okay I was thinking of using STRUC (or CLASS) as you can have FIELD’s with expressions that includes constants and hopefully also the variables I need, but I’m open to absolutely everything. How would I use DataBuffer to structure data?
April 11, 2018 at 8:52 am #14321But I couldn’t find a primitive that can hold a huge amount of pure information such as bytes? Are Strings meant for that?
What are strings stored as internally UTF8 16 or 32 or some other thing?
I would like to store a file or raw numbers inside a string (perhaps) neatly.I’m thinking something like this
DATA
FIELD “NAME” : STRING
FIELD “SESSION” : STRING
FIELD 10 : INT
FIELD 16*4+Z : INT ‘ expression with variables and constants
FIELD A$ + ” seconds” : STRING
FIELD True : Bool
FIELD file.bin : RAW AS FILE
FIELD “FA789AB22FF009” : RAW AS STRING
END DATAApril 11, 2018 at 4:42 pm #14323DataBuffer is probably better for a load of bytes, or a simple byte array in your struct/class?
[/crayon]Monkey12345678910111213141516[crayon-5cb9db90847fe339764043 inline="true" ]#Import "<std>"Using std..Class TestField bytes:Byte []EndFunction Main ()Local t:Test = New Testt.bytes = New Byte [1024]EndApril 11, 2018 at 5:57 pm #14325That’s great!
But exactly how could I check the existence and size of a file, set the size correctly of the array and finally load it in? I’m trying to understand the documentation but it’s really not as easy as I would’ve have thought.
April 12, 2018 at 9:48 pm #14326Docs are a bit tricky (WIP!), but this is how I would go about it, guessing that functions for interacting with files are likely going to be part of std… clicking into the std tree under Ted’s Docs tab, then finding std.filesystem, then going through the function list:
Amend f:String to the file you want to check. (Demo may or may not work as-is… never assume system paths like this, or that OS is even Windows!)
[/crayon]Monkey1234567891011121314151617181920212223242526272829303132[crayon-5cb9db9088df7806817104 inline="true" ]' IGNORE CRAYON CRAP IF SHOWN ABOVE#Import "<std>"Using std..Class TestField bytes:Byte []EndFunction Main ()Local t:Test = New TestLocal f:String = "C:\Windows\System32\notepad.exe"If GetFileType (f) = FileType.FilePrint "File " + f + " found!"Print "File size is " + GetFileSize (f) + " bytes"' Resize array to match file size:t.bytes = New Byte [GetFileSize (f)]Print "Array is " + t.bytes.Length + " bytes"EndifEndApril 12, 2018 at 10:24 pm #14327Hmm, wasn’t able to get FileStream.ReadAll to read into the array without crashing (no idea why), so suggest using DataBuffer instead! Gives you a block of unsigned bytes, much like a byte array…
[/crayon]Monkey12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455[crayon-5cb9db908c05d244823078 inline="true" ]' IGNORE CRAYON CRAP IF SHOWN ABOVE#Import "<std>"Using std..Class TestField bytes:DataBufferEndFunction Main ()Local t:Test = New TestLocal f:String = "C:\Windows\System32\notepad.exe" ' Never assume system paths!If GetFileType (f) = FileType.FilePrint "File " + f + " found!"Print "File size is " + GetFileSize (f) + " bytes"t.bytes = New DataBuffer (GetFileSize (f))Print "Data buffer is " + t.bytes.Length + " bytes"' TEMP WINDOWS BUG WORKAROUND! Reported at https://github.com/blitz-research/monkey2/issues/370f = f.Replace ("\", "/")Local file:FileStream = FileStream.Open (f, "r")If filePrint "Opened"' Read file into data buffer...Print file.ReadAll (t.bytes, 0, t.bytes.Length)' Start of a Win32 executable is always "MZ" (for Mark Zbikowski, DOS developer!):Print String.FromChar (t.bytes.Data [0])Print String.FromChar (t.bytes.Data [1])file.Close ()ElsePrint "Failed"EndifEndifEndApril 13, 2018 at 6:07 am #14331Thanks! Okay, it seem abit complex to just add a file into the mix but I’ll try to understand how it works.
April 13, 2018 at 6:35 am #14332Let me simplify code given above.
DataBuffer class has Load method – use it instead of FileStream etc.
Also there is a PeekString (for this example) and many other methods to operate with bytes in buffer – read docs of them.
My version:
Monkey123456789101112131415161718192021222324252627282930313233343536373839#Import "<std>"#Import "assets/"Using std..Class TestMethod New( path:String )bytes=DataBuffer.Load( path )Assert( bytes<>Null,"Can't load data from "+path+"!" )EndProperty Bytes:DataBuffer() ' make public read-only propertyReturn bytesEndPrivateField bytes:DataBufferEndFunction Main ()' first: place netepad.exe into /assets/ folder near this source fileLocal t := New Test( "asset::notepad.exe" )Local buf:=t.Bytes ' assign to local to use short variablePrint "Data buffer is " + buf.Length + " bytes"' Start of a Win32 executable is always "MZ" (for Mark Zbikowski, DOS developer!):Print buf.PeekString( 0,1 )Print buf.PeekString( 1,1 )EndApril 13, 2018 at 5:16 pm #14349Ha, nicely done.
April 13, 2018 at 8:56 pm #14353Oh I like that.
-
AuthorPosts
You must be logged in to reply to this topic.