📄 file_07.cc
字号:
boolean File::close() { // check the file pointer // if (fp_d == (FILE*)NULL) { return Error::handle(name(), L"close", ERR_NOTOPN, __FILE__, __LINE__, Error::WARNING); } // if the file isn't a standard stream, close it // if ((fp_d != stdout) && (fp_d != stdin) && (fp_d != stderr)) { ::fclose(fp_d); } // reset // fp_d = (FILE*)NULL; mode_d = DEF_MODE; type_d = DEF_TYPE; // exit gracefully // return true;}// method: seek//// arguments:// long offset: (input) byte offset// SEEK mode: (input) where to seek from//// return: a boolean value indicating status//// seek to the specified location within the open file//boolean File::seek(long offset_a, SEEK mode_a) { // check the file pointer // if (fp_d == (FILE*)NULL) { return Error::handle(name(), L"seek", ERR_NOTOPN, __FILE__, __LINE__, Error::WARNING); } // call the system function // if (::fseek(fp_d, offset_a, (long)mode_a) != 0) { return Error::handle(name(), L"seek", Error::SEEK, __FILE__, __LINE__, Error::WARNING); } // exit gracefully // return true;}// method: tell//// arguments: none//// return: a long number//// determine the file position//long File::tell() const { // check the file pointer // if (fp_d == (FILE*)NULL) { Error::handle(name(), L"tell", ERR_NOTOPN, __FILE__, __LINE__, Error::WARNING); return BAD_COUNT; } // call the system function // long pos = ::ftell(fp_d); // error check system call // if (pos < 0) { return Error::handle(name(), L"tell", Error::SYS_CALL, __FILE__, __LINE__, Error::WARNING); } // exit gracefully // return pos;}// method: put//// arguments:// const SysChar chr: (input) character to write// // return: a boolean value indicating status//// output a char into the file//boolean File::put(const SysChar chr_a) { // null file pointer, error // if (fp_d == (FILE*)NULL) { return Error::handle(name(), L"put", Error::WRITE_CLOSED, __FILE__, __LINE__); } // check the mode // if (mode_d == READ_ONLY) { return Error::handle(name(), L"put", Error::MOD_READONLY, __FILE__, __LINE__); } // temporary variable // unichar chr = chr_a; // put the character // if (SysString::isip_fputwc(chr, fp_d) == (wint_t)WEOF) { // nothing has been put // return false; } // exit gracefully // return true;}// method: put//// arguments:// const SysString& str: (output) String of data to write// // return: a boolean value indicating status//// put a string into the file//boolean File::put(const SysString& str_a) { // check the file pointer // if (fp_d == (FILE*)NULL) { return Error::handle(name(), L"put", Error::WRITE_CLOSED, __FILE__, __LINE__); } // check the file mode // if (mode_d == READ_ONLY) { return Error::handle(name(), L"put", Error::MOD_READONLY, __FILE__, __LINE__); } // a local flag indicating line-wrapping // boolean wrapping = false; // if we aren't indenting or wrapping, easy // if ((indent_level_d <= 0) && (line_wrap_d <= 0)) { // write the string // if (SysString::isip_fputws((unichar*)str_a, fp_d) < 0) { // nothing has been written // return false; } // check column position // long l = str_a.length(); if ((l > 0) && (str_a(l - 1) == L'\n')) { column_position_d = 0; } else { column_position_d = 1; } } // else we need to go through newline by newline // else { // build the indent string // SysString indent_str; for (long i = 0; i < indent_level_d; i++) { indent_str.concat(INDENT_STR); } SysString out_str; // we will deal with characters from start_pos to stop_pos, // inclusive, every iteration // long start_pos = 0; long stop_pos = -1; long next_newline = -1; do { // find the newline // if (next_newline < start_pos) { next_newline = str_a.firstChr(L'\n', start_pos); } stop_pos = next_newline; // terminal condition // if (stop_pos == Integral::NO_POS) { stop_pos = str_a.length() - 1; } long tot_len; // if we are at the beginning of a line // if (column_position_d == 0) { tot_len = stop_pos - start_pos + 1 + indent_str.length(); // write out the pre-indent wrap string // if (wrapping) { const long wpis_len = WRAP_PRE_INDENT_STR.length(); tot_len += wpis_len; if (SysString::isip_fputws((unichar*)WRAP_PRE_INDENT_STR, fp_d) < 0){ return false; } } // write out the indentation string // if (indent_level_d > 0) { if (SysString::isip_fputws((unichar*)indent_str, fp_d) < 0) { return false; } } // write out the post-indent wrap string // if (wrapping) { const long wpi_len = WRAP_POST_INDENT_STR.length(); tot_len += wpi_len; if (SysString::isip_fputws((unichar*)WRAP_POST_INDENT_STR,fp_d) < 0){ return false; } } } // else we are continuing a line // else { tot_len = stop_pos - start_pos + 1 + column_position_d; } // possibly wrap // if ((line_wrap_d > 0) && (tot_len > line_wrap_d)) { // make sure user settings are possible (that we can at least // print 1 character per line // if ((tot_len - (stop_pos - start_pos + 1)) > line_wrap_d) { return Error::handle(name(), L"put", ERR_WRAP, __FILE__, __LINE__, Error::WARNING); line_wrap_d = DEF_LINE_WRAP; } // set the flag // wrapping = true; // if we wrap, we need the wrap terminating string // const long wts_len = WRAP_TERM_STR.length(); tot_len += wts_len - 1; // decrement stop_pos by how much we overlap // stop_pos = start_pos + (line_wrap_d - (tot_len - (stop_pos - start_pos + 1))); // keep decrementing until we hit a good break point // long good_stop_pos = stop_pos + 1; SysChar current_char; do { good_stop_pos--; if (good_stop_pos <= start_pos) { break; } current_char.assign(str_a(good_stop_pos)); } while ((current_char.isPrint()) && (!current_char.isSpace())); // if we found a good break point, modify stop_position to be // this new break point. If not, then we have to live with // breaking exactly at the specified location // if (good_stop_pos > start_pos) { stop_pos = good_stop_pos; } // if there is no good breakpoint on this line but this line // already had stuff on it, then don't print anything on this // line and try again to tokenize the next line // else if (column_position_d != 0) { stop_pos = start_pos - 1; } column_position_d = line_wrap_d; } else { // clear the flag // wrapping = false; column_position_d = tot_len; } // write out this portion of the string // str_a.substr(out_str, start_pos, stop_pos - start_pos + 1); if (SysString::isip_fputws((unichar*)out_str, fp_d) < 0) { return false; } long l = out_str.length(); if ((l > 0) && (out_str(l - 1) == L'\n')) { column_position_d = 0; } // possibly add the terminator // if (wrapping) { if (SysString::isip_fputws((unichar*)WRAP_TERM_STR, fp_d) < 0) { return false; } column_position_d = 0; } // get he next start_pos // start_pos = stop_pos + 1; } while (stop_pos < (str_a.length() -1)); } // exit gracefully // return true;}// method: setOpenRetry//// arguments:// long retry: (input) number of times to try to open the file// long delay: (input) pause in seconds between attempts//// return: a boolean value indicating status//// this method sets the number of retry times that a file will be polled for// opening before an error is returned. this is useful in the case// when the file system says the file doesn't exist, but it really does// (such as a file system error).//boolean File::setOpenRetry(long retry_a, long delay_a) { // check arguments // if ((retry_a < 0) || (delay_a < 1)) { return Error::handle(name(), L"setOpenRetry", Error::ARG, __FILE__, __LINE__); } // set the retry flags // open_retry_d = retry_a; open_delay_d = delay_a; // exit gracefully // return true;}// method: size//// arguments:// boolean keep_position: (input) whether we should preserve the// current position//// return: size of the file in bytes//// determine the size of the given file//long File::size(boolean keep_position_a) const { // make sure the file is open // if (!isOpen()) { Error::handle(name(), L"size", ERR_NOTOPN, __FILE__, __LINE__); return -1; } // possibly save the seek position // long cur_pos = -1; if (keep_position_a) { cur_pos = tell(); } long tsize = -1; // seek to the end of the file // const_cast<File*>(this)->seek(0, POS_PLUS_END); // save the size // tsize = tell(); // possibly seek back to the previous position // if (keep_position_a) { const_cast<File*>(this)->seek(cur_pos, POS); } // return the size // return tsize;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -