reading objects from DataStream

Bolot Kerimbaev bolot at cc.gatech.edu
Thu May 28 22:02:22 UTC 1998


If somebody knows what happens, please advise.

I implemented a classroom management (turnin/grading) system for Mark
Guzdial's class, and recently we discovered the following problem (I am
skipping hours of raiding for the lost shark):

Large turnins (i.e., for which text instance variable is >16384 bytes) could
not be recovered from a DataStream. Running a debugger revealed that the
error occurred after the text (that was supposed to be over 16K long) was
recovered into an empty String. However, the error was raised only when the
next instance variable was being read: DataStream raised 'Expected start of
object but found 0' error.

It is my understanding that the text instance variable (containing a String
at the time of save) was written as ByteArray (because it was longer than
16384 bytes). However, when it was read from DataStream, it did not recover
correctly (tried to read as String?).

Bolot Kerimbaev

PS. I am using Mark Guzdial's FileDictionary, which provides a Dictionary
like access to data in a PositionableDataStream (which extends DataStream
with position, position:, and setToEnd methods).

This is a message I sent to Mark and his TAs.

---------- Forwarded message ----------
Date: Thu, 28 May 1998 17:16:15 -0400 (EDT)
From: Bolot Kerimbaev <bolot at cc.gatech.edu>
To: CS 2390 Admin <cs2390-ta at cc.gatech.edu>
Subject: saga: root of problems

New theory:

When a Turnin is saved to disk, it iterates through its instance variables
and tries to save each of them. Since code is-a String, it is subject to the
16384 byte limitation (DataStream>>writeString), i.e., instead of trying to
save it as a String, DataStream saves that large chunk of code as a
ByteArray. But ByteArray and String use 4 and 2 bytes to save length
respectively. In other words, they are different.

Now, when that Turnin is read from the disk, Turnin tries to restore code
(which is in Turnin's text instVar). But for some reason (have not figured
out how exactly), it stores '' (at least on my test runs) in text, and then
chokes on Timestamp. Apparently, it does not correctly process text instVar,
which messes up its DataStream position counter, and then tries to read
Timestamp from an incorrect position!

I reproduced the problem using 'bare' FileDictionary:

| sqFD data |
data := Turnin new initialize; text: (String new: 17000 withAll: $a).
sqFD := FileDictionary fileNamed: 'test'.
sqFD open.
sqFD at: 'fred' put: data.
sqFD close.


and then to read (and crash):

| sqFD data |
sqFD := FileDictionary fileNamed: 'test'.
sqFD open.
[data := sqFD at: 'fred'
] ifError: [:msg :rec |
   Transcript show: 'This is the error! Trying to read Timestamp,
     but Turnin instVar>>text was not properly handled'; cr.
   sqFD close].
sqFD close. " you won't get here "
data inspect.


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Bolot Kerimbaev (bolot at cc.gatech.edu)
-------------------------------------
The difficult -- we'll do immediately.
The impossible will take a bit longer.





More information about the Squeak-dev mailing list