summaryrefslogtreecommitdiff
path: root/src/SegmentMan.h
blob: 857a38f796f5e070a2eb5e6b2e598b557a838453 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
/* <!-- copyright */
/*
 * aria2 - a simple utility for downloading files faster
 *
 * Copyright (C) 2006 Tatsuhiro Tsujikawa
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
/* copyright --> */
#ifndef _D_SEGMENT_MAN_H_
#define _D_SEGMENT_MAN_H_

#include "common.h"
#include "Logger.h"
#include "Segment.h"
#include "Option.h"
#include "SegmentSplitter.h"

using namespace std;

#define SEGMENT_FILE_EXTENSION ".aria2"

/**
 * This class holds the download progress of the one download entry.
 */
class SegmentMan {
private:
  void read(FILE* file);
  FILE* openSegFile(string segFilename, string mode) const;
public:
  /**
   * The total number of bytes to download.
   * If Transfer-Encoding is Chunked or Content-Length header is not provided,
   * then this value is set to be 0.
   */
  long long int totalSize;
  /**
   * Represents whether this download is splittable.
   * In Split download(or segmented download), http client establishes
   * more than one connections to the server, and downloads sevral parts of
   * a file at the same time. This boosts download speed.
   * This value is true by default. If total number of bytes is not known or
   * Chunked transfer encoding is used, then this value is set to be 0 by
   * DownloadCommand class.
   */
  bool isSplittable;
  /**
   * Represents whether the download is start or not.
   * The default value is false.
   */
  bool downloadStarted;
  /**
   * Holds segments.
   */
  Segments segments;
  /**
   * Respresents the file name of the downloaded file.
   * If the URL does not contain file name part(http://www.rednoah.com/, for 
   * example), this value may be 0 length string.
   * The default value is 0 length string.
   */
  string filename;
  /**
   * directory to store a file
   */
  string dir;
  /**
   * User defined file name for downloaded content
   */
  string ufilename;

  const Logger* logger;
  const Option* option;
  SegmentSplitter* splitter;

  SegmentMan();
  ~SegmentMan();
  
  /**
   * Returns dir+"/"+filename.
   * If filename is empty, then returns dir+"/"+"inex.html";
   */
  string getFilePath() const {
    return (dir == "" ? "." : dir)+"/"+
      (ufilename == "" ? 
       (filename == "" ? "index.html" : filename) : ufilename);
  }

  string getSegmentFilePath() const {
    return getFilePath()+SEGMENT_FILE_EXTENSION;
  }

  /**
   * Sets the cuid of the holded segments with specified cuid to 0.
   */
  void unregisterId(int cuid);
  /**
   * There is a segment available for DownloadCommand specified by cuid,
   * fills segment and returns true.
   * There is no segment available, then returns false and segment is
   * undefined in this case.
   *
   * @param segment segment to attach for cuid.
   * @param cuid cuid of DownloadCommand.
   * @returns true: there is a segment available, false: there is no segment
   * available.
   */
  bool getSegment(Segment& segment, int cuid);
  /**
   * Updates the ds value of the specified segment.
   * Only a segment x is updated where x.sp == sgment.sp &amp;&amp; x.ep ==
   * segment.ep &amp;&amp; x.ds == segment.ds &amp;&amp;x.cuid == segment.cuid
   * is true.
   *
   * @param segment segment to update
   */
  void updateSegment(const Segment& segment);
  /**
   * Returns true only if the segment data file exists.
   * The file name of the segment data is filename appended by ".aria2".
   * If isSplittable is false, then returns simply false without any operation.
   */
  bool segmentFileExists() const;
  /**
   * Loads the segment data file.
   * If isSplittable is false, then returns without any operation.
   */
  void load();
  /**
   * Saves the segment data file.
   * If isSplittable is false, then returns without any operation.
   */
  void save() const;
  /**
   * Removes the segment data file.
   * If isSplittable is false, then returns without any operation.
   */
  void remove() const;
  /**
   * Returs true when the download has finished.
   * If downloadStarted is false or the number of the segments of this object
   * holds is 0, then returns false.
   */
  bool finished() const;
  /**
   * if finished() is true, then call remove()
   */
  void removeIfFinished() const;
  /**
   * Returns the total number of bytes to be downloaded.
   */
  long long int getDownloadedSize() const;
};

#endif // _D_SEGMENT_MAN_H_