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.
39 int SparseFile::init_header(size_t blsz
, int blcount
)
43 memset(&header
, 0, sizeof(header
));
44 header
.magic
= SPARSE_HEADER_MAGIC
;
45 header
.major_version
= 1;
46 header
.minor_version
= 0;
47 header
.file_hdr_sz
= sizeof(header
);
48 header
.chunk_hdr_sz
= sizeof(chunk_header
);
50 m_cur_chunk_header_pos
= 0;
53 m_data
.reserve(blsz
*blcount
+ 0x1000);
54 m_max_size
= blsz
* blcount
;
57 push(&header
, sizeof(header
));
58 m_pcrc
= (uint32_t*)(m_data
.data() + offsetof(sparse_header
, image_checksum
));
62 bool SparseFile::is_append_old_chuck(int type
, void *p
)
64 chunk_header_t
*pchunk
;
65 pchunk
= (chunk_header_t
*)(m_data
.data() + m_cur_chunk_header_pos
);
67 if (m_cur_chunk_header_pos
== 0)
70 if (pchunk
->chunk_type
!= type
)
73 if (type
== CHUNK_TYPE_FILL
)
75 uint32_t a
= *(uint32_t*)(pchunk
+ 1);
76 uint32_t b
= *(uint32_t*)p
;
83 bool SparseFile::is_same_value(void *data
, size_t sz
)
85 uint32_t *p
= (uint32_t *)data
;
87 for (size_t i
= 0; i
< sz
/ sizeof(uint32_t); i
++)
93 bool SparseFile::is_validate_sparse_file(void *p
, size_t)
95 sparse_header
*pheader
= (sparse_header
*)p
;
96 if (pheader
->magic
== SPARSE_HEADER_MAGIC
)
101 int SparseFile::push(void *p
, size_t sz
)
103 size_t pos
= m_data
.size();
104 m_data
.resize(pos
+ sz
);
105 memcpy(m_data
.data() + pos
, p
, sz
);
109 int SparseFile::push_one_block(void *data
)
111 chunk_header_t
*pchunk
;
112 pchunk
= (chunk_header_t
*)(m_data
.data() + m_cur_chunk_header_pos
);
114 sparse_header
*pheader
;
115 pheader
= (sparse_header
*)m_data
.data();
117 pheader
->total_blks
++;
119 //int type = is_same_value(data, pheader->blk_sz) ? CHUNK_TYPE_FILL : CHUNK_TYPE_RAW;
120 int type
= CHUNK_TYPE_RAW
;
122 if (!is_append_old_chuck(type
, data
))
124 chunk_header_t header
;
125 header
.chunk_type
= type
;
127 header
.total_sz
= (type
== CHUNK_TYPE_FILL
) ? sizeof(uint32_t) : pheader
->blk_sz
;
128 header
.total_sz
+= sizeof(chunk_header_t
);
129 header
.reserved1
= 0;
131 pheader
->total_chunks
++;
133 m_cur_chunk_header_pos
= m_data
.size();
135 push(&header
, sizeof(chunk_header_t
));
137 if (type
== CHUNK_TYPE_RAW
)
138 push(data
, pheader
->blk_sz
);
140 push(data
, sizeof(uint32_t));
145 if (type
== CHUNK_TYPE_RAW
)
147 push(data
, pheader
->blk_sz
);
148 pchunk
->total_sz
+= pheader
->blk_sz
;
152 if (m_data
.size() + 2 * pheader
->blk_sz
> m_max_size
)
158 size_t SparseFile::push_one_chuck(chunk_header_t
*p
, void *data
)
160 chunk_header_t cheader
= *p
;
161 sparse_header
*pheader
;
162 pheader
= (sparse_header
*)m_data
.data();
164 size_t sz
= p
->total_sz
- sizeof(chunk_header
);
166 if (p
->total_sz
+ m_data
.size() > m_max_size
)
168 if (p
->chunk_type
== CHUNK_TYPE_RAW
)
170 size_t blk
= (m_max_size
- m_data
.size()) / pheader
->blk_sz
;
176 cheader
.chunk_sz
= blk
;
177 sz
= blk
* pheader
->blk_sz
;
178 cheader
.total_sz
= sizeof(chunk_header_t
) + sz
;
184 push(&cheader
, sizeof(chunk_header
));
185 pheader
->total_chunks
++;
186 pheader
->total_blks
+= cheader
.chunk_sz
;
195 size_t SparseFile::push_raw_data(void *data
, size_t sz
)
197 chunk_header_t cheader
;
198 cheader
.chunk_type
= CHUNK_TYPE_RAW
;
200 sparse_header
*pheader
;
201 pheader
= (sparse_header
*)m_data
.data();
203 cheader
.chunk_sz
= sz
/ pheader
->blk_sz
;
204 cheader
.total_sz
= cheader
.chunk_sz
*pheader
->blk_sz
+ sizeof(chunk_header_t
);
205 pheader
= (sparse_header
*)m_data
.data();
207 return push_one_chuck(&cheader
, data
);