|
Packit |
01d647 |
// ***************************************************************** -*- C++ -*-
|
|
Packit |
01d647 |
/*
|
|
Packit |
01d647 |
* This program is part of the Exiv2 distribution.
|
|
Packit |
01d647 |
*
|
|
Packit |
01d647 |
* This program is free software; you can redistribute it and/or
|
|
Packit |
01d647 |
* modify it under the terms of the GNU General Public License
|
|
Packit |
01d647 |
* as published by the Free Software Foundation; either version 2
|
|
Packit |
01d647 |
* of the License, or (at your option) any later version.
|
|
Packit |
01d647 |
*
|
|
Packit |
01d647 |
* This program is distributed in the hope that it will be useful,
|
|
Packit |
01d647 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
01d647 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
01d647 |
* GNU General Public License for more details.
|
|
Packit |
01d647 |
*
|
|
Packit |
01d647 |
* You should have received a copy of the GNU General Public License
|
|
Packit |
01d647 |
* along with this program; if not, write to the Free Software
|
|
Packit |
01d647 |
* Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
|
|
Packit |
01d647 |
*/
|
|
Packit |
01d647 |
/*
|
|
Packit |
01d647 |
Abstract : Tester application for BasicIo functions. Tests MemIo primarily
|
|
Packit |
01d647 |
since FileIo just sits atop of FILE* streams.
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
File : iotest.cpp
|
|
Packit |
01d647 |
Author(s): Brad Schick (brad) <brad@robotbattle.com>
|
|
Packit |
01d647 |
History : 04-Dec-04, brad: created
|
|
Packit |
01d647 |
*/
|
|
Packit |
01d647 |
// *****************************************************************************
|
|
Packit |
01d647 |
// included header files
|
|
Packit |
01d647 |
#include <exiv2/exiv2.hpp>
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
#include <cstdio> // for EOF
|
|
Packit |
01d647 |
#include <cstring>
|
|
Packit |
01d647 |
#include <iostream>
|
|
Packit Service |
fb147c |
#include <stdio.h>
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
using Exiv2::byte;
|
|
Packit |
01d647 |
using Exiv2::BasicIo;
|
|
Packit |
01d647 |
using Exiv2::MemIo;
|
|
Packit |
01d647 |
using Exiv2::FileIo;
|
|
Packit |
01d647 |
using Exiv2::IoCloser;
|
|
Packit |
01d647 |
using Exiv2::Error;
|
|
Packit |
01d647 |
using Exiv2::strError;
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
int WriteReadSeek(BasicIo &io);
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
// *****************************************************************************
|
|
Packit |
01d647 |
// Main
|
|
Packit |
01d647 |
int main(int argc, char* const argv[])
|
|
Packit |
01d647 |
{
|
|
Packit Service |
fb147c |
Exiv2::XmpParser::initialize();
|
|
Packit Service |
fb147c |
::atexit(Exiv2::XmpParser::terminate);
|
|
Packit Service |
fb147c |
|
|
Packit Service |
fb147c |
try {
|
|
Packit Service |
fb147c |
if (argc < 4 || argc > 6 ) {
|
|
Packit Service |
fb147c |
std::cout << "Usage: " << argv[0] << " filein fileout1 fileout2 [remote [blocksize]]\n"
|
|
Packit Service |
fb147c |
"copy filein to fileout1 and copy filein to fileout2\n"
|
|
Packit Service |
fb147c |
"fileout1 and fileout2 are overwritten and should match filein exactly\n"
|
|
Packit Service |
fb147c |
"\n"
|
|
Packit Service |
fb147c |
"You may optionally provide the URL of a remote file to be copied to filein\n"
|
|
Packit Service |
fb147c |
"If you use `remote`, you may optionally provide a blocksize for the copy buffer (default 10k)\n"
|
|
Packit Service |
fb147c |
;
|
|
Packit Service |
fb147c |
return 1;
|
|
Packit Service |
fb147c |
}
|
|
Packit Service |
fb147c |
const char* f0 = argv[1]; // fileIn
|
|
Packit Service |
fb147c |
const char* f1 = argv[2]; // fileOut1
|
|
Packit Service |
fb147c |
const char* f2 = argv[3]; // fileOut2
|
|
Packit Service |
fb147c |
const char* fr = argv[4]; // remote file
|
|
Packit Service |
fb147c |
const char* ba = argv[5]; // block argument
|
|
Packit Service |
fb147c |
|
|
Packit Service |
fb147c |
if ( argc >= 5 ) {
|
|
Packit Service |
fb147c |
int blocksize = argc==6 ? atoi(ba) : 10000;
|
|
Packit Service |
fb147c |
// ensure blocksize is sane
|
|
Packit Service |
fb147c |
if (blocksize>1024*1024) blocksize=10000;
|
|
Packit Service |
fb147c |
Exiv2::byte* bytes = blocksize>0 ? new Exiv2::byte[blocksize]: NULL;
|
|
Packit Service |
fb147c |
|
|
Packit Service |
fb147c |
// copy fileIn from a remote location.
|
|
Packit Service |
fb147c |
BasicIo::AutoPtr io = Exiv2::ImageFactory::createIo(fr);
|
|
Packit Service |
fb147c |
if ( io->open() != 0 ) {
|
|
Packit Service |
fb147c |
Error(Exiv2::kerFileOpenFailed, io->path(), "rb", strError());
|
|
Packit Service |
fb147c |
}
|
|
Packit Service |
fb147c |
FileIo output(f0);
|
|
Packit Service |
fb147c |
if ( !output.open("wb") ) {
|
|
Packit Service |
fb147c |
Error(Exiv2::kerFileOpenFailed, output.path() , "w+b", strError());
|
|
Packit Service |
fb147c |
}
|
|
Packit Service |
fb147c |
size_t l = 0;
|
|
Packit Service |
fb147c |
if ( bytes ) {
|
|
Packit Service |
fb147c |
int r ;
|
|
Packit Service |
fb147c |
while ( (r=io->read(bytes,blocksize)) > 0 ) {
|
|
Packit Service |
fb147c |
l += r;
|
|
Packit Service |
fb147c |
output.write(bytes,r) ;
|
|
Packit Service |
fb147c |
}
|
|
Packit Service |
fb147c |
} else {
|
|
Packit Service |
fb147c |
// read/write byte-wise (#1029)
|
|
Packit Service |
fb147c |
while ( l++ < io->size() ) {
|
|
Packit Service |
fb147c |
output.putb(io->getb()) ;
|
|
Packit Service |
fb147c |
}
|
|
Packit Service |
fb147c |
}
|
|
Packit Service |
fb147c |
if ( bytes ) delete [] bytes;
|
|
Packit Service |
fb147c |
output.close();
|
|
Packit Service |
fb147c |
}
|
|
Packit |
01d647 |
|
|
Packit Service |
fb147c |
FileIo fileIn(f0);
|
|
Packit Service |
fb147c |
if (fileIn.open() != 0) {
|
|
Packit Service |
fb147c |
throw Error(Exiv2::kerDataSourceOpenFailed, fileIn.path(), strError());
|
|
Packit Service |
fb147c |
}
|
|
Packit |
01d647 |
|
|
Packit Service |
fb147c |
FileIo fileOut1(f1);
|
|
Packit Service |
fb147c |
if (fileOut1.open("w+b") != 0) {
|
|
Packit Service |
fb147c |
throw Error(Exiv2::kerFileOpenFailed, f1, "w+b", strError());
|
|
Packit Service |
fb147c |
}
|
|
Packit |
01d647 |
|
|
Packit Service |
fb147c |
MemIo memIo1;
|
|
Packit |
01d647 |
|
|
Packit Service |
fb147c |
// Copy to output file through memIo
|
|
Packit Service |
fb147c |
memIo1.write(fileIn);
|
|
Packit Service |
fb147c |
memIo1.seek(0, BasicIo::beg);
|
|
Packit Service |
fb147c |
fileOut1.write(memIo1);
|
|
Packit |
01d647 |
|
|
Packit Service |
fb147c |
// Make sure they are all the same size
|
|
Packit Service |
fb147c |
if(fileIn.size() != memIo1.size() || memIo1.size() != fileOut1.size()) {
|
|
Packit Service |
fb147c |
std::cerr << argv[0] <<
|
|
Packit Service |
fb147c |
": Sizes do not match\n";
|
|
Packit Service |
fb147c |
return 1;
|
|
Packit Service |
fb147c |
}
|
|
Packit |
01d647 |
|
|
Packit Service |
fb147c |
// Read writereadseek test on MemIo
|
|
Packit Service |
fb147c |
MemIo memIo2;
|
|
Packit Service |
fb147c |
int rc = WriteReadSeek(memIo2);
|
|
Packit Service |
fb147c |
if (rc != 0) return rc;
|
|
Packit |
01d647 |
|
|
Packit Service |
fb147c |
// Read writereadseek test on FileIo
|
|
Packit Service |
fb147c |
// Create or overwrite the file, then close it
|
|
Packit Service |
fb147c |
FileIo fileTest("iotest.txt");
|
|
Packit Service |
fb147c |
if (fileTest.open("w+b") != 0) {
|
|
Packit Service |
fb147c |
throw Error(Exiv2::kerFileOpenFailed, "iotest.txt", "w+b", strError());
|
|
Packit Service |
fb147c |
}
|
|
Packit |
01d647 |
|
|
Packit Service |
fb147c |
fileTest.close();
|
|
Packit Service |
fb147c |
rc = WriteReadSeek(fileTest);
|
|
Packit Service |
fb147c |
if (rc != 0) return rc;
|
|
Packit |
01d647 |
|
|
Packit Service |
fb147c |
// Another test of reading and writing
|
|
Packit Service |
fb147c |
fileOut1.seek(0, BasicIo::beg);
|
|
Packit Service |
fb147c |
memIo2.seek(0, BasicIo::beg);
|
|
Packit Service |
fb147c |
FileIo fileOut2(f2);
|
|
Packit Service |
fb147c |
if (fileOut2.open("w+b") != 0) {
|
|
Packit Service |
fb147c |
throw Error(Exiv2::kerFileOpenFailed, f2, "w+b", strError());
|
|
Packit |
01d647 |
}
|
|
Packit Service |
fb147c |
|
|
Packit Service |
fb147c |
long readCount = 0;
|
|
Packit Service |
fb147c |
byte buf[32];
|
|
Packit Service |
fb147c |
while ((readCount=fileOut1.read(buf, sizeof(buf)))) {
|
|
Packit Service |
fb147c |
if (memIo2.write(buf, readCount) != readCount) {
|
|
Packit Service |
fb147c |
std::cerr << argv[0] <<
|
|
Packit Service |
fb147c |
": MemIo bad write 2\n";
|
|
Packit Service |
fb147c |
return 13;
|
|
Packit Service |
fb147c |
}
|
|
Packit Service |
fb147c |
if (fileOut2.write(buf, readCount) != readCount) {
|
|
Packit Service |
fb147c |
std::cerr << argv[0] <<
|
|
Packit Service |
fb147c |
": FileIo bad write 2\n";
|
|
Packit Service |
fb147c |
return 14;
|
|
Packit Service |
fb147c |
}
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit Service |
fb147c |
return 0;
|
|
Packit Service |
fb147c |
} catch (Exiv2::AnyError& e) {
|
|
Packit Service |
fb147c |
std::cerr << "Caught Exiv2 exception '" << e << "'\n";
|
|
Packit Service |
fb147c |
return 20;
|
|
Packit Service |
fb147c |
}
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
int WriteReadSeek(BasicIo &io)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
byte buf[4096];
|
|
Packit |
01d647 |
const char tester1[] = "this is a little test of MemIo";
|
|
Packit |
01d647 |
const char tester2[] = "Appending this on the end";
|
|
Packit |
01d647 |
const char expect[] = "this is a little teAppending this on the end";
|
|
Packit |
01d647 |
const size_t insert = 19;
|
|
Packit |
01d647 |
const size_t size1 = std::strlen(tester1) + 1;
|
|
Packit |
01d647 |
const size_t size2 = std::strlen(tester2) + 1;
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
if (io.open() != 0) {
|
|
Packit |
01d647 |
throw Error(Exiv2::kerDataSourceOpenFailed, io.path(), strError());
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
IoCloser closer(io);
|
|
Packit |
01d647 |
if ((size_t) io.write((byte*)tester1, (long)size1) != size1) {
|
|
Packit |
01d647 |
std::cerr << ": WRS initial write failed\n";
|
|
Packit |
01d647 |
return 2;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
if (io.size() != size1) {
|
|
Packit |
01d647 |
std::cerr << ": WRS size is not " << size1 << "\n";
|
|
Packit |
01d647 |
return 2;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
long backup = (long)size1;
|
|
Packit |
01d647 |
io.seek(-backup, BasicIo::cur);
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
int c = EOF;
|
|
Packit |
01d647 |
std::memset(buf, -1, sizeof(buf));
|
|
Packit |
01d647 |
for (int i = 0; (c=io.getb()) != EOF; ++i) {
|
|
Packit |
01d647 |
buf[i] = (byte)c;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
// Make sure we got the null back
|
|
Packit |
01d647 |
if(buf[size1-1] != 0) {
|
|
Packit |
01d647 |
std::cerr << ": WRS missing null terminator 1\n";
|
|
Packit |
01d647 |
return 3;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
if (strcmp(tester1, (char*)buf) != 0 ) {
|
|
Packit |
01d647 |
std::cerr << ": WRS strings don't match 1\n";
|
|
Packit |
01d647 |
return 4;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
io.seek(-2, BasicIo::end);
|
|
Packit |
01d647 |
if (io.getb() != 'o') {
|
|
Packit |
01d647 |
std::cerr << ": WRS bad getb o\n";
|
|
Packit |
01d647 |
return 5;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
io.seek(-2, BasicIo::cur);
|
|
Packit |
01d647 |
if (io.getb() != 'I') {
|
|
Packit |
01d647 |
std::cerr << ": WRS bad getb I\n";
|
|
Packit |
01d647 |
return 6;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
if (io.putb('O') != 'O') {
|
|
Packit |
01d647 |
std::cerr << ": WRS bad putb\n";
|
|
Packit |
01d647 |
return 7;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
io.seek(-1, BasicIo::cur);
|
|
Packit |
01d647 |
if (io.getb() != 'O') {
|
|
Packit |
01d647 |
std::cerr << ": WRS bad getb O\n";
|
|
Packit |
01d647 |
return 8;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
io.seek(insert, BasicIo::beg);
|
|
Packit |
01d647 |
if((size_t)io.write((byte*)tester2, (long)size2) != size2) {
|
|
Packit |
01d647 |
std::cerr << ": WRS bad write 1\n";
|
|
Packit |
01d647 |
return 9;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
// open should seek to beginning
|
|
Packit |
01d647 |
if (io.open() != 0) {
|
|
Packit |
01d647 |
throw Error(Exiv2::kerDataSourceOpenFailed, io.path(), strError());
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
std::memset(buf, -1, sizeof(buf));
|
|
Packit |
01d647 |
if ((size_t) io.read(buf, sizeof(buf)) != insert + size2) {
|
|
Packit |
01d647 |
std::cerr << ": WRS something went wrong\n";
|
|
Packit |
01d647 |
return 10;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
// Make sure we got the null back
|
|
Packit |
01d647 |
if(buf[insert + size2 - 1] != 0) {
|
|
Packit |
01d647 |
std::cerr << ": WRS missing null terminator 2\n";
|
|
Packit |
01d647 |
return 11;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
if (std::strcmp(expect, (char*)buf) != 0 ) {
|
|
Packit |
01d647 |
std::cerr << ": WRS strings don't match 2\n";
|
|
Packit |
01d647 |
return 12;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
return 0;
|
|
Packit |
01d647 |
}
|