• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <webrtc/SDP.h>
18 
19 #include "Utils.h"
20 
21 #include <android-base/logging.h>
22 
23 #include <cerrno>
24 #include <iostream>
25 
SDP()26 SDP::SDP()
27     : mInitCheck(-ENODEV),
28       mNewSectionEditorActive(false) {
29 }
30 
initCheck() const31 int SDP::initCheck() const {
32     return mInitCheck;
33 }
34 
countSections() const35 size_t SDP::countSections() const {
36     CHECK(!mInitCheck);
37     return mLineIndexBySection.size();
38 }
39 
clear()40 void SDP::clear() {
41     mInitCheck = -ENODEV;
42     mLines.clear();
43     mLineIndexBySection.clear();
44 }
45 
setTo(const std::string & data)46 int SDP::setTo(const std::string &data) {
47     clear();
48 
49     mLines = SplitString(data, "\r\n");
50 
51     LOG(VERBOSE) << "SDP contained " << mLines.size() << " lines.";
52 
53     mLineIndexBySection.push_back(0);
54 
55     mInitCheck = 0;
56 
57     for (size_t i = 0; i < mLines.size(); ++i) {
58         const auto &line = mLines[i];
59 
60         LOG(VERBOSE) << "Line #" << i << ": " << line;
61 
62         if (i == 0 && line != "v=0") {
63             mInitCheck = -EINVAL;
64             break;
65         }
66 
67         if (line.size() < 2 || line[1] != '=') {
68             mInitCheck = -EINVAL;
69             break;
70         }
71 
72         if (line[0] == 'm') {
73             mLineIndexBySection.push_back(i);
74         }
75     }
76 
77     return mInitCheck;
78 }
79 
getSectionRange(size_t section,size_t * lineStartIndex,size_t * lineStopIndex) const80 void SDP::getSectionRange(
81         size_t section, size_t *lineStartIndex, size_t *lineStopIndex) const {
82     CHECK(!mInitCheck);
83     CHECK_LT(section, mLineIndexBySection.size());
84 
85     if (lineStartIndex) {
86         *lineStartIndex = mLineIndexBySection[section];
87     }
88 
89     if (lineStopIndex) {
90         if (section + 1 < mLineIndexBySection.size()) {
91             *lineStopIndex = mLineIndexBySection[section + 1];
92         } else {
93             *lineStopIndex = mLines.size();
94         }
95     }
96 }
97 
section_begin(size_t section) const98 std::vector<std::string>::const_iterator SDP::section_begin(
99         size_t section) const {
100 
101     size_t startLineIndex;
102     getSectionRange(section, &startLineIndex, nullptr /* lineStopIndex */);
103 
104     return mLines.cbegin() + startLineIndex;
105 }
106 
section_end(size_t section) const107 std::vector<std::string>::const_iterator SDP::section_end(
108         size_t section) const {
109 
110     size_t stopLineIndex;
111     getSectionRange(section, nullptr /* lineStartIndex */, &stopLineIndex);
112 
113     return mLines.cbegin() + stopLineIndex;
114 }
115 
createSection()116 SDP::SectionEditor SDP::createSection() {
117     CHECK(!mNewSectionEditorActive);
118     mNewSectionEditorActive = true;
119 
120     if (mInitCheck) {
121         clear();
122         mInitCheck = 0;
123     }
124 
125     return SectionEditor(this, countSections());
126 }
127 
appendToSection(size_t section)128 SDP::SectionEditor SDP::appendToSection(size_t section) {
129     CHECK_LT(section, countSections());
130     return SectionEditor(this, section);
131 }
132 
commitSectionEdit(size_t section,const std::vector<std::string> & lines)133 void SDP::commitSectionEdit(
134         size_t section, const std::vector<std::string> &lines) {
135 
136     CHECK_LE(section, countSections());
137 
138     if (section == countSections()) {
139         // This was an edit creating a new section.
140         mLineIndexBySection.push_back(mLines.size());
141 
142         mLines.insert(mLines.end(), lines.begin(), lines.end());
143 
144         mNewSectionEditorActive = false;
145         return;
146     }
147 
148     mLines.insert(section_end(section), lines.begin(), lines.end());
149 
150     if (section + 1 < countSections()) {
151         mLineIndexBySection[section + 1] += lines.size();
152     }
153 }
154 
155 ////////////////////////////////////////////////////////////////////////////////
156 
SectionEditor(SDP * sdp,size_t section)157 SDP::SectionEditor::SectionEditor(SDP *sdp, size_t section)
158     : mSDP(sdp),
159       mSection(section) {
160 }
161 
~SectionEditor()162 SDP::SectionEditor::~SectionEditor() {
163     commit();
164 }
165 
operator <<(std::string_view s)166 SDP::SectionEditor &SDP::SectionEditor::operator<<(std::string_view s) {
167     mBuffer.append(s);
168 
169     return *this;
170 }
171 
commit()172 void SDP::SectionEditor::commit() {
173     if (mSDP) {
174         auto lines = SplitString(mBuffer, "\r\n");
175 
176         mSDP->commitSectionEdit(mSection, lines);
177         mSDP = nullptr;
178     }
179 }
180