Προς το περιεχόμενο

LinkedList μεσα σε αρχειο


Evgenios1

Προτεινόμενες αναρτήσεις

Δημοσ.

Γεια, εφτιαξα μια linkedlist, αυτη δουλευει ρολόι εκτος απο μια συναρτηση.

Πιο γενικα, ειναι μια κλαση μεσα σε ενα dll, export γινετε με dllexport/dllimport και το προβλημα ειναι με εναν iterator που δεν αλλαζει.

αυτο εδω

>int CLinkedFile::Next(void* obj,size_t& out_size)
{
if(this->m_first != this->m_last)
{
	this->Read(obj,(*this->m_first).size,(*this->m_first).pos);
	out_size = (*this->m_first).size;
	++(this->m_first);
	return true;
}
return false;
}

Στη γραμμη ++(this->m_first); ο iterator δεν αλλαζει για κανενα λογο. Αποτι ειδα, το προβλημα (warning c4251) εχει να κανει με τα clinet varables, αλλα δεν μπορω να καταλαβω τι ακρβος πρεπει να κανω.

 

Ολη η κλαση

header

>#pragma once
#ifndef _CLINKEDFILE_
#define _CLINKEDFILE_
#include <vector>
#include <algorithm>
#include <Windows.h>
using std::vector;
#ifndef DLLOUT
#pragma comment(lib,"iomgr.lib")
#endif
#define LF_STAMP {'L','i','n','k','e','d',' ','F','i','l','e',0x00,0x00,0x00,0x00,0x00}
#define LF_DATA_ENTERY 0x0000ffff
#define LF_IDX_BEGIN 120
struct LFIndexer
{
unsigned int id;
size_t       size;
size_t       ori_size;
long         pos;
int          is_free;
};
struct LFInfo
{
unsigned char stamp[16];
long          idx_begin;
unsigned int  idx_count;
long          data_entery;
};

class
#ifdef DLLOUT
__declspec(dllexport)
#else
__declspec(dllimport)
#endif
CLinkedFile
{
private:
HANDLE m_file;
LFInfo m_info;
#pragma warning(push)
#pragma warning(disable:4251)
vector<LFIndexer> m_idxs;
vector<LFIndexer>::iterator m_first,m_last;
#pragma warning(pop)
void CreateDefault();
LFIndexer GCGetIndexer(size_t);
void ReplaceIndexer(LFIndexer& ,LFIndexer& );
unsigned int CreateID(const void*,size_t);
void Write(void*,size_t,long);
void Read(void*,size_t,long); 
public:
CLinkedFile(void);
CLinkedFile(const wchar_t*);
~CLinkedFile(void);

unsigned int AddObject(void*,size_t);
int          RemoveObject(void*,size_t);
   int          Next(void*,size_t&);
};

#endif

 

source

>
#include "stdafx.h"
#include "cLinkedFile.h"


CLinkedFile::CLinkedFile(void)
{
}


CLinkedFile::~CLinkedFile(void)
{
ZeroMemory(&this->m_info,sizeof(LFInfo));
this->m_idxs.clear();
CloseHandle(this->m_file);
this->m_file  =  NULL;
}
CLinkedFile::CLinkedFile(const wchar_t* filename)
{
m_file =  CreateFile(filename,GENERIC_WRITE | GENERIC_READ,NULL,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
DWORD dw;
if(m_file == INVALID_HANDLE_VALUE)
	throw;
if(GetFileSize(m_file,&dw) < 20)
	this->CreateDefault();
else
{
	this->Read(&this->m_info,sizeof(LFInfo),0);
	unsigned char stamp[16] = LF_STAMP;
	if( memcmp(&stamp,&this->m_info.stamp,16))
		this->CreateDefault();
	else
	{
		LFIndexer idx;
		for(unsigned int i=0 ; i < m_info.idx_count;i++)
		{
			this->Read(&idx,sizeof(idx),(m_info.idx_begin + i * sizeof(LFIndexer)));
			this->m_idxs.push_back(idx);
		}
	}
}
this->m_first = this->m_idxs.begin();
this->m_last  = this->m_idxs.end();

}
void CLinkedFile::Read(void* data,size_t size,long pos)
{
DWORD dw;
SetFilePointer(m_file,pos,NULL,FILE_BEGIN);
ReadFile(m_file,data,size,&dw,NULL);
if(dw!= size)
	throw;
}
void CLinkedFile::Write(void* data,size_t size,long pos)
{
DWORD dw;
SetFilePointer(m_file,pos,NULL,FILE_BEGIN);
WriteFile(m_file,data,size,&dw,NULL);
if(dw!= size)
	throw;
}
void CLinkedFile::CreateDefault()
{
this->m_info.data_entery = LF_DATA_ENTERY;
this->m_info.idx_begin   = LF_IDX_BEGIN;
this->m_info.idx_count   = 0;
char stamp[16] = LF_STAMP;
memcpy(&this->m_info.stamp,&stamp,16);
this->Write(&this->m_info,sizeof(LFInfo),0);
}
unsigned int CLinkedFile::AddObject(void* obj,size_t size)
{
unsigned int id = this->CreateID(obj,size);
LFIndexer idx = this->GCGetIndexer(size),idx1;
idx1 = idx;
if(idx.pos == -1)
{
	idx.id      = id;
	idx.is_free = false;
	idx.size    = size;
	idx.ori_size= size;
	if(this->m_info.idx_count == 0)
		idx.pos = LF_DATA_ENTERY;
	else
		idx.pos = SetFilePointer(m_file,0,NULL,FILE_END);
	this->Write(obj,size,idx.pos);
	this->m_idxs.push_back(idx);
	this->Write(&idx,sizeof(idx),this->m_info.idx_begin + this->m_info.idx_count * sizeof(idx));
	this->m_info.idx_count++;
	this->Write(&this->m_info,sizeof(LFInfo),0);
}
else
{
	this->Write(obj,size,idx.pos);
	idx.is_free = false;
	idx.size    = size;
	idx.id      = id;

	this->ReplaceIndexer(idx1,idx);
}
return true;

}
unsigned int CLinkedFile::CreateID(const void* ptr,size_t size)
{
unsigned int cs = (0x00000000 | (size<<16));
for(unsigned int i=0;i< (size/sizeof(unsigned short));i++)
{
	cs ^= *((unsigned short*)ptr) + i;
}
return cs;
}
LFIndexer CLinkedFile::GCGetIndexer(size_t size)
{
LFIndexer idx;
idx.pos = -1;
std::for_each(this->m_idxs.begin(),this->m_idxs.end(),[&](LFIndexer &i)
{
	if(i.is_free && i.ori_size > size)
		idx = i;
	
});
return idx;
}
void CLinkedFile::ReplaceIndexer(LFIndexer& idx,LFIndexer& idxnew)
{
int count = 0;
DWORD dw;
std::for_each(this->m_idxs.begin(),this->m_idxs.end(),[&](LFIndexer &i)
{
	if(memcmp(&idx,&i,sizeof(LFIndexer)))
	{
		i = idxnew;
		SetFilePointer(this->m_file,this->m_info.idx_begin + (count* sizeof(LFIndexer)),NULL,FILE_BEGIN);
		WriteFile(this->m_file,&idxnew,sizeof(LFIndexer),&dw,NULL);
	}
	count++;
});
}
int CLinkedFile::RemoveObject(void* obj,size_t size)
{
unsigned id = this->CreateID(const_cast<void*>(obj),size);
std::for_each(this->m_idxs.begin(),this->m_idxs.end(),[&]
   (LFIndexer &idx)
{
	if(idx.id == id && !idx.is_free)
	{
		char *buf = new char[size];
		this->Read(buf,size,idx.pos);
		if(!memcmp(buf,obj,size))
		{
			idx.is_free = true;
		}
		delete buf;
	}
}
);
return 0;
}
int CLinkedFile::Next(void* obj,size_t& out_size)
{
if(this->m_first != this->m_last)
{
	this->Read(obj,(*this->m_first).size,(*this->m_first).pos);
	out_size = (*this->m_first).size;
	++(this->m_first);
	return true;
}
return false;
}

 

Καμια βοηθεια;

Αρχειοθετημένο

Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.

  • Δημιουργία νέου...