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

Subversion Repositories w11

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

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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