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 #14319
Maybe std.memory.DataBuffer class is what you need.April 11, 2018 at 8:43 am #14320
Okay 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 #14321
But 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
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 #14323
DataBuffer is probably better for a load of bytes, or a simple byte array in your struct/class?Monkey12345678910111213141516[crayon-5b54473c06a90935051339 inline="true" ]#Import "<std>"Using std..Class TestField bytes:Byte EndFunction Main ()Local t:Test = New Testt.bytes = New Byte EndApril 11, 2018 at 5:57 pm #14325
That’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 #14326
Docs 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!)Monkey1234567891011121314151617181920212223242526272829303132[crayon-5b54473c0e094398617776 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 #14327
Hmm, 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…Monkey12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455[crayon-5b54473c12e2f115880752 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 )Print String.FromChar (t.bytes.Data )file.Close ()ElsePrint "Failed"EndifEndifEndApril 13, 2018 at 6:07 am #14331
Thanks! 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 #14332
Let 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 #14349
Ha, nicely done.April 13, 2018 at 8:56 pm #14353
Oh I like that.
You must be logged in to reply to this topic.