]> git.vomp.tv Git - vompserver.git/blob - recplayer.c
VDR 1.3 support
[vompserver.git] / recplayer.c
1 /*
2     Copyright 2004-2005 Chris Tallon
3
4     This file is part of VOMP.
5
6     VOMP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     VOMP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with VOMP; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21 #include "recplayer.h"
22
23 RecPlayer::RecPlayer(cRecording* rec)
24 {
25   file = NULL;
26   totalLength = 0;
27   lastPosition = 0;
28   recording = rec;
29
30   // FIXME find out max file path / name lengths
31
32
33   char fileName[2048];
34   for(int i = 1; i < 1001; i++)
35   {
36     snprintf(fileName, 2047, "%s/%03i.vdr", rec->FileName(), i);
37     printf("FILENAME: %s\n", fileName);
38     file = fopen(fileName, "r");
39     if (file)
40     {
41       segments[i] = new Segment();
42       segments[i]->start = totalLength;
43
44       fseek(file, 0, SEEK_END);
45       totalLength += ftell(file);
46       printf("File %i found, totalLength now %llu\n", i, totalLength);
47       segments[i]->end = totalLength;
48       fclose(file);
49     }
50     else
51     {
52       segments[i] = NULL;
53       break;
54     }
55   }
56   openFile(1);
57 }
58
59 RecPlayer::~RecPlayer()
60 {
61   printf("RecPlayer destructor\n");
62   int i = 1;
63   while(segments[i++]) delete segments[i];
64   if (file) fclose(file);
65 }
66
67 int RecPlayer::openFile(int index)
68 {
69   if (file) fclose(file);
70
71   char fileName[2048];
72   snprintf(fileName, 2047, "%s/%03i.vdr", recording->FileName(), index);
73   printf("openFile called for index %i string:%s\n", index, fileName);
74
75   file = fopen(fileName, "r");
76   if (!file)
77   {
78     printf("file failed to open\n");
79     fileOpen = 0;
80     return 0;
81   }
82   fileOpen = index;
83   return 1;
84 }
85
86 ULLONG RecPlayer::getTotalLength()
87 {
88   return totalLength;
89 }
90
91 unsigned long RecPlayer::getBlock(unsigned char* buffer, ULLONG position, unsigned long amount)
92 {
93   if ((amount > totalLength) || (amount > 100000))
94   {
95     printf("Amount %lu requested and rejected\n", amount);
96     return 0;
97   }
98
99   if (position >= totalLength)
100   {
101     printf("Client asked for data starting past end of recording!\n");
102     return 0;
103   }
104
105   if ((position + amount) > totalLength)
106   {
107     printf("Client asked for some data past the end of recording, adjusting amount\n");
108     amount = totalLength - position;
109   }
110
111   // work out what block position is in
112   int segmentNumber;
113   for(segmentNumber = 1; segmentNumber < 1000; segmentNumber++)
114   {
115     if ((position >= segments[segmentNumber]->start) && (position < segments[segmentNumber]->end)) break;
116     // position is in this block
117   }
118
119   // we could be seeking around
120   if (segmentNumber != fileOpen)
121   {
122     if (!openFile(segmentNumber)) return 0;
123   }
124
125   ULLONG currentPosition = position;
126   ULONG yetToGet = amount;
127   ULONG got = 0;
128   ULONG getFromThisSegment = 0;
129   ULONG filePosition;
130
131   while(got < amount)
132   {
133     if (got)
134     {
135       // if(got) then we have already got some and we are back around
136       // advance the file pointer to the next file
137       if (!openFile(++segmentNumber)) return 0;
138     }
139
140     // is the request completely in this block?
141     if ((currentPosition + yetToGet) <= segments[segmentNumber]->end)
142       getFromThisSegment = yetToGet;
143     else
144       getFromThisSegment = segments[segmentNumber]->end - currentPosition;
145
146     filePosition = currentPosition - segments[segmentNumber]->start;
147     fseek(file, filePosition, SEEK_SET);
148     if (fread(&buffer[got], getFromThisSegment, 1, file) != 1) return 0; // umm, big problem.
149
150     got += getFromThisSegment;
151     currentPosition += getFromThisSegment;
152     yetToGet -= getFromThisSegment;
153   }
154
155   lastPosition = position;
156   return got;
157 }
158
159 ULLONG RecPlayer::getLastPosition()
160 {
161   return lastPosition;
162 }
163
164 cRecording* RecPlayer::getCurrentRecording()
165 {
166   return recording;
167 }