投稿者 tel | 2012年7月28日

ファイルをアーカイブ化する – その2

ファイルをアーカイブ化する

やっぱりファイル名でアーカイブから検索したくなったので。

  • 読み込んだらすぐに使える(セットアップとか余分なメモリとか確保しない)
  • ディレクトリ構造は持たない
  • ファイル名を固定長で保持する
  • アラインメントを指定できる

最後のアラインメントの指定は各ファイルデータの先頭にパディングを持たせる。ハードウェアによってはアクセスできるアラインメントが決まっていたり、指定のアラインメントだとアクセスが速くなったりするので重要。

inline int CmpStr(const char *a, const char *b) {
	return std::strcmp(a, b);
}

inline int CmpStr(const wchar_t *a, const wchar_t *b) {
	return std::wcscmp(a, b);
}

template <typename CharT>
struct ArchiveHeader {

	struct File {
		static const int FileNameLength = 32;
		unsigned int offset;
		unsigned int size;
		const CharT name[FileNameLength];
	};

	char signature[4];
	unsigned int fileCount;
	File files[1];

	unsigned int GetFileCount() const {
		return fileCount;
	}

	void *GetFile(int index) {
		if(index < fileCount && index >= 0) {
			return reinterpret_cast(reinterpret_cast(this) + files[index].offset);
		}
		return NULL;
	}

	void *GetFile(const CharT *fileName) {
		return GetFile(IndexOf(fileName));
	}

	size_t GetFileSize(int index) const {
		if(index >= fileCount || index < 0) {
 			return 0;
 		}
 		return files[index].size;
 	}
 	size_t GetFileSize(const CharT *fileName) const {
 		return GetFileSize(IndexOf(fileName));
 	}
 	const CharT *GetFileName(int index) {
 		return files[index].name;
 	}
 	bool ExistFile(const CharT *fileName) const {
 		return IndexOf(fileName) >= 0;
	}

	int IndexOf(const CharT *fileName) const {
		int t = 0;
		int b = fileCount - 1;
		int m = (t + b) / 2;

		while(t <= b) {
			m = (t + b) / 2;
			int cmp = CmpStr(files[m].name, fileName);
			if(cmp == 0) {
				return m;
			} else if(cmp < 0) {
				t = m + 1;
			} else {
				b = m - 1;
			}
		}
		return -1;
	}
};

前回のものと違って個々のファイルサイズを保持するようにした。これはパディングによってオフセットからサイズが求められなくなるため。
アクセスにワイド文字を使う場合もあるのでテンプレートで文字の型を指定した。
いちおうファイル名の一覧はソートされている前提で、検索時にはバイナリサーチをしている。

ファイル名でアクセスできるようになったのはいいが、固定長でファイル名を保持してしまったので容量がムダになってしまった。パディングとファイル名を同一の領域にしておけばもうちょっと容量が削減できるかも。(検索がめんどくさくなりそうだが)


Responses

  1. […] ファイルをアーカイブ化する – その2 […]

  2. […] ファイルをアーカイブ化する – その2 […]


コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

カテゴリー

%d人のブロガーが「いいね」をつけました。