1 /*
2    Drawpile - a collaborative drawing program.
3 
4    Copyright (C) 2015-2019 Calle Laakkonen
5 
6    Drawpile is free software: you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation, either version 3 of the License, or
9    (at your option) any later version.
10 
11    Drawpile is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with Drawpile.  If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #include "opaque.h"
21 
22 #include "annotation.h"
23 #include "image.h"
24 #include "layer.h"
25 #include "meta2.h"
26 #include "brushes.h"
27 #include "undo.h"
28 #include "recording.h"
29 
30 #include <cstring>
31 
32 namespace protocol {
33 
OpaqueMessage(MessageType type,uint8_t ctx,const uchar * payload,int payloadLen)34 OpaqueMessage::OpaqueMessage(MessageType type, uint8_t ctx, const uchar *payload, int payloadLen)
35 	: Message(type, ctx), m_length(payloadLen)
36 {
37 	Q_ASSERT(type >= 64);
38 	if(payloadLen>0) {
39 		m_payload = new uchar[payloadLen];
40 		memcpy(m_payload, payload, payloadLen);
41 	} else {
42 		m_payload = nullptr;
43 	}
44 }
45 
~OpaqueMessage()46 OpaqueMessage::~OpaqueMessage()
47 {
48 	delete []m_payload;
49 }
50 
decode(MessageType type,uint8_t ctx,const uchar * data,uint len)51 NullableMessageRef OpaqueMessage::decode(MessageType type, uint8_t ctx, const uchar *data, uint len)
52 {
53 	Q_ASSERT(type>=64);
54 
55 	Message *msg = nullptr;
56 
57 	switch(type) {
58 	case MSG_INTERVAL: msg = Interval::deserialize(ctx, data, len); break;
59 	case MSG_LASERTRAIL: msg = LaserTrail::deserialize(ctx, data, len); break;
60 	case MSG_MOVEPOINTER: msg = MovePointer::deserialize(ctx, data, len); break;
61 	case MSG_MARKER: msg = Marker::deserialize(ctx, data, len); break;
62 	case MSG_USER_ACL: msg = UserACL::deserialize(ctx, data, len); break;
63 	case MSG_LAYER_ACL: msg = LayerACL::deserialize(ctx, data, len); break;
64 	case MSG_FEATURE_LEVELS: msg = FeatureAccessLevels::deserialize(ctx, data, len); break;
65 	case MSG_LAYER_DEFAULT: msg = DefaultLayer::deserialize(ctx, data, len); break;
66 	case MSG_FILTERED: return Filtered::deserialize(ctx, data, len);
67 
68 	case MSG_CANVAS_RESIZE: msg = CanvasResize::deserialize(ctx, data, len); break;
69 	case MSG_LAYER_CREATE: msg = LayerCreate::deserialize(ctx, data, len); break;
70 	case MSG_LAYER_ATTR: msg = LayerAttributes::deserialize(ctx, data, len); break;
71 	case MSG_LAYER_RETITLE: msg = LayerRetitle::deserialize(ctx, data, len); break;
72 	case MSG_LAYER_ORDER: msg = LayerOrder::deserialize(ctx, data, len); break;
73 	case MSG_LAYER_DELETE: msg = LayerDelete::deserialize(ctx, data, len); break;
74 	case MSG_LAYER_VISIBILITY: msg = LayerVisibility::deserialize(ctx, data, len); break;
75 	case MSG_PUTIMAGE: msg = PutImage::deserialize(ctx, data, len); break;
76 	case MSG_PEN_UP: msg = PenUp::deserialize(ctx, data, len); break;
77 	case MSG_ANNOTATION_CREATE: msg = AnnotationCreate::deserialize(ctx, data, len); break;
78 	case MSG_ANNOTATION_RESHAPE: msg = AnnotationReshape::deserialize(ctx, data, len); break;
79 	case MSG_ANNOTATION_EDIT: msg = AnnotationEdit::deserialize(ctx, data, len); break;
80 	case MSG_ANNOTATION_DELETE: msg = AnnotationDelete::deserialize(ctx, data, len); break;
81 	case MSG_UNDOPOINT: msg = UndoPoint::deserialize(ctx, data, len); break;
82 	case MSG_UNDO: msg = Undo::deserialize(ctx, data, len); break;
83 	case MSG_FILLRECT: msg = FillRect::deserialize(ctx, data, len); break;
84 	case MSG_REGION_MOVE: msg = MoveRegion::deserialize(ctx, data, len); break;
85 	case MSG_PUTTILE: msg = PutTile::deserialize(ctx, data, len); break;
86 	case MSG_CANVAS_BACKGROUND: msg = CanvasBackground::deserialize(ctx, data, len); break;
87 	case MSG_DRAWDABS_CLASSIC: msg = DrawDabsClassic::deserialize(ctx, data, len); break;
88 	case MSG_DRAWDABS_PIXEL: msg = DrawDabsPixel::deserialize(DabShape::Round, ctx, data, len); break;
89 	case MSG_DRAWDABS_PIXEL_SQUARE: msg = DrawDabsPixel::deserialize(DabShape::Square, ctx, data, len); break;
90 	default: qWarning("Unhandled opaque message type: %d", type);
91 	}
92 
93 	return NullableMessageRef(msg);
94 }
95 
decode() const96 NullableMessageRef OpaqueMessage::decode() const
97 {
98 	return decode(type(), contextId(), m_payload, m_length);
99 }
100 
payloadLength() const101 int OpaqueMessage::payloadLength() const
102 {
103 	return m_length;
104 }
105 
serializePayload(uchar * data) const106 int OpaqueMessage::serializePayload(uchar *data) const
107 {
108 	memcpy(data, m_payload, m_length);
109 	return m_length;
110 }
111 
payloadEquals(const Message & m) const112 bool OpaqueMessage::payloadEquals(const Message &m) const
113 {
114 	const OpaqueMessage &om = static_cast<const OpaqueMessage&>(m);
115 	if(m_length != om.m_length)
116 		return false;
117 
118 	return memcmp(m_payload, om.m_payload, m_length) == 0;
119 }
120 
121 }
122 
123