"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "zlib/TarFileWriter.cpp" between
muscle7.61.zip and muscle7.62.zip

About: MUSCLE (Multi User Server Client Linking Environment) is a messaging server and networking API. The included server program ("muscled") lets its clients message each other, and/or store information in its serverside hierarchical database.

TarFileWriter.cpp  (muscle7.61):TarFileWriter.cpp  (muscle7.62)
/* This file is Copyright 2000-2013 Meyer Sound Laboratories Inc. See the inclu ded LICENSE.txt file for details. */ /* This file is Copyright 2000-2013 Meyer Sound Laboratories Inc. See the inclu ded LICENSE.txt file for details. */
#include "dataio/FileDataIO.h" #include "dataio/FileDataIO.h"
#include "util/MiscUtilityFunctions.h" #include "util/MiscUtilityFunctions.h"
#include "zlib/TarFileWriter.h" #include "zlib/TarFileWriter.h"
namespace muscle { namespace muscle {
TarFileWriter :: TarFileWriter() TarFileWriter :: TarFileWriter()
: _currentHeaderOffset(-1)
{ {
// empty Close(); // this will update our int64 member-variables to their appropriate defaults
} }
TarFileWriter :: TarFileWriter(const char * outputFileName, bool append) TarFileWriter :: TarFileWriter(const char * outputFileName, bool append)
: _currentHeaderOffset(-1)
{ {
(void) SetFile(outputFileName, append); (void) SetFile(outputFileName, append); // SetFile() will call Close(), Clos e() will initialize our int64 member-variables to their appropriate defaults
} }
TarFileWriter :: TarFileWriter(const SeekableDataIORef & dio) TarFileWriter :: TarFileWriter(const DataIORef & dio)
: _writerIO(dio)
, _currentHeaderOffset(-1)
{ {
// empty (void) SetFile(dio); // SetFile() will call Close(), Close() will initialize our int64 member-variables to their appropriate defaults
} }
TarFileWriter :: ~TarFileWriter() TarFileWriter :: ~TarFileWriter()
{ {
(void) Close(); (void) Close();
} }
status_t TarFileWriter :: Close() status_t TarFileWriter :: Close()
{ {
const status_t ret = _writerIO() ? FinishCurrentFileDataBlock() : B_NO_ERROR; const status_t ret = _writerIO() ? FinishCurrentFileDataBlock() : B_NO_ERROR;
_writerIO.Reset(); // do this no matter what
_writerIO.Reset();
_seekableWriterIO.Reset();
_currentHeaderOffset = -1;
_prestatedFileSize = 0;
_currentSeekPosition = 0;
return ret; return ret;
} }
void TarFileWriter :: SetFile(const SeekableDataIORef & dio) void TarFileWriter :: SetFile(const DataIORef & dio)
{ {
(void) Close(); (void) Close();
_writerIO = dio; _writerIO = dio;
(void) _seekableWriterIO.SetFromRefCountableRef(dio); // _seekableWriterIO b e a NULL Ref, and that's okay
} }
status_t TarFileWriter :: SetFile(const char * outputFileName, bool append) status_t TarFileWriter :: SetFile(const char * outputFileName, bool append)
{ {
(void) Close(); (void) Close();
_writerIO.Reset();
if (outputFileName) if (outputFileName)
{ {
if (append == false) (void) DeleteFile(outputFileName); if (append == false) (void) DeleteFile(outputFileName);
FILE * fpOut = muscleFopen(outputFileName, append?"ab":"wb"); FILE * fpOut = muscleFopen(outputFileName, append?"ab":"wb");
if (fpOut) if (fpOut)
{ {
_writerIO.SetRef(newnothrow FileDataIO(fpOut)); FileDataIORef ioRef(newnothrow FileDataIO(fpOut));
if (_writerIO()) return B_NO_ERROR; if (ioRef())
else {fclose(fpOut); WARN_OUT_OF_MEMORY;} {
SetFile(ioRef);
if (append) _currentSeekPosition = ioRef()->GetLength();
return B_NO_ERROR;
}
else {fclose(fpOut); WARN_OUT_OF_MEMORY;}
} }
return B_ERRNO; return B_ERRNO;
} }
else return B_NO_ERROR; else return B_NO_ERROR;
} }
static void WriteOctalASCII(uint8 * b, uint64 val, uint8 fieldSize) static void WriteOctalASCII(uint8 * b, uint64 val, uint8 fieldSize)
{ {
// gotta pad out the file data to the nearest block boundary! // gotta pad out the file data to the nearest block boundary!
char formatStr[16]; muscleStrcpy(formatStr, UINT64_FORMAT_SPEC " "); char formatStr[16]; muscleStrcpy(formatStr, UINT64_FORMAT_SPEC " ");
skipping to change at line 86 skipping to change at line 94
muscleSprintf(tmp, formatStr, val); muscleSprintf(tmp, formatStr, val);
const int numChars = muscleMin((int)fieldSize, ((int)(strlen(tmp)+1))); // i nclude the NUL byte if possible const int numChars = muscleMin((int)fieldSize, ((int)(strlen(tmp)+1))); // i nclude the NUL byte if possible
uint8 * dStart = (b+fieldSize)-numChars; uint8 * dStart = (b+fieldSize)-numChars;
memcpy(dStart, tmp, numChars); memcpy(dStart, tmp, numChars);
// The if-test below shouldn't be necessary, but it's here to // The if-test below shouldn't be necessary, but it's here to
// avoid a spurious warning from gcc under Windows (per Mika) // avoid a spurious warning from gcc under Windows (per Mika)
if (dStart > b) memset(b, '0', dStart-b); // initial zeros if (dStart > b) memset(b, '0', dStart-b); // initial zeros
} }
void TarFileWriter::UpdateCurrentHeaderChecksum()
{
memset(&_currentHeaderBytes[148], ' ', 8); // when calculating the checksum,
the checksum field must be full of spaces
uint32 checksum = 0;
for (uint32 i=0; i<TAR_BLOCK_SIZE; i++) checksum += _currentHeaderBytes[i];
WriteOctalASCII(&_currentHeaderBytes[148], checksum, 8);
}
status_t TarFileWriter :: FinishCurrentFileDataBlock() status_t TarFileWriter :: FinishCurrentFileDataBlock()
{ {
if (_writerIO() == NULL) return B_BAD_OBJECT; if (_writerIO() == NULL) return B_BAD_OBJECT;
status_t ret; status_t ret;
if (_currentHeaderOffset >= 0) if (_currentHeaderOffset >= 0)
{ {
const int64 currentPos = GetCurrentSeekPosition(); const uint64 currentFileLength = _currentSeekPosition-(_currentHeaderOffse
const uint64 currentFileLength = currentPos-(_currentHeaderOffset+TAR_BLOC t+TAR_BLOCK_SIZE);
K_SIZE); const int64 extraBytes = (_currentSeekPosition%TAR_BLOCK_SIZE);
const int64 extraBytes = (currentPos%TAR_BLOCK_SIZE);
if (extraBytes != 0) if (extraBytes != 0)
{ {
const int64 numPadBytes = (TAR_BLOCK_SIZE-extraBytes); const int64 numPadBytes = (TAR_BLOCK_SIZE-extraBytes);
uint8 zeros[TAR_BLOCK_SIZE]; memset(zeros, 0, (size_t) numPadBytes); uint8 zeros[TAR_BLOCK_SIZE]; memset(zeros, 0, (size_t) numPadBytes);
if (_writerIO()->WriteFully(zeros, (uint32) numPadBytes) != (uint32) nu
mPadBytes) return B_IO_ERROR; const uint32 numBytesWritten = _writerIO()->WriteFully(zeros, (uint32)
numPadBytes);
_currentSeekPosition += numBytesWritten;
if (numBytesWritten != (uint32) numPadBytes) return B_IO_ERROR;
} }
WriteOctalASCII(&_currentHeaderBytes[124], currentFileLength, 12); if (_seekableWriterIO())
{
WriteOctalASCII(&_currentHeaderBytes[124], currentFileLength, 12);
UpdateCurrentHeaderChecksum();
if (_seekableWriterIO()->Seek(_currentHeaderOffset, SeekableDataIO::IO_
SEEK_SET).IsError(ret)) return ret;
_currentSeekPosition = _currentHeaderOffset;
uint32 checksum = 0; const uint32 numBytesWritten = _seekableWriterIO()->WriteFully(_current
for (uint32 i=0; i<TAR_BLOCK_SIZE; i++) checksum += _currentHeaderBytes[i] HeaderBytes, sizeof(_currentHeaderBytes));
; _currentSeekPosition += _currentHeaderOffset;
WriteOctalASCII(&_currentHeaderBytes[148], checksum, 8); if (numBytesWritten != sizeof(_currentHeaderBytes)) return B_IO_ERROR;
if (_writerIO()->Seek(_currentHeaderOffset, SeekableDataIO::IO_SEEK_SET).I if (_seekableWriterIO()->Seek(0, SeekableDataIO::IO_SEEK_END).IsOK(ret)
sError(ret)) return ret; ) _currentSeekPosition = _seekableWriterIO()->GetLength();
if (_writerIO()->WriteFully(_currentHeaderBytes, sizeof(_currentHeaderByte els
s)) != sizeof(_currentHeaderBytes)) return B_IO_ERROR; e return ret;
if (_writerIO()->Seek(0, SeekableDataIO::IO_SEEK_END).IsError(ret)) return }
ret; else if (_prestatedFileSize != currentFileLength)
{
LogTime(MUSCLE_LOG_ERROR, "TarFileWriter::FinishCurrentFileDataBlock():
DataIO isn't seekable, and the current entry's file-length (" UINT64_FORMAT_S
PEC ") doesn't match the prestated file-length (" UINT64_FORMAT_SPEC ")! Can't
update the tar entry header!\n", currentFileLength, _prestatedFileSize);
return B_BAD_ARGUMENT;
}
_currentHeaderOffset = -1; _currentHeaderOffset = -1;
_prestatedFileSize = 0;
} }
return B_NO_ERROR; return B_NO_ERROR;
} }
int64 TarFileWriter :: GetCurrentSeekPosition() const status_t TarFileWriter :: WriteFileHeader(const char * fileName, uint32 fileMode
{ , uint32 ownerID, uint32 groupID, uint64 modificationTime, int linkIndicator, co
return _writerIO() ? _writerIO()->GetPosition() : -1; nst char * linkedFileName, uint64 prestatedFileSize)
}
status_t TarFileWriter :: WriteFileHeader(const char * fileName, uint32 fileMode
, uint32 ownerID, uint32 groupID, uint64 modificationTime, int linkIndicator, co
nst char * linkedFileName)
{ {
if ((strlen(fileName) > 100)||((linkedFileName)&&(strlen(linkedFileName)>100) )) return B_BAD_ARGUMENT; // string fields are only 100 chars long! if ((strlen(fileName) > 100)||((linkedFileName)&&(strlen(linkedFileName)>100) )) return B_BAD_ARGUMENT; // string fields are only 100 chars long!
status_t ret; status_t ret;
if (FinishCurrentFileDataBlock().IsError(ret)) return ret; // should pad out position out to a multiple of 512, if necessary if (FinishCurrentFileDataBlock().IsError(ret)) return ret; // should pad out position out to a multiple of 512, if necessary
const int64 curSeekPos = GetCurrentSeekPosition(); if ((_currentSeekPosition%TAR_BLOCK_SIZE) != 0) return B_BAD_OBJECT;
if ((curSeekPos < 0)||((curSeekPos%TAR_BLOCK_SIZE) != 0)) return B_BAD_OBJECT
;
_currentHeaderOffset = curSeekPos; _currentHeaderOffset = _currentSeekPosition;
memset(_currentHeaderBytes, 0, sizeof(_currentHeaderBytes)); memset(_currentHeaderBytes, 0, sizeof(_currentHeaderBytes));
muscleStrncpy((char *)(&_currentHeaderBytes[0]), fileName, sizeof(_currentHea derBytes)); muscleStrncpy((char *)(&_currentHeaderBytes[0]), fileName, sizeof(_currentHea derBytes));
WriteOctalASCII(&_currentHeaderBytes[100], fileMode, 8); WriteOctalASCII(&_currentHeaderBytes[100], fileMode, 8);
WriteOctalASCII(&_currentHeaderBytes[108], ownerID, 8); WriteOctalASCII(&_currentHeaderBytes[108], ownerID, 8);
WriteOctalASCII(&_currentHeaderBytes[116], groupID, 8); WriteOctalASCII(&_currentHeaderBytes[116], groupID, 8);
WriteOctalASCII(&_currentHeaderBytes[124], prestatedFileSize, 12);
const uint64 secondsSince1970 = MicrosToSeconds(modificationTime); const uint64 secondsSince1970 = MicrosToSeconds(modificationTime);
if (secondsSince1970 != 0) WriteOctalASCII(&_currentHeaderBytes[136], seconds Since1970, 12); if (secondsSince1970 != 0) WriteOctalASCII(&_currentHeaderBytes[136], seconds Since1970, 12);
memset(&_currentHeaderBytes[148], ' ', 8); // these spaces are used later on , when calculating the header checksum
_currentHeaderBytes[156] = (uint8) (linkIndicator+'0'); _currentHeaderBytes[156] = (uint8) (linkIndicator+'0');
if (linkedFileName) muscleStrncpy((char *)(&_currentHeaderBytes[157]), linked FileName, sizeof(_currentHeaderBytes)-157); if (linkedFileName) muscleStrncpy((char *)(&_currentHeaderBytes[157]), linked FileName, sizeof(_currentHeaderBytes)-157);
UpdateCurrentHeaderChecksum();
// We write out the header as it is now, in order to keep the file offsets co rrect... but we'll rewrite it again later // We write out the header as it is now, in order to keep the file offsets co rrect... but we'll rewrite it again later
// when we know the actual file size. // when we know the actual file size.
return (_writerIO()->WriteFully(_currentHeaderBytes, sizeof(_currentHeaderByt const uint32 numBytesWritten = _writerIO()->WriteFully(_currentHeaderBytes, s
es)) == sizeof(_currentHeaderBytes)) ? B_NO_ERROR : B_IO_ERROR; izeof(_currentHeaderBytes));
_currentSeekPosition += numBytesWritten;
if (numBytesWritten == sizeof(_currentHeaderBytes))
{
_prestatedFileSize = prestatedFileSize;
return B_NO_ERROR;
}
else return B_IO_ERROR;
} }
status_t TarFileWriter :: WriteFileData(const uint8 * fileData, uint32 numBytes) status_t TarFileWriter :: WriteFileData(const uint8 * fileData, uint32 numBytes)
{ {
if ((_writerIO() == NULL)||(_currentHeaderOffset < 0)) return B_BAD_OBJECT; if ((_writerIO() == NULL)||(_currentHeaderOffset < 0)) return B_BAD_OBJECT;
return (_writerIO()->WriteFully(fileData, numBytes) == numBytes) ? B_NO_ERROR
: B_IO_ERROR; const uint32 numBytesWritten = _writerIO()->WriteFully(fileData, numBytes);
_currentSeekPosition += numBytesWritten;
return (numBytesWritten == numBytes) ? B_NO_ERROR : B_IO_ERROR;
} }
} // end namespace muscle } // end namespace muscle
 End of changes. 26 change blocks. 
49 lines changed or deleted 88 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)