Initialize Tizen 2.3
[framework/web/wrt-plugins-common.git] / src_wearable / 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 using namespace Api;
28
29 Stream::Stream(const NodePtr& parent,
30                int mode) :
31     m_parent(parent),
32     m_mode(mode)
33 {
34     AssertMsg(m_parent, "Stream needs to have parent.");
35
36     std::ios_base::openmode mode_ = std::ios_base::binary;
37     if (mode & AM_READ) {
38         mode_ |= std::ios_base::in;
39     }
40     if (mode & AM_WRITE) {
41         mode_ |= std::ios_base::out;
42     } else if (mode &
43                AM_APPEND)
44     {
45         mode_ |= (std::ios_base::app | std::ios_base::out);
46     }
47
48     m_stream.open(m_parent->getPath()->getFullPath().c_str(), mode_);
49     if (!m_stream) {
50         ThrowMsg(Commons::PlatformException, "Could not open stream.");
51     }
52 }
53
54 Stream::~Stream()
55 {
56     close();
57 }
58
59 IStreamPtr Stream::write(bool arg)
60 {
61     return write_(arg);
62 }
63
64 IStreamPtr Stream::write(unsigned char arg)
65 {
66     return write_(arg);
67 }
68
69 IStreamPtr Stream::write(char arg)
70 {
71     return write_(arg);
72 }
73
74 IStreamPtr Stream::write(int arg)
75 {
76     return write_(arg);
77 }
78
79 IStreamPtr Stream::write(double arg)
80 {
81     return write_(arg);
82 }
83
84 IStreamPtr Stream::write(const std::string& arg)
85 {
86     return write_(arg);
87 }
88
89 IStreamPtr Stream::read(bool& arg)
90 {
91     return read_(arg);
92 }
93
94 IStreamPtr Stream::read(unsigned char& arg)
95 {
96     return read_(arg);
97 }
98
99 IStreamPtr Stream::read(char& arg)
100 {
101     return read_(arg);
102 }
103
104 IStreamPtr Stream::read(int& arg)
105 {
106     return read_(arg);
107 }
108
109 IStreamPtr Stream::read(double& arg)
110 {
111     return read_(arg);
112 }
113
114 IStreamPtr Stream::read(std::string& arg)
115 {
116     return read_(arg);
117 }
118
119 char* Stream::getChars(std::size_t num)
120 {
121     checkForReading();
122
123     std::size_t maxChars = num + 1;
124     DPL::ScopedArray<char> result;
125     Try {
126         result.Reset(new char[maxChars]);
127     }
128     Catch(std::bad_alloc) {
129         ThrowMsg(Commons::PlatformException, "Couldn't allocate output buffer.");
130     }
131     if (m_stream.get(result.Get(), maxChars).bad()) {
132         ThrowMsg(Commons::PlatformException,
133                  "Error while reading from the stream.");
134     }
135
136     return result.Release();
137 }
138
139 unsigned char* Stream::getBytes(std::size_t num)
140 {
141     checkForReading();
142
143     DPL::ScopedArray<char> buffer;
144     Try {
145         buffer.Reset(new char[num]);
146     }
147     Catch(std::bad_alloc) {
148         ThrowMsg(Commons::PlatformException, "Couldn't allocate output buffer.");
149     }
150     if (m_stream.read(buffer.Get(), num).bad()) {
151         ThrowMsg(Commons::PlatformException,
152                  "Error while reading from the stream.");
153     }
154
155     return static_cast<unsigned char*>(static_cast<void*>(buffer.Release()));
156 }
157
158 std::size_t Stream::getCount() const
159 {
160     if (!isOpen()) {
161         ThrowMsg(Commons::PlatformException, "Stream is closed.");
162     }
163
164     if (!isReadable()) {
165         ThrowMsg(Commons::PlatformException, "Stream is not readable.");
166     }
167
168     return m_stream.gcount();
169 }
170
171 std::string Stream::getLine()
172 {
173     checkForReading();
174
175     std::string result;
176     std::getline(m_stream, result);
177
178     return result;
179 }
180
181 bool Stream::isOpen() const
182 {
183     return m_stream.is_open();
184 }
185
186 bool Stream::isEof() const
187 {
188     return m_stream.eof();
189 }
190
191 void Stream::close()
192 {
193     if (isOpen()) {
194         m_stream.close();
195         m_parent->onStreamClose(SharedFromThis());
196     }
197 }
198
199 int Stream::getMode() const
200 {
201     return m_mode;
202 }
203
204 long Stream::getPosition() const
205 {
206     return static_cast<long>(m_stream.tellg());
207 }
208
209 void Stream::setPosition(long position)
210 {
211     if (m_stream.rdstate() & std::ios_base::eofbit) {
212         m_stream.clear();
213     }
214     if (!(m_stream.seekg(position)) || !(m_stream.seekp(position))) {
215         ThrowMsg(Commons::PlatformException, "Could not set position.");
216     }
217 }
218
219 long Stream::getSize() const
220 {
221     std::fstream::streampos pos = m_stream.tellg();
222     if (pos == -1) {
223         return -1;
224     }
225
226     if (!m_stream.seekg(0, std::_S_end)) {
227         return -1;
228     }
229
230     long result = m_stream.tellg();
231     m_stream.seekg(pos, std::_S_beg);
232
233     return (result == -1 ? result : result + 1);
234 }
235
236 template<typename T>
237 IStreamPtr Stream::write_(T arg)
238 {
239     checkForWriting();
240
241     if (!(m_stream << arg)) {
242         LogError("Error while writing to the stream.");
243         ThrowMsg(Commons::PlatformException,
244                  "Error while writing to the stream.");
245     }
246     m_stream.flush();
247
248     return DPL::StaticPointerCast<IStream>(SharedFromThis());
249 }
250
251 template<typename T>
252 IStreamPtr Stream::read_(T& arg)
253 {
254     checkForReading();
255
256     if (!(m_stream >> arg)) {
257         ThrowMsg(Commons::PlatformException,
258                  "Error while reading from the stream.");
259     }
260
261     return DPL::StaticPointerCast<IStream>(SharedFromThis());
262 }
263
264 bool Stream::isReadable() const
265 {
266     return (m_mode & AM_READ);
267 }
268
269 bool Stream::isWriteable() const
270 {
271     return ((m_mode & AM_WRITE) || (m_mode & AM_APPEND));
272 }
273
274 void Stream::checkForReading() const
275 {
276     if (!isOpen()) {
277         ThrowMsg(Commons::PlatformException, "Stream is closed.");
278     }
279
280     if (isEof()) {
281         ThrowMsg(Commons::PlatformException, "Stream is marked as EOF.");
282     }
283
284     if (!isReadable()) {
285         ThrowMsg(Commons::PlatformException, "Stream is not readable.");
286     }
287 }
288
289 void Stream::checkForWriting() const
290 {
291     if (!isOpen()) {
292         LogError("Stream is closed.");
293         ThrowMsg(Commons::PlatformException, "Stream is closed.");
294     }
295
296     if (!isWriteable()) {
297         LogError("Stream is not writeable.");
298         ThrowMsg(Commons::PlatformException, "Stream is not writeable.");
299     }
300 }
301 } // Filesystem
302 } // WrtDeviceApis