changed: Add logic to properly handle subtitles for stacked files
[vuplus_xbmc] / xbmc / filesystem / udf25.h
1 #ifndef UDF25_H
2 #define UDF25_H
3 /*
4  *      Copyright (C) 2010 Team Boxee
5  *      http://www.boxee.tv
6  *
7  *      Copyright (C) 2010-2013 Team XBMC
8  *      http://xbmc.org
9  *
10  *  This Program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2, or (at your option)
13  *  any later version.
14  *
15  *  This Program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  *  GNU General Public License for more details.
19  *
20  *  You should have received a copy of the GNU General Public License
21  *  along with XBMC; see the file COPYING.  If not, see
22  *  <http://www.gnu.org/licenses/>.
23  *
24  *  Note: parts of this code comes from libdvdread.
25  *  Jorgen Lundman and team boxee did the necessary modifications to support udf 2.5
26  *
27  */
28 #include "File.h"
29
30 /**
31  * The length of one Logical Block of a DVD.
32  */
33 #define DVD_VIDEO_LB_LEN 2048
34
35 /**
36  * Maximum length of filenames allowed in UDF.
37  */
38 #define MAX_UDF_FILE_NAME_LEN 2048
39
40 struct Partition {
41   int valid;
42   char VolumeDesc[128];
43   uint16_t Flags;
44   uint16_t Number;
45   char Contents[32];
46   uint32_t AccessType;
47   uint32_t Start;
48   uint32_t Length;
49 };
50
51 struct AD {
52   uint32_t Location;
53   uint32_t Length;
54   uint8_t  Flags;
55   uint16_t Partition;
56 };
57
58 /* Previously dvdread would assume files only had one AD chain, and since they
59  * are 1GB or less, this is most problably true. However, now we handle chains
60  * for large files. ECMA_167 does not specify the maximum number of chains, is
61  * it as many as can fit in a 2048 block (minus ID 266 size), or some other
62  * limit. For now, I have assumed that;
63  * a 4.4GB file uses 5 AD chains. A BluRay disk can store 50GB of data, so the
64  * largest file should be 50 GB. So the maximum number of chains should be
65  * around 62.
66  *
67  * However, with AD chain extensions there has been examples of chains up to
68  * around 1600 entries.
69  */
70
71 #define UDF_MAX_AD_CHAINS 2000
72
73 struct FileAD {
74     uint64_t Length;
75     uint32_t num_AD;
76     uint16_t Partition;
77     uint32_t Partition_Start;
78     uint8_t  Type;
79     uint16_t Flags;
80     struct AD AD_chain[UDF_MAX_AD_CHAINS];
81 };
82
83 struct extent_ad {
84   uint32_t location;
85   uint32_t length;
86 };
87
88 struct avdp_t {
89   struct extent_ad mvds;
90   struct extent_ad rvds;
91 };
92
93 struct pvd_t {
94   uint8_t VolumeIdentifier[32];
95   uint8_t VolumeSetIdentifier[128];
96 };
97
98 struct lbudf {
99   uint32_t lb;
100   uint8_t *data;
101   /* needed for proper freeing */
102   uint8_t *data_base;
103 };
104
105 struct icbmap {
106   uint32_t lbn;
107   struct FileAD  file;
108 };
109
110 struct udf_cache {
111   int avdp_valid;
112   struct avdp_t avdp;
113   int pvd_valid;
114   struct pvd_t pvd;
115   int partition_valid;
116   struct Partition partition;
117   int rooticb_valid;
118   struct AD rooticb;
119   int lb_num;
120   struct lbudf *lbs;
121   int map_num;
122   struct icbmap *maps;
123 };
124
125 typedef enum {
126   PartitionCache, RootICBCache, LBUDFCache, MapCache, AVDPCache, PVDCache
127 } UDFCacheType;
128
129 /*
130  * DVDReaddir entry types.
131  */
132 typedef enum {
133   DVD_DT_UNKNOWN = 0,
134   DVD_DT_FIFO,
135   DVD_DT_CHR,
136   DVD_DT_DIR,
137   DVD_DT_BLK,
138   DVD_DT_REG,
139   DVD_DT_LNK,
140   DVD_DT_SOCK,
141   DVD_DT_WHT
142 } udf_dir_type_t;
143
144 /*
145  * DVDReaddir structure.
146  * Extended a little from POSIX to also return filesize.
147  */
148 typedef struct {
149   unsigned char  d_name[MAX_UDF_FILE_NAME_LEN];
150   // "Shall not exceed 1023; Ecma-167 page 123"
151   udf_dir_type_t d_type;       // DT_REG, DT_DIR
152   unsigned int   d_namlen;
153   uint64_t       d_filesize;
154 } udf_dirent_t;
155
156
157 /*
158  * DVDOpendir DIR* structure
159  */
160 typedef struct {
161   uint32_t dir_location;
162   uint32_t dir_length;
163   uint32_t dir_current;   // Separate to _location should we one day want to
164                           // implement dir_rewind()
165   unsigned int current_p; // Internal implementation specific. UDFScanDirX
166   udf_dirent_t entry;
167 } udf_dir_t;
168
169
170
171 typedef struct FileAD *UDF_FILE;
172
173 typedef struct _BD_FILE
174 {
175   UDF_FILE file;
176   uint64_t seek_pos;  // in bytes
177   uint64_t filesize;  // in bytes
178
179 } *BD_FILE;
180
181
182 class udf25
183 {
184
185 public:
186   udf25( );
187   virtual ~udf25( );
188
189   DWORD SetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod );
190   int64_t GetFileSize(HANDLE hFile);
191   int64_t GetFilePosition(HANDLE hFile);
192   int64_t Seek(HANDLE hFile, int64_t lOffset, int whence);
193   bool   Open(const char *isofile);
194   HANDLE OpenFile( const char* filename );
195   long ReadFile(HANDLE fd, unsigned char *pBuffer, long lSize);
196   void CloseFile(HANDLE hFile);
197
198   udf_dir_t *OpenDir( const char *subdir );
199   udf_dirent_t *ReadDir( udf_dir_t *dirp );
200   int CloseDir( udf_dir_t *dirp );
201
202   void Reset();
203   void Scan();
204   bool IsScanned();
205
206 private:
207   UDF_FILE UDFFindFile( const char* filename, uint64_t *filesize );
208   int UDFScanDirX( udf_dir_t *dirp );
209   int DVDUDFCacheLevel(int level);
210   void* GetUDFCacheHandle();
211   void SetUDFCacheHandle(void *cache);
212   int GetUDFCache(UDFCacheType type,uint32_t nr, void *data);
213   int UDFFindPartition( int partnum, struct Partition *part );
214   int UDFGetAVDP( struct avdp_t *avdp);
215   int DVDReadLBUDF( uint32_t lb_number, size_t block_count, unsigned char *data, int encrypted );
216   int ReadAt( int64_t pos, size_t len, unsigned char *data );
217   int UDFMapICB( struct AD ICB, struct Partition *partition, struct FileAD *File );
218   int UDFScanDir( struct FileAD Dir, char *FileName, struct Partition *partition, struct AD *FileICB, int cache_file_info);
219   int SetUDFCache(UDFCacheType type, uint32_t nr, void *data);
220 protected:
221     /* Filesystem cache */
222   int m_udfcache_level; /* 0 - turned off, 1 - on */
223   void *m_udfcache;
224   XFILE::CFile* m_fp;
225 };
226
227 #endif