Browse Source

Added VersionedData system

This was copied over from codesearch-gui (a.k.a. Machsearch)
master
Macoy Madson 5 months ago
parent
commit
47f3c926d4
  1. 1
      ReadMe.org
  2. 143
      src/VersionedData.cake

1
ReadMe.org

@ -126,6 +126,7 @@ Here are the known compatibility results, where blank means untested/unknown:
| TaskSystem.cake | Yes | | Yes | |
| TinyCCompiler.cake | Yes | | Yes | |
| Tracy.cake | Yes | | | |
| VersionedData.cake | Yes | Yes | Yes | Yes |
| WindowsHeader.cake | Yes[2] | Yes[2] | Yes | |
| XML.cake | Yes | Yes | Yes | Yes |

143
src/VersionedData.cake

@ -0,0 +1,143 @@
;; VersionedData.cake: A system to read and write introspect structs with version headers
;; The intention here is to have a mostly plug-and-play system for managing e.g. user application
;; configuration files across many app versions.
(import "Introspection.cake"
"CHelpers.cake" "FileUtilities.cake")
(c-import "<stddef.h>" "<stdio.h>" "<stdlib.h>" "<string.h>")
(defenum versioned-data-result
versioned-data-result-success
;; Failure codes
versioned-data-result-cannot-open-file
versioned-data-result-version-mismatch
versioned-data-result-version-not-readable
versioned-data-result-cannot-parse-data
versioned-data-result-cannot-copy-data-into-output
versioned-data-result-cannot-write-version
versioned-data-result-cannot-write-data)
(def-introspect-struct version-header
version int)
(defun-local write-version (out-file (* FILE) version (* (const version-header)) &return bool)
(unless (write-introspect-struct-s-expr version-header--metadata
version out-file
write-introspect-struct-add-newline)
(return false))
(return true))
(defun-local check-version (current-version (* (const version-header))
read-version-out (* version-header)
s-expr-in (* (const char))
after-version-start-out (* (unsigned int))
error-string-out (* char)
error-string-out-size size_t
&return versioned-data-result)
(set (at 0 error-string-out) 0) ;; Clear error if any
(var result versioned-data-result versioned-data-result-success)
(unless (read-introspect-struct-s-expr version-header--metadata read-version-out
s-expr-in malloc after-version-start-out)
(snprintf error-string-out error-string-out-size
"error: Failed to read data version header")
(set result versioned-data-result-version-not-readable)
(fprintf stderr "%s\n" error-string-out)
(return result))
(unless (= (path current-version > version) (path read-version-out > version))
(snprintf error-string-out error-string-out-size
"error: Not going to read data. Version %d does not match expected %d.
This program's version does not understand data version."
(path read-version-out > version) (path current-version > version))
(set result versioned-data-result-version-mismatch))
(unless (= result versioned-data-result-success)
(fprintf stderr "%s\n" error-string-out))
(return result))
(defun load-versioned-data (filename (* (const char))
current-version (* (const version-header))
read-version-out (* version-header)
data-metadata (* (const metadata-struct))
data-out (* void)
error-buffer (* char)
error-buffer-size (unsigned int)
&return versioned-data-result)
(var result versioned-data-result versioned-data-result-success)
(var in-file (* FILE) (fopen filename "rb"))
(if in-file
(scope ;; File valid
(var file-contents (* (const char)) (read-file-into-memory in-file))
(fclose in-file)
(var start-data-offset (unsigned int) 0)
(var read-version version-header (array 0))
(set result (check-version current-version (addr read-version)
file-contents (addr start-data-offset)
error-buffer error-buffer-size))
(unless (= result versioned-data-result-success)
(free (type-cast file-contents (* void)))
(return result))
;; Read into other data so we don't risk running the app with partially loaded data
(var possible-data (* void) (malloc (path data-metadata > struct-size)))
(memset possible-data 0 (path data-metadata > struct-size))
(unless (read-introspect-struct-s-expr data-metadata possible-data
(+ start-data-offset file-contents) malloc null)
(snprintf error-buffer error-buffer-size
"error: Failed to read data (parsing error)")
(fprintf stderr "%s\n" error-buffer)
(free-introspect-struct-fields data-metadata possible-data free)
(free possible-data)
(set result versioned-data-result-cannot-parse-data)
(return result))
(unless (copy-introspect-struct data-metadata data-out possible-data malloc)
(snprintf error-buffer error-buffer-size
"error: Failed to copy loaded data into runtime data")
(fprintf stderr "%s\n" error-buffer)
(free-introspect-struct-fields data-metadata possible-data free)
(free possible-data)
(set result versioned-data-result-cannot-copy-data-into-output)
(return result))
(free-introspect-struct-fields data-metadata possible-data free)
(free possible-data)
(free (type-cast file-contents (* void))))
(scope ;; File invalid
(set result versioned-data-result-cannot-open-file)))
(return result))
(defun save-versioned-data (filename (* (const char))
current-version (* (const version-header))
data-metadata (* (const metadata-struct))
data-out (* void)
error-buffer (* char)
error-buffer-size (unsigned int)
&return versioned-data-result)
(var result versioned-data-result versioned-data-result-success)
(var out-file (* FILE) (fopen filename "wb"))
(unless out-file
(snprintf error-buffer error-buffer-size
"error: failed to save data. File could %s not be opened\n" filename)
(set result versioned-data-result-cannot-open-file)
(return result))
(unless (write-version out-file current-version)
(fclose out-file)
(snprintf error-buffer error-buffer-size
"error: failed to save user data: could not write version header\n")
(set result versioned-data-result-cannot-write-version)
(return result))
(unless (write-introspect-struct-s-expr data-metadata data-out
out-file write-introspect-struct-add-newline)
(fclose out-file)
(snprintf error-buffer error-buffer-size
"error: failed to save user data\n")
(return versioned-data-result-cannot-write-data))
(fclose out-file)
(return result))
Loading…
Cancel
Save