4 * Redistribution and use in source and binary forms, with or without modification,
5 * are permitted provided that the following conditions are met:
7 * Redistributions of source code must retain the above copyright notice, this
8 * list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright notice, this
11 * list of conditions and the following disclaimer in the documentation and/or
12 * other materials provided with the distribution.
14 * Neither the name of the NXP Semiconductor nor the names of its
15 * contributors may be used to endorse or promote products derived from this
16 * software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
48 int Tar::Open(const string
&filename
)
50 bool end_of_file
=false;
51 char end_of_file_blocks
[2*TAR_BLOCK_SIZE
];
52 memset(end_of_file_blocks
, 0, sizeof(end_of_file_blocks
) );
53 m_tarfilename
=filename
;
55 shared_ptr
<FileBuffer
> file
= get_file_buffer(filename
);
59 uint8_t* data
=file
->data();
60 uint64_t block_counter
=0;
63 if(!memcmp(end_of_file_blocks
,data
+block_counter
*TAR_BLOCK_SIZE
,TAR_BLOCK_SIZE
))
68 struct Tar_header
* th
=(Tar_header
*)(data
+block_counter
*TAR_BLOCK_SIZE
);
70 string
octal_str((char*)th
->size
);
71 //printf("block_counter: %d\n",block_counter );
72 //printf("name: %s\n",th->name );
73 //printf("signature: %s\n",th->ustar );
74 //printf("size: %s\n", th->size);
75 size
=stoll(octal_str
, 0, 8);
76 string
name((char*)th
->name
);
77 m_filemap
[name
].size
=size
;
78 m_filemap
[name
].offset
=(block_counter
+1)*TAR_BLOCK_SIZE
; //+1 because the data located right after the header block
79 m_filemap
[name
].filename
.assign((char*)th
->name
);
82 //skip the data blocks
83 uint64_t data_block_num
=size
/TAR_BLOCK_SIZE
;
84 data_block_num
+= (size
%TAR_BLOCK_SIZE
>0)? 1:0;
85 block_counter
+=data_block_num
;
90 bool Tar::check_file_exist(const string
&filename
)
93 if (m_filemap
.find(filename
) == m_filemap
.end())
96 err
+= "Can't find file ";
98 set_last_err_string(err
);
106 int Tar::get_file_buff(const string
&filename
, shared_ptr
<FileBuffer
> p
)
109 if (m_filemap
.find(filename
) == m_filemap
.end())
112 err
+= "Can't find file ";
114 set_last_err_string(err
);
118 p
->resize(m_filemap
[filename
].size
);
119 atomic_fetch_or(&p
->m_dataflags
, FILEBUFFER_FLAG_KNOWN_SIZE
);
120 p
->m_request_cv
.notify_all();
122 shared_ptr
<FileBuffer
> file
;
123 file
= get_file_buffer(m_tarfilename
);
124 size_t offset
= m_filemap
[filename
].offset
;
125 size_t size
=m_filemap
[filename
].size
;
127 p
->ref_other_buffer(file
, offset
, size
);
128 atomic_fetch_or(&p
->m_dataflags
, FILEBUFFER_FLAG_LOADED
);
129 p
->m_request_cv
.notify_all();