tizen 2.4 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 namespace // anonymous
29 {
30 const size_t DEFAULT_COPY_BUFFER_SIZE = 16768;
31 } // namespace anonymous
32
33 void Copy(AbstractWaitableInput *input, AbstractWaitableOutput *output)
34 {
35     Try
36     {
37         while (true) {
38             BinaryQueueAutoPtr buffer;
39
40             while (true) {
41                 // Try to get data immediately
42                 buffer = input->Read(DEFAULT_COPY_BUFFER_SIZE);
43
44                 // Do we need to wait for data ?
45                 if (!buffer.get()) {
46                     WaitForSingleHandle(
47                         input->WaitableReadHandle(), WaitMode::Read);
48                     continue;
49                 }
50
51                 if (buffer->Empty()) {
52                     return; // Done
53                 }
54                 // Ok, to process
55                 break;
56             }
57
58             // Write out all data
59             while (!buffer->Empty()) {
60                 // Try to write all data immediately
61                 size_t count = output->Write(*buffer, buffer->Size());
62
63                 // Do we need to wait for writing data ?
64                 if (count == 0) {
65                     WaitForSingleHandle(
66                         output->WaitableWriteHandle(), WaitMode::Write);
67                     continue;
68                 }
69
70                 // Consume data
71                 buffer->Consume(count);
72             }
73         }
74     }
75     Catch(DPL::Exception)
76     {
77         ReThrow(CopyFailed);
78     }
79 }
80
81 void Copy(AbstractWaitableInput *input,
82           AbstractWaitableOutput *output,
83           size_t totalBytes)
84 {
85     Try
86     {
87         size_t bytesLeft = totalBytes;
88
89         while (bytesLeft > 0) {
90             BinaryQueueAutoPtr buffer;
91
92             // Copy at most left bytes
93             size_t bytesToCopy = bytesLeft >
94                 DEFAULT_COPY_BUFFER_SIZE ? DEFAULT_COPY_BUFFER_SIZE : bytesLeft;
95
96             while (true) {
97                 // Try to get data immediately
98                 buffer = input->Read(bytesToCopy);
99
100                 // Do we need to wait for data ?
101                 if (!buffer.get()) {
102                     WaitForSingleHandle(
103                         input->WaitableReadHandle(), WaitMode::Read);
104                     continue;
105                 }
106
107                 if (buffer->Empty()) {
108                     ThrowMsg(CopyFailed, "Unexpected end of abstract input");
109                 }
110
111                 // Ok, to process
112                 break;
113             }
114
115             // Write out all data
116             while (!buffer->Empty()) {
117                 // Try to write all data immediately
118                 size_t count = output->Write(*buffer, buffer->Size());
119
120                 // Do we need to wait for writing data ?
121                 if (count == 0) {
122                     WaitForSingleHandle(
123                         output->WaitableWriteHandle(), WaitMode::Write);
124                     continue;
125                 }
126
127                 // Consume data
128                 buffer->Consume(count);
129                 bytesLeft -= count;
130             }
131         }
132     }
133     Catch(DPL::Exception)
134     {
135         ReThrow(CopyFailed);
136     }
137 }
138 } // namespace DPL