Exemple #1
0
void* fxMapArchive(txString base, txCallbackAt callbackAt)
{
	int error = 0;
	txArchive* archive = C_NULL;
#if mxWindows
#else
	struct stat statbuf;
#endif
	txString p;
	Atom atom;
	int c, i;
	txString* symbol;
	txScript* script;

	archive = c_malloc(sizeof(txArchive));
	bailElse(archive);
	c_memset(archive, 0, sizeof(txArchive));
	c_strcpy(archive->base, base);
#if mxWindows
	archive->file = CreateFile(base, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	bailElse(archive->file != INVALID_HANDLE_VALUE);
	archive->size = GetFileSize(archive->file, &archive->size);
	bailElse(archive->size != INVALID_FILE_SIZE);
	archive->mapping = CreateFileMapping(archive->file, NULL, PAGE_READONLY, 0, (SIZE_T)archive->size, NULL);
	bailElse(archive->mapping != INVALID_HANDLE_VALUE);
	archive->address = MapViewOfFile(archive->mapping, FILE_MAP_READ, 0, 0, (SIZE_T)archive->size);
	bailElse(archive->address != NULL);
#else
	archive->fd = open(base, O_RDONLY);
	bailElse(archive->fd >= 0);
	fstat(archive->fd, &statbuf);
	archive->size = statbuf.st_size;
	archive->address = mmap(NULL, archive->size, PROT_READ, MAP_SHARED, archive->fd, 0);
	bailElse(archive->address != MAP_FAILED);
#endif
	p = archive->address;
	p = fxMapAtom(p, &atom);
	bailAssert(atom.atomType == XS_ATOM_ARCHIVE);
	
	p = fxMapAtom(p, &atom);
	bailAssert(atom.atomType == XS_ATOM_VERSION);
	bailAssert(*p++ == XS_MAJOR_VERSION);
	bailAssert(*p++ == XS_MINOR_VERSION);
	bailAssert(*p++ == XS_PATCH_VERSION);
	if ((*p++) && !callbackAt) {
		char* dot;
		dot = c_strrchr(archive->base, '.');
		if (dot)
			*dot = 0;
		#if mxWindows
			c_strcat(archive->base, ".dll");
			archive->library = LoadLibrary(archive->base);
			bailElse(archive->library);
			callbackAt = (txCallbackAt)GetProcAddress(archive->library, "xsHostModuleAt");
			bailElse(callbackAt);
		#else
			c_strcat(archive->base, ".so");
			archive->library = dlopen(archive->base, RTLD_NOW);
			if (!archive->library)
        		fprintf(stderr, "%s\n", dlerror());
			bailElse(archive->library);
			callbackAt = (txCallbackAt)dlsym(archive->library, "xsHostModuleAt");
			bailElse(callbackAt);
		#endif
		archive->keys = callbackAt(0);
	}
	
	p = fxMapAtom(p, &atom);
	bailAssert(atom.atomType == XS_ATOM_SYMBOLS);
	c = archive->symbolCount = ntohs(*((unsigned short*)p));
	p += 2;
	if (c) {
		symbol = archive->symbols = c_malloc(c * sizeof(txString));
		for (i = 0; i < c; i++) {
			*symbol = p;
			p += c_strlen(p) + 1;
			symbol++;
		}
	}
	
	p = fxMapAtom(p, &atom);
	bailAssert(atom.atomType == XS_ATOM_PATHS);
	c = archive->scriptCount = ntohs(*((unsigned short*)p));
	p += 2;
	script = archive->scripts = c_malloc(c * sizeof(txScript));
	c_memset(script, 0, c * sizeof(txScript));
	for (i = 1; i <= c; i++) {
		if (callbackAt)
			script->callback = callbackAt(i);
		script->path = p;
		p += c_strlen(p) + 1;
		script++;
	}
	
	script = archive->scripts;
	for (i = 0; i < c; i++) {
		p = fxMapAtom(p, &atom);
		bailAssert(atom.atomType == XS_ATOM_CODE);
		script->codeSize = atom.atomSize - sizeof(atom);
		script->codeBuffer = (txS1*)p;
		p += script->codeSize;
		script++;
	}
	
	p = c_strrchr(archive->base, mxSeparator);
	if (p) {
		p++;
		*p = 0;
		archive->baseLength = p - archive->base;
	}
bail:
	if (error) {
		fxUnmapArchive(archive);
		archive = C_NULL;
	}
	return archive;
}
Exemple #2
0
void* fxMapArchive(txString base, txCallbackAt callbackAt)
{
	FskErr err = kFskErrNone;
	txArchive* archive = NULL;
	txString p;
	Atom atom;
	int c, i;
	txString* symbol;
	txScript* script;

	bailIfError(FskMemPtrNewClear(sizeof(txArchive), &archive));
	c_strcpy(archive->base, base);
	bailIfError(FskFileMap(base, (unsigned char**)&(archive->address), &(archive->size), 0, &(archive->map)));

	p = archive->address;
	p = fxMapAtom(p, &atom);
	bailAssert(atom.atomType == XS_ATOM_ARCHIVE);
	
	p = fxMapAtom(p, &atom);
	bailAssert(atom.atomType == XS_ATOM_VERSION);
	bailAssert(*p++ == XS_MAJOR_VERSION);
	bailAssert(*p++ == XS_MINOR_VERSION);
	bailAssert(*p++ == XS_PATCH_VERSION);
	if ((*p++) && !callbackAt) {
		char* dot;
		dot = c_strrchr(archive->base, '.');
		if (dot)
			*dot = 0;
		#if mxWindows
			c_strcat(archive->base, ".dll");
		#else
			c_strcat(archive->base, ".so");
		#endif
		bailIfError(FskLibraryLoad(&(archive->library), archive->base));
		bailIfError(FskLibraryGetSymbolAddress(archive->library, "xsHostModuleAt", &callbackAt));
		archive->keys = callbackAt(0);
	}

	p = fxMapAtom(p, &atom);
	bailAssert(atom.atomType == XS_ATOM_SYMBOLS);
	mxDecode2(p, archive->symbolCount);
	c = archive->symbolCount;
	if (c) {
		bailIfError(FskMemPtrNew(c * sizeof(txString), &(archive->symbols)));
		symbol = archive->symbols;
		for (i = 0; i < c; i++) {
			*symbol = p;
			p += c_strlen(p) + 1;
			symbol++;
		}
	}

	p = fxMapAtom(p, &atom);
	bailAssert(atom.atomType == XS_ATOM_PATHS);
	mxDecode2(p, archive->scriptCount);
	c = archive->scriptCount;
	bailIfError(FskMemPtrNewClear(c * sizeof(txScript), &(archive->scripts)));
	script = archive->scripts;
	for (i = 1; i <= c; i++) {
		if (callbackAt)
			script->callback = callbackAt(i);
		script->path = p;
		bailIfNULL(script->path);
		p += c_strlen(p) + 1;
		script++;
	}
	
	script = archive->scripts;
	for (i = 0; i < c; i++) {
		p = fxMapAtom(p, &atom);
		bailAssert(atom.atomType == XS_ATOM_CODE);
		script->codeSize = atom.atomSize - sizeof(atom);
		script->codeBuffer = (txS1*)p;
		p += script->codeSize;
		script++;
	}
	
	p = c_strrchr(archive->base, '/');
	if (p) {
		p++;
		*p = 0;
		archive->baseLength = p - archive->base;
	}
bail:
	if (err) {
		fxUnmapArchive(archive);
		archive = NULL;
	}
	return archive;
}