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