Loading...
Searching...
No Matches
XrdZipLFH.hh
Go to the documentation of this file.
//------------------------------------------------------------------------------
// Copyright (c) 2011-2014 by European Organization for Nuclear Research (CERN)
// Author: Michal Simon <michal.simon@cern.ch>
//------------------------------------------------------------------------------
// This file is part of the XRootD software suite.
//
// XRootD is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// XRootD is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with XRootD. If not, see <http://www.gnu.org/licenses/>.
//
// In applying this licence, CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.
//------------------------------------------------------------------------------
#ifndef SRC_XRDZIP_XRDZIPLFH_HH_
#define SRC_XRDZIP_XRDZIPLFH_HH_
#include "XrdZip/XrdZipUtils.hh"
#include "XrdZip/XrdZipExtra.hh"
#include <string>
#include <memory>
#include <algorithm>
#include <iterator>
namespace XrdZip
{
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
struct LFH
{
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
inline static uint32_t initSize( const off_t &fileSize )
{
return fileSize >= ovrflw<uint32_t>::value ?
ovrflw<uint32_t>::value : fileSize;
}
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
LFH( const std::string &filename, uint32_t crc, off_t fileSize, time_t time ) :
generalBitFlag( 0 ), compressionMethod( 0 ), timestmp( time ), ZCRC32( crc ),
compressedSize( initSize( fileSize ) ), uncompressedSize( initSize( fileSize ) ),
filenameLength( filename.size() ), filename( filename ), extra( new Extra( fileSize ) )
{
extraLength = extra->totalSize;
if ( extraLength == 0 )
minZipVersion = 10;
else
minZipVersion = 45;
lfhSize = lfhBaseSize + filenameLength + extraLength;
}
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
LFH( const char *buffer, const uint64_t bufferSize = 0 )
{
if(bufferSize > 0 && bufferSize < (uint64_t)lfhBaseSize)
throw bad_data();
// check if the buffer contains a LFH record
uint32_t signature = 0;
from_buffer( signature, buffer );
if( signature != lfhSign ) throw bad_data();
// parse LFH filds
from_buffer( minZipVersion, buffer );
from_buffer( generalBitFlag, buffer );
from_buffer( compressionMethod, buffer );
from_buffer( timestmp.time, buffer );
from_buffer( timestmp.date, buffer );
from_buffer( ZCRC32, buffer );
from_buffer( compressedSize, buffer );
from_buffer( uncompressedSize, buffer );
from_buffer( filenameLength, buffer );
from_buffer( extraLength, buffer );
if(bufferSize > 0 && (uint64_t)(lfhBaseSize + filenameLength + extraLength) > bufferSize)
throw bad_data();
// parse the filename
filename.assign( buffer, filenameLength );
buffer += filenameLength;
// parse the extra record
if( extraLength > 0 )
ParseExtra( buffer, extraLength );
lfhSize = lfhBaseSize + filenameLength + extraLength;
}
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
void Serialize( buffer_t &buffer )
{
copy_bytes( lfhSign, buffer );
copy_bytes( minZipVersion, buffer );
copy_bytes( generalBitFlag, buffer );
copy_bytes( compressionMethod, buffer );
copy_bytes( timestmp.time, buffer );
copy_bytes( timestmp.date, buffer );
copy_bytes( ZCRC32, buffer );
copy_bytes( compressedSize, buffer );
copy_bytes( uncompressedSize, buffer );
copy_bytes( filenameLength, buffer );
copy_bytes( extraLength , buffer );
std::copy( filename.begin(), filename.end(), std::back_inserter( buffer ) );
extra->Serialize( buffer );
}
//-------------------------------------------------------------------------
// Parse the extensible data fields
//-------------------------------------------------------------------------
void ParseExtra( const char *buffer, uint16_t length)
{
uint8_t ovrflws = Extra::NONE;
uint16_t exsize = 0;
// check if compressed size is overflown
if( compressedSize == ovrflw<uint32_t>::value)
{
ovrflws |= Extra::CPMSIZE;
exsize += sizeof( uint64_t );
}
// check if original size is overflown
if( uncompressedSize == ovrflw<uint32_t>::value )
{
ovrflws |= Extra::UCMPSIZE;
exsize += sizeof( uint64_t );
}
// if the expected size of ZIP64 extension is 0 we
// can skip parsing of 'extra'
if( exsize == 0 ) return;
extra.reset( new Extra() );
// Parse the extra part
buffer = Extra::Find( buffer, length );
if( buffer )
extra->FromBuffer( buffer, exsize, ovrflws );
}
uint16_t minZipVersion; //< minimum ZIP version required to read the file
uint16_t generalBitFlag; //< flags
uint16_t compressionMethod; //< compression method
dos_timestmp timestmp; //< DOS time stamp
uint32_t ZCRC32; //< crc32 value
uint32_t compressedSize; //< compressed data size
uint32_t uncompressedSize; //< uncompressed data size
uint16_t filenameLength; //< file name length
uint16_t extraLength; //< size of the ZIP64 extra field
std::string filename; //< file name
std::unique_ptr<Extra> extra; //< the ZIP64 extra field
uint16_t lfhSize; //< size of the Local File Header
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
static const uint32_t lfhSign = 0x04034b50;
static const uint16_t lfhBaseSize = 30;
};
}
#endif /* SRC_XRDZIP_XRDZIPLFH_HH_ */
XrdZipExtra.hh
XrdZipUtils.hh
XrdZip
Definition XrdZipCDFH.hh:42
XrdZip::from_buffer
static void from_buffer(INT &var, const char *&buffer)
Definition XrdZipUtils.hh:78
XrdZip::buffer_t
std::vector< char > buffer_t
Definition XrdZipUtils.hh:56
XrdZip::copy_bytes
static void copy_bytes(const INT value, buffer_t &buffer)
Definition XrdZipUtils.hh:62
XrdZip::Extra
Definition XrdZipExtra.hh:39
XrdZip::Extra::Find
static const char * Find(const char *buffer, uint16_t length)
Definition XrdZipExtra.hh:101
XrdZip::Extra::CPMSIZE
@ CPMSIZE
Definition XrdZipExtra.hh:164
XrdZip::Extra::UCMPSIZE
@ UCMPSIZE
Definition XrdZipExtra.hh:163
XrdZip::Extra::NONE
@ NONE
Definition XrdZipExtra.hh:162
XrdZip::LFH::ZCRC32
uint32_t ZCRC32
Definition XrdZipLFH.hh:161
XrdZip::LFH::Serialize
void Serialize(buffer_t &buffer)
Serialize the object into a buffer.
Definition XrdZipLFH.hh:106
XrdZip::LFH::lfhBaseSize
static const uint16_t lfhBaseSize
Definition XrdZipLFH.hh:174
XrdZip::LFH::timestmp
dos_timestmp timestmp
Definition XrdZipLFH.hh:160
XrdZip::LFH::extraLength
uint16_t extraLength
Definition XrdZipLFH.hh:165
XrdZip::LFH::compressedSize
uint32_t compressedSize
Definition XrdZipLFH.hh:162
XrdZip::LFH::LFH
LFH(const char *buffer, const uint64_t bufferSize=0)
Constructor from buffer.
Definition XrdZipLFH.hh:71
XrdZip::LFH::LFH
LFH(const std::string &filename, uint32_t crc, off_t fileSize, time_t time)
Constructor.
Definition XrdZipLFH.hh:55
XrdZip::LFH::initSize
static uint32_t initSize(const off_t &fileSize)
Convenience function for initializing compressed/uncompressed size.
Definition XrdZipLFH.hh:46
XrdZip::LFH::compressionMethod
uint16_t compressionMethod
Definition XrdZipLFH.hh:159
XrdZip::LFH::generalBitFlag
uint16_t generalBitFlag
Definition XrdZipLFH.hh:158
XrdZip::LFH::ParseExtra
void ParseExtra(const char *buffer, uint16_t length)
Definition XrdZipLFH.hh:126
XrdZip::LFH::lfhSize
uint16_t lfhSize
Definition XrdZipLFH.hh:168
XrdZip::LFH::extra
std::unique_ptr< Extra > extra
Definition XrdZipLFH.hh:167
XrdZip::LFH::uncompressedSize
uint32_t uncompressedSize
Definition XrdZipLFH.hh:163
XrdZip::LFH::minZipVersion
uint16_t minZipVersion
Definition XrdZipLFH.hh:157
XrdZip::LFH::filename
std::string filename
Definition XrdZipLFH.hh:166
XrdZip::LFH::filenameLength
uint16_t filenameLength
Definition XrdZipLFH.hh:164
XrdZip::LFH::lfhSign
static const uint32_t lfhSign
Local File Header signature.
Definition XrdZipLFH.hh:173
XrdZip::bad_data
Definition XrdZipUtils.hh:42
XrdZip::dos_timestmp
Definition XrdZipUtils.hh:105
XrdZip::ovrflw::value
static const UINT value
Definition XrdZipUtils.hh:50