xref: /haiku/src/bin/package/command_dump.cpp (revision 5fb1c6ff1f55fe4094a761b653041b3a0b9abf1d)
1050aa61bSIngo Weinhold /*
2050aa61bSIngo Weinhold  * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3050aa61bSIngo Weinhold  * Distributed under the terms of the MIT License.
4050aa61bSIngo Weinhold  */
5050aa61bSIngo Weinhold 
6050aa61bSIngo Weinhold 
7050aa61bSIngo Weinhold #include <ctype.h>
8050aa61bSIngo Weinhold #include <errno.h>
9050aa61bSIngo Weinhold #include <getopt.h>
10050aa61bSIngo Weinhold #include <stdio.h>
11050aa61bSIngo Weinhold #include <stdlib.h>
12050aa61bSIngo Weinhold #include <string.h>
13050aa61bSIngo Weinhold 
14*5fb1c6ffSOliver Tappe #include <package/hpkg/HPKGDefs.h>
15*5fb1c6ffSOliver Tappe #include <package/hpkg/PackageAttributeValue.h>
16*5fb1c6ffSOliver Tappe #include <package/hpkg/PackageContentHandler.h>
170d6b3b20SOliver Tappe #include <package/hpkg/PackageEntry.h>
180d6b3b20SOliver Tappe #include <package/hpkg/PackageEntryAttribute.h>
190d6b3b20SOliver Tappe #include <package/hpkg/PackageReader.h>
200d6b3b20SOliver Tappe 
21050aa61bSIngo Weinhold #include "package.h"
226dccfe13SIngo Weinhold #include "StandardErrorOutput.h"
23050aa61bSIngo Weinhold 
24050aa61bSIngo Weinhold 
25*5fb1c6ffSOliver Tappe using namespace BPackageKit::BHPKG;
260d6b3b20SOliver Tappe 
270d6b3b20SOliver Tappe 
28*5fb1c6ffSOliver Tappe struct PackageContentDumpHandler : BLowLevelPackageContentHandler {
29050aa61bSIngo Weinhold 	PackageContentDumpHandler()
30050aa61bSIngo Weinhold 		:
31050aa61bSIngo Weinhold 		fLevel(0),
32050aa61bSIngo Weinhold 		fErrorOccurred(false),
33050aa61bSIngo Weinhold 		fHasChildren(false)
34050aa61bSIngo Weinhold 	{
35050aa61bSIngo Weinhold 	}
36050aa61bSIngo Weinhold 
37050aa61bSIngo Weinhold 	virtual status_t HandleAttribute(const char* attributeName,
38*5fb1c6ffSOliver Tappe 		const BPackageAttributeValue& value, void* parentToken, void*& _token)
39050aa61bSIngo Weinhold 	{
40050aa61bSIngo Weinhold 		if (fErrorOccurred)
41050aa61bSIngo Weinhold 			return B_OK;
42050aa61bSIngo Weinhold 
43050aa61bSIngo Weinhold 		printf("%*s>%s: ", fLevel * 2, "", attributeName);
44050aa61bSIngo Weinhold 		_PrintValue(value);
45050aa61bSIngo Weinhold 		printf("\n");
46050aa61bSIngo Weinhold 
47050aa61bSIngo Weinhold 		fHasChildren = false;
48050aa61bSIngo Weinhold 		fLevel++;
49050aa61bSIngo Weinhold 		return B_OK;
50050aa61bSIngo Weinhold 	}
51050aa61bSIngo Weinhold 
52050aa61bSIngo Weinhold 	virtual status_t HandleAttributeDone(const char* attributeName,
53*5fb1c6ffSOliver Tappe 		const BPackageAttributeValue& value, void* token)
54050aa61bSIngo Weinhold 	{
55050aa61bSIngo Weinhold 		if (fErrorOccurred)
56050aa61bSIngo Weinhold 			return B_OK;
57050aa61bSIngo Weinhold 
58050aa61bSIngo Weinhold 		fLevel--;
59050aa61bSIngo Weinhold 
60050aa61bSIngo Weinhold 		if (fHasChildren)
61050aa61bSIngo Weinhold 			printf("%*s<%s\n", fLevel * 2, "", attributeName);
62050aa61bSIngo Weinhold 
63050aa61bSIngo Weinhold 		fHasChildren = true;
64050aa61bSIngo Weinhold 		return B_OK;
65050aa61bSIngo Weinhold 	}
66050aa61bSIngo Weinhold 
67050aa61bSIngo Weinhold 	virtual void HandleErrorOccurred()
68050aa61bSIngo Weinhold 	{
69050aa61bSIngo Weinhold 		fErrorOccurred = true;
70050aa61bSIngo Weinhold 	}
71050aa61bSIngo Weinhold 
72050aa61bSIngo Weinhold private:
73*5fb1c6ffSOliver Tappe 	void _PrintValue(const BPackageAttributeValue& value)
74050aa61bSIngo Weinhold 	{
75050aa61bSIngo Weinhold 		switch (value.type) {
76050aa61bSIngo Weinhold 			case B_HPKG_ATTRIBUTE_TYPE_INT:
77050aa61bSIngo Weinhold 				printf("%lld (%#llx)", value.signedInt, value.signedInt);
78050aa61bSIngo Weinhold 				break;
79050aa61bSIngo Weinhold 			case B_HPKG_ATTRIBUTE_TYPE_UINT:
80050aa61bSIngo Weinhold 				printf("%llu (%#llx)", value.unsignedInt, value.unsignedInt);
81050aa61bSIngo Weinhold 				break;
82050aa61bSIngo Weinhold 			case B_HPKG_ATTRIBUTE_TYPE_STRING:
83050aa61bSIngo Weinhold 				printf("\"%s\"", value.string);
84050aa61bSIngo Weinhold 				break;
85050aa61bSIngo Weinhold 			case B_HPKG_ATTRIBUTE_TYPE_RAW:
86050aa61bSIngo Weinhold 				switch (value.encoding) {
87050aa61bSIngo Weinhold 					case B_HPKG_ATTRIBUTE_ENCODING_RAW_INLINE:
88050aa61bSIngo Weinhold 						printf("data: size: %llu, inline", value.data.size);
89050aa61bSIngo Weinhold 						// TODO: Print the data bytes!
90050aa61bSIngo Weinhold 						break;
91050aa61bSIngo Weinhold 					case B_HPKG_ATTRIBUTE_ENCODING_RAW_HEAP:
92050aa61bSIngo Weinhold 						printf("data: size: %llu, offset: %llu",
93050aa61bSIngo Weinhold 							value.data.size, value.data.offset);
94050aa61bSIngo Weinhold 						break;
95050aa61bSIngo Weinhold 					default:
96050aa61bSIngo Weinhold 						break;
97050aa61bSIngo Weinhold 				}
98050aa61bSIngo Weinhold 				break;
99050aa61bSIngo Weinhold 			default:
100050aa61bSIngo Weinhold 				printf("<unknown type %u>\n", value.type);
101050aa61bSIngo Weinhold 				break;
102050aa61bSIngo Weinhold 		}
103050aa61bSIngo Weinhold 	}
104050aa61bSIngo Weinhold 
105050aa61bSIngo Weinhold private:
106050aa61bSIngo Weinhold 	int		fLevel;
107050aa61bSIngo Weinhold 	bool	fErrorOccurred;
108050aa61bSIngo Weinhold 	bool	fHasChildren;
109050aa61bSIngo Weinhold };
110050aa61bSIngo Weinhold 
111050aa61bSIngo Weinhold 
112050aa61bSIngo Weinhold int
113050aa61bSIngo Weinhold command_dump(int argc, const char* const* argv)
114050aa61bSIngo Weinhold {
115050aa61bSIngo Weinhold 	while (true) {
116050aa61bSIngo Weinhold 		static struct option sLongOptions[] = {
117050aa61bSIngo Weinhold 			{ "help", no_argument, 0, 'h' },
118050aa61bSIngo Weinhold 			{ 0, 0, 0, 0 }
119050aa61bSIngo Weinhold 		};
120050aa61bSIngo Weinhold 
121050aa61bSIngo Weinhold 		opterr = 0; // don't print errors
122050aa61bSIngo Weinhold 		int c = getopt_long(argc, (char**)argv, "+h", sLongOptions, NULL);
123050aa61bSIngo Weinhold 		if (c == -1)
124050aa61bSIngo Weinhold 			break;
125050aa61bSIngo Weinhold 
126050aa61bSIngo Weinhold 		switch (c) {
127050aa61bSIngo Weinhold 			case 'h':
128050aa61bSIngo Weinhold 				print_usage_and_exit(false);
129050aa61bSIngo Weinhold 				break;
130050aa61bSIngo Weinhold 
131050aa61bSIngo Weinhold 			default:
132050aa61bSIngo Weinhold 				print_usage_and_exit(true);
133050aa61bSIngo Weinhold 				break;
134050aa61bSIngo Weinhold 		}
135050aa61bSIngo Weinhold 	}
136050aa61bSIngo Weinhold 
137050aa61bSIngo Weinhold 	// One argument should remain -- the package file name.
138050aa61bSIngo Weinhold 	if (optind + 1 != argc)
139050aa61bSIngo Weinhold 		print_usage_and_exit(true);
140050aa61bSIngo Weinhold 
141050aa61bSIngo Weinhold 	const char* packageFileName = argv[optind++];
142050aa61bSIngo Weinhold 
143050aa61bSIngo Weinhold 	// open package
1446dccfe13SIngo Weinhold 	StandardErrorOutput errorOutput;
145*5fb1c6ffSOliver Tappe 	BPackageReader packageReader(&errorOutput);
146050aa61bSIngo Weinhold 	status_t error = packageReader.Init(packageFileName);
147050aa61bSIngo Weinhold printf("Init(): %s\n", strerror(error));
148050aa61bSIngo Weinhold 	if (error != B_OK)
149050aa61bSIngo Weinhold 		return 1;
150050aa61bSIngo Weinhold 
151050aa61bSIngo Weinhold 	// list
152050aa61bSIngo Weinhold 	PackageContentDumpHandler handler;
153050aa61bSIngo Weinhold 	error = packageReader.ParseContent(&handler);
154050aa61bSIngo Weinhold printf("ParseContent(): %s\n", strerror(error));
155050aa61bSIngo Weinhold 	if (error != B_OK)
156050aa61bSIngo Weinhold 		return 1;
157050aa61bSIngo Weinhold 
158050aa61bSIngo Weinhold 	return 0;
159050aa61bSIngo Weinhold }
160