* Copyright 2006, 2023, Haiku. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
* Zardshard
*/
#include "MessageExporter.h"
#include <ByteOrder.h>
#include <DataIO.h>
#include <Message.h>
#include <TypeConstants.h>
#include "Container.h"
#include "Defines.h"
#include "Icon.h"
#include "PathSourceShape.h"
#include "ReferenceImage.h"
#include "Shape.h"
#include "Style.h"
#include "Transformer.h"
#include "VectorPath.h"
MessageExporter::MessageExporter()
{
}
MessageExporter::~MessageExporter()
{
}
status_t
MessageExporter::Export(const Icon* icon, BPositionIO* stream)
{
status_t ret = B_OK;
BMessage archive;
const Container<VectorPath>* paths = icon->Paths();
const Container<Style>* styles = icon->Styles();
if (ret == B_OK) {
BMessage allPaths;
int32 count = paths->CountItems();
for (int32 i = 0; i < count; i++) {
VectorPath* path = paths->ItemAtFast(i);
BMessage pathArchive;
ret = _Export(path, &pathArchive);
if (ret < B_OK)
break;
ret = allPaths.AddMessage("path", &pathArchive);
if (ret < B_OK)
break;
}
if (ret == B_OK)
ret = archive.AddMessage("paths", &allPaths);
}
if (ret == B_OK) {
BMessage allStyles;
int32 count = styles->CountItems();
for (int32 i = 0; i < count; i++) {
Style* style = styles->ItemAtFast(i);
BMessage styleArchive;
ret = _Export(style, &styleArchive);
if (ret < B_OK)
break;
ret = allStyles.AddMessage("style", &styleArchive);
if (ret < B_OK)
break;
}
if (ret == B_OK)
ret = archive.AddMessage("styles", &allStyles);
}
if (ret == B_OK) {
BMessage allShapes;
const Container<Shape>* shapes = icon->Shapes();
int32 count = shapes->CountItems();
for (int32 i = 0; i < count; i++) {
Shape* shape = shapes->ItemAtFast(i);
BMessage shapeArchive;
ret = _Export(shape, paths, styles, &shapeArchive);
if (ret < B_OK)
break;
ret = allShapes.AddMessage("shape", &shapeArchive);
if (ret < B_OK)
break;
}
if (ret == B_OK)
ret = archive.AddMessage("shapes", &allShapes);
}
if (ret == B_OK) {
ssize_t size = sizeof(uint32);
uint32 magic = B_HOST_TO_BENDIAN_INT32(kNativeIconMagicNumber);
ssize_t written = stream->Write(&magic, size);
if (written != size) {
if (written < 0)
ret = (status_t)written;
else
ret = B_IO_ERROR;
}
}
if (ret == B_OK)
ret = archive.Flatten(stream);
return ret;
}
const char*
MessageExporter::MIMEType()
{
return kNativeIconMimeType;
}
status_t
MessageExporter::_Export(const VectorPath* path, BMessage* into) const
{
return path->Archive(into, true);
}
status_t
MessageExporter::_Export(const Style* style, BMessage* into) const
{
return style->Archive(into, true);
}
status_t
MessageExporter::_Export(const Shape* shape,
const Container<VectorPath>* globalPaths,
const Container<Style>* globalStyles,
BMessage* into) const
{
status_t ret = B_OK;
const PathSourceShape* pathSourceShape = dynamic_cast<const PathSourceShape*>(shape);
if (pathSourceShape != NULL) {
ret = into->AddInt32("type", PathSourceShape::archive_code);
if (ret == B_OK) {
Style* style = pathSourceShape->Style();
ret = into->AddInt32("style ref", globalStyles->IndexOf(style));
}
if (ret == B_OK) {
int32 count = pathSourceShape->Paths()->CountItems();
for (int32 i = 0; i < count; i++) {
VectorPath* path = pathSourceShape->Paths()->ItemAtFast(i);
ret = into->AddInt32("path ref", globalPaths->IndexOf(path));
if (ret < B_OK)
break;
}
}
}
const ReferenceImage* referenceImage = dynamic_cast<const ReferenceImage*>(shape);
if (referenceImage != NULL) {
ret = into->AddInt32("type", ReferenceImage::archive_code);
}
if (ret == B_OK)
ret = shape->Archive(into);
return ret;
}