disable the unrecognized nls and x flags
[AROS-Contrib.git] / FryingPan / DTLib / rSplitISOData.cpp
blob0e3131eb88b96a1375e32df06572a1123615fa8e
1 /*
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
4 *
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.
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 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);
38 return pSkel;
41 rSplitISOData::rSplitISOData(const char *sName, EDtError &rc)
43 rc = DT_OK;
44 sFileName = sName;
45 memset(&item, 0, sizeof(item));
47 sector_size = 0;
48 sector_count = 0;
49 num_parts = 0;
50 current_file = 0;
52 if (false == readDescriptor(rc))
54 sector_count = 0;
55 sector_size = 0;
59 rSplitISOData::~rSplitISOData()
61 for (int i=0; i<descs.Count(); i++)
62 delete descs[i];
63 cleanUp();
66 bool rSplitISOData::checkFile(const char* sFile, EDtError &rc)
68 bool res = false;
69 FileInfoBlock *b = new FileInfoBlock;
71 BPTR l = DOS->Lock((char*)sFile, ACCESS_READ);
73 if (l != 0)
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)
83 XMLDocument xdoc;
85 if (true == xdoc.ReadXML(sFile))
87 if (xdoc.GetName() == "SplitISOInfo")
89 res = true;
90 rc = DT_OK;
95 else
96 rc = DT_UnableToOpenFile;
98 DOS->UnLock(l);
100 else
101 rc = DT_UnableToOpenFile;
103 delete b;
105 return res;
108 bool rSplitISOData::readDescriptor(EDtError &rc)
110 XMLDocument xdoc;
111 XMLAttribute *elem;
113 xdoc.ReadXML(sFileName.Data());
115 sector_size = 0;
116 elem = xdoc.FindAttribute("SectorSize");
117 if (elem != 0)
119 sector_size = elem->GetValue().ToLong();
122 sector_count = 0;
123 elem = xdoc.FindAttribute("SectorCount");
124 if (elem != 0)
126 sector_count = elem->GetValue().ToLong();
129 num_parts = 0;
130 elem = xdoc.FindAttribute("NumParts");
131 if (elem != 0)
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");
148 if (elem != 0)
149 pdesc->md5sum = elem->GetValue();
151 elem = xel->FindAttribute("PartName");
152 if (elem != 0)
153 pdesc->fileName = elem->GetValue();
155 elem = xel->FindAttribute("PartSize");
156 if (elem != 0)
157 pdesc->sectors = elem->GetValue().ToLong();
159 descs << pdesc;
161 if (validatePart(pdesc) == 0)
163 rc = DT_FileMalformed;
164 return false;
170 rc = DT_OK;
171 return true;
174 bool rSplitISOData::validatePart(PartDescriptor *pdesc)
176 BPTR fh;
177 uint8 *mem;
178 SumMD5 sum;
179 uint32 sval[4];
180 int len;
181 String sstr;
182 bool res = false;
184 fh = DOS->Open(pdesc->fileName.Data(), MODE_OLDFILE);
185 if (0 != fh)
187 mem = new uint8[CHECK_FIRST_CNT * sector_size];
188 if (0 != mem)
190 len = DOS->Read(fh, mem, CHECK_FIRST_CNT * sector_size);
191 if (len > 0)
193 sum.Initialize();
194 sum.Update(mem, len);
195 sum.Finalize();
197 sum.GetSum(sval);
198 sstr.FormatStr("%08lx%08lx%08lx%08lx", ARRAY(sval[0], sval[1], sval[2], sval[3]));
200 if (sstr == pdesc->md5sum)
202 res = true;
205 delete [] mem;
207 DOS->Close(fh);
210 return res;
213 const char *rSplitISOData::static_getName()
215 return "Split ISO Data Track";
218 bool rSplitISOData::static_isAudio()
220 return false;
223 bool rSplitISOData::static_isData()
225 return true;
228 bool rSplitISOData::static_isSession()
230 return false;
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)
255 int32 len;
257 ASSERT(pBuff != 0);
258 ASSERT(pLen != 0);
259 if ((pBuff == 0) || (pLen == 0))
260 return false;
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;
271 ASSERT(len > 0);
273 ASSERT(0 != current_file);
274 if (current_file != 0)
276 DOS->Read(current_file, pBuff, len * sector_size);
278 else
280 return false;
283 pLen -= len;
284 current_pos += len;
286 if (current_pos >= current_size)
288 if (current_file)
289 DOS->Close(current_file);
291 current_file = 0;
292 current_pos = 0;
293 current_elem++;
296 if (pLen > 0)
297 return readData(item, &((char*)pBuff)[len * sector_size], pLen);
299 return true;
302 bool rSplitISOData::setUp()
304 current_file = 0;
305 current_pos = 0;
306 current_size = 0;
307 current_elem = 0;
308 return true;
311 void rSplitISOData::cleanUp()
313 if (current_file != 0)
315 DOS->Close(current_file);
317 current_file = 0;
320 void rSplitISOData::dispose()
322 delete this;
325 unsigned long rSplitISOData::getBlockCount()
327 return sector_count;
330 unsigned short rSplitISOData::getBlockSize()
332 return sector_size;
335 bool rSplitISOData::fillOptItem(IOptItem *item)
337 item->setDataType(Data_Mode1);
338 item->setDataBlockCount(sector_count);
339 item->setSectorSize(2048);
341 return true;
344 // vim: ts=3 et