Пример #1
0
int asyncFileWriteStart(AsyncFile *f, int fPosition, void *bufferPtr, int bufferSize) {
  /* Start an asynchronous operation to write bufferSize bytes to the given file
	 starting at the given file position. The file's semaphore will be signalled when
	 the operation is complete. The client may then use asyncFileWriteResult() to
	 find out if the operation succeeded and how many bytes were actually written. */

	AsyncFileState *state;
	OSErr err;

	if (!asyncFileValid(f)) return success(false);
	state = f->state;
	if (state->status == BUSY) return success(false);  /* operation in progress */
	if (!state->writable) return success(false);

	/* allocate a new buffer if necessary */
	asyncFileAllocateBuffer(state, bufferSize);
	if (state->bufferPtr == nil) return success(false);  /* could not allocate buffer */

	/* copy the squeak buffer into the file buffer */
	memcpy(state->bufferPtr, bufferPtr, bufferSize);

	asyncFileInitPB(state, fPosition);
	err = PBWriteAsync(&state->pb);
	if (err != noErr) {
		state->status = IDLE;
		return success(false);
	}
	return 0;
}
Пример #2
0
int asyncFileWriteStart(AsyncFile *f, int fPosition, int bufferPtr, int bufferSize) {
  /* Start an asynchronous operation to write bufferSize bytes to the given file
     starting at the given file position. The file''s semaphore will be signalled when
     the operation is complete. The client may then use asyncFileWriteResult() to
     find out if the operation succeeded and how many bytes were actually written. */
  AsyncFileState *state = (AsyncFileState *) f->state;

  if (!asyncFileValid(f)) return success(false);
  if (state->status == BUSY) return success(false);  /* operation in progress */
  if (!state->writable) return success(false);

  /* allocate a new buffer if necessary */
  asyncFileAllocateBuffer(state, bufferSize);
  if (state->bufferPtr == NULL) return success(false);  /* could not allocate buffer */

  /* copy the squeak buffer into the file buffer */
  MoveMemory((void*)state->bufferPtr, (void*) bufferPtr, bufferSize);

  state->dwPosition = fPosition;
  state->dwSize = bufferSize;
  state->status = BUSY;
  state->rFlag = FALSE;
  SetEvent(state->hEvent);
  return 1;
}
Пример #3
0
int asyncFileReadStart(AsyncFile *f, int fPosition, int count) {
  /* Start an asynchronous operation to read count bytes from the given file
	 starting at the given file position. The file's semaphore will be signalled when
	 the operation is complete. The client may then use asyncFileReadResult() to
	 find out if the operation succeeded and to get the data that was read. */

	AsyncFileState *state;
	OSErr err;

	if (!asyncFileValid(f)) return success(false);
	state = f->state;
	if (state->status == BUSY) return success(false);  /* operation in progress */

	/* allocate a new buffer if necessary */
	asyncFileAllocateBuffer(state, count);
	if (state->bufferPtr == nil) return success(false);  /* could not allocate buffer */

	asyncFileInitPB(state, fPosition);
	err = PBReadAsync(&state->pb);
	if (err != noErr) {
		state->status = IDLE;
		success(false);
		return 0;
	}
	return 0;
}
Пример #4
0
int asyncFileClose(AsyncFile *f) {
  /* Close the given asynchronous file. */

	AsyncFileState *state;
	short int volRefNum;
	OSErr err;

	if (!asyncFileValid(f)) return 0;  /* already closed */
	state = f->state;

	err = GetVRefNum(state->refNum, &volRefNum);
	success(err == noErr);

	err = FSClose(state->refNum);
	success(err == noErr);

	if (!interpreterProxy->failed()) err = FlushVol(NULL, volRefNum);
	success(err == noErr);

    if (asyncFileCompletionProc != nil)
        DisposeIOCompletionUPP(asyncFileCompletionProc);
  
	asyncFileCompletionProc = nil;
	if (state->bufferPtr != nil) DisposePtr(state->bufferPtr);
	DisposePtr((void *) f->state);
	f->state = nil;
	f->sessionID = 0;
	return 0;
}
Пример #5
0
int asyncFileClose(AsyncFile *f) {
  /* Close the given asynchronous file. */

  AsyncFileState *state;

  if (!asyncFileValid(f)) return 0;  /* already closed */
  state = (AsyncFileState*) f->state;
  if(!CloseHandle(state->hFile)) {
    printLastError(TEXT("AsyncFileClose failed"));
    success(false);
  }
  state->hFile = INVALID_HANDLE_VALUE;
  SetEvent(state->hEvent);
  WaitForSingleObject(state->hThread, 5000);
  if(state->hThread) {
    warnPrintf(TEXT("Terminating async thread"));
    TerminateThread(state->hThread,0);
  }
  CloseHandle(state->hEvent);
  if (state->bufferPtr != NULL) asyncFree(state->bufferPtr);
  free((void *) f->state);
  f->state = NULL;
  f->sessionID = 0;
  return 1;
}
Пример #6
0
int asyncFileWriteResult(AsyncFile *f) {
  /* Return the number of bytes copied by the last write operation.
     Negative values indicate:
     -1    -- busy; the last operation has not finished yet
     -2    -- error; the last operation failed */

  AsyncFileState *state = (AsyncFileState *) f->state;
  
  if (!asyncFileValid(f)) return success(false);
  if (state->status == BUSY) return -1;
  if (state->status == LAST_OP_FAILED) return -2;
  return state->bytesTransferred;
}
Пример #7
0
int asyncFileReadStart(AsyncFile *f, int fPosition, int count) {
  /* Start an asynchronous operation to read count bytes from the given file
     starting at the given file position. The file''s semaphore will be signalled when
     the operation is complete. The client may then use asyncFileReadResult() to
     find out if the operation succeeded and to get the data that was read. */
  AsyncFileState *state = (AsyncFileState *) f->state;
  
  if (!asyncFileValid(f)) return success(false);
  if (state->status == BUSY) return success(false);  /* operation in progress */
  
  /* allocate a new buffer if necessary */
  asyncFileAllocateBuffer(state, count);
  if (state->bufferPtr == NULL) return success(false);  /* could not allocate buffer */

  state->dwPosition = fPosition;
  state->dwSize = count;
  state->status = BUSY;
  state->rFlag = TRUE;
  SetEvent(state->hEvent);
  return 1;
}
Пример #8
0
int asyncFileReadResult(AsyncFile *f, int bufferPtr, int bufferSize) {
  /* Copy up to bufferSize bytes from the buffer of the last read operation
     into the given Squeak buffer, and return the number of bytes copied.
     Negative values indicate:
     -1    -- busy; the last operation has not finished yet
     -2    -- error; the last operation failed
     Note that a read operation may read fewer bytes than requested if, for
     example, there are fewer than the requested number of bytes between the
     starting file position of the read operation and the end-of-file. */

  AsyncFileState *state = (AsyncFileState *) f->state;
  int bytesRead;

  if (!asyncFileValid(f)) return success(false);
  if (state->status == BUSY) return -1;
  if (state->status == LAST_OP_FAILED) return -2;
  
  /* copy the file buffer into the squeak buffer */
  bytesRead = (bufferSize < state->bytesTransferred) ? bufferSize : state->bytesTransferred;
  MoveMemory((void *) bufferPtr, (void *)state->bufferPtr, bytesRead);
  return bytesRead;
}
Пример #9
0
int asyncFileOpen(AsyncFile *f, char *fileNamePtr, int fileNameSize, int writeFlag, int semaIndex) {
  /* Opens the given file using the supplied AsyncFile structure to record
	 its state. Fails with no side effects if f is already open. Files are
	 always opened in binary mode. */

	short int fileRefNum;
	AsyncFileState *state;
	OSErr err;
	void * ithisSessionfn;
	int thisSession;
        FSSpec	theSpec; 

	/* don't open an already open file */
	if (asyncFileValid(f)) return success(false);

	/* build complete routine descriptor, if necessary */
	if (asyncFileCompletionProc == nil) {
#if TARGET_API_MAC_CARBON
		asyncFileCompletionProc = NewIOCompletionUPP((pascal void (*) (union ParamBlockRec *) )asyncFileCompletionRoutine);
#else
		asyncFileCompletionProc = NewIOCompletionProc((pascal void (*) (union ParamBlockRec *) )asyncFileCompletionRoutine);
#endif
	}

	/* copy the file name into a null-terminated C string */
	if (fileNameSize > 1000) return success(false);
	
	makeFSSpec((char*) fileNamePtr, fileNameSize,&theSpec);
        
	f->sessionID = 0;
	if (writeFlag) {
		/* first try to open an existing file read/write: */
		err = FSpOpenDF(&theSpec,fsRdWrPerm, &fileRefNum); 
		if (err != noErr) {
			/* file does not exist; must create it. */
			err = FSpCreate(&theSpec,'R*ch','TEXT',smSystemScript); 
			if (err != noErr) return success(false);
			err = FSpOpenDF(&theSpec,fsRdWrPerm, &fileRefNum); 
			if (err != noErr) return success(false);
		}
	} else {
		/* open the file read-only  */
		err = FSpOpenDF(&theSpec,fsRdPerm, &fileRefNum); 
		if (err != noErr) return success(false);
	}
	f->state = (AsyncFileState *) NewPtr(sizeof(AsyncFileState));	/* allocate state record */
	if (f->state == nil) {
		FSClose(fileRefNum);
		return success(false);
	}
	ithisSessionfn = interpreterProxy->ioLoadFunctionFrom("getThisSession", "FilePlugin");
	if (ithisSessionfn != 0)
		thisSession =  ((int (*) (void)) ithisSessionfn)();
	else 
		thisSession = 0;
	f->sessionID = thisSession;
	state = (AsyncFileState *) f->state;
	state->refNum = fileRefNum;
	state->writable = writeFlag;
	state->semaIndex = semaIndex;
	state->status = IDLE;
	state->bytesTransferred = 0;
	state->bufferSize = 0;
	state->bufferPtr = nil;
	return 0;
}
Пример #10
0
int asyncFileOpen(AsyncFile *f, int fileNamePtr, int fileNameSize, 
		  int writeFlag, int semaIndex) {
  /* Opens the given file using the supplied AsyncFile structure to record
     its state. Fails with no side effects if f is already open. Files are
     always opened in binary mode. */

  int i;
  char  cFileName[256];
  WCHAR wFileName[256];
  AsyncFileState *state;
  HANDLE hFile;
  DWORD id;

  /* don''t open an already open file */
  if (asyncFileValid(f)) return success(false);

  /* copy the file name into a null-terminated C string */
  if (fileNameSize > 255) return success(false);
  for (i = 0; i < fileNameSize; i++) {
    cFileName[i] = *((char *) (fileNamePtr + i));
  }
  cFileName[fileNameSize] = 0;

  /* Convert to Unicode */
  MultiByteToWideChar(CP_UTF8, 0, cFileName, -1, wFileName, 255);

  f->sessionID = 0;
  hFile = CreateFileW(wFileName,
	    writeFlag ? (GENERIC_READ | GENERIC_WRITE) : GENERIC_READ,
	    writeFlag ? FILE_SHARE_READ : (FILE_SHARE_READ | FILE_SHARE_WRITE),
	    NULL, /* No security descriptor */
	    writeFlag ? OPEN_ALWAYS : OPEN_EXISTING,
	    FILE_ATTRIBUTE_NORMAL,
	    NULL /* No template */);
  if(hFile == INVALID_HANDLE_VALUE)
    return success(false);
  f->state = (AsyncFileState *) 
    calloc(1,sizeof(AsyncFileState));	/* allocate state record */
  if (f->state == NULL) {
    CloseHandle(hFile);
    return success(false);
  }
  f->sessionID = thisSession;
  state = (AsyncFileState *) f->state;
  state->hFile = hFile;
  state->writable = writeFlag;
  state->semaIndex = semaIndex;
  state->status = IDLE;
  state->bytesTransferred = 0;
  state->bufferSize = 0;
  state->bufferPtr = NULL;
  state->hEvent = CreateEvent(NULL, 0, 0, NULL);
  state->hThread =
    CreateThread(NULL,                    /* No security descriptor */
		 0,                       /* default stack size     */
		 (LPTHREAD_START_ROUTINE) &sqAsyncFileThread, /* what to do */
		 (LPVOID) state,       /* parameter for thread   */
		 CREATE_SUSPENDED,        /* create suspended */
		 &id);                    /* return value for thread id */
  if(!state->hThread) {
    printLastError(TEXT("CreateThread() failed"));
    return success(false);
  }
  /* file operations run with high priority */
  if(!SetThreadPriority(state->hThread, THREAD_PRIORITY_HIGHEST))
    printLastError(TEXT("SetThreadPriority() failed"));
  if(!ResumeThread(state->hThread)) {
    printLastError(TEXT("ResumeThread() failed"));
    return success(false);
  }
  return 1;
}