1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     snd_GroupFileReader.cpp
4 
5   Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain proprietary
8   information of Nintendo and/or its licensed developers and are protected by
9   national and international copyright laws. They may not be disclosed to third
10   parties or copied or duplicated in any form, in whole or in part, without the
11   prior written consent of Nintendo.
12 
13   The content herein is highly confidential and should be handled accordingly.
14 
15   $Revision: 31311 $
16  *---------------------------------------------------------------------------*/
17 
18 #include "precompiled.h"
19 
20 #include <nw/snd/snd_GroupFileReader.h>
21 
22 namespace nw {
23 namespace snd {
24 namespace internal {
25 
26 namespace {
27 
28 const u32 SIGNATURE_INFO_BLOCK  = NW_UT_MAKE_SIGWORD( 'I', 'N', 'F', 'O' );
29 const u32 SIGNATURE_FILE_BLOCK  = NW_UT_MAKE_SIGWORD( 'F', 'I', 'L', 'E' );
30 const u32 SIGNATURE_INFOEX_BLOCK  = NW_UT_MAKE_SIGWORD( 'I', 'N', 'F', 'X' );
31 
32 const u32 SUPPORTED_FILE_VERSION = 0x01000000;
33 const u32 CURRENT_FILE_VERSION   = 0x01010000;
34 
IsValidFileHeader(const void * groupFile)35 bool IsValidFileHeader( const void* groupFile )
36 {
37     const ut::BinaryFileHeader* header =
38         reinterpret_cast<const ut::BinaryFileHeader*>( groupFile );
39 
40     // シグニチャ確認
41     NW_ASSERTMSG( header->signature == GroupFileReader::SIGNATURE_FILE,
42             "invalid file signature. group file is not available." );
43     if ( header->signature != GroupFileReader::SIGNATURE_FILE )
44     {
45         return false;
46     }
47 
48     // バージョン確認
49     NW_ASSERTMSG( header->version >= SUPPORTED_FILE_VERSION,
50             "group file is not supported version.\n"
51             "please reconvert file using new version tools.\n"
52             "(SUPPORTED_FILE_VERSION:0x%08x >= your version:0x%08x)\n",
53             SUPPORTED_FILE_VERSION, header->version
54     );
55     if ( header->version < SUPPORTED_FILE_VERSION ) return false;
56 
57     NW_ASSERTMSG( header->version <= CURRENT_FILE_VERSION,
58             "group file is not supported version.\n"
59             "please reconvert file using new version tools.\n"
60             "(CURRENT_FILE_VERSION:0x%08x >= your version:0x%08x)\n",
61             CURRENT_FILE_VERSION, header->version
62     );
63     if ( header->version > CURRENT_FILE_VERSION ) return false;
64 
65     return true;
66 }
67 
68 } // anonymous namespace
69 
GroupFileReader(const void * groupFile)70 GroupFileReader::GroupFileReader( const void* groupFile )
71 : m_pInfoBlockBody( NULL ),
72   m_pFileBlockBody( NULL ),
73   m_pInfoExBlockBody( NULL )
74 {
75     NW_NULL_ASSERT( groupFile );
76 
77     if ( ! IsValidFileHeader( groupFile ) ) return;
78 
79     const GroupFile::FileHeader* header =
80         static_cast<const GroupFile::FileHeader*>( groupFile );
81 
82     const GroupFile::InfoBlock* infoBlock = header->GetInfoBlock();
83     const GroupFile::FileBlock* fileBlock = header->GetFileBlock();
84     const GroupFile::InfoExBlock* infoExBlock = header->GetInfoExBlock();
85 
86     if ( infoBlock == NULL ) return;
87     if ( fileBlock == NULL ) return;
88 
89     NW_ASSERT( infoBlock->header.kind == SIGNATURE_INFO_BLOCK );
90     NW_ASSERT( fileBlock->header.kind == SIGNATURE_FILE_BLOCK );
91 
92     m_pInfoBlockBody = &(infoBlock->body);
93     m_pFileBlockBody = &(fileBlock->body);
94 
95 
96     // バイナリバージョンが 1.0.0.0 のときは InfoExBlock が含まれない
97     if ( infoExBlock != NULL )
98     {
99         NW_ASSERT( infoExBlock->header.kind == SIGNATURE_INFOEX_BLOCK );
100         m_pInfoExBlockBody = &(infoExBlock->body);
101     }
102 }
103 
ReadGroupItemLocationInfo(GroupItemLocationInfo * out,u32 index) const104 bool GroupFileReader::ReadGroupItemLocationInfo(
105         GroupItemLocationInfo* out, u32 index ) const
106 {
107     if ( m_pInfoBlockBody == NULL )
108     {
109         return false;
110     }
111 
112     const GroupFile::GroupItemInfo* groupItemInfo = m_pInfoBlockBody->GetGroupItemInfo( index );
113     if ( groupItemInfo == NULL )
114     {
115         return false;
116     }
117 
118     out->fileId = groupItemInfo->fileId;
119     out->address = groupItemInfo->GetFileLocation( m_pFileBlockBody );
120     return true;
121 }
122 
GetGroupItemExCount() const123 u32 GroupFileReader::GetGroupItemExCount() const
124 {
125     if ( m_pInfoExBlockBody == NULL )
126     {
127         return 0;
128     }
129 
130     return m_pInfoExBlockBody->GetGroupItemInfoExCount();
131 }
132 
ReadGroupItemInfoEx(GroupFile::GroupItemInfoEx * out,u32 index) const133 bool GroupFileReader::ReadGroupItemInfoEx( GroupFile::GroupItemInfoEx* out, u32 index ) const
134 {
135     if ( m_pInfoExBlockBody == NULL )
136     {
137         return false;
138     }
139 
140     const GroupFile::GroupItemInfoEx* groupItemInfoEx =
141         m_pInfoExBlockBody->GetGroupItemInfoEx( index );
142     if ( groupItemInfoEx == NULL )
143     {
144         return false;
145     }
146 
147     *out = *groupItemInfoEx; // 構造体のコピー
148     return true;
149 }
150 
151 } // namespace nw::snd::internal
152 } // namespace nw::snd
153 } // namespace nw
154 
155