/* * Format: * `METHOD {signature} {return type}` (all freestanding methods) * \BLANK\ * `CLASS {name} {size in bytes}` * `MEMBER {name} {typeName} {offset in bytes}` * `METHOD {signature} {return type}` (actual methods) * (a `CLASS` starts a new class) * * NOTE: Everything's going to be Access::PUBLIC automatically, because this is an API */ void LibGenerator::AddFromFile(const std::string& path) { std::cout << "Adding library: " << path << std::endl; std::vector<std::string> lines = Util::Split(Util::LoadFile(path), '\n'); bool isInClass = false; ClassDef* currentClass; for (auto& line : lines) { if (line.empty()) continue; auto lineSplit = Util::Split(line, ' '); if (lineSplit[0] == "CLASS") { currentClass = new ClassDef(lineSplit[1], Attribs(), true); currentClass->typeSize = std::atoi(lineSplit[2].c_str()); m_parse.classes.push_back(currentClass); } else if (lineSplit[0] == "MEMBER") { VariableDef* varDef = new VariableDef(lineSplit[1], lineSplit[2], Attribs(), false); varDef->offset = std::atoi(lineSplit[3].c_str()); currentClass->memberVars.push_back(varDef); } else if (lineSplit[0] == "METHOD") { // TODO std::vector<VariableDef*> params; std::vector<VariableDef*> locals; Attribs attribs(Attribs::Access::PUBLIC, false, false); MethodDef* method = new MethodDef(lineSplit[1], attribs, params, locals, lineSplit[2], nullptr, true); if (isInClass) currentClass->methods.push_back(method); else m_parse.methods.push_back(method); } else { std::cerr << "WARNING: Malformed library file (" << path << ") - skipping this library!" << std::endl; return; } } }
bool ASessionDescription::parse(const void *data, size_t size) { mTracks.clear(); mFormats.clear(); mTracks.push(Attribs()); mFormats.push(AString("[root]")); AString desc((const char *)data, size); size_t i = 0; for (;;) { ssize_t eolPos = desc.find("\n", i); if (eolPos < 0) { break; } AString line; if ((size_t)eolPos > i && desc.c_str()[eolPos - 1] == '\r') { // We accept both '\n' and '\r\n' line endings, if it's // the latter, strip the '\r' as well. line.setTo(desc, i, eolPos - i - 1); } else { line.setTo(desc, i, eolPos - i); } if (line.empty()) { i = eolPos + 1; continue; } if (line.size() < 2 || line.c_str()[1] != '=') { return false; } ALOGI("%s", line.c_str()); switch (line.c_str()[0]) { case 'v': { if (strcmp(line.c_str(), "v=0")) { return false; } break; } case 'a': case 'b': { AString key, value; ssize_t colonPos = line.find(":", 2); if (colonPos < 0) { key = line; } else { key.setTo(line, 0, colonPos); if (key == "a=fmtp" || key == "a=rtpmap" || key == "a=framesize") { ssize_t spacePos = line.find(" ", colonPos + 1); if (spacePos < 0) { return false; } key.setTo(line, 0, spacePos); colonPos = spacePos; } value.setTo(line, colonPos + 1, line.size() - colonPos - 1); } key.trim(); value.trim(); ALOGV("adding '%s' => '%s'", key.c_str(), value.c_str()); mTracks.editItemAt(mTracks.size() - 1).add(key, value); break; } case 'm': { ALOGV("new section '%s'", AString(line, 2, line.size() - 2).c_str()); mTracks.push(Attribs()); mFormats.push(AString(line, 2, line.size() - 2)); break; } default: { AString key, value; ssize_t equalPos = line.find("="); key = AString(line, 0, equalPos + 1); value = AString(line, equalPos + 1, line.size() - equalPos - 1); key.trim(); value.trim(); ALOGV("adding '%s' => '%s'", key.c_str(), value.c_str()); mTracks.editItemAt(mTracks.size() - 1).add(key, value); break; } } i = eolPos + 1; } return true; }
bool ASessionDescription::parse(const void *data, size_t size) { mTracks.clear(); mFormats.clear(); mTracks.push(Attribs()); mFormats.push(AString("[root]")); AString desc((const char *)data, size); #ifndef ANDROID_DEFAULT_CODE int rtpmapNum = 0; bool unsupported = false; #endif // #ifndef ANDROID_DEFAULT_CODE size_t i = 0; for (;;) { #ifndef ANDROID_DEFAULT_CODE if (i >= desc.size()) { break; } #endif // #ifndef ANDROID_DEFAULT_CODE ssize_t eolPos = desc.find("\n", i); if (eolPos < 0) { #ifndef ANDROID_DEFAULT_CODE eolPos = desc.size(); #else break; #endif // #ifndef ANDROID_DEFAULT_CODE } AString line; if ((size_t)eolPos > i && desc.c_str()[eolPos - 1] == '\r') { // We accept both '\n' and '\r\n' line endings, if it's // the latter, strip the '\r' as well. line.setTo(desc, i, eolPos - i - 1); } else { line.setTo(desc, i, eolPos - i); } if (line.empty()) { i = eolPos + 1; continue; } if (line.size() < 2 || line.c_str()[1] != '=') { return false; } #ifndef ANDROID_DEFAULT_CODE if (unsupported && line.c_str()[0] != 'm') { LOGI("skip %s in unsupported media description", line.c_str()); i = eolPos + 1; continue; } else #endif // #ifndef ANDROID_DEFAULT_CODE LOGI("%s", line.c_str()); switch (line.c_str()[0]) { case 'v': { if (strcmp(line.c_str(), "v=0")) { return false; } break; } case 'a': case 'b': { AString key, value; ssize_t colonPos = line.find(":", 2); if (colonPos < 0) { key = line; } else { key.setTo(line, 0, colonPos); if (key == "a=fmtp" || key == "a=rtpmap" || key == "a=framesize") { ssize_t spacePos = line.find(" ", colonPos + 1); if (spacePos < 0) { return false; } #ifndef ANDROID_DEFAULT_CODE if (key == "a=rtpmap") { if (rtpmapNum > 0) { mTracks.pop(); mFormats.pop(); unsupported = true; LOGW("ASessionDescription: multiple rtpmap" " for one media is not supported yet"); break; } else { rtpmapNum++; } } #endif // #ifndef ANDROID_DEFAULT_CODE key.setTo(line, 0, spacePos); colonPos = spacePos; } value.setTo(line, colonPos + 1, line.size() - colonPos - 1); } key.trim(); value.trim(); LOGV("adding '%s' => '%s'", key.c_str(), value.c_str()); mTracks.editItemAt(mTracks.size() - 1).add(key, value); break; } case 'm': { LOGV("new section '%s'", AString(line, 2, line.size() - 2).c_str()); #ifndef ANDROID_DEFAULT_CODE rtpmapNum = 0; unsupported = false; #endif // #ifndef ANDROID_DEFAULT_CODE mTracks.push(Attribs()); mFormats.push(AString(line, 2, line.size() - 2)); break; } default: { AString key, value; ssize_t equalPos = line.find("="); key = AString(line, 0, equalPos + 1); value = AString(line, equalPos + 1, line.size() - equalPos - 1); key.trim(); value.trim(); LOGV("adding '%s' => '%s'", key.c_str(), value.c_str()); mTracks.editItemAt(mTracks.size() - 1).add(key, value); break; } } i = eolPos + 1; } return true; }