Application Context Implementation #4
| @ -281,8 +281,7 @@ pub const FileSystem = union(enum) { | ||||
|     /// | ||||
|     pub const Path = struct { | ||||
|         file_system: *FileSystem, | ||||
|         length: u8, | ||||
|         buffer: [max]u8, | ||||
|         path: oar.Path, | ||||
| 
 | ||||
|         /// | ||||
|         /// With files typically being backed by a block device, they can produce a variety of | ||||
| @ -430,11 +429,10 @@ pub const FileSystem = union(enum) { | ||||
|                             } | ||||
|                         }; | ||||
| 
 | ||||
|                         entry.* = archive.instance.find(path.buffer[0 .. path.length]) catch |err| | ||||
|                             return switch (err) { | ||||
|                                 error.FileInaccessible => error.FileNotFound, | ||||
|                                 error.EntryNotFound => error.FileNotFound, | ||||
|                             }; | ||||
|                         entry.* = archive.instance.find(path.path) catch |err| return switch (err) { | ||||
|                             error.FileInaccessible => error.FileNotFound, | ||||
|                             error.EntryNotFound => error.FileNotFound, | ||||
|                         }; | ||||
| 
 | ||||
|                         return FileAccess{ | ||||
|                             .context = entry, | ||||
| @ -460,15 +458,15 @@ pub const FileSystem = union(enum) { | ||||
|                     var path_buffer = std.mem.zeroes([4096]u8); | ||||
|                     const seperator_length = @boolToInt(native[native.len - 1] != seperator); | ||||
| 
 | ||||
|                     if ((native.len + seperator_length + path.length) >= | ||||
|                     if ((native.len + seperator_length + path.path.length) >= | ||||
|                         path_buffer.len) return error.FileNotFound; | ||||
| 
 | ||||
|                     std.mem.copy(u8, path_buffer[0 ..], native); | ||||
| 
 | ||||
|                     if (seperator_length != 0) path_buffer[native.len] = seperator; | ||||
| 
 | ||||
|                     std.mem.copy(u8, path_buffer[native.len .. | ||||
|                         path_buffer.len], path.buffer[0 .. path.length]); | ||||
|                     std.mem.copy(u8, path_buffer[native.len .. path_buffer. | ||||
|                         len], path.path.buffer[0 .. path.path.length]); | ||||
| 
 | ||||
|                     ext.SDL_ClearError(); | ||||
| 
 | ||||
| @ -592,8 +590,7 @@ pub const FileSystem = union(enum) { | ||||
|     pub fn joinedPath(file_system: *FileSystem, sequences: []const []const u8) PathError!Path { | ||||
|         var path = Path{ | ||||
|             .file_system = file_system, | ||||
|             .buffer = std.mem.zeroes([Path.max]u8), | ||||
|             .length = 0, | ||||
|             .path = oar.Path.empty, | ||||
|         }; | ||||
| 
 | ||||
|         if (sequences.len != 0) { | ||||
| @ -607,25 +604,25 @@ pub const FileSystem = union(enum) { | ||||
| 
 | ||||
|                 while (components.next()) |component| if (component.len != 0) { | ||||
|                     for (component) |byte| { | ||||
|                         if (path.length == Path.max) return error.TooLong; | ||||
|                         if (path.path.length == Path.max) return error.TooLong; | ||||
| 
 | ||||
|                         path.buffer[path.length] = byte; | ||||
|                         path.length += 1; | ||||
|                         path.path.buffer[path.path.length] = byte; | ||||
|                         path.path.length += 1; | ||||
|                     } | ||||
| 
 | ||||
|                     if (components.hasNext()) { | ||||
|                         if (path.length == Path.max) return error.TooLong; | ||||
|                         if (path.path.length == Path.max) return error.TooLong; | ||||
| 
 | ||||
|                         path.buffer[path.length] = '/'; | ||||
|                         path.length += 1; | ||||
|                         path.path.buffer[path.path.length] = '/'; | ||||
|                         path.path.length += 1; | ||||
|                     } | ||||
|                 }; | ||||
| 
 | ||||
|                 if (index < last_sequence_index) { | ||||
|                     if (path.length == Path.max) return error.TooLong; | ||||
|                     if (path.path.length == Path.max) return error.TooLong; | ||||
| 
 | ||||
|                     path.buffer[path.length] = '/'; | ||||
|                     path.length += 1; | ||||
|                     path.path.buffer[path.path.length] = '/'; | ||||
|                     path.path.length += 1; | ||||
|                 } | ||||
|             }; | ||||
|         } | ||||
|  | ||||
| @ -26,7 +26,10 @@ pub const Archive = struct { | ||||
|     /// As the archive is queried via [find], the cache is lazily assembled with the absolute | ||||
|     /// offsets of each queried file. | ||||
|     /// | ||||
|     const IndexCache = ona.table.Hashed([]const u8, u64, ona.table.string_context); | ||||
|     const IndexCache = ona.table.Hashed(Path, u64, .{ | ||||
|         .equals = Path.equals, | ||||
|         .hash = Path.hash, | ||||
|     }); | ||||
| 
 | ||||
|     /// | ||||
|     /// Deinitializes the index cache of `archive`, freeing all associated memory. | ||||
| @ -43,12 +46,12 @@ pub const Archive = struct { | ||||
|     /// | ||||
|     /// The found [Entry] value is returned or a [FindError] if it failed to be found. | ||||
|     /// | ||||
|     pub fn find(archive: *Archive, entry_path: []const u8) FindError!Entry { | ||||
|     pub fn find(archive: *Archive, entry_path: Path) FindError!Entry { | ||||
|         return Entry{ | ||||
|             .header = find_header: { | ||||
|                 var header = Entry.Header{ | ||||
|                     .revision = 0, | ||||
|                     .path = std.mem.zeroes(Path), | ||||
|                     .path = Path.empty, | ||||
|                     .file_size = 0, | ||||
|                     .absolute_offset = 0 | ||||
|                 }; | ||||
| @ -73,7 +76,7 @@ pub const Archive = struct { | ||||
| 
 | ||||
|                     // Read first entry. | ||||
|                     while ((try archive.file_access.read(mem.asBytes(&header))) == header_size) { | ||||
|                         if (mem.eql(u8, entry_path, header.path.buffer[0 .. header.path.length])) { | ||||
|                         if (entry_path.equals(header.path)) { | ||||
|                             // If caching fails... oh well... | ||||
|                             archive.index_cache.insert(entry_path, header.absolute_offset) catch {}; | ||||
| 
 | ||||
| @ -156,11 +159,33 @@ pub const Entry = struct { | ||||
| }; | ||||
| 
 | ||||
| /// | ||||
| /// Unique identifier pointing to an entry within an archive. | ||||
| /// | ||||
| /// A path does not do any verification that the given entry pointed to actually exists. | ||||
| /// | ||||
| pub const Path = extern struct { | ||||
|     buffer: [255]u8, | ||||
|     length: u8, | ||||
| 
 | ||||
|     /// | ||||
|     /// An empty [Path] with a length of `0`. | ||||
|     /// | ||||
|     pub const empty = std.mem.zeroes(Path); | ||||
| 
 | ||||
|     /// | ||||
|     /// Returns `true` if `this_path` is equal to `that_path, otherwise `false`. | ||||
|     /// | ||||
|     pub fn equals(this_path: Path, that_path: Path) bool { | ||||
|         return ona.io.equalsBytes(this_path.buffer[0 ..this_path. | ||||
|             length], that_path.buffer[0 .. that_path.length]); | ||||
|     } | ||||
| 
 | ||||
|     /// | ||||
|     /// Returns the hash of the text in `path`. | ||||
|     /// | ||||
|     pub fn hash(path: Path) usize { | ||||
|         return ona.io.hashBytes(path.buffer[0 .. path.length]); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| /// | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user