Пример #1
0
		void teCompressFile(const teString & from, const teString & to, u32 chunkSize, c8 * chunkInputBuffer, u32 chunkInputBufferSize, c8 * chunkOutputBuffer, u32 chunkOutputBufferSize, u1 highCompression, u1 localPath)
		{
			TE_ASSERT(chunkInputBufferSize >= chunkSize);
			TE_ASSERT(chunkOutputBufferSize >= LZ4_compressBound(chunkSize));

			teLZ4CompressionFunction compressionFunction = highCompression ? LZ4_compressHC : LZ4_compress;

			IBuffer * fileInput = GetFileManager()->OpenFile(from, CFileBuffer::FWM_READ, localPath);

			if(!fileInput)
				return;

			IBuffer * fileOutput = GetFileManager()->OpenFile(to, CFileBuffer::FWM_WRITE, localPath);

			if(!fileOutput)
			{
				TE_SAFE_DROP(fileInput);
				return;
			}

			fileInput->SetStreamMode(true);
			fileOutput->SetStreamMode(true);

			fileInput->Lock(BLT_READ);
			fileInput->SetPosition(0);

			fileOutput->Lock(BLT_WRITE);
			fileOutput->SetPosition(0);

			u32 magicNumber = ARCHIVE_MAGICNUMBER;
			fileOutput->Write(&magicNumber, ARCHIVE_MAGICNUMBER_SIZE);

			c8 * inBuffer = chunkInputBuffer;
			c8 * outBuffer = chunkOutputBuffer;

			u32 fileSize = 0;

			while(true)
			{
				u32 inSize = teMin(chunkSize, fileInput->GetSize() - fileInput->GetPosition());
				fileInput->Read(inBuffer, inSize);
				fileSize += inSize;

				if(!inSize)
					break;

				u32 outSize = compressionFunction(inBuffer, outBuffer + 4, inSize);
				*(u32*)outBuffer = outSize;

				fileOutput->Write(outBuffer, outSize + 4);
			}

			fileInput->Unlock();
			fileOutput->Unlock();

			TE_SAFE_DROP(fileInput);
			TE_SAFE_DROP(fileOutput);
		}
Пример #2
0
		void teDecodeFile(const teString & from, const teString & to, u32 chunkSize, c8 * chunkInputBuffer, u32 chunkInputBufferSize, c8 * chunkOutputBuffer, u32 chunkOutputBufferSize, u1 localPath)
		{
			TE_ASSERT(chunkInputBufferSize >= LZ4_compressBound(chunkSize));
			TE_ASSERT(chunkOutputBufferSize >= chunkSize);

			IBuffer * fileInput = GetFileManager()->OpenFile(from, CFileBuffer::FWM_READ, localPath);

			if(!fileInput)
				return;

			IBuffer * fileOutput = GetFileManager()->OpenFile(to, CFileBuffer::FWM_WRITE, localPath);

			if(!fileOutput)
			{
				TE_SAFE_DROP(fileInput);
				return;
			}

			fileInput->SetStreamMode(true);
			fileOutput->SetStreamMode(true);

			fileInput->Lock(BLT_READ);
			fileInput->SetPosition(0);

			u32 magicNumber = u32Max;
			fileInput->Read(&magicNumber, ARCHIVE_MAGICNUMBER_SIZE);
			TE_ASSERT(magicNumber == ARCHIVE_MAGICNUMBER);

			fileOutput->Lock(BLT_WRITE);
			fileOutput->SetPosition(0);

			c8 * inBuffer = chunkInputBuffer;
			c8 * outBuffer = chunkOutputBuffer;

			while(true)
			{
				if((fileInput->GetSize() - fileInput->GetPosition()) < ARCHIVE_MAGICNUMBER_SIZE)
					break;

				u32 chunkSizeInFile;
				fileInput->Read(&chunkSizeInFile, sizeof(u32));

				if(chunkSizeInFile == ARCHIVE_MAGICNUMBER)
					continue;

				fileInput->Read(inBuffer, chunkSizeInFile);

				s32 outputSize = LZ4_uncompress_unknownOutputSize(inBuffer, outBuffer, chunkSizeInFile, chunkSize);

				if(outputSize < 0)
				{
					TE_LOG_ERR("lz4 decoding failed, corrupted input\n");

					fileInput->Unlock();
					fileOutput->Unlock();

					TE_SAFE_DROP(fileInput);
					TE_SAFE_DROP(fileOutput);

					return;
				}

				fileOutput->Write(outBuffer, (u32)outputSize);
			}

			fileInput->Unlock();
			fileOutput->Unlock();

			TE_SAFE_DROP(fileInput);
			TE_SAFE_DROP(fileOutput);
		}
Пример #3
0
ECode InputStreamReader::Read(
    /* [out] */ ArrayOf<Char32>* buffer,
    /* [in] */ Int32 offset,
    /* [in] */ Int32 count,
    /* [out] */ Int32* number)
{
    VALIDATE_NOT_NULL(number);
    *number = -1;
    VALIDATE_NOT_NULL(buffer);

    AutoLock lock(mLock);

    if (!IsOpen()) {
        Logger::E("InputStreamReader", "InputStreamReader is closed. E_IO_EXCEPTION");
        return E_IO_EXCEPTION;
    }
    FAIL_RETURN(Arrays::CheckOffsetAndCount(buffer->GetLength(), offset, count));
    if (count == 0) {
        *number = 0;
        return NOERROR;
    }

    AutoPtr<ICharBuffer> out;
    FAIL_RETURN(CharBuffer::Wrap(buffer, offset, count, (ICharBuffer**)&out));
    IBuffer* bout = IBuffer::Probe(out);
    AutoPtr<ICoderResult> UNDERFLOW, result;
    CCoderResult::GetUNDERFLOW((ICoderResult**)&UNDERFLOW);
    result = UNDERFLOW;

    // bytes.remaining() indicates number of bytes in buffer
    // when 1-st time entered, it'll be equal to zero
    Boolean hasRemaining, needInput;
    IBuffer* bBytes = IBuffer::Probe(mBytes);
    bBytes->HasRemaining(&hasRemaining);
    needInput = !hasRemaining;

    Int32 num = 0, position = 0;
    while (bout->HasRemaining(&hasRemaining), hasRemaining) {
        // fill the buffer if needed
        if (needInput) {
            mIn->Available(&num);
            bout->GetPosition(&position);
            if (num == 0 && position > offset) {
                // we could return the result without blocking read
                break;
            }

            Int32 capacity, limit, arrayOffset;
            bBytes->GetCapacity(&capacity);
            bBytes->GetLimit(&limit);
            bBytes->GetArrayOffset(&arrayOffset);
            Int32 desiredByteCount = capacity - limit;
            Int32 off = arrayOffset + limit;
            AutoPtr<ArrayOf<Byte> > buf;
            mBytes->GetArray((ArrayOf<Byte>**)&buf);
            Int32 actualByteCount;
            mIn->Read(buf, off, desiredByteCount, &actualByteCount);
            if (actualByteCount == -1) {
                mEndOfInput = TRUE;
                break;
            }
            else if (actualByteCount == 0) {
                break;
            }
            bBytes->SetLimit(limit + actualByteCount);
            needInput = FALSE;
        }

        // decode bytes
        result = NULL;
        mDecoder->Decode(mBytes, out, FALSE, (ICoderResult**)&result);
        Boolean isUnderflow;
        result->IsUnderflow(&isUnderflow);
        if (isUnderflow) {
            // compact the buffer if no space left
            Int32 capacity, limit;
            bBytes->GetLimit(&limit);
            bBytes->GetCapacity(&capacity);

            // compact the buffer if no space left
            if (limit == capacity) {
                mBytes->Compact();
                bBytes->GetPosition(&position);
                bBytes->SetLimit(position);
                bBytes->SetPosition(0);
            }
            needInput = TRUE;
        }
        else {
            break;
        }
    }

    if (result.Get() == UNDERFLOW.Get() && mEndOfInput) {
        result = NULL;
        mDecoder->Decode(mBytes, out, TRUE, (ICoderResult**)&result);
        if (result.Get() == UNDERFLOW.Get()) {
            AutoPtr<ICoderResult> resultFlush;
            mDecoder->Flush(out, (ICoderResult**)&resultFlush);
            result = resultFlush;
        }

        mDecoder->Reset();
    }

    Boolean isMalformed, isUnmappable;
    result->IsMalformed(&isMalformed);
    result->IsUnmappable(&isUnmappable);
    if (isMalformed || isUnmappable) {
        return result->ThrowException();
    }

    bout->GetPosition(&position);
    *number = position - offset == 0 ? -1 : position - offset;
    return NOERROR;
}