// Documented in header. zvalue symtabFromZassoc(zassoc ass) { if (DAT_CONSTRUCTION_PARANOIA) { for (zint i = 0; i < ass.size; i++) { assertValid(ass.elems[i].key); assertValid(ass.elems[i].value); } } if (ass.size == 0) { return EMPTY_SYMBOL_TABLE; } zvalue result = allocInstance(ass.size); SymbolTableInfo *info = getInfo(result); for (zint i = 0; i < ass.size; i++) { putInto(&result, &info, ass.elems[i]); } return result; }
/** * Mutates an instance, putting a mapping into it, possibly reallocating it * (hence the pointer arguments). As a minor convenience, this function * returns early (doing nothing) if given `NULL` for `elem.key`. */ static void putInto(zvalue *result, SymbolTableInfo **info, zmapping elem) { if (elem.key == NULL) { return; } zint arraySize = (*info)->arraySize; zmapping *array = (*info)->array; zint index = symbolIndex(elem.key) % arraySize; for (int i = 0; i < DAT_SYMTAB_MAX_PROBES; i++) { zvalue foundKey = array[index].key; if (foundKey == NULL) { array[index] = elem; (*info)->size++; return; } else if (foundKey == elem.key) { // Update a pre-existing mapping for the key. array[index].value = elem.value; return; } index = (index + 1) % arraySize; } // Too many collisions! Reallocate, and then add the originally-requested // pair. zvalue newResult = allocInstance(arraySize); // This grows `array`. SymbolTableInfo *newInfo = getInfo(newResult); for (int i = 0; i < arraySize; i++) { putInto(&newResult, &newInfo, array[i]); } putInto(&newResult, &newInfo, elem); *result = newResult; *info = newInfo; }
w_int RandomAccessFile_createFromString (JNIEnv *env, w_instance thisRAF, w_instance path, int mode) { w_thread thread = JNIEnv2w_thread(env); w_string pathname_string; char *pathname; const char *fmode = "r+"; int openmode; int fdesc; vfs_FILE *file; w_instance fd_obj; struct vfs_STAT statbuf; int rc; if (mustBeInitialized(clazzFileDescriptor) == CLASS_LOADING_FAILED) { return 0; } pathname_string = String2string(path); pathname = (char*)string2UTF8(pathname_string, NULL) + 2; switch(mode) { case 0: openmode = VFS_O_RDONLY; fmode = "r"; break; case 1: openmode = VFS_O_RDWR | VFS_O_CREAT; break; case 2: openmode = VFS_O_RDWR | VFS_O_CREAT | VFS_O_DIRECT; break; case 3: openmode = VFS_O_RDWR | VFS_O_CREAT | VFS_O_SYNC; break; default: openmode = 0; } rc = vfs_stat(pathname, &statbuf); switch(mode) { case 0: if (rc != 0 || !VFS_S_ISREG(statbuf.st_mode) || (((statbuf.st_mode & VFS_S_IRWXU) & VFS_S_IRUSR) != VFS_S_IRUSR)) { return 1; } break; default: if (rc == 0 && (!VFS_S_ISREG(statbuf.st_mode) || (((statbuf.st_mode & VFS_S_IRWXU) & VFS_S_IWUSR) != VFS_S_IWUSR))) { return 1; } } fdesc = vfs_open(pathname, openmode, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); releaseMem(pathname - 2); if(fdesc == -1) { return 1; } file = vfs_fdopen(fdesc, fmode); if (file == NULL) { return 1; } else { enterUnsafeRegion(thread); fd_obj = allocInstance(thread, clazzFileDescriptor); enterSafeRegion(thread); if(fd_obj != NULL) { setReferenceField(thisRAF, fd_obj, F_RandomAccessFile_fd); setBooleanField(fd_obj, F_FileDescriptor_validFD, 1); setWotsitField(fd_obj, F_FileDescriptor_fd, file); setReferenceField(fd_obj, path, F_FileDescriptor_fileName); } } return 0; }