OpenCores
URL https://opencores.org/ocsvn/w11/w11/trunk

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.61/] [tools/] [src/] [librw11/] [Rw11UnitTerm.cpp] - Blame information for rev 26

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 21 wfjm
// $Id: Rw11UnitTerm.cpp 516 2013-05-05 21:24:52Z mueller $
2 19 wfjm
//
3
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4
//
5
// This program is free software; you may redistribute and/or modify it under
6
// the terms of the GNU General Public License as published by the Free
7
// Software Foundation, either version 2, or at your option any later version.
8
//
9
// This program is distributed in the hope that it will be useful, but
10
// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
11
// or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12
// for complete details.
13
// 
14
// Revision History: 
15
// Date         Rev Version  Comment
16 21 wfjm
// 2013-05-03   515   1.1    use AttachDone(),DetachCleanup(),DetachDone()
17 19 wfjm
// 2013-04-13   504   1.0    Initial version
18
// 2013-02-19   490   0.1    First draft
19
// ---------------------------------------------------------------------------
20
 
21
/*!
22
  \file
23 21 wfjm
  \version $Id: Rw11UnitTerm.cpp 516 2013-05-05 21:24:52Z mueller $
24 19 wfjm
  \brief   Implemenation of Rw11UnitTerm.
25
*/
26
 
27
#include "boost/thread/locks.hpp"
28
#include "boost/bind.hpp"
29
 
30 20 wfjm
#include "librtools/RparseUrl.hpp"
31 19 wfjm
#include "librtools/RosPrintf.hpp"
32 20 wfjm
#include "librtools/Rexception.hpp"
33 19 wfjm
 
34
#include "Rw11UnitTerm.hpp"
35
 
36
using namespace std;
37
 
38
/*!
39
  \class Retro::Rw11UnitTerm
40
  \brief FIXME_docs
41
*/
42
 
43
// all method definitions in namespace Retro
44
namespace Retro {
45
 
46
//------------------------------------------+-----------------------------------
47
//! Constructor
48
 
49
Rw11UnitTerm::Rw11UnitTerm(Rw11Cntl* pcntl, size_t index)
50
  : Rw11UnitVirt<Rw11VirtTerm>(pcntl, index),
51 20 wfjm
    fTo7bit(false),
52
    fToEnpc(false),
53
    fTi7bit(false),
54
    fRcvQueue(),
55
    fLogFname(),
56
    fLogStream(),
57
    fLogOptCrlf(false),
58
    fLogCrPend(false),
59
    fLogLfLast(false)
60
{
61
  fStats.Define(kStatNPreAttDrop,    "NPreAttDrop",
62
                "snd bytes dropped prior attach");
63
}
64 19 wfjm
 
65
//------------------------------------------+-----------------------------------
66
//! Destructor
67
 
68
Rw11UnitTerm::~Rw11UnitTerm()
69
{}
70
 
71
//------------------------------------------+-----------------------------------
72
//! FIXME_docs
73
 
74
const std::string& Rw11UnitTerm::ChannelId() const
75
{
76
  if (fpVirt) return fpVirt->ChannelId();
77
  static string nil;
78
  return nil;
79
}
80
 
81
//------------------------------------------+-----------------------------------
82
//! FIXME_docs
83
 
84 20 wfjm
void Rw11UnitTerm::SetLog(const std::string& fname)
85
{
86
  if (fLogStream.is_open()) {
87
    if (fLogCrPend) fLogStream << "\r";
88
    fLogCrPend = false;
89
    fLogStream.close();
90
  }
91
 
92
  fLogFname.clear();
93
  if (fname.length() == 0) return;
94
 
95
  RparseUrl purl;
96
  RerrMsg emsg;
97 21 wfjm
  if (!purl.Set(fname, "|app|bck=|crlf|", emsg))
98 20 wfjm
    throw Rexception(emsg);
99 21 wfjm
  if (!Rtools::CreateBackupFile(purl, emsg))
100
    throw Rexception(emsg);
101 20 wfjm
 
102
  ios_base::openmode mode = ios_base::out;
103
  if (purl.FindOpt("app")) mode |= ios_base::app;
104
 
105
  fLogStream.open(purl.Path(), mode);
106
  if (!fLogStream.is_open()) {
107
    throw Rexception("Rw11UnitTerm::SetLog",
108
                     string("failed to open '")+purl.Path()+"'");
109
  }
110
 
111
  fLogFname = fname;
112
  fLogOptCrlf = purl.FindOpt("crlf");
113
  fLogCrPend = false;
114
  fLogLfLast = false;
115
 
116
  return;
117
}
118
 
119
//------------------------------------------+-----------------------------------
120
//! FIXME_docs
121
 
122 19 wfjm
bool Rw11UnitTerm::RcvQueueEmpty()
123
{
124
  return fRcvQueue.empty();
125
}
126
 
127
//------------------------------------------+-----------------------------------
128
//! FIXME_docs
129
 
130
size_t Rw11UnitTerm::RcvQueueSize()
131
{
132
  return fRcvQueue.size();
133
}
134
 
135
//------------------------------------------+-----------------------------------
136
//! FIXME_docs
137
 
138
uint8_t Rw11UnitTerm::RcvNext()
139
{
140
  if (RcvQueueEmpty()) return 0;
141
  uint8_t ochr = fRcvQueue.front();
142
  fRcvQueue.pop_front();
143
  return ochr;
144
}
145
 
146
//------------------------------------------+-----------------------------------
147
//! FIXME_docs
148
 
149
size_t Rw11UnitTerm::Rcv(uint8_t* buf, size_t count)
150
{
151
  uint8_t* p = buf;
152
  for (size_t i=0; i<count && !fRcvQueue.empty(); i++) {
153
    *p++ = fRcvQueue.front();
154
    fRcvQueue.pop_front();
155
  }
156
  return p - buf;
157
}
158
 
159
//------------------------------------------+-----------------------------------
160
//! FIXME_docs
161
 
162
bool Rw11UnitTerm::Snd(const uint8_t* buf, size_t count)
163
{
164
  bool ok = true;
165 20 wfjm
  vector<uint8_t> bufmod;
166
  const uint8_t* bufout = buf;
167
  size_t bufcnt = count;
168
 
169
  if (fTo7bit || fToEnpc) {
170
    for (size_t i=0; i<count; i++) {
171
      uint8_t ochr = buf[i];
172
      if (fTo7bit) ochr &= 0177;
173
      if (fToEnpc) {
174
        if ((ochr>=040 && ochr<177) ||
175
             ochr=='\t' || ochr=='\n' || ochr=='\r') {
176
          bufmod.push_back(ochr);
177
        } else {
178
          if (ochr != 0) {
179
            bufmod.push_back('<');
180
            bufmod.push_back('0' + ((ochr>>6)&07) );
181
            bufmod.push_back('0' + ((ochr>>3)&07) );
182
            bufmod.push_back('0' +  (ochr    &07) );
183
            bufmod.push_back('>');
184
          }
185
        }
186
 
187
      } else {
188
        bufmod.push_back(ochr);
189
      }
190
    }
191
    bufout = bufmod.data();
192
    bufcnt = bufmod.size();
193
  }
194
 
195
  if (fLogStream.is_open()) {
196
    for (size_t i=0; i<bufcnt; i++) {
197
      uint8_t ochr = bufout[i];
198
      // the purpose of the 'crlf' filter is to map
199
      //   \r\n   -> \n
200
      //   \r\r\n -> \n  (any number of \r)
201
      //   \n\r   -> \n
202
      //   \n\r\r -> \n  (any number of \r)
203
      // and to ignore \0 chars
204
      if (fLogOptCrlf) {                    // crlf filtering on
205
        if (ochr == 0) continue;              // ignore \0 chars
206
        if (fLogCrPend) {
207
          if (ochr == '\r') continue;         // collapes multiple \r
208
          if (ochr != '\n') fLogStream << '\r'; // log \r if not followed by \n
209
          fLogCrPend = false;
210
        }
211
        if (ochr == '\r') {                   // \r seen 
212
          fLogCrPend = !fLogLfLast;           // remember \r if last wasn't \n 
213
          continue;
214
        }
215
      }
216
      fLogStream << char(ochr);
217
      fLogLfLast = (ochr == '\n');
218
    }
219
  }
220
 
221
  if (fpVirt) {                             // if virtual device attached
222 19 wfjm
    RerrMsg emsg;
223 20 wfjm
    ok = fpVirt->Snd(bufout, bufcnt, emsg);
224 19 wfjm
    // FIXME_code: handler errors
225 20 wfjm
 
226
  } else {                                  // no virtual device attached
227
    if (Name() == "tta0") {                 // is it main console ?
228
      for (size_t i=0; i<bufcnt; i++) {       // than print to stdout 
229
        cout << char(bufout[i]) << flush;
230
      }
231
    } else {                                // otherwise discard
232
      fStats.Inc(kStatNPreAttDrop);         // and count at least...
233
    }
234 19 wfjm
  }
235
  return ok;
236
}
237
 
238
 
239
//------------------------------------------+-----------------------------------
240
//! FIXME_docs
241
 
242
bool Rw11UnitTerm::RcvCallback(const uint8_t* buf, size_t count)
243
{
244
  // lock connect to protect rxqueue
245
  boost::lock_guard<RlinkConnect> lock(Connect());
246
 
247
  bool que_empty_old = fRcvQueue.empty();
248 20 wfjm
  for (size_t i=0; i<count; i++) {
249
    uint8_t ichr = buf[i];
250
    if (fTi7bit) ichr &= 0177;
251
    fRcvQueue.push_back(ichr);
252
  }
253 19 wfjm
  bool que_empty_new = fRcvQueue.empty();
254
  if (que_empty_old && !que_empty_new) WakeupCntl();
255
  return true;
256
}
257
 
258
//------------------------------------------+-----------------------------------
259
//! FIXME_docs
260
 
261
void Rw11UnitTerm::WakeupCntl()
262
{
263
  return;
264
}
265
 
266
//------------------------------------------+-----------------------------------
267
//! FIXME_docs
268
 
269
void Rw11UnitTerm::Dump(std::ostream& os, int ind, const char* text) const
270
{
271
  RosFill bl(ind);
272
  os << bl << (text?text:"--") << "Rw11UnitTerm @ " << this << endl;
273
 
274 20 wfjm
  os << bl << "  fTo7bit:         " << fTo7bit << endl;
275
  os << bl << "  fToEnpc:         " << fToEnpc << endl;
276
  os << bl << "  fTi7bit:         " << fTi7bit << endl;
277 19 wfjm
  {
278
    boost::lock_guard<RlinkConnect> lock(Connect());
279
    size_t size = fRcvQueue.size();
280
    os << bl << "  fRcvQueue.size:  " << fRcvQueue.size() << endl;
281
    if (size > 0) {
282
      os << bl << "  fRcvQueue:       \"";
283
      size_t ocount = 0;
284
      for (size_t i=0; i<size; i++) {
285
        if (ocount >= 50) {
286
          os << "...";
287
          break;
288
        }
289
        uint8_t byt = fRcvQueue[i];
290
        if (byt >= 040 && byt <= 0176) {
291
          os << char(byt);
292
          ocount += 1;
293
        } else {
294
          os << "<" << RosPrintf(byt,"o0",3) << ">";
295
          ocount += 5;
296
        }
297
      }
298
      os << "\"" << endl;
299
    }
300
  }
301
 
302 20 wfjm
  os << bl << "  fLogFname:       " << fLogFname << endl;
303
  os << bl << "  fLogStream.is_open: " << fLogStream.is_open() << endl;
304
  os << bl << "  fLogOptCrlf:     " << fLogOptCrlf << endl;
305
  os << bl << "  fLogCrPend:      " << fLogCrPend << endl;
306
  os << bl << "  fLogLfLast:      " << fLogLfLast << endl;
307
 
308 19 wfjm
  Rw11UnitVirt<Rw11VirtTerm>::Dump(os, ind, " ^");
309
  return;
310
}
311
 
312
//------------------------------------------+-----------------------------------
313
//! FIXME_docs
314
 
315 21 wfjm
void Rw11UnitTerm::AttachDone()
316 19 wfjm
{
317
  fpVirt->SetupRcvCallback(boost::bind(&Rw11UnitTerm::RcvCallback,
318
                                           this, _1, _2));
319
  return;
320
}
321
 
322
 
323
} // end namespace Retro

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.