Ejemplo n.º 1
0
bool OleMainStream::readParagraphStyleTable(const char *headerBuffer, const OleEntry &tableEntry) {
	//PlcBtePapx structure is table with formatting for all paragraphs
	unsigned int beginParagraphInfo = OleUtil::getU4Bytes(headerBuffer, 0x102); // address of PlcBtePapx structure
	std::size_t paragraphInfoLength = (std::size_t)OleUtil::getU4Bytes(headerBuffer, 0x106); // length of PlcBtePapx structure
	if (paragraphInfoLength < 4) {
		return false;
	}

	OleStream tableStream(myStorage, tableEntry, myBaseStream);
	std::string buffer;
	if (!readToBuffer(buffer, beginParagraphInfo, paragraphInfoLength, tableStream)) {
		return false;
	}

	static const unsigned int PAPX_SIZE = 4;
	std::size_t size = calcCountOfPLC(paragraphInfoLength, PAPX_SIZE);

	std::vector<unsigned int> paragraphBlocks;
	for (std::size_t index = 0, tOffset = (size + 1) * 4; index < size; ++index, tOffset += PAPX_SIZE) {
		paragraphBlocks.push_back(OleUtil::getU4Bytes(buffer.c_str(), tOffset));
	}

	char *formatPageBuffer = new char[OleStorage::BBD_BLOCK_SIZE];
	for (std::size_t index = 0; index < paragraphBlocks.size(); ++index) {
		seek(paragraphBlocks.at(index) * OleStorage::BBD_BLOCK_SIZE, true);
		if (read(formatPageBuffer, OleStorage::BBD_BLOCK_SIZE) != OleStorage::BBD_BLOCK_SIZE) {
			return false;
		}
		const unsigned int paragraphsCount = OleUtil::getU1Byte(formatPageBuffer, 0x1ff); //offset with 'cpara' value (count of paragraphs)
		for (unsigned int index2 = 0; index2 < paragraphsCount; ++index2) {
			const unsigned int offset = OleUtil::getU4Bytes(formatPageBuffer, index2 * 4);
			unsigned int papxOffset = OleUtil::getU1Byte(formatPageBuffer, (paragraphsCount + 1) * 4 + index2 * 13) * 2;
			if (papxOffset <= 0) {
				continue;
			}
			unsigned int len = OleUtil::getU1Byte(formatPageBuffer, papxOffset) * 2;
			if (len == 0) {
				++papxOffset;
				len = OleUtil::getU1Byte(formatPageBuffer, papxOffset) * 2;
			}

			const unsigned int styleId = OleUtil::getU2Bytes(formatPageBuffer, papxOffset + 1);
			Style styleInfo = getStyleFromStylesheet(styleId, myStyleSheet);

			if (len >= 3) {
				getStyleInfo(papxOffset, formatPageBuffer + 3, len - 3, styleInfo);
			}

			unsigned int charPos = 0;
			if (!offsetToCharPos(offset, charPos, myPieces)) {
				continue;
			}
			myStyleInfoList.push_back(CharPosToStyle(charPos, styleInfo));
		}
	}
	delete[] formatPageBuffer;
	return true;
}
Ejemplo n.º 2
0
bool OleMainStream::readCharInfoTable(const char *headerBuffer, const OleEntry &tableEntry) {
	//PlcfbteChpx structure is table with formatting for particular run of text
	unsigned int beginCharInfo = OleUtil::getU4Bytes(headerBuffer, 0xfa); // address of PlcfbteChpx structure
	std::size_t charInfoLength = (std::size_t)OleUtil::getU4Bytes(headerBuffer, 0xfe); // length of PlcfbteChpx structure
	if (charInfoLength < 4) {
		return false;
	}

	OleStream tableStream(myStorage, tableEntry, myBaseStream);
	std::string buffer;
	if (!readToBuffer(buffer, beginCharInfo, charInfoLength, tableStream)) {
		return false;
	}

	static const unsigned int CHPX_SIZE = 4;
	std::size_t size = calcCountOfPLC(charInfoLength, CHPX_SIZE);
	std::vector<unsigned int> charBlocks;
	for (std::size_t index = 0, offset = (size + 1) * 4; index < size; ++index, offset += CHPX_SIZE) {
		charBlocks.push_back(OleUtil::getU4Bytes(buffer.c_str(), offset));
	}

	char *formatPageBuffer = new char[OleStorage::BBD_BLOCK_SIZE];
	for (std::size_t index = 0; index < charBlocks.size(); ++index) {
		seek(charBlocks.at(index) * OleStorage::BBD_BLOCK_SIZE, true);
		if (read(formatPageBuffer, OleStorage::BBD_BLOCK_SIZE) != OleStorage::BBD_BLOCK_SIZE) {
			return false;
		}
		unsigned int crun = OleUtil::getU1Byte(formatPageBuffer, 0x1ff); //offset with crun (count of 'run of text')
		for (unsigned int index2 = 0; index2 < crun; ++index2) {
			unsigned int offset = OleUtil::getU4Bytes(formatPageBuffer, index2 * 4);
			unsigned int chpxOffset = 2 * OleUtil::getU1Byte(formatPageBuffer, (crun + 1) * 4 + index2);
			unsigned int len = OleUtil::getU1Byte(formatPageBuffer, chpxOffset);
			unsigned int charPos = 0;
			if (!offsetToCharPos(offset, charPos, myPieces)) {
				continue;
			}
			unsigned int styleId = getStyleIdByCharPos(charPos, myStyleInfoList);

			CharInfo charInfo = getStyleFromStylesheet(styleId, myStyleSheet).CurrentCharInfo;
			if (chpxOffset != 0) {
				getCharInfo(chpxOffset, styleId, formatPageBuffer + 1, len - 1, charInfo);
			}
			myCharInfoList.push_back(CharPosToCharInfo(charPos, charInfo));

			if (chpxOffset != 0) {
				InlineImageInfo pictureInfo;
				if (getInlineImageInfo(chpxOffset, formatPageBuffer + 1, len - 1, pictureInfo)) {
					myInlineImageInfoList.push_back(CharPosToInlineImageInfo(charPos, pictureInfo));
				}
			}

		}
	}
	delete[] formatPageBuffer;
	return true;
}
Ejemplo n.º 3
0
bool OleMainStream::readFloatingImages(const char *headerBuffer, const OleEntry &tableEntry) {
	//Plcspa structure is a table with information for FSPA (File Shape Address)
	unsigned int beginPicturesInfo = OleUtil::getU4Bytes(headerBuffer, 0x01DA); // address of Plcspa structure
	if (beginPicturesInfo == 0) {
		return true; //there's no office art objects
	}
	unsigned int picturesInfoLength = OleUtil::getU4Bytes(headerBuffer, 0x01DE); // length of Plcspa structure
	if (picturesInfoLength < 4) {
		return false;
	}

	OleStream tableStream(myStorage, tableEntry, myBaseStream);
	std::string buffer;
	if (!readToBuffer(buffer, beginPicturesInfo, picturesInfoLength, tableStream)) {
		return false;
	}


	static const unsigned int SPA_SIZE = 26;
	size_t size = calcCountOfPLC(picturesInfoLength, SPA_SIZE);

	std::vector<unsigned int> picturesBlocks;
	for (size_t index = 0, tOffset = 0; index < size; ++index, tOffset += 4) {
		picturesBlocks.push_back(OleUtil::getU4Bytes(buffer.c_str(), tOffset));
	}

	for (size_t index = 0, tOffset = (size + 1) * 4; index < size; ++index, tOffset += SPA_SIZE) {
		unsigned int spid = OleUtil::getU4Bytes(buffer.c_str(), tOffset);
		FloatImageInfo info;
		unsigned int charPos = picturesBlocks.at(index);
		info.ShapeId = spid;
		myFloatImageInfoList.push_back(CharPosToFloatImageInfo(charPos, info));
	}

	//DggInfo structure is office art object table data
	unsigned int beginOfficeArtContent = OleUtil::getU4Bytes(headerBuffer, 0x22A); // address of DggInfo structure
	if (beginOfficeArtContent == 0) {
		return true; //there's no office art objects
	}
	unsigned int officeArtContentLength = OleUtil::getU4Bytes(headerBuffer, 0x022E); // length of DggInfo structure
	if (officeArtContentLength < 4) {
		return false;
	}

	shared_ptr<OleStream> newTableStream = new OleStream(myStorage, tableEntry, myBaseStream);
	shared_ptr<OleStream> newMainStream = new OleStream(myStorage, myOleEntry, myBaseStream);
	if (newTableStream->open() && newMainStream->open()) {
		myFLoatImageReader = new DocFloatImageReader(beginOfficeArtContent, officeArtContentLength, newTableStream, newMainStream);
		myFLoatImageReader->readAll();
	}
	return true;
}
Ejemplo n.º 4
0
bool OleMainStream::readSectionsInfoTable(const char *headerBuffer, const OleEntry &tableEntry) {
	//PlcfSed structure is a section table
	unsigned int beginOfText = OleUtil::getU4Bytes(headerBuffer, 0x18); //address of text's begin in main stream
	unsigned int beginSectInfo = OleUtil::getU4Bytes(headerBuffer, 0xca); //address if PlcfSed structure

	std::size_t sectInfoLen = (std::size_t)OleUtil::getU4Bytes(headerBuffer, 0xce); //length of PlcfSed structure
	if (sectInfoLen < 4) {
		return false;
	}

	OleStream tableStream(myStorage, tableEntry, myBaseStream);
	std::string buffer;
	if (!readToBuffer(buffer, beginSectInfo, sectInfoLen, tableStream)) {
		return false;
	}

	static const unsigned int SED_SIZE = 12;
	std::size_t decriptorsCount = calcCountOfPLC(sectInfoLen, SED_SIZE);

	//saving the section offsets (in character positions)
	std::vector<unsigned int> charPos;
	for (std::size_t index = 0, tOffset = 0; index < decriptorsCount; ++index, tOffset += 4) {
		unsigned int ulTextOffset = OleUtil::getU4Bytes(buffer.c_str(), tOffset);
		charPos.push_back(beginOfText + ulTextOffset);
	}

	//saving sepx offsets
	std::vector<unsigned int> sectPage;
	for (std::size_t index = 0, tOffset = (decriptorsCount + 1) * 4; index < decriptorsCount; ++index, tOffset += SED_SIZE) {
		sectPage.push_back(OleUtil::getU4Bytes(buffer.c_str(), tOffset + 2));
	}

	//reading the section properties
	char tmpBuffer[2];
	for (std::size_t index = 0; index < sectPage.size(); ++index) {
		if (sectPage.at(index) == 0xffffffffUL) { //check for invalid record, to make default section info
			SectionInfo sectionInfo;
			sectionInfo.CharPosition = charPos.at(index);
			mySectionInfoList.push_back(sectionInfo);
			continue;
		}
		//getting number of bytes to read
		if (!seek(sectPage.at(index), true)) {
			continue;
		}
		if (read(tmpBuffer, 2) != 2) {
			continue;
		}
		std::size_t bytes = 2 + (std::size_t)OleUtil::getU2Bytes(tmpBuffer, 0);

		if (!seek(sectPage.at(index), true)) {
			continue;
		}
		char *formatPageBuffer = new char[bytes];
		if (read(formatPageBuffer, bytes) != bytes) {
			delete[] formatPageBuffer;
			continue;
		}
		SectionInfo sectionInfo;
		sectionInfo.CharPosition = charPos.at(index);
		getSectionInfo(formatPageBuffer + 2, bytes - 2, sectionInfo);
		mySectionInfoList.push_back(sectionInfo);
		delete[] formatPageBuffer;
	}
	return true;
}
Ejemplo n.º 5
0
bool OleMainStream::readStylesheet(const char *headerBuffer, const OleEntry &tableEntry) {
	//STSH structure is a stylesheet
	unsigned int beginStshInfo = OleUtil::getU4Bytes(headerBuffer, 0xa2); // address of STSH structure
	std::size_t stshInfoLength = (std::size_t)OleUtil::getU4Bytes(headerBuffer, 0xa6); // length of STSH structure

	OleStream tableStream(myStorage, tableEntry, myBaseStream);
	char *buffer = new char[stshInfoLength];
	if (!tableStream.seek(beginStshInfo, true)) {
		ZLLogger::Instance().println("DocPlugin", "problems with reading STSH structure");
		return false;
	}
	if (tableStream.read(buffer, stshInfoLength) != stshInfoLength) {
		ZLLogger::Instance().println("DocPlugin", "problems with reading STSH structure, invalid length");
		return false;
	}

	std::size_t stdCount = (std::size_t)OleUtil::getU2Bytes(buffer, 2);
	std::size_t stdBaseInFile = (std::size_t)OleUtil::getU2Bytes(buffer, 4);
	myStyleSheet.resize(stdCount);

	std::vector<bool> isFilled;
	isFilled.resize(stdCount, false);

	std::size_t stdLen = 0;
	bool styleSheetWasChanged = false;
	do { //make it in while loop, because some base style can be after their successors
		styleSheetWasChanged = false;
		for (std::size_t index = 0, offset = 2 + (std::size_t)OleUtil::getU2Bytes(buffer, 0); index < stdCount; index++, offset += 2 + stdLen) {
			stdLen = (std::size_t)OleUtil::getU2Bytes(buffer, offset);
			if (isFilled.at(index)) {
				continue;
			}

			if (stdLen == 0) {
				//if record is empty, left it default
				isFilled[index] = true;
				continue;
			}

			Style styleInfo = myStyleSheet.at(index);

			const unsigned int styleAndBaseType = OleUtil::getU2Bytes(buffer, offset + 4);
			const unsigned int styleType = styleAndBaseType % 16;
			const unsigned int baseStyleId = styleAndBaseType / 16;
			if (baseStyleId == Style::STYLE_NIL || baseStyleId == Style::STYLE_USER) {
				//if based on nil or user style, left default
			} else {
				int baseStyleIndex = getStyleIndex(baseStyleId, isFilled, myStyleSheet);
				if (baseStyleIndex < 0) {
					//this base style is not filled yet, so pass it at some time
					continue;
				}
				styleInfo = myStyleSheet.at(baseStyleIndex);
				styleInfo.StyleIdCurrent = Style::STYLE_INVALID;
			}

			// parse STD structure
			unsigned int tmp = OleUtil::getU2Bytes(buffer, offset + 6);
			unsigned int upxCount = tmp % 16;
			styleInfo.StyleIdNext = tmp / 16;

			//adding current style
			myStyleSheet[index] = styleInfo;
			isFilled[index] = true;
			styleSheetWasChanged = true;

			std::size_t pos = 2 + stdBaseInFile;
			std::size_t nameLen = (std::size_t)OleUtil::getU2Bytes(buffer, offset + pos);
			nameLen = nameLen * 2 + 2; //from Unicode characters to bytes + Unicode null charachter length
			pos += 2 + nameLen;
			if (pos % 2 != 0) {
				++pos;
			}
			if (pos >= stdLen) {
				continue;
			}
			std::size_t upxLen = (std::size_t)OleUtil::getU2Bytes(buffer, offset + pos);
			if (pos + upxLen > stdLen) {
				//UPX length too large
				continue;
			}
			//for style info styleType must be equal 1
			if (styleType == 1 && upxCount >= 1) {
				if (upxLen >= 2) {
					styleInfo.StyleIdCurrent = OleUtil::getU2Bytes(buffer, offset + pos + 2);
					getStyleInfo(0, buffer + offset + pos + 4, upxLen - 2, styleInfo);
					myStyleSheet[index] = styleInfo;
				}
				pos += 2 + upxLen;
				if (pos % 2 != 0) {
					++pos;
				}
				upxLen = (std::size_t)OleUtil::getU2Bytes(buffer, offset + pos);
			}
			if (upxLen == 0 || pos + upxLen > stdLen) {
				//too small/too large
				continue;
			}
			//for char info styleType can be equal 1 or 2
			if ((styleType == 1 && upxCount >= 2) || (styleType == 2 && upxCount >= 1)) {
				CharInfo charInfo;
				getCharInfo(0, Style::STYLE_INVALID, buffer + offset + pos + 2, upxLen, charInfo);
				styleInfo.CurrentCharInfo = charInfo;
				myStyleSheet[index] = styleInfo;
			}
		}
	} while (styleSheetWasChanged);
	delete[] buffer;
	return true;
}
Ejemplo n.º 6
0
bool OleMainStream::readBookmarks(const char *headerBuffer, const OleEntry &tableEntry) {
	//SttbfBkmk structure is a table of bookmark name strings
	unsigned int beginNamesInfo = OleUtil::getU4Bytes(headerBuffer, 0x142); // address of SttbfBkmk structure
	std::size_t namesInfoLength = (std::size_t)OleUtil::getU4Bytes(headerBuffer, 0x146); // length of SttbfBkmk structure

	if (namesInfoLength == 0) {
		return true; //there's no bookmarks
	}

	OleStream tableStream(myStorage, tableEntry, myBaseStream);
	std::string buffer;
	if (!readToBuffer(buffer, beginNamesInfo, namesInfoLength, tableStream)) {
		return false;
	}

	unsigned int recordsNumber = OleUtil::getU2Bytes(buffer.c_str(), 0x2); //count of records

	std::vector<std::string> names;
	unsigned int offset = 0x6; //initial offset
	for (unsigned int i = 0; i < recordsNumber; ++i) {
		if (buffer.size() < offset + 2) {
			ZLLogger::Instance().println("DocPlugin", "problmes with reading bookmarks names");
			break;
		}
		unsigned int length = OleUtil::getU2Bytes(buffer.c_str(), offset) * 2; //length of string in bytes
		ZLUnicodeUtil::Ucs2String name;
		for (unsigned int j = 0; j < length; j+=2) {
			char ch1 = buffer.at(offset + 2 + j);
			char ch2 = buffer.at(offset + 2 + j + 1);
			ZLUnicodeUtil::Ucs2Char ucs2Char = (unsigned int)ch1 | ((unsigned int)ch2 << 8);
			name.push_back(ucs2Char);
		}
		std::string utf8Name;
		ZLUnicodeUtil::ucs2ToUtf8(utf8Name, name);
		names.push_back(utf8Name);
		offset += length + 2;
	}

	//plcfBkmkf structure is table recording beginning CPs of bookmarks
	unsigned int beginCharPosInfo = OleUtil::getU4Bytes(headerBuffer, 0x14A); // address of plcfBkmkf structure
	std::size_t charPosInfoLen = (std::size_t)OleUtil::getU4Bytes(headerBuffer, 0x14E); // length of plcfBkmkf structure

	if (charPosInfoLen == 0) {
		return true; //there's no bookmarks
	}

	if (!readToBuffer(buffer, beginCharPosInfo, charPosInfoLen, tableStream)) {
		return false;
	}

	static const unsigned int BKF_SIZE = 4;
	std::size_t size = calcCountOfPLC(charPosInfoLen, BKF_SIZE);
	std::vector<unsigned int> charPage;
	for (std::size_t index = 0, offset = 0; index < size; ++index, offset += 4) {
		charPage.push_back(OleUtil::getU4Bytes(buffer.c_str(), offset));
	}

	for (std::size_t i = 0; i < names.size(); ++i) {
		if (i >= charPage.size()) {
			break; //for the case if something in these structures goes wrong, to not to lose all bookmarks
		}
		Bookmark bookmark;
		bookmark.CharPosition = charPage.at(i);
		bookmark.Name = names.at(i);
		myBookmarks.push_back(bookmark);
	}

	return true;
}
Ejemplo n.º 7
0
bool OleMainStream::readPieceTable(const char *headerBuffer, const OleEntry &tableEntry) {
	OleStream tableStream(myStorage, tableEntry, myBaseStream);
	std::string piecesTableBuffer = getPiecesTableBuffer(headerBuffer, tableStream);

	if (piecesTableBuffer.empty()) {
		return false;
	}

	//getting count of Character Positions for different types of subdocuments in Main Stream
	int ccpText = OleUtil::get4Bytes(headerBuffer, 0x004C); //text
	int ccpFtn = OleUtil::get4Bytes(headerBuffer, 0x0050); //footnote subdocument
	int ccpHdd = OleUtil::get4Bytes(headerBuffer, 0x0054); //header subdocument
	int ccpMcr = OleUtil::get4Bytes(headerBuffer, 0x0058); //macro subdocument
	int ccpAtn = OleUtil::get4Bytes(headerBuffer, 0x005C); //comment subdocument
	int ccpEdn = OleUtil::get4Bytes(headerBuffer, 0x0060); //endnote subdocument
	int ccpTxbx = OleUtil::get4Bytes(headerBuffer, 0x0064); //textbox subdocument
	int ccpHdrTxbx = OleUtil::get4Bytes(headerBuffer, 0x0068); //textbox subdocument of the header
	int lastCP = ccpFtn + ccpHdd + ccpMcr + ccpAtn + ccpEdn + ccpTxbx + ccpHdrTxbx;
	if (lastCP != 0) {
		++lastCP;
	}
	lastCP += ccpText;

	//getting the CP (character positions) and CP descriptors
	std::vector<int> cp; //array of character positions for pieces
	unsigned int j = 0;
	for (j = 0; ; j += 4) {
		if (piecesTableBuffer.size() < j + 4) {
			ZLLogger::Instance().println("DocPlugin", "invalid piece table, cp ends not with a lastcp");
			break;
		}
		int curCP = OleUtil::get4Bytes(piecesTableBuffer.c_str(), j);
		cp.push_back(curCP);
		if (curCP == lastCP) {
			break;
		}
	}

	if (cp.size() < 2) {
		ZLLogger::Instance().println("DocPlugin", "invalid piece table, < 2 pieces");
		return false;
	}

	std::vector<std::string> descriptors;
	for (std::size_t k = 0; k < cp.size() - 1; ++k) {
		//j + 4, because it should be taken after CP in PiecesTable Buffer
		//k * 8, because it should be taken 8 byte for each descriptor
		std::size_t substrFrom = j + 4 + k * 8;
		if (piecesTableBuffer.size() < substrFrom + 8) {
			ZLLogger::Instance().println("DocPlugin", "invalid piece table, problems with descriptors reading");
			break;
		}
		descriptors.push_back(piecesTableBuffer.substr(substrFrom, 8));
	}

	//filling the Pieces vector
	std::size_t minValidSize = std::min(cp.size() - 1, descriptors.size());
	if (minValidSize == 0) {
		ZLLogger::Instance().println("DocPlugin", "invalid piece table, there are no pieces");
		return false;
	}

	for (std::size_t i = 0; i < minValidSize; ++i) {
		//4byte integer with offset and ANSI flag
		int fcValue = OleUtil::get4Bytes(descriptors.at(i).c_str(), 0x2); //offset for piece structure
		Piece piece;
		piece.IsANSI = (fcValue & 0x40000000) == 0x40000000; //ansi flag
		piece.Offset = fcValue & 0x3FFFFFFF; //gettting offset for current piece
		piece.Length = cp.at(i + 1) - cp.at(i);
		myPieces.push_back(piece);
	}

	//split pieces into different types
	Pieces piecesText, piecesFootnote, piecesOther;
	splitPieces(myPieces, piecesText, piecesFootnote, Piece::PIECE_TEXT, Piece::PIECE_FOOTNOTE, ccpText);
	splitPieces(piecesFootnote, piecesFootnote, piecesOther, Piece::PIECE_FOOTNOTE, Piece::PIECE_OTHER, ccpFtn);

	myPieces.clear();
	for (std::size_t i = 0; i < piecesText.size(); ++i) {
		myPieces.push_back(piecesText.at(i));
	}
	for (std::size_t i = 0; i < piecesFootnote.size(); ++i) {
		myPieces.push_back(piecesFootnote.at(i));
	}
	for (std::size_t i = 0; i < piecesOther.size(); ++i) {
		myPieces.push_back(piecesOther.at(i));
	}

	//converting length and offset depending on isANSI
	for (std::size_t i = 0; i < myPieces.size(); ++i) {
		Piece &piece = myPieces.at(i);
		if (!piece.IsANSI) {
			piece.Length *= 2;
		} else {
			piece.Offset /= 2;
		}
	}

	//filling startCP field
	unsigned int curStartCP = 0;
	for (std::size_t i = 0; i < myPieces.size(); ++i) {
		Piece &piece = myPieces.at(i);
		piece.startCP = curStartCP;
		if (piece.IsANSI) {
			curStartCP += piece.Length;
		} else {
			curStartCP += piece.Length / 2;
		}
	}
	return true;
}
Ejemplo n.º 8
0
bool HuffmanCoder::LoadHuffmanTableFromFile(const char* fileName)
{
    if (mDebug > kInfo) std::cout << "Huffman table will be loaded from file " << fileName << std::endl;
    if (mHuffmanTableExists) {
        if (mDebug > kWarning) std::cout << "WARNING: Huffman table is already available" << std::endl;
        return true;
    }

    std::ifstream tableStream(fileName,std::ios::in);
    if (tableStream.is_open()) {
        std::string temp;
        getline(tableStream,temp,'\n');

        // Skip first lines of file
        while (temp != "Huffman codes:") getline(tableStream,temp,'\n');

        int value = 0;
        int length = 0;
        float weight = 0;
        std::string code = "";
        std::string truncatedHuffmanMarkerCandidate = "";

        // read file and parse the lines
        do {
            // read line
            getline(tableStream,temp,'\n');

            // parse values
            value = atoi(temp.substr(temp.find("=")+1,temp.find("weight")).c_str());
            temp = temp.substr(temp.find("weight"));

            weight = atof(temp.substr(temp.find("=")+1,temp.find("length")).c_str());
            temp = temp.substr(temp.find("length"));

            length = atoi(temp.substr(temp.find("=")+1,temp.find("code")).c_str());
            temp = temp.substr(temp.find("code"));

            code = temp.substr(temp.find("=")+1);
            code = code.substr(code.size()-length);

//			// Look for raw data marker in file
//			if (value == 0 && weight != 0) {
//				mRawDataMarker = code;
//				mRawDataMarkerSize = code.size();
//			}

            // Store Huffman code in map
            HuffmanCode hCode(value, length, weight, code);
            if (mHuffmanTable.find(value) == mHuffmanTable.end()) {
                mHuffmanTable[value] = hCode;
            } else {
                if (mDebug > kWarning) std::cout << "WARNING: Huffman code for value " << value << " exists already in Huffman table" << std::endl;
            }

            // if Huffman code is short enough, it is stored in the truncated Huffman table
            if ((unsigned int) length <= mMaxCodeLength) {
                if (mTruncatedHuffmanTable.find(value) == mTruncatedHuffmanTable.end()) {
                    mTruncatedHuffmanTable[value] = hCode;
                } else {
                    if (mDebug > kWarning) std::cout << "WARNING: Huffman code for value " << value << " exists already in truncated Huffman table" << std::endl;
                }
            } else if ((unsigned int) length < truncatedHuffmanMarkerCandidate.size() || truncatedHuffmanMarkerCandidate.size() == 0) {
                // else, a possible marker is stored
                truncatedHuffmanMarkerCandidate = code;
            }
        } while ((unsigned int) value < (mHuffmanRange-1));

        // done, closing file, creating raw data marker if not found and return
        if (mDebug > kInfo) std::cout << "Reading of Huffman table done." << std::endl;
        tableStream.close();

        if (mRawDataMarkerSize == 0) {
            // if no raw data marker was found, one of the shortest codes which were thrown away
            // is used.
            mRawDataMarker = truncatedHuffmanMarkerCandidate;
            mRawDataMarkerSize = mRawDataMarker.size();
            if (mDebug > kWarning) std::cout << "WARNING: No raw data marker was found, it is set to " << mRawDataMarker << std::endl;
        }

        mHuffmanTableExists = true;

        mMapToUse = &mTruncatedHuffmanTable;
        mMarkerToUse = mRawDataMarker;
        mMarkerLengthToUse = mRawDataMarkerSize;

        return true;
    } else {
        if (mDebug > kError) std::cerr << "ERROR: Could not open file " << fileName << " to read the Huffman Table, no table is loaded!" << std::endl;
        return false;
    }
}