[rucksack-devel] non-simple-strings and fill-pointers

Pixel B. Interface, III pixel at kepibu.org
Wed Jun 15 10:25:29 UTC 2011


Greetings!

I've been using rucksack for the past, uh, two days.  I may have found a
bug.

I happened to be adding some on-disk caching of HTTP responses to my
cliki-spam-reverting-bot, and hit a tiny, easily-worked-around snag.
What I'm getting from Drakma is an adjustable (and hence non-simple)
string /without/ a fill-pointer.  Rucksack, on the other hand, assumes
non-simple-strings always have fill-pointers.

To wit:
  (defmethod serialize ((string string) stream)
     ...
       (unless simple-p
         (serialize (fill-pointer string) stream)
         (serialize (adjustable-array-p string) stream))
       ...)

Creating a non-simple string without a fill pointer:
  (setq str (make-array '(0) :element-type 'character
                             :adjustable t :fill-pointer nil))
  (fill-pointer str) =>
      #<type-error not an array with a fill-pointer>
  (simple-string-p str) => nil
  (array-has-fill-pointer-p str) => nil
  (rs::serialize str stream) =>
      #<type-error not an array with a fill-pointer>

Fortunately, the non-simple-arrays-have-fill-pointers assumption is
avoided when dealing with arrays in general:
  (defmethod serialize ((array array) stream)
    ...
    (when (= 1 (array-rank array))
      ;; Arrays with rank > 1 can't have fill-pointers.
      (serialize (array-has-fill-pointer-p array) stream)
      (when (array-has-fill-pointer-p array)
        (serialize (fill-pointer array) stream)))
    ...)

Unfortunately, adjusting string serialization to match array's
<fill-pointer-p>[<optional-fill-pointer>] format would break
file-compatibility between rucksack versions.  However, I believe a
fairly simple change would allow for fill-pointer-less non-simple
strings while maintaining the existing format:
   (defmethod serialize ((string string) stream)
      ...
        (unless simple-p
-         (serialize (fill-pointer string) stream)
+         (serialize (and (array-has-fill-pointer-p string)
+                         (fill-pointer string)) stream)
          (serialize (adjustable-array-p string) stream))
        ...)

(Apologies for not sending a proper patch, but I'm mostly pontificating
anyway; haven't tested it.) If I understand rucksack's serialization and
deserialization correctly, that should work fine, resulting in
deserializing the fill-pointer as nil, which is a perfectly acceptable
value and does the right thing.

Or maybe I'm nuts and wrong entirely.  Either way, for now, I'm working
around the issue by just coercing to a simple-string.

Other than that little snag, Rucksack has been remarkably easy to work
with.  So, uh, thanks!

-- 
-pix
What?  Manually reverting spam on cliki got old.





More information about the rucksack-devel mailing list