Merge branch 'master' of ssh://feistymeow.org/feisty_meow
[feisty_meow.git] / nucleus / library / filesystem / filename_list.cpp
1 /*****************************************************************************\
2 *                                                                             *
3 *  Name   : filename_list                                                     *
4 *  Author : Chris Koeritz                                                     *
5 *                                                                             *
6 *******************************************************************************
7 * Copyright (c) 2005-$now By Author.  This program is free software; you can  *
8 * redistribute it and/or modify it under the terms of the GNU General Public  *
9 * License as published by the Free Software Foundation; either version 2 of   *
10 * the License or (at your option) any later version.  This is online at:      *
11 *     http://www.fsf.org/copyleft/gpl.html                                    *
12 * Please send any updates to: fred@gruntose.com                               *
13 \*****************************************************************************/
14
15 #include "filename_list.h"
16
17 #include <structures/string_array.h>
18 #include <textual/parser_bits.h>
19
20 using namespace basis;
21 using namespace structures;
22 using namespace textual;
23
24 namespace filesystem {
25
26 filename_list::filename_list() : amorph<file_info>() {}
27
28 filename_list &filename_list::operator =(const filename_list &to_copy)
29 {
30   if (this == &to_copy) return *this;
31   reset();
32   for (int i = 0; i < to_copy.elements(); i++) {
33     append(new file_info(*to_copy.get(i)));
34   }
35   return *this;
36 }
37
38 int filename_list::total_files() const { return elements(); }
39
40 int filename_list::packed_size() const
41 { return amorph_packed_size(*this); }
42
43 void filename_list::pack(byte_array &packed_form) const
44 { amorph_pack(packed_form, *this); }
45
46 bool filename_list::unpack(byte_array &packed_form)
47 { return amorph_unpack(packed_form, *this); }
48
49 double filename_list::total_size() const
50 {
51   double to_return = 0;
52   for (int i = 0; i < elements(); i++)
53     to_return += get(i)->_file_size;
54   return to_return;
55 }
56
57 bool filename_list::calculate_progress(const filename &file,
58     double current_offset, int &current_file, double &current_size)
59 {
60   current_file = 0;
61   current_size = 0;
62   int posn = locate(file);
63   if (negative(posn)) {
64     if (file.raw().t()) return false;  // not a member.
65     // they're at the start of the run.
66     current_file = 1;
67     return true;
68   }
69   current_file = posn + 1;  // position zero in array means file number 1.
70   double size_finished = 0;
71   // iterate on all files before the current one.
72   for (int i = 0; i < posn; i++) {
73     size_finished += get(i)->_file_size;
74   }
75   current_size = size_finished + current_offset;
76   return true;
77 }
78
79 filename_list &filename_list::operator = (const string_array &to_copy)
80 {
81   reset();
82   for (int i = 0; i < to_copy.length(); i++) {
83     append(new file_info(to_copy[i], 0));
84   }
85   return *this;
86 }
87
88 void filename_list::fill(string_array &to_fill)
89 {
90   to_fill.reset();
91   for (int i = 0; i < elements(); i++) {
92     to_fill += get(i)->raw();
93   }
94 }
95
96 const file_info *filename_list::find(const filename &to_check) const
97 {
98   for (int i = 0; i < elements(); i++) {
99 #if defined(__WIN32__) || defined(__VMS__)
100     if (to_check.raw().iequals(get(i)->raw())) return get(i);
101 #else
102     if (to_check.raw() == get(i)->raw()) return get(i);
103 #endif
104   }
105   return NIL;
106 }
107
108 int filename_list::locate(const filename &to_find) const
109 {
110   for (int i = 0; i < elements(); i++) {
111 #if defined(__WIN32__) || defined(__VMS__)
112     if (to_find.raw().iequals(get(i)->raw())) return i;
113 #else
114     if (to_find.raw() == get(i)->raw()) return i;
115 #endif
116   }
117   return common::NOT_FOUND;
118 }
119
120 bool filename_list::member(const filename &to_check) const
121 {
122   for (int i = 0; i < elements(); i++) {
123 #if defined(__WIN32__) || defined(__VMS__)
124     if (to_check.raw().iequals(get(i)->raw())) return true;
125 #else
126     if (to_check.raw() == get(i)->raw()) return true;
127 #endif
128   }
129   return false;
130 }
131
132 bool filename_list::member_with_state(const file_info &to_check, file_info::file_similarity how)
133 {
134   for (int i = 0; i < elements(); i++) {
135 #if defined(__WIN32__) || defined(__VMS__)
136     if (to_check.raw().iequals(get(i)->raw())) {
137 #else
138     if (to_check.raw() == get(i)->raw()) {
139 #endif
140       // once we have matched a name, the other checks will cause us to
141       // reject any other potential matches after this one if the requested
142       // check fails.
143       if ((how & file_info::EQUAL_FILESIZE) && (to_check._file_size != get(i)->_file_size) )
144         return false;
145       if ((how & file_info::EQUAL_TIMESTAMP) && (to_check._time != get(i)->_time) )
146         return false;
147       if ((how & file_info::EQUAL_CHECKSUM) && (to_check._checksum != get(i)->_checksum) )
148         return false;
149       return true;
150     }
151   }
152   return false;
153 }
154
155 astring filename_list::text_form() const
156 {
157   astring to_return;
158 //hmmm: a length limit might be nice?
159   for (int i = 0; i < elements(); i++) {
160     to_return += a_sprintf("%d. ", i + 1);
161     if (get(i))
162       to_return += get(i)->text_form();
163     if (i != elements() - 1)
164       to_return += parser_bits::platform_eol_to_chars();
165   }
166   return to_return;
167 }
168
169 } //namespace.
170