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