cb95fa55efa4044d79d0e50a15acded11bd901cb
[framework/web/wrt-plugins-tizen.git] / src / Filesystem / Stream.cpp
1 //
2 // Tizen Web Device API
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18  
19 #include "Stream.h"
20
21 #include <stdio.h>
22 #include <new>
23 #include <dpl/assert.h>
24 #include <dpl/scoped_array.h>
25
26 #include <Commons/Exception.h>
27 #include "Manager.h"
28 #include "Node.h"
29 #include <Logger.h>
30
31 using namespace WrtDeviceApis;
32 using namespace WrtDeviceApis::Commons;
33
34 namespace DeviceAPI {
35 namespace Filesystem {
36 Stream::Stream(const NodePtr& parent,
37         int mode) :
38     m_parent(parent),
39     m_mode(mode)
40 {
41     Assert(m_parent && "Stream needs to have parent.");
42
43     std::ios_base::openmode mode_ = std::ios_base::binary;
44     if (mode & AM_READ) { mode_ |= std::ios_base::in; }
45     if (mode & AM_WRITE) { mode_ |= std::ios_base::out; } 
46     else if (mode & AM_APPEND) {
47         mode_ |= (std::ios_base::app | std::ios_base::out);
48     }
49
50     m_stream.open(m_parent->getPath()->getFullPath().c_str(), mode_);
51     if (!m_stream) {
52         ThrowMsg(Commons::PlatformException, "Could not open stream.");
53     }
54 }
55
56 Stream::~Stream()
57 {
58     close();
59 }
60
61 IStreamPtr Stream::write(bool arg)
62 {
63     return write_(arg);
64 }
65
66 IStreamPtr Stream::write(unsigned char arg)
67 {
68     return write_(arg);
69 }
70
71 IStreamPtr Stream::write(char arg)
72 {
73     return write_(arg);
74 }
75
76 IStreamPtr Stream::write(int arg)
77 {
78     return write_(arg);
79 }
80
81 IStreamPtr Stream::write(double arg)
82 {
83     return write_(arg);
84 }
85
86 IStreamPtr Stream::write(const std::string& arg)
87 {
88     return write_(arg);
89 }
90
91 IStreamPtr Stream::read(bool& arg)
92 {
93     return read_(arg);
94 }
95
96 IStreamPtr Stream::read(unsigned char& arg)
97 {
98     return read_(arg);
99 }
100
101 IStreamPtr Stream::read(char& arg)
102 {
103     return read_(arg);
104 }
105
106 IStreamPtr Stream::read(int& arg)
107 {
108     return read_(arg);
109 }
110
111 IStreamPtr Stream::read(double& arg)
112 {
113     return read_(arg);
114 }
115
116 IStreamPtr Stream::read(std::string& arg)
117 {
118     return read_(arg);
119 }
120
121 void Stream::setCharSet(const std::string &charSet)
122 {
123     m_charSet = charSet;
124 }
125
126 std::string Stream::getCharSet() const
127 {
128     return m_charSet;   
129 }
130
131 char* Stream::getChars(std::size_t num)
132 {
133     checkForReading();
134
135     std::size_t maxChars = num + 1;
136     DPL::ScopedArray<char> result;
137     Try {
138         result.Reset(new char[maxChars]);
139         memset(result.Get(), 0, maxChars);
140
141     }
142     Catch(std::bad_alloc) {
143         ThrowMsg(Commons::PlatformException, "Couldn't allocate output buffer.");
144     }
145 //    if (m_stream.get(result.Get(), maxChars).bad()) {
146     m_stream.read(result.Get(), num);
147
148     if (m_stream.bad()) {
149         ThrowMsg(Commons::PlatformException,
150                  "Error while reading from the stream.");
151     }
152
153     return result.Release();
154 }
155
156 unsigned char* Stream::getBytes(std::size_t num)
157 {
158     checkForReading();
159
160     DPL::ScopedArray<char> buffer;
161     Try {
162         buffer.Reset(new char[num]);
163     }
164     Catch(std::bad_alloc) {
165         ThrowMsg(Commons::PlatformException, "Couldn't allocate output buffer.");
166     }
167     if (m_stream.read(buffer.Get(), num).bad()) {
168         ThrowMsg(Commons::PlatformException,
169                  "Error while reading from the stream.");
170     }
171
172     return static_cast<unsigned char*>(static_cast<void*>(buffer.Release()));
173 }
174
175 std::size_t Stream::getCount() const
176 {
177     if (!isOpen()) {
178         ThrowMsg(Commons::PlatformException, "Stream is closed.");
179     }
180
181     if (!isReadable()) {
182         ThrowMsg(Commons::PlatformException, "Stream is not readable.");
183     }
184
185     return m_stream.gcount();
186 }
187
188 std::string Stream::getLine()
189 {
190     checkForReading();
191
192     std::string result;
193     std::getline(m_stream, result);
194
195     return result;
196 }
197
198 bool Stream::isOpen() const
199 {
200     return m_stream.is_open();
201 }
202
203 bool Stream::isEof() const
204 {
205     return m_stream.eof();
206 }
207
208 void Stream::close()
209 {
210     if (isOpen()) {
211         m_stream.close();
212         m_parent->onStreamClose(SharedFromThis());
213     }
214 }
215
216 int Stream::getMode() const
217 {
218     return m_mode;
219 }
220
221 long Stream::getPosition() const
222 {
223     return static_cast<long>(m_stream.tellg());
224 }
225
226 void Stream::setPosition(long position)
227 {
228     if (m_stream.rdstate() & std::ios_base::eofbit) {
229         m_stream.clear();
230     }
231     if (!(m_stream.seekg(position)) || !(m_stream.seekp(position))) {
232         ThrowMsg(PlatformException, "Could not set position.");
233     }
234 }
235
236 unsigned long long Stream::getSize() const
237 {
238     std::fstream::streampos pos = m_stream.tellg();
239     if (pos == -1) {
240         return -1;
241     }
242
243     if (!m_stream.seekg(0, std::_S_end)) {
244         return -1;
245     }
246
247     unsigned long long result = m_stream.tellg();
248     m_stream.seekg(pos, std::_S_beg);
249
250     return (result == -1 ? result : result + 1);
251 }
252
253 template<typename T>
254 IStreamPtr Stream::write_(T arg)
255 {
256     checkForWriting();
257
258     if (!(m_stream << arg)) {
259         LoggerE("Error while writing to the stream.");
260         ThrowMsg(Commons::PlatformException,
261                  "Error while writing to the stream.");
262     }
263     m_stream.flush();
264
265     return DPL::StaticPointerCast<IStream>(SharedFromThis());
266 }
267
268 template<typename T>
269 IStreamPtr Stream::read_(T& arg)
270 {
271     checkForReading();
272
273     if (!(m_stream >> arg)) {
274         ThrowMsg(Commons::PlatformException,
275                  "Error while reading from the stream.");
276     }
277
278     return DPL::StaticPointerCast<IStream>(SharedFromThis());
279 }
280
281 bool Stream::isReadable() const
282 {
283     return (m_mode & AM_READ);
284 }
285
286 bool Stream::isWriteable() const
287 {
288     return ((m_mode & AM_WRITE) || (m_mode & AM_APPEND));
289 }
290
291 void Stream::checkForReading() const
292 {
293     if (!isOpen()) {
294         ThrowMsg(Commons::PlatformException, "Stream is closed.");
295     }
296
297     if (isEof()) {
298         ThrowMsg(Commons::PlatformException, "Stream is marked as EOF.");
299     }
300
301     if (!isReadable()) {
302         ThrowMsg(Commons::PlatformException, "Stream is not readable.");
303     }
304 }
305
306 void Stream::checkForWriting() const
307 {
308     if (!isOpen()) {
309         LoggerE("Stream is closed.");
310         ThrowMsg(Commons::PlatformException, "Stream is closed.");
311     }
312
313     if (!isWriteable()) {
314         LoggerE("Stream is not writeable.");
315         ThrowMsg(Commons::PlatformException, "Stream is not writeable.");
316     }
317 }
318 } // Filesystem
319 } // TizenApis