//------------------------------------------------------------------------------ // Copyright (c) 2011-2014 by European Organization for Nuclear Research (CERN) // Author: Michal Simon //------------------------------------------------------------------------------ // 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 . // // 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_XRDZIPUTILS_HH_ #define SRC_XRDZIP_XRDZIPUTILS_HH_ #include "XrdSys/XrdSysPlatform.hh" #include #include #include #include #include #include namespace XrdZip { //--------------------------------------------------------------------------- // Exception indicating corrupted data //--------------------------------------------------------------------------- struct bad_data : public std::exception { }; //--------------------------------------------------------------------------- // Provides overflow value for unsigned int types //--------------------------------------------------------------------------- template struct ovrflw { static const UINT value = -1; }; //--------------------------------------------------------------------------- // Buffer type (a typedef for std::vector) //--------------------------------------------------------------------------- typedef std::vector buffer_t; //--------------------------------------------------------------------------- // Copies integer byte by byte into a buffer //--------------------------------------------------------------------------- template inline static void copy_bytes( const INT value, buffer_t &buffer) { const char *begin = reinterpret_cast( &value ); const char *end = begin + sizeof( INT ); #ifdef Xrd_Big_Endian std::reverse_copy( begin, end, std::back_inserter( buffer ) ); #else std::copy( begin, end, std::back_inserter( buffer ) ); #endif } //--------------------------------------------------------------------------- // Copies bytes into an integer type and advances the buffer by the number // of bytes read. //--------------------------------------------------------------------------- template inline static void from_buffer( INT &var, const char *&buffer ) { memcpy( &var, buffer, sizeof( INT ) ); #ifdef Xrd_Big_Endian var = bswap(var); #endif buffer += sizeof( INT ); } //--------------------------------------------------------------------------- // Converts bytes into an integer type //--------------------------------------------------------------------------- template inline static INT to( const char *buffer ) { INT value; memcpy( &value, buffer, sizeof( INT ) ); #ifdef Xrd_Big_Endian value = bswap(value); #endif return value; } //--------------------------------------------------------------------------- // Generate a DOS timestamp (time/date) //--------------------------------------------------------------------------- struct dos_timestmp { //------------------------------------------------------------------------- // Default constructor (creates a timestamp for current time) //------------------------------------------------------------------------- inline dos_timestmp() : time( 0 ), date( 0 ) { const std::time_t now = std::time( nullptr ); const std::tm calendar_time = *std::localtime( std::addressof( now ) ); time |= ( hour_mask & uint16_t( calendar_time.tm_hour ) ) << hour_shift; time |= ( min_mask & uint16_t( calendar_time.tm_min ) ) << min_shift; time |= ( sec_mask & uint16_t( calendar_time.tm_sec / 2 ) ) << sec_shift; date |= ( year_mask & uint16_t( calendar_time.tm_year - 1980 ) ) << year_shift; date |= ( mon_mask & uint16_t( calendar_time.tm_mon ) ) << mon_shift; date |= ( day_mask & uint16_t( calendar_time.tm_mday ) ) << day_shift; } //------------------------------------------------------------------------- // Constructs a DOS timestamp from time_t value //------------------------------------------------------------------------- inline dos_timestmp( time_t timestmp ) : time( 0 ), date( 0 ) { const std::tm calendar_time = *std::localtime( std::addressof( timestmp ) ); time |= ( hour_mask & uint16_t( calendar_time.tm_hour ) ) << hour_shift; time |= ( min_mask & uint16_t( calendar_time.tm_min ) ) << min_shift; time |= ( sec_mask & uint16_t( calendar_time.tm_sec / 2 ) ) << sec_shift; date |= ( year_mask & uint16_t( calendar_time.tm_year - 1980 ) ) << year_shift; date |= ( mon_mask & uint16_t( calendar_time.tm_mon ) ) << mon_shift; date |= ( day_mask & uint16_t( calendar_time.tm_mday ) ) << day_shift; } //------------------------------------------------------------------------- // The time part of the DOS timestamp //------------------------------------------------------------------------- uint16_t time; static const uint16_t sec_mask = 0x1f; //< seconds mask static const uint16_t min_mask = 0x3f; //< minutes mask static const uint16_t hour_mask = 0x1f; //< hour mask static const uint8_t sec_shift = 0; //< seconds shift static const uint8_t min_shift = 5; //< minutes shift static const uint8_t hour_shift = 11; //< hour shift //------------------------------------------------------------------------- // The date part of the DOS timestamp //------------------------------------------------------------------------- uint16_t date; static const uint16_t day_mask = 0x1f; //< day mask static const uint16_t mon_mask = 0x0f; //< month mask static const uint16_t year_mask = 0x7f; //< year mask static const uint8_t day_shift = 0; //< day shift static const uint8_t mon_shift = 5; //< month shift static const uint8_t year_shift = 9; //< year shift }; } #endif /* SRC_XRDZIP_XRDZIPUTILS_HH_ */