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