1bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber/* 2bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * Copyright 2012, The Android Open Source Project 3bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * 4bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * you may not use this file except in compliance with the License. 6bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * You may obtain a copy of the License at 7bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * 8bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * 10bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * Unless required by applicable law or agreed to in writing, software 11bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * See the License for the specific language governing permissions and 14bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * limitations under the License. 15bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber */ 16bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 17bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#include "ParsedMessage.h" 18bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 19bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#include <ctype.h> 20bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 21bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#include <media/stagefright/foundation/ADebug.h> 22bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 23bb197f84c4119651e5face418285688ddaf08ea3Andreas Hubernamespace android { 24bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 25bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber// static 26bb197f84c4119651e5face418285688ddaf08ea3Andreas Hubersp<ParsedMessage> ParsedMessage::Parse( 27bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber const char *data, size_t size, bool noMoreData, size_t *length) { 28bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber sp<ParsedMessage> msg = new ParsedMessage; 29bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ssize_t res = msg->parse(data, size, noMoreData); 30bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 31bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (res < 0) { 32bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber *length = 0; 33bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return NULL; 34bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 35bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 36bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber *length = res; 37bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return msg; 38bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 39bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 40bb197f84c4119651e5face418285688ddaf08ea3Andreas HuberParsedMessage::ParsedMessage() { 41bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 42bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 43bb197f84c4119651e5face418285688ddaf08ea3Andreas HuberParsedMessage::~ParsedMessage() { 44bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 45bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 46bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberbool ParsedMessage::findString(const char *name, AString *value) const { 47bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber AString key = name; 48bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber key.tolower(); 49bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 50bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ssize_t index = mDict.indexOfKey(key); 51bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 52bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (index < 0) { 53bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber value->clear(); 54bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 55bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return false; 56bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 57bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 58bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber *value = mDict.valueAt(index); 59bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return true; 60bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 61bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 62bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberbool ParsedMessage::findInt32(const char *name, int32_t *value) const { 63bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber AString stringValue; 64bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 65bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (!findString(name, &stringValue)) { 66bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return false; 67bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 68bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 69bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber char *end; 70bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber *value = strtol(stringValue.c_str(), &end, 10); 71bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 72bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (end == stringValue.c_str() || *end != '\0') { 73bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber *value = 0; 74bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return false; 75bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 76bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 77bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return true; 78bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 79bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 80bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberconst char *ParsedMessage::getContent() const { 81bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return mContent.c_str(); 82bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 83bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 84bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberssize_t ParsedMessage::parse(const char *data, size_t size, bool noMoreData) { 85bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (size == 0) { 86bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return -1; 87bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 88bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 89bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ssize_t lastDictIndex = -1; 90bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 91bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber size_t offset = 0; 92bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber while (offset < size) { 93bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber size_t lineEndOffset = offset; 94bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber while (lineEndOffset + 1 < size 95bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber && (data[lineEndOffset] != '\r' 96bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber || data[lineEndOffset + 1] != '\n')) { 97bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ++lineEndOffset; 98bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 99bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 100bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (lineEndOffset + 1 >= size) { 101bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return -1; 102bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 103bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 104bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber AString line(&data[offset], lineEndOffset - offset); 105bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 106bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (offset == 0) { 107bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber // Special handling for the request/status line. 108bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 109bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mDict.add(AString("_"), line); 110bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber offset = lineEndOffset + 2; 111bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 112bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber continue; 113bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 114bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 115bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (lineEndOffset == offset) { 116bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber offset += 2; 117bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber break; 118bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 119bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 120bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (line.c_str()[0] == ' ' || line.c_str()[0] == '\t') { 121bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber // Support for folded header values. 122bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 123bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (lastDictIndex >= 0) { 124bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber // Otherwise it's malformed since the first header line 125bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber // cannot continue anything... 126bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 127bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber AString &value = mDict.editValueAt(lastDictIndex); 128bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber value.append(line); 129bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 130bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 131bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber offset = lineEndOffset + 2; 132bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber continue; 133bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 134bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 135bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ssize_t colonPos = line.find(":"); 136bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (colonPos >= 0) { 137bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber AString key(line, 0, colonPos); 138bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber key.trim(); 139bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber key.tolower(); 140bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 141bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber line.erase(0, colonPos + 1); 142bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 143bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber lastDictIndex = mDict.add(key, line); 144bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 145bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 146bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber offset = lineEndOffset + 2; 147bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 148bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 149bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber for (size_t i = 0; i < mDict.size(); ++i) { 150bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mDict.editValueAt(i).trim(); 151bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 152bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 153bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber // Found the end of headers. 154bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 155bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int32_t contentLength; 156bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (!findInt32("content-length", &contentLength) || contentLength < 0) { 157bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber contentLength = 0; 158bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 159bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 160bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber size_t totalLength = offset + contentLength; 161bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 162bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (size < totalLength) { 163bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return -1; 164bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 165bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 166bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mContent.setTo(&data[offset], contentLength); 167bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 168bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return totalLength; 169bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 170bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 171bb197f84c4119651e5face418285688ddaf08ea3Andreas Hubervoid ParsedMessage::getRequestField(size_t index, AString *field) const { 172bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber AString line; 173bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber CHECK(findString("_", &line)); 174bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 175bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber size_t prevOffset = 0; 176bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber size_t offset = 0; 177bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber for (size_t i = 0; i <= index; ++i) { 178bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ssize_t spacePos = line.find(" ", offset); 179bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 180bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (spacePos < 0) { 181bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber spacePos = line.size(); 182bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 183bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 184bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber prevOffset = offset; 185bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber offset = spacePos + 1; 186bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 187bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 188bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber field->setTo(line, prevOffset, offset - prevOffset - 1); 189bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 190bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 191bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberbool ParsedMessage::getStatusCode(int32_t *statusCode) const { 192bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber AString statusCodeString; 193bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber getRequestField(1, &statusCodeString); 194bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 195bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber char *end; 196bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber *statusCode = strtol(statusCodeString.c_str(), &end, 10); 197bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 198bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (*end != '\0' || end == statusCodeString.c_str() 199bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber || (*statusCode) < 100 || (*statusCode) > 999) { 200bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber *statusCode = 0; 201bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return false; 202bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 203bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 204bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return true; 205bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 206bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 207bb197f84c4119651e5face418285688ddaf08ea3Andreas HuberAString ParsedMessage::debugString() const { 208bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber AString line; 209bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber CHECK(findString("_", &line)); 210bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 211bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber line.append("\n"); 212bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 213bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber for (size_t i = 0; i < mDict.size(); ++i) { 214bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber const AString &key = mDict.keyAt(i); 215bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber const AString &value = mDict.valueAt(i); 216bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 217bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (key == AString("_")) { 218bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber continue; 219bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 220bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 221bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber line.append(key); 222bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber line.append(": "); 223bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber line.append(value); 224bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber line.append("\n"); 225bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 226bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 227bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber line.append("\n"); 228bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber line.append(mContent); 229bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 230bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return line; 231bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 232bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 233bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber// static 234bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberbool ParsedMessage::GetAttribute( 235bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber const char *s, const char *key, AString *value) { 236bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber value->clear(); 237bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 238bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber size_t keyLen = strlen(key); 239bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 240bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber for (;;) { 241bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber while (isspace(*s)) { 242bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ++s; 243bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 244bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 245bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber const char *colonPos = strchr(s, ';'); 246bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 247bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber size_t len = 248bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber (colonPos == NULL) ? strlen(s) : colonPos - s; 249bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 250bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (len >= keyLen + 1 && s[keyLen] == '=' && !strncmp(s, key, keyLen)) { 251bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber value->setTo(&s[keyLen + 1], len - keyLen - 1); 252bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return true; 253bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 254bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 255bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (colonPos == NULL) { 256bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return false; 257bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 258bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 259bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber s = colonPos + 1; 260bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 261bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 262bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 263bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber// static 264bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberbool ParsedMessage::GetInt32Attribute( 265bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber const char *s, const char *key, int32_t *value) { 266bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber AString stringValue; 267bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (!GetAttribute(s, key, &stringValue)) { 268bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber *value = 0; 269bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return false; 270bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 271bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 272bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber char *end; 273bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber *value = strtol(stringValue.c_str(), &end, 10); 274bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 275bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (end == stringValue.c_str() || *end != '\0') { 276bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber *value = 0; 277bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return false; 278bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 279bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 280bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return true; 281bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 282bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 283bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} // namespace android 284bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 285