CPPMyth
Library to interoperate with MythTV server
Loading...
Searching...
No Matches
mythprototransfer.cpp
1/*
2 * Copyright (C) 2014 Jean-Luc Barriere
3 *
4 * This Program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2, or (at your option)
7 * any later version.
8 *
9 * This Program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; see the file COPYING. If not, write to
16 * the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
17 * MA 02110-1301 USA
18 * http://www.gnu.org/copyleft/gpl.html
19 *
20 */
21
22#include "mythprototransfer.h"
23#include "../private/debug.h"
24#include "../private/socket.h"
25#include "../private/os/threads/latch.h"
26#include "../private/builtin.h"
27
28#include <limits>
29#include <cstdio>
30
31using namespace Myth;
32
37
38ProtoTransfer::ProtoTransfer(const std::string& server, unsigned port, const std::string& pathname, const std::string& sgname)
39: ProtoBase(server, port)
40, m_fileSize(0)
41, m_filePosition(0)
42, m_fileRequest(0)
43, m_fileId(0)
44, m_pathName(pathname)
45, m_storageGroupName(sgname)
46{
47}
48
49bool ProtoTransfer::Open()
50{
51 bool ok = false;
52
53 if (IsOpen())
54 return true;
55 if (!OpenConnection(PROTO_TRANSFER_RCVBUF))
56 return false;
57
58 if (m_protoVersion >= 75)
59 ok = Announce75();
60
61 if (!ok)
62 {
63 m_hang = true; // set hang to close without notice
64 Close();
65 return false;
66 }
67 return true;
68}
69
70void ProtoTransfer::Close()
71{
72 OS::WriteLock lock(*m_latch);
73 ProtoBase::Close();
74 // Clean hanging and disable retry
75 m_tainted = m_hang = false;
76 // Reset transfer
78 m_fileId = 0;
79}
80
81void ProtoTransfer::Lock()
82{
83 m_latch->lock();
84}
85
86void ProtoTransfer::Unlock()
87{
88 m_latch->unlock();
89}
90
92{
93 OS::WriteLock lock(*m_latch);
94 int64_t unread = m_fileRequest - m_filePosition;
95 if (unread > 0)
96 {
97 char buf[PROTO_BUFFER_SIZE];
98 size_t n = (size_t)unread;
99 while (n > 0)
100 {
101 size_t s = (n > PROTO_BUFFER_SIZE ? PROTO_BUFFER_SIZE : n);
102 if(m_socket->ReceiveData(buf, s) != s)
103 break;
104 n -= s;
105 }
106 DBG(DBG_DEBUG, "%s: unreaded bytes (%u)\n", __FUNCTION__, (unsigned)n);
107 // Reset position regardless bytes read
109 }
110}
111
112bool ProtoTransfer::Announce75()
113{
114 OS::WriteLock lock(*m_latch);
116 std::string cmd("ANN FileTransfer ");
117 cmd.append(m_socket->GetMyHostName());
118 cmd.append(" 0 0 1000" PROTO_STR_SEPARATOR);
119 cmd.append(m_pathName).append(PROTO_STR_SEPARATOR);
120 cmd.append(m_storageGroupName);
121 if (!SendCommand(cmd.c_str()))
122 return false;
123
124 std::string field;
125 if (!ReadField(field) || !IsMessageOK(field))
126 goto out;
127 if (!ReadField(field) || 0 != string_to_uint32(field.c_str(), &m_fileId))
128 goto out;
129 if (!ReadField(field) || 0 != string_to_int64(field.c_str(), &m_fileSize))
130 goto out;
131 return true;
132
133out:
134 FlushMessage();
135 return false;
136}
137
138uint32_t ProtoTransfer::GetFileId() const
139{
140 return m_fileId;
141}
142
143std::string ProtoTransfer::GetPathName() const
144{
145 return m_pathName;
146}
147
148std::string ProtoTransfer::GetStorageGroupName() const
149{
150 return m_storageGroupName;
151}
152
153int64_t ProtoTransfer::GetSize() const
154{
155 OS::ReadLock lock(*m_latch);
156 return m_fileSize;
157}
158
159int64_t ProtoTransfer::GetPosition() const
160{
161 OS::ReadLock lock(*m_latch);
162 return m_filePosition;
163}
164
165int64_t ProtoTransfer::GetRequested() const
166{
167 OS::ReadLock lock(*m_latch);
168 return m_fileRequest;
169}
170
171int64_t ProtoTransfer::GetRemaining() const
172{
173 OS::ReadLock lock(*m_latch);
174 return (m_fileSize - m_filePosition);
175}
176
177void ProtoTransfer::SetSize(int64_t size)
178{
179 OS::WriteLock lock(*m_latch);
180 m_fileSize = size;
181}
182
183void ProtoTransfer::SetPosition(int64_t position)
184{
185 OS::WriteLock lock(*m_latch);
186 m_filePosition = position;
187}
188
189void ProtoTransfer::SetRequested(int64_t requested)
190{
191 OS::WriteLock lock(*m_latch);
192 m_fileRequest = requested;
193}
bool m_tainted
Connection has hung since last reset.
bool ReadField(std::string &field)
bool m_hang
Connection hang: while true allow retry.
int64_t m_fileRequest
Current requested position.
int64_t m_fileSize
Size of file.
int64_t m_filePosition
Current read position.
void Flush()
Flushing unread data previously requested.
This is the main namespace that encloses all public classes.
Definition mythcontrol.h:30