OLD | NEW |
1 /* | 1 /* |
2 ****************************************************************************** | 2 ****************************************************************************** |
3 * Copyright (C) 1997-2015, International Business Machines Corporation and | 3 * Copyright (C) 1997-2015, International Business Machines Corporation and |
4 * others. All Rights Reserved. | 4 * others. All Rights Reserved. |
5 ****************************************************************************** | 5 ****************************************************************************** |
6 * | 6 * |
7 * File uresbund.cpp | 7 * File uresbund.cpp |
8 * | 8 * |
9 * Modification History: | 9 * Modification History: |
10 * | 10 * |
(...skipping 1864 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1875 fillIn = init_resb_result(&(resB->fResData), res, key, -1, resB->fDa
ta, resB, 0, fillIn, status); | 1875 fillIn = init_resb_result(&(resB->fResData), res, key, -1, resB->fDa
ta, resB, 0, fillIn, status); |
1876 } | 1876 } |
1877 } | 1877 } |
1878 else { | 1878 else { |
1879 *status = U_RESOURCE_TYPE_MISMATCH; | 1879 *status = U_RESOURCE_TYPE_MISMATCH; |
1880 } | 1880 } |
1881 ures_close(helper); | 1881 ures_close(helper); |
1882 return fillIn; | 1882 return fillIn; |
1883 } | 1883 } |
1884 | 1884 |
| 1885 namespace { |
| 1886 |
| 1887 void getAllContainerItemsWithFallback( |
| 1888 const UResourceBundle *bundle, ResourceDataValue &value, |
| 1889 ResourceArraySink *arraySink, ResourceTableSink *tableSink, |
| 1890 UErrorCode &errorCode) { |
| 1891 if (U_FAILURE(errorCode)) { return; } |
| 1892 // We recursively enumerate child-first, |
| 1893 // only storing parent items in the absence of child items. |
| 1894 // We store a placeholder value for the no-fallback/no-inheritance marker |
| 1895 // to prevent a parent item from being stored. |
| 1896 // |
| 1897 // It would be possible to recursively enumerate parent-first, |
| 1898 // overriding parent items with child items. |
| 1899 // When we see the no-fallback/no-inheritance marker, |
| 1900 // then we would remove the parent's item. |
| 1901 // We would deserialize parent values even though they are overridden in a c
hild bundle. |
| 1902 UResType expectedType = arraySink != NULL ? URES_ARRAY : URES_TABLE; |
| 1903 if (ures_getType(bundle) == expectedType) { |
| 1904 value.pResData = &bundle->fResData; |
| 1905 if (arraySink != NULL) { |
| 1906 ures_getAllArrayItems(&bundle->fResData, bundle->fRes, value, *array
Sink, errorCode); |
| 1907 } else /* tableSink != NULL */ { |
| 1908 ures_getAllTableItems(&bundle->fResData, bundle->fRes, value, *table
Sink, errorCode); |
| 1909 } |
| 1910 } |
| 1911 UResourceDataEntry *entry = bundle->fData->fParent; |
| 1912 if (entry != NULL && U_SUCCESS(entry->fBogus)) { |
| 1913 // We might try to query the sink whether |
| 1914 // any fallback from the parent bundle is still possible. |
| 1915 |
| 1916 // Turn the parent UResourceDataEntry into a UResourceBundle, |
| 1917 // much like in ures_openWithType(). |
| 1918 // TODO: See if we can refactor ures_getByKeyWithFallback() |
| 1919 // and pull out an inner function that takes and returns a UResourceData
Entry |
| 1920 // so that we need not create UResourceBundle objects. |
| 1921 UResourceBundle parentBundle; |
| 1922 ures_initStackObject(&parentBundle); |
| 1923 parentBundle.fTopLevelData = parentBundle.fData = entry; |
| 1924 // TODO: What is the difference between bundle fData and fTopLevelData? |
| 1925 uprv_memcpy(&parentBundle.fResData, &entry->fData, sizeof(ResourceData))
; |
| 1926 // TODO: Try to replace bundle.fResData with just using bundle.fData->fD
ata. |
| 1927 parentBundle.fHasFallback = !parentBundle.fResData.noFallback; |
| 1928 parentBundle.fIsTopLevel = TRUE; |
| 1929 parentBundle.fRes = parentBundle.fResData.rootRes; |
| 1930 parentBundle.fSize = res_countArrayItems(&(parentBundle.fResData), paren
tBundle.fRes); |
| 1931 parentBundle.fIndex = -1; |
| 1932 entryIncrease(entry); |
| 1933 |
| 1934 // Look up the container item in the parent bundle. |
| 1935 UResourceBundle containerBundle; |
| 1936 ures_initStackObject(&containerBundle); |
| 1937 const UResourceBundle *rb; |
| 1938 if (bundle->fResPath == NULL || *bundle->fResPath == 0) { |
| 1939 rb = &parentBundle; |
| 1940 } else { |
| 1941 rb = ures_getByKeyWithFallback(&parentBundle, bundle->fResPath, |
| 1942 &containerBundle, &errorCode); |
| 1943 } |
| 1944 if (U_SUCCESS(errorCode) && ures_getType(rb) == expectedType) { |
| 1945 getAllContainerItemsWithFallback(rb, value, |
| 1946 arraySink, tableSink, errorCode); |
| 1947 } |
| 1948 ures_close(&containerBundle); |
| 1949 ures_close(&parentBundle); |
| 1950 } |
| 1951 } |
| 1952 |
| 1953 void getAllContainerItemsWithFallback( |
| 1954 const UResourceBundle *bundle, const char *path, |
| 1955 ResourceArraySink *arraySink, ResourceTableSink *tableSink, |
| 1956 UErrorCode &errorCode) { |
| 1957 if (U_FAILURE(errorCode)) { return; } |
| 1958 if (path == NULL) { |
| 1959 errorCode = U_ILLEGAL_ARGUMENT_ERROR; |
| 1960 return; |
| 1961 } |
| 1962 UResourceBundle stackBundle; |
| 1963 ures_initStackObject(&stackBundle); |
| 1964 const UResourceBundle *rb; |
| 1965 if (*path == 0) { |
| 1966 // empty path |
| 1967 rb = bundle; |
| 1968 } else { |
| 1969 rb = ures_getByKeyWithFallback(bundle, path, &stackBundle, &errorCode); |
| 1970 if (U_FAILURE(errorCode)) { |
| 1971 ures_close(&stackBundle); |
| 1972 return; |
| 1973 } |
| 1974 } |
| 1975 UResType expectedType = arraySink != NULL ? URES_ARRAY : URES_TABLE; |
| 1976 if (ures_getType(rb) != expectedType) { |
| 1977 errorCode = U_RESOURCE_TYPE_MISMATCH; |
| 1978 ures_close(&stackBundle); |
| 1979 return; |
| 1980 } |
| 1981 // Get all table items with fallback. |
| 1982 ResourceDataValue value; |
| 1983 getAllContainerItemsWithFallback(rb, value, arraySink, tableSink, errorCode)
; |
| 1984 ures_close(&stackBundle); |
| 1985 } |
| 1986 |
| 1987 } // namespace |
| 1988 |
| 1989 U_CAPI void U_EXPORT2 |
| 1990 ures_getAllArrayItemsWithFallback(const UResourceBundle *bundle, const char *pat
h, |
| 1991 ResourceArraySink &sink, UErrorCode &errorCode
) { |
| 1992 getAllContainerItemsWithFallback(bundle, path, &sink, NULL, errorCode); |
| 1993 } |
| 1994 |
| 1995 U_CAPI void U_EXPORT2 |
| 1996 ures_getAllTableItemsWithFallback(const UResourceBundle *bundle, const char *pat
h, |
| 1997 ResourceTableSink &sink, UErrorCode &errorCode
) { |
| 1998 getAllContainerItemsWithFallback(bundle, path, NULL, &sink, errorCode); |
| 1999 } |
1885 | 2000 |
1886 U_CAPI UResourceBundle* U_EXPORT2 ures_getByKey(const UResourceBundle *resB, con
st char* inKey, UResourceBundle *fillIn, UErrorCode *status) { | 2001 U_CAPI UResourceBundle* U_EXPORT2 ures_getByKey(const UResourceBundle *resB, con
st char* inKey, UResourceBundle *fillIn, UErrorCode *status) { |
1887 Resource res = RES_BOGUS; | 2002 Resource res = RES_BOGUS; |
1888 UResourceDataEntry *realData = NULL; | 2003 UResourceDataEntry *realData = NULL; |
1889 const char *key = inKey; | 2004 const char *key = inKey; |
1890 | 2005 |
1891 if (status==NULL || U_FAILURE(*status)) { | 2006 if (status==NULL || U_FAILURE(*status)) { |
1892 return fillIn; | 2007 return fillIn; |
1893 } | 2008 } |
1894 if(resB == NULL) { | 2009 if(resB == NULL) { |
(...skipping 991 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2886 ures_getVersionByKey(const UResourceBundle* res, const char *key, UVersionInfo v
er, UErrorCode *status) { | 3001 ures_getVersionByKey(const UResourceBundle* res, const char *key, UVersionInfo v
er, UErrorCode *status) { |
2887 const UChar *str; | 3002 const UChar *str; |
2888 int32_t len; | 3003 int32_t len; |
2889 str = ures_getStringByKey(res, key, &len, status); | 3004 str = ures_getStringByKey(res, key, &len, status); |
2890 if(U_SUCCESS(*status)) { | 3005 if(U_SUCCESS(*status)) { |
2891 u_versionFromUString(ver, str); | 3006 u_versionFromUString(ver, str); |
2892 } | 3007 } |
2893 } | 3008 } |
2894 | 3009 |
2895 /* eof */ | 3010 /* eof */ |
OLD | NEW |