f0d95841ee
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27811 a95241bf-73f2-0310-859d-f6bbb57e9c96
262 lines
6.9 KiB
C++
262 lines
6.9 KiB
C++
/*
|
|
* Copyright 2000-2008, François Revol, <revol@free.fr>. All rights reserved.
|
|
* Distributed under the terms of the MIT License.
|
|
*/
|
|
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <ctype.h>
|
|
#include <Font.h>
|
|
#include <Message.h>
|
|
#include <String.h>
|
|
|
|
#include "DumpMessage.h"
|
|
#include "Utils.h"
|
|
|
|
//#define WHAT_ALWAYS_HEX 1
|
|
|
|
const char *msg_header_comment = "// new BMessage\n"; // avoids mime to think it's a .bmp ("BM")
|
|
|
|
status_t HexDumpToStream(const void *data, size_t len, BDataIO &stream, const char *prefix = NULL)
|
|
{
|
|
const unsigned char *p = (unsigned char *)data;
|
|
char buffer[100];
|
|
size_t i, j;
|
|
for (i=0; i<len; i+=16) {
|
|
if (prefix) stream.Write(prefix, strlen(prefix));
|
|
sprintf(buffer, "0x%06lx: ", i);
|
|
stream.Write(buffer, strlen(buffer));
|
|
for (j=0; j<16; j++) {
|
|
if (i+j < len)
|
|
sprintf(buffer, "%02x", p[i+j]);
|
|
else
|
|
sprintf(buffer, " ");
|
|
if (j % 4 == 3)
|
|
sprintf(buffer+strlen(buffer), " ");
|
|
stream.Write(buffer, strlen(buffer));
|
|
}
|
|
sprintf(buffer, " '");
|
|
stream.Write(buffer, strlen(buffer));
|
|
for (j=0; j<16; j++) {
|
|
if (i+j >= len)
|
|
sprintf(buffer, " ");
|
|
//else if (p[i+j] < 255 && p[i+j] >= 0x20)
|
|
else if (isalpha(p[i+j]))
|
|
sprintf(buffer, "%c", p[i+j]);
|
|
else
|
|
sprintf(buffer, ".");
|
|
stream.Write(buffer, 1);
|
|
}
|
|
sprintf(buffer, "'\n");
|
|
stream.Write(buffer, strlen(buffer));
|
|
}
|
|
return B_OK;
|
|
}
|
|
|
|
/* look up human readable names from an other BMessage */
|
|
bool LookUpFieldName(const char **name, const char *field_name, BMessage *names)
|
|
{
|
|
if (names == NULL)
|
|
return false;
|
|
if (names->FindString(field_name, name) == B_OK)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
status_t DumpMessageToStream(BMessage *message, BDataIO &stream, int tabCount, BMessage *names)
|
|
{
|
|
int32 field, index;
|
|
char *field_name;
|
|
type_code field_code;
|
|
int32 field_count;
|
|
char buffer[80];
|
|
char tabs[20];
|
|
const char *easy_name;
|
|
|
|
if (message == NULL)
|
|
return EINVAL;
|
|
|
|
if (tabCount < 1)
|
|
stream.Write(msg_header_comment, strlen(msg_header_comment));
|
|
|
|
memset(tabs, '\t', (++tabCount) + 1);
|
|
tabs[tabCount+1] = '\0';
|
|
//tabCount;
|
|
|
|
#ifndef WHAT_ALWAYS_HEX
|
|
if ( isalnum(message->what & 0x0ff) &&
|
|
isalnum((message->what >> 8) & 0x0ff) &&
|
|
isalnum((message->what >> 16) & 0x0ff) &&
|
|
isalnum((message->what >> 24) & 0x0ff))
|
|
sprintf(buffer, "BMessage('%c%c%c%c') {\n",
|
|
(char)(message->what >> 24) & 0x0ff,
|
|
(char)(message->what >> 16) & 0x0ff,
|
|
(char)(message->what >> 8) & 0x0ff,
|
|
(char)message->what & 0x0ff);
|
|
else
|
|
#endif
|
|
sprintf(buffer, "BMessage(0x%08lx) {\n", message->what);
|
|
// stream.Write(tabs+2, tabCount-2);
|
|
stream.Write(buffer, strlen(buffer));
|
|
|
|
for (field = 0; message->GetInfo(B_ANY_TYPE, field,
|
|
GET_INFO_NAME_PTR(&field_name),
|
|
&field_code,
|
|
&field_count) == B_OK; field++) {
|
|
if (LookUpFieldName(&easy_name, field_name, names)) {
|
|
stream.Write(tabs+1, tabCount);
|
|
stream.Write("// ", 3);
|
|
stream.Write(easy_name, strlen(easy_name));
|
|
stream.Write("\n", 1);
|
|
}
|
|
|
|
for (index=0; index < field_count; index++) {
|
|
stream.Write(tabs+1, tabCount);
|
|
stream.Write(field_name, strlen(field_name));
|
|
if (field_count > 1) {
|
|
sprintf(buffer, "[%ld]", index);
|
|
stream.Write(buffer, strlen(buffer));
|
|
}
|
|
stream.Write(" = ", 3);
|
|
|
|
switch (field_code) {
|
|
case 'MSGG':
|
|
{
|
|
BMessage m;
|
|
if (message->FindMessage(field_name, index, &m) >= B_OK)
|
|
DumpMessageToStream(&m, stream, tabCount, names);
|
|
}
|
|
break;
|
|
case B_RGB_COLOR_TYPE:
|
|
{
|
|
rgb_color c;
|
|
if (FindRGBColor(*message, field_name, index, &c) >= B_OK) {
|
|
sprintf(buffer, "rgb_color(%d,%d,%d,%d)",
|
|
c.red, c.green, c.blue, c.alpha);
|
|
stream.Write(buffer, strlen(buffer));
|
|
}
|
|
stream.Write("\n", 1);
|
|
}
|
|
break;
|
|
case 'FONt':
|
|
{
|
|
BFont f;
|
|
if (FindFont(*message, field_name, index, &f) >= B_OK) {
|
|
#ifdef B_BEOS_VERSION_DANO
|
|
stream << f;
|
|
#else
|
|
font_family family;
|
|
font_style style;
|
|
font_height height;
|
|
f.GetFamilyAndStyle(&family, &style);
|
|
f.GetHeight(&height);
|
|
BString s;
|
|
s << "BFont(" << family;
|
|
s << "/" << style << "/" << f.Size();
|
|
s << ", shear=" << f.Shear();
|
|
s << ", rot=" << f.Rotation();
|
|
s << ", height=" << height.ascent;
|
|
s << "+" << height.descent;
|
|
s << "+" << height.leading << ")";
|
|
stream.Write(s.String(), s.Length());
|
|
#endif
|
|
}
|
|
stream.Write("\n", 1);
|
|
}
|
|
break;
|
|
case B_BOOL_TYPE:
|
|
{
|
|
bool value;
|
|
if (message->FindBool(field_name, index, &value) >= B_OK) {
|
|
sprintf(buffer, "bool(%s)", value?"true":"false");
|
|
stream.Write(buffer, strlen(buffer));
|
|
}
|
|
stream.Write("\n", 1);
|
|
}
|
|
break;
|
|
case B_INT32_TYPE:
|
|
{
|
|
int32 value;
|
|
if (message->FindInt32(field_name, index, &value) >= B_OK) {
|
|
#if 1
|
|
if (value == 0)
|
|
sprintf(buffer, "int32(0 or (nil))");
|
|
else
|
|
#endif
|
|
// sprintf(buffer, "int32(%d)", value);
|
|
sprintf(buffer, "int32(%ld or 0x%lx)", value, value);
|
|
stream.Write(buffer, strlen(buffer));
|
|
}
|
|
stream.Write("\n", 1);
|
|
}
|
|
break;
|
|
case B_FLOAT_TYPE:
|
|
{
|
|
float value;
|
|
if (message->FindFloat(field_name, index, &value) >= B_OK) {
|
|
sprintf(buffer, "float(%f)", value);
|
|
stream.Write(buffer, strlen(buffer));
|
|
}
|
|
stream.Write("\n", 1);
|
|
}
|
|
break;
|
|
case B_STRING_TYPE:
|
|
{
|
|
const char *value;
|
|
if (message->FindString(field_name, index, &value) >= B_OK) {
|
|
BString str(value);
|
|
str.CharacterEscape("\\\"\n", '\\');
|
|
//sprintf(buffer, "string(\"%s\", %ld bytes)", str.String(), strlen(value));
|
|
// DO NOT use buffer!
|
|
str.Prepend("string(\"");
|
|
str << "\", " << strlen(value) << " bytes)";
|
|
stream.Write(str.String(), strlen(str.String()));
|
|
}
|
|
stream.Write("\n", 1);
|
|
}
|
|
break;
|
|
case B_POINT_TYPE:
|
|
{
|
|
BPoint value;
|
|
if (message->FindPoint(field_name, index, &value) >= B_OK) {
|
|
sprintf(buffer, "BPoint(%1.1f, %1.1f)", value.x, value.y);
|
|
stream.Write(buffer, strlen(buffer));
|
|
}
|
|
stream.Write("\n", 1);
|
|
}
|
|
break;
|
|
default:
|
|
{
|
|
const void *data;
|
|
ssize_t numBytes = 0;
|
|
if (message->FindData(field_name, field_code, index, &data, &numBytes) != B_OK) {
|
|
//stream.Write("\n", 1);
|
|
break;
|
|
}
|
|
|
|
if ( isalnum(field_code & 0x0ff) &&
|
|
isalnum((field_code >> 8) & 0x0ff) &&
|
|
isalnum((field_code >> 16) & 0x0ff) &&
|
|
isalnum((field_code >> 24) & 0x0ff))
|
|
sprintf(buffer, "'%c%c%c%c' %ld bytes:\n",
|
|
(char)(field_code >> 24) & 0x0ff,
|
|
(char)(field_code >> 16) & 0x0ff,
|
|
(char)(field_code >> 8) & 0x0ff,
|
|
(char)field_code & 0x0ff,
|
|
numBytes);
|
|
else
|
|
sprintf(buffer, "0x%08lx %ld bytes:\n", field_code, numBytes);
|
|
stream.Write(buffer, strlen(buffer));
|
|
stream.Write("\n", 1);
|
|
HexDumpToStream(data, numBytes, stream, tabs);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
stream.Write(tabs+2, tabCount-1);
|
|
stream.Write("}\n", 2);
|
|
return B_OK;
|
|
}
|
|
|