LuaValue LuaTable::get(const LuaValue& k, bool raw) const { if (k.isTypeOf(LVT_Number)) { int idx = (int)k.getNumber() - 1; if (idx >= 0 && idx < (int)m_vec.size()) return m_vec[idx]; } auto iter = m_hashTable.find(k); if (iter != m_hashTable.end()) return iter->second; if (!raw && m_metaTable != NULL) { LuaValue f = m_metaTable->get(LuaValue("__index")); if (f.isTypeOf(LVT_Nil)) {} else if (f.isTypeOf(LVT_Table)) return f.getTable()->get(k); else if (f.isTypeOf(LVT_Function)) { vector<LuaValue> args, rets; { auto t = const_cast<LuaTable*>(this); t->addRef(); args.push_back(LuaValue(t)); args.push_back(k); } f.getFunction()->call(args, rets); if (!rets.empty()) return rets[0]; } else ASSERT(0); } return LuaValue::NIL; }
void LuaTable::set(const LuaValue& k, const LuaValue& v, bool raw) { if (!raw && m_metaTable != NULL && !v.isTypeOf(LVT_Nil)) { if (!hasKey(k)) { LuaValue f = m_metaTable->get(LuaValue("__newindex")); if (f.isTypeOf(LVT_Nil)) {} else if (f.isTypeOf(LVT_Table)) { f.getTable()->set(k, v); return; } else if (f.isTypeOf(LVT_Function)) { vector<LuaValue> args, rets; addRef(); args.push_back(LuaValue(this)); args.push_back(k); args.push_back(v); f.getFunction()->call(args, rets); return; } else ASSERT(0); } } if (k.isTypeOf(LVT_Number)) { int idx = (int)k.getNumber() - 1; if (idx >= 0 && idx < (int)m_vec.size()) { m_vec[idx] = v; return; } if (idx == (int)m_vec.size()) { m_vec.push_back(v); return; } } if (v.isTypeOf(LVT_Nil)) { m_hashTable.erase(k); } else m_hashTable[k] = v; return; }
void LuaValue::concatFrom(const LuaValue& l, const LuaValue& r) { if (l.isTypeOf(LVT_String)) { auto str1 = l.getString(), str2 = r.getString(); int nsize = str1->size() + str2->size(); vector<char> buf(nsize); if (nsize > 0) { memcpy(&buf[0], str1->buf(), str1->size()); memcpy(&buf[0] + str1->size(), str2->buf(), str2->size()); *this = LuaValue(&buf[0], nsize); } else { *this = LuaValue("", 0); } } else { *this = meta_concat(l.getTable(), r); } }