/**
 * Loads the properties of a MIDlet suite from persistent storage.
 *
 * @param suiteId ID of the suite
 * @param pJadProps [out] pointer to a structure containing an array of strings,
 * in a pair pattern of key and value; NULL may be passed if it is not required
 * to read JAD properties
 * @param pJarProps [out] pointer to a structure containing an array of strings,
 * in a pair pattern of key and value; NULL may be passed if it is not required
 * to read JAR properties
 *
 * @return error code (ALL_OK for success)
 */
MIDPError
load_install_properties(SuiteIdType suiteId, MidpProperties* pJadProps,
                        MidpProperties* pJarProps) {
    pcsl_string filename;
    char* pszError = NULL;
    int handle, i, n;
    int numberOfProps;
    MIDPError status;

    status = get_property_file(suiteId, KNI_TRUE, &filename);
    if (status != ALL_OK) {
        return status;
    }

    handle = storage_open(&pszError, &filename, OPEN_READ);
    pcsl_string_free(&filename);
    if (pszError != NULL) {
        storageFreeError(pszError);
        return IO_ERROR;
    }

    status = ALL_OK;

    /* Read JAD, then JAR properties. */
    for (n = 0; n < 2; n++) {
        MidpProperties *pProps = n ? pJarProps : pJadProps;
        if (!pProps) {
            continue;
        }

        storageRead(&pszError, handle, (char*)&numberOfProps,
            sizeof (numberOfProps));
        if (pszError != NULL) {
            break;
        }

        pProps->pStringArr = alloc_pcsl_string_list(numberOfProps << 1);

        for (i = 0; i < numberOfProps << 1; i++) {
            storage_read_utf16_string(&pszError, handle,
                                      &pProps->pStringArr[i]);
            if (pszError != NULL) {
                break;
            }
        }

        if (pszError != NULL) {
            break;
        }

        pProps->numberOfProperties = numberOfProps;
    }

    if (pszError != NULL) {
        status = IO_ERROR;
        storageFreeError(pszError);
    }

    storageClose(&pszError, handle);
    storageFreeError(pszError);

    if (status != ALL_OK) {
        if (pJadProps) {
            free_pcsl_string_list(pJadProps->pStringArr,
                                  pJadProps->numberOfProperties << 1);
        }
        if (pJarProps) {
            free_pcsl_string_list(pJarProps->pStringArr,
                                  pJarProps->numberOfProperties << 1);
        }
    }

    return status;
}
/**
 * Retrieves the list of strings in a file.
 * The file has the number of strings at the front, each string
 * is a length and the jchars.
 *
 * @param ppszError pointer to character string pointer to accept an error
 * @param pFilename name of the file of strings
 * @param paList pointer to an array of pcsl_strings, free with
 *               free_pcsl_string_list
 * @param pStringNum number of strings if successful (can be 0)
 *
 * @return error code (ALL_OK if successful)
 */
static MIDPError
get_string_list(char** ppszError, const pcsl_string* pFilename,
                pcsl_string** paList, int* pStringNum) {
    char* pszTemp;
    int i = 0;
    int handle;
    int numberOfStrings = 0;
    pcsl_string* pStrings = NULL;
    MIDPError status = ALL_OK;

    *ppszError = NULL;
    *paList = NULL;
    *pStringNum = 0;

    handle = storage_open(ppszError, pFilename, OPEN_READ);
    if (*ppszError != NULL) {
        return IO_ERROR;
    }

    do {
        storageRead(ppszError, handle, (char*)&numberOfStrings,
            sizeof (numberOfStrings));
        if (*ppszError != NULL) {
            status = IO_ERROR;
            break;
        }
        if (numberOfStrings == 0) {
            break;
        }

        pStrings = alloc_pcsl_string_list(numberOfStrings);
        if (pStrings == NULL) {
            status = OUT_OF_MEMORY;
            break;
        }

        for (i = 0; i < numberOfStrings; i++) {
            pStrings[i] = PCSL_STRING_NULL;
        }

        for (i = 0; i < numberOfStrings; i++) {
            storage_read_utf16_string(ppszError, handle, &pStrings[i]);
            if (*ppszError != NULL) {
                status = IO_ERROR;
                break;
            }

        }

        if (i != numberOfStrings) {
            status = SUITE_CORRUPTED_ERROR;
            break;
        }
    } while (0);

    storageClose(&pszTemp, handle);
    storageFreeError(pszTemp);

    if (status == ALL_OK) {
        *paList = pStrings;
        *pStringNum = numberOfStrings;
    } else if (pStrings != NULL) {
        free_pcsl_string_list(pStrings, i);
    }

    return status;
}