|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.0 (the 'License'). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License."
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24: /*
25: StreamTable.m
26: Pickling data structures
27: Copyright 1989, NeXT, Inc.
28: Responsability: Bertrand Serlet
29:
30: */
31:
32: #ifndef KERNEL
33: #ifdef SHLIB
34: #import "shlib.h"
35: #endif SHLIB
36:
37: #import <stdlib.h>
38: #import <stdio.h>
39: #import <string.h>
40: #import "StreamTable.h"
41:
42: typedef struct {
43: id object;
44: char *buffer;
45: int length;
46: } Pickle;
47:
48: @implementation StreamTable
49:
50: + newKeyDesc: (const char *) aKeyDesc {
51: return [super newKeyDesc: aKeyDesc valueDesc: "!"];
52: };
53:
54: + new {
55: return [self newKeyDesc: "@"];
56: };
57:
58: - initKeyDesc: (const char *) aKeyDesc {
59: return [self initKeyDesc: aKeyDesc valueDesc: "!"];
60: };
61:
62: - init {
63: return [self initKeyDesc: "@"];
64: };
65:
66: static void freePickle (void *value) {
67: Pickle *pick;
68: if (! value) return;
69: pick = (Pickle *) value;
70: free (pick->buffer); /* we use free and not NXFreeObjectBuffer because malloc was used for creation */
71: free (pick);
72: };
73:
74: static void freePickleAndObject (void *value) {
75: Pickle *pick;
76: if (! value) return;
77: pick = (Pickle *) value;
78: [pick->object free];
79: free (pick->buffer); /* we use free and not NXFreeObjectBuffer because malloc was used for creation */
80: free (pick);
81: };
82:
83: static id getObject (void *value, NXZone *zone) {
84: Pickle *pick;
85: if (! value) return nil;
86: pick = (Pickle *) value;
87: if (! pick->object)
88: pick->object = NXReadObjectFromBufferWithZone (pick->buffer, pick->length, zone);
89: return pick->object;
90: };
91:
92: static void freeObject (void *item) {
93: [(id) item free];
94: };
95:
96: static void noFree (void *item) {
97: };
98:
99: - free {
100: [self freeKeys: noFree values: freePickle];
101: return [super free];
102: };
103:
104: - freeObjects {
105: return [self freeKeys: (keyDesc[0] == '@') ? freeObject : noFree values: freePickleAndObject];
106: };
107:
108: - (id) valueForStreamKey: (const void *) aKey {
109: void *value = [self valueForKey: aKey];
110: return getObject (value, [self zone]);
111: };
112:
113: - (id) insertStreamKey: (const void *) aKey value: (id) aValue {
114: Pickle *pick;
115: char *vmbuffer;
116: NXZone *zone = [self zone];
117:
118: pick = (Pickle *) NXZoneMalloc (zone, sizeof (Pickle));
119: vmbuffer = NXWriteRootObjectToBuffer ((id) aValue, &pick->length);
120: pick->buffer = NXZoneMalloc (zone, pick->length);
121: bcopy (vmbuffer, pick->buffer, pick->length);
122: NXFreeObjectBuffer (vmbuffer, pick->length);
123: pick->object = (id) aValue;
124: [self insertKey: aKey value: pick];
125: return nil;
126: };
127:
128: - (id) removeStreamKey: (const void *) aKey {
129: freePickle ([self removeKey: aKey]);
130: return nil;
131: };
132:
133: - (NXHashState) initStreamState {
134: return [self initState];
135: };
136:
137: - (BOOL) nextStreamState: (NXHashState *) aState key: (const void **) aKey value: (id *) aValue {
138: void *aux;
139: BOOL result = [self nextState: aState key: aKey value: &aux];
140: *aValue = getObject (aux, [self zone]);
141: return result;
142: };
143:
144: - write:(NXTypedStream *) stream
145: {
146: NXHashState state = [self initState];
147: const void *key;
148: Pickle *pick;
149: [super write: stream];
150: while ([self nextState: &state key: &key value: (void **) &pick]) {
151: NXWriteType (stream, keyDesc, &key);
152: NXWriteType (stream, "i", &pick->length);
153: NXWriteArray (stream, "c", pick->length, pick->buffer);
154: };
155: return self;
156: }
157:
158: - read:(NXTypedStream *) stream
159: {
160: int nb;
161: NXZone *zone = [self zone];
162:
163: [super read: stream];
164: nb = count;
165: while (nb--) {
166: const void *key;
167: Pickle *pick = (Pickle *) NXZoneMalloc (zone, sizeof (Pickle));
168: NXReadType (stream, keyDesc, &key);
169: NXReadType (stream, "i", &pick->length);
170: pick->buffer = (char *) NXZoneMalloc (zone, pick->length);
171: NXReadArray (stream, "c", pick->length, pick->buffer);
172: pick->object = nil;
173: [self insertKey: key value: pick];
174: };
175: return self;
176: }
177:
178:
179: @end
180:
181:
182: #endif /* KERNEL */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.