diff options
author | Oscar Najera <hi@oscarnajera.com> | 2025-06-06 16:12:09 +0200 |
---|---|---|
committer | Oscar Najera <hi@oscarnajera.com> | 2025-06-06 16:12:09 +0200 |
commit | 4bb8b7bc2f1a4912f2b156ccafb2a22dd8766540 (patch) | |
tree | 16fe9b96338315831292153fee25fc419b0bc4e7 /geoip | |
parent | 00d94fe38bf6df6d666d700f25550a5fe78968bf (diff) | |
download | scratch-4bb8b7bc2f1a4912f2b156ccafb2a22dd8766540.tar.gz scratch-4bb8b7bc2f1a4912f2b156ccafb2a22dd8766540.tar.bz2 scratch-4bb8b7bc2f1a4912f2b156ccafb2a22dd8766540.zip |
Read pointer values
Horrible debugging because I didn't correctly consider that reading a
pointer did not advance the reader pointer. I must set it thus back.
Diffstat (limited to 'geoip')
-rw-r--r-- | geoip/ip.lisp | 37 |
1 files changed, 33 insertions, 4 deletions
diff --git a/geoip/ip.lisp b/geoip/ip.lisp index 63c373f..7098c94 100644 --- a/geoip/ip.lisp +++ b/geoip/ip.lisp @@ -59,7 +59,9 @@ (data-offset -1 :type fixnum)) (defstruct db-reader - (db-ptr)) + (db-ptr) + (head-ptr) + (data-offset)) (defstruct maxmind-database-metadata (node-count 0 :read-only t :type fixnum) @@ -167,7 +169,10 @@ (setf type (+ 7 (read-db-char db-ptr)))) (list type (cond - ((or (= type 1) (< length 29)) + ((= type 1) + (incf-pointer (db-reader-db-ptr db-ptr) -1) + (+ 2 (ash length -3))) + ((< length 29) length) ((= length 29) (+ 29 (read-db-char db-ptr))) @@ -181,16 +186,38 @@ (loop repeat length collect (cons - (substitute #\- #\_ (mread-data db-ptr)) + (intern (string-upcase (substitute #\- #\_ (mread-data db-ptr))) :keyword) (mread-data db-ptr)))) (defun mread-list (db-ptr length) (loop repeat length collect (mread-data db-ptr))) +(defun read-pointer (reader) + (let* ((control-byte (read-db-char reader)) + (size-bits (ldb (byte 2 3) control-byte)) + (value-bits (ldb (byte 3 0) control-byte))) + (ecase size-bits + (0 (+ (ash value-bits 8) (read-db-char reader))) + (1 (+ (ash value-bits 16) (mread-unsigned reader 2) 2048)) + (2 (+ (ash value-bits 24) (mread-unsigned reader 3) 526336)) + (3 (mread-unsigned reader 4))))) + +(defun mread-pointer (reader) + (with-slots (db-ptr head-ptr data-offset) reader + (let* ((target (+ (read-pointer reader) data-offset)) + (curr-ptr db-ptr) + (result)) + (setf db-ptr (inc-pointer head-ptr target)) + (setf result (mread-data reader)) + (setf db-ptr curr-ptr) + result))) + (defun mread-data (db-ptr) (destructuring-bind (type length) (mread-datafield-metadata db-ptr) (ecase type + (1 (mread-pointer db-ptr)) (2 (mread-uft8 db-ptr length)) + (3 (cons 'double (mread-unsigned db-ptr 8))) (4 (bytes-from-foreign db-ptr length)) ((5 6 9 10) (mread-unsigned db-ptr length)) (7 (mread-map db-ptr length)) @@ -233,7 +260,9 @@ (with-slots (node-count) metadata (mread-data (make-db-reader - :db-ptr (inc-pointer ptr (+ data-offset (- record node-count 16))))))))) + :db-ptr (inc-pointer ptr (+ data-offset (- record node-count 16))) + :head-ptr ptr + :data-offset data-offset)))))) (defun integer-to-bits (n bit-count) "Convert integer to list of bits (MSB first)" |