Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0cfc1c6d authored by Tomasz Wasilczyk's avatar Tomasz Wasilczyk Committed by Automerger Merge Worker
Browse files

Merge "Move String8 path functions to androidfw and aapt" into main am: 713e3930

parents 17d66bb4 713e3930
Loading
Loading
Loading
Loading
+26 −1
Original line number Diff line number Diff line
@@ -85,7 +85,10 @@ cc_library {
    export_include_dirs: ["include"],
    export_shared_lib_headers: ["libz"],
    static_libs: ["libincfs-utils"],
    whole_static_libs: ["libincfs-utils"],
    whole_static_libs: [
        "libandroidfw_pathutils",
        "libincfs-utils",
    ],
    export_static_lib_headers: ["libincfs-utils"],
    target: {
        android: {
@@ -137,6 +140,28 @@ cc_library {
    },
}

cc_library_static {
    name: "libandroidfw_pathutils",
    defaults: ["libandroidfw_defaults"],
    host_supported: true,
    export_include_dirs: ["include_pathutils"],
    srcs: [
        "PathUtils.cpp",
    ],
    shared_libs: [
        "libutils",
    ],
    target: {
        windows: {
            enabled: true,
        },
    },
    visibility: [
        ":__subpackages__",
        "//frameworks/base/tools/aapt",
    ],
}

common_test_libs = [
    "libandroidfw",
    "libbase",
+20 −20
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include <androidfw/AssetDir.h>
#include <androidfw/AssetManager.h>
#include <androidfw/misc.h>
#include <androidfw/PathUtils.h>
#include <androidfw/ResourceTypes.h>
#include <androidfw/ZipFileRO.h>
#include <cutils/atomic.h>
@@ -88,7 +89,7 @@ String8 idmapPathForPackagePath(const String8& pkgPath) {
    const char* root = getenv("ANDROID_DATA");
    LOG_ALWAYS_FATAL_IF(root == NULL, "ANDROID_DATA not set");
    String8 path(root);
    path.appendPath(kResourceCache);
    appendPath(path, kResourceCache);

    char buf[256]; // 256 chars should be enough for anyone...
    strncpy(buf, pkgPath.c_str(), 255);
@@ -104,7 +105,7 @@ String8 idmapPathForPackagePath(const String8& pkgPath) {
        }
        ++p;
    }
    path.appendPath(filename);
    appendPath(path, filename);
    path.append("@idmap");

    return path;
@@ -181,7 +182,7 @@ bool AssetManager::addAssetPath(

    String8 realPath(path);
    if (kAppZipName) {
        realPath.appendPath(kAppZipName);
        appendPath(realPath, kAppZipName);
    }
    ap.type = ::getFileType(realPath.c_str());
    if (ap.type == kFileTypeRegular) {
@@ -367,7 +368,7 @@ bool AssetManager::addDefaultAssets()
    LOG_ALWAYS_FATAL_IF(root == NULL, "ANDROID_ROOT not set");

    String8 path(root);
    path.appendPath(kSystemAssets);
    appendPath(path, kSystemAssets);

    return addAssetPath(path, NULL, false /* appAsLib */, true /* isSystemAsset */);
}
@@ -439,7 +440,7 @@ Asset* AssetManager::open(const char* fileName, AccessMode mode)
    LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager");

    String8 assetName(kAssetsRoot);
    assetName.appendPath(fileName);
    appendPath(assetName, fileName);

    /*
     * For each top-level asset path, search for the asset.
@@ -587,8 +588,8 @@ bool AssetManager::appendPathToResTable(asset_path& ap, bool appAsLib) const {
                const char* data = getenv("ANDROID_DATA");
                LOG_ALWAYS_FATAL_IF(data == NULL, "ANDROID_DATA not set");
                String8 overlaysListPath(data);
                overlaysListPath.appendPath(kResourceCache);
                overlaysListPath.appendPath("overlays.list");
                appendPath(overlaysListPath, kResourceCache);
                appendPath(overlaysListPath, "overlays.list");
                addSystemOverlays(overlaysListPath.c_str(), ap.path, sharedRes, nextEntryIdx);
#endif
                sharedRes = const_cast<AssetManager*>(this)->
@@ -789,7 +790,7 @@ Asset* AssetManager::openNonAssetInPathLocked(const char* fileName, AccessMode m
    /* look at the filesystem on disk */
    if (ap.type == kFileTypeDirectory) {
        String8 path(ap.path);
        path.appendPath(fileName);
        appendPath(path, fileName);

        pAsset = openAssetFromFileLocked(path, mode);

@@ -841,9 +842,9 @@ String8 AssetManager::createZipSourceNameLocked(const String8& zipFileName,
    sourceName.append(zipFileName);
    sourceName.append(":");
    if (dirName.length() > 0) {
        sourceName.appendPath(dirName);
        appendPath(sourceName, dirName);
    }
    sourceName.appendPath(fileName);
    appendPath(sourceName, fileName);
    return sourceName;
}

@@ -853,7 +854,7 @@ String8 AssetManager::createZipSourceNameLocked(const String8& zipFileName,
String8 AssetManager::createPathNameLocked(const asset_path& ap, const char* rootDir)
{
    String8 path(ap.path);
    if (rootDir != NULL) path.appendPath(rootDir);
    if (rootDir != NULL) appendPath(path, rootDir);
    return path;
}

@@ -897,7 +898,7 @@ Asset* AssetManager::openAssetFromFileLocked(const String8& pathName,
{
    Asset* pAsset = NULL;

    if (strcasecmp(pathName.getPathExtension().c_str(), ".gz") == 0) {
    if (strcasecmp(getPathExtension(pathName).c_str(), ".gz") == 0) {
        //printf("TRYING '%s'\n", (const char*) pathName);
        pAsset = Asset::createFromCompressedFile(pathName.c_str(), mode);
    } else {
@@ -1078,8 +1079,7 @@ bool AssetManager::scanAndMergeDirLocked(SortedVector<AssetDir::FileInfo>* pMerg
    //printf("scanAndMergeDir: %s %s %s\n", ap.path.c_str(), rootDir, dirName);

    String8 path = createPathNameLocked(ap, rootDir);
    if (dirName[0] != '\0')
        path.appendPath(dirName);
    if (dirName[0] != '\0') appendPath(path, dirName);

    SortedVector<AssetDir::FileInfo>* pContents = scanDirLocked(path);
    if (pContents == NULL)
@@ -1176,7 +1176,7 @@ SortedVector<AssetDir::FileInfo>* AssetManager::scanDirLocked(const String8& pat
            fileType = kFileTypeUnknown;
#else
        // stat the file
        fileType = ::getFileType(path.appendPathCopy(entry->d_name).c_str());
        fileType = ::getFileType(appendPathCopy(path, entry->d_name).c_str());
#endif

        if (fileType != kFileTypeRegular && fileType != kFileTypeDirectory)
@@ -1184,9 +1184,9 @@ SortedVector<AssetDir::FileInfo>* AssetManager::scanDirLocked(const String8& pat

        AssetDir::FileInfo info;
        info.set(String8(entry->d_name), fileType);
        if (strcasecmp(info.getFileName().getPathExtension().c_str(), ".gz") == 0)
            info.setFileName(info.getFileName().getBasePath());
        info.setSourceName(path.appendPathCopy(info.getFileName()));
        if (strcasecmp(getPathExtension(info.getFileName()).c_str(), ".gz") == 0)
            info.setFileName(getBasePath(info.getFileName()));
        info.setSourceName(appendPathCopy(path, info.getFileName()));
        pContents->add(info);
    }

@@ -1220,7 +1220,7 @@ bool AssetManager::scanAndMergeZipLocked(SortedVector<AssetDir::FileInfo>* pMerg

    /* convert "sounds" to "rootDir/sounds" */
    if (rootDir != NULL) dirName = rootDir;
    dirName.appendPath(baseDirName);
    appendPath(dirName, baseDirName);

    /*
     * Scan through the list of files, looking for a match.  The files in
@@ -1269,7 +1269,7 @@ bool AssetManager::scanAndMergeZipLocked(SortedVector<AssetDir::FileInfo>* pMerg
            if (nextSlash == NULL) {
                /* this is a file in the requested directory */

                info.set(String8(nameBuf).getPathLeaf(), kFileTypeRegular);
                info.set(getPathLeaf(String8(nameBuf)), kFileTypeRegular);

                info.setSourceName(
                    createZipSourceNameLocked(zipName, dirName, info.getFileName()));
+4 −3
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@
#include <utime.h>
#include <zlib.h>

#include <androidfw/PathUtils.h>
#include <log/log.h>
#include <utils/ByteOrder.h>
#include <utils/KeyedVector.h>
@@ -606,14 +607,14 @@ int write_tarfile(const String8& packageName, const String8& domain,
            prefix += packageName;
        }
        if (domain.length() > 0) {
            prefix.appendPath(domain);
            appendPath(prefix, domain);
        }

        // pax extended means we don't put in a prefix field, and put a different
        // string in the basic name field.  We can also construct the full path name
        // out of the substrings we've now built.
        fullname = prefix;
        fullname.appendPath(relpath);
        appendPath(fullname, relpath);

        // ustar:
        //    [   0 : 100 ]; file name/path
@@ -654,7 +655,7 @@ int write_tarfile(const String8& packageName, const String8& domain,
        // Now build the pax *header* templated on the ustar header
        memcpy(paxHeader, buf, 512);

        String8 leaf = fullname.getPathLeaf();
        String8 leaf = getPathLeaf(fullname);
        memset(paxHeader, 0, 100);                  // rewrite the name area
        snprintf(paxHeader, 100, "PaxHeader/%s", leaf.c_str());
        memset(paxHeader + 345, 0, 155);            // rewrite the prefix area
+135 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <androidfw/PathUtils.h>

#include <utils/Compat.h>

namespace android {

String8 getPathLeaf(const String8& str) {
    const char* cp;
    const char*const buf = str.c_str();

    cp = strrchr(buf, OS_PATH_SEPARATOR);
    if (cp == nullptr)
        return str;
    else
        return String8(cp+1);
}

String8 getPathDir(const String8& str8) {
    const char* cp;
    const char*const str = str8.c_str();

    cp = strrchr(str, OS_PATH_SEPARATOR);
    if (cp == nullptr)
        return String8();
    else
        return String8(str, cp - str);
}

static char* findExtension(const String8& str8) {
    const char* lastSlash;
    const char* lastDot;
    const char* const str = str8.c_str();

    // only look at the filename
    lastSlash = strrchr(str, OS_PATH_SEPARATOR);
    if (lastSlash == nullptr)
        lastSlash = str;
    else
        lastSlash++;

    // find the last dot
    lastDot = strrchr(lastSlash, '.');
    if (lastDot == nullptr)
        return nullptr;

    // looks good, ship it
    return const_cast<char*>(lastDot);
}

String8 getPathExtension(const String8& str) {
    char* ext;

    ext = findExtension(str);
    if (ext != nullptr)
        return String8(ext);
    else
        return String8();
}

String8 getBasePath(const String8& str8) {
    char* ext;
    const char* const str = str8.c_str();

    ext = findExtension(str8);
    if (ext == nullptr)
        return str8;
    else
        return String8(str, ext - str);
}

static void setPathName(String8& s, const char* name) {
    size_t len = strlen(name);
    char* buf = s.lockBuffer(len);

    memcpy(buf, name, len);

    // remove trailing path separator, if present
    if (len > 0 && buf[len - 1] == OS_PATH_SEPARATOR) len--;
    buf[len] = '\0';

    s.unlockBuffer(len);
}

String8& appendPath(String8& str, const char* name) {
    // TODO: The test below will fail for Win32 paths. Fix later or ignore.
    if (name[0] != OS_PATH_SEPARATOR) {
        if (*name == '\0') {
            // nothing to do
            return str;
        }

        size_t len = str.length();
        if (len == 0) {
            // no existing filename, just use the new one
            setPathName(str, name);
            return str;
        }

        // make room for oldPath + '/' + newPath
        int newlen = strlen(name);

        char* buf = str.lockBuffer(len+1+newlen);

        // insert a '/' if needed
        if (buf[len-1] != OS_PATH_SEPARATOR)
            buf[len++] = OS_PATH_SEPARATOR;

        memcpy(buf+len, name, newlen+1);
        len += newlen;

        str.unlockBuffer(len);
        return str;
    } else {
        setPathName(str, name);
        return str;
    }
}

} // namespace android
+98 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <utils/String8.h>

/* This library contains path manipulation functions that are used only by androidfw and aapt.
 * When it's possible, migrate all uses to std::filesystem::path.
 */

namespace android {

/**
 * Get just the filename component.
 *
 * DEPRECATED: use std::filesystem::path::filename
 *
 * "/tmp/foo/bar.c" --> "bar.c"
 */
String8 getPathLeaf(const String8& str);

/**
 * Remove the last (file name) component, leaving just the directory
 * name.
 *
 * DEPRECATED: use std::filesystem::path::parent_path
 *
 * "/tmp/foo/bar.c" --> "/tmp/foo"
 * "/tmp" --> "" // ????? shouldn't this be "/" ???? XXX
 * "bar.c" --> ""
 */
String8 getPathDir(const String8& str);

/**
 * Return the filename extension.  This is the last '.' and any number
 * of characters that follow it.  The '.' is included in case we
 * decide to expand our definition of what constitutes an extension.
 *
 * DEPRECATED: use std::filesystem::path::extension
 *
 * "/tmp/foo/bar.c" --> ".c"
 * "/tmp" --> ""
 * "/tmp/foo.bar/baz" --> ""
 * "foo.jpeg" --> ".jpeg"
 * "foo." --> ""
 */
String8 getPathExtension(const String8& str);

/**
 * Return the path without the extension.  Rules for what constitutes
 * an extension are described in the comment for getPathExtension().
 *
 * DEPRECATED: use std::filesystem::path::stem and std::filesystem::path::parent_path
 *
 * "/tmp/foo/bar.c" --> "/tmp/foo/bar"
 */
String8 getBasePath(const String8& str);

/**
 * Add a component to the pathname.  We guarantee that there is
 * exactly one path separator between the old path and the new.
 * If there is no existing name, we just copy the new name in.
 *
 * DEPRECATED: use std::filesystem::path::operator/=
 *
 * If leaf is a fully qualified path (i.e. starts with '/', it
 * replaces whatever was there before.
 */
String8& appendPath(String8& str, const char* leaf);
inline String8& appendPath(String8& str, const String8& leaf) {
    return appendPath(str, leaf.c_str());
}

/**
 * Like appendPath(), but does not affect this string.  Returns a new one instead.
 *
 * DEPRECATED: use std::filesystem::operator/
 */
inline String8 appendPathCopy(String8 str, const char* leaf) { return appendPath(str, leaf); }
inline String8 appendPathCopy(String8 str, const String8& leaf) {
    return appendPath(str, leaf.c_str());
}

} // namespace android
Loading