Advertisement
Guest User

Untitled

a guest
Jul 22nd, 2019
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.61 KB | None | 0 0
  1. #include <cache/cache_file_tag_resources.h>
  2. #include <zlib/zlib.h>
  3.  
  4. /* ---------- code */
  5.  
  6. bool c_cache_file::tag_resource_try_and_get(
  7.     long index,
  8.     long length,
  9.     void **out_address)
  10. {
  11.     if (index == NONE)
  12.     {
  13.         if (out_address)
  14.             *out_address = nullptr;
  15.         return false;
  16.     }
  17.  
  18.     long zone_index = NONE;
  19.     long tag_count = get_tags_header()->tag_count;
  20.  
  21.     for (auto i = 0; i < tag_count; i++)
  22.     {
  23.         auto instance = get_tag_instance(i);
  24.  
  25.         if (!instance || !instance->address  || instance->group_index == NONE)
  26.             continue;
  27.  
  28.         auto group = get_tag_group(instance->group_index);
  29.  
  30.         if (!group)
  31.             continue;
  32.  
  33.         if (group->is_in_group(k_cache_file_resource_gestalt_group_tag))
  34.         {
  35.             zone_index = i;
  36.             break;
  37.         }
  38.     }
  39.  
  40.     if (zone_index == NONE)
  41.     {
  42.         if (out_address)
  43.             *out_address = nullptr;
  44.         return false;
  45.     }
  46.  
  47.     auto definition = get_tag_definition<s_cache_file_resource_gestalt>(zone_index);
  48.     auto resource = &definition->tag_resources[index & k_word_maximum];
  49.  
  50.     if (!resource->segment_index)
  51.     {
  52.         if (out_address)
  53.             *out_address = nullptr;
  54.         return false;
  55.     }
  56.  
  57.     s_cache_file_resource_segment *segment = nullptr;
  58.  
  59.     if (!resource->segment_index.try_resolve(&definition->layout_table.segments, &segment) ||
  60.         !segment->primary_page || segment->primary_segment_offset == NONE)
  61.     {
  62.         if (out_address)
  63.             *out_address = nullptr;
  64.         return false;
  65.     }
  66.  
  67.     auto page_index = (segment->secondary_page) ?
  68.         segment->secondary_page :
  69.         segment->primary_page;
  70.  
  71.     auto segment_offset = (segment->secondary_segment_offset != NONE) ?
  72.         segment->secondary_segment_offset :
  73.         segment->primary_segment_offset;
  74.  
  75.     if (!page_index || segment_offset == NONE)
  76.     {
  77.         if (out_address)
  78.             *out_address = nullptr;
  79.         return false;
  80.     }
  81.  
  82.     if (page_index.resolve(&definition->layout_table.pages)->block_offset == NONE)
  83.     {
  84.         page_index = segment->primary_page;
  85.         segment_offset = segment->primary_segment_offset;
  86.     }
  87.  
  88.     auto page = page_index.resolve(&definition->layout_table.pages);
  89.    
  90.     length = (length == NONE) ?
  91.         (page->uncompressed_block_size - segment_offset) :
  92.         length;
  93.  
  94.     char resource_cache_file_path[1024];
  95.     memset(resource_cache_file_path, 0, 1024);
  96.  
  97.     if (page->shared_cache_file)
  98.     {
  99.         memcpy(resource_cache_file_path, g_cache_file_path, strrchr(g_cache_file_path, '\\') - g_cache_file_path);
  100.  
  101.         auto entry = page->shared_cache_file.resolve(&definition->layout_table.physical_locations);
  102.         auto file_path = strrchr(entry->path.ascii, '\\');
  103.         memcpy(resource_cache_file_path + strlen(resource_cache_file_path), file_path, strlen(file_path));
  104.     }
  105.     else
  106.     {
  107.         memcpy(resource_cache_file_path, g_cache_file_path, strlen(g_cache_file_path));
  108.     }
  109.  
  110.     auto resource_data_offset = m_header.interop.debug_section_size + page->block_offset;
  111.    
  112.     auto uncompressed_data = new byte[length];
  113.  
  114.     if (out_address)
  115.         *out_address = uncompressed_data;
  116.  
  117.     FILE *stream = fopen(resource_cache_file_path, "rb+");
  118.     fseek(stream, resource_data_offset, SEEK_SET);
  119.  
  120.     if (!page->compression_codec)
  121.     {
  122.         fread(uncompressed_data, length, 1, stream);
  123.     }
  124.     else
  125.     {
  126.         auto compressed_data = new byte[page->compressed_block_size];
  127.         fread(compressed_data, page->compressed_block_size, 1, stream);
  128.  
  129.         z_stream infstream;
  130.         infstream.zalloc = Z_NULL;
  131.         infstream.zfree = Z_NULL;
  132.         infstream.opaque = Z_NULL;
  133.         infstream.avail_in = page->compressed_block_size;
  134.         infstream.next_in = compressed_data;
  135.         infstream.avail_out = length;
  136.         infstream.next_out = uncompressed_data;
  137.  
  138.         inflateInit(&infstream);
  139.         inflate(&infstream, Z_NO_FLUSH);
  140.         inflateEnd(&infstream);
  141.  
  142.         delete[] compressed_data;
  143.     }
  144.  
  145.     fclose(stream);
  146.  
  147.     return true;
  148. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement