Esempio n. 1
0
/**
 * Parse an unknown data type.
 * This is not exposed to the world because it is expected that one would
 * know what type they are parsing to begin with. This is used by parseDictionary
 * and parseList to grab pieces of data which are of unknown type and parse them.
 *
 * @param reader the reader to get the stream of data from.
 * @param allocator the means of storing the parsed data.
 * @param output a pointer which will be pointed to the output.
 */
static int32_t parseGeneric(const struct Reader* reader,
                            const struct Allocator* allocator,
                            Object** output)
{
    #define OUT_OF_CONTENT_TO_READ -2
    #define UNPARSABLE -3

    int ret;
    char firstChar;
    ret = reader->read(&firstChar, 0, reader);
    if (ret != 0) {
        return OUT_OF_CONTENT_TO_READ;
    }

    Object* out = Allocator_malloc(allocator, sizeof(Object));

    if (firstChar <= '9' && firstChar >= '0') {
        /* It's a string! */
        String* string = NULL;
        ret = parseString(reader, allocator, &string);
        out->type = Object_STRING;
        out->as.string = string;
    } else {
        switch (firstChar) {
            case 'i':;
                /* int64_t. Int is special because it is not a pointer but a int64_t. */
                int64_t bint = 0;
                ret = parseint64_t(reader, &bint);
                out->type = Object_INTEGER;
                out->as.number = bint;
                break;
            case 'l':;
                /* List. */
                List* list = Allocator_calloc(allocator, sizeof(List), 1);
                ret = parseList(reader, allocator, list);
                out->type = Object_LIST;
                out->as.list = list;
                break;
            case 'd':;
                /* Dictionary. */
                Dict* dict = Allocator_calloc(allocator, sizeof(Dict), 1);
                ret = parseDictionary(reader, allocator, dict);
                out->type = Object_DICT;
                out->as.dictionary = dict;
                break;
            default:
                return UNPARSABLE;
        }
    }

    if (ret != 0) {
        /* Something went wrong while parsing. */
        return ret;
    }

    *output = out;
    return 0;

    #undef OUT_OF_CONTENT_TO_READ
    #undef UNPARSABLE
}
Esempio n. 2
0
static int32_t parseGeneric(const struct Reader* reader,
                            const struct Allocator* allocator,
                            Object** output)
{
    int ret = 0;
    char firstChar;

    for (;;) {
        ret = reader->read(&firstChar, 0, reader);
        switch (firstChar) {
            case ' ':
            case '\r':
            case '\n':
            case '\t':
                reader->skip(1, reader);
                continue;

            case '/':;
                if ((ret = parseComment(reader)) != 0) {
                    return ret;
                }
                continue;

            default:
                break;
        }
        if (ret) {
            printf("Unexpected end of input\n");
            return OUT_OF_CONTENT_TO_READ;
        }
        break;
    }

    Object* out = allocator->malloc(sizeof(Object), allocator);

    switch (firstChar) {
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':;
            // int64_t. Int is special because it is not a pointer but a int64_t.
            int64_t bint;
            ret = parseint64_t(reader, &bint);
            out->type = Object_INTEGER;
            out->as.number = bint;
            break;

        case '[':;
            // List.
            List* list = allocator->calloc(sizeof(List), 1, allocator);
            ret = parseList(reader, allocator, list);
            out->type = Object_LIST;
            out->as.list = list;
            break;

        case '{':;
            // Dictionary
            Dict* dict = allocator->calloc(sizeof(Dict), 1, allocator);
            ret = parseDictionary(reader, allocator, dict);
            out->type = Object_DICT;
            out->as.dictionary = dict;
            break;

        case '"':;
            // String
            String* string = NULL;
            ret = parseString(reader, allocator, &string);
            out->type = Object_STRING;
            out->as.string = string;
            break;

        default:
            printf("While looking for something to parse: "
                   "expected one of 0 1 2 3 4 5 6 7 8 9 [ { \", found '%c'\n", firstChar);
            return UNPARSABLE;
    }

    if (ret != 0) {
        // Something went wrong while parsing.
        return ret;
    }

    *output = out;
    return 0;
}
Esempio n. 3
0
BitTorrent::BitTorrent(std::string filename)
{
	std::fstream in(filename.c_str(),std::ios::in | std::ios::binary | std::ios::ate);
	char * contents = 0;
	
	if (in.is_open()){

		size_t size = in.tellg();
		contents = new char[size + 1];
		in.seekg(0, std::ios::beg);
		in.read(contents, size);
		contents[size] = 0;
		in.close();
	}

	ListType lst;
	DictionaryType dic;

	if (contents != 0){
		char * to_delete = contents;
		parseDictionary(contents, lst, dic);
		delete [] to_delete;
	}
	

	for (size_t i = 0; i < dic.getItems().size(); ++i){
		const auto & item = dic.getItems().at(i);
		auto  key = item.first;
		const auto & value = item.second;

		std::transform(key.begin(), key.end(), key.begin(), ::tolower);
		if (key == "announce"){
			assert(value->getType() == BType::STRING);
			this->announce_ = static_cast<StringType*>(value)->getValue();
		}
		else if (key == "announce-list"){
			assert(value->getType() == BType::LIST);
			auto & items = static_cast<ListType*>(value)->getItems();
			for (size_t j = 0; j < items.size(); ++j){
				auto & item = items[j];

				if (item->getType() == BType::STRING){
					const std::string & name = static_cast<StringType*>(item)->getValue();
					this->announce_list_.push_back(name);
				}
				
			}
		}
		else if (key == "comment"){
			assert(value->getType() == BType::STRING);
			this->comment_ = this->comment_utf_8_ =
				static_cast<StringType*>(value)->getValue();
		}
		else if (key == "creation date"){
			assert(value->getType() == BType::INTEGER);
			this->creation_date_ = static_cast<IntegerType*>(value)->getValue();
		}
		else if (key == "length"){
			assert(value->getType() == BType::INTEGER);
			this->info_.length = static_cast<IntegerType*>(value)->getValue();
		}
		else if (key == "name"){
			assert(value->getType() == BType::STRING);
			this->info_.name = this->info_.name_utf_8 =
				static_cast<StringType*>(value)->getValue();
		}
		else if (key == "piece length"){
			assert(value->getType() == BType::INTEGER);
			this->piece_length_ = static_cast<IntegerType*>(value)->getValue();
		}
		else if (key == "pieces"){
			assert(value->getType() == BType::STRING);
			this->pieces_ = static_cast<StringType*>(value)->getValue();
		}
		else if (key == "info"){
			// do nothing
		}
		else if (key == "httpseeds"){
			// do nothing
		}
		else if (key == "files"){
			THROW_BT_EXCEPTION("currrent don't support multi files");
		}
		else{
			THROW_BT_EXCEPTION("unexpected token");
		}
		
	}

	this->encoding_ = "utf-8";
}