/************************************************************************
* EOS - the CERN Disk Storage System *
* Copyright (C) 2018 CERN/Switzerland *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program 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 General Public License *
* along with this program. If not, see .*
************************************************************************/
//------------------------------------------------------------------------------
// author: Georgios Bitzes
// desc: Namespace checksum utilities
//------------------------------------------------------------------------------
#ifndef EOS_NS_CHECKSUM_HH
#define EOS_NS_CHECKSUM_HH
#include "common/Logging.hh"
#include "common/LayoutId.hh"
#include "proto/FileMd.pb.h"
#include "namespace/utils/Buffer.hh"
#include "namespace/interface/IFileMD.hh"
namespace eos
{
//----------------------------------------------------------------------------
//! Append FileMD checksum onto the given string. Return false only if we're
//! not able to determine checksum type for given layout id.
//!
//! Use the given separator to separate each two hexadecimal digits.
//! i.e. "b5 e1 70 20" instead of "b5e17020"
//!
//! We use a template to support both std::string and XrdOucString...
//----------------------------------------------------------------------------
template
bool appendChecksumOnStringAsHexNoFmd(IFileMD::layoutId_t layoutId,
const Buffer &buffer,
StringType &out,
char separator = 0x00,
int overrideLength = -1) {
// All this is to maintain backward compatibility in all places where
// we print checksums.. I'm not sure if we absolutely need to pad with
// zeroes, for example.
unsigned int nominalChecksumLength =
eos::common::LayoutId::GetChecksumLen(layoutId);
unsigned int targetChecksumLength;
if (overrideLength == -1) {
targetChecksumLength = nominalChecksumLength;
} else {
targetChecksumLength = overrideLength;
}
for (unsigned int i = 0; i < targetChecksumLength; i++) {
unsigned char targetCharacter = 0x00;
char hb[4];
if (i < nominalChecksumLength) {
targetCharacter = buffer.getDataPadded(i);
}
if (separator != 0x00 && i != (targetChecksumLength-1)) {
sprintf(hb, "%02x%c", targetCharacter, separator);
out += hb;
} else {
sprintf(hb, "%02x", targetCharacter);
out += hb;
}
}
return (nominalChecksumLength > 0);
}
template
bool appendChecksumOnStringAsHex(const eos::IFileMD *fmd, StringType &out,
char separator = 0x00,
int overrideLength = -1) {
if(!fmd) return false;
return appendChecksumOnStringAsHexNoFmd(fmd->getLayoutId(), fmd->getChecksum(),
out, separator, overrideLength);
}
inline bool appendChecksumOnStringProtobuf(const eos::ns::FileMdProto &proto,
std::string &out, char separator = 0x00, int overrideLength = -1) {
Buffer checksumBuffer(proto.checksum().size());
checksumBuffer.putData((void*)proto.checksum().data(), proto.checksum().size());
return appendChecksumOnStringAsHexNoFmd(proto.layout_id(), checksumBuffer, out, separator, overrideLength);
}
inline bool hexArrayToByteArray(const char* hexArray, size_t sz, std::string &byteArray) {
byteArray.clear();
if(sz == 0) {
return true;
}
if(sz % 2 != 0) {
return false;
}
for(size_t i = 0; i < sz; i += 2) {
char *endptr = nullptr;
char tmpArray[3];
tmpArray[0] = hexArray[i];
tmpArray[1] = hexArray[i+1];
tmpArray[2] = 0x00;
char byte = static_cast(strtol(tmpArray, &endptr, 16));
byteArray.push_back(byte);
if(endptr != tmpArray+2) {
byteArray.clear();
return false;
}
}
return true;
}
inline bool hexArrayToByteArray(const std::string &hexArray, std::string &byteArray) {
return hexArrayToByteArray(hexArray.c_str(), hexArray.size(), byteArray);
}
}
#endif