1 | /*
|
---|
2 | * Copyright 2018, Marcin Konicki <shard@neoni.net>
|
---|
3 | * All rights reserved. Distributed under the terms of the MIT license.
|
---|
4 | *
|
---|
5 | * Build it with: g++ -o testApp -lbe test-bmsg-previous-delete.cpp
|
---|
6 | *
|
---|
7 | * Run either:
|
---|
8 | * - testApp -i (safe)
|
---|
9 | * - testApp -d (crash)
|
---|
10 | * - testApp (usage info)
|
---|
11 | */
|
---|
12 | #include <Application.h>
|
---|
13 | #include <stdio.h>
|
---|
14 |
|
---|
15 | class TestApp : public BApplication
|
---|
16 | {
|
---|
17 | public:
|
---|
18 | TestApp();
|
---|
19 | ~TestApp();
|
---|
20 |
|
---|
21 | thread_id Run(bool deletePrevious = true);
|
---|
22 | void MessageReceived(BMessage* msg);
|
---|
23 | };
|
---|
24 |
|
---|
25 | TestApp::TestApp()
|
---|
26 | :
|
---|
27 | BApplication("application/x-vnd.Test.DeletePreiousMessage")
|
---|
28 | {
|
---|
29 | }
|
---|
30 |
|
---|
31 | TestApp::~TestApp()
|
---|
32 | {
|
---|
33 | }
|
---|
34 |
|
---|
35 | thread_id
|
---|
36 | TestApp::Run(bool deletePrevious)
|
---|
37 | {
|
---|
38 | BMessage request('test');
|
---|
39 | request.AddInt32("step", 1);
|
---|
40 | printf("\tTesting BMessage::Previous %s deleting returned message\n",
|
---|
41 | deletePrevious ? "WITH" : "WITHOUT");
|
---|
42 | request.AddBool("deletePrevious", deletePrevious);
|
---|
43 | printf("\tSending test message with need for a reply... ");
|
---|
44 | PostMessage(&request, this, this);
|
---|
45 | printf("done\n");
|
---|
46 | return BApplication::Run();
|
---|
47 | }
|
---|
48 |
|
---|
49 | void
|
---|
50 | TestApp::MessageReceived(BMessage* msg)
|
---|
51 | {
|
---|
52 | printf("\n\tReceived message\n");
|
---|
53 | msg->PrintToStream();
|
---|
54 | if (msg->what != 'test') {
|
---|
55 | printf("\tUnknown message, pass over to BApplication and return\n");
|
---|
56 | BApplication::MessageReceived(msg);
|
---|
57 | return;
|
---|
58 | }
|
---|
59 |
|
---|
60 | if (msg->GetInt32("step", 0) == 1) {
|
---|
61 | printf("\tGot request for a reply\n");
|
---|
62 | BMessage reply('test');
|
---|
63 | reply.AddInt32("step", 2);
|
---|
64 | printf("\tSend reply... ");
|
---|
65 | msg->SendReply(&reply);
|
---|
66 | printf("done\n");
|
---|
67 | printf("\tReturn\n");
|
---|
68 | return;
|
---|
69 | }
|
---|
70 |
|
---|
71 | if (msg->IsReply() && msg->GetInt32("step", 0) == 2) {
|
---|
72 | printf("\tGot reply\n");
|
---|
73 | const BMessage* previous = msg->Previous();
|
---|
74 | if (previous && previous->GetInt32("step", 0) == 1) {
|
---|
75 | printf("\tFound previous BMessage* with correct step number\n");
|
---|
76 | if (previous->GetBool("deletePrevious", true)) {
|
---|
77 | printf("\tDeleting previous as advised by documentation\n");
|
---|
78 | delete previous;
|
---|
79 | } else
|
---|
80 | printf(
|
---|
81 | "\tLeaving previous, hoping it will be deleted by API\n");
|
---|
82 |
|
---|
83 | printf("\tTest complete, posting B_QUIT_REQUESTED to quit... ");
|
---|
84 | PostMessage(B_QUIT_REQUESTED);
|
---|
85 | printf("done\n");
|
---|
86 | printf("\tReturn\n");
|
---|
87 | return;
|
---|
88 | }
|
---|
89 |
|
---|
90 | printf("\tPrevious not found or did not contain correct step number\n");
|
---|
91 | printf("\tReturn\n");
|
---|
92 | return;
|
---|
93 | }
|
---|
94 |
|
---|
95 | printf("\tHow did we get here? Anyway, pass message over to BApplication "
|
---|
96 | "and return\n");
|
---|
97 | BApplication::MessageReceived(msg);
|
---|
98 | }
|
---|
99 |
|
---|
100 | void
|
---|
101 | PrintUsage()
|
---|
102 | {
|
---|
103 | printf(
|
---|
104 | ""
|
---|
105 | "Usage: testApp [option]\n"
|
---|
106 | "Options:\n"
|
---|
107 | "\t-h print this usage info\n"
|
---|
108 | "\t-d delete BMessage returned from BMessage::Previous\n"
|
---|
109 | "\t-i ignore documentation and leave returned object to the API\n"
|
---|
110 | "\n"
|
---|
111 | "It runs test application which sends message to itself and then "
|
---|
112 | "replies to it.\n"
|
---|
113 | "After receiving reply, it gets result of BMessage->Previous() and, "
|
---|
114 | "depending \n"
|
---|
115 | "on option passed to it, deletes result or not.\n"
|
---|
116 | "Documentation mentions that result SHOULD be deleted by the caller:\n"
|
---|
117 | "https://www.haiku-os.org/docs/api/"
|
---|
118 | "classBMessage.html#a57c84d02e54ef19fd1516d9bf7e3fe45\n"
|
---|
119 | "But when we do that on Haiku, application crashes. That suggests "
|
---|
120 | "that, unlike\n"
|
---|
121 | "described in documentation, Haiku does not return a COPY of previous "
|
---|
122 | "message.\n"
|
---|
123 | "Instead it seems to return a pointer to ORIGINAL BMessage.\n");
|
---|
124 | }
|
---|
125 |
|
---|
126 | int
|
---|
127 | main(int argc, char** argv)
|
---|
128 | {
|
---|
129 | if (argc <= 1 || argv[1][0] != '-' || argv[1][1] == 'h') {
|
---|
130 | PrintUsage();
|
---|
131 | return B_NO_ERROR;
|
---|
132 | }
|
---|
133 |
|
---|
134 | bool deletePrevious = argv[1][1] == 'd';
|
---|
135 |
|
---|
136 | printf("Creating TestApp... ");
|
---|
137 | TestApp* app = new TestApp();
|
---|
138 | printf("done\n");
|
---|
139 | printf("Calling TestApp->Run()\n");
|
---|
140 | app->Run(deletePrevious);
|
---|
141 | printf("... done.\nDeleting TestApp... ");
|
---|
142 | delete app;
|
---|
143 | printf("done.\nBye bye!\n");
|
---|
144 |
|
---|
145 | return B_NO_ERROR;
|
---|
146 | }
|
---|