25 using namespace basis;
35 #define LOG(to_print) printf("%s::%s: %s\n", static_class_name(), func, astring(to_print).s())
44 file_transfer_header::file_transfer_header(
const file_time &time_stamp)
111 switch (to_name.
value()) {
112 case SOURCE_MISSING:
return "SOURCE_MISSING";
113 case TARGET_ACCESS_ERROR:
return "TARGET_ACCESS_ERROR";
114 case TARGET_DIR_ERROR:
return "TARGET_DIR_ERROR";
115 default:
return common::outcome_name(to_name);
120 const astring &destination,
int copy_chunk_factor)
122 #ifdef DEBUG_HEAVY_FILE_OPS
127 if (!source_path.
exists())
return SOURCE_MISSING;
137 if (!source_file.
good())
return SOURCE_MISSING;
141 huge_file target_file(destination,
"wb");
142 if (!target_file.
good())
return TARGET_ACCESS_ERROR;
150 ret = target_file.
write(chunk, bytes_stored);
151 if (bytes_stored != bytes_read)
return TARGET_ACCESS_ERROR;
152 if (source_file.
eof())
break;
158 #ifdef DEBUG_HEAVY_FILE_OPS
161 LOG(
astring(
"setting file time for ") + source +
" to " + time);
168 double byte_start,
const byte_array &chunk,
bool truncate,
169 int copy_chunk_factor)
176 #ifdef DEBUG_HEAVY_FILE_OPS
181 return TARGET_DIR_ERROR;
184 if (!targ_name.
exists()) {
190 if (!target_file.
good())
return TARGET_ACCESS_ERROR;
191 double curr_len = target_file.
length();
194 if (curr_len < byte_start) {
196 while (curr_len < byte_start) {
199 int(curr_len - byte_start + 1)));
202 if (written < new_chunk.
length())
return TARGET_ACCESS_ERROR;
203 curr_len = target_file.
length();
210 if (wrote != chunk.
length())
return TARGET_ACCESS_ERROR;
228 #ifdef DEBUG_HEAVY_FILE_OPS
230 LOG(
astring(
"failed for ") + currfile->
raw() +
" -- has zero file time");
253 bool fresh_file =
false;
256 while (storage.
length() < maximum_bytes) {
257 double remaining_in_array = maximum_bytes - storage.
length()
285 if (!current.
good()) {
287 LOG(
astring(
"skipping bad file: ") + full_file);
289 to_return = advance(to_transfer, last_action);
290 if (to_return !=
OKAY)
break;
298 #ifdef DEBUG_HEAVY_FILE_OPS
299 LOG(
astring(
"finished stuffing file: ") + full_file);
302 to_return = advance(to_transfer, last_action);
303 if (to_return !=
OKAY)
break;
313 double remaining_in_file = current.
length() - new_start;
314 if (remaining_in_file < 0) remaining_in_file = 0;
315 double new_len =
minimum(remaining_in_file, remaining_in_array);
321 outcome ret = current.
read(new_chunk,
int(new_len), bytes_read);
322 if (bytes_read != new_len) {
326 to_return = advance(to_transfer, last_action);
327 if (to_return !=
OKAY)
break;
335 last_action.
_length = int(new_len);
338 last_action.
pack(storage);
339 storage += new_chunk;
345 to_return = advance(to_transfer, last_action);
346 if (to_return !=
OKAY)
break;
a_sprintf is a specialization of astring that provides printf style support.
void reset(int number=0, const contents *initial_contents=NULL_POINTER)
Resizes this array and sets the contents from an array of contents.
int length() const
Returns the current reported length of the allocated C array.
Provides a dynamically resizable ASCII character string.
void pack(byte_array &target) const
stores this string in the "target". it can later be unpacked again.
int length() const
Returns the current length of the string.
bool unpack(byte_array &source)
retrieves a string (packed with pack()) from "source" into this string.
A very common template for a dynamic array of bytes.
Outcomes describe the state of completion for an operation.
@ FROM_START
offset is from the beginning of the file.
@ FROM_END
offset is from the end of the file.
static bool recursive_create(const basis::astring &directory_name)
returns true if the "directory_name" can be created or already exists.
Encapsulates some measures and calculations based on a file's contents.
file_time _time
the file's access time.
bool set_time(const basis::astring &filename)
sets the time for the the "filename" to the currently held time.
virtual int packed_size() const
virtual void pack(basis::byte_array &packed_form) const
virtual void text_form(basis::base_string &time_string) const
returns a definitive but sorta ugly version of the file's time.
virtual void readable_text_form(basis::base_string &time_string) const
sets "time_string" to a human readable form of the file's time.
virtual bool unpack(basis::byte_array &packed_form)
const file_info * find(const filename &to_check) const
locates the record of information for the filename "to_check".
int locate(const filename &to_find) const
Provides operations commonly needed on file names.
bool exists() const
returns true if the file exists.
const basis::astring & raw() const
returns the astring that we're holding onto for the path.
filename dirname() const
returns the directory for the filename.
static size_t copy_chunk_factor()
method can be exported for use by shared libs.
static const size_t COPY_CHUNK_FACTOR
the default copy chunk size for the file copy method.
static basis::outcome copy_file(const basis::astring &source, const basis::astring &destination, int copy_chunk_factor=heavy_file_operations::copy_chunk_factor())
copies a file from the "source" location to the "destination".
static basis::outcome write_file_chunk(const basis::astring &target, double byte_start, const basis::byte_array &chunk, bool truncate=true, int copy_chunk_factor=heavy_file_operations::copy_chunk_factor())
stores a chunk of bytes into the "target" file.
static const char * outcome_name(const basis::outcome &to_name)
virtual ~heavy_file_operations()
static basis::outcome buffer_files(const basis::astring &source_root, const filename_list &to_transfer, file_transfer_header &last_action, basis::byte_array &storage, int maximum_bytes)
reads files in "to_transfer" and packs them into a "storage" buffer.
Supports reading and writing to very large files, > 4 gigabytes.
double length()
expensive operation accesses the file to find length.
bool truncate()
truncates the file after the current position.
bool eof() const
reports when the file pointer has reached the end of the file.
basis::outcome seek(double new_position, byte_filer::origins origin=byte_filer::FROM_CURRENT)
move the file pointer to "new_position" if possible.
basis::outcome write(const basis::byte_array &to_write, int &size_written)
stores the array "to_write" into the file.
bool good() const
reports if the file was opened successfully.
basis::outcome read(basis::byte_array &to_fill, int desired_size, int &size_read)
reads "desired_size" into "to_fill" if possible.
int elements() const
the maximum number of elements currently allowed in this amorph.
const contents * get(int field) const
Returns a constant pointer to the information at the index "field".
#define FUNCDEF(func_in)
FUNCDEF sets the name of a function (and plugs it into the callstack).
The guards collection helps in testing preconditions and reporting errors.
const int MEGABYTE
Number of bytes in a megabyte.
void attach(byte_array &packed_form, const char *to_attach)
Packs a character string "to_attach" into "packed_form".
bool detach(byte_array &packed_form, astring &to_detach)
Unpacks a character string "to_attach" from "packed_form".
type minimum(type a, type b)
maximum returns the greater of two values.
bool negative(const type &a)
negative returns true if "a" is less than zero.
A platform independent way to obtain the timestamp of a file.
const int MINIMUM_ARRAY_SIZE
A dynamic container class that holds any kind of object via pointers.