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