[cstdstring] demise Format, replacing with StringUtils::Format
[vuplus_xbmc] / xbmc / filesystem / test / TestRarFile.cpp
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program 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 General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 #include "system.h"
22 #ifdef HAS_FILESYSTEM_RAR
23 #include "filesystem/Directory.h"
24 #include "filesystem/File.h"
25 #include "filesystem/NFSFile.h"
26 #include "utils/URIUtils.h"
27 #include "FileItem.h"
28 #include "test/TestUtils.h"
29 #include "utils/StringUtils.h"
30
31 #include <errno.h>
32
33 #include "gtest/gtest.h"
34
35 TEST(TestRarFile, Read)
36 {
37   XFILE::CFile file;
38   char buf[20];
39   memset(&buf, 0, sizeof(buf));
40   CStdString reffile, strrarpath, strpathinrar;
41   CFileItemList itemlist;
42
43   reffile = XBMC_REF_FILE_PATH("xbmc/filesystem/test/reffile.txt.rar");
44   URIUtils::CreateArchivePath(strrarpath, "rar", reffile, "");
45   ASSERT_TRUE(XFILE::CDirectory::GetDirectory(strrarpath, itemlist, "",
46     XFILE::DIR_FLAG_NO_FILE_DIRS));
47   strpathinrar = itemlist[0]->GetPath();
48   ASSERT_TRUE(file.Open(strpathinrar));
49   EXPECT_EQ(0, file.GetPosition());
50   EXPECT_EQ(1616, file.GetLength());
51   EXPECT_EQ(sizeof(buf), file.Read(buf, sizeof(buf)));
52   file.Flush();
53   EXPECT_EQ(20, file.GetPosition());
54   EXPECT_TRUE(!memcmp("About\n-----\nXBMC is ", buf, sizeof(buf) - 1));
55   EXPECT_TRUE(file.ReadString(buf, sizeof(buf)));
56   EXPECT_EQ(39, file.GetPosition());
57   EXPECT_STREQ("an award-winning fr", buf);
58   EXPECT_EQ(100, file.Seek(100));
59   EXPECT_EQ(100, file.GetPosition());
60   EXPECT_EQ(sizeof(buf), file.Read(buf, sizeof(buf)));
61   file.Flush();
62   EXPECT_EQ(120, file.GetPosition());
63   EXPECT_TRUE(!memcmp("ent hub for digital ", buf, sizeof(buf) - 1));
64   EXPECT_EQ(220, file.Seek(100, SEEK_CUR));
65   EXPECT_EQ(220, file.GetPosition());
66   EXPECT_EQ(sizeof(buf), file.Read(buf, sizeof(buf)));
67   file.Flush();
68   EXPECT_EQ(240, file.GetPosition());
69   EXPECT_TRUE(!memcmp("rs, XBMC is a non-pr", buf, sizeof(buf) - 1));
70   EXPECT_EQ(1596, file.Seek(-(int64_t)sizeof(buf), SEEK_END));
71   EXPECT_EQ(1596, file.GetPosition());
72   EXPECT_EQ(sizeof(buf), file.Read(buf, sizeof(buf)));
73   file.Flush();
74   EXPECT_EQ(1616, file.GetPosition());
75   EXPECT_TRUE(!memcmp("multimedia jukebox.\n", buf, sizeof(buf) - 1));
76   EXPECT_EQ(1716, file.Seek(100, SEEK_CUR));
77   EXPECT_EQ(1716, file.GetPosition());
78   EXPECT_EQ(0, file.Seek(0, SEEK_SET));
79   EXPECT_EQ(sizeof(buf), file.Read(buf, sizeof(buf)));
80   file.Flush();
81   EXPECT_EQ(20, file.GetPosition());
82   EXPECT_TRUE(!memcmp("About\n-----\nXBMC is ", buf, sizeof(buf) - 1));
83   EXPECT_EQ(0, file.Seek(0, SEEK_SET));
84   EXPECT_EQ(-1, file.Seek(-100, SEEK_SET));
85   file.Close();
86 }
87
88 TEST(TestRarFile, Exists)
89 {
90   CStdString reffile, strrarpath, strpathinrar;
91   CFileItemList itemlist;
92
93   reffile = XBMC_REF_FILE_PATH("xbmc/filesystem/test/reffile.txt.rar");
94   URIUtils::CreateArchivePath(strrarpath, "rar", reffile, "");
95   ASSERT_TRUE(XFILE::CDirectory::GetDirectory(strrarpath, itemlist, "",
96     XFILE::DIR_FLAG_NO_FILE_DIRS));
97   strpathinrar = itemlist[0]->GetPath();
98
99   EXPECT_TRUE(XFILE::CFile::Exists(strpathinrar));
100 }
101
102 TEST(TestRarFile, Stat)
103 {
104   struct __stat64 buffer;
105   CStdString reffile, strrarpath, strpathinrar;
106   CFileItemList itemlist;
107
108   reffile = XBMC_REF_FILE_PATH("xbmc/filesystem/test/reffile.txt.rar");
109   URIUtils::CreateArchivePath(strrarpath, "rar", reffile, "");
110   ASSERT_TRUE(XFILE::CDirectory::GetDirectory(strrarpath, itemlist, "",
111     XFILE::DIR_FLAG_NO_FILE_DIRS));
112   strpathinrar = itemlist[0]->GetPath();
113
114   EXPECT_EQ(0, XFILE::CFile::Stat(strpathinrar, &buffer));
115   EXPECT_TRUE(buffer.st_mode | _S_IFREG);
116 }
117
118 /* Test case to test for graceful handling of corrupted input.
119  * NOTE: The test case is considered a "success" as long as the corrupted
120  * file was successfully generated and the test case runs without a segfault.
121  */
122 TEST(TestRarFile, CorruptedFile)
123 {
124   XFILE::CFile *file;
125   char buf[16];
126   memset(&buf, 0, sizeof(buf));
127   CStdString reffilepath, strrarpath, strpathinrar, str;
128   CFileItemList itemlist;
129   unsigned int size, i;
130   int64_t count = 0;
131
132   reffilepath = XBMC_REF_FILE_PATH("xbmc/filesystem/test/reffile.txt.rar");
133   ASSERT_TRUE((file = XBMC_CREATECORRUPTEDFILE(reffilepath, ".rar")) != NULL);
134   std::cout << "Reference file generated at '" << XBMC_TEMPFILEPATH(file) << "'" << std::endl;
135
136   URIUtils::CreateArchivePath(strrarpath, "rar", XBMC_TEMPFILEPATH(file), "");
137   if (!XFILE::CDirectory::GetDirectory(strrarpath, itemlist, "",
138                                        XFILE::DIR_FLAG_NO_FILE_DIRS))
139   {
140     XBMC_DELETETEMPFILE(file);
141     SUCCEED();
142     return;
143   }
144   if (itemlist.IsEmpty())
145   {
146     XBMC_DELETETEMPFILE(file);
147     SUCCEED();
148     return;
149   }
150   strpathinrar = itemlist[0]->GetPath();
151
152   if (!file->Open(strpathinrar))
153   {
154     XBMC_DELETETEMPFILE(file);
155     SUCCEED();
156     return;
157   }
158   std::cout << "file->GetLength(): " <<
159     testing::PrintToString(file->GetLength()) << std::endl;
160   std::cout << "file->Seek(file->GetLength() / 2, SEEK_CUR) return value: " <<
161     testing::PrintToString(file->Seek(file->GetLength() / 2, SEEK_CUR)) << std::endl;
162   std::cout << "file->Seek(0, SEEK_END) return value: " <<
163     testing::PrintToString(file->Seek(0, SEEK_END)) << std::endl;
164   std::cout << "file->Seek(0, SEEK_SET) return value: " <<
165     testing::PrintToString(file->Seek(0, SEEK_SET)) << std::endl;
166   std::cout << "File contents:" << std::endl;
167   while ((size = file->Read(buf, sizeof(buf))) > 0)
168   {
169     str = StringUtils::Format("  %08X", count);
170     std::cout << str << "  ";
171     count += size;
172     for (i = 0; i < size; i++)
173     {
174       str = StringUtils::Format("%02X ", buf[i]);
175       std::cout << str;
176     }
177     while (i++ < sizeof(buf))
178       std::cout << "   ";
179     std::cout << " [";
180     for (i = 0; i < size; i++)
181     {
182       if (buf[i] >= ' ' && buf[i] <= '~')
183         std::cout << buf[i];
184       else
185         std::cout << ".";
186     }
187     std::cout << "]" << std::endl;
188   }
189   file->Close();
190   XBMC_DELETETEMPFILE(file);
191 }
192
193 TEST(TestRarFile, StoredRAR)
194 {
195   XFILE::CFile file;
196   char buf[20];
197   memset(&buf, 0, sizeof(buf));
198   CStdString reffile, strrarpath, strpathinrar;
199   CFileItemList itemlist, itemlistemptydir;
200   struct __stat64 stat_buffer;
201
202   reffile = XBMC_REF_FILE_PATH("xbmc/filesystem/test/refRARstored.rar");
203   URIUtils::CreateArchivePath(strrarpath, "rar", reffile, "");
204   ASSERT_TRUE(XFILE::CDirectory::GetDirectory(strrarpath, itemlist));
205   itemlist.Sort(SortByPath, SortOrderAscending);
206
207   /* /reffile.txt */
208   /*
209    * NOTE: Use of Seek gives inconsistent behavior from when seeking through
210    * an uncompressed RAR archive. See TestRarFile.Read test case.
211    */
212   strpathinrar = itemlist[1]->GetPath();
213   ASSERT_TRUE(StringUtils::EndsWith(strpathinrar, "/reffile.txt"));
214   EXPECT_EQ(0, XFILE::CFile::Stat(strpathinrar, &stat_buffer));
215   EXPECT_TRUE((stat_buffer.st_mode & S_IFMT) | S_IFREG);
216
217   ASSERT_TRUE(file.Open(strpathinrar));
218   EXPECT_EQ(0, file.GetPosition());
219   EXPECT_EQ(1616, file.GetLength());
220   EXPECT_EQ(sizeof(buf), file.Read(buf, sizeof(buf)));
221   file.Flush();
222   EXPECT_EQ(20, file.GetPosition());
223   EXPECT_TRUE(!memcmp("About\n-----\nXBMC is ", buf, sizeof(buf) - 1));
224   EXPECT_TRUE(file.ReadString(buf, sizeof(buf)));
225   EXPECT_EQ(39, file.GetPosition());
226   EXPECT_STREQ("an award-winning fr", buf);
227   EXPECT_EQ(100, file.Seek(100));
228   EXPECT_EQ(100, file.GetPosition());
229   EXPECT_EQ(sizeof(buf), file.Read(buf, sizeof(buf)));
230   file.Flush();
231   EXPECT_EQ(120, file.GetPosition());
232   EXPECT_TRUE(!memcmp("ent hub for digital ", buf, sizeof(buf) - 1));
233   EXPECT_EQ(220, file.Seek(100, SEEK_CUR));
234   EXPECT_EQ(220, file.GetPosition());
235   EXPECT_EQ(sizeof(buf), file.Read(buf, sizeof(buf)));
236   file.Flush();
237   EXPECT_EQ(240, file.GetPosition());
238   EXPECT_TRUE(!memcmp("rs, XBMC is a non-pr", buf, sizeof(buf) - 1));
239   EXPECT_EQ(1596, file.Seek(-(int64_t)sizeof(buf), SEEK_END));
240   EXPECT_EQ(1596, file.GetPosition());
241   EXPECT_EQ(sizeof(buf), file.Read(buf, sizeof(buf)));
242   file.Flush();
243   EXPECT_EQ(1616, file.GetPosition());
244   EXPECT_TRUE(!memcmp("multimedia jukebox.\n", buf, sizeof(buf) - 1));
245   EXPECT_EQ(-1, file.Seek(100, SEEK_CUR));
246   EXPECT_EQ(1616, file.GetPosition());
247   EXPECT_EQ(0, file.Seek(0, SEEK_SET));
248   EXPECT_EQ(sizeof(buf), file.Read(buf, sizeof(buf)));
249   file.Flush();
250   EXPECT_EQ(20, file.GetPosition());
251   EXPECT_TRUE(!memcmp("About\n-----\nXBMC is ", buf, sizeof(buf) - 1));
252   EXPECT_EQ(0, file.Seek(0, SEEK_SET));
253   EXPECT_EQ(-100, file.Seek(-100, SEEK_SET));
254   file.Close();
255
256   /* /testsymlink -> testdir/reffile.txt */
257   strpathinrar = itemlist[2]->GetPath();
258   ASSERT_TRUE(StringUtils::EndsWith(strpathinrar, "/testsymlink"));
259   EXPECT_EQ(0, XFILE::CFile::Stat(strpathinrar, &stat_buffer));
260   EXPECT_TRUE((stat_buffer.st_mode & S_IFMT) | S_IFLNK);
261
262   /*
263    * FIXME: Reading symlinks in RARs is currently broken. It takes a long time
264    * to read them and they produce erroneous results. The expected result is
265    * the target paths of the symlinks.
266    */
267   ASSERT_TRUE(file.Open(strpathinrar));
268   EXPECT_EQ(19, file.GetLength());
269   file.Close();
270
271   /* /testsymlinksubdir -> testdir/testsubdir/reffile.txt */
272   strpathinrar = itemlist[3]->GetPath();
273   ASSERT_TRUE(StringUtils::EndsWith(strpathinrar, "/testsymlinksubdir"));
274   EXPECT_EQ(0, XFILE::CFile::Stat(strpathinrar, &stat_buffer));
275   EXPECT_TRUE((stat_buffer.st_mode & S_IFMT) | S_IFLNK);
276
277   ASSERT_TRUE(file.Open(strpathinrar));
278   EXPECT_EQ(30, file.GetLength());
279   file.Close();
280
281   /* /testdir/ */
282   strpathinrar = itemlist[0]->GetPath();
283   ASSERT_TRUE(StringUtils::EndsWith(strpathinrar, "/testdir/"));
284   EXPECT_EQ(0, XFILE::CFile::Stat(strpathinrar, &stat_buffer));
285   EXPECT_TRUE((stat_buffer.st_mode & S_IFMT) | S_IFDIR);
286
287   itemlist.Clear();
288   ASSERT_TRUE(XFILE::CDirectory::GetDirectory(strpathinrar, itemlist));
289   itemlist.Sort(SortByPath, SortOrderAscending);
290
291   /* /testdir/reffile.txt */
292   strpathinrar = itemlist[1]->GetPath();
293   ASSERT_TRUE(StringUtils::EndsWith(strpathinrar, "/testdir/reffile.txt"));
294   EXPECT_EQ(0, XFILE::CFile::Stat(strpathinrar, &stat_buffer));
295   EXPECT_TRUE((stat_buffer.st_mode & S_IFMT) | S_IFREG);
296
297   ASSERT_TRUE(file.Open(strpathinrar));
298   EXPECT_EQ(0, file.GetPosition());
299   EXPECT_EQ(1616, file.GetLength());
300   EXPECT_EQ(sizeof(buf), file.Read(buf, sizeof(buf)));
301   file.Flush();
302   EXPECT_EQ(20, file.GetPosition());
303   EXPECT_TRUE(!memcmp("About\n-----\nXBMC is ", buf, sizeof(buf) - 1));
304   EXPECT_TRUE(file.ReadString(buf, sizeof(buf)));
305   EXPECT_EQ(39, file.GetPosition());
306   EXPECT_STREQ("an award-winning fr", buf);
307   EXPECT_EQ(100, file.Seek(100));
308   EXPECT_EQ(100, file.GetPosition());
309   EXPECT_EQ(sizeof(buf), file.Read(buf, sizeof(buf)));
310   file.Flush();
311   EXPECT_EQ(120, file.GetPosition());
312   EXPECT_TRUE(!memcmp("ent hub for digital ", buf, sizeof(buf) - 1));
313   EXPECT_EQ(220, file.Seek(100, SEEK_CUR));
314   EXPECT_EQ(220, file.GetPosition());
315   EXPECT_EQ(sizeof(buf), file.Read(buf, sizeof(buf)));
316   file.Flush();
317   EXPECT_EQ(240, file.GetPosition());
318   EXPECT_TRUE(!memcmp("rs, XBMC is a non-pr", buf, sizeof(buf) - 1));
319   EXPECT_EQ(1596, file.Seek(-(int64_t)sizeof(buf), SEEK_END));
320   EXPECT_EQ(1596, file.GetPosition());
321   EXPECT_EQ(sizeof(buf), file.Read(buf, sizeof(buf)));
322   file.Flush();
323   EXPECT_EQ(1616, file.GetPosition());
324   EXPECT_TRUE(!memcmp("multimedia jukebox.\n", buf, sizeof(buf) - 1));
325   EXPECT_EQ(-1, file.Seek(100, SEEK_CUR));
326   EXPECT_EQ(1616, file.GetPosition());
327   EXPECT_EQ(0, file.Seek(0, SEEK_SET));
328   EXPECT_EQ(sizeof(buf), file.Read(buf, sizeof(buf)));
329   file.Flush();
330   EXPECT_EQ(20, file.GetPosition());
331   EXPECT_TRUE(!memcmp("About\n-----\nXBMC is ", buf, sizeof(buf) - 1));
332   EXPECT_EQ(0, file.Seek(0, SEEK_SET));
333   EXPECT_EQ(-100, file.Seek(-100, SEEK_SET));
334   file.Close();
335
336   /* /testdir/testemptysubdir */
337   strpathinrar = itemlist[2]->GetPath();
338   ASSERT_TRUE(StringUtils::EndsWith(strpathinrar, "/testdir/testemptysubdir"));
339   /* TODO: Should this set the itemlist to an empty list instead? */
340   EXPECT_FALSE(XFILE::CDirectory::GetDirectory(strpathinrar, itemlistemptydir));
341   EXPECT_EQ(0, XFILE::CFile::Stat(strpathinrar, &stat_buffer));
342   EXPECT_TRUE((stat_buffer.st_mode & S_IFMT) | S_IFDIR);
343
344   /* FIXME: This directory appears a second time as a file */
345   strpathinrar = itemlist[3]->GetPath();
346   ASSERT_TRUE(StringUtils::EndsWith(strpathinrar, "/testdir/testsubdir"));
347
348   /* /testdir/testsymlink -> testsubdir/reffile.txt */
349   strpathinrar = itemlist[4]->GetPath();
350   ASSERT_TRUE(StringUtils::EndsWith(strpathinrar, "/testdir/testsymlink"));
351   EXPECT_EQ(0, XFILE::CFile::Stat(strpathinrar, &stat_buffer));
352   EXPECT_TRUE((stat_buffer.st_mode & S_IFMT) | S_IFLNK);
353
354   ASSERT_TRUE(file.Open(strpathinrar));
355   EXPECT_EQ(22, file.GetLength());
356   file.Close();
357
358   /* /testdir/testsubdir/ */
359   strpathinrar = itemlist[0]->GetPath();
360   ASSERT_TRUE(StringUtils::EndsWith(strpathinrar, "/testdir/testsubdir/"));
361   EXPECT_EQ(0, XFILE::CFile::Stat(strpathinrar, &stat_buffer));
362   EXPECT_TRUE((stat_buffer.st_mode & S_IFMT) | S_IFDIR);
363
364   itemlist.Clear();
365   ASSERT_TRUE(XFILE::CDirectory::GetDirectory(strpathinrar, itemlist));
366   itemlist.Sort(SortByPath, SortOrderAscending);
367
368   /* /testdir/testsubdir/reffile.txt */
369   strpathinrar = itemlist[0]->GetPath();
370   ASSERT_TRUE(StringUtils::EndsWith(strpathinrar,
371                                     "/testdir/testsubdir/reffile.txt"));
372   EXPECT_EQ(0, XFILE::CFile::Stat(strpathinrar, &stat_buffer));
373   EXPECT_TRUE((stat_buffer.st_mode & S_IFMT) | S_IFREG);
374
375   ASSERT_TRUE(file.Open(strpathinrar));
376   EXPECT_EQ(0, file.GetPosition());
377   EXPECT_EQ(1616, file.GetLength());
378   EXPECT_EQ(sizeof(buf), file.Read(buf, sizeof(buf)));
379   file.Flush();
380   EXPECT_EQ(20, file.GetPosition());
381   EXPECT_TRUE(!memcmp("About\n-----\nXBMC is ", buf, sizeof(buf) - 1));
382   EXPECT_TRUE(file.ReadString(buf, sizeof(buf)));
383   EXPECT_EQ(39, file.GetPosition());
384   EXPECT_STREQ("an award-winning fr", buf);
385   EXPECT_EQ(100, file.Seek(100));
386   EXPECT_EQ(100, file.GetPosition());
387   EXPECT_EQ(sizeof(buf), file.Read(buf, sizeof(buf)));
388   file.Flush();
389   EXPECT_EQ(120, file.GetPosition());
390   EXPECT_TRUE(!memcmp("ent hub for digital ", buf, sizeof(buf) - 1));
391   EXPECT_EQ(220, file.Seek(100, SEEK_CUR));
392   EXPECT_EQ(220, file.GetPosition());
393   EXPECT_EQ(sizeof(buf), file.Read(buf, sizeof(buf)));
394   file.Flush();
395   EXPECT_EQ(240, file.GetPosition());
396   EXPECT_TRUE(!memcmp("rs, XBMC is a non-pr", buf, sizeof(buf) - 1));
397   EXPECT_EQ(1596, file.Seek(-(int64_t)sizeof(buf), SEEK_END));
398   EXPECT_EQ(1596, file.GetPosition());
399   EXPECT_EQ(sizeof(buf), file.Read(buf, sizeof(buf)));
400   file.Flush();
401   EXPECT_EQ(1616, file.GetPosition());
402   EXPECT_TRUE(!memcmp("multimedia jukebox.\n", buf, sizeof(buf) - 1));
403   EXPECT_EQ(-1, file.Seek(100, SEEK_CUR));
404   EXPECT_EQ(1616, file.GetPosition());
405   EXPECT_EQ(0, file.Seek(0, SEEK_SET));
406   EXPECT_EQ(sizeof(buf), file.Read(buf, sizeof(buf)));
407   file.Flush();
408   EXPECT_EQ(20, file.GetPosition());
409   EXPECT_TRUE(!memcmp("About\n-----\nXBMC is ", buf, sizeof(buf) - 1));
410   EXPECT_EQ(0, file.Seek(0, SEEK_SET));
411   EXPECT_EQ(-100, file.Seek(-100, SEEK_SET));
412   file.Close();
413 }
414
415 TEST(TestRarFile, NormalRAR)
416 {
417   XFILE::CFile file;
418   char buf[20];
419   memset(&buf, 0, sizeof(buf));
420   CStdString reffile, strrarpath, strpathinrar;
421   CFileItemList itemlist, itemlistemptydir;
422   struct __stat64 stat_buffer;
423
424   reffile = XBMC_REF_FILE_PATH("xbmc/filesystem/test/refRARnormal.rar");
425   URIUtils::CreateArchivePath(strrarpath, "rar", reffile, "");
426   ASSERT_TRUE(XFILE::CDirectory::GetDirectory(strrarpath, itemlist));
427   itemlist.Sort(SortByPath, SortOrderAscending);
428
429   /* /reffile.txt */
430   strpathinrar = itemlist[1]->GetPath();
431   ASSERT_TRUE(StringUtils::EndsWith(strpathinrar, "/reffile.txt"));
432   EXPECT_EQ(0, XFILE::CFile::Stat(strpathinrar, &stat_buffer));
433   EXPECT_TRUE((stat_buffer.st_mode & S_IFMT) | S_IFREG);
434
435   ASSERT_TRUE(file.Open(strpathinrar));
436   EXPECT_EQ(0, file.GetPosition());
437   EXPECT_EQ(1616, file.GetLength());
438   EXPECT_EQ(sizeof(buf), file.Read(buf, sizeof(buf)));
439   file.Flush();
440   EXPECT_EQ(20, file.GetPosition());
441   EXPECT_TRUE(!memcmp("About\n-----\nXBMC is ", buf, sizeof(buf) - 1));
442   EXPECT_TRUE(file.ReadString(buf, sizeof(buf)));
443   EXPECT_EQ(39, file.GetPosition());
444   EXPECT_STREQ("an award-winning fr", buf);
445   EXPECT_EQ(100, file.Seek(100));
446   EXPECT_EQ(100, file.GetPosition());
447   EXPECT_EQ(sizeof(buf), file.Read(buf, sizeof(buf)));
448   file.Flush();
449   EXPECT_EQ(120, file.GetPosition());
450   EXPECT_TRUE(!memcmp("ent hub for digital ", buf, sizeof(buf) - 1));
451   EXPECT_EQ(220, file.Seek(100, SEEK_CUR));
452   EXPECT_EQ(220, file.GetPosition());
453   EXPECT_EQ(sizeof(buf), file.Read(buf, sizeof(buf)));
454   file.Flush();
455   EXPECT_EQ(240, file.GetPosition());
456   EXPECT_TRUE(!memcmp("rs, XBMC is a non-pr", buf, sizeof(buf) - 1));
457   EXPECT_EQ(1596, file.Seek(-(int64_t)sizeof(buf), SEEK_END));
458   EXPECT_EQ(1596, file.GetPosition());
459   EXPECT_EQ(sizeof(buf), file.Read(buf, sizeof(buf)));
460   file.Flush();
461   EXPECT_EQ(1616, file.GetPosition());
462   EXPECT_TRUE(!memcmp("multimedia jukebox.\n", buf, sizeof(buf) - 1));
463   EXPECT_EQ(1716, file.Seek(100, SEEK_CUR));
464   EXPECT_EQ(1716, file.GetPosition());
465   EXPECT_EQ(0, file.Seek(0, SEEK_SET));
466   EXPECT_EQ(sizeof(buf), file.Read(buf, sizeof(buf)));
467   file.Flush();
468   EXPECT_EQ(20, file.GetPosition());
469   EXPECT_TRUE(!memcmp("About\n-----\nXBMC is ", buf, sizeof(buf) - 1));
470   EXPECT_EQ(0, file.Seek(0, SEEK_SET));
471   EXPECT_EQ(-1, file.Seek(-100, SEEK_SET));
472   file.Close();
473
474   /* /testsymlink -> testdir/reffile.txt */
475   strpathinrar = itemlist[2]->GetPath();
476   ASSERT_TRUE(StringUtils::EndsWith(strpathinrar, "/testsymlink"));
477   EXPECT_EQ(0, XFILE::CFile::Stat(strpathinrar, &stat_buffer));
478   EXPECT_TRUE((stat_buffer.st_mode & S_IFMT) | S_IFLNK);
479
480   /*
481    * FIXME: Reading symlinks in RARs is currently broken. It takes a long time
482    * to read them and they produce erroneous results. The expected result is
483    * the target paths of the symlinks.
484    */
485   ASSERT_TRUE(file.Open(strpathinrar));
486   EXPECT_EQ(19, file.GetLength());
487   file.Close();
488
489   /* /testsymlinksubdir -> testdir/testsubdir/reffile.txt */
490   strpathinrar = itemlist[3]->GetPath();
491   ASSERT_TRUE(StringUtils::EndsWith(strpathinrar, "/testsymlinksubdir"));
492   EXPECT_EQ(0, XFILE::CFile::Stat(strpathinrar, &stat_buffer));
493   EXPECT_TRUE((stat_buffer.st_mode & S_IFMT) | S_IFLNK);
494
495   ASSERT_TRUE(file.Open(strpathinrar));
496   EXPECT_EQ(30, file.GetLength());
497   file.Close();
498
499   /* /testdir/ */
500   strpathinrar = itemlist[0]->GetPath();
501   ASSERT_TRUE(StringUtils::EndsWith(strpathinrar, "/testdir/"));
502   EXPECT_EQ(0, XFILE::CFile::Stat(strpathinrar, &stat_buffer));
503   EXPECT_TRUE((stat_buffer.st_mode & S_IFMT) | S_IFDIR);
504
505   itemlist.Clear();
506   ASSERT_TRUE(XFILE::CDirectory::GetDirectory(strpathinrar, itemlist));
507   itemlist.Sort(SortByPath, SortOrderAscending);
508
509   /* /testdir/reffile.txt */
510   strpathinrar = itemlist[1]->GetPath();
511   ASSERT_TRUE(StringUtils::EndsWith(strpathinrar, "/testdir/reffile.txt"));
512   EXPECT_EQ(0, XFILE::CFile::Stat(strpathinrar, &stat_buffer));
513   EXPECT_TRUE((stat_buffer.st_mode & S_IFMT) | S_IFREG);
514
515   ASSERT_TRUE(file.Open(strpathinrar));
516   EXPECT_EQ(0, file.GetPosition());
517   EXPECT_EQ(1616, file.GetLength());
518   EXPECT_EQ(sizeof(buf), file.Read(buf, sizeof(buf)));
519   file.Flush();
520   EXPECT_EQ(20, file.GetPosition());
521   EXPECT_TRUE(!memcmp("About\n-----\nXBMC is ", buf, sizeof(buf) - 1));
522   EXPECT_TRUE(file.ReadString(buf, sizeof(buf)));
523   EXPECT_EQ(39, file.GetPosition());
524   EXPECT_STREQ("an award-winning fr", buf);
525   EXPECT_EQ(100, file.Seek(100));
526   EXPECT_EQ(100, file.GetPosition());
527   EXPECT_EQ(sizeof(buf), file.Read(buf, sizeof(buf)));
528   file.Flush();
529   EXPECT_EQ(120, file.GetPosition());
530   EXPECT_TRUE(!memcmp("ent hub for digital ", buf, sizeof(buf) - 1));
531   EXPECT_EQ(220, file.Seek(100, SEEK_CUR));
532   EXPECT_EQ(220, file.GetPosition());
533   EXPECT_EQ(sizeof(buf), file.Read(buf, sizeof(buf)));
534   file.Flush();
535   EXPECT_EQ(240, file.GetPosition());
536   EXPECT_TRUE(!memcmp("rs, XBMC is a non-pr", buf, sizeof(buf) - 1));
537   EXPECT_EQ(1596, file.Seek(-(int64_t)sizeof(buf), SEEK_END));
538   EXPECT_EQ(1596, file.GetPosition());
539   EXPECT_EQ(sizeof(buf), file.Read(buf, sizeof(buf)));
540   file.Flush();
541   EXPECT_EQ(1616, file.GetPosition());
542   EXPECT_TRUE(!memcmp("multimedia jukebox.\n", buf, sizeof(buf) - 1));
543   EXPECT_EQ(1716, file.Seek(100, SEEK_CUR));
544   EXPECT_EQ(1716, file.GetPosition());
545   EXPECT_EQ(0, file.Seek(0, SEEK_SET));
546   EXPECT_EQ(sizeof(buf), file.Read(buf, sizeof(buf)));
547   file.Flush();
548   EXPECT_EQ(20, file.GetPosition());
549   EXPECT_TRUE(!memcmp("About\n-----\nXBMC is ", buf, sizeof(buf) - 1));
550   EXPECT_EQ(0, file.Seek(0, SEEK_SET));
551   EXPECT_EQ(-1, file.Seek(-100, SEEK_SET));
552   file.Close();
553
554   /* /testdir/testemptysubdir */
555   strpathinrar = itemlist[2]->GetPath();
556   ASSERT_TRUE(StringUtils::EndsWith(strpathinrar, "/testdir/testemptysubdir"));
557   /* TODO: Should this set the itemlist to an empty list instead? */
558   EXPECT_FALSE(XFILE::CDirectory::GetDirectory(strpathinrar, itemlistemptydir));
559   EXPECT_EQ(0, XFILE::CFile::Stat(strpathinrar, &stat_buffer));
560   EXPECT_TRUE((stat_buffer.st_mode & S_IFMT) | S_IFDIR);
561
562   /* FIXME: This directory appears a second time as a file */
563   strpathinrar = itemlist[3]->GetPath();
564   ASSERT_TRUE(StringUtils::EndsWith(strpathinrar, "/testdir/testsubdir"));
565
566   /* /testdir/testsymlink -> testsubdir/reffile.txt */
567   strpathinrar = itemlist[4]->GetPath();
568   ASSERT_TRUE(StringUtils::EndsWith(strpathinrar, "/testdir/testsymlink"));
569   EXPECT_EQ(0, XFILE::CFile::Stat(strpathinrar, &stat_buffer));
570   EXPECT_TRUE((stat_buffer.st_mode & S_IFMT) | S_IFLNK);
571
572   ASSERT_TRUE(file.Open(strpathinrar));
573   EXPECT_EQ(22, file.GetLength());
574   file.Close();
575
576   /* /testdir/testsubdir/ */
577   strpathinrar = itemlist[0]->GetPath();
578   ASSERT_TRUE(StringUtils::EndsWith(strpathinrar, "/testdir/testsubdir/"));
579   EXPECT_EQ(0, XFILE::CFile::Stat(strpathinrar, &stat_buffer));
580   EXPECT_TRUE((stat_buffer.st_mode & S_IFMT) | S_IFDIR);
581
582   itemlist.Clear();
583   ASSERT_TRUE(XFILE::CDirectory::GetDirectory(strpathinrar, itemlist));
584   itemlist.Sort(SortByPath, SortOrderAscending);
585
586   /* /testdir/testsubdir/reffile.txt */
587   strpathinrar = itemlist[0]->GetPath();
588   ASSERT_TRUE(StringUtils::EndsWith(strpathinrar,
589                                     "/testdir/testsubdir/reffile.txt"));
590   EXPECT_EQ(0, XFILE::CFile::Stat(strpathinrar, &stat_buffer));
591   EXPECT_TRUE((stat_buffer.st_mode & S_IFMT) | S_IFREG);
592
593   ASSERT_TRUE(file.Open(strpathinrar));
594   EXPECT_EQ(0, file.GetPosition());
595   EXPECT_EQ(1616, file.GetLength());
596   EXPECT_EQ(sizeof(buf), file.Read(buf, sizeof(buf)));
597   file.Flush();
598   EXPECT_EQ(20, file.GetPosition());
599   EXPECT_TRUE(!memcmp("About\n-----\nXBMC is ", buf, sizeof(buf) - 1));
600   EXPECT_TRUE(file.ReadString(buf, sizeof(buf)));
601   EXPECT_EQ(39, file.GetPosition());
602   EXPECT_STREQ("an award-winning fr", buf);
603   EXPECT_EQ(100, file.Seek(100));
604   EXPECT_EQ(100, file.GetPosition());
605   EXPECT_EQ(sizeof(buf), file.Read(buf, sizeof(buf)));
606   file.Flush();
607   EXPECT_EQ(120, file.GetPosition());
608   EXPECT_TRUE(!memcmp("ent hub for digital ", buf, sizeof(buf) - 1));
609   EXPECT_EQ(220, file.Seek(100, SEEK_CUR));
610   EXPECT_EQ(220, file.GetPosition());
611   EXPECT_EQ(sizeof(buf), file.Read(buf, sizeof(buf)));
612   file.Flush();
613   EXPECT_EQ(240, file.GetPosition());
614   EXPECT_TRUE(!memcmp("rs, XBMC is a non-pr", buf, sizeof(buf) - 1));
615   EXPECT_EQ(1596, file.Seek(-(int64_t)sizeof(buf), SEEK_END));
616   EXPECT_EQ(1596, file.GetPosition());
617   EXPECT_EQ(sizeof(buf), file.Read(buf, sizeof(buf)));
618   file.Flush();
619   EXPECT_EQ(1616, file.GetPosition());
620   EXPECT_TRUE(!memcmp("multimedia jukebox.\n", buf, sizeof(buf) - 1));
621   EXPECT_EQ(1716, file.Seek(100, SEEK_CUR));
622   EXPECT_EQ(1716, file.GetPosition());
623   EXPECT_EQ(0, file.Seek(0, SEEK_SET));
624   EXPECT_EQ(sizeof(buf), file.Read(buf, sizeof(buf)));
625   file.Flush();
626   EXPECT_EQ(20, file.GetPosition());
627   EXPECT_TRUE(!memcmp("About\n-----\nXBMC is ", buf, sizeof(buf) - 1));
628   EXPECT_EQ(0, file.Seek(0, SEEK_SET));
629   EXPECT_EQ(-1, file.Seek(-100, SEEK_SET));
630   file.Close();
631 }
632 #endif /*HAS_FILESYSTEM_RAR*/