src/XattrAttributeFinder.h
branchv_0
changeset 4 d44ed75822e7
parent 3 62eac7ab4cf4
child 5 ec661baf433a
equal deleted inserted replaced
3:62eac7ab4cf4 4:d44ed75822e7
       
     1 /**
       
     2  * Relational pipes
       
     3  * Copyright © 2019 František Kučera (Frantovo.cz, GlobalCode.info)
       
     4  *
       
     5  * This program is free software: you can redistribute it and/or modify
       
     6  * it under the terms of the GNU General Public License as published by
       
     7  * the Free Software Foundation, either version 3 of the License, or
       
     8  * (at your option) any later version.
       
     9  *
       
    10  * This program is distributed in the hope that it will be useful,
       
    11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
       
    13  * GNU General Public License for more details.
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License
       
    16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
       
    17  */
       
    18 #pragma once
       
    19 
       
    20 #include <vector>
       
    21 #include <filesystem>
       
    22 
       
    23 #include <relpipe/writer/typedefs.h>
       
    24 #include <relpipe/writer/AttributeMetadata.h>
       
    25 #include <relpipe/writer/RelationalWriter.h>
       
    26 
       
    27 #include "RequestedField.h"
       
    28 
       
    29 namespace relpipe {
       
    30 namespace in {
       
    31 namespace filesystem {
       
    32 
       
    33 namespace fs = std::filesystem;
       
    34 using namespace relpipe::writer;
       
    35 
       
    36 class XattrAttributeFinder : public AttributeFinder {
       
    37 private:
       
    38 	std::wstring_convert<codecvt_utf8<wchar_t>> convertor; // TODO: support also other encodings.
       
    39 
       
    40 	fs::path currentFile;
       
    41 
       
    42 	string_t getXattr(const fs::path& file, const string_t& attributeName) {
       
    43 		// TODO: review, test on multiple platforms
       
    44 		// TODO: improve documentation in xattr.h in glibc
       
    45 		// TODO: check XATTR_NAME_MAX in limits.h and if it is reasonably small on our system, allocate buffer for it instead of reading twice
       
    46 		// TODO: avoid race condition (another process might change the attribute between reading its length and its value)
       
    47 		ssize_t length = getxattr(file.c_str(), convertor.to_bytes(attributeName).c_str(), nullptr, 0);
       
    48 		if (length > 0) {
       
    49 			std::vector<char> buffer(length + 1);
       
    50 			getxattr(file.c_str(), convertor.to_bytes(attributeName).c_str(), buffer.data(), buffer.size());
       
    51 			return convertor.from_bytes(buffer.data());
       
    52 		} else {
       
    53 			return L"";
       
    54 		}
       
    55 	}
       
    56 public:
       
    57 
       
    58 	virtual vector<AttributeMetadata> toMetadata(const RequestedField& field) override {
       
    59 		if (field.group == RequestedField::GROUP_XATTR) return { AttributeMetadata{field.name, TypeId::STRING}};
       
    60 		else return {};
       
    61 	}
       
    62 
       
    63 	void startFile(const fs::path& file) override {
       
    64 		currentFile = file;
       
    65 	};
       
    66 
       
    67 	void endFile() override {
       
    68 	};
       
    69 
       
    70 	virtual void writeField(RelationalWriter* writer, const RequestedField& field) override {
       
    71 		if (field.group == RequestedField::GROUP_XATTR) writer->writeAttribute(getXattr(currentFile, field.name));
       
    72 	}
       
    73 
       
    74 	virtual ~XattrAttributeFinder() override {
       
    75 	}
       
    76 };
       
    77 
       
    78 }
       
    79 }
       
    80 }