1 /*
2  * MFString.cpp
3  *
4  * Copyright (C) 1999 Stephen F. White
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 (see the file "COPYING" for details); if
18  * not, write to the Free Software Foundation, Inc., 675 Mass Ave,
19  * Cambridge, MA 02139, USA.
20  */
21 
22 #include <stdio.h>
23 #include "stdafx.h"
24 
25 #include "MFString.h"
26 #include "SFString.h"
27 #include "DuneApp.h"
28 #include "swt.h"
29 
MFString()30 MFString::MFString()
31 {
32 }
33 
MFString(StringArray * values)34 MFString::MFString(StringArray *values)
35 {
36     m_value.setData(values->getData(), values->size());
37 }
38 
MFString(MyString value)39 MFString::MFString(MyString value)
40 {
41     m_value.resize(0);
42     m_value.append(value);
43 }
44 
MFString(const MFString & string)45 MFString::MFString(const MFString &string)
46 {
47     m_value.setData(string.getValues(), string.getSize());
48 }
49 
~MFString()50 MFString::~MFString()
51 {
52     if (m_value.size() > 0)
53         m_value.resize(0);
54 }
55 
56 MyString
getString(int index,int stride) const57 MFString::getString(int index, int stride) const
58 {
59     MyString ret = "";
60     ret += '"';
61     ret += m_value[index];
62     ret += '"';
63     ret.gsub("\n", "\\n");
64     ret.gsub("\r", "\\r");
65     return ret;
66 
67 }
68 
69 FieldValue *
copy()70 MFString::copy()
71 {
72     StringArray *value= new StringArray();
73     for (long i = 0;i < m_value.size(); i++)
74         value->append(*new MyString(m_value[i]));
75     return new MFString(value);
76 }
77 
writeDataC(int f,int i,int languageFlag) const78 int MFString::writeDataC(int f, int i, int languageFlag) const
79 {
80     MyString value = "";
81     value += m_value[i];
82     bool hasEndN = false;
83     if (value.length() > 0  && value[value.length() - 1] == '\n')
84         hasEndN = true;
85     value.gsub("\n", " \\");
86 //    if (hasEndN)
87 //        value.setChar(value.length() - 1, '\n');
88     value.gsub("\\", " \\\n");
89     value.gsub("\r", "\\r");
90     RET_ONERROR( mywritestr(f, "\"") )
91     RET_ONERROR( mywritestr(f, value) )
92     RET_ONERROR( mywritestr(f, "\"") )
93     return(0);
94 }
95 
writeData(int f,int i) const96 int MFString::writeData(int f, int i) const
97 {
98     RET_ONERROR( mywritestr(f, "\"") )
99     RET_ONERROR( mywritestr(f, m_value[i]) )
100     RET_ONERROR( mywritestr(f, "\"") )
101     return(0);
102 }
103 
writeDataXml(int f,int i) const104 int MFString::writeDataXml(int f, int i) const
105 {
106     MyString string = "";
107     string += m_value[i];
108     string.gsub("&", "&amp;");
109     string.gsub("\\\"", "\\&quot;");
110     string.gsub("'", "&apos;");
111     string.gsub(">", "&gt;");
112     string.gsub("<", "&lt;");
113     RET_ONERROR( mywritestr(f, "\"") )
114     RET_ONERROR( mywritestr(f, string) )
115     RET_ONERROR( mywritestr(f, "\"") )
116     return(0);
117 }
118 
write4FieldPipe(int filedes,int indent) const119 int MFString::write4FieldPipe(int filedes, int indent) const
120 {
121     for (int i = 0; i < getSFSize(); i++) {
122         RET_ONERROR( ((FieldValue *)this)->writeDequoted(filedes, m_value[i]) )
123         RET_ONERROR( mywritestr(filedes, "\n") )
124     }
125     return(0);
126 }
127 
writeRaw(int f,int indent) const128 int MFString::writeRaw(int f, int indent) const
129 {
130     for (int i = 0; i < getSFSize(); i++) {
131         RET_ONERROR( indentf(f, indent) )
132         RET_ONERROR( mywritestr(f, m_value[i]) )
133         RET_ONERROR( mywritestr(f, "\n") )
134         TheApp->incSelectionLinenumber();
135         if (i != 0 && i != getSFSize() - 1) {
136             RET_ONERROR( mywritestr(f, "\"\n\"") )
137             TheApp->incSelectionLinenumber();
138         }
139     }
140     return(0);
141 }
142 
143 int
writeCWonderlandArt(int filedes,const char * variableName,int languageFlag) const144 MFString::writeCWonderlandArt(int filedes, const char* variableName,
145                               int languageFlag) const
146 {
147     RET_ONERROR( mywritestr(filedes, "m_") );
148     RET_ONERROR( mywritestr(filedes, variableName) );
149     if (getSFSize() == 0) {
150         RET_ONERROR( mywritestr(filedes, "[1];\n") );
151         return 0;
152     }
153     RET_ONERROR( mywritestr(filedes, "[] = { ") );
154     for (int i = 0; i < getSFSize(); i++) {
155         RET_ONERROR( TheApp->writeWonderlandModuleArtPath(filedes, m_value[i]) )
156         if (i < (getSFSize() - 1))
157             RET_ONERROR( mywritestr(filedes, ", ") );
158     }
159     RET_ONERROR( mywritestr(filedes, " };\n") );
160     return 0;
161 }
162 
163 const char *
getTypeC(int languageFlag) const164 MFString::getTypeC(int languageFlag) const
165 {
166     if (languageFlag & JAVA_SOURCE)
167         return "String";
168     return "const char*";
169 }
170 
171 bool
readLine(int index,char * line)172 MFString::readLine(int index, char *line)
173 {
174     m_value.set(index, line);
175     return true;
176 }
177 
178 bool
equals(const FieldValue * value) const179 MFString::equals(const FieldValue *value) const
180 {
181     if (value->getType() == MFSTRING) {
182         MFString *v = (MFString *) value;
183         if (v->getSize() != (int)m_value.size()) return false;
184         for (long i = 0; i < m_value.size(); i++)
185             if (v->getValue(i) != m_value[i]) return false;
186         return true;
187     }
188     return false;
189 }
190 
191 FieldValue *
getSFValue(int index) const192 MFString::getSFValue(int index) const
193 {
194     return new SFString(m_value[index]);
195 }
196 
197 void
setSFValue(int index,FieldValue * value)198 MFString::setSFValue(int index, FieldValue *value)
199 {
200     m_value.set(index, ((SFString *) value)->getValue());
201 }
202 
203 void
setSFValue(int index,const char * value)204 MFString::setSFValue(int index, const char* value)
205 {
206     m_value.set(index, value);
207 }
208 
209 
210 MyString
getEcmaScriptComment(MyString name,int flags) const211 MFString::getEcmaScriptComment(MyString name, int flags) const
212 {
213     const char *indent = ((FieldValue *)this)->getEcmaScriptIndent(flags);
214     MyString ret;
215     ret = "";
216     if (TheApp->GetEcmaScriptAddAllowedValues()) {
217         ret += indent;
218         ret += "// allowed values:\n";
219 
220         ret += indent;
221         ret += "   // array ([0] [1] [2] ...) of 'string value's \n";
222     }
223     if (TheApp->GetEcmaScriptAddAvailableFunctions()) {
224         ret += indent;
225         ret += "// available functions:\n";
226         if (flags != EL_EVENT_IN) {
227             ret += indent;
228             ret += "   // ";
229             ret += name;
230             ret += " = new MFString(string_s1, string_s2, ...);\n";
231         }
232         if (flags != EL_EVENT_OUT) {
233             ret += indent;
234             ret += "   // int_i = ";
235             ret += name;
236             ret += ".length();\n";
237 
238             ret += indent;
239             ret += "   // string_str = ";
240             ret += name;
241             ret += ".toString();\n";
242        }
243     }
244     if (TheApp->GetEcmaScriptAddBrowserObject()) {
245         if (flags != EL_EVENT_OUT) {
246             ret += indent;
247             ret += "// related Browser Object functions:\n";
248 
249             ret += indent;
250             ret += "   // Browser.createVrmlFromURL(";
251             ret += name;
252             ret += ", sfnode_n, string_event);\n";
253 
254             ret += indent;
255             ret += "   // Browser.loadURL(";
256             ret += name;
257             ret += ", mfstring_parameter);\n";
258         }
259     }
260     if (TheApp->GetEcmaScriptAddExampleUsage()) {
261         ret += indent;
262         ret += "// example usage:\n";
263         if (flags != EL_EVENT_IN) {
264             ret += indent;
265             ret += "   // ";
266             ret += name;
267             ret += " = new MFString('hello','world');\n";
268 
269             ret += indent;
270             ret += "   // ";
271             ret += name;
272             ret += "[0] = ' hello ';\n";
273 
274             ret += indent;
275             ret += "   // ";
276             ret += name;
277             ret += "[1] = Browser.getName();\n";
278 
279         }
280         if (flags != EL_EVENT_OUT) {
281             ret += indent;
282             ret += "   // Browser.loadURL(";
283             ret += name;
284             ret += ", new MFString());\n";
285         }
286     }
287     return ret;
288 }
289 
290 void
insertSFValue(int index,FieldValue * value)291 MFString::insertSFValue(int index, FieldValue *value)
292 {
293     if (value->getType() != SFSTRING)
294         assert(0);
295     m_value.insert(((SFString *)value)->getValue(), index);
296 }
297 
298 void
insertSFValue(int index,const char * value)299 MFString::insertSFValue(int index, const char* value)
300 {
301     m_value.insert(value, index);
302 }
303 
304 FieldValue *
getRandom(Scene * scene,int nodeType)305 MFString::getRandom(Scene *scene, int nodeType)
306 {
307     StringArray *values = new StringArray();
308     for (int i = 0; i < INT_RAND(); i++) {
309         MyString newString = "";
310         for (int j = 0; j < INT_RAND(); j++) {
311             char newChar = (char)('0' + RAND() * (126 - '0'));
312             if ((newChar != '\\') && (newChar != '"'))
313                 newString += newChar;
314         }
315         values->append(newString);
316     }
317     return new MFString(values);
318 }
319