예제 #1
0
NativeString*
AssetManagerGlue::getResourceName(int resid)
{
	ResTable::resource_name name;
	if (!getResources().getResourceName(resid, &name)) {
		return NULL;
	}

	String16 str;
	if (name.package != NULL) {
		str.setTo(name.package, name.packageLen);
	}
	if (name.type != NULL) {
		if (str.size() > 0) {
			char16_t div = ':';
			str.append(&div, 1);
		}
		str.append(name.type, name.typeLen);
	}
	if (name.name != NULL) {
		if (str.size() > 0) {
			char16_t div = '/';
			str.append(&div, 1);
		}
		str.append(name.name, name.nameLen);
	}

	return new NativeString(str);
}
예제 #2
0
ssize_t StringPool::add(const String16& ident, const String16& value,
                        bool mergeDuplicates)
{
    if (ident.size() > 0) {
        ssize_t idx = mIdents.valueFor(ident);
        if (idx >= 0) {
            fprintf(stderr, "ERROR: Duplicate string identifier %s\n",
                    String8(mEntries[idx].value).string());
            return UNKNOWN_ERROR;
        }
    }

    ssize_t vidx = mValues.indexOfKey(value);
    ssize_t pos = vidx >= 0 ? mValues.valueAt(vidx) : -1;
    ssize_t eidx = pos >= 0 ? mEntryArray.itemAt(pos) : -1;
    if (eidx < 0) {
        eidx = mEntries.add(entry(value));
        if (eidx < 0) {
            fprintf(stderr, "Failure adding string %s\n", String8(value).string());
            return eidx;
        }
    }

    const bool first = vidx < 0;
    if (first || !mergeDuplicates) {
        pos = mEntryArray.add(eidx);
        if (first) {
            vidx = mValues.add(value, pos);
            const size_t N = mEntryArrayToValues.size();
            for (size_t i=0; i<N; i++) {
                size_t& e = mEntryArrayToValues.editItemAt(i);
                if ((ssize_t)e >= vidx) {
                    e++;
                }
            }
        }
        mEntryArrayToValues.add(vidx);
        if (!mSorted) {
            entry& ent = mEntries.editItemAt(eidx);
            ent.indices.add(pos);
        }
    }

    if (ident.size() > 0) {
        mIdents.add(ident, vidx);
    }

    NOISY(printf("Adding string %s to pool: pos=%d eidx=%d vidx=%d\n",
            String8(value).string(), pos, eidx, vidx));
    
    return pos;
}
예제 #3
0
파일: buffer.cpp 프로젝트: tehme/mcprotocol
size_t Buffer::writeString16(String16 _src, size_t _offset)
{
	if(_offset != npos)
		_pf_writeOffset = _offset;
	else
		_pf_writeOffset = _pf_buffer.size();

	writeInt16(_src.size(), _pf_writeOffset);
	for(int i = 0; i < _src.size(); ++i)
		writeInt16(_src[i], _offset);

	return _pf_writeOffset;
}
예제 #4
0
TEST(OpenCVEngineTest, GetPathForUnExistVersion)
{
    sp<IOpenCVEngine> Engine = InitConnect();
    EXPECT_FALSE(NULL == Engine.get());
    String16 result = Engine->GetLibPathByVersion(String16("2.5"));
    EXPECT_EQ(0, result.size());
}
예제 #5
0
status_t ChatSession::Say(const String16& statement)
{
	HRESULT hr = S_OK;
	String16 userName;
	int callerPid = GetCallerPID();
	_TRACE("ChatSession::Say(%s) >>",DISPLAY_STRING16(statement));	
	
	{
		Mutex::Autolock _lock(m_csAdviseLock);
		sp<IBinder> binder = m_Listeners.valueFor(callerPid);
		sp<IChatSessionEvents> eventSink = interface_cast<IChatSessionEvents>(binder);
		if(eventSink != NULL){
			_TRACE("**source(cse:%p  binder:%p) ",eventSink.get(),binder.get());
			userName  =  eventSink->GetUserName();
		}
	}

	if (userName.size() && CheckAccess(userName))
	{		
		{
			Mutex::Autolock _lock(m_csStatementLock);
			m_statements.add(userName + String16("\t:\t") +statement);
		}
		//Fire_OnNewStatement(userName, statement);
		ChatWorker::getInstance().Defer_OnNewStatement(this,userName, statement);
	}
	else
		hr = E_ACCESSDENIED;

	_TRACE("ChatSession::Say() <<hr:%x",hr);
	return hr;
}
예제 #6
0
void    ChatSession::Advise(const sp<IChatSessionEvents>& eventSink)
{
	int callerPid = GetCallerPID();

	_TRACE("ChatSession::Advise >>(%s,pid:%d)",DISPLAY_STRING16(m_wszSessionName),callerPid);	

	if (eventSink == NULL){
		_TRACE("ChatSession::Advise << E_INVALIDARG");
		return;
	}

	String16 userName = eventSink->GetUserName();

	if(userName.size()&& !m_bAllowAnonymousAccess){
		_TRACE("ChatSession::Advise << E_ACCESSDENIED");
		return;
	}

	 sp<IBinder> binder = eventSink->asBinder();
	 binder->linkToDeath(this);
	_TRACE("**ADD(cse:%p binder:%p) ",eventSink.get(),binder.get());

	_TRACE("add user %s",DISPLAY_STRING16(userName));
	Fire_OnNewUser(userName);
	//ChatWorker::getInstance().Defer_OnNewUser(this,userName);

	Mutex::Autolock _lock(m_csAdviseLock);
	m_Listeners.add(callerPid,binder);

	_TRACE("ChatSession::Advise << S_OK");
	return;
}
예제 #7
0
TEST(OpenCVEngineTest, GetPathForExecHWNewVersion)
{
    sp<IOpenCVEngine> Engine = InitConnect();
    Starter.PackageManager->InstalledPackages.clear();
    Starter.PackageManager->InstallVersion("241", PLATFORM_UNKNOWN, ARCH_X86);
    EXPECT_FALSE(NULL == Engine.get());
    String16 result = Engine->GetLibPathByVersion(String16("2.4.2"));
    EXPECT_EQ(0, result.size());
}
예제 #8
0
TEST(OpenCVEngineTest, GetPathForInCompatiblePackage1)
{
    sp<IOpenCVEngine> Engine = InitConnect();
    Starter.PackageManager->InstalledPackages.clear();
    Starter.PackageManager->InstallVersion("242", PLATFORM_UNKNOWN, ARCH_ARMv7);
    EXPECT_FALSE(NULL == Engine.get());
    String16 result = Engine->GetLibPathByVersion(String16("2.4"));
    EXPECT_EQ(0, result.size());
}
예제 #9
0
TEST(OpenCVEngineTest, GetPathForExecHWNewVersion)
{
    sp<IOpenCVEngine> Engine = InitConnect();
    Starter.PackageManager->InstalledPackages.clear();
    Starter.PackageManager->InstallVersion(2040100, PLATFORM_TEGRA3, ARCH_ARMv7 | FEATURES_HAS_NEON);
    EXPECT_FALSE(NULL == Engine.get());
    String16 result = Engine->GetLibPathByVersion(String16("2.4.2"));
    EXPECT_EQ(0, result.size());
}
예제 #10
0
TEST(OpenCVEngineTest, GetPathFor2_4_5)
{
    sp<IOpenCVEngine> Engine = InitConnect();
    Starter.PackageManager->InstalledPackages.clear();
    Starter.PackageManager->InstallVersion(2040500, PLATFORM_UNKNOWN, ARCH_ARMv7);
    EXPECT_FALSE(NULL == Engine.get());
    String16 result = Engine->GetLibPathByVersion(String16("2.4.5"));
    EXPECT_EQ(0, result.size()); // 2.4.5 is not published yet
}
예제 #11
0
String16
pseudo_generate_expansion(const unsigned int length) {
    String16 result = k_expansion_string;
    const char16_t* s = result.string();
    if (result.size() < length) {
        result += String16(" ");
        result += pseudo_generate_expansion(length - result.size());
    } else {
        int ext = 0;
        // Should contain only whole words, so looking for a space
        for (unsigned int i = length + 1; i < result.size(); ++i) {
          ++ext;
          if (s[i] == ' ') {
            break;
          }
        }
        result.remove(length + ext, 0);
    }
    return result;
}
예제 #12
0
static String8 good_old_string(const String16& src)
{
    String8 name8;
    char ch8[2];
    ch8[1] = 0;
    for (unsigned j = 0; j < src.size(); j++) {
        char16_t ch = src[j];
        if (ch < 128) ch8[0] = (char)ch;
        name8.append(ch8);
    }
    return name8;
}
예제 #13
0
SensorManager& SensorManager::getInstanceForPackage(const String16& packageName) {
    Mutex::Autolock _l(sLock);
    SensorManager* sensorManager;
    std::map<String16, SensorManager*>::iterator iterator =
        sPackageInstances.find(packageName);

    if (iterator != sPackageInstances.end()) {
        sensorManager = iterator->second;
    } else {
        String16 opPackageName = packageName;

        // It is possible that the calling code has no access to the package name.
        // In this case we will get the packages for the calling UID and pick the
        // first one for attributing the app op. This will work correctly for
        // runtime permissions as for legacy apps we will toggle the app op for
        // all packages in the UID. The caveat is that the operation may be attributed
        // to the wrong package and stats based on app ops may be slightly off.
        if (opPackageName.size() <= 0) {
            sp<IBinder> binder = defaultServiceManager()->getService(String16("permission"));
            if (binder != 0) {
                const uid_t uid = IPCThreadState::self()->getCallingUid();
                Vector<String16> packages;
                interface_cast<IPermissionController>(binder)->getPackagesForUid(uid, packages);
                if (!packages.isEmpty()) {
                    opPackageName = packages[0];
                } else {
                    ALOGE("No packages for calling UID");
                }
            } else {
                ALOGE("Cannot get permission service");
            }
        }

        sensorManager = new SensorManager(opPackageName);

        // If we had no package name, we looked it up from the UID and the sensor
        // manager instance we created should also be mapped to the empty package
        // name, to avoid looking up the packages for a UID and get the same result.
        if (packageName.size() <= 0) {
            sPackageInstances.insert(std::make_pair(String16(), sensorManager));
        }

        // Stash the per package sensor manager.
        sPackageInstances.insert(std::make_pair(opPackageName, sensorManager));
    }

    return *sensorManager;
}
예제 #14
0
/* BnHelloWorld */
status_t BnHelloWorld::onTransact(uint32_t code,
                                                const Parcel &data,
                                                Parcel *reply,
                                                uint32_t flags)
{
        LOGE("OnTransact(%u,%u)", code, flags);
        CHECK_INTERFACE(IHelloWorld, data, reply);
        switch(code) {
        case HW_HELLOTHERE: {
                /**
                 * Checking permissions is always a good idea.
                 *
                 * Note that the native client will also be granted these permissions in two cases
                 * 1) you run the client code as root or system user.
                 * 2) you run the client code as user who was granted this permission.
                 * @see http://github.com/keesj/gomo/wiki/AndroidSecurity for more information
                 **/
                if (checkCallingPermission(String16("org.credil.helloworldservice.permissions.CALL_HELLOTHERE")) == false){
                    return   PERMISSION_DENIED;
                }
                String16 str = data.readString16();
                hellothere(String8(str).string());
                ///reply->writeString16(str);
                return NO_ERROR;
        } break;
		case RETURN_INT_SHANQUAN:{
                if (checkCallingPermission(String16("org.credil.helloworldservice.permissions.CALL_HELLOTHERE")) == false){
                    return   PERMISSION_DENIED;
                }
                String16 str = data.readString16();
                helloint(String8(str).string());
				int tmp= str.size();
				printf("servie str.size():%i\n",tmp);
				status_t status = reply->writeInt32(tmp);
				if( status == NO_ERROR)
					printf("file:%s,line:%i,no error\n",__FILE__,__LINE__);
				else
					printf("file:%s,line:%i, error\n",__FILE__,__LINE__);
                return NO_ERROR;
		} break;
        default:
                return BBinder::onTransact(code, data, reply, flags);
        }
        return NO_ERROR;
}
// Send a command to the supplicant, and return the reply as a String.
static jstring doStringCommand(JNIEnv* env, jstring javaCommand) {
    char reply[REPLY_BUF_SIZE];
    ScopedUtfChars command(env, javaCommand);
    if (!doCommand(env, javaCommand, reply, sizeof(reply))) {
        return NULL;
    }
    if (DBG) ALOGD("cmd = %s, reply: %s", command.c_str(), reply);
    String16 str;
    if (strstr(command.c_str(),"BSS RANGE=")) {
        parseScanResults(str,reply);
    } else if (strstr(command.c_str(),"GET_NETWORK") &&
              strstr(command.c_str(),"ssid") && !strstr(command.c_str(),"bssid")
              && !strstr(command.c_str(),"scan_ssid")){
        constructSsid(str, reply);
    } else {
        str += String16((char *)reply);
    }
    return env->NewString((const jchar *)str.string(), str.size());
}
예제 #16
0
status_t String16::setTo(const String16& other, size_t len, size_t begin)
{
    const size_t N = other.size();
    if (begin >= N) {
        SharedBuffer::bufferFromData(mString)->release();
        mString = getEmptyString();
        return NO_ERROR;
    }
    if ((begin+len) > N) len = N-begin;
    if (begin == 0 && len == N) {
        setTo(other);
        return NO_ERROR;
    }

    if (&other == this) {
        LOG_ALWAYS_FATAL("Not implemented");
    }

    return setTo(other.string()+begin, len);
}
예제 #17
0
status_t String16::append(const String16& other)
{
    const size_t myLen = size();
    const size_t otherLen = other.size();
    if (myLen == 0) {
        setTo(other);
        return NO_ERROR;
    } else if (otherLen == 0) {
        return NO_ERROR;
    }
    
    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
        ->editResize((myLen+otherLen+1)*sizeof(char16_t));
    if (buf) {
        char16_t* str = (char16_t*)buf->data();
        memcpy(str+myLen, other, (otherLen+1)*sizeof(char16_t));
        mString = str;
        return NO_ERROR;
    }
    return NO_MEMORY;
}
예제 #18
0
파일: XMLNode.cpp 프로젝트: bincker/Webkey
String16 getNamespaceResourcePackage(String16 namespaceUri, bool* outIsPublic)
{
    //printf("%s starts with %s?\n", String8(namespaceUri).string(),
    //       String8(RESOURCES_PREFIX).string());
    size_t prefixSize;
    bool isPublic = true;
    if (namespaceUri.startsWith(RESOURCES_PREFIX)) {
        prefixSize = RESOURCES_PREFIX.size();
    } else if (namespaceUri.startsWith(RESOURCES_PRV_PREFIX)) {
        isPublic = false;
        prefixSize = RESOURCES_PRV_PREFIX.size();
    } else {
        if (outIsPublic) *outIsPublic = isPublic; // = true
        return String16();
    }

    //printf("YES!\n");
    //printf("namespace: %s\n", String8(String16(namespaceUri, namespaceUri.size()-prefixSize, prefixSize)).string());
    if (outIsPublic) *outIsPublic = isPublic;
    return String16(namespaceUri, namespaceUri.size()-prefixSize, prefixSize);
}
예제 #19
0
String16
pseudobidi_string(const String16& source)
{
    const char16_t* s = source.string();
    String16 result;
    result += k_rlm;
    result += k_rlo;
    for (size_t i=0; i<source.size(); i++) {
        char16_t c = s[i];
        switch(c) {
            case ' ': result += k_pdf;
                      result += k_rlm;
                      result.append(&c, 1);
                      result += k_rlm;
                      result += k_rlo;
                      break;
            default: result.append(&c, 1);
                     break;
        }
    }
    result += k_pdf;
    result += k_rlm;
    return result;
}
예제 #20
0
status_t ChatSession::Unadvise()
{
	String16 userName;
	int callerPid = GetCallerPID();

	_TRACE("ChatSession::Unadvise(%s,pid:%d)",DISPLAY_STRING16(m_wszSessionName),callerPid);
	
	{
		Mutex::Autolock _lock(m_csAdviseLock);
		sp<IBinder> binder = m_Listeners.valueFor(callerPid);
		sp<IChatSessionEvents> eventSink = interface_cast<IChatSessionEvents>(binder);
		if(eventSink != NULL){
			m_Listeners.removeItem(callerPid);
			userName  =  eventSink->GetUserName();
			_TRACE("**MOV(cse:%p binder:%p) ",eventSink.get(),binder.get());
		}
	}

	if(userName.size()){
		//ChatWorker::getInstance().Defer_OnUserLeft(this,userName);
		Fire_OnUserLeft(userName);
	}
	return NO_ERROR;
}
예제 #21
0
/**
 * Converts characters so they look like they've been localized.
 *
 * Note: This leaves escape sequences untouched so they can later be
 * processed by ResTable::collectString in the normal way.
 */
String16
pseudolocalize_string(const String16& source)
{
    const char16_t* s = source.string();
    String16 result;
    const size_t I = source.size();
    for (size_t i=0; i<I; i++) {
        char16_t c = s[i];
        if (c == '\\') {
            // Escape syntax, no need to pseudolocalize
            if (i<I-1) {
                result += String16("\\");
                i++;
                c = s[i];
                switch (c) {
                    case 'u':
                        // this one takes up 5 chars
                        result += String16(s+i, 5);
                        i += 4;
                        break;
                    case 't':
                    case 'n':
                    case '#':
                    case '@':
                    case '?':
                    case '"':
                    case '\'':
                    case '\\':
                    default:
                        result.append(&c, 1);
                        break;
                }
            } else {
                result.append(&c, 1);
            }
        } else if (c == '%') {
            // Placeholder syntax, no need to pseudolocalize
            result += k_placeholder_open;
            bool end = false;
            result.append(&c, 1);
            while (!end && i < I) {
                ++i;
                c = s[i];
                result.append(&c, 1);
                if (is_possible_normal_placeholder_end(c)) {
                    end = true;
                } else if (c == 't') {
                    ++i;
                    c = s[i];
                    result.append(&c, 1);
                    end = true;
                }
            }
            result += k_placeholder_close;
        } else if (c == '<' || c == '&') {
            // html syntax, no need to pseudolocalize
            bool tag_closed = false;
            while (!tag_closed && i < I) {
                if (c == '&') {
                    String16 escape_text;
                    escape_text.append(&c, 1);
                    bool end = false;
                    size_t htmlCodePos = i;
                    while (!end && htmlCodePos < I) {
                        ++htmlCodePos;
                        c = s[htmlCodePos];
                        escape_text.append(&c, 1);
                        // Valid html code
                        if (c == ';') {
                            end = true;
                            i = htmlCodePos;
                        }
                        // Wrong html code
                        else if (!((c == '#' ||
                                 (c >= 'a' && c <= 'z') ||
                                 (c >= 'A' && c <= 'Z') ||
                                 (c >= '0' && c <= '9')))) {
                            end = true;
                        }
                    }
                    result += escape_text;
                    if (escape_text != String16("&lt;")) {
                        tag_closed = true;
                    }
                    continue;
                }
                if (c == '>') {
                    tag_closed = true;
                    result.append(&c, 1);
                    continue;
                }
                result.append(&c, 1);
                i++;
                c = s[i];
            }
        } else {
            // This is a pure text that should be pseudolocalized
            const char* p = pseudolocalize_char(c);
            if (p != NULL) {
                result += String16(p);
            } else {
                result.append(&c, 1);
            }
        }
    }
    return result;
}
예제 #22
0
bool String16::startsWith(const String16& prefix) const
{
    const size_t ps = prefix.size();
    if (ps > size()) return false;
    return strzcmp16(mString, ps, prefix.string(), ps) == 0;
}
jstring string16ToJstring(JNIEnv* env, String16 string) {
    const char16_t* str = string.string();
    size_t len = string.size();

    return env->NewString(reinterpret_cast<const jchar*>(str), len);
}
예제 #24
0
파일: String8.cpp 프로젝트: AmesianX/frash
String8::String8(const String16& o)
    : mString(allocFromUTF16(o.string(), o.size()))
{
}
예제 #25
0
파일: XMLNode.cpp 프로젝트: bincker/Webkey
status_t parseStyledString(Bundle* bundle,
                           const char* fileName,
                           ResXMLTree* inXml,
                           const String16& endTag,
                           String16* outString,
                           Vector<StringPool::entry_style_span>* outSpans,
                           bool pseudolocalize)
{
    Vector<StringPool::entry_style_span> spanStack;
    String16 curString;
    String16 rawString;
    const char* errorMsg;
    int xliffDepth = 0;
    bool firstTime = true;

    size_t len;
    ResXMLTree::event_code_t code;
    while ((code=inXml->next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {

        if (code == ResXMLTree::TEXT) {
            String16 text(inXml->getText(&len));
            if (firstTime && text.size() > 0) {
                firstTime = false;
                if (text.string()[0] == '@') {
                    // If this is a resource reference, don't do the pseudoloc.
                    pseudolocalize = false;
                }
            }
            if (xliffDepth == 0 && pseudolocalize) {
                std::string orig(String8(text).string());
                std::string pseudo = pseudolocalize_string(orig);
                curString.append(String16(String8(pseudo.c_str())));
            } else {
                curString.append(text);
            }
        } else if (code == ResXMLTree::START_TAG) {
            const String16 element16(inXml->getElementName(&len));
            const String8 element8(element16);

            size_t nslen;
            const uint16_t* ns = inXml->getElementNamespace(&nslen);
            if (ns == NULL) {
                ns = (const uint16_t*)"\0\0";
                nslen = 0;
            }
            const String8 nspace(String16(ns, nslen));
            if (nspace == XLIFF_XMLNS) {
                const int N = sizeof(ALLOWED_XLIFF_ELEMENTS)/sizeof(ALLOWED_XLIFF_ELEMENTS[0]);
                for (int i=0; i<N; i++) {
                    if (element8 == ALLOWED_XLIFF_ELEMENTS[i]) {
                        xliffDepth++;
                        // in this case, treat it like it was just text, in other words, do nothing
                        // here and silently drop this element
                        goto moveon;
                    }
                }
                {
                    SourcePos(String8(fileName), inXml->getLineNumber()).error(
                            "Found unsupported XLIFF tag <%s>\n",
                            element8.string());
                    return UNKNOWN_ERROR;
                }
moveon:
                continue;
            }

            if (outSpans == NULL) {
                SourcePos(String8(fileName), inXml->getLineNumber()).error(
                        "Found style tag <%s> where styles are not allowed\n", element8.string());
                return UNKNOWN_ERROR;
            }

            if (!ResTable::collectString(outString, curString.string(),
                                         curString.size(), false, &errorMsg, true)) {
                SourcePos(String8(fileName), inXml->getLineNumber()).error("%s (in %s)\n",
                        errorMsg, String8(curString).string());
                return UNKNOWN_ERROR;
            }
            rawString.append(curString);
            curString = String16();

            StringPool::entry_style_span span;
            span.name = element16;
            for (size_t ai=0; ai<inXml->getAttributeCount(); ai++) {
                span.name.append(String16(";"));
                const char16_t* str = inXml->getAttributeName(ai, &len);
                span.name.append(str, len);
                span.name.append(String16("="));
                str = inXml->getAttributeStringValue(ai, &len);
                span.name.append(str, len);
            }
            //printf("Span: %s\n", String8(span.name).string());
            span.span.firstChar = span.span.lastChar = outString->size();
            spanStack.push(span);

        } else if (code == ResXMLTree::END_TAG) {
            size_t nslen;
            const uint16_t* ns = inXml->getElementNamespace(&nslen);
            if (ns == NULL) {
                ns = (const uint16_t*)"\0\0";
                nslen = 0;
            }
            const String8 nspace(String16(ns, nslen));
            if (nspace == XLIFF_XMLNS) {
                xliffDepth--;
                continue;
            }
            if (!ResTable::collectString(outString, curString.string(),
                                         curString.size(), false, &errorMsg, true)) {
                SourcePos(String8(fileName), inXml->getLineNumber()).error("%s (in %s)\n",
                        errorMsg, String8(curString).string());
                return UNKNOWN_ERROR;
            }
            rawString.append(curString);
            curString = String16();

            if (spanStack.size() == 0) {
                if (strcmp16(inXml->getElementName(&len), endTag.string()) != 0) {
                    SourcePos(String8(fileName), inXml->getLineNumber()).error(
                            "Found tag %s where <%s> close is expected\n",
                            String8(inXml->getElementName(&len)).string(),
                            String8(endTag).string());
                    return UNKNOWN_ERROR;
                }
                break;
            }
            StringPool::entry_style_span span = spanStack.top();
            String16 spanTag;
            ssize_t semi = span.name.findFirst(';');
            if (semi >= 0) {
                spanTag.setTo(span.name.string(), semi);
            } else {
                spanTag.setTo(span.name);
            }
            if (strcmp16(inXml->getElementName(&len), spanTag.string()) != 0) {
                SourcePos(String8(fileName), inXml->getLineNumber()).error(
                        "Found close tag %s where close tag %s is expected\n",
                        String8(inXml->getElementName(&len)).string(),
                        String8(spanTag).string());
                return UNKNOWN_ERROR;
            }
            bool empty = true;
            if (outString->size() > 0) {
                span.span.lastChar = outString->size()-1;
                if (span.span.lastChar >= span.span.firstChar) {
                    empty = false;
                    outSpans->add(span);
                }
            }
            spanStack.pop();

            /*
             * This warning seems to be just an irritation to most people,
             * since it is typically introduced by translators who then never
             * see the warning.
             */
            if (0 && empty) {
                fprintf(stderr, "%s:%d: warning: empty '%s' span found in text '%s'\n",
                        fileName, inXml->getLineNumber(),
                        String8(spanTag).string(), String8(*outString).string());

            }
        } else if (code == ResXMLTree::START_NAMESPACE) {
            // nothing
        }
    }

    if (code == ResXMLTree::BAD_DOCUMENT) {
            SourcePos(String8(fileName), inXml->getLineNumber()).error(
                    "Error parsing XML\n");
    }

    if (outSpans != NULL && outSpans->size() > 0) {
        if (curString.size() > 0) {
            if (!ResTable::collectString(outString, curString.string(),
                                         curString.size(), false, &errorMsg, true)) {
                SourcePos(String8(fileName), inXml->getLineNumber()).error(
                        "%s (in %s)\n",
                        errorMsg, String8(curString).string());
                return UNKNOWN_ERROR;
            }
        }
    } else {
        // There is no style information, so string processing will happen
        // later as part of the overall type conversion.  Return to the
        // client the raw unprocessed text.
        rawString.append(curString);
        outString->setTo(rawString);
    }

    return NO_ERROR;
}
예제 #26
0
static bool getAppInfo(const String8& path, AppInfo& outInfo) {
    memset(&outInfo, 0, sizeof(outInfo));

    AssetManager assetManager;
    int32_t cookie = 0;
    if (!assetManager.addAssetPath(path, &cookie)) {
        return false;
    }

    Asset* asset = assetManager.openNonAsset(cookie, "AndroidManifest.xml", Asset::ACCESS_BUFFER);
    if (asset == NULL) {
        return false;
    }

    ResXMLTree xml;
    if (xml.setTo(asset->getBuffer(true), asset->getLength(), false) != NO_ERROR) {
        delete asset;
        return false;
    }

    const String16 kAndroidNamespace("http://schemas.android.com/apk/res/android");
    const String16 kManifestTag("manifest");
    const String16 kApplicationTag("application");
    const String16 kUsesSdkTag("uses-sdk");
    const String16 kVersionCodeAttr("versionCode");
    const String16 kMultiArchAttr("multiArch");
    const String16 kMinSdkVersionAttr("minSdkVersion");

    ResXMLParser::event_code_t event;
    while ((event = xml.next()) != ResXMLParser::BAD_DOCUMENT &&
            event != ResXMLParser::END_DOCUMENT) {
        if (event != ResXMLParser::START_TAG) {
            continue;
        }

        size_t len;
        const char16_t* name = xml.getElementName(&len);
        String16 name16(name, len);
        if (name16 == kManifestTag) {
            ssize_t idx = xml.indexOfAttribute(
                    kAndroidNamespace.string(), kAndroidNamespace.size(),
                    kVersionCodeAttr.string(), kVersionCodeAttr.size());
            if (idx >= 0) {
                outInfo.versionCode = xml.getAttributeData(idx);
            }

        } else if (name16 == kApplicationTag) {
            ssize_t idx = xml.indexOfAttribute(
                    kAndroidNamespace.string(), kAndroidNamespace.size(),
                    kMultiArchAttr.string(), kMultiArchAttr.size());
            if (idx >= 0) {
                outInfo.multiArch = xml.getAttributeData(idx) != 0;
            }

        } else if (name16 == kUsesSdkTag) {
            ssize_t idx = xml.indexOfAttribute(
                    kAndroidNamespace.string(), kAndroidNamespace.size(),
                    kMinSdkVersionAttr.string(), kMinSdkVersionAttr.size());
            if (idx >= 0) {
                uint16_t type = xml.getAttributeDataType(idx);
                if (type >= Res_value::TYPE_FIRST_INT && type <= Res_value::TYPE_LAST_INT) {
                    outInfo.minSdkVersion = xml.getAttributeData(idx);
                } else if (type == Res_value::TYPE_STRING) {
                    String8 minSdk8(xml.getStrings().string8ObjectAt(idx));
                    char* endPtr;
                    int minSdk = strtol(minSdk8.string(), &endPtr, 10);
                    if (endPtr != minSdk8.string() + minSdk8.size()) {
                        fprintf(stderr, "warning: failed to parse android:minSdkVersion '%s'\n",
                                minSdk8.string());
                    } else {
                        outInfo.minSdkVersion = minSdk;
                    }
                } else {
                    fprintf(stderr, "warning: unrecognized value for android:minSdkVersion.\n");
                }
            }
        }
    }

    delete asset;
    return true;
}