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