/* This file is part of Ground Control. Ground Control is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Ground Control is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Ground Control. If not, see . */ #include "wren.h" #include "bencode.h" const char* read_int(const char* buf, int* out) { int result = 0; while (*buf != 'e') { int digit = *buf - '0'; result *= 10; result += digit; buf++; } buf++; *out = result; return buf; } static const char* bdecode_partial(WrenVM* vm, const char* buf) { wrenEnsureSlots(vm, 1); switch (*buf) { case 't': case 'f': { wrenSetSlotBool(vm, 0, *buf=='t'); buf++; break; } case 'n': { wrenSetSlotNull(vm, 0); buf++; break; } case 'i': { int value; buf++; buf = read_int(buf, &value); wrenSetSlotDouble(vm, 0, (double)value); break; } case 's': { int len; buf++; buf = read_int(buf, &len); wrenSetSlotBytes(vm, 0, buf, len); buf += len; break; } case 'l': { WrenHandle* list; buf++; wrenEnsureSlots(vm, 2); wrenSetSlotNewList(vm, 0); list = wrenGetSlotHandle(vm, 0); while (*buf != 'e') { buf = bdecode_partial(vm, buf); wrenSetSlotHandle(vm, 1, list); wrenInsertInList(vm, 1, -1, 0); } wrenSetSlotHandle(vm, 0, list); wrenReleaseHandle(vm, list); buf++; break; } case 'd': { WrenHandle* map; WrenHandle* key; buf++; wrenEnsureSlots(vm, 3); wrenSetSlotNewMap(vm, 0); map = wrenGetSlotHandle(vm, 0); while (*buf != 'e') { buf = bdecode_partial(vm, buf); key = wrenGetSlotHandle(vm, 0); buf = bdecode_partial(vm, buf); /* value is in slot 0 */ wrenSetSlotHandle(vm, 1, key); /* key is in slot 1 */ wrenReleaseHandle(vm, key); wrenSetSlotHandle(vm, 2, map); /* map is in slot 2 */ wrenSetMapValue(vm, 2, 1, 0); } wrenSetSlotHandle(vm, 0, map); wrenReleaseHandle(vm, map); buf++; break; } } return buf; } void bdecode(WrenVM* vm) { const char* buf = wrenGetSlotString(vm, 1); bdecode_partial(vm, buf); }