1 | // $Id: ColumnStream.cc 2384 2010-12-22 14:03:36Z peter $ |
---|
2 | |
---|
3 | /* |
---|
4 | Copyright (C) 2007, 2008 Jari Häkkinen, Peter Johansson |
---|
5 | Copyright (C) 2010 Peter Johansson |
---|
6 | |
---|
7 | This file is part of yat, http://dev.thep.lu.se/yat |
---|
8 | |
---|
9 | yat is free software; you can redistribute it and/or modify it |
---|
10 | under the terms of the GNU General Public License as published by |
---|
11 | the Free Software Foundation; either version 3 of the License, or |
---|
12 | (at your option) any later version. |
---|
13 | |
---|
14 | yat is distributed in the hope that it will be useful, but |
---|
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
---|
17 | General Public License for more details. |
---|
18 | |
---|
19 | You should have received a copy of the GNU General Public License |
---|
20 | along with yat. If not, see <http://www.gnu.org/licenses/>. |
---|
21 | */ |
---|
22 | |
---|
23 | #include "ColumnStream.h" |
---|
24 | |
---|
25 | #include <cassert> |
---|
26 | #include <iostream> |
---|
27 | |
---|
28 | namespace theplu{ |
---|
29 | namespace yat{ |
---|
30 | namespace utility{ |
---|
31 | |
---|
32 | ColumnStream::ColumnStream(std::ostream& os, size_t columns) |
---|
33 | : activated_(0),os_(os) |
---|
34 | { |
---|
35 | margins_=std::vector<size_t>(columns); |
---|
36 | buffer_.reserve(columns); |
---|
37 | while (buffer_.size()<columns) |
---|
38 | buffer_.push_back(new std::stringstream); |
---|
39 | width_=std::vector<size_t>(columns, 8); |
---|
40 | } |
---|
41 | |
---|
42 | |
---|
43 | ColumnStream::~ColumnStream(void) |
---|
44 | { |
---|
45 | for (size_t i=0; i<buffer_.size(); ++i) |
---|
46 | delete buffer_[i]; |
---|
47 | } |
---|
48 | |
---|
49 | |
---|
50 | void ColumnStream::fill(size_t column, size_t count) |
---|
51 | { |
---|
52 | while(count<width_[column]){ |
---|
53 | os_ << ' '; |
---|
54 | ++count; |
---|
55 | } |
---|
56 | } |
---|
57 | |
---|
58 | |
---|
59 | void ColumnStream::flush(void) |
---|
60 | { |
---|
61 | bool empty=false; |
---|
62 | while(!empty) { |
---|
63 | empty=true; |
---|
64 | for (size_t i=0; i<columns(); ++i){ |
---|
65 | if (writeline(i)) |
---|
66 | empty=false; |
---|
67 | } |
---|
68 | os_ << '\n'; |
---|
69 | } |
---|
70 | for (size_t i=0; i<columns(); ++i) |
---|
71 | buffer_[i]->clear(std::ios::goodbit); |
---|
72 | } |
---|
73 | |
---|
74 | |
---|
75 | size_t& ColumnStream::margin(size_t c) |
---|
76 | { |
---|
77 | return margins_[c]; |
---|
78 | } |
---|
79 | |
---|
80 | |
---|
81 | void ColumnStream::next_column(void) |
---|
82 | { |
---|
83 | ++activated_; |
---|
84 | if (activated_>=columns()) { |
---|
85 | flush(); |
---|
86 | } |
---|
87 | } |
---|
88 | |
---|
89 | void ColumnStream::print(std::stringstream& ss) |
---|
90 | { |
---|
91 | assert(buffer_[activated_]); |
---|
92 | assert(activated_<buffer_.size()); |
---|
93 | char c; |
---|
94 | ss.get(c); |
---|
95 | while(ss.good()) { |
---|
96 | if (c=='\t'){ |
---|
97 | //*(buffer_[activated_]) << ' '; |
---|
98 | next_column(); |
---|
99 | } |
---|
100 | else if (c=='\n'){ |
---|
101 | //*(buffer_[activated_]) << ' '; |
---|
102 | flush(); |
---|
103 | activated_=0; |
---|
104 | } |
---|
105 | else |
---|
106 | *(buffer_[activated_]) << c; |
---|
107 | ss.get(c); |
---|
108 | } |
---|
109 | } |
---|
110 | |
---|
111 | |
---|
112 | size_t& ColumnStream::width(size_t c) |
---|
113 | { |
---|
114 | return width_[c]; |
---|
115 | } |
---|
116 | |
---|
117 | |
---|
118 | bool ColumnStream::writeline(size_t column) |
---|
119 | { |
---|
120 | assert(column<columns()); |
---|
121 | for (size_t i=0; i<margins_[column]; ++i) |
---|
122 | os_ << ' '; |
---|
123 | size_t count=0; |
---|
124 | std::string word; |
---|
125 | char c; |
---|
126 | while (buffer_[column]->good()) { |
---|
127 | buffer_[column]->get(c); |
---|
128 | assert(c!='\t'); |
---|
129 | assert(c!='\n'); |
---|
130 | if (buffer_[column]->good()) |
---|
131 | word += c; |
---|
132 | if (c==' ' || !buffer_[column]->good()) { |
---|
133 | if (count+word.size()<=width_[column]) { |
---|
134 | os_ << word; |
---|
135 | count += word.size(); |
---|
136 | word = ""; |
---|
137 | } |
---|
138 | else { |
---|
139 | if (!buffer_[column]->good()) |
---|
140 | buffer_[column]->clear(std::ios::goodbit); |
---|
141 | |
---|
142 | // if line is empty and word is longer than column width, we |
---|
143 | // have to split the word |
---|
144 | if (!count) { |
---|
145 | os_ << word.substr(0,width_[column]); |
---|
146 | for (std::string::reverse_iterator i=word.rbegin(); |
---|
147 | i!=word.rbegin()+(word.size()-width_[column]); ++i) |
---|
148 | buffer_[column]->putback(*i); |
---|
149 | } |
---|
150 | else { |
---|
151 | for (std::string::reverse_iterator i=word.rbegin(); |
---|
152 | i!=word.rend(); ++i) |
---|
153 | buffer_[column]->putback(*i); |
---|
154 | fill(column, count); |
---|
155 | } |
---|
156 | return true; |
---|
157 | } |
---|
158 | } |
---|
159 | |
---|
160 | } |
---|
161 | fill(column, count); |
---|
162 | return false; |
---|
163 | } |
---|
164 | |
---|
165 | |
---|
166 | }}} // end of namespace utility, yat, and theplu |
---|