resources/src/main/java/org/robolectric/res/android/ResTable.java
int addInternal(byte[] data, int dataSize, final Object idmapData, int idmapDataSize,
      boolean appAsLib, final int cookie, boolean copyData, boolean isSystemAsset)
  {
    if (!isTruthy(data)) {
      return NO_ERROR;
    }

    if (dataSize < ResTable_header.SIZEOF) {
      ALOGE("Invalid data. Size(%d) is smaller than a ResTable_header(%d).",
          (int) dataSize, (int) ResTable_header.SIZEOF);
      return UNKNOWN_ERROR;
    }

    Header header = new Header(this);
    header.index = mHeaders.size();
    header.cookie = cookie;
    if (idmapData != NULL) {
      header.resourceIDMap = new int[idmapDataSize / 4];
      if (header.resourceIDMap == NULL) {
//        delete header;
        return (mError = NO_MEMORY);
      }
//      memcpy(header.resourceIDMap, idmapData, idmapDataSize);
//      header.resourceIDMapSize = idmapDataSize;
    }
    mHeaders.add(header);

    final boolean notDeviceEndian = htods((short) 0xf0) != 0xf0;

    if (kDebugLoadTableNoisy) {
      ALOGV("Adding resources to ResTable: data=%s, size=0x%x, cookie=%d, copy=%d " +
          "idmap=%s\n", data, dataSize, cookie, copyData, idmapData);
    }

    if (copyData || notDeviceEndian) {
      header.ownedData = data; // malloc(dataSize);
      if (header.ownedData == NULL) {
        return (mError=NO_MEMORY);
      }
//      memcpy(header.ownedData, data, dataSize);
      data = header.ownedData;
    }

    ByteBuffer buf = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN);
//    header->header = (const ResTable_header*)data;
    header.header = new ResTable_header(buf, 0);
    header.size = dtohl(header.header.header.size);
    if (kDebugLoadTableSuperNoisy) {
      ALOGI("Got size 0x%x, again size 0x%x, raw size 0x%x\n", header.size,
          dtohl(header.header.header.size), header.header.header.size);
    }
    if (kDebugLoadTableNoisy) {
      ALOGV("Loading ResTable @%s:\n", header.header);
    }
    if (dtohs(header.header.header.headerSize) > header.size
        || header.size > dataSize) {
      ALOGW("Bad resource table: header size 0x%x or total size 0x%x is larger than data size 0x%x\n",
          (int)dtohs(header.header.header.headerSize),
          (int)header.size, (int)dataSize);
      return (mError=BAD_TYPE);
    }
    if (((dtohs(header.header.header.headerSize)|header.size)&0x3) != 0) {
      ALOGW("Bad resource table: header size 0x%x or total size 0x%x is not on an integer boundary\n",
          (int)dtohs(header.header.header.headerSize),
          (int)header.size);
      return (mError=BAD_TYPE);
    }
//    header->dataEnd = ((const uint8_t*)header->header) + header->size;
    header.dataEnd = header.size;

    // Iterate through all chunks.
    int curPackage = 0;

//    const ResChunk_header* chunk =
//      (const ResChunk_header*)(((const uint8_t*)header->header)
//    + dtohs(header->header->header.headerSize));
    ResChunk_header chunk =
      new ResChunk_header(buf, dtohs(header.header.header.headerSize));
    while (chunk != null && (chunk.myOffset()) <= (header.dataEnd -ResChunk_header.SIZEOF) &&
      (chunk.myOffset()) <= (header.dataEnd -dtohl(chunk.size))) {
    int err = validate_chunk(chunk, ResChunk_header.SIZEOF, header.dataEnd, "ResTable");
    if (err != NO_ERROR) {
      return (mError=err);
    }
    if (kDebugTableNoisy) {
      ALOGV("Chunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%s\n",
          dtohs(chunk.type), dtohs(chunk.headerSize), dtohl(chunk.size),
          (Object)((chunk.myOffset()) - (header.header.myOffset())));
    }
    final int csize = dtohl(chunk.size);
    final int ctype = dtohs(chunk.type);
    if (ctype == RES_STRING_POOL_TYPE) {
      if (header.values.getError() != NO_ERROR) {
        // Only use the first string chunk; ignore any others that
        // may appear.
        err = header.values.setTo(chunk.myBuf(), chunk.myOffset(), csize, false);
        if (err != NO_ERROR) {
          return (mError=err);
        }
      } else {
        ALOGW("Multiple string chunks found in resource table.");
      }
    } else if (ctype == RES_TABLE_PACKAGE_TYPE) {
      if (curPackage >= dtohl(header.header.packageCount)) {
        ALOGW("More package chunks were found than the %d declared in the header.",
            dtohl(header.header.packageCount));
        return (mError=BAD_TYPE);
      }

      if (parsePackage(
          new ResTable_package(chunk.myBuf(), chunk.myOffset()), header, appAsLib, isSystemAsset) != NO_ERROR) {
        return mError;
      }
      curPackage++;
    } else {
      ALOGW("Unknown chunk type 0x%x in table at 0x%x.\n",
          ctype,
          (chunk.myOffset()) - (header.header.myOffset()));
    }
    chunk = chunk.myOffset() + csize < header.dataEnd
        ? new ResChunk_header(chunk.myBuf(), chunk.myOffset() + csize)
        : null;
  }

    if (curPackage < dtohl(header.header.packageCount)) {
      ALOGW("Fewer package chunks (%d) were found than the %d declared in the header.",
          (int)curPackage, dtohl(header.header.packageCount));
      return (mError=BAD_TYPE);
    }
    mError = header.values.getError();
    if (mError != NO_ERROR) {
      ALOGW("No string values found in resource table!");
    }

    if (kDebugTableNoisy) {
      ALOGV("Returning from add with mError=%d\n", mError);
    }
    return mError;
  }
int addInternal(byte[] data, int dataSize, final Object idmapData, int idmapDataSize,
      boolean appAsLib, final int cookie, boolean copyData, boolean isSystemAsset)
  {
    if (!isTruthy(data)) {
      return NO_ERROR;
    }

    if (dataSize < ResTable_header.SIZEOF) {
      ALOGE("Invalid data. Size(%d) is smaller than a ResTable_header(%d).",
          (int) dataSize, (int) ResTable_header.SIZEOF);
      return UNKNOWN_ERROR;
    }

    Header header = new Header(this);
    header.index = mHeaders.size();
    header.cookie = cookie;
    if (idmapData != NULL) {
      header.resourceIDMap = new int[idmapDataSize / 4];
      if (header.resourceIDMap == NULL) {
//        delete header;
        return (mError = NO_MEMORY);
      }
//      memcpy(header.resourceIDMap, idmapData, idmapDataSize);
//      header.resourceIDMapSize = idmapDataSize;
    }
    mHeaders.add(header);

    final boolean notDeviceEndian = htods((short) 0xf0) != 0xf0;

    if (kDebugLoadTableNoisy) {
      ALOGV("Adding resources to ResTable: data=%s, size=0x%x, cookie=%d, copy=%d " +
          "idmap=%s\n", data, dataSize, cookie, copyData, idmapData);
    }

    if (copyData || notDeviceEndian) {
      header.ownedData = data; // malloc(dataSize);
      if (header.ownedData == NULL) {
        return (mError=NO_MEMORY);
      }
//      memcpy(header.ownedData, data, dataSize);
      data = header.ownedData;
    }

    ByteBuffer buf = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN);
//    header->header = (const ResTable_header*)data;
    header.header = new ResTable_header(buf, 0);
    header.size = dtohl(header.header.header.size);
    if (kDebugLoadTableSuperNoisy) {
      ALOGI("Got size 0x%x, again size 0x%x, raw size 0x%x\n", header.size,
          dtohl(header.header.header.size), header.header.header.size);
    }
    if (kDebugLoadTableNoisy) {
      ALOGV("Loading ResTable @%s:\n", header.header);
    }
    if (dtohs(header.header.header.headerSize) > header.size
        || header.size > dataSize) {
      ALOGW("Bad resource table: header size 0x%x or total size 0x%x is larger than data size 0x%x\n",
          (int)dtohs(header.header.header.headerSize),
          (int)header.size, (int)dataSize);
      return (mError=BAD_TYPE);
    }
    if (((dtohs(header.header.header.headerSize)|header.size)&0x3) != 0) {
      ALOGW("Bad resource table: header size 0x%x or total size 0x%x is not on an integer boundary\n",
          (int)dtohs(header.header.header.headerSize),
          (int)header.size);
      return (mError=BAD_TYPE);
    }
//    header->dataEnd = ((const uint8_t*)header->header) + header->size;
    header.dataEnd = header.size;

    // Iterate through all chunks.
    int curPackage = 0;

//    const ResChunk_header* chunk =
//      (const ResChunk_header*)(((const uint8_t*)header->header)
//    + dtohs(header->header->header.headerSize));
    ResChunk_header chunk =
      new ResChunk_header(buf, dtohs(header.header.header.headerSize));
    while (chunk != null && (chunk.myOffset()) <= (header.dataEnd -ResChunk_header.SIZEOF) &&
      (chunk.myOffset()) <= (header.dataEnd -dtohl(chunk.size))) {
    int err = validate_chunk(chunk, ResChunk_header.SIZEOF, header.dataEnd, "ResTable");
    if (err != NO_ERROR) {
      return (mError=err);
    }
    if (kDebugTableNoisy) {
      ALOGV("Chunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%s\n",
          dtohs(chunk.type), dtohs(chunk.headerSize), dtohl(chunk.size),
          (Object)((chunk.myOffset()) - (header.header.myOffset())));
    }
    final int csize = dtohl(chunk.size);
    final int ctype = dtohs(chunk.type);
    if (ctype == RES_STRING_POOL_TYPE) {
      if (header.values.getError() != NO_ERROR) {
        // Only use the first string chunk; ignore any others that
        // may appear.
        err = header.values.setTo(chunk.myBuf(), chunk.myOffset(), csize, false);
        if (err != NO_ERROR) {
          return (mError=err);
        }
      } else {
        ALOGW("Multiple string chunks found in resource table.");
      }
    } else if (ctype == RES_TABLE_PACKAGE_TYPE) {
      if (curPackage >= dtohl(header.header.packageCount)) {
        ALOGW("More package chunks were found than the %d declared in the header.",
            dtohl(header.header.packageCount));
        return (mError=BAD_TYPE);
      }

      if (parsePackage(
          new ResTable_package(chunk.myBuf(), chunk.myOffset()), header, appAsLib, isSystemAsset) != NO_ERROR) {
        return mError;
      }
      curPackage++;
    } else {
      ALOGW("Unknown chunk type 0x%x in table at 0x%x.\n",
          ctype,
          (chunk.myOffset()) - (header.header.myOffset()));
    }
    chunk = chunk.myOffset() + csize < header.dataEnd
        ? new ResChunk_header(chunk.myBuf(), chunk.myOffset() + csize)
        : null;
  }

    if (curPackage < dtohl(header.header.packageCount)) {
      ALOGW("Fewer package chunks (%d) were found than the %d declared in the header.",
          (int)curPackage, dtohl(header.header.packageCount));
      return (mError=BAD_TYPE);
    }
    mError = header.values.getError();
    if (mError != NO_ERROR) {
      ALOGW("No string values found in resource table!");
    }

    if (kDebugTableNoisy) {
      ALOGV("Returning from add with mError=%d\n", mError);
    }
    return mError;
  }
int addInternal ( byte [ ] data , int dataSize , final Object idmapData , int idmapDataSize , boolean appAsLib , final int cookie , boolean copyData , boolean isSystemAsset ) { if ( ! isTruthy ( data ) ) { return NO_ERROR ; } if ( dataSize < ResTable_header . SIZEOF ) { ALOGE ( "Invalid data. Size(%d) is smaller than a ResTable_header(%d)." , ( int ) dataSize , ( int ) ResTable_header . SIZEOF ) ; return UNKNOWN_ERROR ; } Header header = new Header ( this ) ; header . index = mHeaders . size ( ) ; header . cookie = cookie ; if ( idmapData != NULL ) { header . resourceIDMap = new int [ idmapDataSize / 4 ] ; if ( header . resourceIDMap == NULL ) { //        delete header; return ( mError = NO_MEMORY ) ; } //      memcpy(header.resourceIDMap, idmapData, idmapDataSize); //      header.resourceIDMapSize = idmapDataSize; } mHeaders . add ( header ) ; final boolean notDeviceEndian = htods ( ( short ) 0xf0 ) != 0xf0 ; if ( kDebugLoadTableNoisy ) { ALOGV ( "Adding resources to ResTable: data=%s, size=0x%x, cookie=%d, copy=%d " + "idmap=%s\n" , data , dataSize , cookie , copyData , idmapData ) ; } if ( copyData || notDeviceEndian ) { header . ownedData = data ; // malloc(dataSize); if ( header . ownedData == NULL ) { return ( mError = NO_MEMORY ) ; } //      memcpy(header.ownedData, data, dataSize); data = header . ownedData ; } ByteBuffer buf = ByteBuffer . wrap ( data ) . order ( ByteOrder . LITTLE_ENDIAN ) ; //    header->header = (const ResTable_header*)data; header . header = new ResTable_header ( buf , 0 ) ; header . size = dtohl ( header . header . header . size ) ; if ( kDebugLoadTableSuperNoisy ) { ALOGI ( "Got size 0x%x, again size 0x%x, raw size 0x%x\n" , header . size , dtohl ( header . header . header . size ) , header . header . header . size ) ; } if ( kDebugLoadTableNoisy ) { ALOGV ( "Loading ResTable @%s:\n" , header . header ) ; } if ( dtohs ( header . header . header . headerSize ) > header . size || header . size > dataSize ) { ALOGW ( "Bad resource table: header size 0x%x or total size 0x%x is larger than data size 0x%x\n" , ( int ) dtohs ( header . header . header . headerSize ) , ( int ) header . size , ( int ) dataSize ) ; return ( mError = BAD_TYPE ) ; } if ( ( ( dtohs ( header . header . header . headerSize ) | header . size ) & 0x3 ) != 0 ) { ALOGW ( "Bad resource table: header size 0x%x or total size 0x%x is not on an integer boundary\n" , ( int ) dtohs ( header . header . header . headerSize ) , ( int ) header . size ) ; return ( mError = BAD_TYPE ) ; } //    header->dataEnd = ((const uint8_t*)header->header) + header->size; header . dataEnd = header . size ; // Iterate through all chunks. int curPackage = 0 ; //    const ResChunk_header* chunk = //      (const ResChunk_header*)(((const uint8_t*)header->header) //    + dtohs(header->header->header.headerSize)); ResChunk_header chunk = new ResChunk_header ( buf , dtohs ( header . header . header . headerSize ) ) ; while ( chunk != null && ( chunk . myOffset ( ) ) <= ( header . dataEnd - ResChunk_header . SIZEOF ) && ( chunk . myOffset ( ) ) <= ( header . dataEnd - dtohl ( chunk . size ) ) ) { int err = validate_chunk ( chunk , ResChunk_header . SIZEOF , header . dataEnd , "ResTable" ) ; if ( err != NO_ERROR ) { return ( mError = err ) ; } if ( kDebugTableNoisy ) { ALOGV ( "Chunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%s\n" , dtohs ( chunk . type ) , dtohs ( chunk . headerSize ) , dtohl ( chunk . size ) , ( Object ) ( ( chunk . myOffset ( ) ) - ( header . header . myOffset ( ) ) ) ) ; } final int csize = dtohl ( chunk . size ) ; final int ctype = dtohs ( chunk . type ) ; if ( ctype == RES_STRING_POOL_TYPE ) { if ( header . values . getError ( ) != NO_ERROR ) { // Only use the first string chunk; ignore any others that // may appear. err = header . values . setTo ( chunk . myBuf ( ) , chunk . myOffset ( ) , csize , false ) ; if ( err != NO_ERROR ) { return ( mError = err ) ; } } else { ALOGW ( "Multiple string chunks found in resource table." ) ; } } else if ( ctype == RES_TABLE_PACKAGE_TYPE ) { if ( curPackage >= dtohl ( header . header . packageCount ) ) { ALOGW ( "More package chunks were found than the %d declared in the header." , dtohl ( header . header . packageCount ) ) ; return ( mError = BAD_TYPE ) ; } if ( parsePackage ( new ResTable_package ( chunk . myBuf ( ) , chunk . myOffset ( ) ) , header , appAsLib , isSystemAsset ) != NO_ERROR ) { return mError ; } curPackage ++ ; } else { ALOGW ( "Unknown chunk type 0x%x in table at 0x%x.\n" , ctype , ( chunk . myOffset ( ) ) - ( header . header . myOffset ( ) ) ) ; } chunk = chunk . myOffset ( ) + csize < header . dataEnd ? new ResChunk_header ( chunk . myBuf ( ) , chunk . myOffset ( ) + csize ) : null ; } if ( curPackage < dtohl ( header . header . packageCount ) ) { ALOGW ( "Fewer package chunks (%d) were found than the %d declared in the header." , ( int ) curPackage , dtohl ( header . header . packageCount ) ) ; return ( mError = BAD_TYPE ) ; } mError = header . values . getError ( ) ; if ( mError != NO_ERROR ) { ALOGW ( "No string values found in resource table!" ) ; } if ( kDebugTableNoisy ) { ALOGV ( "Returning from add with mError=%d\n" , mError ) ; } return mError ; }
bool appAsLib, const int32_t cookie, bool copyData, bool isSystemAsset=false);
bool appAsLib const int32_t cookie bool copyData bool isSystemAsset = false ) ;