Tizen 2.0 Release
[framework/web/wrt-commons.git] / modules / core / src / copy.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        copy.cpp
18  * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
19  * @version     1.0
20  * @brief       This file is the implementation file of copy
21  */
22 #include <stddef.h>
23 #include <dpl/copy.h>
24 #include <dpl/waitable_handle.h>
25 #include <dpl/binary_queue.h>
26
27 namespace DPL
28 {
29 namespace // anonymous
30 {
31 const size_t DEFAULT_COPY_BUFFER_SIZE = 16768;
32 } // namespace anonymous
33
34 void Copy(AbstractWaitableInput *input, AbstractWaitableOutput *output)
35 {
36     Try
37     {
38         while (true)
39         {
40             BinaryQueueAutoPtr buffer;
41
42             while (true)
43             {
44                 // Try to get data immediately
45                 buffer = input->Read(DEFAULT_COPY_BUFFER_SIZE);
46
47                 // Do we need to wait for data ?
48                 if (!buffer.get())
49                 {
50                     WaitForSingleHandle(input->WaitableReadHandle(), WaitMode::Read);
51                     continue;
52                 }
53
54                 if (buffer->Empty())
55                     return; // Done
56
57                 // Ok, to process
58                 break;
59             }
60
61             // Write out all data
62             while (!buffer->Empty())
63             {
64                 // Try to write all data immediately
65                 size_t count = output->Write(*buffer, buffer->Size());
66
67                 // Do we need to wait for writing data ?
68                 if (count == 0)
69                 {
70                     WaitForSingleHandle(output->WaitableWriteHandle(), WaitMode::Write);
71                     continue;
72                 }
73
74                 // Consume data
75                 buffer->Consume(count);
76             }
77         }
78     }
79     Catch (DPL::Exception)
80     {
81         ReThrow(CopyFailed);
82     }
83 }
84
85 void Copy(AbstractWaitableInput *input, AbstractWaitableOutput *output, size_t totalBytes)
86 {
87     Try
88     {
89         size_t bytesLeft = totalBytes;
90
91         while (bytesLeft > 0)
92         {
93             BinaryQueueAutoPtr buffer;
94
95             // Copy at most left bytes
96             size_t bytesToCopy = bytesLeft > DEFAULT_COPY_BUFFER_SIZE ? DEFAULT_COPY_BUFFER_SIZE : bytesLeft;
97
98             while (true)
99             {
100                 // Try to get data immediately
101                 buffer = input->Read(bytesToCopy);
102
103                 // Do we need to wait for data ?
104                 if (!buffer.get())
105                 {
106                     WaitForSingleHandle(input->WaitableReadHandle(), WaitMode::Read);
107                     continue;
108                 }
109
110                 if (buffer->Empty())
111                     ThrowMsg(CopyFailed, "Unexpected end of abstract input");
112
113                 // Ok, to process
114                 break;
115             }
116
117             // Write out all data
118             while (!buffer->Empty())
119             {
120                 // Try to write all data immediately
121                 size_t count = output->Write(*buffer, buffer->Size());
122
123                 // Do we need to wait for writing data ?
124                 if (count == 0)
125                 {
126                     WaitForSingleHandle(output->WaitableWriteHandle(), WaitMode::Write);
127                     continue;
128                 }
129
130                 // Consume data
131                 buffer->Consume(count);
132                 bytesLeft -= count;
133             }
134         }
135     }
136     Catch (DPL::Exception)
137     {
138         ReThrow(CopyFailed);
139     }
140 }
141 } // namespace DPL