first check-in of feisty meow codebase. many things broken still due to recent
[feisty_meow.git] / core / library / filesystem / heavy_file_ops.h
1 #ifndef HEAVY_FILE_OPERATIONS_CLASS
2 #define HEAVY_FILE_OPERATIONS_CLASS
3
4 /*****************************************************************************\
5 *                                                                             *
6 *  Name   : heavy file operations                                             *
7 *  Author : Chris Koeritz                                                     *
8 *                                                                             *
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 \*****************************************************************************/
17
18 #include "filename_list.h"
19
20 #include <basis/astring.h>
21 #include <basis/contracts.h>
22
23 namespace filesystem {
24
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. */
28
29 class file_transfer_header : public basis::packable
30 {
31 public:
32   basis::astring _filename;  //!< the name of the file being transferred.
33   double _byte_start;  //!< the starting location in the file being sent.
34   int _length;  //!< the length of the transferred piece.
35   file_time _time;  //!< the timestamp on the file.
36
37   DEFINE_CLASS_NAME("file_transfer_header");
38
39   file_transfer_header(const file_time &time_stamp);
40     //!< refactored to force addition of the time_stamp.
41
42   virtual void pack(basis::byte_array &packed_form) const;
43   virtual bool unpack(basis::byte_array &packed_form);
44
45   virtual int packed_size() const;
46
47   basis::astring text_form() const;
48
49 //hmmm: this could live in lots of other places.  file_info for one.
50   basis::astring readable_text_form() const;
51     //!< a nicer formatting of the information.
52 };
53
54 //////////////
55
56 //! Provides serious file operations, such as copy and partial writing.
57
58 class heavy_file_operations : public virtual basis::root_object
59 {
60 public:
61   virtual ~heavy_file_operations();
62
63   enum outcomes {
64     OKAY = basis::common::OKAY,
65     BAD_INPUT = basis::common::BAD_INPUT,
66 //    GARBAGE = basis::common::GARBAGE,
67 //    NOT_FOUND = basis::common::NOT_FOUND,
68 //    NONE_READY = basis::common::NONE_READY,
69 //    FAILURE = basis::common::FAILURE,
70     DEFINE_OUTCOME(SOURCE_MISSING, -43, "The source file is not accessible"),
71     DEFINE_OUTCOME(TARGET_DIR_ERROR, -44, "The target's directory could not "
72         "be created"),
73     DEFINE_OUTCOME(TARGET_ACCESS_ERROR, -45, "The target file could not be "
74         "created")
75   };
76   static const char *outcome_name(const basis::outcome &to_name);
77
78   DEFINE_CLASS_NAME("heavy_file_operations");
79
80   static const size_t COPY_CHUNK_FACTOR;
81     //!< the default copy chunk size for the file copy method.
82   static size_t copy_chunk_factor();
83     //!< method can be exported for use by shared libs.
84
85   static basis::outcome copy_file(const basis::astring &source, const basis::astring &destination,
86           int copy_chunk_factor = copy_chunk_factor());
87     //!< copies a file from the "source" location to the "destination".
88     /*!< the outcomes could be from this class or from common::outcomes.
89     the "copy_chunk_factor" is the read buffer size to use while copying. */
90
91   static basis::outcome write_file_chunk(const basis::astring &target, double byte_start,
92           const basis::byte_array &chunk, bool truncate = true,
93           int copy_chunk_factor = copy_chunk_factor());
94     //!< stores a chunk of bytes into the "target" file.
95     /*!< writes the content stored in "chunk" into the file "target" at the
96     position "byte_start".  the entire "chunk" will be used, which means the
97     file will either be that much larger or have the space between byte_start
98     and (byte_start + chunk.length() - 1) replaced.  if the file is not yet as
99     large as "byte_start", then it will be expanded appropriately.  if
100     "truncate" is true, then any contents past the new chunk are dropped from
101     the file. */
102
103   static basis::outcome buffer_files(const basis::astring &source_root,
104           const filename_list &to_transfer, file_transfer_header &last_action,
105           basis::byte_array &storage, int maximum_bytes);
106     //!< reads files in "to_transfer" and packs them into a "storage" buffer.
107     /*!< the maximum size allowed in storage is "maximum_bytes".  the record
108     of the last file piece stored in "last_action" allows the next chunk
109     to be sent in subsequent calls.  note that the buffer "storage" is cleared
110     out before bytes are stored into it; this is not an additive operation. */
111
112 private:
113   static bool advance(const filename_list &to_transfer, file_transfer_header &last_action);
114     //!< advances to the next file in the transfer list "to_transfer".
115 };
116
117 //////////////
118
119 } //namespace.
120
121 #endif
122