Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 10:34:40

0001 //------------------------------------------------------------------------------
0002 // Copyright (c) 2011-2014 by European Organization for Nuclear Research (CERN)
0003 // Author: Michal Simon <michal.simon@cern.ch>
0004 //------------------------------------------------------------------------------
0005 // This file is part of the XRootD software suite.
0006 //
0007 // XRootD is free software: you can redistribute it and/or modify
0008 // it under the terms of the GNU Lesser General Public License as published by
0009 // the Free Software Foundation, either version 3 of the License, or
0010 // (at your option) any later version.
0011 //
0012 // XRootD is distributed in the hope that it will be useful,
0013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
0014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0015 // GNU General Public License for more details.
0016 //
0017 // You should have received a copy of the GNU Lesser General Public License
0018 // along with XRootD.  If not, see <http://www.gnu.org/licenses/>.
0019 //
0020 // In applying this licence, CERN does not waive the privileges and immunities
0021 // granted to it by virtue of its status as an Intergovernmental Organization
0022 // or submit itself to any jurisdiction.
0023 //------------------------------------------------------------------------------
0024 
0025 #ifndef SRC_XRDZIP_XRDZIPUTILS_HH_
0026 #define SRC_XRDZIP_XRDZIPUTILS_HH_
0027 
0028 #include "XrdSys/XrdSysPlatform.hh"
0029 
0030 #include <algorithm>
0031 #include <cstdint>
0032 #include <cstring>
0033 #include <ctime>
0034 #include <iterator>
0035 #include <vector>
0036 
0037 namespace XrdZip
0038 {
0039   //---------------------------------------------------------------------------
0040   // Exception indicating corrupted data
0041   //---------------------------------------------------------------------------
0042   struct bad_data : public std::exception { };
0043 
0044   //---------------------------------------------------------------------------
0045   // Provides overflow value for unsigned int types
0046   //---------------------------------------------------------------------------
0047   template<typename UINT>
0048   struct ovrflw
0049   {
0050     static const UINT value = -1;
0051   };
0052 
0053   //---------------------------------------------------------------------------
0054   // Buffer type (a typedef for std::vector<char>)
0055   //---------------------------------------------------------------------------
0056   typedef std::vector<char> buffer_t;
0057 
0058   //---------------------------------------------------------------------------
0059   // Copies integer byte by byte into a buffer
0060   //---------------------------------------------------------------------------
0061   template<typename INT>
0062   inline static void copy_bytes( const INT value, buffer_t &buffer)
0063   {
0064     const char *begin = reinterpret_cast<const char*>( &value );
0065     const char *end   = begin + sizeof( INT );
0066 #ifdef Xrd_Big_Endian
0067     std::reverse_copy( begin, end, std::back_inserter( buffer ) );
0068 #else
0069     std::copy( begin, end, std::back_inserter( buffer ) );
0070 #endif
0071   }
0072 
0073   //---------------------------------------------------------------------------
0074   // Copies bytes into an integer type and advances the buffer by the number
0075   // of bytes read.
0076   //---------------------------------------------------------------------------
0077   template<typename INT>
0078   inline static void from_buffer( INT &var, const char *&buffer )
0079   {
0080     memcpy( &var, buffer, sizeof( INT ) );
0081 #ifdef Xrd_Big_Endian
0082     var = bswap(var);
0083 #endif
0084     buffer += sizeof( INT );
0085   }
0086 
0087   //---------------------------------------------------------------------------
0088   // Converts bytes into an integer type
0089   //---------------------------------------------------------------------------
0090   template<typename INT>
0091   inline static INT to( const char *buffer )
0092   {
0093     INT value;
0094     memcpy( &value, buffer, sizeof( INT ) );
0095 #ifdef Xrd_Big_Endian
0096     value = bswap(value);
0097 #endif
0098     return value;
0099   }
0100 
0101   //---------------------------------------------------------------------------
0102   // Generate a DOS timestamp (time/date)
0103   //---------------------------------------------------------------------------
0104   struct dos_timestmp
0105   {
0106     //-------------------------------------------------------------------------
0107     // Default constructor (creates a timestamp for current time)
0108     //-------------------------------------------------------------------------
0109     inline dos_timestmp() : time( 0 ), date( 0 )
0110     {
0111       const std::time_t now = std::time( nullptr );
0112       const std::tm calendar_time = *std::localtime( std::addressof( now ) );
0113 
0114       time |= ( hour_mask & uint16_t( calendar_time.tm_hour    ) ) << hour_shift;
0115       time |= ( min_mask  & uint16_t( calendar_time.tm_min     ) ) << min_shift;
0116       time |= ( sec_mask  & uint16_t( calendar_time.tm_sec / 2 ) ) << sec_shift;
0117 
0118       date |= ( year_mask & uint16_t( calendar_time.tm_year - 1980 ) ) << year_shift;
0119       date |= ( mon_mask  & uint16_t( calendar_time.tm_mon         ) ) << mon_shift;
0120       date |= ( day_mask  & uint16_t( calendar_time.tm_mday        ) ) << day_shift;
0121     }
0122 
0123     //-------------------------------------------------------------------------
0124     // Constructs a DOS timestamp from time_t value
0125     //-------------------------------------------------------------------------
0126     inline dos_timestmp( time_t timestmp ) : time( 0 ), date( 0 )
0127     {
0128       const std::tm calendar_time = *std::localtime( std::addressof( timestmp ) );
0129 
0130       time |= ( hour_mask & uint16_t( calendar_time.tm_hour    ) ) << hour_shift;
0131       time |= ( min_mask  & uint16_t( calendar_time.tm_min     ) ) << min_shift;
0132       time |= ( sec_mask  & uint16_t( calendar_time.tm_sec / 2 ) ) << sec_shift;
0133 
0134       date |= ( year_mask & uint16_t( calendar_time.tm_year - 1980 ) ) << year_shift;
0135       date |= ( mon_mask  & uint16_t( calendar_time.tm_mon         ) ) << mon_shift;
0136       date |= ( day_mask  & uint16_t( calendar_time.tm_mday        ) ) << day_shift;
0137     }
0138 
0139     //-------------------------------------------------------------------------
0140     // The time part of the DOS timestamp
0141     //-------------------------------------------------------------------------
0142     uint16_t time;
0143 
0144     static const uint16_t sec_mask  = 0x1f; //< seconds mask
0145     static const uint16_t min_mask  = 0x3f; //< minutes mask
0146     static const uint16_t hour_mask = 0x1f; //< hour mask
0147 
0148     static const uint8_t sec_shift  = 0; //< seconds shift
0149     static const uint8_t min_shift  = 5; //< minutes shift
0150     static const uint8_t hour_shift = 11; //< hour shift
0151 
0152     //-------------------------------------------------------------------------
0153     // The date part of the DOS timestamp
0154     //-------------------------------------------------------------------------
0155     uint16_t date;
0156 
0157     static const uint16_t day_mask  = 0x1f; //< day mask
0158     static const uint16_t mon_mask  = 0x0f; //< month mask
0159     static const uint16_t year_mask = 0x7f; //< year mask
0160 
0161     static const uint8_t day_shift  = 0; //< day shift
0162     static const uint8_t mon_shift  = 5; //< month shift
0163     static const uint8_t year_shift = 9; //< year shift
0164   };
0165 }
0166 
0167 #endif /* SRC_XRDZIP_XRDZIPUTILS_HH_ */