On Sun, Feb 01, 2009 at 11:58:34AM -0500, Josh Kropf wrote: > The iostream class library is supposed to be a framework for "streams > of data" so in that sense it's not just about files. It's true that > the standard library only has implementations for streams from files > (and stringd) but if we stick to using references of std::istream and > std::ostream in the API then that leaves it open to other > implementations of these classes. This simplifies the code in > JavaLoader. Take GetScreenShot for example. Currently the Data class > is used to resize a buffer and append bytes to it:
Sorry for the delay. I gave this some thought the other day, and I think iostreams is the right way to go where it makes sense. Perhaps in addition to the APIs we have now (see below for example and reasoning). Iostreams gives the programmer the option of writing directly to files or to a memory buffer, while we use the same code for both, and this would help optimize memory usage. I was bothered about the fact that large COD modules are kicking around in memory, and making better use of iostreams could fix this as well. > The iostream class library is supposed to be a framework for "streams > of data" so in that sense it's not just about files. It's true that > the standard library only has implementations for streams from files > (and stringd) but if we stick to using references of std::istream and > std::ostream in the API then that leaves it open to other > implementations of these classes. This simplifies the code in > JavaLoader. Take GetScreenShot for example. Currently the Data class > is used to resize a buffer and append bytes to it: > > // Copy data > unsigned char *buffer = image.GetBuffer(image.GetSize() + bytereceived); > memcpy(buffer + image.GetSize(), pd + 4, bytereceived); > > // New size > image.ReleaseBuffer(image.GetSize() + bytereceived); > > > Switching to std::ostream would simplify this to: > > output.write (response.GetData() + 4, bytereceived); I think if we look at things at a higher level, the idea of iostreams exposes a hole in the current API that I overlooked, but doesn't necessarily say that iostreams works for GetScreenshot(). Currently, the screenshot API gives access to the raw Blackberry screenshot data, as well as an API to convert this data into BMP format. This is different from every other part of the Barry API, which sanitizes all raw Blackberry data into a usable format (or tries to). Screenshot capture is a two stage process, with two buffers to hold the data. One buffer for raw data, and one for BMP. And everyone wants the BMP data... the raw buffer is only an intermediate step that could be hidden by the library. Converting from Blackberry image format to BMP (or something else, maybe JPG) format, isn't a process that is easily done in a stream. (And probably why programs like ImageMagick always take lots of memory to process photos.) The first pixels we get from the device are the last ones we'd be writing to the BMP stream, so there needs to be some buffering anyway. At least one buffer to hold the raw data. So I don't think GetScreenshot() is an iostreams candidate, but I do think it should return a BMP directly, and not the raw data. Perhaps the Raw-to-BMP conversion function is an iostreams candidate. > Could also add a method to Data class to simplify this further: > > // Write data to the output stream > /// \param output output stream to write to > /// \param offset offset into data buffer to begin writing > /// \param length length of data to write, defaults to remaining data > Data::Write(std::ostream &output, size_t offset = 0, size_t length = > -1); It probably makes more sense to do: cout.write(data.GetData(), data.GetSize()); I think Data::Write() should be reserved for an I/O style API for writing *into* a Data object. Similar to your iostreams example: data.Write (response.GetData() + 4, bytereceived); > Looking at the Boost libraries there is an example of setting up HTTP > (or basic TCP socket) sessions and they use iostream classes, eg: > > http://www.boost.org/doc/libs/1_37_0/doc/html/boost_asio/example/http/client/sync_client.cpp > > This could be used to stream the cod file from a web server for loading > to the device for example. Nice. > For memory only streams, I think the std::ostringstream class would > work. One could also write a simple implementation of std::streambuf > and use it to create std::ostream. Again in Boost, it looks like there > is another library that simplifies this and makes it more robust. > > http://www.boost.org/doc/libs/1_37_0/libs/iostreams/doc/index.html Boost's version of iostreams do look pretty powerful. I keep wanting to play with them. :-) It might be useful to use a Data object as a streambuf buffer, depending on the platform. The current iostream way of writing to memory would be something like this: std::ostringstream bitmap; // 1 javaloader.GetScreenshotBMP(bitmap); // 2 std::string bitbuf = bitmap.str(); // 3 Data hexdump(bitbuf.data(), bitbuf.size()); // 4 cout << hexdump << endl; // 5 The only reason for adding a datastreambuf class would be for those platforms that don't have copy-on-write std::strings. In that case, there would be a redundant copy at line 3. Line 4 doesn't copy, it just uses a pointer, which is why a bitbuf object is needed in line 3. Summary: please submit your Save() patch using iostreams. :-) - Chris ------------------------------------------------------------------------------ Create and Deploy Rich Internet Apps outside the browser with Adobe(R)AIR(TM) software. With Adobe AIR, Ajax developers can use existing skills and code to build responsive, highly engaging applications that combine the power of local resources and data with the reach of the web. Download the Adobe AIR SDK and Ajax docs to start building applications today-http://p.sf.net/sfu/adobe-com _______________________________________________ Barry-devel mailing list Barry-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/barry-devel