Fix coverity #29352
[supertux.git] / src / scripting / serialize.cpp
1 //  SuperTux
2 //  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
3 //
4 //  This program is free software: you can redistribute it and/or modify
5 //  it under the terms of the GNU General Public License as published by
6 //  the Free Software Foundation, either version 3 of the License, or
7 //  (at your option) any later version.
8 //
9 //  This program is distributed in the hope that it will be useful,
10 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 //  GNU General Public License for more details.
13 //
14 //  You should have received a copy of the GNU General Public License
15 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
17 #include "scripting/serialize.hpp"
18
19 #include <iostream>
20
21 #include "lisp/writer.hpp"
22 #include "lisp/list_iterator.hpp"
23 #include "scripting/squirrel_error.hpp"
24
25 namespace scripting {
26
27 void load_squirrel_table(HSQUIRRELVM vm, SQInteger table_idx, const Reader& lisp)
28 {
29   using namespace lisp;
30
31   if(table_idx < 0)
32     table_idx -= 2;
33
34   lisp::ListIterator iter(&lisp);
35   while(iter.next() && iter.lisp() != NULL) {
36     const std::string& token = iter.item();
37     sq_pushstring(vm, token.c_str(), token.size());
38
39     const lisp::Lisp* value = iter.value();
40     switch(value->get_type()) {
41       case Lisp::TYPE_CONS:
42         sq_newtable(vm);
43         load_squirrel_table(vm, sq_gettop(vm), *iter.lisp());
44         break;
45       case Lisp::TYPE_INTEGER:
46         sq_pushinteger(vm, value->get_int());
47         break;
48       case Lisp::TYPE_REAL:
49         sq_pushfloat(vm, value->get_float());
50         break;
51       case Lisp::TYPE_STRING:
52         sq_pushstring(vm, value->get_string().c_str(), -1);
53         break;
54       case Lisp::TYPE_BOOLEAN:
55         sq_pushbool(vm, value->get_bool() ? SQTrue : SQFalse);
56         break;
57       case Lisp::TYPE_SYMBOL:
58         std::cerr << "Unexpected symbol in lisp file...";
59         sq_pushnull(vm);
60         break;
61       default:
62         assert(false);
63         break;
64     }
65
66     if(SQ_FAILED(sq_createslot(vm, table_idx)))
67       throw scripting::SquirrelError(vm, "Couldn't create new index");
68   }
69 }
70
71 void save_squirrel_table(HSQUIRRELVM vm, SQInteger table_idx, Writer& writer)
72 {
73   // offset because of sq_pushnull
74   if(table_idx < 0)
75     table_idx -= 1;
76
77   //iterator table
78   sq_pushnull(vm);
79   while(SQ_SUCCEEDED(sq_next(vm, table_idx))) {
80     if(sq_gettype(vm, -2) != OT_STRING) {
81       std::cerr << "Table contains non-string key\n";
82       continue;
83     }
84     const SQChar* key;
85     sq_getstring(vm, -2, &key);
86
87     switch(sq_gettype(vm, -1)) {
88       case OT_INTEGER: {
89         SQInteger val;
90         sq_getinteger(vm, -1, &val);
91         writer.write(key, static_cast<int> (val));
92         break;
93       }
94       case OT_FLOAT: {
95         SQFloat val;
96         sq_getfloat(vm, -1, &val);
97         writer.write(key, static_cast<float> (val));
98         break;
99       }
100       case OT_BOOL: {
101         SQBool val;
102         if(SQ_SUCCEEDED(sq_getbool(vm, -1, &val)))
103           writer.write(key, val == SQTrue);
104         break;
105       }
106       case OT_STRING: {
107         const SQChar* str;
108         sq_getstring(vm, -1, &str);
109         writer.write(key, reinterpret_cast<const char*> (str));
110         break;
111       }
112       case OT_TABLE: {
113         writer.start_list(key, true);
114         save_squirrel_table(vm, -1, writer);
115         writer.end_list(key);
116         break;
117       }
118       case OT_CLOSURE:
119         break; // ignore
120       case OT_NATIVECLOSURE:
121         break;
122       default:
123         std::cerr << "Can't serialize key '" << key << "' in table.\n";
124         break;
125     }
126     sq_pop(vm, 2);
127   }
128   sq_pop(vm, 1);
129 }
130
131 } // namespace scripting
132
133 /* EOF */