Reading entire file in memory?
#1
Could anyone share a piece of standard code to read an entire file in memory? I'm a noob when it comes to the XBMC C++ code, but eager to learn more of it Smile

I'd like to use it on an enhancement to the HTTP API TakeScreenshot where an additional parameter would specify whether to download the screenshot as binary or base64 encoded. I have a feeling that encoding the file in base64 is rather slow on Xbox and I'd like to speed it up by sending over the binary file as an option.

Thanks,
Dan
Reply
#2
Code:
CFile file;
char* buffer;
if (file.Open("/some/path/to/a/file"))
{
  buffer = new char[file.GetLength()];
  file.Read(buffer,file.GetLength());
}
file.Close();
Reply
#3
Thank Spiff, much appreciated!

Had a quick look at the CXbmcHttp::encodeFileToBase64() code and it used a fairly similar code - from what I could see using FileMon on Windows, the CFile.Read() does an unbuffered read, it only reads as much as you say it to, in this case 3 bytes at a time, which could be the at cause of lack of performance on Xbox.

Thanks for your code again, I'll try to use that to improve the speed on base64 encoding in XbmcHttp or preparing the binary image to be sent back as it is.
Reply
#4
if you want truncated reads, pass the flag on open. that would of course necessitate additional logic / code.
Reply
#5
The screenshot is created from memory, so you shouldn't have to hit the disk with it. I haven't looked at that code in quite awhile, so I won't speculate further.
Reply
#6
@althekiller
https://xbmc.svn.sourceforge.net/svnroot...MChttp.cpp

From what I understand it calls CUtils::TakeScreenshot that writes a .bmp file on disk (this is required since it calls the XGWriteSurfaceToFile() at least for Xbox is a XDK function), then it calls the CPicture.ConvertFile() to convert to a .jpg on disk again (this is CxImageLib I believe), then it encodes the .jpg file base64 (this is in memory, but it reads the input file in very small chunks).
Reply
#7
yes, it's different on xbox. as described ^^^
Reply
#8
Dan Dare Wrote:from what I could see using FileMon on Windows, the CFile.Read() does an unbuffered read, it only reads as much as you say it to, in this case 3 bytes at a time, which could be the at cause of lack of performance on Xbox.
What you're seeing is happening in userspace. A 3-byte read actually pulls a 256KB region of a file into system cache memory then does a 3-byte copy to userspace and returns the data. Subsequent sequential reads don't hit the disk at all and are returned directly from the 256KB file cache block.

It has been a long time since I've worked on an XBOX, and I don't have the resources to look it up any longer, but if I remember correctly the system kernel on the XBOX worked in the same way but with a much smaller cache. I want to say it had a small number of blocks the same size as the default hard drive's disk cluster (16KB). I could be completely misremembering this though.

That's really not important because I think the best thing to do though would be to use the XDK function to write it to a bmp file then use CxImage.Load() /Encode(...,CXIMAGE_FORMAT_JPG) and skip the intermediate jpg file altogether.
For troubleshooting and bug reporting please make sure you read this first.
Reply
#9
@CapnBry
Thanks, I'll try to do some timing and see which part take how long - I still think the part that may take too long (around 4 seconds for the whole round trip over the wire) is the one that does the base64 encoding and if possible to optimize that fine, if not then try to read and send the JPG file as it is.

That's what it does already, see the link below - then it's followed by the base64 encoding as the third step:
1) screen -> .bmp file (XDK),
2) .bmp file -> .jpg file (CxImage),
3) .jpg file -> base64 string (XBMChttp.c)

https://xbmc.svn.sourceforge.net/svnroot...MChttp.cpp
Reply

Logout Mark Read Team Forum Stats Members Help
Reading entire file in memory?0