XRootD
Loading...
Searching...
No Matches
XrdClXRootDResponses.cc
Go to the documentation of this file.
1//------------------------------------------------------------------------------
2// Copyright (c) 2011-2012 by European Organization for Nuclear Research (CERN)
3// Author: Lukasz Janyst <ljanyst@cern.ch>
4//------------------------------------------------------------------------------
5// XRootD is free software: you can redistribute it and/or modify
6// it under the terms of the GNU Lesser General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// XRootD is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU Lesser General Public License
16// along with XRootD. If not, see <http://www.gnu.org/licenses/>.
17//------------------------------------------------------------------------------
18
20#include "XrdCl/XrdClLog.hh"
23#include "XrdCl/XrdClUtils.hh"
24#include <cstdlib>
25
26namespace XrdCl
27{
28 //----------------------------------------------------------------------------
29 // LocationInfo constructor
30 //----------------------------------------------------------------------------
34
35 //----------------------------------------------------------------------------
36 // Parse the server location response
37 //----------------------------------------------------------------------------
38 bool LocationInfo::ParseServerResponse( const char *data )
39 {
40 if( !data || strlen( data ) == 0 )
41 return false;
42
43 std::vector<std::string> locations;
44 std::vector<std::string>::iterator it;
45 Utils::splitString( locations, data, " " );
46 for( it = locations.begin(); it != locations.end(); ++it )
47 if( ProcessLocation( *it ) == false )
48 return false;
49 return true;
50 }
51
52 //----------------------------------------------------------------------------
53 // Process location
54 //----------------------------------------------------------------------------
55 bool LocationInfo::ProcessLocation( std::string &location )
56 {
57 if( location.length() < 5 )
58 return false;
59
60 //--------------------------------------------------------------------------
61 // Decode location type
62 //--------------------------------------------------------------------------
64 switch( location[0] )
65 {
66 case 'M':
68 break;
69 case 'm':
71 break;
72 case 'S':
74 break;
75 case 's':
77 break;
78 default:
79 return false;
80 }
81
82 //--------------------------------------------------------------------------
83 // Decode access type
84 //--------------------------------------------------------------------------
86 switch( location[1] )
87 {
88 case 'r':
90 break;
91 case 'w':
93 break;
94 default:
95 return false;
96 }
97
98 //--------------------------------------------------------------------------
99 // Push the location info
100 //--------------------------------------------------------------------------
101 pLocations.push_back( Location( location.substr(2), type, access ) );
102
103 return true;
104 }
105
106 //----------------------------------------------------------------------------
107 // StatInfo implementation
108 //----------------------------------------------------------------------------
110 {
111 StatInfoImpl() : pSize( 0 ), pFlags( 0 ), pModifyTime( 0 ),
112 pChangeTime( 0 ), pAccessTime( 0 ),
113 pExtended( false ), pHasCksum( false )
114 {
115 }
116
117 StatInfoImpl( const StatInfoImpl & pimpl ) : pId( pimpl.pId ),
118 pSize( pimpl.pSize ),
119 pFlags( pimpl.pFlags ),
120 pModifyTime( pimpl.pModifyTime ),
121 pChangeTime( pimpl.pChangeTime ),
122 pAccessTime( pimpl.pAccessTime ),
123 pMode( pimpl.pMode ),
124 pOwner( pimpl.pOwner ),
125 pGroup( pimpl.pGroup ),
126 pExtended( pimpl.pExtended ),
127 pHasCksum( pimpl.pHasCksum )
128 {
129 }
130
131 //------------------------------------------------------------------------
132 // Parse the stat info returned by the server
133 //------------------------------------------------------------------------
134 bool ParseServerResponse( const char *data )
135 {
136 if( !data || strlen( data ) == 0 )
137 return false;
138
139 std::vector<std::string> chunks;
140 Utils::splitString( chunks, data, " " );
141
142 if( chunks.size() < 4 )
143 return false;
144
145 pId = chunks[0];
146
147 char *result;
148 pSize = ::strtoll( chunks[1].c_str(), &result, 0 );
149 if( *result != 0 )
150 {
151 pSize = 0;
152 return false;
153 }
154
155 pFlags = ::strtol( chunks[2].c_str(), &result, 0 );
156 if( *result != 0 )
157 {
158 pFlags = 0;
159 return false;
160 }
161
162 pModifyTime = ::strtoll( chunks[3].c_str(), &result, 0 );
163 if( *result != 0 )
164 {
165 pModifyTime = 0;
166 return false;
167 }
168
169 if( chunks.size() >= 9 )
170 {
171 pChangeTime = ::strtoll( chunks[4].c_str(), &result, 0 );
172 if( *result != 0 )
173 {
174 pChangeTime = 0;
175 return false;
176 }
177
178 pAccessTime = ::strtoll( chunks[5].c_str(), &result, 0 );
179 if( *result != 0 )
180 {
181 pAccessTime = 0;
182 return false;
183 }
184
185 // we are expecting at least 4 characters, e.g.: 0644
186 if( chunks[6].size() < 4 ) return false;
187 pMode = chunks[6];
188
189 pOwner = chunks[7];
190 pGroup = chunks[8];
191
192 pExtended = true;
193 }
194
195 // after the extended stat information, we might have the checksum
196 if( chunks.size() >= 10 )
197 {
198 if( ( chunks[9] == "[" ) && ( chunks[11] == "]" ) )
199 {
200 pHasCksum = true;
201 pCksum = chunks[10];
202 }
203 }
204
205 return true;
206 }
207
208 std::string pId;
209 uint64_t pSize;
210 uint32_t pFlags;
211 uint64_t pModifyTime;
212 uint64_t pChangeTime;
213 uint64_t pAccessTime;
214 std::string pMode;
215 std::string pOwner;
216 std::string pGroup;
217
220 std::string pCksum;
221 };
222
223 //----------------------------------------------------------------------------
224 // StatInfo constructor
225 //----------------------------------------------------------------------------
227 {
228 }
229
230 //------------------------------------------------------------------------
231 // Constructor
232 //------------------------------------------------------------------------
233 StatInfo::StatInfo( const std::string &id, uint64_t size, uint32_t flags,
234 uint64_t modTime ) : pImpl( new StatInfoImpl() )
235
236 {
237 pImpl->pId = id;
238 pImpl->pSize = size;
239 pImpl->pFlags = flags;
240 pImpl->pModifyTime = modTime;
241 }
242
243 //------------------------------------------------------------------------
244 // Copy constructor
245 //------------------------------------------------------------------------
246 StatInfo::StatInfo( const StatInfo &info ) : pImpl( new StatInfoImpl( *info.pImpl) )
247 {
248 }
249
250 //------------------------------------------------------------------------
251 // Destructor (it can be only defined after StatInfoImpl is defined!!!)
252 //------------------------------------------------------------------------
253 StatInfo::~StatInfo() = default;
254
255 //----------------------------------------------------------------------------
256 // Parse the stat info returned by the server
257 //----------------------------------------------------------------------------
258 bool StatInfo::ParseServerResponse( const char *data )
259 {
260 return pImpl->ParseServerResponse( data );
261 }
262
263 //------------------------------------------------------------------------
265 //------------------------------------------------------------------------
266 const std::string& StatInfo::GetId() const
267 {
268 return pImpl->pId;
269 }
270
271 //------------------------------------------------------------------------
273 //------------------------------------------------------------------------
274 uint64_t StatInfo::GetSize() const
275 {
276 return pImpl->pSize;
277 }
278
279 //------------------------------------------------------------------------
281 //------------------------------------------------------------------------
282 void StatInfo::SetSize( uint64_t size )
283 {
284 pImpl->pSize = size;
285 }
286
287 //------------------------------------------------------------------------
289 //------------------------------------------------------------------------
290 uint32_t StatInfo::GetFlags() const
291 {
292 return pImpl->pFlags;
293 }
294
295 //------------------------------------------------------------------------
297 //------------------------------------------------------------------------
298 void StatInfo::SetFlags( uint32_t flags )
299 {
300 pImpl->pFlags = flags;
301 }
302
303 //------------------------------------------------------------------------
305 //------------------------------------------------------------------------
306 bool StatInfo::TestFlags( uint32_t flags ) const
307 {
308 return pImpl->pFlags & flags;
309 }
310
311 //------------------------------------------------------------------------
313 //------------------------------------------------------------------------
314 uint64_t StatInfo::GetModTime() const
315 {
316 return pImpl->pModifyTime;
317 }
318
319 //------------------------------------------------------------------------
321 //------------------------------------------------------------------------
323 {
324 return TimeToString( pImpl->pModifyTime );
325 }
326
327 //------------------------------------------------------------------------
329 //------------------------------------------------------------------------
330 uint64_t StatInfo::GetChangeTime() const
331 {
332 return pImpl->pChangeTime;
333 }
334
335 //------------------------------------------------------------------------
337 //------------------------------------------------------------------------
339 {
340 return TimeToString( pImpl->pChangeTime );
341 }
342
343 //------------------------------------------------------------------------
345 //------------------------------------------------------------------------
346 uint64_t StatInfo::GetAccessTime() const
347 {
348 return pImpl->pAccessTime;
349 }
350
351 //------------------------------------------------------------------------
353 //------------------------------------------------------------------------
355 {
356 return TimeToString( pImpl->pAccessTime );
357 }
358
359 //------------------------------------------------------------------------
361 //------------------------------------------------------------------------
362 const std::string& StatInfo::GetModeAsString() const
363 {
364 return pImpl->pMode;
365 }
366
367 //------------------------------------------------------------------------
369 //------------------------------------------------------------------------
370 const std::string StatInfo::GetModeAsOctString() const
371 {
372 std::string ret;
373 ret.reserve( 9 );
374
375 // we care about 3 last digits
376 size_t size = pImpl->pMode.size();
377
378 uint8_t oct = pImpl->pMode[size - 3] - '0';
379 OctToString( oct, ret );
380
381 oct = pImpl->pMode[size - 2] - '0';
382 OctToString( oct, ret );
383
384 oct = pImpl->pMode[size - 1] - '0';
385 OctToString( oct, ret );
386
387 return ret;
388 }
389
390 //------------------------------------------------------------------------
392 //------------------------------------------------------------------------
393 const std::string& StatInfo::GetOwner() const
394 {
395 return pImpl->pOwner;
396 }
397
398 //------------------------------------------------------------------------
400 //------------------------------------------------------------------------
401 const std::string& StatInfo::GetGroup() const
402 {
403 return pImpl->pGroup;
404 }
405
406 //------------------------------------------------------------------------
408 //------------------------------------------------------------------------
409 const std::string& StatInfo::GetChecksum() const
410 {
411 return pImpl->pCksum;
412 }
413
414 //------------------------------------------------------------------------
416 //------------------------------------------------------------------------
418 {
419 return pImpl->pExtended;
420 }
421
422 //------------------------------------------------------------------------
424 //------------------------------------------------------------------------
426 {
427 return pImpl->pHasCksum;
428 }
429
430 //----------------------------------------------------------------------------
431 // StatInfo constructor
432 //----------------------------------------------------------------------------
434 pNodesRW( 0 ),
435 pFreeRW( 0 ),
436 pUtilizationRW( 0 ),
437 pNodesStaging( 0 ),
438 pFreeStaging( 0 ),
439 pUtilizationStaging( 0 )
440 {
441 }
442
443 //----------------------------------------------------------------------------
444 // Parse the stat info returned by the server
445 //----------------------------------------------------------------------------
446 bool StatInfoVFS::ParseServerResponse( const char *data )
447 {
448 if( !data || strlen( data ) == 0 )
449 return false;
450
451 std::vector<std::string> chunks;
452 Utils::splitString( chunks, data, " " );
453
454 if( chunks.size() < 6 )
455 return false;
456
457 char *result;
458 pNodesRW = ::strtoll( chunks[0].c_str(), &result, 0 );
459 if( *result != 0 )
460 {
461 pNodesRW = 0;
462 return false;
463 }
464
465 pFreeRW = ::strtoll( chunks[1].c_str(), &result, 0 );
466 if( *result != 0 )
467 {
468 pFreeRW = 0;
469 return false;
470 }
471
472 pUtilizationRW = ::strtol( chunks[2].c_str(), &result, 0 );
473 if( *result != 0 )
474 {
475 pUtilizationRW = 0;
476 return false;
477 }
478
479 pNodesStaging = ::strtoll( chunks[3].c_str(), &result, 0 );
480 if( *result != 0 )
481 {
482 pNodesStaging = 0;
483 return false;
484 }
485
486 pFreeStaging = ::strtoll( chunks[4].c_str(), &result, 0 );
487 if( *result != 0 )
488 {
489 pFreeStaging = 0;
490 return false;
491 }
492
493 pUtilizationStaging = ::strtol( chunks[5].c_str(), &result, 0 );
494 if( *result != 0 )
495 {
496 pUtilizationStaging = 0;
497 return false;
498 }
499
500 return true;
501 }
502
503 const std::string DirectoryList::dStatPrefix = ".\n0 0 0 0";
504
505 //----------------------------------------------------------------------------
506 // DirectoryList constructor
507 //----------------------------------------------------------------------------
511
512 //----------------------------------------------------------------------------
513 // Destructor
514 //----------------------------------------------------------------------------
516 {
517 for( Iterator it = pDirList.begin(); it != pDirList.end(); ++it )
518 delete *it;
519 }
520
521 //----------------------------------------------------------------------------
522 // Parse the directory list
523 //----------------------------------------------------------------------------
524 bool DirectoryList::ParseServerResponse( const std::string &hostId,
525 const char *data )
526 {
527 if( !data )
528 return false;
529
530 //--------------------------------------------------------------------------
531 // Check what kind of response we're dealing with
532 //--------------------------------------------------------------------------
533 bool isDStat = HasStatInfo( data );
534 if( isDStat )
535 data += dStatPrefix.size();
536 return ParseServerResponse( hostId, data, isDStat );
537 }
538
539 //------------------------------------------------------------------------
541 //------------------------------------------------------------------------
542 bool DirectoryList::ParseServerResponse( const std::string &hostId,
543 const char *data,
544 bool isDStat )
545 {
546 if( !data )
547 return false;
548
549 std::string dat = data;
550 std::vector<std::string> entries;
551 std::vector<std::string>::iterator it;
552 Utils::splitString( entries, dat, "\n" );
553
554 //--------------------------------------------------------------------------
555 // Normal response
556 //--------------------------------------------------------------------------
557 if( !isDStat )
558 {
559 for( it = entries.begin(); it != entries.end(); ++it )
560 Add( new ListEntry( hostId, *it ) );
561 return true;
562 }
563
564 //--------------------------------------------------------------------------
565 // kXR_dstat
566 //--------------------------------------------------------------------------
567 if( entries.size() % 2 )
568 return false;
569
570 it = entries.begin(); //++it; ++it;
571 for( ; it != entries.end(); ++it )
572 {
573 ListEntry *entry = new ListEntry( hostId, *it );
574 Add( entry );
575 ++it;
576 StatInfo *i = new StatInfo();
577 entry->SetStatInfo( i );
578 bool ok = i->ParseServerResponse( it->c_str() );
579 if( !ok )
580 return false;
581 }
582 return true;
583 }
584
585 //------------------------------------------------------------------------
586 // Returns true if data contain stat info
587 //------------------------------------------------------------------------
588 bool DirectoryList::HasStatInfo( const char *data )
589 {
590 std::string dat = data;
591 return !dat.compare( 0, dStatPrefix.size(), dStatPrefix );
592 }
593
595 {
596 PageInfoImpl( uint64_t offset = 0, uint32_t length = 0, void *buffer = 0,
597 std::vector<uint32_t> &&cksums = std::vector<uint32_t>() ) :
598 offset( offset ),
599 length( length ),
600 buffer( buffer ),
601 cksums( std::move( cksums ) ),
602 nbrepair( 0 )
603 {
604 }
605
606 PageInfoImpl( PageInfoImpl &&pginf ) : offset( pginf.offset ),
607 length( pginf.length ),
608 buffer( pginf.buffer ),
609 cksums( std::move( pginf.cksums ) ),
610 nbrepair( pginf.nbrepair )
611 {
612 }
613
614 uint64_t offset; //> offset in the file
615 uint32_t length; //> length of the data read
616 void *buffer; //> buffer with the read data
617 std::vector<uint32_t> cksums; //> a vector of crc32c checksums
618 size_t nbrepair; //> number of repaired pages
619 };
620
621 //----------------------------------------------------------------------------
622 // Default constructor
623 //----------------------------------------------------------------------------
624 PageInfo::PageInfo( uint64_t offset, uint32_t length, void *buffer,
625 std::vector<uint32_t> &&cksums ) :
626 pImpl( new PageInfoImpl( offset, length, buffer, std::move( cksums ) ) )
627 {
628 }
629
630 //----------------------------------------------------------------------------
631 // Move constructor
632 //----------------------------------------------------------------------------
633 PageInfo::PageInfo( PageInfo &&pginf ) : pImpl( std::move( pginf.pImpl ) )
634 {
635 }
636
637 //----------------------------------------------------------------------------
639 //----------------------------------------------------------------------------
641 {
642 pImpl.swap( pginf.pImpl );
643 return *this;
644 }
645
646 //----------------------------------------------------------------------------
647 // Destructor
648 //----------------------------------------------------------------------------
650 {
651 }
652
653 //----------------------------------------------------------------------------
654 // Get the offset
655 //----------------------------------------------------------------------------
656 uint64_t PageInfo::GetOffset() const
657 {
658 return pImpl->offset;
659 }
660
661 //----------------------------------------------------------------------------
662 // Get the data length
663 //----------------------------------------------------------------------------
664 uint32_t PageInfo::GetLength() const
665 {
666 return pImpl->length;
667 }
668
669 //----------------------------------------------------------------------------
670 // Get the buffer
671 //----------------------------------------------------------------------------
673 {
674 return pImpl->buffer;
675 }
676
677 //----------------------------------------------------------------------------
678 // Get the buffer
679 //----------------------------------------------------------------------------
680 std::vector<uint32_t>& PageInfo::GetCksums()
681 {
682 return pImpl->cksums;
683 }
684
685 //----------------------------------------------------------------------------
686 // Set number of repaired pages
687 //----------------------------------------------------------------------------
688 void PageInfo::SetNbRepair( size_t nbrepair )
689 {
690 pImpl->nbrepair = nbrepair;
691 }
692
693 //----------------------------------------------------------------------------
694 // Get number of repaired pages
695 //----------------------------------------------------------------------------
697 {
698 return pImpl->nbrepair;
699 }
700
702 {
703 RetryInfoImpl( std::vector<std::tuple<uint64_t, uint32_t>> && retries ) :
704 retries( std::move( retries ) )
705 {
706
707 }
708
709 std::vector<std::tuple<uint64_t, uint32_t>> retries;
710 };
711
712 //----------------------------------------------------------------------------
713 // Constructor
714 //----------------------------------------------------------------------------
715 RetryInfo::RetryInfo( std::vector<std::tuple<uint64_t, uint32_t>> && retries ) :
716 pImpl( new RetryInfoImpl( std::move( retries ) ) )
717 {
718
719 }
720
721 //----------------------------------------------------------------------------
722 // Destructor
723 //----------------------------------------------------------------------------
725
726 //----------------------------------------------------------------------------
727 // @return : true if some pages need retrying, false otherwise
728 //----------------------------------------------------------------------------
730 {
731 return !pImpl->retries.empty();
732 }
733
734 //----------------------------------------------------------------------------
735 // @return number of pages that need to be retransmitted
736 //----------------------------------------------------------------------------
738 {
739 return pImpl->retries.size();
740 }
741
742 //----------------------------------------------------------------------------
743 // @return : offset and size of respective page that requires to be
744 // retransmitted
745 //----------------------------------------------------------------------------
746 std::tuple<uint64_t, uint32_t> RetryInfo::At( size_t i )
747 {
748 return pImpl->retries[i];
749 }
750
751 //------------------------------------------------------------------------
752 // Factory function for generating handler objects from lambdas
753 //------------------------------------------------------------------------
755 {
756 struct FuncHandler : public ResponseHandler
757 {
758 FuncHandler( std::function<void(XRootDStatus&, AnyObject&)> func ) : func( std::move( func ) )
759 {
760 }
761
762 void HandleResponse( XRootDStatus *status, AnyObject *response )
763 {
764 // make sure the arguments will be released
765 std::unique_ptr<XRootDStatus> stptr( status );
766 std::unique_ptr<AnyObject> rspptr( response );
767 // if there is no response provide a null reference placeholder
768 static AnyObject nullref;
769 if( response == nullptr )
770 response = &nullref;
771 // call the user completion handler
772 func( *status, *response );
773 // check if this is a final respons
774 bool finalrsp = !( status->IsOK() && status->code == suContinue );
775 // deallocate the wrapper if final
776 if( finalrsp )
777 delete this;
778 }
779
780 std::function<void(XRootDStatus&, AnyObject&)> func;
781 };
782
783 return new FuncHandler( func );
784 }
785
787 {
788 struct FuncHandler : public ResponseHandler
789 {
790 FuncHandler( std::function<void(XRootDStatus*, AnyObject*)> func ) : func( std::move( func ) )
791 {
792 }
793
794 void HandleResponse( XRootDStatus *status, AnyObject *response )
795 {
796 // check if this is a final respons
797 bool finalrsp = !( status->IsOK() && status->code == suContinue );
798 // call the user completion handler
799 func( status, response );
800 // deallocate the wrapper if final
801 if( finalrsp )
802 delete this;
803 }
804
805 std::function<void(XRootDStatus*, AnyObject*)> func;
806 };
807
808 return new FuncHandler( func );
809 }
810}
#define access(a, b)
Definition XrdPosix.hh:44
void SetStatInfo(StatInfo *info)
Set the stat info object (and transfer the ownership)
void Add(ListEntry *entry)
Add an entry to the list - takes ownership.
DirList::iterator Iterator
Directory listing iterator.
static bool HasStatInfo(const char *data)
Returns true if data contain stat info.
bool ParseServerResponse(const std::string &hostId, const char *data)
Parse server response and fill up the object.
bool ParseServerResponse(const char *data)
Parse server response and fill up the object.
AccessType
Describes the allowed access type for the file at given location.
@ Read
read access is allowed
@ ReadWrite
write access is allowed
LocationType
Describes the node type and file status for a given location.
@ ServerPending
server node where the file is pending to be online
@ ManagerOnline
manager node where the file is online
@ ServerOnline
server node where the file is online
@ ManagerPending
manager node where the file is pending to be online
Handle an async response.
static ResponseHandler * Wrap(std::function< void(XRootDStatus &, AnyObject &)> func)
bool ParseServerResponse(const char *data)
Parse server response and fill up the object.
Object stat info.
uint64_t GetChangeTime() const
Get change time (in seconds since epoch)
std::string GetChangeTimeAsString() const
Get change time.
std::string GetModTimeAsString() const
Get modification time.
bool HasChecksum() const
Has checksum.
bool TestFlags(uint32_t flags) const
Test flags.
uint64_t GetSize() const
Get size (in bytes)
const std::string GetModeAsOctString() const
Get mode.
~StatInfo()
Destructor.
const std::string & GetOwner() const
Get owner.
bool ParseServerResponse(const char *data)
Parse server response and fill up the object.
uint32_t GetFlags() const
Get flags.
bool ExtendedFormat() const
Has extended stat information.
const std::string & GetModeAsString() const
Get mode.
const std::string & GetId() const
Get id.
const std::string & GetGroup() const
Get group.
uint64_t GetModTime() const
Get modification time (in seconds since epoch)
std::string GetAccessTimeAsString() const
Get change time.
void SetSize(uint64_t size)
Set size.
uint64_t GetAccessTime() const
Get change time (in seconds since epoch)
void SetFlags(uint32_t flags)
Set flags.
const std::string & GetChecksum() const
Get checksum.
static void splitString(Container &result, const std::string &input, const std::string &delimiter)
Split a string.
Definition XrdClUtils.hh:56
const uint16_t suContinue
PageInfoImpl(uint64_t offset=0, uint32_t length=0, void *buffer=0, std::vector< uint32_t > &&cksums=std::vector< uint32_t >())
std::vector< uint32_t > cksums
PageInfoImpl(PageInfoImpl &&pginf)
size_t GetNbRepair()
Get number of repaired pages.
void SetNbRepair(size_t nbrepair)
Set number of repaired pages.
PageInfo(uint64_t offset=0, uint32_t length=0, void *buffer=0, std::vector< uint32_t > &&cksums=std::vector< uint32_t >())
Default constructor.
PageInfo & operator=(PageInfo &&pginf)
Move assigment operator.
std::vector< uint32_t > & GetCksums()
Get the checksums.
uint32_t GetLength() const
Get the data length.
uint64_t GetOffset() const
Get the offset.
void * GetBuffer()
Get the buffer.
std::vector< std::tuple< uint64_t, uint32_t > > retries
RetryInfoImpl(std::vector< std::tuple< uint64_t, uint32_t > > &&retries)
RetryInfo(std::vector< std::tuple< uint64_t, uint32_t > > &&retries)
Constructor.
std::tuple< uint64_t, uint32_t > At(size_t i)
bool ParseServerResponse(const char *data)
StatInfoImpl(const StatInfoImpl &pimpl)
uint16_t code
Error type, or additional hints on what to do.
bool IsOK() const
We're fine.