command_dump.cpp revision 050aa61b
1/*
2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7#include "package.h"
8
9#include <ctype.h>
10#include <errno.h>
11#include <getopt.h>
12#include <stdio.h>
13#include <stdlib.h>
14#include <string.h>
15
16#include "package.h"
17#include "PackageEntry.h"
18#include "PackageEntryAttribute.h"
19#include "PackageReader.h"
20
21
22struct PackageContentDumpHandler : LowLevelPackageContentHandler {
23	PackageContentDumpHandler()
24		:
25		fLevel(0),
26		fErrorOccurred(false),
27		fHasChildren(false)
28	{
29	}
30
31	virtual status_t HandleAttribute(const char* attributeName,
32		const PackageAttributeValue& value, void* parentToken, void*& _token)
33	{
34		if (fErrorOccurred)
35			return B_OK;
36
37		printf("%*s>%s: ", fLevel * 2, "", attributeName);
38		_PrintValue(value);
39		printf("\n");
40
41		fHasChildren = false;
42		fLevel++;
43		return B_OK;
44	}
45
46	virtual status_t HandleAttributeDone(const char* attributeName,
47		const PackageAttributeValue& value, void* token)
48	{
49		if (fErrorOccurred)
50			return B_OK;
51
52		fLevel--;
53
54		if (fHasChildren)
55			printf("%*s<%s\n", fLevel * 2, "", attributeName);
56
57		fHasChildren = true;
58		return B_OK;
59	}
60
61	virtual void HandleErrorOccurred()
62	{
63		fErrorOccurred = true;
64	}
65
66private:
67	void _PrintValue(const PackageAttributeValue& value)
68	{
69		switch (value.type) {
70			case B_HPKG_ATTRIBUTE_TYPE_INT:
71				printf("%lld (%#llx)", value.signedInt, value.signedInt);
72				break;
73			case B_HPKG_ATTRIBUTE_TYPE_UINT:
74				printf("%llu (%#llx)", value.unsignedInt, value.unsignedInt);
75				break;
76			case B_HPKG_ATTRIBUTE_TYPE_STRING:
77				printf("\"%s\"", value.string);
78				break;
79			case B_HPKG_ATTRIBUTE_TYPE_RAW:
80				switch (value.encoding) {
81					case B_HPKG_ATTRIBUTE_ENCODING_RAW_INLINE:
82						printf("data: size: %llu, inline", value.data.size);
83						// TODO: Print the data bytes!
84						break;
85					case B_HPKG_ATTRIBUTE_ENCODING_RAW_HEAP:
86						printf("data: size: %llu, offset: %llu",
87							value.data.size, value.data.offset);
88						break;
89					default:
90						break;
91				}
92				break;
93			default:
94				printf("<unknown type %u>\n", value.type);
95				break;
96		}
97	}
98
99private:
100	int		fLevel;
101	bool	fErrorOccurred;
102	bool	fHasChildren;
103};
104
105
106int
107command_dump(int argc, const char* const* argv)
108{
109	while (true) {
110		static struct option sLongOptions[] = {
111			{ "help", no_argument, 0, 'h' },
112			{ 0, 0, 0, 0 }
113		};
114
115		opterr = 0; // don't print errors
116		int c = getopt_long(argc, (char**)argv, "+h", sLongOptions, NULL);
117		if (c == -1)
118			break;
119
120		switch (c) {
121			case 'h':
122				print_usage_and_exit(false);
123				break;
124
125			default:
126				print_usage_and_exit(true);
127				break;
128		}
129	}
130
131	// One argument should remain -- the package file name.
132	if (optind + 1 != argc)
133		print_usage_and_exit(true);
134
135	const char* packageFileName = argv[optind++];
136
137	// open package
138	PackageReader packageReader;
139	status_t error = packageReader.Init(packageFileName);
140printf("Init(): %s\n", strerror(error));
141	if (error != B_OK)
142		return 1;
143
144	// list
145	PackageContentDumpHandler handler;
146	error = packageReader.ParseContent(&handler);
147printf("ParseContent(): %s\n", strerror(error));
148	if (error != B_OK)
149		return 1;
150
151	return 0;
152}
153