27 using namespace basis;
32 #define LOG(s) program_wide_logger::get().log(s, 0)
40 c_filename_held(nechung_filename),
41 c_index_held(index_filename),
42 c_number_of_fortunes(0)
47 void nechung_oracle::parse_file()
53 LOG(
astring(
"filename=") + c_filename_held +
" idx file=" + c_index_held);
55 if (!fortune_file.good())
62 if (index_file.good()) {
64 LOG(
"index file exists");
66 file_time index_time((FILE *)index_file.file_handle());
67 file_time fortune_time((FILE *)fortune_file.file_handle());
68 if (index_time >= fortune_time) {
71 sscanf((
char *)buffer.access(),
"%d", &c_number_of_fortunes);
73 LOG(
astring(astring::SPRINTF,
"%d entries in index",
74 c_number_of_fortunes));
89 c_number_of_fortunes = 0;
90 fortune_states state = chowing_separators;
94 while (state != done_parsing) {
96 LOG(
astring(astring::SPRINTF,
"#%d", c_number_of_fortunes));
98 if (fortune_file.eof()) {
100 state = done_parsing;
104 case chowing_separators: {
108 posn = int(fortune_file.tell());
121 if (strlen((
char *)buffer.access()) == 2) posn += 2;
123 state = adding_fortunes;
127 case adding_fortunes: {
131 fortune_posns += posn;
132 c_number_of_fortunes++;
133 state = chowing_fortunes;
136 case chowing_fortunes: {
140 posn = int(fortune_file.tell());
145 LOG(
astring(astring::SPRINTF,
"got a line: %s", buffer.access()));
146 LOG(
astring(astring::SPRINTF,
"len is %d", strlen((
char *)buffer.access())));
149 && (strlen((
char *)buffer.access()) == 2) )
150 state = chowing_separators;
153 state = adding_fortunes;
162 fortune_file.close();
165 index_file.open(c_index_held.
observe(),
"w");
166 if (!index_file.good())
168 astring to_write(astring::SPRINTF,
"%d\n", c_number_of_fortunes);
169 index_file.write((
abyte *)to_write.s(), to_write.length());
170 for (
int j = 0; j < c_number_of_fortunes; j++) {
171 to_write.sprintf(
"%d\n", fortune_posns[j]);
172 index_file.write((
abyte *)to_write.s(), to_write.length());
184 byte_filer fortune_file(c_filename_held.
s(),
"rb");
188 if (!fortune_file.
good())
190 int to_display = c_randomizer.
inclusive(0, c_number_of_fortunes - 1);
200 if (index_file.
good()) {
203 for (
int i = 0; i <= to_display; i++) {
205 accumulated_text +=
astring(astring::SPRINTF,
"#%d: ", i);
208 sscanf((
char *)buffer.
access(),
"%d", &chosen_posn);
210 accumulated_text +=
astring(astring::SPRINTF,
"%d, ", chosen_posn);
211 if ((i + 1) % 5 == 0) accumulated_text +=
"\n";
215 LOG(accumulated_text);
220 astring(
"Could not open the index file \"") + c_index_held +
"\"");
224 LOG(
astring(astring::SPRINTF,
"about to seek @ num %d and "
225 "index %d", to_display, chosen_posn));
227 if (!fortune_file.
seek(chosen_posn, byte_filer::FROM_START))
235 while (!fortune_file.
eof()) {
238 if (!fortune_file.
eof()) {
250 {
return (to_check ==
'\n') || (to_check ==
'\r'); }
256 to_show.
zap(to_show.
end(), to_show.
end());
contents * access()
A non-constant access of the underlying C-array. BE REALLY CAREFUL.
Provides a dynamically resizable ASCII character string.
const char * s() const
synonym for observe. the 's' stands for "string", if that helps.
virtual void zap(int start, int end)
Deletes the characters between "start" and "end" inclusively.
int end() const
returns the index of the last (non-null) character in the string.
virtual const char * observe() const
observes the underlying pointer to the zero-terminated string.
A very common template for a dynamic array of bytes.
A simple object that wraps a templated array of ints.
Provides file managment services using the standard I/O support.
int getline(basis::abyte *buffer, int desired_size)
reads a line of text (terminated by a return) into the "buffer".
void close()
shuts down the open file, if any.
bool seek(int where, origins origin=FROM_START)
places the cursor in the file at "where", based on the "origin".
bool eof()
returns true if the cursor is at (or after) the end of the file.
bool good()
returns true if the file seems to be in the appropriate desired state.
int inclusive(int low, int high) const
< Returns a pseudo-random number r, such that "low" <= r <= "high".
basis::astring pick_random()
nechung_oracle(const basis::astring &data_filename, const basis::astring &index_filename)
virtual ~nechung_oracle()
#define non_continuable_error(c, f, i)
an extra piece of information used, if available, in bounds_halt below.
#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.
unsigned char abyte
A fairly important unit which is seldom defined...
A platform independent way to obtain the timestamp of a file.
A logger that sends to the console screen using the standard output device.
const int MAX_LINE_LENGTH
hmmm: fix filter value to be ALWAYS_PRINT!
bool is_eol(char to_check)
const char NECHUNG_SEPARATION_CHARACTER