コード例 #1
0
ファイル: DEHT.c プロジェクト: itn0x2e/TestProj21218
DEHT * create_empty_DEHT(const char *prefix,
                        hashKeyIntoTableFunctionPtr hashfun, hashKeyforEfficientComparisonFunctionPtr validfun,
                        const char *dictName,
                        int numEntriesInHashTable, int nPairsPerBlock, int nBytesPerKey,
			int nUserBytes)
{
	bool_t errorState = FALSE;

	DEHT * ht = NULL;

	TRACE_FUNC_ENTRY();

	/* sanity */
	CHECK(0 != numEntriesInHashTable);
	CHECK(0 != nPairsPerBlock);
	CHECK(0 != nBytesPerKey);

	ht = DEHT_initInstance(prefix, "c+b", hashfun, validfun);
	CHECK(NULL != ht);

	/* Do extra inits */
	ht->header.magic = DEHT_HEADER_MAGIC;
	SAFE_STRNCPY(ht->header.sDictionaryName, dictName, sizeof(ht->header.sDictionaryName));
	ht->header.numEntriesInHashTable = numEntriesInHashTable;
	ht->header.nPairsPerBlock = nPairsPerBlock;
	ht->header.nBytesPerValidationKey = nBytesPerKey;
	ht->header.numUnrelatedBytesSaved = nUserBytes;

	/* write header to disk */
	CHECK_MSG(ht->sKeyfileName, (1 == fwrite(&(ht->header), sizeof(ht->header), 1, ht->keyFP)));

	/* write (empty) pointer table to disk */
	CHECK_MSG(ht->sKeyfileName, (growFile(ht->keyFP, sizeof(DEHT_DISK_PTR) * numEntriesInHashTable)));

	/* write (empty) user data to disk */
	CHECK_MSG(ht->sKeyfileName, (growFile(ht->dataFP, ht->header.numUnrelatedBytesSaved)));



	goto LBL_CLEANUP;	

LBL_ERROR:
	errorState = TRUE;
	TRACE_FUNC_ERROR();

LBL_CLEANUP:
	if (errorState) {
		if (NULL != ht) {
			DEHT_freeResources(ht, TRUE);
			ht = NULL;
		}
	}

	TRACE_FUNC_EXIT();

	return ht;
}
コード例 #2
0
ファイル: MemStream.cpp プロジェクト: lorichen/xgame
bool MemoryStream::seek(int offset, uint from) 
{
	Assert(from == SEEK_SET || from == SEEK_CUR || from == SEEK_END);

	int64 newPos = m_pos;

	if (from == SEEK_SET)
		newPos = offset;
	else if (from == SEEK_CUR)
		newPos += offset;
	else if (from == SEEK_END)
		newPos = m_fileSize + offset;	
	else
		return false;

	if (newPos < 0) // bad seek
		return false;

	if (static_cast<uint>(newPos) > m_fileSize) // 超过文件大小
	{
		if (m_growBytes == 0)
			return false;

		growFile((uint)newPos);
	}

	m_pos = (uint)newPos;

	return true;
}
コード例 #3
0
ファイル: MemStream.cpp プロジェクト: lorichen/xgame
bool MemoryStream::write(const void* buffer, uint toWrite)
{
	Assert(buffer != NULL);
	if (buffer == NULL || toWrite == 0) 
		return false;

	if (m_pos + toWrite > m_bufSize)
	{
		if (m_growBytes == 0)
			return false;

		growFile(m_pos + toWrite);
	}

	Assert(m_pos + toWrite <= m_bufSize); // growFile success ?

	__memcpy((uchar*)m_buffer + m_pos, (uchar*)buffer, toWrite);

	m_pos += toWrite;

	if (m_pos > m_fileSize)
		m_fileSize = m_pos;

	return true;
}
コード例 #4
0
ファイル: mmapfile.cpp プロジェクト: dreamsxin/ktorrent
    Uint32 MMapFile::write(const void* buf, Uint32 buf_size)
    {
        if (!fptr || mode == QIODevice::ReadOnly)
            return 0;

        // check if data fits in memory mapping
        if (ptr + buf_size > size)
            throw Error(i18n("Cannot write beyond end of the mmap buffer."));

        Out(SYS_GEN | LOG_DEBUG) << "MMapFile::write : " << (ptr + buf_size) << " " << file_size << endl;
        // enlarge the file if necessary
        if (ptr + buf_size > file_size)
        {
            growFile(ptr + buf_size);
        }

        // memcpy data
        memcpy(&data[ptr], buf, buf_size);
        // update ptr
        ptr += buf_size;
        // update file size if necessary
        if (ptr >= size)
            size = ptr;

        return buf_size;
    }
コード例 #5
0
ファイル: DEHT.c プロジェクト: itn0x2e/TestProj21218
static DEHT_DISK_PTR DEHT_allocKeyBlock(DEHT * ht)
{
	DEHT_DISK_PTR newBlock  = 0;

	TRACE_FUNC_ENTRY();

	CHECK(NULL != ht);

	/* this is the first block - use the end of the file */
	(void) fflush(ht->keyFP);
	CHECK(0 == fseek(ht->keyFP, 0, SEEK_END));
	newBlock = ftell(ht->keyFP);
	
	/* alloc an empty block (init to NULLs) */
	CHECK(growFile(ht->keyFP, KEY_FILE_BLOCK_SIZE(ht)));

	TRACE_FPRINTF((stderr, "TRACE: %s:%d (%s): allocated a block at %#x\n", __FILE__, __LINE__, __FUNCTION__, (uint_t) newBlock));

	goto LBL_CLEANUP;

LBL_ERROR:
	newBlock = 0;
	TRACE_FUNC_ERROR();

LBL_CLEANUP:
	TRACE_FUNC_EXIT();
	return newBlock;
}
コード例 #6
0
void CacheFile::write(const Uint8* buf,Uint32 size,Uint64 off)
{
    QMutexLocker lock(&mutex);
    bool close_again = false;

    // reopen the file if necessary
    if (fd == -1)
    {
        //	Out() << "Reopening " << path << endl;
        openFile(RW);
        close_again = true;
    }

    if (read_only)
        throw Error(i18n("Cannot open %1 for writing : readonly filesystem").arg(path));

    if (off + size > max_size)
    {
        Out() << "Warning : writing past the end of " << path << endl;
        Out() << (off + size) << " " << max_size << endl;
    }

    if (file_size < off)
    {
        //Out() << QString("Writing %1 bytes at %2").arg(size).arg(off) << endl;
        growFile(off - file_size);
    }

    // jump to right position
    SeekFile(fd,(Int64)off,SEEK_SET);
    int ret = ::write(fd,buf,size);
    if (close_again)
        closeTemporary();

    if (ret == -1)
        throw Error(i18n("Error writing to %1 : %2").arg(path).arg(strerror(errno)));
    else if ((Uint32)ret != size)
    {
        Out() << QString("Incomplete write of %1 bytes, should be %2").arg(ret).arg(size) << endl;
        throw Error(i18n("Error writing to %1").arg(path));
    }

    if (off + size > file_size)
        file_size = off + size;
}
コード例 #7
0
ファイル: cachefile.cpp プロジェクト: KDE/libktorrent
	void CacheFile::write(const Uint8* buf,Uint32 size,Uint64 off)
	{
		QMutexLocker lock(&mutex);
		bool close_again = false;
		
		// reopen the file if necessary
		if (!fptr)
		{
		//	Out(SYS_DIO|LOG_DEBUG) << "Reopening " << path << endl;
			openFile(RW);
			close_again = true;
		}
		
		if (read_only)
			throw Error(i18n("Cannot open %1 for writing: readonly filesystem",path));
		
		if (off + size > max_size)
		{
			Out(SYS_DIO|LOG_DEBUG) << "Warning : writing past the end of " << path << endl;
			Out(SYS_DIO|LOG_DEBUG) << (off + size) << " " << max_size << endl;
			throw Error(i18n("Attempting to write beyond the maximum size of %1",path));
		}
		
		if (file_size < off)
		{
			//Out(SYS_DIO|LOG_DEBUG) << QString("Writing %1 bytes at %2").arg(size).arg(off) << endl;
			growFile(off - file_size);
		}
		
		
		// jump to right position
		if (!fptr->seek(off))
			throw Error(i18n("Failed to seek file %1: %2",path,fptr->errorString()));
		
		if (fptr->write((const char*)buf,size) != size)
		{
			throw Error(i18n("Failed to write to file %1: %2",path,fptr->errorString()));
		}
		
		if (close_again)
			closeTemporary();
	
		if (off + size > file_size)
			file_size = off + size;
	}
コード例 #8
0
ファイル: MemStream.cpp プロジェクト: lorichen/xgame
bool MemoryStream::setLength(uint newLen)
{
	Assert(newLen <= 0xffffffffUL);

	if (newLen > m_bufSize)
	{
		if (m_growBytes == 0)
			return false;

		growFile(newLen);
	}

	if (newLen < m_pos)
		m_pos = newLen;

	m_fileSize = newLen;
	return true;
}
コード例 #9
0
void* CacheFile::map(MMappeable* thing,Uint64 off,Uint32 size,Mode mode)
{
    QMutexLocker lock(&mutex);
    // reopen the file if necessary
    if (fd == -1)
    {
        //	Out() << "Reopening " << path << endl;
        openFile(mode);
    }

    if (read_only && mode != READ)
    {
        throw Error(i18n("Cannot open %1 for writing : readonly filesystem").arg(path));
    }

    if (off + size > max_size)
    {
        Out() << "Warning : writing past the end of " << path << endl;
        Out() << (off + size) << " " << max_size << endl;
        return 0;
    }

    int mmap_flag = 0;
    switch (mode)
    {
    case READ:
        mmap_flag = PROT_READ;
        break;
    case WRITE:
        mmap_flag = PROT_WRITE;
        break;
    case RW:
        mmap_flag = PROT_READ|PROT_WRITE;
        break;
    }

    if (off + size > file_size)
    {
        Uint64 to_write = (off + size) - file_size;
        //	Out() << "Growing file with " << to_write << " bytes" << endl;
        growFile(to_write);
    }

    Uint32 page_size = sysconf(_SC_PAGESIZE);
    if (off % page_size > 0)
    {
        // off is not a multiple of the page_size
        // so we play around a bit
        Uint32 diff = (off % page_size);
        Uint64 noff = off - diff;
        //	Out() << "Offsetted mmap : " << diff << endl;
#if HAVE_MMAP64
        char* ptr = (char*)mmap64(0, size + diff, mmap_flag, MAP_SHARED, fd, noff);
#else
        char* ptr = (char*)mmap(0, size + diff, mmap_flag, MAP_SHARED, fd, noff);
#endif
        if (ptr == MAP_FAILED)
        {
            Out() << "mmap failed : " << QString(strerror(errno)) << endl;
            return 0;
        }
        else
        {
            CacheFile::Entry e;
            e.thing = thing;
            e.offset = off;
            e.diff = diff;
            e.ptr = ptr;
            e.size = size + diff;
            e.mode = mode;
            mappings.insert((void*)(ptr + diff),e);
            return ptr + diff;
        }
    }
    else
    {
#if HAVE_MMAP64
        void* ptr = mmap64(0, size, mmap_flag, MAP_SHARED, fd, off);
#else
        void* ptr = mmap(0, size, mmap_flag, MAP_SHARED, fd, off);
#endif
        if (ptr == MAP_FAILED)
        {
            Out() << "mmap failed : " << QString(strerror(errno)) << endl;
            return 0;
        }
        else
        {
            CacheFile::Entry e;
            e.thing = thing;
            e.offset = off;
            e.ptr = ptr;
            e.diff = 0;
            e.size = size;
            e.mode = mode;
            mappings.insert(ptr,e);
            return ptr;
        }
    }
}
コード例 #10
0
ファイル: cachefile.cpp プロジェクト: KDE/libktorrent
	void* CacheFile::map(MMappeable* thing,Uint64 off,Uint32 size,Mode mode)
	{
		QMutexLocker lock(&mutex);
		// reopen the file if necessary
		if (!fptr)
		{
		//	Out(SYS_DIO|LOG_DEBUG) << "Reopening " << path << endl;
			QStorageInfo mount(path); //ntfs cannot handle mmap properly
			if (!OpenFileAllowed() || mount.fileSystemType()=="fuseblk" || mount.fileSystemType().startsWith("ntfs"))
				return 0; // Running out of file descriptors, force buffered mode
			openFile(mode);
		}
		
		if (read_only && mode != READ)
		{
			throw Error(i18n("Cannot open %1 for writing: readonly filesystem",path));
		}
		
		if (off + size > max_size)
		{
			Out(SYS_DIO|LOG_DEBUG) << "Warning : writing past the end of " << path << endl;
			Out(SYS_DIO|LOG_DEBUG) << (off + size) << " " << max_size << endl;
			throw Error(i18n("Attempting to write beyond the maximum size of %1",path));
		}
		
		/*
		if (!read_only && (mode == WRITE || mode == RW) && !allocateBytes(off,size))
			throw Error(i18n("Not enough free disk space for %1",path));
		*/
		
		int mmap_flag = 0;
		switch (mode)
		{
			case READ:
				mmap_flag = PROT_READ;
				break;
			case WRITE:
				mmap_flag = PROT_WRITE;
				break;
			case RW:
				mmap_flag = PROT_READ|PROT_WRITE;
				break;
		}
		
		if (off + size > file_size)
		{
			Uint64 to_write = (off + size) - file_size;
		//	Out(SYS_DIO|LOG_DEBUG) << "Growing file with " << to_write << " bytes" << endl;
			growFile(to_write);
		}
		
#ifndef Q_WS_WIN
		int fd = fptr->handle();
		Uint32 page_size = sysconf(_SC_PAGESIZE);
		if (off % page_size > 0)
		{
			// off is not a multiple of the page_size
			// so we play around a bit
			Uint32 diff = (off % page_size);
			Uint64 noff = off - diff;
		//	Out(SYS_DIO|LOG_DEBUG) << "Offsetted mmap : " << diff << endl;
#ifdef HAVE_MMAP64
			char* ptr = (char*)mmap64(0, size + diff, mmap_flag, MAP_SHARED, fd, noff);
#else
			char* ptr = (char*)mmap(0, size + diff, mmap_flag, MAP_SHARED, fd, noff);
#endif
			if (ptr == MAP_FAILED) 
			{
				Out(SYS_DIO|LOG_DEBUG) << "mmap failed : " << QString(strerror(errno)) << endl;
				return 0;
			}
			else
			{
				CacheFile::Entry e;
				e.thing = thing;
				e.offset = off;
				e.diff = diff;
				e.ptr = ptr;
				e.size = size + diff;
				e.mode = mode;
				mappings.insert((void*)(ptr + diff),e);
				return ptr + diff;
			}
		}
		else
		{
#ifdef HAVE_MMAP64
			void* ptr = mmap64(0, size, mmap_flag, MAP_SHARED, fd, off);
#else
			void* ptr = mmap(0, size, mmap_flag, MAP_SHARED, fd, off);
#endif
			if (ptr == MAP_FAILED) 
			{
				Out(SYS_DIO|LOG_DEBUG) << "mmap failed : " << QString(strerror(errno)) << endl;
				return 0;
			}
			else
			{
				CacheFile::Entry e;
				e.thing = thing;
				e.offset = off;
				e.ptr = ptr;
				e.diff = 0;
				e.size = size;
				e.mode = mode;
				mappings.insert(ptr,e);
				return ptr;
			}
		}
#else // Q_WS_WIN
		char* ptr = (char*)fptr->map(off,size);
		
		if (!ptr) 
		{
			Out(SYS_DIO|LOG_DEBUG) << "mmap failed3 : " << fptr->handle() << " " << QString(strerror(errno)) << endl;
			Out(SYS_DIO|LOG_DEBUG) << off << " " << size << endl;
			return 0;
		}
		else
		{
			CacheFile::Entry e;
			e.thing = thing;
			e.offset = off;
			e.ptr = ptr;
			e.diff = 0;
			e.size = size;
			e.mode = mode;
			mappings.insert(ptr,e);
			return ptr;
		}
#endif
	}
コード例 #11
0
/*
 * Write data to current position in file.
 * Return > 0 on success, < 0 on failure.
 */
int GOSFS_Write(struct File *file, void *buf, ulong_t numBytes) {
    GOSFSinstance *instance = (GOSFSinstance *) file->mountPoint->fsData;
    GOSFSptr *filePtr = (GOSFSptr *) file->fsData;
    GOSFSdirectory *dir;
    ulong_t start = file->filePos, endPos = file->endPos;
    ulong_t seekPos, vblock, offset, length;
    int rc, physBlock;
    char *blockBuf;

    /* Do we even have write access? Is numBytes valid? */
    if (!(file->mode & O_WRITE) || numBytes > INT_MAX
            || filePtr->node.isDirectory)
        return EINVALID;

    blockBuf = Malloc(GOSFS_BLOCK_SIZE);
    if (!blockBuf)
        goto memfail;

    seekPos = start;
    while (numBytes) {
        vblock = seekPos / GOSFS_BLOCK_SIZE;
        offset = seekPos % GOSFS_BLOCK_SIZE;
        length = GOSFS_BLOCK_SIZE - offset;
        if (numBytes < length)
            length = numBytes;

        /* Do we need to allocate a new block? */
        if (offset == 0 && seekPos >= file->endPos) {
            /* We should grow the file */
            physBlock = growFile(file);
            if (physBlock < 0)
                goto fail;
        } else {
            physBlock = getPhysicalBlockNum(instance, &filePtr->node, vblock);
        }

        /* Next read in block into buffer */
        rc = readGOSFSBlock(instance->dev, physBlock, blockBuf,
                GOSFS_BLOCK_SIZE);
        if (rc < 0)
            goto fail;

        /* Memcpy() over to replace buffer data */
        memcpy(blockBuf + offset, buf, length);

        /* Write out buffer back to disk */
        rc = writeGOSFSBlock(instance->dev, physBlock, blockBuf,
                GOSFS_BLOCK_SIZE);
        if (rc < 0)
            goto fail;

        /* Increment position */
        seekPos += length;
        buf += length;
        numBytes -= length;
        if (seekPos > file->endPos)
            file->endPos = seekPos;
    }

    /* Update the file position */
    file->filePos = seekPos;

    /* We may need to update the file size */
    if (endPos < file->endPos) {
        filePtr->node.size = file->endPos;

        dir = (GOSFSdirectory *) blockBuf;
        /* Now update file node on disk */
        rc = readGOSFSBlock(instance->dev, filePtr->blockNum, dir,
                sizeof(GOSFSdirectory));
        if (rc < 0)
            goto fail;
        memcpy(&dir->files[filePtr->offset], &filePtr->node,
                sizeof(GOSFSfileNode));
        rc = writeGOSFSBlock(instance->dev, filePtr->blockNum, dir,
                sizeof(GOSFSdirectory));
    }

    Free(blockBuf);

    return seekPos - start;

    memfail: rc = ENOMEM;
    goto fail;
    fail: if (blockBuf)
        Free(blockBuf);
    return rc;
}