Liste des Groupes | Revenir à cl c |
There's a good reason for sth. like #embed: I just wrote a very quick
xxd alternative and generated a C-file with a char-array and the size
of this file is 1,2GB. MSVC quitted compilation after allocating 50GB
of memory, gcc and clang compiled for minutes. This would be better
with an #embed-Tag. So there's really good reason for that.
This is my xxd-substitude. Compared to xxd it only can dump C-files.
On my PC it's about 15 times faster than xxd because it does its own
I/O-buffering.
#include <iostream>
#include <fstream>
#include <charconv>
#include <span>
#include <vector>
using namespace std;
int main( int argc, char **argv )
{
if( argc < 4 )
return EXIT_FAILURE;
char const
*inFile = argv[1],
*symbol = argv[2],
*outFile = argv[3];
ifstream ifs;
ifs.exceptions( ifstream::failbit | ifstream::badbit );
ifs.open( inFile, ifstream::binary | ifstream::ate );
streampos size( ifs.tellg() );
if( size > (size_t)-1 )
return EXIT_FAILURE;
ifs.seekg( ifstream::beg );
union ndi { char c; ndi() {} };
vector<ndi> rawBytes( size );
span<char> bytes( &rawBytes.data()->c, rawBytes.size() );
ifs.read( bytes.data(), bytes.size() );
ofstream ofs;
ofs.exceptions( ofstream::failbit | ofstream::badbit );
ofs.open( outFile );
vector<ndi> rawBuf( 0x100000 );
span<char> buf( &rawBuf.begin()->c, rawBuf.size() );
ofs << "unsigned char " << symbol << "[" << (size_t)size << "] = \n{\n";
auto rd = bytes.begin();
auto wrt = buf.begin();
auto flush = [&]
{
ofs.write( buf.data(), wrt - buf.begin() );
wrt = buf.begin();
};
while( rd != bytes.end() )
{
size_t remaining = bytes.end() - rd;
constexpr size_t N_LINE = 1 + 12 * 6 - 1 + 1;
size_t n = remaining > 12 ? 12 : remaining;
auto rowEnd = rd + n;
*wrt++ = '\t';
do
{
*wrt++ = '0';
*wrt++ = 'x';
char *wb = to_address( wrt );
(void)(wrt + 2);
auto tcr = to_chars( wb, wb + 2, (unsigned char)*rd++, 16 );
if( tcr.ptr == wb + 1 )
wb[1] = wb[0],
wb[0] = '0';
wrt += 2;
if( rd != bytes.end() )
{
*wrt++ = ',';
if( rd != rowEnd )
*wrt++ = ' ';
}
} while( rd != rowEnd );
*wrt++ = '\n';
if( buf.end() - wrt < N_LINE )
flush();
}
flush();
ofs << "};\n" << endl;
}
Les messages affichés proviennent d'usenet.