00001 #ifndef WX_DEBUGGING_BASE_IMPLEMENTATION_FILE
00002 #define WX_DEBUGGING_BASE_IMPLEMENTATION_FILE
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "wx_debugging_base.h"
00020
00021 #include <basis/convert_utf.h>
00022 #include <basis/function.h>
00023 #include <basis/istring.h>
00024 #include <basis/version_record.h>
00025 #include <data_struct/static_memory_gremlin.h>
00026 #include <loggers/file_logger.h>
00027 #ifdef LIGHTLINK_CODEBASE
00028 #include <uls/uls.h>
00029 #endif
00030
00031 #undef GetClassInfo
00032 #include <wx/textctrl.h>
00033
00034 using namespace portable;
00035
00036
00037
00038
00039 const u_int LENGTH_CHOP_FACTOR = 8192;
00040
00041
00042
00043 const int ULS_BUFFER_SIZE = 164 * KILOBYTE;
00044
00045
00046
00047 const wxString wxstring_crlf = to_unicode_wx("\r\n");
00048 const wxString wxstring_lf = to_unicode_wx("\n");
00049
00050 #define DISABLE
00051 #define REENABLE
00052
00054
00055 wx_debugging_base::wx_debugging_base(wxTextCtrl &editor, int buffer_size, int file_size)
00056 : log_base(),
00057 _editor(editor),
00058 _length(0),
00059 _maximum_active_length(0),
00060 _file_limit(0),
00061 _log_name(new istring),
00062 _the_log(NIL)
00063 {
00064 buffer_limit(buffer_size);
00065 file_limit(file_size);
00066 }
00067
00068 wx_debugging_base::~wx_debugging_base()
00069 {
00070 shut_down();
00071 WHACK(_log_name);
00072 }
00073
00074 int wx_debugging_base::buffer_limit() { return _maximum_active_length; }
00075
00076 void wx_debugging_base::buffer_limit(int new_limit)
00077 {
00078 _maximum_active_length = new_limit;
00079 }
00080
00081 int wx_debugging_base::file_limit() const { return _file_limit; }
00082
00083
00084
00085 void wx_debugging_base::file_limit(int new_limit)
00086 {
00087 _file_limit = new_limit;
00088 if (!_file_limit) {
00089
00090 WHACK(_the_log);
00091 }
00092 if (_the_log) {
00093 #ifndef LIGHTLINK_CODEBASE
00094 _the_log->limit(_file_limit);
00095 #else
00096 _the_log->reopen(name(), _maximum_active_length, _file_limit);
00097 #endif
00098 }
00099 }
00100
00101 wxTextCtrl &wx_debugging_base::get_editor() { return _editor; }
00102
00103 istring wx_debugging_base::name() const { return *_log_name; }
00104
00105 void wx_debugging_base::name(const istring &new_name)
00106 {
00107 *_log_name = new_name;
00108 if (!_log_name->t()) {
00109
00110 WHACK(_the_log);
00111 }
00112 if (_the_log) {
00113 #ifndef LIGHTLINK_CODEBASE
00114 _the_log->name(new_name);
00115 #else
00116 _the_log->reopen(new_name, _maximum_active_length, _file_limit);
00117 #endif
00118 }
00119 }
00120
00121 void wx_debugging_base::setup()
00122 {
00123 _editor.SetMaxLength(0);
00124
00125
00126
00127 if (_file_limit && _log_name->t()) {
00128 #ifndef LIGHTLINK_CODEBASE
00129 _the_log = new file_logger(*_log_name, _file_limit);
00130 #else
00131 _the_log = new uls(*_log_name, ULS_BUFFER_SIZE, _file_limit);
00132 #endif
00133 }
00134
00135 }
00136
00137 void wx_debugging_base::shut_down()
00138 {
00139
00140 WHACK(_the_log);
00141 }
00142
00143 bool wx_debugging_base::get_selection(int &start, int &end)
00144 {
00145 DISABLE;
00146 long s, e;
00147 _editor.GetSelection(&s, &e);
00148 start = int(s);
00149 e = int(e);
00150 int curr = locked_current_length();
00151 if ( (start >= curr) && (end >= curr) ) {
00152
00153 REENABLE;
00154 return false;
00155 }
00156 REENABLE;
00157 return true;
00158 }
00159
00160 void wx_debugging_base::select(int start, int end)
00161 {
00162 DISABLE;
00163 _editor.SetSelection(start, end);
00164 REENABLE;
00165 }
00166
00167 int wx_debugging_base::current_length()
00168 {
00169 int to_return = 0;
00170 DISABLE;
00171 to_return = locked_current_length();
00172 REENABLE;
00173 return to_return;
00174 }
00175
00176 int wx_debugging_base::locked_current_length()
00177 {
00178 long old_start, old_end;
00179 _editor.GetSelection(&old_start, &old_end);
00180 _editor.SetSelection(-1, -1);
00181 long new_start, new_end;
00182 _editor.GetSelection(&new_start, &new_end);
00183 _editor.SetSelection(old_start, old_end);
00184 int len = int(new_end - new_start);
00185 _length = len;
00186 return len;
00187 }
00188
00189 void wx_debugging_base::log_ending(const istring &to_show,
00190 int filter, line_ending ending)
00191 {
00192 line_ending temp = eol();
00193 eol(ending);
00194 log(to_show, filter);
00195 eol(temp);
00196 }
00197
00198 outcome wx_debugging_base::log(const istring &to_show_in, int filter)
00199 {
00200 DISABLE;
00201
00202
00203 if (member(filter)) {
00204
00205 if (_the_log) {
00206 line_ending temp = _the_log->eol();
00207 if (eol() == NO_ENDING) _the_log->eol(NO_ENDING);
00208 _the_log->log(to_show_in, ALWAYS_PRINT);
00209 _the_log->eol(temp);
00210 }
00211
00212 wxString to_show = to_unicode_wx(to_show_in);
00213
00214
00215
00216
00217 to_show.Replace(wxstring_crlf, wxstring_lf);
00218
00219
00220 if (eol() != NO_ENDING)
00221 to_show += to_unicode_wx(get_ending());
00222
00223 _editor.Freeze();
00224
00225
00226 long sel_start, sel_end;
00227 _editor.GetSelection(&sel_start, &sel_end);
00228 bool at_end = (sel_start == sel_end) && (sel_end >= _length);
00229
00230
00231 #ifdef DEBUG_DEBUGGING
00232 to_show += istring(istring::SPRINTF, "<%d %d>:len=%d", sel_start,
00233 sel_end, _length);
00234 if (eol() != NO_ENDING) get_ending(to_show);
00235 #endif
00236
00237
00238
00239
00240 while (to_show.length() > 0) {
00241 locked_current_length();
00242 int num_to_show = minimum(512, int(to_show.length()));
00243 wxString chunk_to_show = to_show.Left(num_to_show);
00244 to_show = to_show.Mid(num_to_show);
00245
00246
00247 if (_length + int(chunk_to_show.length()) >= _maximum_active_length) {
00248
00249 locked_current_length();
00250 int old_len = _length;
00251
00252 _editor.Remove(0, LENGTH_CHOP_FACTOR);
00253 locked_current_length();
00254 int difference = old_len - _length;
00255
00256 sel_start -= difference;
00257 sel_end -= difference;
00258 if ( (sel_start < 0) || (sel_end < 0) ) {
00259
00260 sel_start = 0;
00261 sel_end = 0;
00262 }
00263 }
00264 _editor.AppendText(chunk_to_show);
00265
00266 _length += int(chunk_to_show.length());
00267 }
00268
00269
00270
00271 if (at_end) {
00272 sel_start = _length;
00273 sel_end = _length;
00274 }
00275 _editor.Thaw();
00276 _editor.SetSelection(sel_start, sel_end);
00277 }
00278 REENABLE;
00279 return common::OKAY;
00280 }
00281
00282 void wx_debugging_base::go_to_end()
00283 {
00284 DISABLE;
00285
00286 locked_current_length();
00287
00288 _editor.SetSelection(_length, _length);
00289 REENABLE;
00290 }
00291
00292 bool wx_debugging_base::get_contents(istring &to_fill)
00293 {
00294 DISABLE;
00295 to_fill = from_unicode_wx(_editor.GetValue());
00296 REENABLE;
00297 return true;
00298 }
00299
00300 void wx_debugging_base::reset()
00301 {
00302 DISABLE;
00303 _editor.Clear();
00304 locked_current_length();
00305 REENABLE;
00306 }
00307
00308 void wx_debugging_base::display_message(byte_array &message)
00309 {
00310 line_ending ending;
00311 int filter;
00312 istring to_show = debugger::crack_debug_message((void *)&message, ending, filter);
00313 log_ending(to_show, filter, ending);
00314 }
00315
00316 #endif //WX_DEBUGGING_BASE_IMPLEMENTATION_FILE
00317