Re: How to save C++ objects using Cocoa?



On 4 Jan, 19:17, Steve555 <foursh...@xxxxxxxxxxxxxx> wrote:
On 4 Jan, 14:12, Gregory Weston <u...@xxxxxxxxxx> wrote:



In article
<7c0d2395-85c1-4ac5-a18d-5bdd8d6d0...@xxxxxxxxxxxxxxxxxxxxxxxxxxx>,

 Steve555 <foursh...@xxxxxxxxxxxxxx> wrote:
On 2 Jan, 19:43, Gregory Weston <u...@xxxxxxxxxx> wrote:
In article
<1959d534-b29a-41bd-923f-45de26c91...@xxxxxxxxxxxxxxxxxxxxxxxxxxxx>,

 Steve555 <foursh...@xxxxxxxxxxxxxx> wrote:
Given a byte stream, I know how to put it in NSData, but, how do I
store it in an NSArray,

NSMutableArray's addObject: method (with the NSData instance as the
argument).

flatten it and write it to disk?

NSKeyedArchiver's archiveRootObject:toFile: method, using the array
populated above as the root object. Since arrays and data objects know
how to encode themselves, everything else is already done.

Any pointers to tutorials or example code are welcome, as all of the
Apple examples are so wrapped up in NSDictionaries and keys/values, I
can not see how it's possible to write a simple NSData. Sorry, my
misunderstanding must seem baffling when you know how it works, but
from my perspective it seems like with a byte stream I have to invent
unnecessary structures (and key/value pairs?) to do what I thought
must be a very common and simple task.

Probably the examples you've run across have been aimed at the more
complex situation of dealing with your own custom (Obj-C) classes that
you want to conform to NSCoding. But since the intermediate structures
you'll be using {NSData, NS(Mutable)Array} already do that, you just
have to archive the array.

Given a byte stream of length n, could anyone copy/paste some code
that writes it to disk? (Not as a text file!)

[[NSData dataWithWithBytes:b length:n] writetoFile:p atomically:YES];

Apologies again if that sounds cheeky, but I'm really confused as to
whether what I'm asking for is very complex or trivial!

Trivial. As long as you know which classes to look at in the first
place. That just takes a little bit of experience.

Am I barking up the wrong tree with Cocoa... would I be better off
writing traditional C style data saving routines, or could Cocoa be a
time saver?

Really depends what you're trying to accomplish. I know you're trying to
"save arrays of custom C++ class objects in to a binary file" but what's
the actual goal? What are these objects, why are they C++ types rather
than Obj-C, and what led you to looking into Cocoa's persistence
mechanisms with such objects?

Gregory, thanks so much for the help, I've got it working via

[[NSData dataWithWithBytes:b length:n] writetoFile:p atomically:YES];

I was confused between the flattening, and the writing process, but I
still think the documentation and examples
imply that Cocoa streamlines the whole lot; it never mentions manually
creating byte streams.

Cocoa *does* streamline the whole lot. As long as you're using Cocoa
objects. If you're using other sorts of allocations, there's really no
way that the library could know how to turn your arbitrary chunk of data
into something that can be stored and reliably reconstituted. (Actually,
I'm going to take that back a bit. With a relatively little work from
you, a broad class of such chunks *can* be handled reliably. Discussed
further at the bottom of this message.)

Anyway, once I've flattened the data, writeToFile: works without
putting it into NSArray.

How are you tracking where each individual object begins in your
flattened stream of thousands of items? My recommendation was that you
provide some relatively simple code to convert between individual
objects and data streams, but let Cocoa manage the flattening and
reinflation of the collection. Less code for you to write, likely with
any nasty edge cases already caught and fixed before there even was a
Mac OS X.

What are these objects, why are they C++ types rather
than Obj-C,

It's a basic database of users' music ratings. Once in memory the data
exists as  STL containers that contain my custom classes. It works
speedily cross-platform, and hence I saw no benefit in re-writing the
Mac code using Cocoa containers.

If it's your code, rather than someone else's for which you're providing
the Mac port, I might suggest looking into an actual DBMS. If SQLite's
up to the job it can probably reduce the amount of code you're
maintaining.

and what led you to looking into Cocoa's persistence
mechanisms with such objects?

The only bottleneck is parsing an 800Mb text file of this database
from disk at startup which takes about 15 seconds; I thought I might
improve this by saving and reading a copy of it in binary form. From
the examples I'd seen, it looked like Cocoa was doing everything from
flattening the data to saving it; I wasn't sure why, or if, this was
limited to Cocoa containers. I am disappointed that I have to flatten
the class data myself, as this was the bulk of the work, but at least
now I understand how to use writetoFile:.

What I'm still a little puzzled about is whether - even if you've
embraced Cocoa - you still use, say, simple C arrays[] (or structs )
occasionally when there is no need for anything more complex?

Of course.

What
would happen in the simplest case where your data is adequately
represented by an array of doubles and you want to save it to disk? Do
you have to memory copy the array in to a byte stream and write it to
disk like the old days, or can you store an array of doubles as a
single object in a Cocoa container, and trick it in to flattening the
data for you?

NSCoder - the base class from which NSArchiver and NSKeyedArchiver
derive - provides a mechanism for archiving and extracting standard C
arrays. To flatten, send encodeArrayOfObjCType:count:at: to the coder
with the first argument being an @encode() directive.

--
"Harry?" Ron's voice was a mere whisper. "Do you smell something ... burning?"
   - Harry Potter and the Odor of the Phoenix

OK, I need to go and experiment with some pure Cocoa examples so I can
learn about the classes you've mentioned.
Also, ncodeArrayOfObjCType:count:at:    sounds like it could be
perfect if I write a little bridging code.

Thanks again for the clear advice.

Steve

Forgot to mention...
How are you tracking where each individual object begins in your
flattened stream of thousands of items?

Where the data doesn't conform to a known, repeating size, I'm simply
writing a 'length' number before each chunk.
Not great, but enough to see that writeToFile was working.

.



Relevant Pages

  • Re: How to save C++ objects using Cocoa?
    ... from my perspective it seems like with a byte stream I have to invent ... have to archive the array. ... imply that Cocoa streamlines the whole lot; ... flattening the data to saving it; I wasn't sure why, or if, this was ...
    (comp.sys.mac.programmer.help)
  • Re: How to save C++ objects using Cocoa?
    ... NSKeyedArchiver's archiveRootObject:toFile: method, using the array ... from my perspective it seems like with a byte stream I have to invent ... I was confused between the flattening, and the writing process, but I ... imply that Cocoa streamlines the whole lot; ...
    (comp.sys.mac.programmer.help)
  • Re: How to save C++ objects using Cocoa?
    ... method (with the NSData instance as the ... NSKeyedArchiver's archiveRootObject:toFile: method, using the array ... I was confused between the flattening, and the writing process, but I ... imply that Cocoa streamlines the whole lot; ...
    (comp.sys.mac.programmer.help)
  • Re: increasing the size of a byte array and reading streams
    ... > reading the stream below (where buf is a byte array). ... When you're reading a file, for example, and you know that the file is ... There are times, however, when it makes sense to read a stream in small ... write those uncompressed bytes to your secondary MemoryStream. ...
    (microsoft.public.dotnet.languages.csharp)
  • RE: Handling blank lines in while(<CONF>) construct
    ... This is the terminal code to produce a yellow text output. ... If I were watching my maillog file stream past, ... This array is created dynamically by the code ... I posted the code to the list yesterday, ...
    (perl.beginners)