blob: f27c531dc29b904f13422f1aca0992f145fff81d [file] [log] [blame]
/*
* Copyright 2013 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Author: Victor Chudnovsky
#ifndef PAGESPEED_KERNEL_IMAGE_SCANLINE_STATUS_H_
#define PAGESPEED_KERNEL_IMAGE_SCANLINE_STATUS_H_
#include <cstdarg>
#include "pagespeed/kernel/base/printf_format.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/base/string_util.h"
namespace pagespeed {
namespace image_compression {
#if defined(PAGESPEED_SCANLINE_STATUS) || \
defined(PAGESPEED_SCANLINE_STATUS_SOURCE) || \
defined(PAGESPEED_SCANLINE_STATUS_ENUM_NAME) || \
defined(PAGESPEED_SCANLINE_STATUS_ENUM_STRING)
#error "Preprocessor macro collision."
#endif
#define PAGESPEED_SCANLINE_STATUS(_X) \
_X(SCANLINE_STATUS_UNINITIALIZED), \
_X(SCANLINE_STATUS_SUCCESS), \
_X(SCANLINE_STATUS_UNSUPPORTED_FORMAT), \
_X(SCANLINE_STATUS_UNSUPPORTED_FEATURE), \
_X(SCANLINE_STATUS_PARSE_ERROR), \
_X(SCANLINE_STATUS_MEMORY_ERROR), \
_X(SCANLINE_STATUS_INTERNAL_ERROR), \
_X(SCANLINE_STATUS_TIMEOUT_ERROR), \
_X(SCANLINE_STATUS_INVOCATION_ERROR), \
\
_X(NUM_SCANLINE_STATUS)
// Note the source of the error message by means of an enum rather
// than a string.
#define PAGESPEED_SCANLINE_STATUS_SOURCE(_X) \
_X(SCANLINE_UNKNOWN), \
_X(SCANLINE_PNGREADER), \
_X(SCANLINE_PNGREADERRAW), \
_X(SCANLINE_GIFREADER), \
_X(SCANLINE_GIFREADERRAW), \
_X(SCANLINE_JPEGREADER), \
_X(SCANLINE_WEBPREADER), \
_X(SCANLINE_RESIZER), \
_X(SCANLINE_PNGWRITER), \
_X(SCANLINE_JPEGWRITER), \
_X(SCANLINE_WEBPWRITER), \
_X(SCANLINE_UTIL), \
_X(SCANLINE_PIXEL_FORMAT_OPTIMIZER), \
_X(FRAME_TO_SCANLINE_READER_ADAPTER), \
_X(FRAME_TO_SCANLINE_WRITER_ADAPTER), \
_X(SCANLINE_TO_FRAME_READER_ADAPTER), \
_X(SCANLINE_TO_FRAME_WRITER_ADAPTER), \
_X(FRAME_GIFREADER), \
_X(FRAME_WEBPWRITER), \
_X(FRAME_PADDING_READER), \
\
_X(NUM_SCANLINE_SOURCE)
#define PAGESPEED_SCANLINE_STATUS_ENUM_NAME(_Y) _Y
#define PAGESPEED_SCANLINE_STATUS_ENUM_STRING(_Y) #_Y
enum ScanlineStatusType {
PAGESPEED_SCANLINE_STATUS(PAGESPEED_SCANLINE_STATUS_ENUM_NAME)
};
enum ScanlineStatusSource {
PAGESPEED_SCANLINE_STATUS_SOURCE(PAGESPEED_SCANLINE_STATUS_ENUM_NAME)
};
// A class to report the success or error of ScanlineInterface
// operations. Scanline*Interface should return the
// ScanlineStatus corresponding to the earliest error
// encountered. ScanlineStatus.details_ should be of the form
// "FunctionThatFailed()" or "failure message".
class ScanlineStatus {
public:
ScanlineStatus() : type_(SCANLINE_STATUS_SUCCESS),
source_(SCANLINE_UNKNOWN),
details_() {}
ScanlineStatus(ScanlineStatusType type,
ScanlineStatusSource source,
const GoogleString& details)
: type_(type),
source_(source),
details_(details) {}
explicit ScanlineStatus(ScanlineStatusType type)
: type_(type),
source_(SCANLINE_UNKNOWN),
details_() {}
// This function takes variadic arguments so that we can use the
// same sets of arguments here and for logging via the
// PS_LOGGED_STATUS macro below.
static ScanlineStatus New(ScanlineStatusType type,
ScanlineStatusSource source,
const char* details,
...) INSTAWEB_PRINTF_FORMAT(3, 4) {
va_list args;
GoogleString detail_list;
// Ignore the name of this routine: it formats with vsnprintf.
// See base/stringprintf.cc.
va_start(args, details);
StringAppendV(&detail_list, details, args);
va_end(args);
return ScanlineStatus(type, source, detail_list);
};
bool Success() const { return (type_ == SCANLINE_STATUS_SUCCESS); }
ScanlineStatusType type() const { return type_; }
ScanlineStatusSource source() const { return source_; }
const GoogleString& details() const { return details_; }
const char* TypeStr() const {
static const char* const kScanlineStatusTypeNames[] = {
PAGESPEED_SCANLINE_STATUS(PAGESPEED_SCANLINE_STATUS_ENUM_STRING)
};
return kScanlineStatusTypeNames[type_];
}
const char* SourceStr() const {
static const char* const kScanlineStatusSourceNames[] = {
PAGESPEED_SCANLINE_STATUS_SOURCE(PAGESPEED_SCANLINE_STATUS_ENUM_STRING)
};
return kScanlineStatusSourceNames[source_];
}
const GoogleString ToString() const {
return GoogleString(SourceStr()) + "/" + TypeStr() + " " + details();
}
// Determines whether the source of this status is a reader of some
// sort.
bool ComesFromReader() const {
switch (source_) {
case SCANLINE_PNGREADER:
case SCANLINE_PNGREADERRAW:
case SCANLINE_GIFREADER:
case SCANLINE_GIFREADERRAW:
case SCANLINE_JPEGREADER:
case SCANLINE_WEBPREADER:
case FRAME_TO_SCANLINE_READER_ADAPTER:
case SCANLINE_TO_FRAME_READER_ADAPTER:
case FRAME_GIFREADER:
case FRAME_PADDING_READER:
return true;
default:
return false;
}
return false;
}
private:
ScanlineStatusType type_;
ScanlineStatusSource source_;
GoogleString details_;
// Note: we are allowing the implicit copy constructor and
// assignment operators.
};
#undef PAGESPEED_SCANLINE_STATUS_ENUM_STRING
#undef PAGESPEED_SCANLINE_STATUS_ENUM_NAME
#undef PAGESPEED_SCANLINE_STATUS_SOURCE
#undef PAGESPEED_SCANLINE_STATUS
// Convenience macro for simultaneously logging error descriptions and
// creating a ScanlineStatus with that error description. _LOGGER is
// meant to be one of the PS_LOG* macros defined in message_handler.h.
#define PS_LOGGED_STATUS(_LOGGER, _HANDLER, _TYPE, _SOURCE, ...) \
(_LOGGER(_HANDLER, #_SOURCE "/" #_TYPE " " __VA_ARGS__), \
ScanlineStatus::New(_TYPE, _SOURCE, __VA_ARGS__))
} // namespace image_compression
} // namespace pagespeed
#endif // PAGESPEED_KERNEL_IMAGE_SCANLINE_STATUS_H_