1 #ifndef HEAVY_FILE_OPERATIONS_CLASS
2 #define HEAVY_FILE_OPERATIONS_CLASS
4 /*****************************************************************************\
6 * Name : heavy file operations *
7 * Author : Chris Koeritz *
9 *******************************************************************************
10 * Copyright (c) 2005-$now By Author. This program is free software; you can *
11 * redistribute it and/or modify it under the terms of the GNU General Public *
12 * License as published by the Free Software Foundation; either version 2 of *
13 * the License or (at your option) any later version. This is online at: *
14 * http://www.fsf.org/copyleft/gpl.html *
15 * Please send any updates to: fred@gruntose.com *
16 \*****************************************************************************/
18 #include "filename_list.h"
20 #include <basis/astring.h>
21 #include <basis/contracts.h>
23 namespace filesystem {
25 //! describes one portion of an ongoing file transfer.
26 /*! this is just a header describing an attached byte package. it is expected
27 that the bytes follow this in the communication stream. */
29 class file_transfer_header : public basis::packable
32 basis::astring _filename; //!< the name of the file being transferred.
33 //hmmm: consider adding full length here so we know it.
34 double _byte_start; //!< the starting location in the file being sent.
35 int _length; //!< the length of the transferred piece.
36 file_time _time; //!< the timestamp on the file.
38 DEFINE_CLASS_NAME("file_transfer_header");
40 file_transfer_header(const file_time &time_stamp);
41 //!< refactored to force addition of the time_stamp.
43 virtual void pack(basis::byte_array &packed_form) const;
44 virtual bool unpack(basis::byte_array &packed_form);
46 virtual int packed_size() const;
48 basis::astring text_form() const;
50 //hmmm: this could live in lots of other places. file_info for one.
51 basis::astring readable_text_form() const;
52 //!< a nicer formatting of the information.
57 //! Provides serious file operations, such as copy and partial writing.
59 class heavy_file_operations : public virtual basis::root_object
62 virtual ~heavy_file_operations();
65 OKAY = basis::common::OKAY,
66 BAD_INPUT = basis::common::BAD_INPUT,
67 FINISHED = basis::common::IS_EMPTY, // nothing left to pack.
68 DEFINE_OUTCOME(SOURCE_MISSING, -43, "The source file is not accessible"),
69 DEFINE_OUTCOME(TARGET_DIR_ERROR, -44, "The target's directory could not "
71 DEFINE_OUTCOME(TARGET_ACCESS_ERROR, -45, "The target file could not be "
74 static const char *outcome_name(const basis::outcome &to_name);
76 DEFINE_CLASS_NAME("heavy_file_operations");
78 static const size_t COPY_CHUNK_FACTOR;
79 //!< the default copy chunk size for the file copy method.
80 static size_t copy_chunk_factor();
81 //!< method can be exported for use by shared libs.
83 static basis::outcome copy_file(const basis::astring &source, const basis::astring &destination,
84 int copy_chunk_factor = heavy_file_operations::copy_chunk_factor());
85 //!< copies a file from the "source" location to the "destination".
86 /*!< the outcomes could be from this class or from common::outcomes.
87 the "copy_chunk_factor" is the read buffer size to use while copying. */
89 static basis::outcome write_file_chunk(const basis::astring &target, double byte_start,
90 const basis::byte_array &chunk, bool truncate = true,
91 int copy_chunk_factor = heavy_file_operations::copy_chunk_factor());
92 //!< stores a chunk of bytes into the "target" file.
93 /*!< writes the content stored in "chunk" into the file "target" at the
94 position "byte_start". the entire "chunk" will be used, which means the
95 file will either be that much larger or have the space between byte_start
96 and (byte_start + chunk.length() - 1) replaced. if the file is not yet as
97 large as "byte_start", then it will be expanded appropriately. if
98 "truncate" is true, then any contents past the new chunk are dropped from
101 static basis::outcome buffer_files(const basis::astring &source_root,
102 const filename_list &to_transfer, file_transfer_header &last_action,
103 basis::byte_array &storage, int maximum_bytes);
104 //!< reads files in "to_transfer" and packs them into a "storage" buffer.
105 /*!< the maximum size allowed in storage is "maximum_bytes". the record
106 of the last file piece stored in "last_action" allows the next chunk
107 to be sent in subsequent calls. note that the buffer "storage" is cleared
108 out before bytes are stored into it; this is not an additive operation. */
111 static basis::outcome advance(const filename_list &to_transfer,
112 file_transfer_header &last_action);
113 //!< advances to the next file in the transfer list "to_transfer".