1 /*
2 SuperCollider real time audio synthesis system
3 Copyright (c) 2002 James McCartney. All rights reserved.
4 http://www.audiosynth.com
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20 /*
21
22 An object archiving system for SuperCollider.
23
24 */
25
26 #include "PyrArchiverT.h"
27 #include "PyrKernel.h"
28 #include "PyrPrimitive.h"
29 #include "VMGlobals.h"
30 #include "GC.h"
31 #include "ReadWriteMacros.h"
32
33 int prAsArchive(struct VMGlobals* g, int numArgsPushed);
prAsArchive(struct VMGlobals * g,int numArgsPushed)34 int prAsArchive(struct VMGlobals* g, int numArgsPushed) {
35 PyrSlot* a = g->sp;
36
37 PyrArchiver<char*> arch(g);
38
39 int err = arch.prepareToWriteArchive(a);
40 if (err)
41 return err;
42
43 int32 size = arch.calcArchiveSize();
44
45 PyrInt8Array* obj = newPyrInt8Array(g->gc, size, 0, true);
46 obj->size = size;
47 arch.setStream((char*)obj->b);
48 err = arch.writeArchive();
49
50 if (err == errNone)
51 SetObject(a, obj);
52 else
53 SetNil(a);
54
55 return err;
56 }
57
58 int prUnarchive(struct VMGlobals* g, int numArgsPushed);
prUnarchive(struct VMGlobals * g,int numArgsPushed)59 int prUnarchive(struct VMGlobals* g, int numArgsPushed) {
60 PyrSlot* a = g->sp;
61
62 if (!isKindOfSlot(a, class_int8array))
63 return errWrongType;
64
65 PyrArchiver<char*> arch(g);
66
67 arch.setStream((char*)slotRawObject(a)->slots);
68 int err = arch.readArchive(a);
69 return err;
70 }
71
72 int prWriteArchive(struct VMGlobals* g, int numArgsPushed);
prWriteArchive(struct VMGlobals * g,int numArgsPushed)73 int prWriteArchive(struct VMGlobals* g, int numArgsPushed) {
74 PyrSlot* a = g->sp - 1;
75 PyrSlot* b = g->sp;
76
77 if (!isKindOfSlot(b, class_string))
78 return errWrongType;
79
80 char pathname[PATH_MAX];
81 memcpy(pathname, slotRawString(b)->s, slotRawObject(b)->size);
82 pathname[slotRawString(b)->size] = 0;
83
84 PyrArchiver<FILE*> arch(g);
85 FILE* file = fopen(pathname, "wb");
86 int err = errNone;
87 if (file) {
88 err = arch.prepareToWriteArchive(a);
89 if (!err) {
90 arch.setStream(file);
91 err = arch.writeArchive();
92 }
93 fclose(file);
94 } else {
95 error("file open failed\n");
96 err = errFailed;
97 }
98 return err;
99 }
100
101 int prReadArchive(struct VMGlobals* g, int numArgsPushed);
prReadArchive(struct VMGlobals * g,int numArgsPushed)102 int prReadArchive(struct VMGlobals* g, int numArgsPushed) {
103 PyrSlot* a = g->sp - 1;
104 PyrSlot* b = g->sp;
105
106 if (!isKindOfSlot(b, class_string))
107 return errWrongType;
108
109 char pathname[PATH_MAX];
110 memcpy(pathname, slotRawString(b)->s, slotRawObject(b)->size);
111 pathname[slotRawString(b)->size] = 0;
112
113 PyrArchiver<FILE*> arch(g);
114 FILE* file = fopen(pathname, "rb");
115
116 int err;
117 if (file) {
118 arch.setStream(file);
119 err = arch.readArchive(a);
120 fclose(file);
121 } else {
122 error("file open failed\n");
123 err = errFailed;
124 }
125 return err;
126 }
127
128 void initArchiverPrimitives();
initArchiverPrimitives()129 void initArchiverPrimitives() {
130 int base, index;
131
132 base = nextPrimitiveIndex();
133 index = 0;
134
135 definePrimitive(base, index++, "_AsArchive", prAsArchive, 1, 0);
136 definePrimitive(base, index++, "_Unarchive", prUnarchive, 1, 0);
137 definePrimitive(base, index++, "_WriteArchive", prWriteArchive, 2, 0);
138 definePrimitive(base, index++, "_ReadArchive", prReadArchive, 2, 0);
139 }
140
141
142 #if _SC_PLUGINS_
143
144 # include "SCPlugin.h"
145
146 // export the function that SC will call to load the plug in.
147 # pragma export on
148 extern "C" {
149 SCPlugIn* loadPlugIn(void);
150 }
151 # pragma export off
152
153
154 // define plug in object
155 class APlugIn : public SCPlugIn {
156 public:
157 APlugIn();
158 virtual ~APlugIn();
159
160 virtual void AboutToCompile();
161 };
162
APlugIn()163 APlugIn::APlugIn() {
164 // constructor for plug in
165 }
166
~APlugIn()167 APlugIn::~APlugIn() {
168 // destructor for plug in
169 }
170
AboutToCompile()171 void APlugIn::AboutToCompile() {
172 // this is called each time the class library is compiled.
173 initArchiverPrimitives();
174 }
175
176 // This function is called when the plug in is loaded into SC.
177 // It returns an instance of APlugIn.
loadPlugIn()178 SCPlugIn* loadPlugIn() { return new APlugIn(); }
179
180 #endif
181