'스타크래프트 chk의 구조 - Chunk의 읽기와 작성
'Code by ModMapper
Imports System.Collections.Generic
Imports System.Text
Imports System.IO
''' <summary>Chunk를 읽거나 작성하는 모듈입니다.</summary>
Module Chunk
''' <summary>Chunk 구휙 형식</summary>
Public Structure Section
Dim Name As String '구휙 이름
Dim Data As MemoryStream '구휙 내용
End Structure
''' <summary>파일에서 Chunk를 읽는 함수.</summary>
''' <param name="FileName">읽어들일 파일 이름.</param>
''' <returns>읽어들인 Chunk값</returns>
Public Function Chunk_ReadFile(FileName As String) As List(Of Section)
'읽기 전용으로 파일 스트림을 연다.
Dim FS As New FileStream(FileName, FileMode.Open, FileAccess.Read)
Dim Chunk = Chunk_ReadStream(FS)
FS.Close() '사용한 파일 스트림을 닫음
Return Chunk
End Function
''' <summary>스트림에서 Chunk를 읽는 함수.</summary>
''' <param name="Stream">읽어들일 스트림.</param>
''' <returns>읽어들인 Chunk값</returns>
Public Function Chunk_ReadStream(Stream As Stream) As List(Of Section)
'스트림 읽기에 관련된 함수가 있는 BinaryReader를 생성한다.
Dim Reader As New BinaryReader(Stream)
Dim Chunk As New List(Of Section)
'스트림이 끝날때 까지 반복
While Stream.Position < Stream.Length
Dim Section As Section
Dim Size As Integer
'스트림에서 구휙의 이름을 읽어들임 (4바이트 문자열)
Section.Name = Encoding.Default.GetString(Reader.ReadBytes(4))
'스트림에서 구휙의 크기를 읽어들임 (4바이트 정수)
Size = Reader.ReadInt32()
'메모리를 사용하기 위해 MemoryStream을 생성한다.
Section.Data = New MemoryStream()
If Size > 0 Then '만일 크기가 0이하면 할당 할 수 없기 때문에 예외 처리
'스트림에서 내용을 읽어서 작성한다.
Section.Data.Write(Reader.ReadBytes(Size), 0, Size)
Else
'스트림을 Size만큼 이동시킨다.
Stream.Position += Size
End If
'읽어들인 구휙을 리스트에 넣는다
Chunk.Add(Section)
End While
'읽어들인 Chunk를 반환
Return Chunk
End Function
''' <summary>파일에 Chunk를 작성하는 함수.</summary>
''' <param name="Chunk">작성할 Chunk 내용.</param>
''' <param name="FileName">Chunk를 작성할 파일 경로.</param>
Public Sub Chunk_WriteFile(Chunk As List(Of Section), FileName As String)
'쓰기 전용으로 파일 스트림을 연다. (이어서 작성하기를 원하면 Append를 사용해도 된다)
Dim FS As New FileStream(FileName, FileMode.Create, FileAccess.Write)
Chunk_WriteStream(Chunk, FS)
FS.Close() '사용한 파일 스트림을 닫음
End Sub
''' <summary>스트림에 Chunk를 작성하는 함수.</summary>
''' <param name="Chunk">작성할 Chunk 내용.</param>
''' <param name="Stream">Chunk를 작성할 스트림.</param>
Public Sub Chunk_WriteStream(Chunk As List(Of Section), Stream As Stream)
'스트림 작성에 관련된 함수가 있는 BinaryWriter를 생성한다.
Dim Writer As New BinaryWriter(Stream, Encoding.ASCII)
'각 섹션을 반복
For Each Section In Chunk
'스트림의 이름을 바이트 값으로 변환
Dim Name = Encoding.Default.GetBytes(Section.Name)
'스트림 이름이 4바이트가 아녈 경우를 위한 예외 처리
If Not Name.Length = 4 Then Array.Resize(Of Byte)(Name, 4)
'스트림에 구휙 이름을 작성
Writer.Write(Name)
'스트림에 구휙 크기를 작성 (스트림의 Length는 8바이트이므로 변환)
Writer.Write(CInt(Section.Data.Length))
'스트림에 구휙 내용을 작성
Section.Data.WriteTo(Stream)
Next
End Sub
End Module
댓글