2 * FryingPan - Amiga CD/DVD Recording Software (User Interface and supporting Libraries only)
3 * Copyright (C) 2001-2011 Tomasz Wiszkowski Tomasz.Wiszkowski at gmail.com
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public License
7 * as published by the Free Software Foundation; either version 2.1
8 * of the License, or (at your option) any later version.
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 Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 #include "rSplitISOData.h"
21 #include <libclass/dos.h>
22 #include <libclass/exec.h>
23 #include <libclass/utility.h>
24 #include <exec/lists.h>
25 #include <Generic/HookT.h>
26 #include <Generic/XMLDocument.h>
27 #include <Generic/SumMD5.h>
29 #define CHECK_FIRST_CNT 64
31 IFileReader
*rSplitISOData::openRead(const char* sFile
, EDtError
&rc
)
33 rSplitISOData
*pSkel
= 0;
34 if (true == checkFile(sFile
, rc
))
36 pSkel
= new rSplitISOData(sFile
, rc
);
41 rSplitISOData::rSplitISOData(const char *sName
, EDtError
&rc
)
45 memset(&item
, 0, sizeof(item
));
52 if (false == readDescriptor(rc
))
59 rSplitISOData::~rSplitISOData()
61 for (int i
=0; i
<descs
.Count(); i
++)
66 bool rSplitISOData::checkFile(const char* sFile
, EDtError
&rc
)
69 FileInfoBlock
*b
= new FileInfoBlock
;
71 BPTR l
= DOS
->Lock((char*)sFile
, ACCESS_READ
);
75 if (DOS
->Examine(l
, b
))
77 // our files should never grow any larger :P
79 rc
= DT_InvalidFormat
;
81 if (b
->fib_Size
< 4*1024)
85 if (true == xdoc
.ReadXML(sFile
))
87 if (xdoc
.GetName() == "SplitISOInfo")
96 rc
= DT_UnableToOpenFile
;
101 rc
= DT_UnableToOpenFile
;
108 bool rSplitISOData::readDescriptor(EDtError
&rc
)
113 xdoc
.ReadXML(sFileName
.Data());
116 elem
= xdoc
.FindAttribute("SectorSize");
119 sector_size
= elem
->GetValue().ToLong();
123 elem
= xdoc
.FindAttribute("SectorCount");
126 sector_count
= elem
->GetValue().ToLong();
130 elem
= xdoc
.FindAttribute("NumParts");
133 num_parts
= elem
->GetValue().ToLong();
136 for (int i
=0; i
<num_parts
; i
++)
138 for (int j
=0; j
<xdoc
.GetChildrenCount(); j
++)
140 XMLElement
*xel
= xdoc
.GetChild(j
);
142 elem
= xel
->FindAttribute("PartNumber");
143 if ((0 != elem
) && (elem
->GetValue().ToLong() == i
))
145 PartDescriptor
*pdesc
= new PartDescriptor
;
147 elem
= xel
->FindAttribute("MD5Sum");
149 pdesc
->md5sum
= elem
->GetValue();
151 elem
= xel
->FindAttribute("PartName");
153 pdesc
->fileName
= elem
->GetValue();
155 elem
= xel
->FindAttribute("PartSize");
157 pdesc
->sectors
= elem
->GetValue().ToLong();
161 if (validatePart(pdesc
) == 0)
163 rc
= DT_FileMalformed
;
174 bool rSplitISOData::validatePart(PartDescriptor
*pdesc
)
184 fh
= DOS
->Open(pdesc
->fileName
.Data(), MODE_OLDFILE
);
187 mem
= new uint8
[CHECK_FIRST_CNT
* sector_size
];
190 len
= DOS
->Read(fh
, mem
, CHECK_FIRST_CNT
* sector_size
);
194 sum
.Update(mem
, len
);
198 sstr
.FormatStr("%08lx%08lx%08lx%08lx", ARRAY(sval
[0], sval
[1], sval
[2], sval
[3]));
200 if (sstr
== pdesc
->md5sum
)
213 const char *rSplitISOData::static_getName()
215 return "Split ISO Data Track";
218 bool rSplitISOData::static_isAudio()
223 bool rSplitISOData::static_isData()
228 bool rSplitISOData::static_isSession()
233 bool rSplitISOData::isAudio()
235 return static_isAudio();
238 bool rSplitISOData::isData()
240 return static_isData();
243 const char *rSplitISOData::getName()
245 return static_getName();
248 const char* rSplitISOData::getTrackName()
250 return sFileName
.Data();
253 bool rSplitISOData::readData(const IOptItem
* item
, void* pBuff
, int pLen
)
259 if ((pBuff
== 0) || (pLen
== 0))
262 if (0 == current_file
)
264 current_file
= DOS
->Open(descs
[current_elem
]->fileName
.Data(), MODE_OLDFILE
);
265 current_size
= descs
[current_elem
]->sectors
;
268 len
= current_size
- current_pos
;
269 len
= len
< pLen
? len
: pLen
;
273 ASSERT(0 != current_file
);
274 if (current_file
!= 0)
276 DOS
->Read(current_file
, pBuff
, len
* sector_size
);
286 if (current_pos
>= current_size
)
289 DOS
->Close(current_file
);
297 return readData(item
, &((char*)pBuff
)[len
* sector_size
], pLen
);
302 bool rSplitISOData::setUp()
311 void rSplitISOData::cleanUp()
313 if (current_file
!= 0)
315 DOS
->Close(current_file
);
320 void rSplitISOData::dispose()
325 uint32
rSplitISOData::getBlockCount()
330 uint16
rSplitISOData::getBlockSize()
335 bool rSplitISOData::fillOptItem(IOptItem
*item
)
337 item
->setDataType(Data_Mode1
);
338 item
->setDataBlockCount(sector_count
);
339 item
->setSectorSize(2048);