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