1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: ut_BinaryFileFormat.cpp
4
5 Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Revision:$
14 *---------------------------------------------------------------------------*/
15
16 #include "precompiled.h"
17
18 #include <nw/types.h>
19 #include <nw/assert.h>
20 #include <nw/ut/ut_BinaryFileFormat.h>
21 #include <nw/ut/ut_Inlines.h>
22
23
24 namespace nw {
25 namespace ut {
26
27
28 bool
IsValidBinaryFile(const BinaryFileHeader * pHeader,u32 signature,u32 version,u16 minBlocks)29 IsValidBinaryFile(
30 const BinaryFileHeader* pHeader,
31 u32 signature,
32 u32 version,
33 u16 minBlocks /* = 1 */
34 )
35 {
36 NW_POINTER_ASSERT( pHeader );
37
38 if ( pHeader->signature != signature )
39 {
40 NW_WARNING(false, "Signature check failed ('%c%c%c%c' must be '%c%c%c%c').",
41 static_cast<char>(BitExtract(pHeader->signature, 24, 8)),
42 static_cast<char>(BitExtract(pHeader->signature, 16, 8)),
43 static_cast<char>(BitExtract(pHeader->signature, 8, 8)),
44 static_cast<char>(BitExtract(pHeader->signature, 0, 8)),
45 static_cast<char>(BitExtract(signature, 24, 8)),
46 static_cast<char>(BitExtract(signature, 16, 8)),
47 static_cast<char>(BitExtract(signature, 8, 8)),
48 static_cast<char>(BitExtract(signature, 0, 8))
49 );
50 return false;
51 }
52
53 if ( pHeader->byteOrder != BYTE_ORDER_MARK )
54 {
55 NW_WARNING(false, "Unsupported byte order.");
56 return false;
57 }
58
59 if ( NW_UT_VERSION_MAJOR(version) != NW_UT_VERSION_MAJOR(pHeader->version) ||
60 NW_UT_VERSION_MINOR(version) < NW_UT_VERSION_MINOR(pHeader->version) ||
61 NW_UT_VERSION_BINARYBUGFIX(version) > NW_UT_VERSION_BINARYBUGFIX(pHeader->version) )
62 {
63 NW_WARNING(false, "Version check faild (bin:'%d.%d.%d.%d', lib:'%d.%d.%d.%d').",
64 NW_UT_VERSION_MAJOR(pHeader->version),
65 NW_UT_VERSION_MINOR(pHeader->version),
66 NW_UT_VERSION_MICRO(pHeader->version),
67 NW_UT_VERSION_BINARYBUGFIX(pHeader->version),
68 NW_UT_VERSION_MAJOR(version),
69 NW_UT_VERSION_MINOR(version),
70 NW_UT_VERSION_MICRO(version),
71 NW_UT_VERSION_BINARYBUGFIX(version)
72 );
73 return false;
74 }
75
76 if( pHeader->fileSize < sizeof(BinaryFileHeader) + sizeof(BinaryBlockHeader) * minBlocks )
77 {
78 NW_WARNING(false, "Too small file size(=%d).", pHeader->fileSize);
79 return false;
80 }
81
82 if( pHeader->dataBlocks < minBlocks )
83 {
84 NW_WARNING(false, "Too small number of data blocks(=%d).", pHeader->dataBlocks);
85 return false;
86 }
87
88 return true;
89 }
90
91
92 /*!--------------------------------------------------------------------------*
93 Name: IsReverseEndianBinaryFile
94
95 @brief NintendoWare 標準バイナリファイルのエンディアンが逆かどうかを
96 チェックします。
97
98 @param[in] pFileHeader 対象のファイルヘッダへのポインタ
99
100 @return エンディアンが逆なら true,さもなければ false を返します。
101 *---------------------------------------------------------------------------*/
102 bool
IsReverseEndianBinaryFile(const BinaryFileHeader * pFileHeader)103 IsReverseEndianBinaryFile( const BinaryFileHeader* pFileHeader )
104 {
105 NW_POINTER_ASSERT( pFileHeader );
106 return ( pFileHeader->byteOrder != BYTE_ORDER_MARK );
107 }
108
109
110 /*!--------------------------------------------------------------------------*
111 Name: GetNextBinaryBlockHeader
112
113 @brief NintendoWare 標準バイナリファイル内の次のブロックヘッダを
114 取得します。
115
116 @param[in] pFileHeader 対象のファイルヘッダへのポインタ
117 @param[in] pBlockHeader 現在のブロックヘッダへのポインタ
118
119 @return pBlockHeaderの次のブロックヘッダを返します。
120 次のブロックがない場合は、NULLを返します。
121 pBlockHeaderがNULLの場合は、一番始めのブロックヘッダを返します。
122 *---------------------------------------------------------------------------*/
123 BinaryBlockHeader*
GetNextBinaryBlockHeader(BinaryFileHeader * pFileHeader,BinaryBlockHeader * pBlockHeader)124 GetNextBinaryBlockHeader(
125 BinaryFileHeader* pFileHeader,
126 BinaryBlockHeader* pBlockHeader
127 )
128 {
129 NW_POINTER_ASSERT( pFileHeader );
130
131 void* ptr;
132 if ( ! IsReverseEndianBinaryFile( pFileHeader ) )
133 {
134 if ( pBlockHeader == NULL )
135 {
136 if ( pFileHeader->dataBlocks == 0 ) return NULL;
137 ptr = AddOffsetToPtr( pFileHeader, pFileHeader->headerSize );
138 }
139 else
140 {
141 ptr = AddOffsetToPtr( pBlockHeader, pBlockHeader->size );
142 }
143
144 if ( ptr >= AddOffsetToPtr( pFileHeader, pFileHeader->fileSize ) )
145 {
146 return NULL;
147 }
148 }
149 else
150 {
151 if ( pBlockHeader == NULL )
152 {
153 if ( pFileHeader->dataBlocks == 0 ) return NULL;
154 ptr = AddOffsetToPtr( pFileHeader, ReverseEndian( pFileHeader->headerSize ) );
155 }
156 else
157 {
158 ptr = AddOffsetToPtr( pBlockHeader, ReverseEndian( pBlockHeader->size ) );
159 }
160
161 if ( ptr >= AddOffsetToPtr( pFileHeader, ReverseEndian( pFileHeader->fileSize ) ) )
162 {
163 return NULL;
164 }
165 }
166
167 return reinterpret_cast<BinaryBlockHeader*>( ptr );
168 }
169
170 } /* namespace ut */
171 } /* namespace nw */
172