TinyXML: how to parse a file pointer - c++

I'm trying to connect the output of popen, a file pointer, to the input of TinyXML.
According to the main page, the best way to do it is using the parse method:
C style input:
* based on FILE*
* the Parse() and LoadFile() methods
I believe I need to use the TIXML_USE_STL to get to this. How do I go about finding examples and import it?
A reply since deleted pointed me in the right direction on the docs
http://www.grinninglizard.com/tinyxmldocs/index.html
Thanks.
Now, i just need to figure out how to link and import it.

I'm not hugely familiar with TinyXML, but does LoadFile() not work in its overloaded version which takes a FILE *?
http://www.grinninglizard.com/tinyxmldocs/classTiXmlDocument.html#a12
EDIT: Ah, the problem is that TinyXML doesn't support reading from a stream (see the link above). Your only choice then is to read the stream manually into a buffer and pass it to TinyXML's Parse().

You can read the file data into some buffer (say SomeCharBuffer), append null terminator to it and do
TiXmlDocument doc;
doc.Parse(SomeCharBuffer);

Related

Get raw buffer for in-memory dataset in GDAL C++ API

I have generated a GeoTiff dataset in-memory using GDALTranslate() with a /vsimem/ filepath. I need access to the buffer for the actual GeoTiff file to put it in a stream for an external API. My understanding is that this should be possible with VSIGetMemFileBuffer(), however I can't seem to get this to return anything other than nullptr.
My code is essentially as follows:
//^^ GDALDataset* srcDataset created somewhere up here ^^
//psOptions struct has "-b 4" and "-of GTiff" settings.
const char* filep = "/vsimem/foo.tif";
GDALDataset* gtiffData = GDALTranslate(filep, srcDataset, psOptions, nullptr);
vsi_l_offset size = 0;
GByte* buf = VSIGetMemFileBuffer(filep, &size, true); //<-- returns nullptr
gtiffData seems to be a real dataset on inspection, it has all the appropriate properties (number of bands, raster size, etc). When I provide a real filesystem location to GDALTranslate() rather than the /vsimem/ path and load it up in QGIS it renders correctly too.
Looking a the source for VSIGetMemFileBuffer(), this should really only be returning nullptr if the file can't be found. This suggests i'm using it incorrectly. Does anyone know what the correct usage is?
Bonus points: Is there a better way to do this (stream the file out)?
Thanks!
I don't know anything about the C++ API. But in Python, the snippet below is what I sometimes use to get the contents of an in-mem file. In my case mainly VRT's but it shouldn't be any different for other formats.
But as said, I don't know if the VSI-api translate 1-on-1 to C++.
from osgeo import gdal
filep = "/vsimem/foo.tif"
# get the file size
stat = gdal.VSIStatL(filep, gdal.VSI_STAT_SIZE_FLAG)
# open file
vsifile = gdal.VSIFOpenL(filep, 'r')
# read entire contents
vsimem_content = gdal.VSIFReadL(1, stat.size, vsifile)
In the case of a VRT the content would be text, shown with something like print(vsimem_content.decode()). For a tiff it would of course be binary data.
I came back to this after putting in a workaround, and upon swapping things back over it seems to work fine. #mmomtchev suggested looking at the CPL_DEBUG output, which showed nothing unusual (and was silent during the actual VSIGetMemFileBuffer call).
In particular, for other reasons I had to put a GDALWarp call in between calling GDALTranslate and accessing the buffer, and it seems that this is what makes the difference. My guess is that GDALWarp is calling VSIFOpenL internally - although I can't find this in the source - and this does some kind of initialisation for VSIGetMemFileBuffer. Something to try for anyone else who encounters this.

Convert Arduino fs:File* into c++ std::File*

it seemed too easy. I stored an xml file on a sdcard connected to my esp32.
I use the SD.open() function to access the files stored on the sdcard. For parsing the xml file I downloaded the tinyxml2 library and tried to use the xmlDocument.LoadFile() function.
The problem is that the xmlDocument.LoadFile function is using a std::File pointer. The SD.open() function return an fs::File pointer.
The resulting error message in my ArduinoIDE is:
No matching function for call to tinyxml2::XMLDocument::LoadFile(fs::File*).
Does anybody has an idea how to convert the fs::File* into std::File*?
Thank you very much!
tinyxml2 lib:tinyxml2 lib
Thank you so much.
as #Galik mentioned, his hint was the key for me. But in the long run #Juraj suggestion to use json the better way.

how to read binary file data using dlang

I'm trying to read struct data from specific position in a a binary file.
Found out that I can use import std.stdio and its File, however all i seem to find is all about string handling.
I have c-code written data on binary files that compose of several different structs and they all, as far as I understand coding lay in a oneliner. In order to find specific struct I need to, like in old c,
Open file for reading .... (binary read??)
using sizeof and move to startposition of struct data to read
read data (struct.sizeof data) into receivingbuffer and
Close file
Documentation for std.stdio.File # read talks about reading entire or up to size but can't find how to read as below c-code line?
fseek(filehandle, sizeof(firstStructData), SEEK_SET));
read(filehandle, (char *)nextReceivingBuffer, sizeof(nextReceivingBuffer))
Any ideas or hints?
Try File.seek and File.rawRead. They work like their C counterparts, but rawRead determines the read count from the size of the output buffer you hand it.

How to open a gzip file using fopen (or a function with the same return value as fopen) in C++?

I currently have some code reading files which are not compressed, it uses the following approach to read a file in C++
FILE* id = fopen("myfile.dat", "r");
after obtaining id, different parts of the code access the file using fread, fseek, etc.
I would like to adapt my code so as to open a gzip version of the file, e.g. "myfile.dat.gz" without needing to change too much.
Ideally I would implement a wrapper to fopen, call it fopen2, which can read both myfile.dat and myfile.dat.gz, i.e. it should return a pointer to a FILE object, so that the remaining of the code does not need to be changed.
Any suggestions?
Thank you.
PS: it would be fine to decompress the whole file in memory, if this approach provides a solution
zlib provides analogs of fopen(), fread(), etc. called gzopen(), gzread(), etc. for reading and writing gzip files. If the file is not gzip-compressed, it will be read just as the f functions would. So you would only need to change the function names and link in zlib.

Converting FILE * to CMemFile (or retrieving void* from FILE *)

I'm currently working with a function call that uses FILE *, but I need to get data from the FILE * into a buffer without letting the data touch the HDD. My first idea was to convert FILE * to a CMemFile, but I cannot find a way to do this. Any ideas?
Using MFC...
This question comes up from using the JPEG library by IJG whose homepage can be found here: http://www.ijg.org/
You can use setvbuf to make a FILE pointer use a predefined (and filled) buffer.