25 #include <boost/locale.hpp>
49 using namespace boost::locale;
92 bool addFile(
const filesystem::path& filename,
void* data =
nullptr);
141 virtual bool hasPrevious() const final {
return previous !=
nullptr; }
148 virtual bool hasNext() const final {
return next !=
nullptr; }
155 virtual bool hasParent() const final {
return parent !=
nullptr; }
165 virtual bool hasElement(
const string& elementName)
const final;
172 virtual string getName() const final {
return name; }
244 virtual void*
getData()
const {
return nullptr; }
259 virtual void setData(
void* newData) { assert(
false); }
262 virtual Element* getElement(
const string& elementName,
Element** lastElement =
nullptr) const final;
265 bool addFile(const
ArrayString& dirs, const
size_t cur, const
string& filename,
void* data =
nullptr);
269 Element* createDirsAndAddFile(const
ArrayString& dirs, const
size_t cur, const
string& filename,
void* data =
nullptr);
314 bool isAFile() const override final {
return true; };
321 void*
getData()
const override {
return data; }
328 void setData(
void* newData)
override final { data = newData; }
362 bool hasChild() const override final {
return child !=
nullptr; }
369 bool isAFile() const override final {
return false; }
492 assert(f !=
nullptr);
522 bool XCKSDirStruct::addFile(
const filesystem::path& filename,
void* data)
531 return root->addFile(dirs, 0,
from_u8string(filename.filename().u8string()), data);
540 return root->addFile(dirs, 0,
from_u8string(filename.filename().u8string()), data);
557 XCKSDirStruct::Element::Element(
const string& elementName,
561 parent(parentElement),
562 previous(previousElement),
594 while (!found && e !=
nullptr)
622 while ((r ==
nullptr) && (e !=
nullptr))
630 if (lastElement !=
nullptr)
656 bool addDir = cur < dirs.size();
657 const string& fn = addDir ? dirs[cur] : filename;
662 Element* e = this->getElement(fn, &last);
668 assert(last->
getNext() ==
nullptr);
694 assert(last->
getNext() ==
nullptr);
720 const string& filename,
723 bool addDir = cur < dirs.size();
724 const string& fn = addDir ? dirs[cur] : filename;
753 assert(next !=
nullptr);
757 if (this->hasChild())
760 assert(next !=
nullptr);
762 else if (this->hasNext())
765 assert(next !=
nullptr);
797 assert(next !=
nullptr);
801 if (this->hasParent())
809 if (this->hasChild())
812 assert(next !=
nullptr);
819 assert(next !=
nullptr);
823 if (this->hasParent())
844 return this->getNextFile(
false);
937 const std::filesystem::path& baseDir,
941 writerHandler(xcksWriterHandler),
942 ckProvider(checksumProvider),
943 writerOptions(options),
944 baseDirectory(baseDir),
945 version(getValidVersion(version)),
946 possibleSumsAlgos(getAvailableChecksumTypesName()),
947 sumsAlgos(getValidChecksumTypesForNewEntries(algoIds)),
948 ckfConfProvider(confProvider)
950 assert(baseDir.is_absolute());
1046 case Version::V1_0_0 :
1063 unsigned int major, minor, revision;
1065 return to_string(major) +
'.' + to_string(minor) +
'.' + to_string(revision);
1090 unsigned int major, minor, revision;
1093 ok =
writeV1(os, relativePaths);
1117 if (ver >= Version::First_Valid && ver <= Version::Last_Valid)
1120 return Version::Last_Valid;
1141 while (i < res.size())
1144 while (j < res.size())
1146 if (res[j] == res[i])
1147 res.erase(res.begin() + j);
1156 while (i < res.size())
1158 ArrayChecksumAlgoId::const_iterator a = find(aIds.cbegin(), aIds.cend(), res[i]);
1159 if (a == aIds.cend())
1160 res.erase(res.begin() + i);
1191 uintmax_t& filesize,
1192 time_t& filedatetime,
1194 const filesystem::path& filePath,
1195 bool& stopWriting)
const
1200 if (status == Status::Ok || status == Status::MissingAlgorithm)
1206 if (find_if(ckValues.cbegin(), ckValues.cend(), [&](
const ChecksumValue& ckv) { return ckv.getType() == id; }) == ckValues.cend())
1211 status = Status::MissingAlgorithm;
1214 status, stopWriting,
id);
1218 if (status == Status::Ok && ckValues.size() > ids.size())
1221 while (i < ckValues.size())
1223 if (find(ids.cbegin(), ids.cend(), ckValues[i].getType()) == ids.cend())
1224 ckValues.erase(ckValues.begin() + i);
1237 status = Status::BadChecksumValue;
1249 while (i < ckValues.size())
1253 while (j < ckValues.size())
1255 if (ckv.
getType() == ckValues[j].getType())
1257 if (ckv == ckValues[j])
1258 ckValues.erase(ckValues.begin() + j);
1261 status = Status::BadDuplicateValue;
1277 status, stopWriting);
1301 for (
const filesystem::path& p : relativePaths)
1302 dirs.
addFile(p,
const_cast<filesystem::path*
>(&p));
1306 time_t filedatetime;
1312 const filesystem::path& fnNewRel = *(
reinterpret_cast<const filesystem::path* const
>(it->
getData()));
1318 bool stopWriting =
false;
1324 while ((dirIdx < curDir.size()) && (dirs.size() > 0))
1328 dirs.erase(dirs.begin());
1334 while (ok && curDir.size() > dirIdx)
1338 ok =
writeLine(os,
"</parentDirectory>", --indent);
1343 ok =
writeLine(os,
"</directory>", --indent);
1348 while (ok && dirs.size() > 0)
1350 curDir.emplace_back(dirs[0]);
1353 ok =
writeLine(os,
"<parentDirectory>", indent++);
1363 dirs.erase(dirs.begin());
1372 string line =
"<information";
1374 line +=
" size=\"" + to_string(filesize) +
"\"";
1378 #if defined(_WIN32) || defined(_WIN64)
1379 ss << put_time(localtime(&filedatetime),
"%Y-%m-%dT%T");
1381 ss << put_time(localtime(&filedatetime),
"%FT%T");
1383 line +=
" date=\"" + ss.str() +
"\"";
1399 ok = ok &&
writeLine(os,
"<checksum type=\"" + algoName +
"\" value=\"" + ckf.
format(ckv.getValue(), ckv.getSize()) +
"\"/>", indent);
1405 ok =
writeLine(os,
"</file>", --indent);
1411 if (stopWriting || (status == Status::BadChecksumValue) ||
1412 (status == Status::BadDuplicateValue) || (status == Status::MissingAlgorithm))
1417 while (ok && curDir.size() > 0)
1421 ok =
writeLine(os,
"</parentDirectory>", --indent);
1426 ok =
writeLine(os,
"</directory>", --indent);
1453 os <<
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
1457 ok = ok &&
writeLine(os,
"<checksumsFile xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://xcks.sourceforge.net/schemas/xsd-1.0/xcks-" +
getStrVersion() +
".xsd\" version=\"" +
getStrVersion() +
"\">", indent++);
1464 time_t t = time(
nullptr);
1465 #if defined(_WIN32) || defined(_WIN64)
1466 ss << put_time(localtime(&t),
"%Y-%m-%dT%T");
1468 ss << put_time(localtime(&t),
"%FT%T");
1472 if (appName.empty() || appVersion.empty())
1482 ok = ok &&
writeLine(os,
"<generated by=\"" + appName +
"\" version=\"" + appVersion +
"\" on=\"" + ss.str() +
"\"/>", indent);
1487 ok = ok &&
writeLine(os,
"<algorithms>", indent++);
1496 ok = ok &&
writeLine(os,
"<algorithm type=\"" + algoName +
"\"/>", indent);
1504 ok = ok &&
writeLine(os,
"</algorithms>", --indent);
1508 ok = ok &&
writeLine(os,
"<localFiles>", indent++);
1513 ok = ok &&
writeLine(os,
"</localFiles>", --indent);
1517 ok = ok &&
writeLine(os,
"</checksumsFile>", --indent);
1522 return (os.good() && ok);
1543 sIndent.append(indent,
'\t');
1572 StringSet::const_iterator idx = availableChecksumTypesName.cend();
1573 ArrayString::const_iterator it = algoNames.cbegin();
1574 while ((idx == availableChecksumTypesName.cend()) && (it != algoNames.cend()))
1576 idx = availableChecksumTypesName.find(*it);
1579 if (idx == availableChecksumTypesName.cend())
Classes for enumerate and create all the checksums' algorithms that the application knows.
std::vector< ChecksumValue > ArrayChecksumValue
Array of values of checksum.
static size_t getSize(const ChecksumAlgoId id)
Gets the size in bytes of the specified checksum or hash identifier.
static bool getAlgorithmAltNames(ArrayString &altNames, const ChecksumAlgoId id, const bool giveName=false)
Gets the alternatives names of a checksum or hash algorithm from its identifier.
static bool getAlgorithmId(ChecksumAlgoId &id, const std::string &name, const bool lookInAltNames=true)
Gets the identifier of a checksum or hash algorithm from its name.
Stores the value of a checksum.
ChecksumAlgoId getType() const
Gets the type of the checksum.
A directory of the directory structure for XCKS files.
void setChild(Element *newChild) override final
Sets the child of the element.
Element * child
Address of the first child if the element if a directory.
Directory & operator=(const Directory &)=delete
Deleted assignment operator.
bool isAFile() const override final
Does the element is a file?
Directory()=delete
Deleted default constructor.
Element * getChild() const override final
Gets the child of the element.
virtual ~Directory()
Destructor.
bool hasChild() const override final
Does the element have a child?
Directory(const Directory &)=delete
Deleted copy constructor.
An element of the directory structure for XCKS files.
bool addFile(const ArrayString &dirs, const size_t cur, const string &filename, void *data=nullptr)
Adds a new file in the directory structure.
virtual Element * getParent() const final
Gets the parent element of the element.
Element(const Element &)=delete
Deleted copy constructor.
virtual void setPrevious(Element *newPrevious) final
Sets the previous element of the element.
virtual Element * getElement(const string &elementName, Element **lastElement=nullptr) const final
Gets the element with the given name in the current level.
virtual Element * getChild() const
Gets the child of the element.
virtual bool hasChild() const
Does the element have a child?
virtual ~Element()
Destructor.
virtual bool hasPrevious() const final
Does the element have a previous element?
string name
The name of the element.
Element * parent
Address of the parent.
virtual bool isAFile() const =0
Does the element is a file?
virtual Element * getNext() const final
Gets the following element of the element.
virtual void setData(void *newData)
Sets the data associated with the element.
virtual void setChild(Element *newChild)
Sets the child of the element.
Element * next
Address of the next element at the same level.
XCKSDirStruct::File * getNextFile() const
Gets the next file in the directory structure.
virtual void getParent(Element *newParent) final
Sets the parent element of the element.
virtual bool hasElement(const string &elementName) const final
Does an element exist with the given name in the current level?
virtual bool hasNext() const final
Does the element have a following element?
Element * createDirsAndAddFile(const ArrayString &dirs, const size_t cur, const string &filename, void *data=nullptr)
Creates directories and adds a new file in the directory structure.
XCKSDirStruct::File * getNextFile(const bool calledFromChild) const
Gets the next file in the directory structure.
XCKSDirStruct::File * getNextFileRec() const
Gets the next file in the directory structure (recursive).
Element * previous
Address of the previous element at the same level.
virtual void setNext(Element *newNext) final
Sets the following element of the element.
Element & operator=(const Element &)=delete
Deleted assignment operator.
virtual bool hasParent() const final
Does the element have a parent?
virtual string getName() const final
Gets the name of the element.
Element()=delete
Deleted default constructor.
virtual Element * getPrevious() const final
Gets the previous element of the element.
virtual void * getData() const
Gets the data associated with the element.
An file of the directory structure for XCKS files.
bool isAFile() const override final
Does the element is a file?
void setData(void *newData) override final
Sets the data associated with the element.
void * data
Data associated with the element.
File & operator=(const File &)=delete
Deleted assignment operator.
File(const File &)=delete
Deleted copy constructor.
void * getData() const override
Gets the data associated with the element.
virtual ~File()
Destructor.
File()=delete
Deleted default constructor.
A forward iterator on files of a directory structure.
const XCKSDirStruct::File & operator*() const
Indirection operator.
const XCKSDirStruct::File * operator->() const
Member of pointer operator.
bool operator!=(const const_file_iterator &it) const
Inequality operator.
const_file_iterator & operator++()
Prefix increment operator.
const_file_iterator operator++(int)
Postfix increment operator.
const_file_iterator(XCKSDirStruct::File *initFile)
Constructor.
const_file_iterator()
Default constructor.
bool operator==(const const_file_iterator &it) const
Equality operator.
const_file_iterator & operator=(const const_file_iterator &)=default
Assignment operator.
const_file_iterator(const const_file_iterator &)=default
Copy constructor.
XCKSDirStruct::File * file
Current file.
void plusPlus()
Do the ++ operation on the iterator.
A directories structure for XCKS files.
XCKSDirStruct & operator=(const XCKSDirStruct &)=delete
Deleted assignment operator.
XCKSDirStruct(const XCKSDirStruct &)=delete
Deleted copy constructor.
const_file_iterator files_end() const
Returns an iterator pointing at the one-after-the-last file of directory structure.
bool addFile(const filesystem::path &filename, void *data=nullptr)
Adds a new file in the directory structure.
const_file_iterator files_begin() const
Returns an iterator pointing at the first file of the directory structure.
Element * root
Root of the directory structure.
XCKSDirStruct()
Default constructor.
~XCKSFileWriter()
Destructor.
ArrayChecksumAlgoId getValidChecksumTypesForNewEntries(const ArrayChecksumAlgoId &ids) const
Gets a valid list of algorithms to calculate for each file.
bool getXCKSAlgorithmName(std::string &algoName, const ChecksumAlgoId algoId)
Gets the algorithm name in the XCKS specification.
std::string getStrVersion() const
Gets the version of the checksums' file type as a string.
static const std::string parentDir
Parent directory on Unix and windows.
XCKSFileWriter(XCKSWriterHandler &xcksWriterHandler, XCKSWriterChecksumProvider &checksumProvider, const XCKSWriterOptions &options, const std::filesystem::path &baseDir, const ArrayChecksumAlgoId &algoIds, const ChecksumFormatter::ConfigurationProvider &confProvider, Version version=Version::Last_Valid)
Constructor.
Version getVersion() const
Returns the version of the checksums' file type.
static Version getValidVersion(const Version ver)
Ensures a valid version of XCKS file.
XCKSWriterChecksumProvider::Status getChecksumValues(ArrayChecksumValue &ckValues, uintmax_t &filesize, time_t &filedatetime, const ArrayChecksumAlgoId &ids, const std::filesystem::path &filePath, bool &stopWriting) const
Gets checksums values from an array of wanted algorithms of checksums.
const std::filesystem::path baseDirectory
The base directory of the checksums' file.
bool writeV1(std::ostream &os, const ArrayPath &relativePaths)
Writes the XCKS file version 1.0.0 in a stream.
ArrayChecksumAlgoId getChecksumTypesForNewEntries() const
Returns the list of checksums algorithms to compute for new entries of this type of checksums' file.
const Version version
Version of the (Z)XCKS file to write.
const XCKSWriterOptions & writerOptions
The writer options.
bool writeLine(std::ostream &os, const std::string &line, const int indent)
Writes a line in the XCKS file.
XCKSWriterHandler & writerHandler
The XCKS file writer handler.
const ChecksumFormatter::ConfigurationProvider & ckfConfProvider
Configuration provider for ChecksumFormatter.
StringSet getAvailableChecksumTypesName() const
Returns the list of names of available checksums algorithms for this particular version of XCKS file.
const StringSet possibleSumsAlgos
Possible algorithms names for a (Z)XCKS file.
bool write(std::ostream &os, const ArrayPath &relativePaths)
Writes the checksums in a stream.
bool writeLocalFilesV1(std::ostream &os, const ArrayPath &relativePaths, int &indent)
Writes the "localFiles" section of a XCKS file version 1.0.0 in a stream.
const ArrayChecksumAlgoId sumsAlgos
Type of algorithms' checksums to write for each file.
XCKSWriterChecksumProvider & ckProvider
The provider of checksums values.
ArrayChecksumAlgoId getAvailableChecksumTypes() const
Returns the list of available checksums algorithms for this type of checksums' file.
Provides checksums values from an array of wanted algorithms of checksums for the XCKS writer.
virtual Status getChecksumValues(ArrayChecksumValue &sumValues, uintmax_t &filesize, time_t &filedatetime, const ArrayChecksumAlgoId &ids, const std::filesystem::path &filepath)=0
Provides checksums values from an array of wanted algorithms of checksums.
Status
Return status of getChecksumValues().
Handler for writing XCKS files.
virtual void onFatalError(const std::string &errorMessage)=0
Called on a non-recoverable error.
virtual void onChecksumsFileEnd()=0
Called on write checksumsFile end tag.
virtual void onParentDirectoryStart()=0
Called on write parentDirectory start tag.
virtual void onFileChecksum(const ChecksumValue &value)=0
Called on write checksum element (for file).
virtual void onFile(const std::filesystem::path &path, const ArrayChecksumValue &checksums, const uintmax_t size=Invalid_File_Size, const time_t date=Invalid_DateTime)=0
Called on write file element.
virtual void onDirectoryEnd()=0
Called on write directory end tag.
virtual void onAlgorithms(const ArrayChecksumAlgoId &types)=0
Called on write algorithms element.
virtual void onParentDirectoryEnd()=0
Called on write parentDirectory end tag.
virtual void onChecksumsFileStart(const std::string &version)=0
Called on write checksumsFile start tag.
virtual void onFileGetChecksumsError(const std::filesystem::path &relativePath, const std::filesystem::path &absolutePath, const XCKSWriterChecksumProvider::Status status, bool &stopWriting, const ChecksumAlgoId algoId=ChecksumAlgoId::Invalid)=0
Called on a failure on getting the checksums values for a file.
virtual void onLocalFilesStart()=0
Called on write localFiles start tag.
virtual void onGenerated(const std::string &by, const std::string &version, const std::time_t on)=0
Called on write generated element.
virtual void onFileGetChecksumError(const std::filesystem::path &relativePath, const std::filesystem::path &absolutePath, const XCKSWriterChecksumProvider::Status status, const ChecksumValue &ckValue)=0
Called on a failure on verifying a checksums value for a file.
virtual void onAlgorithm(const ChecksumAlgoId type)=0
Called on write algorithm element.
virtual void onFileInformation(const uintmax_t size=Invalid_File_Size, const time_t date=Invalid_DateTime)=0
Called on write information tag (for file).
virtual void onDirectoryStart(const std::string name)=0
Called on write directory start tag.
virtual void onLocalFilesEnd()=0
Called on write localFiles end tag.
virtual void onAlgorithmsStart()=0
Called on write algorithms start tag.
virtual void onFileStart(const std::string name)=0
Called on write file start tag.
virtual void onFileEnd()=0
Called on write file end tag.
Provides options for the XCKS writer.
virtual bool writeGeneratedElement() const final
Indicates whether the generated element must be written in the XCKS file.
virtual bool useCompactXML() const final
Indicates whether the XCKS file must be written in its compact form or not.
virtual bool writeFileDateTime() const final
Indicates whether the files' date/time must be written in the XCKS file.
virtual unsigned int getIndentSpaces() const final
Returns the number of spaces to use for indention (meaningful only if useTabsforIndentation() returns...
virtual bool writeLibXCKSVersion() const final
Indicates whether the name and version of the libxcks must be written with the application name and v...
virtual bool checkReturnedChecksums() const final
Indicates whether all checksums values returned by an XCKSWriterChecksumProvider instance must be ver...
virtual std::string getApplicationWriter() const final
Gets the name of the application using libxcks to write the XCKS file.
virtual std::string getApplicationWriterVersion() const final
Gets the version of the application using libxcks to write the XCKS file.
virtual bool useTabsforIndentation() const final
Indicates which type of indentation should be used when writing the XCKS file.
virtual bool writeFileSize() const final
Indicates whether the files' size must be written in the XCKS file.
Common definitions for libxcks.
constexpr const char * libxcks_domain
Domain for translations (i18n).
constexpr std::uintmax_t Invalid_File_Size
Invalid file size.
constexpr std::time_t Invalid_DateTime
Invalid date/time.
int compareFileName(const std::string &fn1, const std::string &fn2)
Compares two file names.
std::filesystem::path constructPath(const ArrayString &dirs, const std::string &filename)
Constructs a path from an array of directories and an optional filename.
ArrayString getDirectoriesAsArrayString(const std::filesystem::path &p)
Gets directories of a path.
std::filesystem::path ensureEndsWithPathSeparator(const std::filesystem::path &p)
Ensures the path ends with a path separator.
std::string from_u8string(const std::string &s)
Returns an UTF-8 encoded string in an object of type std::string (C++17).
std::string escapeForXML(const std::string &str)
Escapes a string for writing it in a XML stream.
std::vector< ChecksumAlgoId > ArrayChecksumAlgoId
Array of ids of algorithms of checksums.
std::vector< std::filesystem::path > ArrayPath
Array of paths.
ChecksumAlgoId
Ids of algorithms of checksums.
std::vector< std::string > ArrayString
Array of strings.
Version
Known versions of XCKS file.
std::set< std::string > StringSet
Set of strings.
LIBXCKS_SO_EXPORT const std::string getLibraryVersion()
Gets the version of the library.
LIBXCKS_SO_EXPORT const std::string getLibraryName()
Gets the name of the library.
LIBXCKS_SO_EXPORT const std::string getLibraryNameAndVersion()
Gets the name and the version of the library.
Classes that write a XCKS file.
Versions of (Z)XCKS files.
LIBXCKS_SO_EXPORT const StringSet getAvailableAlgorithmNames(const Version version)
Gets the available names of algorithm for a version of (Z)XCKS file.