/** @file * @author Edouard DUPIN * @copyright 2014, Edouard DUPIN, all right reserved * @license MPL v2.0 (see license file) */ #include #include #include #include #include #include #include "debug.hpp" #include ETK_DECLARE_TYPE(zeus::FileImpl); ememory::SharedPtr zeus::File::create(etk::Uri _fileNameReal) { return ememory::makeShared(_fileNameReal); } ememory::SharedPtr zeus::File::create(etk::Uri _fileNameReal, etk::String _sha512) { return ememory::makeShared(_fileNameReal, _sha512); } ememory::SharedPtr zeus::File::create(etk::Uri _fileNameReal, etk::String _fileNameShow, etk::String _mineType) { return ememory::makeShared(_fileNameReal, _fileNameShow, _mineType); } ememory::SharedPtr zeus::File::create(etk::Uri _fileNameReal, etk::String _fileNameShow, etk::String _mineType, etk::String _sha512) { return ememory::makeShared(_fileNameReal, _fileNameShow, _mineType, _sha512); } ememory::SharedPtr zeus::File::create(etk::Vector _fileData, etk::String _virtualName, etk::String _mineType) { return ememory::makeShared(etk::move(_fileData), _virtualName, _mineType); } zeus::FileImpl::FileImpl(etk::Vector _value, etk::String _virtualName, etk::String _mineType) : m_filename(_virtualName), m_gettedData(0), m_mineType(_mineType), m_sha512("") { ZEUS_ERROR(" ==============>>>>>>>>>>>>>> CREATE FILE 1 " << _virtualName); m_dataRaw = true; m_data = _value; m_size = m_data.size(); } zeus::FileImpl::FileImpl(etk::Uri _fileNameReal, etk::String _sha512) : m_filename(_fileNameReal.getPath().getFileName()), m_file(etk::uri::get(_fileNameReal)), m_gettedData(0), m_sha512(_sha512) { ZEUS_ERROR(" ==============>>>>>>>>>>>>>> CREATE FILE 3 " << _fileNameReal << " '" << _sha512 << "' size=" << m_file->size()); m_size = m_file->size(); etk::String extention = _fileNameReal.getPath().getExtention(); m_mineType = zeus::getMineType(extention); if ( _sha512.size() > 0 && _sha512.size() != 128) { ZEUS_ERROR("Set a wrong sha512 file type"); _sha512.clear(); } } // sha 512 example: 6134b4a4b5b116cf1b1b757c5aa48bd8b3482b86c6d3fee389a0a3232f74e7331e5f8af6ad516d2ca92eda0a475f44e1291618562ce6f9e54634ba052650dcd7 // 000000000100000000020000000003000000000400000000050000000006000000000700000000080000000009000000000A000000000B000000000C00000000 zeus::FileImpl::FileImpl(etk::Uri _fileNameReal, etk::String _fileNameShow, etk::String _mineType, etk::String _sha512) : m_filename(_fileNameShow), m_file(etk::uri::get(_fileNameReal)), m_gettedData(0), m_mineType(_mineType), m_sha512(_sha512) { ZEUS_ERROR(" ==============>>>>>>>>>>>>>> CREATE FILE 2 " << _fileNameReal); m_size = m_file->size(); if ( _sha512.size() > 0 && _sha512.size() != 128) { ZEUS_ERROR("Set a wrong sha512 file type"); _sha512.clear(); } } zeus::FileImpl::~FileImpl() { ZEUS_ERROR(" <<<<<<<<<<<<<<============== DESTROY FILE"); if (m_file->isOpen() == true) { m_file->close(); } } uint64_t zeus::FileImpl::getSize() { return m_size; } etk::String zeus::FileImpl::getName() { return m_filename; } etk::String zeus::FileImpl::getSha512() { ZEUS_VERBOSE("Get SHA 512 ... " << m_sha512.size() << " '" << m_sha512 << "'"); if (m_sha512 == "") { ZEUS_INFO("calculation of sha 512 (start)"); if (m_dataRaw == false) { m_sha512 = algue::stringConvert(algue::sha512::encodeFromFile(m_file)); } else { m_sha512 = algue::stringConvert(algue::sha512::encode(m_data)); } ZEUS_INFO("calculation of sha 512 (stop)"); } ZEUS_VERBOSE("return sha512 : '" << m_sha512 << "'"); return m_sha512; } etk::String zeus::FileImpl::getMineType() { return m_mineType; } zeus::Raw zeus::FileImpl::getPart(uint64_t _start, uint64_t _stop) { ZEUS_VERBOSE("REQUEST Get part ... " << _start << " " << _stop); if ((_stop - _start) > 25*1024*1024) { ZEUS_ERROR("REQUEST more that 25 Mo in a part file ..."); throw etk::exception::InvalidArgument("REQUEST more that 25 Mo in a part file ..." + etk::toString(_stop - _start) + " Bytes"); return zeus::Raw(); } if (_start >= m_size) { throw etk::exception::InvalidArgument("REQUEST start position out of file size" + etk::toString(_start) + " > " + etk::toString(m_size)); } if (m_dataRaw == false) { if (m_file->isOpen() == false) { m_file->open(etk::io::OpenMode::Read); } m_gettedData += (_stop - _start); //ZEUS_PRINT("Reading file : " << m_gettedData << "/" << m_size << " ==> " << float(m_gettedData)/float(m_size)*100.0f << "%"); printf("Reading file : %d/%d ==> %f \r", int(m_gettedData), int(m_size), float(m_gettedData)/float(m_size)*100.0f); zeus::Raw tmp(_stop - _start); if (m_file->seek(_start, etk::io::SeekMode::Start) == false) { ZEUS_ERROR("REQUEST seek error ..."); throw etk::exception::RuntimeError("Seek in the file error"); return zeus::Raw(); } int64_t sizeCopy = m_file->read(tmp.writeData(), 1, _stop-_start); if (m_size <= _stop) { m_file->close(); } // TODO : Check if copy is correct ... return etk::move(tmp); } else { m_gettedData += (_stop - _start); //ZEUS_PRINT("Reading file : " << m_gettedData << "/" << m_size << " ==> " << float(m_gettedData)/float(m_size)*100.0f << "%"); printf("Reading file : %d/%d ==> %f \r", int(m_gettedData), int(m_size), float(m_gettedData)/float(m_size)*100.0f); zeus::Raw tmp(_stop - _start); memcpy(tmp.writeData(), &m_data[_start], _stop-_start); return etk::move(tmp); } } etk::String zeus::storeInFile(zeus::ProxyFile _file, etk::Uri _uri) { zeus::ActionNotification tmp; return zeus::storeInFileNotify(_file, _uri, tmp); } etk::String zeus::storeInFileNotify(zeus::ProxyFile _file, etk::Uri _uri, zeus::ActionNotification _notification) { auto futSize = _file.getSize(); auto futSha = _file.getSha512(); futSize.wait(); int64_t retSize = futSize.get(); int64_t offset = 0; algue::Sha512 shaCtx; ememory::SharedPtr file = etk::uri::get(_uri); file->open(etk::io::OpenMode::Write); while (retSize > 0) { // get by batch of 1 MB int32_t nbElement = 1*1024*1024; if (retSize exception when read data ..."); throw etk::exception::RuntimeError("Error when loading data"); } zeus::Raw buffer = futData.get(); shaCtx.update(buffer.data(), buffer.size()); file->write(buffer.data(), 1, buffer.size()); offset += nbElement; retSize -= nbElement; ZEUS_VERBOSE("read: " << offset << "/" << futSize.get() << " " << buffer.size()); _notification.notify("{\"pourcent\":" + etk::toString(float(offset)/float(buffer.size())) + ", \"comment\":\"download\""); } file->close(); // get the final sha512 of the file: etk::String sha512String = algue::stringConvert(shaCtx.finalize()); futSha.wait(); if (sha512String != futSha.get()) { ZEUS_ERROR("get wrong Sha512 local : '" << sha512String << "'"); ZEUS_ERROR("get wrong Sha512 remote: '" << futSha.get() << "'"); throw etk::exception::RuntimeError("SHA-512 error check"); } return sha512String; } etk::Vector zeus::storeInMemory(zeus::ProxyFile _file) { etk::Vector out; auto futSize = _file.getSize(); auto futSha = _file.getSha512(); futSize.wait(); int64_t retSize = futSize.get(); int64_t offset = 0; algue::Sha512 shaCtx; out.resize(retSize); int64_t currentOffset = 0; while (retSize > 0) { // get by batch of 1 MB int32_t nbElement = 1*1024*1024; if (retSize