示例#1
0
/*
 * Enumerate one resource item and its children and extract dependencies from
 * aliases.
 */
static void
ures_enumDependencies(const char *itemName,
                      const ResourceData *pResData,
                      Resource res, const char *inKey, const char *parentKey, int32_t depth,
                      CheckDependency check, void *context,
                      Package *pkg,
                      UErrorCode *pErrorCode) {
    switch(res_getPublicType(res)) {
    case URES_STRING:
        {
            UBool useResSuffix = TRUE;
            // Check for %%ALIAS
            if(depth==1 && inKey!=NULL) {
                if(0!=strcmp(inKey, "%%ALIAS")) {
                    break;
                }
            }
            // Check for %%DEPENDENCY
            else if(depth==2 && parentKey!=NULL) {
                if(0!=strcmp(parentKey, "%%DEPENDENCY")) {
                    break;
                }
                useResSuffix = FALSE;
            } else {
                // we ignore all other strings
                break;
            }
            int32_t length;
            const UChar *alias=res_getString(pResData, res, &length);
            checkAlias(itemName, res, alias, length, useResSuffix, check, context, pErrorCode);
        }
        break;
    case URES_ALIAS:
        {
            int32_t length;
            const UChar *alias=res_getAlias(pResData, res, &length);
            checkAlias(itemName, res, alias, length, TRUE, check, context, pErrorCode);
        }
        break;
    case URES_TABLE:
        {
            /* recurse */
            int32_t count=res_countArrayItems(pResData, res);
            for(int32_t i=0; i<count; ++i) {
                const char *itemKey;
                Resource item=res_getTableItemByIndex(pResData, res, i, &itemKey);
                ures_enumDependencies(
                        itemName, pResData,
                        item, itemKey,
                        inKey, depth+1,
                        check, context,
                        pkg,
                        pErrorCode);
                if(U_FAILURE(*pErrorCode)) {
                    fprintf(stderr, "icupkg/ures_enumDependencies(%s table res=%08x)[%d].recurse(%s: %08x) failed\n",
                                    itemName, res, i, itemKey, item);
                    break;
                }
            }
        }
        break;
    case URES_ARRAY:
        {
            /* recurse */
            int32_t count=res_countArrayItems(pResData, res);
            for(int32_t i=0; i<count; ++i) {
                Resource item=res_getArrayItem(pResData, res, i);
                ures_enumDependencies(
                        itemName, pResData,
                        item, NULL,
                        inKey, depth+1,
                        check, context,
                        pkg,
                        pErrorCode);
                if(U_FAILURE(*pErrorCode)) {
                    fprintf(stderr, "icupkg/ures_enumDependencies(%s array res=%08x)[%d].recurse(%08x) failed\n",
                                    itemName, res, i, item);
                    break;
                }
            }
        }
        break;
    default:
        break;
    }
}
示例#2
0
U_CFUNC Resource
res_findResource(const ResourceData *pResData, Resource r, char** path, const char** key) {
  /* we pass in a path. CollationElements/Sequence or zoneStrings/3/2 etc.
   * iterates over a path and stops when a scalar resource is found. This
   * CAN be an alias. Path gets set to the part that has not yet been processed.
   */

  char *pathP = *path, *nextSepP = *path;
  char *closeIndex = NULL;
  Resource t1 = r;
  Resource t2;
  int32_t indexR = 0;
  UResType type = (UResType)RES_GET_TYPE(t1);

  /* if you come in with an empty path, you'll be getting back the same resource */
  if(!uprv_strlen(pathP)) {
      return r;
  }

  /* one needs to have an aggregate resource in order to search in it */
  if(!URES_IS_CONTAINER(type)) {
      return RES_BOGUS;
  }

  while(nextSepP && *pathP && t1 != RES_BOGUS && URES_IS_CONTAINER(type)) {
    /* Iteration stops if: the path has been consumed, we found a non-existing
     * resource (t1 == RES_BOGUS) or we found a scalar resource (including alias)
     */
    nextSepP = uprv_strchr(pathP, RES_PATH_SEPARATOR);
    /* if there are more separators, terminate string
     * and set path to the remaining part of the string
     */
    if(nextSepP != NULL) {
      *nextSepP = 0; /* overwrite the separator with a NUL to terminate the key */
      *path = nextSepP+1;
    } else {
      *path = uprv_strchr(pathP, 0);
    }

    /* if the resource is a table */
    /* try the key based access */
    if(URES_IS_TABLE(type)) {
      *key = pathP;
      t2 = res_getTableItemByKey(pResData, t1, &indexR, key);
      if(t2 == RES_BOGUS) {
        /* if we fail to get the resource by key, maybe we got an index */
        indexR = uprv_strtol(pathP, &closeIndex, 10);
        if(closeIndex != pathP) {
          /* if we indeed have an index, try to get the item by index */
          t2 = res_getTableItemByIndex(pResData, t1, indexR, key);
        }
      }
    } else if(URES_IS_ARRAY(type)) {
      indexR = uprv_strtol(pathP, &closeIndex, 10);
      if(closeIndex != pathP) {
        t2 = res_getArrayItem(pResData, t1, indexR);
      } else {
        t2 = RES_BOGUS; /* have an array, but don't have a valid index */
      }
      *key = NULL;
    } else { /* can't do much here, except setting t2 to bogus */
      t2 = RES_BOGUS;
    }
    t1 = t2;
    type = (UResType)RES_GET_TYPE(t1);
    /* position pathP to next resource key/index */
    pathP = *path;
  }

  return t1;
}
示例#3
0
static void printOutBundle(UFILE *out, UResourceBundle *resource, int32_t indent, const char *pname, UErrorCode *status)
{
    static const UChar cr[] = { 0xA };  // LF

/*    int32_t noOfElements = ures_getSize(resource);*/
    int32_t i = 0;
    const char *key = ures_getKey(resource);

    switch(ures_getType(resource)) {
    case URES_STRING :
        {
            int32_t len=0;
            const UChar* thestr = ures_getString(resource, &len, status);
            UChar *string = quotedString(thestr);

            /* TODO: String truncation */
            if(opt_truncate && len > truncsize) {
                char msg[128];
                printIndent(out, indent);
                sprintf(msg, "// WARNING: this resource, size %li is truncated to %li\n",
                        (long)len, (long)(truncsize/2));
                printCString(out, msg, -1);
                len = truncsize/2;
            }
            printIndent(out, indent);
            if(key != NULL) {
                static const UChar openStr[] = { 0x0020, 0x007B, 0x0020, 0x0022 }; /* " { \"" */
                static const UChar closeStr[] = { 0x0022, 0x0020, 0x007D }; /* "\" }" */
                printCString(out, key, (int32_t)uprv_strlen(key));
                printString(out, openStr, UPRV_LENGTHOF(openStr));
                printString(out, string, len);
                printString(out, closeStr, UPRV_LENGTHOF(closeStr));
            } else {
                static const UChar openStr[] = { 0x0022 }; /* "\"" */
                static const UChar closeStr[] = { 0x0022, 0x002C }; /* "\"," */

                printString(out, openStr, UPRV_LENGTHOF(openStr));
                printString(out, string, (int32_t)(u_strlen(string)));
                printString(out, closeStr, UPRV_LENGTHOF(closeStr));
            }

            if(verbose) {
                printCString(out, "// STRING", -1);
            }
            printString(out, cr, UPRV_LENGTHOF(cr));

            uprv_free(string);
        }
        break;

    case URES_INT :
        {
            static const UChar openStr[] = { 0x003A, 0x0069, 0x006E, 0x0074, 0x0020, 0x007B, 0x0020 }; /* ":int { " */
            static const UChar closeStr[] = { 0x0020, 0x007D }; /* " }" */
            UChar num[20];

            printIndent(out, indent);
            if(key != NULL) {
                printCString(out, key, -1);
            }
            printString(out, openStr, UPRV_LENGTHOF(openStr));
            uprv_itou(num, 20, ures_getInt(resource, status), 10, 0);
            printString(out, num, u_strlen(num));
            printString(out, closeStr, UPRV_LENGTHOF(closeStr));

            if(verbose) {
                printCString(out, "// INT", -1);
            }
            printString(out, cr, UPRV_LENGTHOF(cr));
            break;
        }
    case URES_BINARY :
        {
            int32_t len = 0;
            const int8_t *data = (const int8_t *)ures_getBinary(resource, &len, status);
            if(opt_truncate && len > truncsize) {
                char msg[128];
                printIndent(out, indent);
                sprintf(msg, "// WARNING: this resource, size %li is truncated to %li\n",
                        (long)len, (long)(truncsize/2));
                printCString(out, msg, -1);
                len = truncsize;
            }
            if(U_SUCCESS(*status)) {
                static const UChar openStr[] = { 0x003A, 0x0062, 0x0069, 0x006E, 0x0061, 0x0072, 0x0079, 0x0020, 0x007B, 0x0020 }; /* ":binary { " */
                static const UChar closeStr[] = { 0x0020, 0x007D, 0x0020 }; /* " } " */
                printIndent(out, indent);
                if(key != NULL) {
                    printCString(out, key, -1);
                }
                printString(out, openStr, UPRV_LENGTHOF(openStr));
                for(i = 0; i<len; i++) {
                    printHex(out, *data++);
                }
                printString(out, closeStr, UPRV_LENGTHOF(closeStr));
                if(verbose) {
                    printCString(out, " // BINARY", -1);
                }
                printString(out, cr, UPRV_LENGTHOF(cr));
            } else {
                reportError(pname, status, "getting binary value");
            }
        }
        break;
    case URES_INT_VECTOR :
        {
            int32_t len = 0;
            const int32_t *data = ures_getIntVector(resource, &len, status);
            if(U_SUCCESS(*status)) {
                static const UChar openStr[] = { 0x003A, 0x0069, 0x006E, 0x0074, 0x0076, 0x0065, 0x0063, 0x0074, 0x006F, 0x0072, 0x0020, 0x007B, 0x0020 }; /* ":intvector { " */
                static const UChar closeStr[] = { 0x0020, 0x007D, 0x0020 }; /* " } " */
                UChar num[20];

                printIndent(out, indent);
                if(key != NULL) {
                    printCString(out, key, -1);
                }
                printString(out, openStr, UPRV_LENGTHOF(openStr));
                for(i = 0; i < len - 1; i++) {
                    int32_t numLen =  uprv_itou(num, 20, data[i], 10, 0);
                    num[numLen++] = 0x002C; /* ',' */
                    num[numLen++] = 0x0020; /* ' ' */
                    num[numLen] = 0;
                    printString(out, num, u_strlen(num));
                }
                if(len > 0) {
                    uprv_itou(num, 20, data[len - 1], 10, 0);
                    printString(out, num, u_strlen(num));
                }
                printString(out, closeStr, UPRV_LENGTHOF(closeStr));
                if(verbose) {
                    printCString(out, "// INTVECTOR", -1);
                }
                printString(out, cr, UPRV_LENGTHOF(cr));
            } else {
                reportError(pname, status, "getting int vector");
            }
      }
      break;
    case URES_TABLE :
    case URES_ARRAY :
        {
            static const UChar openStr[] = { 0x007B }; /* "{" */
            static const UChar closeStr[] = { 0x007D, '\n' }; /* "}\n" */

            UResourceBundle *t = NULL;
            ures_resetIterator(resource);
            printIndent(out, indent);
            if(key != NULL) {
                printCString(out, key, -1);
            }
            printString(out, openStr, UPRV_LENGTHOF(openStr));
            if(verbose) {
                if(ures_getType(resource) == URES_TABLE) {
                    printCString(out, "// TABLE", -1);
                } else {
                    printCString(out, "// ARRAY", -1);
                }
            }
            printString(out, cr, UPRV_LENGTHOF(cr));

            if(suppressAliases == FALSE) {
              while(U_SUCCESS(*status) && ures_hasNext(resource)) {
                  t = ures_getNextResource(resource, t, status);
                  if(U_SUCCESS(*status)) {
                    printOutBundle(out, t, indent+indentsize, pname, status);
                  } else {
                    reportError(pname, status, "While processing table");
                    *status = U_ZERO_ERROR;
                  }
              }
            } else { /* we have to use low level access to do this */
              Resource r;
              int32_t resSize = ures_getSize(resource);
              UBool isTable = (UBool)(ures_getType(resource) == URES_TABLE);
              for(i = 0; i < resSize; i++) {
                /* need to know if it's an alias */
                if(isTable) {
                  r = res_getTableItemByIndex(&resource->fResData, resource->fRes, i, &key);
                } else {
                  r = res_getArrayItem(&resource->fResData, resource->fRes, i);
                }
                if(U_SUCCESS(*status)) {
                  if(res_getPublicType(r) == URES_ALIAS) {
                    printOutAlias(out, resource, r, key, indent+indentsize, pname, status);
                  } else {
                    t = ures_getByIndex(resource, i, t, status);
                    printOutBundle(out, t, indent+indentsize, pname, status);
                  }
                } else {
                  reportError(pname, status, "While processing table");
                  *status = U_ZERO_ERROR;
                }
              }
            }

            printIndent(out, indent);
            printString(out, closeStr, UPRV_LENGTHOF(closeStr));
            ures_close(t);
        }
        break;
    default:
        break;
    }

}