summaryrefslogtreecommitdiff
path: root/lib/qt-tar-xz/QTarDecode.cpp
blob: fe153599380821b6e39de93aaca08cfd0f16ef1e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/** \file QTarDecode.cpp
\brief To read a tar data block
\author alpha_one_x86
\version 0.3
\date 2010
\licence GPL3, see the file COPYING */

#include "QTarDecode.h"
#include <QDebug>

QTarDecode::QTarDecode()
{
	error="Unknow error";
}

QString QTarDecode::errorString()
{
	return error;
}

void QTarDecode::setErrorString(QString error)
{
	this->error=error;
	fileList.clear();
	dataList.clear();
}

bool QTarDecode::decodeData(QByteArray data)
{
	setErrorString("Unknow error");
	if(data.size()<1024)
		return false;
	int offset=0;
	while(offset<data.size())
	{
		//load the file name from ascii, from 0+offset with size of 100
		QString fileName=data.mid(0+offset,100);
		//load the file type
		QString fileType=data.mid(156+offset,1);
		//load the ustar string
		QString ustar=data.mid(257+offset,5);
		//load the ustar version
		QString ustarVersion=data.mid(263+offset,2);
		bool ok;
		//load the file size from ascii, from 124+offset with size of 12
		int finalSize=QString(data.mid(124+offset,12)).toUInt(&ok,8);
		//if the size conversion to qulonglong have failed, then qui with error
		if(ok==false)
		{
			//if((offset+1024)==data.size())
			//it's the end of the archive, no more verification
			break;
			/*else
			{
				setErrorString("Unable to convert ascii size at "+QString::number(124+offset)+" to usigned long long: \""+QString(data.mid(124+offset,12))+"\"");
				return false;
			}*/
		}
		//if check if the ustar not found
		if(ustar!="ustar")
		{
			setErrorString("\"ustar\" string not found at "+QString::number(257+offset)+", content: \""+ustar+"\"");
			return false;
		}
		if(ustarVersion!="00")
		{
			setErrorString("ustar version string is wrong, content:\""+ustarVersion+"\"");
			return false;
		}
		//check if the file have the good size for load the data
		if((offset+512+finalSize)>data.size())
		{
			setErrorString("The tar file seem be too short");
			return false;
		}
		if(fileType=="0") //this code manage only the file, then only the file is returned
		{
			QByteArray fileData=data.mid(512+offset,finalSize);
			fileList << fileName;
			dataList << fileData;
		}
		//calculate the offset for the next header
		bool retenu=((finalSize%512)!=0);
		//go to the next header
		offset+=512+(finalSize/512+retenu)*512;
	}
	if(fileList.size()>0)
	{
		QString baseDirToTest=fileList.at(0);
		baseDirToTest.remove(QRegExp("/.*$"));
		baseDirToTest+='/';
		bool isFoundForAllEntries=true;
		for (int i = 0; i < fileList.size(); ++i)
			if(!fileList.at(i).startsWith(baseDirToTest))
				isFoundForAllEntries=false;
		if(isFoundForAllEntries)
			for (int i = 0; i < fileList.size(); ++i)
				fileList[i].remove(0,baseDirToTest.size());
	}
	return true;
}

QStringList QTarDecode::getFileList()
{
	return fileList;
}

QList<QByteArray> QTarDecode::getDataList()
{
	return dataList;
}