HaikuDepot: notify work status from main window
[haiku.git] / src / libs / icon / message / MessageImporter.cpp
blobbcf782122ec57f2e1603b80d34a3b5f854c9c5f9
1 /*
2 * Copyright 2006-2010, Haiku. All rights reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Stephan Aßmus <superstippi@gmx.de>
7 */
10 #include "MessageImporter.h"
12 #include <new>
13 #include <stdio.h>
15 #include <Archivable.h>
16 #include <ByteOrder.h>
17 #include <DataIO.h>
18 #include <Message.h>
20 #include "Defines.h"
21 #include "Icon.h"
22 #include "PathContainer.h"
23 #include "Shape.h"
24 #include "Style.h"
25 #include "StyleContainer.h"
26 #include "VectorPath.h"
29 using std::nothrow;
32 MessageImporter::MessageImporter()
33 #ifdef ICON_O_MATIC
34 : Importer()
35 #endif
40 MessageImporter::~MessageImporter()
45 status_t
46 MessageImporter::Import(Icon* icon, BPositionIO* stream)
48 #ifdef ICON_O_MATIC
49 status_t ret = Init(icon);
50 if (ret < B_OK) {
51 printf("MessageImporter::Import() - "
52 "Init() error: %s\n", strerror(ret));
53 return ret;
55 #else
56 status_t ret;
57 #endif
59 uint32 magic = 0;
60 ssize_t size = sizeof(magic);
61 off_t position = stream->Position();
62 ssize_t read = stream->Read(&magic, size);
63 if (read != size) {
64 if (read < 0)
65 ret = (status_t)read;
66 else
67 ret = B_IO_ERROR;
68 return ret;
71 if (B_BENDIAN_TO_HOST_INT32(magic) != kNativeIconMagicNumber) {
72 // this might be an old native icon file, where
73 // we didn't prepend the magic number yet, seek back
74 if (stream->Seek(position, SEEK_SET) != position) {
75 printf("MessageImporter::Import() - "
76 "failed to seek back to beginning of stream\n");
77 return B_IO_ERROR;
81 BMessage archive;
82 ret = archive.Unflatten(stream);
83 if (ret != B_OK)
84 return ret;
86 // paths
87 PathContainer* paths = icon->Paths();
88 ret = _ImportPaths(&archive, paths);
89 if (ret < B_OK) {
90 printf("MessageImporter::Import() - "
91 "error importing paths: %s\n", strerror(ret));
92 return ret;
95 // styles
96 StyleContainer* styles = icon->Styles();
97 ret = _ImportStyles(&archive, styles);
98 if (ret < B_OK) {
99 printf("MessageImporter::Import() - "
100 "error importing styles: %s\n", strerror(ret));
101 return ret;
104 // shapes
105 ret = _ImportShapes(&archive, paths, styles, icon->Shapes());
106 if (ret < B_OK) {
107 printf("MessageImporter::Import() - "
108 "error importing shapes: %s\n", strerror(ret));
109 return ret;
112 return B_OK;
116 // #pragma mark -
119 status_t
120 MessageImporter::_ImportPaths(const BMessage* archive,
121 PathContainer* paths) const
123 BMessage allPaths;
124 status_t ret = archive->FindMessage("paths", &allPaths);
125 if (ret < B_OK)
126 return ret;
128 BMessage pathArchive;
129 for (int32 i = 0;
130 allPaths.FindMessage("path", i, &pathArchive) == B_OK; i++) {
131 VectorPath* path = new (nothrow) VectorPath(&pathArchive);
132 if (!path || !paths->AddPath(path)) {
133 delete path;
134 ret = B_NO_MEMORY;
136 if (ret < B_OK)
137 break;
140 return ret;
144 status_t
145 MessageImporter::_ImportStyles(const BMessage* archive,
146 StyleContainer* styles) const
148 BMessage allStyles;
149 status_t ret = archive->FindMessage("styles", &allStyles);
150 if (ret < B_OK)
151 return ret;
153 BMessage styleArchive;
154 for (int32 i = 0;
155 allStyles.FindMessage("style", i, &styleArchive) == B_OK; i++) {
156 Style* style = new (nothrow) Style(&styleArchive);
157 if (!style || !styles->AddStyle(style)) {
158 delete style;
159 ret = B_NO_MEMORY;
161 if (ret < B_OK)
162 break;
165 return ret;
169 status_t
170 MessageImporter::_ImportShapes(const BMessage* archive, PathContainer* paths,
171 StyleContainer* styles, ShapeContainer* shapes) const
173 BMessage allShapes;
174 status_t ret = archive->FindMessage("shapes", &allShapes);
175 if (ret < B_OK)
176 return ret;
178 BMessage shapeArchive;
179 for (int32 i = 0;
180 allShapes.FindMessage("shape", i, &shapeArchive) == B_OK; i++) {
181 // find the right style
182 int32 styleIndex;
183 if (shapeArchive.FindInt32("style ref", &styleIndex) < B_OK) {
184 printf("MessageImporter::_ImportShapes() - "
185 "Shape %" B_PRId32 " doesn't reference a Style!", i);
186 continue;
188 #ifdef ICON_O_MATIC
189 Style* style = styles->StyleAt(StyleIndexFor(styleIndex));
190 #else
191 Style* style = styles->StyleAt(styleIndex);
192 #endif
193 if (!style) {
194 printf("MessageImporter::_ImportShapes() - "
195 "Shape %" B_PRId32 " wants Style %" B_PRId32 ", which does not exist\n",
196 i, styleIndex);
197 continue;
200 // create shape
201 Shape* shape = new (nothrow) Shape(style);
202 if (!shape || shape->InitCheck() < B_OK || !shapes->AddShape(shape)) {
203 delete shape;
204 ret = B_NO_MEMORY;
206 if (ret < B_OK)
207 break;
209 // find the referenced paths
210 int32 pathIndex;
211 for (int32 j = 0;
212 shapeArchive.FindInt32("path ref", j, &pathIndex) == B_OK;
213 j++) {
214 #ifdef ICON_O_MATIC
215 VectorPath* path = paths->PathAt(PathIndexFor(pathIndex));
216 #else
217 VectorPath* path = paths->PathAt(pathIndex);
218 #endif
219 if (!path) {
220 printf("MessageImporter::_ImportShapes() - "
221 "Shape %" B_PRId32 " referenced path %" B_PRId32 ", "
222 "which does not exist\n", i, pathIndex);
223 continue;
225 shape->Paths()->AddPath(path);
228 // Shape properties
229 if (ret == B_OK)
230 shape->Unarchive(&shapeArchive);
233 return ret;