summaryrefslogtreecommitdiff
path: root/common/lines.hh
blob: d3bfc75998f0eda55422991531248eb161f55b4f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#ifndef __COMMON_LINES_HH__
#define __COMMON_LINES_HH__

#include "lout/object.hh"
#include "lout/container.hh"

namespace rtfl {

namespace tools {

class LinesSource;

class LinesSink: public lout::object::Object
{
public:
   virtual void setLinesSource (LinesSource *source) = 0;
   virtual void processLine (char *line) = 0;
   virtual void timeout (int type) = 0;
   virtual void finish () = 0;
};

   
class LinesSource: public lout::object::Object
{
public:
   virtual void setup (LinesSink *sink) = 0;
   virtual void addTimeout (double secs, int type) = 0;
   virtual void removeTimeout (int type) = 0;
};


class LinesSourceSequence: public LinesSource
{
private:
   class VirtualSink: public LinesSink
   {
   public:
      LinesSourceSequence *sequence;

      VirtualSink ();
      void setLinesSource (LinesSource *source);
      void processLine (char *line);
      void timeout (int type);
      void finish ();
   };

   VirtualSink virtualSink;
   LinesSink *sink;
   lout::container::typed::List<LinesSource> *sources;
   bool setupCalled;
   lout::container::typed::Iterator<LinesSource> iterator;

public:
   LinesSourceSequence (bool ownerOfSources);
   ~LinesSourceSequence ();
   void add (LinesSource *source);
   void setup (LinesSink *sink);
   void addTimeout (double secs, int type);
   void removeTimeout (int type);
};


class FileLinesSource: public LinesSource
{
private:
   enum { MAX_LINE_SIZE = 1000 };

   tools::LinesSink *sink;
   char buf[MAX_LINE_SIZE + 1];
   int bufPos;
   bool completeLine;

protected:
   FileLinesSource ();
   
   int processInput (int fd);
   inline void setSink (LinesSink *sink) {
      this->sink = sink; sink->setLinesSource (this); }      
   inline LinesSink *getSink () { return sink; }
};


class BlockingLinesSource: public FileLinesSource
{
private:
   class TimeoutInfo: public lout::object::Object
   {
   private:
      long time;
      int type;

   public:
      TimeoutInfo (long time, int type);
      bool equals(Object *other);
      int hashValue();

      inline long getTime () { return time; }
      inline int getType () { return type; }
   };
   
   int fd;
   lout::container::typed::HashSet<TimeoutInfo> *timeoutInfos;

   long getCurrentTime ();
   TimeoutInfo *getNextTimeoutInfo ();
   void processTimeouts ();

public:
   BlockingLinesSource (int fd);
   ~BlockingLinesSource ();
   void setup (LinesSink *sink);
   void addTimeout (double secs, int type);
   void removeTimeout (int type);
};


} // namespace tools

} // namespace rtfl

#endif // __COMMON_LINES_HH__