/* * Copyright (C) 2005-2018 Team Kodi * This file is part of Kodi - https://kodi.tv * * SPDX-License-Identifier: GPL-2.0-or-later * See LICENSES/README.md for more information. */ #pragma once #include "AddonClass.h" #include "AddonString.h" #include "LanguageHook.h" #include "commons/Buffer.h" #include "filesystem/File.h" #include namespace XBMCAddon { namespace xbmcvfs { // /// \defgroup python_file File /// \ingroup python_xbmcvfs /// @{ /// @brief Kodi's file class. /// /// \python_class{ xbmcvfs.File(filepath, [mode]) } /// /// @param filepath string Selected file path /// @param mode [opt] string Additional mode options (if no mode is supplied, the default is Open for Read). /// | Mode | Description | /// |:------:|:--------------------------------| /// | w | Open for write | /// /// ///-------------------------------------------------------------------------- /// @python_v19 Added context manager support /// /// **Example:** /// ~~~~~~~~~~~~~{.py} /// .. /// f = xbmcvfs.File(file, 'w') /// .. /// ~~~~~~~~~~~~~ /// /// **Example (v19 and up):** /// ~~~~~~~~~~~~~{.py} /// .. /// with xbmcvfs.File(file, 'w') as f: /// .. /// .. /// ~~~~~~~~~~~~~ // class File : public AddonClass { XFILE::CFile* file; public: inline File(const String& filepath, const char* mode = NULL) : file(new XFILE::CFile()) { DelayedCallGuard dg(languageHook); if (mode && strncmp(mode, "w", 1) == 0) file->OpenForWrite(filepath,true); else file->Open(filepath, XFILE::READ_NO_CACHE); } inline ~File() override { delete file; } #if !defined(DOXYGEN_SHOULD_USE_THIS) inline File* __enter__() { return this; } inline void __exit__() { close(); } #endif #ifdef DOXYGEN_SHOULD_USE_THIS /// /// \ingroup python_file /// @brief \python_func{ read([bytes]) } /// Read file parts as string. /// /// @param bytes [opt] How many bytes to read - if not /// set it will read the whole file /// @return string /// /// ///----------------------------------------------------------------------- /// /// **Example:** /// ~~~~~~~~~~~~~{.py} /// .. /// f = xbmcvfs.File(file) /// b = f.read() /// f.close() /// .. /// ~~~~~~~~~~~~~ /// /// **Example (v19 and up):** /// ~~~~~~~~~~~~~{.py} /// .. /// with xbmcvfs.File(file) as file: /// b = f.read() /// .. /// ~~~~~~~~~~~~~ /// read(...); #else inline String read(unsigned long numBytes = 0) { XbmcCommons::Buffer b = readBytes(numBytes); return b.getString(numBytes == 0 ? b.remaining() : std::min((unsigned long)b.remaining(),numBytes)); } #endif #ifdef DOXYGEN_SHOULD_USE_THIS /// /// \ingroup python_file /// @brief \python_func{ readBytes(numbytes) } /// Read bytes from file. /// /// @param numbytes How many bytes to read [opt]- if not set /// it will read the whole file /// @return bytearray /// /// ///----------------------------------------------------------------------- /// /// **Example:** /// ~~~~~~~~~~~~~{.py} /// .. /// f = xbmcvfs.File(file) /// b = f.readBytes() /// f.close() /// .. /// ~~~~~~~~~~~~~ /// /// **Example (v19 and up):** /// ~~~~~~~~~~~~~{.py} /// .. /// with xbmcvfs.File(file) as f: /// b = f.readBytes() /// .. /// ~~~~~~~~~~~~~ /// readBytes(...); #else XbmcCommons::Buffer readBytes(unsigned long numBytes = 0); #endif #ifdef DOXYGEN_SHOULD_USE_THIS /// /// \ingroup python_file /// @brief \python_func{ write(buffer) } /// To write given data in file. /// /// @param buffer Buffer to write to file /// @return True on success. /// /// ///----------------------------------------------------------------------- /// /// **Example:** /// ~~~~~~~~~~~~~{.py} /// .. /// f = xbmcvfs.File(file, 'w') /// result = f.write(buffer) /// f.close() /// .. /// ~~~~~~~~~~~~~ /// /// **Example (v19 and up):** /// ~~~~~~~~~~~~~{.py} /// .. /// with xbmcvfs.File(file, 'w') as f: /// result = f.write(buffer) /// .. /// ~~~~~~~~~~~~~ /// write(...); #else bool write(XbmcCommons::Buffer& buffer); #endif #ifdef DOXYGEN_SHOULD_USE_THIS /// /// \ingroup python_file /// @brief \python_func{ size() } /// Get the file size. /// /// @return The file size /// /// ///----------------------------------------------------------------------- /// /// **Example:** /// ~~~~~~~~~~~~~{.py} /// .. /// f = xbmcvfs.File(file) /// s = f.size() /// f.close() /// .. /// ~~~~~~~~~~~~~ /// /// **Example (v19 and up):** /// ~~~~~~~~~~~~~{.py} /// .. /// with xbmcvfs.File(file) as f: /// s = f.size() /// .. /// ~~~~~~~~~~~~~ /// size(); #else inline long long size() { DelayedCallGuard dg(languageHook); return file->GetLength(); } #endif #ifdef DOXYGEN_SHOULD_USE_THIS /// /// \ingroup python_file /// @brief \python_func{ seek(seekBytes, iWhence) } /// Seek to position in file. /// /// @param seekBytes position in the file /// @param iWhence [opt] where in a file to seek from[0 beginning, /// 1 current , 2 end position] /// /// ///----------------------------------------------------------------------- /// @python_v19 Function changed. param **iWhence** is now optional. /// /// **Example:** /// ~~~~~~~~~~~~~{.py} /// .. /// f = xbmcvfs.File(file) /// result = f.seek(8129, 0) /// f.close() /// .. /// ~~~~~~~~~~~~~ /// /// **Example (v19 and up):** /// ~~~~~~~~~~~~~{.py} /// .. /// with xbmcvfs.File(file) as f: /// result = f.seek(8129, 0) /// .. /// ~~~~~~~~~~~~~ /// seek(...); #else inline long long seek(long long seekBytes, int iWhence = SEEK_SET) { DelayedCallGuard dg(languageHook); return file->Seek(seekBytes,iWhence); } #endif #ifdef DOXYGEN_SHOULD_USE_THIS /// /// \ingroup python_file /// @brief \python_func{ tell() } /// Get the current position in the file. /// /// @return The file position /// /// ///----------------------------------------------------------------------- /// @python_v19 New function added /// /// **Example:** /// ~~~~~~~~~~~~~{.py} /// .. /// f = xbmcvfs.File(file) /// s = f.tell() /// f.close() /// .. /// ~~~~~~~~~~~~~ /// /// **Example (v19 and up):** /// ~~~~~~~~~~~~~{.py} /// .. /// with xbmcvfs.File(file) as f: /// s = f.tell() /// .. /// ~~~~~~~~~~~~~ /// tell(); #else inline long long tell() { DelayedCallGuard dg(languageHook); return file->GetPosition(); } #endif #ifdef DOXYGEN_SHOULD_USE_THIS /// /// \ingroup python_file /// @brief \python_func{ close() } /// Close opened file. /// /// ///----------------------------------------------------------------------- /// /// **Example:** /// ~~~~~~~~~~~~~{.py} /// .. /// f = xbmcvfs.File(file) /// f.close() /// .. /// ~~~~~~~~~~~~~ /// /// **Example (v19 and up):** /// ~~~~~~~~~~~~~{.py} /// .. /// with xbmcvfs.File(file) as f: /// .. /// .. /// ~~~~~~~~~~~~~ /// close(); #else inline void close() { DelayedCallGuard dg(languageHook); file->Close(); } #endif #ifndef SWIG inline const XFILE::CFile* getFile() const { return file; } #endif }; //@} } }