tizen 2.4 release
[framework/web/wrt-commons.git] / modules / core / src / file_input.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 /*
17  * @file        file_input.cpp
18  * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
19  * @version     1.0
20  * @brief       This file is the implementation file of named input pipe
21  */
22 #include <stddef.h>
23 #include <dpl/file_input.h>
24 #include <dpl/binary_queue.h>
25 #include <dpl/log/wrt_log.h>
26 #include <unistd.h>
27 #include <sys/stat.h>
28 #include <fcntl.h>
29 #include <errno.h>
30
31 namespace DPL {
32 namespace // anonymous
33 {
34 const size_t DEFAULT_READ_BUFFER_SIZE = 4096;
35 } // namespace anonymous
36
37 FileInput::FileInput() :
38     m_fd(-1)
39 {}
40
41 FileInput::FileInput(const std::string& fileName) :
42     m_fd(-1)
43 {
44     Open(fileName);
45 }
46
47 FileInput::~FileInput()
48 {
49     Close();
50 }
51
52 void FileInput::Open(const std::string& fileName)
53 {
54     // Open non-blocking
55     int fd = TEMP_FAILURE_RETRY(open(fileName.c_str(), O_RDONLY | O_NONBLOCK));
56
57     // Throw an exception if an error occurred
58     if (fd == -1) {
59         ThrowMsg(Exception::OpenFailed, fileName);
60     }
61
62     // Close if any existing
63     Close();
64
65     // Save new descriptor
66     m_fd = fd;
67
68     WrtLogD("Opened file: %s", fileName.c_str());
69 }
70
71 void FileInput::Close()
72 {
73     if (m_fd == -1) {
74         return;
75     }
76
77     if (TEMP_FAILURE_RETRY(close(m_fd)) == -1) {
78         Throw(Exception::CloseFailed);
79     }
80
81     m_fd = -1;
82
83     WrtLogD("Closed file");
84 }
85
86 BinaryQueueAutoPtr FileInput::Read(size_t size)
87 {
88     size_t bytesToRead = size >
89         DEFAULT_READ_BUFFER_SIZE ? DEFAULT_READ_BUFFER_SIZE : size;
90
91     // Malloc default read buffer size
92     // It is unmanaged, so it can be then attached directly to binary queue
93     void *buffer = malloc(bytesToRead);
94
95     if (buffer == NULL) {
96         throw std::bad_alloc();
97     }
98
99     WrtLogD("Trying to read %u bytes", bytesToRead);
100
101     ssize_t result = TEMP_FAILURE_RETRY(read(m_fd, buffer, bytesToRead));
102
103     WrtLogD("Read %u bytes from file", result);
104
105     if (result > 0) {
106         // Succedded to read socket data
107         BinaryQueueAutoPtr binaryQueue(new BinaryQueue());
108
109         // Append unmanaged memory
110         binaryQueue->AppendUnmanaged(buffer,
111                                      result,
112                                      &BinaryQueue::BufferDeleterFree,
113                                      NULL);
114
115         // Return buffer
116         return binaryQueue;
117     } else if (result == 0) {
118         // Socket was gracefuly closed
119         free(buffer);
120
121         // Return empty buffer
122         return BinaryQueueAutoPtr(new BinaryQueue());
123     } else {
124         // Must first save errno value, because it may be altered
125         int lastErrno = errno;
126
127         // Free buffer
128         free(buffer);
129
130         // Interpret error result
131         (void)lastErrno;
132
133         // FIXME: Handle specific errno
134         Throw(AbstractInput::Exception::ReadFailed);
135     }
136 }
137
138 WaitableHandle FileInput::WaitableReadHandle() const
139 {
140     return static_cast<WaitableHandle>(m_fd);
141 }
142 } // namespace DPL