xref: /haiku/src/bin/package/command_dump.cpp (revision 0d6b3b20e15fe2cbeb5e81749f888c26ca289338)
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*0d6b3b20SOliver Tappe #include <package/hpkg/PackageEntry.h>
15*0d6b3b20SOliver Tappe #include <package/hpkg/PackageEntryAttribute.h>
16*0d6b3b20SOliver Tappe #include <package/hpkg/PackageReader.h>
17*0d6b3b20SOliver Tappe 
18050aa61bSIngo Weinhold #include "package.h"
196dccfe13SIngo Weinhold #include "StandardErrorOutput.h"
20050aa61bSIngo Weinhold 
21050aa61bSIngo Weinhold 
22*0d6b3b20SOliver Tappe using namespace BPackageKit::BHaikuPackage::BPrivate;
23*0d6b3b20SOliver Tappe 
24*0d6b3b20SOliver Tappe 
25050aa61bSIngo Weinhold struct PackageContentDumpHandler : LowLevelPackageContentHandler {
26050aa61bSIngo Weinhold 	PackageContentDumpHandler()
27050aa61bSIngo Weinhold 		:
28050aa61bSIngo Weinhold 		fLevel(0),
29050aa61bSIngo Weinhold 		fErrorOccurred(false),
30050aa61bSIngo Weinhold 		fHasChildren(false)
31050aa61bSIngo Weinhold 	{
32050aa61bSIngo Weinhold 	}
33050aa61bSIngo Weinhold 
34050aa61bSIngo Weinhold 	virtual status_t HandleAttribute(const char* attributeName,
35050aa61bSIngo Weinhold 		const PackageAttributeValue& value, void* parentToken, void*& _token)
36050aa61bSIngo Weinhold 	{
37050aa61bSIngo Weinhold 		if (fErrorOccurred)
38050aa61bSIngo Weinhold 			return B_OK;
39050aa61bSIngo Weinhold 
40050aa61bSIngo Weinhold 		printf("%*s>%s: ", fLevel * 2, "", attributeName);
41050aa61bSIngo Weinhold 		_PrintValue(value);
42050aa61bSIngo Weinhold 		printf("\n");
43050aa61bSIngo Weinhold 
44050aa61bSIngo Weinhold 		fHasChildren = false;
45050aa61bSIngo Weinhold 		fLevel++;
46050aa61bSIngo Weinhold 		return B_OK;
47050aa61bSIngo Weinhold 	}
48050aa61bSIngo Weinhold 
49050aa61bSIngo Weinhold 	virtual status_t HandleAttributeDone(const char* attributeName,
50050aa61bSIngo Weinhold 		const PackageAttributeValue& value, void* token)
51050aa61bSIngo Weinhold 	{
52050aa61bSIngo Weinhold 		if (fErrorOccurred)
53050aa61bSIngo Weinhold 			return B_OK;
54050aa61bSIngo Weinhold 
55050aa61bSIngo Weinhold 		fLevel--;
56050aa61bSIngo Weinhold 
57050aa61bSIngo Weinhold 		if (fHasChildren)
58050aa61bSIngo Weinhold 			printf("%*s<%s\n", fLevel * 2, "", attributeName);
59050aa61bSIngo Weinhold 
60050aa61bSIngo Weinhold 		fHasChildren = true;
61050aa61bSIngo Weinhold 		return B_OK;
62050aa61bSIngo Weinhold 	}
63050aa61bSIngo Weinhold 
64050aa61bSIngo Weinhold 	virtual void HandleErrorOccurred()
65050aa61bSIngo Weinhold 	{
66050aa61bSIngo Weinhold 		fErrorOccurred = true;
67050aa61bSIngo Weinhold 	}
68050aa61bSIngo Weinhold 
69050aa61bSIngo Weinhold private:
70050aa61bSIngo Weinhold 	void _PrintValue(const PackageAttributeValue& value)
71050aa61bSIngo Weinhold 	{
72050aa61bSIngo Weinhold 		switch (value.type) {
73050aa61bSIngo Weinhold 			case B_HPKG_ATTRIBUTE_TYPE_INT:
74050aa61bSIngo Weinhold 				printf("%lld (%#llx)", value.signedInt, value.signedInt);
75050aa61bSIngo Weinhold 				break;
76050aa61bSIngo Weinhold 			case B_HPKG_ATTRIBUTE_TYPE_UINT:
77050aa61bSIngo Weinhold 				printf("%llu (%#llx)", value.unsignedInt, value.unsignedInt);
78050aa61bSIngo Weinhold 				break;
79050aa61bSIngo Weinhold 			case B_HPKG_ATTRIBUTE_TYPE_STRING:
80050aa61bSIngo Weinhold 				printf("\"%s\"", value.string);
81050aa61bSIngo Weinhold 				break;
82050aa61bSIngo Weinhold 			case B_HPKG_ATTRIBUTE_TYPE_RAW:
83050aa61bSIngo Weinhold 				switch (value.encoding) {
84050aa61bSIngo Weinhold 					case B_HPKG_ATTRIBUTE_ENCODING_RAW_INLINE:
85050aa61bSIngo Weinhold 						printf("data: size: %llu, inline", value.data.size);
86050aa61bSIngo Weinhold 						// TODO: Print the data bytes!
87050aa61bSIngo Weinhold 						break;
88050aa61bSIngo Weinhold 					case B_HPKG_ATTRIBUTE_ENCODING_RAW_HEAP:
89050aa61bSIngo Weinhold 						printf("data: size: %llu, offset: %llu",
90050aa61bSIngo Weinhold 							value.data.size, value.data.offset);
91050aa61bSIngo Weinhold 						break;
92050aa61bSIngo Weinhold 					default:
93050aa61bSIngo Weinhold 						break;
94050aa61bSIngo Weinhold 				}
95050aa61bSIngo Weinhold 				break;
96050aa61bSIngo Weinhold 			default:
97050aa61bSIngo Weinhold 				printf("<unknown type %u>\n", value.type);
98050aa61bSIngo Weinhold 				break;
99050aa61bSIngo Weinhold 		}
100050aa61bSIngo Weinhold 	}
101050aa61bSIngo Weinhold 
102050aa61bSIngo Weinhold private:
103050aa61bSIngo Weinhold 	int		fLevel;
104050aa61bSIngo Weinhold 	bool	fErrorOccurred;
105050aa61bSIngo Weinhold 	bool	fHasChildren;
106050aa61bSIngo Weinhold };
107050aa61bSIngo Weinhold 
108050aa61bSIngo Weinhold 
109050aa61bSIngo Weinhold int
110050aa61bSIngo Weinhold command_dump(int argc, const char* const* argv)
111050aa61bSIngo Weinhold {
112050aa61bSIngo Weinhold 	while (true) {
113050aa61bSIngo Weinhold 		static struct option sLongOptions[] = {
114050aa61bSIngo Weinhold 			{ "help", no_argument, 0, 'h' },
115050aa61bSIngo Weinhold 			{ 0, 0, 0, 0 }
116050aa61bSIngo Weinhold 		};
117050aa61bSIngo Weinhold 
118050aa61bSIngo Weinhold 		opterr = 0; // don't print errors
119050aa61bSIngo Weinhold 		int c = getopt_long(argc, (char**)argv, "+h", sLongOptions, NULL);
120050aa61bSIngo Weinhold 		if (c == -1)
121050aa61bSIngo Weinhold 			break;
122050aa61bSIngo Weinhold 
123050aa61bSIngo Weinhold 		switch (c) {
124050aa61bSIngo Weinhold 			case 'h':
125050aa61bSIngo Weinhold 				print_usage_and_exit(false);
126050aa61bSIngo Weinhold 				break;
127050aa61bSIngo Weinhold 
128050aa61bSIngo Weinhold 			default:
129050aa61bSIngo Weinhold 				print_usage_and_exit(true);
130050aa61bSIngo Weinhold 				break;
131050aa61bSIngo Weinhold 		}
132050aa61bSIngo Weinhold 	}
133050aa61bSIngo Weinhold 
134050aa61bSIngo Weinhold 	// One argument should remain -- the package file name.
135050aa61bSIngo Weinhold 	if (optind + 1 != argc)
136050aa61bSIngo Weinhold 		print_usage_and_exit(true);
137050aa61bSIngo Weinhold 
138050aa61bSIngo Weinhold 	const char* packageFileName = argv[optind++];
139050aa61bSIngo Weinhold 
140050aa61bSIngo Weinhold 	// open package
1416dccfe13SIngo Weinhold 	StandardErrorOutput errorOutput;
1426dccfe13SIngo Weinhold 	PackageReader packageReader(&errorOutput);
143050aa61bSIngo Weinhold 	status_t error = packageReader.Init(packageFileName);
144050aa61bSIngo Weinhold printf("Init(): %s\n", strerror(error));
145050aa61bSIngo Weinhold 	if (error != B_OK)
146050aa61bSIngo Weinhold 		return 1;
147050aa61bSIngo Weinhold 
148050aa61bSIngo Weinhold 	// list
149050aa61bSIngo Weinhold 	PackageContentDumpHandler handler;
150050aa61bSIngo Weinhold 	error = packageReader.ParseContent(&handler);
151050aa61bSIngo Weinhold printf("ParseContent(): %s\n", strerror(error));
152050aa61bSIngo Weinhold 	if (error != B_OK)
153050aa61bSIngo Weinhold 		return 1;
154050aa61bSIngo Weinhold 
155050aa61bSIngo Weinhold 	return 0;
156050aa61bSIngo Weinhold }
157