<commit_before>/*
  MIT License

  Copyright (c) 2018-2019 HolyWu

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files (the "Software"), to deal
  in the Software without restriction, including without limitation the rights
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the Software is
  furnished to do so, subject to the following conditions:

  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  SOFTWARE.
*/

#include <cmath>
#include <string>

#include <VapourSynth.h>
#include <VSHelper.h>

#include <w2xconv.h>

struct Waifu2xData {
    VSNodeRef * node;
    VSVideoInfo vi;
    int noise, scale, block;
    int iterTimesTwiceScaling;
    float * srcInterleaved, * dstInterleaved;
    W2XConv * conv;
};

static bool isPowerOf2(const int i) noexcept {
    return i && !(i & (i - 1));
}

static bool filter(const VSFrameRef * src, VSFrameRef * dst, Waifu2xData * const VS_RESTRICT d, const VSAPI * vsapi) noexcept {
    const int width = vsapi->getFrameWidth(src, 0);
    const int height = vsapi->getFrameHeight(src, 0);
    const int srcStride = vsapi->getStride(src, 0) / sizeof(float);
    const int dstStride = vsapi->getStride(dst, 0) / sizeof(float);
    const float * srcpR = reinterpret_cast<const float *>(vsapi->getReadPtr(src, 0));
    const float * srcpG = reinterpret_cast<const float *>(vsapi->getReadPtr(src, 1));
    const float * srcpB = reinterpret_cast<const float *>(vsapi->getReadPtr(src, 2));
    float * VS_RESTRICT dstpR = reinterpret_cast<float *>(vsapi->getWritePtr(dst, 0));
    float * VS_RESTRICT dstpG = reinterpret_cast<float *>(vsapi->getWritePtr(dst, 1));
    float * VS_RESTRICT dstpB = reinterpret_cast<float *>(vsapi->getWritePtr(dst, 2));

    for (int y = 0; y < height; y++) {
        for (int x = 0; x < width; x++) {
            const int pos = (width * y + x) * 3;
            d->srcInterleaved[pos + 0] = srcpR[x];
            d->srcInterleaved[pos + 1] = srcpG[x];
            d->srcInterleaved[pos + 2] = srcpB[x];
        }

        srcpR += srcStride;
        srcpG += srcStride;
        srcpB += srcStride;
    }

    if (w2xconv_convert_rgb_f32(d->conv,
                                reinterpret_cast<unsigned char *>(d->dstInterleaved),
                                d->vi.width * 3 * sizeof(float),
                                reinterpret_cast<unsigned char *>(d->srcInterleaved),
                                width * 3 * sizeof(float),
                                width, height, d->noise, d->scale, d->block) < 0)
        return false;

    for (int y = 0; y < d->vi.height; y++) {
        for (int x = 0; x < d->vi.width; x++) {
            const int pos = (d->vi.width * y + x) * 3;
            dstpR[x] = d->dstInterleaved[pos + 0];
            dstpG[x] = d->dstInterleaved[pos + 1];
            dstpB[x] = d->dstInterleaved[pos + 2];
        }

        dstpR += dstStride;
        dstpG += dstStride;
        dstpB += dstStride;
    }

    return true;
}

static void VS_CC waifu2xInit(VSMap *in, VSMap *out, void **instanceData, VSNode *node, VSCore *core, const VSAPI *vsapi) {
    Waifu2xData * d = static_cast<Waifu2xData *>(*instanceData);
    vsapi->setVideoInfo(&d->vi, 1, node);
}

static const VSFrameRef *VS_CC waifu2xGetFrame(int n, int activationReason, void **instanceData, void **frameData, VSFrameContext *frameCtx, VSCore *core, const VSAPI *vsapi) {
    Waifu2xData * d = static_cast<Waifu2xData *>(*instanceData);

    if (activationReason == arInitial) {
        vsapi->requestFrameFilter(n, d->node, frameCtx);
    } else if (activationReason == arAllFramesReady) {
        const VSFrameRef * src = vsapi->getFrameFilter(n, d->node, frameCtx);
        VSFrameRef * dst = vsapi->newVideoFrame(d->vi.format, d->vi.width, d->vi.height, src, core);

        if (!filter(src, dst, d, vsapi)) {
            char * error = w2xconv_strerror(&d->conv->last_error);
            vsapi->setFilterError((std::string{ "Waifu2x-w2xc: " } + error).c_str(), frameCtx);
            w2xconv_free(error);
            vsapi->freeFrame(src);
            vsapi->freeFrame(dst);
            return nullptr;
        }

        vsapi->freeFrame(src);
        return dst;
    }

    return nullptr;
}

static void VS_CC waifu2xFree(void *instanceData, VSCore *core, const VSAPI *vsapi) {
    Waifu2xData * d = static_cast<Waifu2xData *>(instanceData);

    vsapi->freeNode(d->node);

    delete[] d->srcInterleaved;
    delete[] d->dstInterleaved;

    w2xconv_fini(d->conv);

    delete d;
}

static void VS_CC waifu2xCreate(const VSMap *in, VSMap *out, void *userData, VSCore *core, const VSAPI *vsapi) {
    Waifu2xData d{};
    int err;

    d.node = vsapi->propGetNode(in, "clip", 0, nullptr);
    d.vi = *vsapi->getVideoInfo(d.node);

    try {
        if (!isConstantFormat(&d.vi) || d.vi.format->colorFamily != cmRGB || d.vi.format->sampleType != stFloat || d.vi.format->bitsPerSample != 32)
            throw std::string{ "only constant RGB format and 32 bit float input supported" };

        d.noise = int64ToIntS(vsapi->propGetInt(in, "noise", 0, &err));

        d.scale = int64ToIntS(vsapi->propGetInt(in, "scale", 0, &err));
        if (err)
            d.scale = 2;

        d.block = int64ToIntS(vsapi->propGetInt(in, "block", 0, &err));
        if (err)
            d.block = 512;

        const bool photo = !!vsapi->propGetInt(in, "photo", 0, &err);

        W2XConvGPUMode gpu = static_cast<W2XConvGPUMode>(int64ToIntS(vsapi->propGetInt(in, "gpu", 0, &err)));
        if (err)
            gpu = W2XCONV_GPU_AUTO;

        int processor = int64ToIntS(vsapi->propGetInt(in, "processor", 0, &err));
        if (err)
            processor = -1;

        const bool log = !!vsapi->propGetInt(in, "log", 0, &err);

        size_t numProcessors;
        const W2XConvProcessor * processors = w2xconv_get_processor_list(&numProcessors);

        if (d.noise < -1 || d.noise > 3)
            throw std::string{ "noise must be -1, 0, 1, 2, or 3" };

        if (d.scale < 1 || !isPowerOf2(d.scale))
            throw std::string{ "scale must be greater than or equal to 1 and be a power of 2" };

        if (d.block < 1)
            throw std::string{ "block must be greater than or equal to 1" };

        if (gpu < 0 || gpu > 2)
            throw std::string{ "gpu must be 0, 1, or 2" };

        if (processor >= static_cast<int>(numProcessors))
            throw std::string{ "the specified processor is not available" };

        if (!!vsapi->propGetInt(in, "list_proc", 0, &err)) {
            std::string text;

            for (size_t i = 0; i < numProcessors; i++) {
                const W2XConvProcessor * p = &processors[i];
                const char * type;

                switch (p->type) {
                case W2XCONV_PROC_HOST:
                    switch (p->sub_type) {
                    case W2XCONV_PROC_HOST_FMA:
                        type = "FMA";
                        break;
                    case W2XCONV_PROC_HOST_AVX:
                        type = "AVX";
                        break;
                    case W2XCONV_PROC_HOST_SSE3:
                        type = "SSE3";
                        break;
                    default:
                        type = "OpenCV";
                    }
                    break;

                case W2XCONV_PROC_CUDA:
                    type = "CUDA";
                    break;

                case W2XCONV_PROC_OPENCL:
                    type = "OpenCL";
                    break;

                default:
                    type = "unknown";
                }

                text += std::to_string(i) + ": " + p->dev_name + " (" + type + ")\n";
            }

            VSMap * args = vsapi->createMap();
            vsapi->propSetNode(args, "clip", d.node, paReplace);
            vsapi->freeNode(d.node);
            vsapi->propSetData(args, "text", text.c_str(), -1, paReplace);

            VSMap * ret = vsapi->invoke(vsapi->getPluginById("com.vapoursynth.text", core), "Text", args);
            if (vsapi->getError(ret)) {
                vsapi->setError(out, vsapi->getError(ret));
                vsapi->freeMap(args);
                vsapi->freeMap(ret);
                return;
            }

            d.node = vsapi->propGetNode(ret, "clip", 0, nullptr);
            vsapi->freeMap(args);
            vsapi->freeMap(ret);
            vsapi->propSetNode(out, "clip", d.node, paReplace);
            vsapi->freeNode(d.node);
            return;
        }

        if (d.noise == -1 && d.scale == 1) {
            vsapi->propSetNode(out, "clip", d.node, paReplace);
            vsapi->freeNode(d.node);
            return;
        }

        if (d.scale != 1) {
            d.vi.width *= d.scale;
            d.vi.height *= d.scale;
            d.iterTimesTwiceScaling = static_cast<int>(std::log2(d.scale));
        }

        d.srcInterleaved = new (std::nothrow) float[vsapi->getVideoInfo(d.node)->width * vsapi->getVideoInfo(d.node)->height * 3];
        d.dstInterleaved = new (std::nothrow) float[d.vi.width * d.vi.height * 3];
        if (!d.srcInterleaved || !d.dstInterleaved)
            throw std::string{ "malloc failure (srcInterleaved/dstInterleaved)" };

        const int numThreads = vsapi->getCoreInfo(core)->numThreads;
        if (processor > -1)
            d.conv = w2xconv_init_with_processor(processor, numThreads, log);
        else
            d.conv = w2xconv_init(gpu, numThreads, log);

        const std::string pluginPath{ vsapi->getPluginPath(vsapi->getPluginById("com.holywu.waifu2x-w2xc", core)) };
        std::string modelPath{ pluginPath.substr(0, pluginPath.find_last_of('/')) };
        if (photo)
            modelPath += "/models/photo";
        else
            modelPath += "/models/anime_style_art_rgb";

        if (w2xconv_load_models(d.conv, modelPath.c_str()) < 0) {
            char * error = w2xconv_strerror(&d.conv->last_error);
            vsapi->setError(out, (std::string{ "Waifu2x-w2xc: " } + error).c_str());
            w2xconv_free(error);
            vsapi->freeNode(d.node);
            w2xconv_fini(d.conv);
            return;
        }
    } catch (const std::string & error) {
        vsapi->setError(out, ("Waifu2x-w2xc: " + error).c_str());
        vsapi->freeNode(d.node);
        return;
    }

    Waifu2xData * data = new Waifu2xData{ d };

    vsapi->createFilter(in, out, "Waifu2x-w2xc", waifu2xInit, waifu2xGetFrame, waifu2xFree, fmParallelRequests, 0, data, core);
}

//////////////////////////////////////////
// Init

VS_EXTERNAL_API(void) VapourSynthPluginInit(VSConfigPlugin configFunc, VSRegisterFunction registerFunc, VSPlugin *plugin) {
    configFunc("com.holywu.waifu2x-w2xc", "w2xc", "Image Super-Resolution using Deep Convolutional Neural Networks", VAPOURSYNTH_API_VERSION, 1, plugin);
    registerFunc("Waifu2x",
                 "clip:clip;"
                 "noise:int:opt;"
                 "scale:int:opt;"
                 "block:int:opt;"
                 "photo:int:opt;"
                 "gpu:int:opt;"
                 "processor:int:opt;"
                 "list_proc:int:opt;"
                 "log:int:opt;",
                 waifu2xCreate, nullptr, plugin);
}
<commit_msg>Define HAVE_OPENCV before including w2xconv.h<commit_after>/*
  MIT License

  Copyright (c) 2018-2019 HolyWu

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files (the "Software"), to deal
  in the Software without restriction, including without limitation the rights
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the Software is
  furnished to do so, subject to the following conditions:

  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  SOFTWARE.
*/

#include <cmath>
#include <string>

#include <VapourSynth.h>
#include <VSHelper.h>

#define HAVE_OPENCV
#include <w2xconv.h>

struct Waifu2xData {
    VSNodeRef * node;
    VSVideoInfo vi;
    int noise, scale, block;
    int iterTimesTwiceScaling;
    float * srcInterleaved, * dstInterleaved;
    W2XConv * conv;
};

static bool isPowerOf2(const int i) noexcept {
    return i && !(i & (i - 1));
}

static bool filter(const VSFrameRef * src, VSFrameRef * dst, Waifu2xData * const VS_RESTRICT d, const VSAPI * vsapi) noexcept {
    const int width = vsapi->getFrameWidth(src, 0);
    const int height = vsapi->getFrameHeight(src, 0);
    const int srcStride = vsapi->getStride(src, 0) / sizeof(float);
    const int dstStride = vsapi->getStride(dst, 0) / sizeof(float);
    const float * srcpR = reinterpret_cast<const float *>(vsapi->getReadPtr(src, 0));
    const float * srcpG = reinterpret_cast<const float *>(vsapi->getReadPtr(src, 1));
    const float * srcpB = reinterpret_cast<const float *>(vsapi->getReadPtr(src, 2));
    float * VS_RESTRICT dstpR = reinterpret_cast<float *>(vsapi->getWritePtr(dst, 0));
    float * VS_RESTRICT dstpG = reinterpret_cast<float *>(vsapi->getWritePtr(dst, 1));
    float * VS_RESTRICT dstpB = reinterpret_cast<float *>(vsapi->getWritePtr(dst, 2));

    for (int y = 0; y < height; y++) {
        for (int x = 0; x < width; x++) {
            const int pos = (width * y + x) * 3;
            d->srcInterleaved[pos + 0] = srcpR[x];
            d->srcInterleaved[pos + 1] = srcpG[x];
            d->srcInterleaved[pos + 2] = srcpB[x];
        }

        srcpR += srcStride;
        srcpG += srcStride;
        srcpB += srcStride;
    }

    if (w2xconv_convert_rgb_f32(d->conv,
                                reinterpret_cast<unsigned char *>(d->dstInterleaved),
                                d->vi.width * 3 * sizeof(float),
                                reinterpret_cast<unsigned char *>(d->srcInterleaved),
                                width * 3 * sizeof(float),
                                width, height, d->noise, d->scale, d->block) < 0)
        return false;

    for (int y = 0; y < d->vi.height; y++) {
        for (int x = 0; x < d->vi.width; x++) {
            const int pos = (d->vi.width * y + x) * 3;
            dstpR[x] = d->dstInterleaved[pos + 0];
            dstpG[x] = d->dstInterleaved[pos + 1];
            dstpB[x] = d->dstInterleaved[pos + 2];
        }

        dstpR += dstStride;
        dstpG += dstStride;
        dstpB += dstStride;
    }

    return true;
}

static void VS_CC waifu2xInit(VSMap *in, VSMap *out, void **instanceData, VSNode *node, VSCore *core, const VSAPI *vsapi) {
    Waifu2xData * d = static_cast<Waifu2xData *>(*instanceData);
    vsapi->setVideoInfo(&d->vi, 1, node);
}

static const VSFrameRef *VS_CC waifu2xGetFrame(int n, int activationReason, void **instanceData, void **frameData, VSFrameContext *frameCtx, VSCore *core, const VSAPI *vsapi) {
    Waifu2xData * d = static_cast<Waifu2xData *>(*instanceData);

    if (activationReason == arInitial) {
        vsapi->requestFrameFilter(n, d->node, frameCtx);
    } else if (activationReason == arAllFramesReady) {
        const VSFrameRef * src = vsapi->getFrameFilter(n, d->node, frameCtx);
        VSFrameRef * dst = vsapi->newVideoFrame(d->vi.format, d->vi.width, d->vi.height, src, core);

        if (!filter(src, dst, d, vsapi)) {
            char * error = w2xconv_strerror(&d->conv->last_error);
            vsapi->setFilterError((std::string{ "Waifu2x-w2xc: " } + error).c_str(), frameCtx);
            w2xconv_free(error);
            vsapi->freeFrame(src);
            vsapi->freeFrame(dst);
            return nullptr;
        }

        vsapi->freeFrame(src);
        return dst;
    }

    return nullptr;
}

static void VS_CC waifu2xFree(void *instanceData, VSCore *core, const VSAPI *vsapi) {
    Waifu2xData * d = static_cast<Waifu2xData *>(instanceData);

    vsapi->freeNode(d->node);

    delete[] d->srcInterleaved;
    delete[] d->dstInterleaved;

    w2xconv_fini(d->conv);

    delete d;
}

static void VS_CC waifu2xCreate(const VSMap *in, VSMap *out, void *userData, VSCore *core, const VSAPI *vsapi) {
    Waifu2xData d{};
    int err;

    d.node = vsapi->propGetNode(in, "clip", 0, nullptr);
    d.vi = *vsapi->getVideoInfo(d.node);

    try {
        if (!isConstantFormat(&d.vi) || d.vi.format->colorFamily != cmRGB || d.vi.format->sampleType != stFloat || d.vi.format->bitsPerSample != 32)
            throw std::string{ "only constant RGB format and 32 bit float input supported" };

        d.noise = int64ToIntS(vsapi->propGetInt(in, "noise", 0, &err));

        d.scale = int64ToIntS(vsapi->propGetInt(in, "scale", 0, &err));
        if (err)
            d.scale = 2;

        d.block = int64ToIntS(vsapi->propGetInt(in, "block", 0, &err));
        if (err)
            d.block = 512;

        const bool photo = !!vsapi->propGetInt(in, "photo", 0, &err);

        W2XConvGPUMode gpu = static_cast<W2XConvGPUMode>(int64ToIntS(vsapi->propGetInt(in, "gpu", 0, &err)));
        if (err)
            gpu = W2XCONV_GPU_AUTO;

        int processor = int64ToIntS(vsapi->propGetInt(in, "processor", 0, &err));
        if (err)
            processor = -1;

        const bool log = !!vsapi->propGetInt(in, "log", 0, &err);

        size_t numProcessors;
        const W2XConvProcessor * processors = w2xconv_get_processor_list(&numProcessors);

        if (d.noise < -1 || d.noise > 3)
            throw std::string{ "noise must be -1, 0, 1, 2, or 3" };

        if (d.scale < 1 || !isPowerOf2(d.scale))
            throw std::string{ "scale must be greater than or equal to 1 and be a power of 2" };

        if (d.block < 1)
            throw std::string{ "block must be greater than or equal to 1" };

        if (gpu < 0 || gpu > 2)
            throw std::string{ "gpu must be 0, 1, or 2" };

        if (processor >= static_cast<int>(numProcessors))
            throw std::string{ "the specified processor is not available" };

        if (!!vsapi->propGetInt(in, "list_proc", 0, &err)) {
            std::string text;

            for (size_t i = 0; i < numProcessors; i++) {
                const W2XConvProcessor * p = &processors[i];
                const char * type;

                switch (p->type) {
                case W2XCONV_PROC_HOST:
                    switch (p->sub_type) {
                    case W2XCONV_PROC_HOST_FMA:
                        type = "FMA";
                        break;
                    case W2XCONV_PROC_HOST_AVX:
                        type = "AVX";
                        break;
                    case W2XCONV_PROC_HOST_SSE3:
                        type = "SSE3";
                        break;
                    default:
                        type = "OpenCV";
                    }
                    break;

                case W2XCONV_PROC_CUDA:
                    type = "CUDA";
                    break;

                case W2XCONV_PROC_OPENCL:
                    type = "OpenCL";
                    break;

                default:
                    type = "unknown";
                }

                text += std::to_string(i) + ": " + p->dev_name + " (" + type + ")\n";
            }

            VSMap * args = vsapi->createMap();
            vsapi->propSetNode(args, "clip", d.node, paReplace);
            vsapi->freeNode(d.node);
            vsapi->propSetData(args, "text", text.c_str(), -1, paReplace);

            VSMap * ret = vsapi->invoke(vsapi->getPluginById("com.vapoursynth.text", core), "Text", args);
            if (vsapi->getError(ret)) {
                vsapi->setError(out, vsapi->getError(ret));
                vsapi->freeMap(args);
                vsapi->freeMap(ret);
                return;
            }

            d.node = vsapi->propGetNode(ret, "clip", 0, nullptr);
            vsapi->freeMap(args);
            vsapi->freeMap(ret);
            vsapi->propSetNode(out, "clip", d.node, paReplace);
            vsapi->freeNode(d.node);
            return;
        }

        if (d.noise == -1 && d.scale == 1) {
            vsapi->propSetNode(out, "clip", d.node, paReplace);
            vsapi->freeNode(d.node);
            return;
        }

        if (d.scale != 1) {
            d.vi.width *= d.scale;
            d.vi.height *= d.scale;
            d.iterTimesTwiceScaling = static_cast<int>(std::log2(d.scale));
        }

        d.srcInterleaved = new (std::nothrow) float[vsapi->getVideoInfo(d.node)->width * vsapi->getVideoInfo(d.node)->height * 3];
        d.dstInterleaved = new (std::nothrow) float[d.vi.width * d.vi.height * 3];
        if (!d.srcInterleaved || !d.dstInterleaved)
            throw std::string{ "malloc failure (srcInterleaved/dstInterleaved)" };

        const int numThreads = vsapi->getCoreInfo(core)->numThreads;
        if (processor > -1)
            d.conv = w2xconv_init_with_processor(processor, numThreads, log);
        else
            d.conv = w2xconv_init(gpu, numThreads, log);

        const std::string pluginPath{ vsapi->getPluginPath(vsapi->getPluginById("com.holywu.waifu2x-w2xc", core)) };
        std::string modelPath{ pluginPath.substr(0, pluginPath.find_last_of('/')) };
        if (photo)
            modelPath += "/models/photo";
        else
            modelPath += "/models/anime_style_art_rgb";

        if (w2xconv_load_models(d.conv, modelPath.c_str()) < 0) {
            char * error = w2xconv_strerror(&d.conv->last_error);
            vsapi->setError(out, (std::string{ "Waifu2x-w2xc: " } + error).c_str());
            w2xconv_free(error);
            vsapi->freeNode(d.node);
            w2xconv_fini(d.conv);
            return;
        }
    } catch (const std::string & error) {
        vsapi->setError(out, ("Waifu2x-w2xc: " + error).c_str());
        vsapi->freeNode(d.node);
        return;
    }

    Waifu2xData * data = new Waifu2xData{ d };

    vsapi->createFilter(in, out, "Waifu2x-w2xc", waifu2xInit, waifu2xGetFrame, waifu2xFree, fmParallelRequests, 0, data, core);
}

//////////////////////////////////////////
// Init

VS_EXTERNAL_API(void) VapourSynthPluginInit(VSConfigPlugin configFunc, VSRegisterFunction registerFunc, VSPlugin *plugin) {
    configFunc("com.holywu.waifu2x-w2xc", "w2xc", "Image Super-Resolution using Deep Convolutional Neural Networks", VAPOURSYNTH_API_VERSION, 1, plugin);
    registerFunc("Waifu2x",
                 "clip:clip;"
                 "noise:int:opt;"
                 "scale:int:opt;"
                 "block:int:opt;"
                 "photo:int:opt;"
                 "gpu:int:opt;"
                 "processor:int:opt;"
                 "list_proc:int:opt;"
                 "log:int:opt;",
                 waifu2xCreate, nullptr, plugin);
}
<|endoftext|>


<commit_before>/*********************************************************************************
* Copyright (c) 2013 David D. Marshall <ddmarsha@calpoly.edu>
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*    David D. Marshall - initial code and implementation
********************************************************************************/

#ifndef eli_mutil_nls_iterative_root_system_method_hpp
#define eli_mutil_nls_iterative_root_system_method_hpp

#ifdef Success  // X11 #define collides with Eigen
#undef Success
#endif

#include "Eigen/Eigen"

#include "eli/mutil/nls/iterative_root_base.hpp"

namespace eli
{
  namespace mutil
  {
    namespace nls
    {
      template<typename data__, size_t N__, size_t NSOL__>
      class iterative_system_root_base : public iterative_root_base<data__>
      {
        public:
          typedef Eigen::Matrix<data__, N__, NSOL__> solution_matrix;
          typedef Eigen::Matrix<data__, N__, N__>    jacobian_matrix;

          enum system_norm_type
          {
            L1=100,            // for vectors this is sum of maxes, for matrices this is maximum absolute column sum
            L2=200,            // for vectors this is sqrt of sum of squares, for matrices this will be equivalent to the Frobenius norm
            Linf=300,          // for vectors this is the largest (in magnitude) terms, for matrices this is maximum abolute row sum
            max_norm=400,      // for vectors this is equivalent to Linf, for matrices it is the largest element in matrix
            Frobenius_norm=500 // for vectors this is L2, for matrices this is the sqrt of sum of squares of each term
          };

        public:
          iterative_system_root_base()
          : iterative_root_base<data__>(), norm_type(iterative_system_root_base<data__, N__, NSOL__>::max_norm)
          {
          }

          iterative_system_root_base(const iterative_system_root_base<data__, N__, NSOL__>& isrb)
          : iterative_root_base<data__>(isrb), norm_type(isrb.norm_type)
          {
          }

          ~iterative_system_root_base()
          {
          }

          system_norm_type get_norm_type() const
          {
            return norm_type;
          }

          void set_norm_type(system_norm_type snt)
          {
            norm_type = snt;
          }

        protected:
          data__ calculate_norm(const solution_matrix &mat) const
          {
            // handle the cases that do not need to distinguish between vectors and matrices
            switch (get_norm_type())
            {
              case(L1):            // for vectors this is sum of maxes, for matrices this is maximum absolute column sum
              {
                data__ rtn_val(-1), tmp;

                for (typename solution_matrix::Index nc=0; nc<mat.cols(); ++nc)
                {
                  tmp=mat.col(nc).cwiseAbs().sum();
                  if (tmp>rtn_val)
                    rtn_val=tmp;
                }

                return rtn_val;
                break;
              }
              case(Linf):          // for vectors this is the largest (in magnitude) terms, for matrices this is maximum absolute row sum
              {
                data__ rtn_val(-1), tmp;

                for (typename solution_matrix::Index nr=0; nr<mat.rows(); ++nr)
                {
                  tmp=mat.row(nr).cwiseAbs().sum();
                  if (tmp>rtn_val)
                    rtn_val=tmp;
                }

                return rtn_val;
                break;
              }
              case(max_norm):      // for vectors this is equivalent to Linf, for matrices it is the largest element in matrix
              {
                return std::abs(mat.maxCoeff());
                break;
              }
              case(L2):             // for vectors this is sqrt of sum of squares, for matrices this will be equivalent to the Frobenius norm
              case(Frobenius_norm): // for vectors this is L2, for matrices this is the sqrt of sum of squares of each term
              {
                data__ rtn_val(0);

                for (typename solution_matrix::Index nc=0; nc<mat.cols(); ++nc)
                  rtn_val+=mat.col(nc).squaredNorm();

                return std::sqrt(rtn_val);
                break;
              }
              default:
              {
                // unknown norm type
                assert(false);
                return static_cast<data__>(-1);
              }
            }

            return static_cast<data__>(-1);
          }

        private:
          system_norm_type norm_type;
      };
    }
  }
}
#endif
<commit_msg>Matrix inf norm was calculated wrong.<commit_after>/*********************************************************************************
* Copyright (c) 2013 David D. Marshall <ddmarsha@calpoly.edu>
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*    David D. Marshall - initial code and implementation
********************************************************************************/

#ifndef eli_mutil_nls_iterative_root_system_method_hpp
#define eli_mutil_nls_iterative_root_system_method_hpp

#ifdef Success  // X11 #define collides with Eigen
#undef Success
#endif

#include "Eigen/Eigen"

#include "eli/mutil/nls/iterative_root_base.hpp"

namespace eli
{
  namespace mutil
  {
    namespace nls
    {
      template<typename data__, size_t N__, size_t NSOL__>
      class iterative_system_root_base : public iterative_root_base<data__>
      {
        public:
          typedef Eigen::Matrix<data__, N__, NSOL__> solution_matrix;
          typedef Eigen::Matrix<data__, N__, N__>    jacobian_matrix;

          enum system_norm_type
          {
            L1=100,            // for vectors this is sum of maxes, for matrices this is maximum absolute column sum
            L2=200,            // for vectors this is sqrt of sum of squares, for matrices this will be equivalent to the Frobenius norm
            Linf=300,          // for vectors this is the largest (in magnitude) terms, for matrices this is maximum abolute row sum
            max_norm=400,      // for vectors this is equivalent to Linf, for matrices it is the largest element in matrix
            Frobenius_norm=500 // for vectors this is L2, for matrices this is the sqrt of sum of squares of each term
          };

        public:
          iterative_system_root_base()
          : iterative_root_base<data__>(), norm_type(iterative_system_root_base<data__, N__, NSOL__>::max_norm)
          {
          }

          iterative_system_root_base(const iterative_system_root_base<data__, N__, NSOL__>& isrb)
          : iterative_root_base<data__>(isrb), norm_type(isrb.norm_type)
          {
          }

          ~iterative_system_root_base()
          {
          }

          system_norm_type get_norm_type() const
          {
            return norm_type;
          }

          void set_norm_type(system_norm_type snt)
          {
            norm_type = snt;
          }

        protected:
          data__ calculate_norm(const solution_matrix &mat) const
          {
            // handle the cases that do not need to distinguish between vectors and matrices
            switch (get_norm_type())
            {
              case(L1):            // for vectors this is sum of maxes, for matrices this is maximum absolute column sum
              {
                data__ rtn_val(-1), tmp;

                for (typename solution_matrix::Index nc=0; nc<mat.cols(); ++nc)
                {
                  tmp=mat.col(nc).cwiseAbs().sum();
                  if (tmp>rtn_val)
                    rtn_val=tmp;
                }

                return rtn_val;
                break;
              }
              case(Linf):          // for vectors this is the largest (in magnitude) terms, for matrices this is maximum absolute row sum
              {
                data__ rtn_val(-1), tmp;

                for (typename solution_matrix::Index nr=0; nr<mat.rows(); ++nr)
                {
                  tmp=mat.row(nr).cwiseAbs().sum();
                  if (tmp>rtn_val)
                    rtn_val=tmp;
                }

                return rtn_val;
                break;
              }
              case(max_norm):      // for vectors this is equivalent to Linf, for matrices it is the largest element in matrix
              {
                data__ maxval = std::abs(mat.maxCoeff());
                data__ minval = std::abs(mat.minCoeff());
                if( maxval > minval ) return maxval;
                else return minval;
                // The following should work, but it throws an error: Expected expression.
                // return mat.lpNorm<Eigen::Infinity>();
                break;
              }
              case(L2):             // for vectors this is sqrt of sum of squares, for matrices this will be equivalent to the Frobenius norm
              case(Frobenius_norm): // for vectors this is L2, for matrices this is the sqrt of sum of squares of each term
              {
                data__ rtn_val(0);

                for (typename solution_matrix::Index nc=0; nc<mat.cols(); ++nc)
                  rtn_val+=mat.col(nc).squaredNorm();

                return std::sqrt(rtn_val);
                break;
              }
              default:
              {
                // unknown norm type
                assert(false);
                return static_cast<data__>(-1);
              }
            }

            return static_cast<data__>(-1);
          }

        private:
          system_norm_type norm_type;
      };
    }
  }
}
#endif
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2007 Alp Toker <alp@atoker.com>
 * Copyright (C) 2007 Apple Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "config.h"
#include "PrintContext.h"

#include "GraphicsContext.h"
#include "Frame.h"
#include "RenderView.h"

using namespace WebCore;

namespace WebCore {

PrintContext::PrintContext(Frame* frame)
    : m_frame(frame)
{
}

PrintContext::~PrintContext()
{
    m_pageRects.clear();
}

int PrintContext::pageCount() const
{
    return m_pageRects.size();
}

void PrintContext::computePageRects(const FloatRect& printRect, float headerHeight, float footerHeight, float userScaleFactor, float& outPageHeight)
{
    m_pageRects.clear();
    outPageHeight = 0;

    if (!m_frame->document() || !m_frame->view() || !m_frame->document()->renderer())
        return;

    RenderView* root = static_cast<RenderView*>(m_frame->document()->renderer());

    if (!root) {
        LOG_ERROR("document to be printed has no renderer");
        return;
    }

    if (userScaleFactor <= 0) {
        LOG_ERROR("userScaleFactor has bad value %.2f", userScaleFactor);
        return;
    }

    float ratio = printRect.height() / printRect.width();

    float pageWidth  = (float)root->docWidth();
    float pageHeight = pageWidth * ratio;
    outPageHeight = pageHeight;   // this is the height of the page adjusted by margins
    pageHeight -= headerHeight + footerHeight;

    if (pageHeight <= 0) {
        LOG_ERROR("pageHeight has bad value %.2f", pageHeight);
        return;
    }

    float currPageHeight = pageHeight / userScaleFactor;
    float docHeight = root->layer()->height();
    float currPageWidth = pageWidth / userScaleFactor;

    // always return at least one page, since empty files should print a blank page
    float printedPagesHeight = 0.0;
    do {
        float proposedBottom = std::min(docHeight, printedPagesHeight + pageHeight);
        m_frame->adjustPageHeight(&proposedBottom, printedPagesHeight, proposedBottom, printedPagesHeight);
        currPageHeight = max(1.0f, proposedBottom - printedPagesHeight);

        m_pageRects.append(IntRect(0, (int)printedPagesHeight, (int)currPageWidth, (int)currPageHeight));
        printedPagesHeight += currPageHeight;
    } while (printedPagesHeight < docHeight);
}

void PrintContext::begin(float width)
{
    // By imaging to a width a little wider than the available pixels,
    // thin pages will be scaled down a little, matching the way they
    // print in IE and Camino. This lets them use fewer sheets than they
    // would otherwise, which is presumably why other browsers do this.
    // Wide pages will be scaled down more than this.
    const float PrintingMinimumShrinkFactor = 1.25f;

    // This number determines how small we are willing to reduce the page content
    // in order to accommodate the widest line. If the page would have to be
    // reduced smaller to make the widest line fit, we just clip instead (this
    // behavior matches MacIE and Mozilla, at least)
    const float PrintingMaximumShrinkFactor = 2.0f;

    float minLayoutWidth = width * PrintingMinimumShrinkFactor;
    float maxLayoutWidth = width * PrintingMaximumShrinkFactor;

    // FIXME: This will modify the rendering of the on-screen frame.
    // Could lead to flicker during printing.
    m_frame->setPrinting(true, minLayoutWidth, maxLayoutWidth, true);
}

void PrintContext::spoolPage(GraphicsContext& ctx, int pageNumber, float width)
{
    IntRect pageRect = m_pageRects[pageNumber];
    float scale = width / pageRect.width();

    ctx.save();
    ctx.scale(FloatSize(scale, scale));
    ctx.translate(-pageRect.x(), -pageRect.y());
    ctx.clip(pageRect);
    m_frame->paint(&ctx, pageRect);
    ctx.restore();
}

void PrintContext::end()
{
    m_frame->setPrinting(false, 0, 0, true);
}

}
<commit_msg>Fix Qt bustage.<commit_after>/*
 * Copyright (C) 2007 Alp Toker <alp@atoker.com>
 * Copyright (C) 2007 Apple Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "config.h"
#include "PrintContext.h"

#include "GraphicsContext.h"
#include "Frame.h"
#include "RenderView.h"

using namespace WebCore;

namespace WebCore {

PrintContext::PrintContext(Frame* frame)
    : m_frame(frame)
{
}

PrintContext::~PrintContext()
{
    m_pageRects.clear();
}

int PrintContext::pageCount() const
{
    return m_pageRects.size();
}

void PrintContext::computePageRects(const FloatRect& printRect, float headerHeight, float footerHeight, float userScaleFactor, float& outPageHeight)
{
    m_pageRects.clear();
    outPageHeight = 0;

    if (!m_frame->document() || !m_frame->view() || !m_frame->document()->renderer())
        return;

    RenderView* root = static_cast<RenderView*>(m_frame->document()->renderer());

    if (!root) {
        LOG_ERROR("document to be printed has no renderer");
        return;
    }

    if (userScaleFactor <= 0) {
        LOG_ERROR("userScaleFactor has bad value %.2f", userScaleFactor);
        return;
    }

    float ratio = printRect.height() / printRect.width();

    float pageWidth  = (float)root->docWidth();
    float pageHeight = pageWidth * ratio;
    outPageHeight = pageHeight;   // this is the height of the page adjusted by margins
    pageHeight -= headerHeight + footerHeight;

    if (pageHeight <= 0) {
        LOG_ERROR("pageHeight has bad value %.2f", pageHeight);
        return;
    }

    float currPageHeight = pageHeight / userScaleFactor;
    float docHeight = root->layer()->height();
    float currPageWidth = pageWidth / userScaleFactor;

    // always return at least one page, since empty files should print a blank page
    float printedPagesHeight = 0.0;
    do {
        float proposedBottom = std::min(docHeight, printedPagesHeight + pageHeight);
        m_frame->adjustPageHeight(&proposedBottom, printedPagesHeight, proposedBottom, printedPagesHeight);
        currPageHeight = max(1.0f, proposedBottom - printedPagesHeight);

        m_pageRects.append(IntRect(0, (int)printedPagesHeight, (int)currPageWidth, (int)currPageHeight));
        printedPagesHeight += currPageHeight;
    } while (printedPagesHeight < docHeight);
}

void PrintContext::begin(float width)
{
    // By imaging to a width a little wider than the available pixels,
    // thin pages will be scaled down a little, matching the way they
    // print in IE and Camino. This lets them use fewer sheets than they
    // would otherwise, which is presumably why other browsers do this.
    // Wide pages will be scaled down more than this.
    const float PrintingMinimumShrinkFactor = 1.25f;

    // This number determines how small we are willing to reduce the page content
    // in order to accommodate the widest line. If the page would have to be
    // reduced smaller to make the widest line fit, we just clip instead (this
    // behavior matches MacIE and Mozilla, at least)
    const float PrintingMaximumShrinkFactor = 2.0f;

    float minLayoutWidth = width * PrintingMinimumShrinkFactor;
    float maxLayoutWidth = width * PrintingMaximumShrinkFactor;

    // FIXME: This will modify the rendering of the on-screen frame.
    // Could lead to flicker during printing.
    m_frame->setPrinting(true, minLayoutWidth, maxLayoutWidth, true);
}

void PrintContext::spoolPage(GraphicsContext& ctx, int pageNumber, float width)
{
    IntRect pageRect = m_pageRects[pageNumber];
    float scale = width / pageRect.width();

    ctx.save();
    ctx.scale(FloatSize(scale, scale));
    ctx.translate(-pageRect.x(), -pageRect.y());
    ctx.clip(pageRect);
    m_frame->view()->paintContents(&ctx, pageRect);
    ctx.restore();
}

void PrintContext::end()
{
    m_frame->setPrinting(false, 0, 0, true);
}

}
<|endoftext|>


<commit_before>/*
* mod_compare - compares apache requests
*
* Copyright (C) 2013 Orange
*
* 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.
*/

#include <httpd.h>
#include <http_config.h>
#include <http_request.h>
#include <http_protocol.h>
#include <http_connection.h>
#include <apr_pools.h>
#include <apr_hooks.h>
#include "apr_strings.h"
#include <unistd.h>
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/interprocess/sync/named_mutex.hpp>
#include <exception>
#include <set>
#include <sstream>
#include <sys/syscall.h>
#include <algorithm>
#include <boost/tokenizer.hpp>
#include <fstream>
#include <unixd.h>

#include "mod_compare.hh"

#define MOD_REWRITE_NAME "mod_rewrite.c"

namespace alg = boost::algorithm;

namespace CompareModule {

const char* gName = "Compare";
const char* gNameOut = "CompareOut";
const char* gNameOut2 = "CompareOut2";
const char* c_COMPONENT_VERSION = "Compare/1.0";
const char* c_named_mutex = "mod_compare_log_mutex";
bool gRem = boost::interprocess::named_mutex::remove(c_named_mutex);
std::ofstream gFile;
const char * gFilePath = "/var/opt/hosting/log/apache2/compare_diff.log";
bool gWriteInFile = true;
std::string gLogFacility;

boost::interprocess::named_mutex &getGlobalMutex() {
    static boost::interprocess::named_mutex *gMutex = NULL;
    try {
        if (!gMutex) {
            gMutex = new boost::interprocess::named_mutex(boost::interprocess::open_or_create, c_named_mutex);
        }
        return *gMutex;
    } catch (boost::interprocess::interprocess_exception& e) {
        // Just in case the log has not been init yet
        Log::init();
        Log::error(42, "Cannot initialize global mutex named: %s. What: %s", c_named_mutex, e.what());
        throw e;
    }
}

CompareConf::CompareConf(): mCompareDisabled(false), mIsActive(false) {
}

apr_status_t CompareConf::cleaner(void *self) {
    if(self){
        CompareConf *c = reinterpret_cast<CompareConf *>(self);

        c->~CompareConf();
    }
    return 0;
}

/**
 * @brief allocate a pointer to a string which will hold the path for the dir config if mod_compare is active on it
 * @param pPool the apache pool on which to allocate data
 * @param pDirName the directory name for which to create data
 * @return a void pointer to newly allocated object
 */
void *
createDirConfig(apr_pool_t *pPool, char *pDirName)
{
    void *addr= apr_pcalloc(pPool, sizeof(class CompareConf));
    new (addr) CompareConf();
    apr_pool_cleanup_register(pPool, addr, CompareConf::cleaner,  apr_pool_cleanup_null);
    return addr;
}

/**
 * @brief Initialize logging post-config
 * @param pPool the apache pool
 * @param pServer the corresponding server record
 * @return Always OK
 */
int
postConfig(apr_pool_t * pPool, apr_pool_t * pLog, apr_pool_t * pTemp, server_rec * pServer) {
    Log::init();

    ap_add_version_component(pPool, c_COMPONENT_VERSION) ;

    if( !gWriteInFile ){
        return APR_SUCCESS;
    }

    apr_pool_cleanup_register(pPool, NULL, apr_pool_cleanup_null, closeLogFile);
    return openLogFile(gFilePath, std::ofstream::out | std::ofstream::app);

}

apr_status_t
closeLogFile(void *) {

    gFile.close();
    return APR_SUCCESS;
}

apr_status_t openLogFile(const char * filepath,std::ios_base::openmode mode) {

    gFile.open(filepath,mode);
    if (!gFile.is_open()){
        Log::error(43,"Couldn't open correctly the file");
        return 400; // to modify
    }
    if ( chown(filepath, unixd_config.user_id, unixd_config.group_id) < 0 ) {
       Log::error(528, "Failed to change ownership of shared mem file %s to child user %s, error %d (%s)", filepath, unixd_config.user_name, errno, strerror(errno) );
    }
    gFile.close();
    return APR_SUCCESS;
}

void
childInit(apr_pool_t *pPool, server_rec *pServer)
{
    if( gWriteInFile ){
        gFile.open(gFilePath, std::ofstream::out | std::ofstream::app );
        if (!gFile.is_open()){
            Log::error(43,"Couldn't open correctly the file");
        }
    }
}

/**
 * @brief Set the list of errors which stop the comparison
 * @param pParams miscellaneous data
 * @param pCfg user data for the directory/location
 * @param pListType the type of list (STOP or IGNORE)
 * @param pValue the reg_ex to insert in the list
 * @return NULL if parameters are valid, otherwise a string describing the error
 */
const char*
setBodyList(cmd_parms* pParams, void* pCfg, const char* pListType, const char* pValue) {
    if (!pValue || strlen(pValue) == 0) {
        return "Missing reg_ex value for the body";
    }

    if (!pListType || strlen(pListType) == 0) {
        return "Missing the type of list";
    }

    CompareConf *lConf = reinterpret_cast<CompareConf *>(pCfg);
    std::string lListType(pListType);
    std::string lValue(pValue);

    if (strcmp("STOP", pListType) == 0)
    {
        lConf->mCompBody.addStopRegex(lValue);
    }
    else if(strcmp("IGNORE", pListType) == 0)
    {
        lConf->mCompBody.addIgnoreRegex(lValue);
    }
    else
    {
        return "Invalid value for the list type";
    }

    return NULL;
}

/**
 * @brief Set the list of errors to ignore in the comparison
 * @param pParams miscellaneous data
 * @param pCfg user data for the directory/location
 * @param pListType the type of list (STOP or IGNORE)
 * @param pHeader the header for which to apply the regex
 * @param pValue the reg_ex to insert in the list
 * @return NULL if parameters are valid, otherwise a string describing the error
 */
const char* setHeaderList(cmd_parms* pParams, void* pCfg, const char* pListType, const char* pAffectedKey,const char* pValue) {
    if (!pValue || strlen(pValue) == 0) {
        return "Missing reg_ex value for the header";
    }

    if (!pAffectedKey || strlen(pAffectedKey) == 0) {
            return "Missing header value";
        }

    if (!pListType || strlen(pListType) == 0) {
        return "Missing the type list";
    }

    CompareConf *lConf = reinterpret_cast<CompareConf *>(pCfg);
    std::string lHeader(pAffectedKey);
    std::string lValue(pValue);

    if (strcmp("STOP", pListType) == 0)
    {
        lConf->mCompHeader.addStopRegex(lHeader, lValue);
    }
    else if(strcmp("IGNORE", pListType) == 0)
    {
        lConf->mCompHeader.addIgnoreRegex(lHeader, lValue);
    }
    else
    {
        return "Invalid value for the list type";
    }

    return NULL;
}

/**
 * @brief Enable/Disable the utilization of the libws-diff tools
 * @param pParams miscellaneous data
 * @param pCfg user data for the directory/location
 * @param pValue the value
 * @return NULL if parameters are valid, otherwise a string describing the error
 */
const char*
setDisableLibwsdiff(cmd_parms* pParams, void* pCfg, const char* pValue) {
    Log::init();
	CompareConf *lConf = reinterpret_cast<CompareConf *>(pCfg);
	lConf->mCompareDisabled= strcmp(pValue, "1")==0 || strcmp(pValue, "true")==0;
    if(lConf->mCompareDisabled){
    	Log::warn(42,"The use of the diffing library \nlibws-diff has been disabled!");
    }
    return NULL;
}

const char*
setCompareLog(cmd_parms* pParams, void* pCfg, const char* pType, const char* pValue) {

    if (!pType || strlen(pValue) == 0) {
            return "Missing log type";
        }

    if (!pValue || strlen(pValue) == 0) {
        return "Missing file path or facility";
    }

    if (strcmp("FILE", pType) == 0)
    {
        gWriteInFile = true;
        gFilePath = pValue;
    }
    else if(strcmp("SYSLOG", pType) == 0)
    {
        gLogFacility = std::string(pValue);
        gWriteInFile = false;
        //closes the log if it was initialized
        Log::close();
        //initializes the log
        Log::init(gLogFacility);
    }
    else
    {
        return "Invalid value for the log type";
    }

    return NULL;

}

const char*
setCompare(cmd_parms* pParams, void* pCfg, const char* pValue) {
    CompareConf *lConf = reinterpret_cast<CompareConf *>(pCfg);

    lConf->mIsActive= true;

#ifndef UNIT_TESTING
        if (!ap_find_linked_module(MOD_REWRITE_NAME)) {
            return "'mod_rewrite' is not loaded, Enable mod_rewrite to use mod_compare";
        }
#endif

    return NULL;
}

/** @brief Declaration of configuration commands */
    command_rec gCmds[] = {
        // AP_INIT_(directive,
        //          function,
        //          void * extra data,
        //          overrides to allow in order to enable,
        //          help message),
        AP_INIT_TAKE2("BodyList",
                      reinterpret_cast<const char *(*)()>(&setBodyList),
                      0,
                      ACCESS_CONF,
                      "List of reg_ex to apply to the body for the comparison."),
        AP_INIT_TAKE3("HeaderList",
                      reinterpret_cast<const char *(*)()>(&setHeaderList),
                      0,
                      ACCESS_CONF,
                      "List of reg_ex to apply to the Header for the comparison."),
        AP_INIT_NO_ARGS("Compare",
                      reinterpret_cast<const char *(*)()>(&setCompare),
                      0,
                      ACCESS_CONF,
                      "Activate mod_compare."),
        AP_INIT_TAKE2("CompareLog",
                      reinterpret_cast<const char *(*)()>(&setCompareLog),
                      0,
                      OR_ALL,
                      "Log to a facility instead of a file."),
        AP_INIT_TAKE1("DisableLibwsdiff",
                      reinterpret_cast<const char *(*)()>(&setDisableLibwsdiff),
                      0,
                      ACCESS_CONF,
                      "Disable the use of libws-diff tools. Print raw serialization of the data in the log file."),
        {0}
    };

#ifndef UNIT_TESTING

static void insertInputFilter(request_rec *pRequest) {
    CompareConf *lConf = reinterpret_cast<CompareConf *>(ap_get_module_config(pRequest->per_dir_config, &compare_module));
    assert(lConf);
    if (lConf->mIsActive){
        ap_add_input_filter(gName, NULL, pRequest, pRequest->connection);
    }
}

static void insertOutputFilter(request_rec *pRequest) {
    CompareConf *lConf = reinterpret_cast<CompareConf *>(ap_get_module_config(pRequest->per_dir_config, &compare_module));
    assert(lConf);
    if (lConf->mIsActive){
        ap_add_output_filter(gNameOut, NULL, pRequest, pRequest->connection);
    }
}

static void insertOutputFilter2(request_rec *pRequest) {
    CompareConf *lConf = reinterpret_cast<CompareConf *>(ap_get_module_config(pRequest->per_dir_config, &compare_module));
    assert(lConf);
    if (lConf->mIsActive){
        ap_add_output_filter(gNameOut2, NULL, pRequest, pRequest->connection);
    }
}
#endif

/**
 * @brief register hooks in apache
 * @param pPool the apache pool
 */
void
registerHooks(apr_pool_t *pPool) {
#ifndef UNIT_TESTING
    ap_hook_post_config(postConfig, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_child_init(&childInit, NULL, NULL, APR_HOOK_MIDDLE);
    ap_register_input_filter(gName, inputFilterHandler, NULL, AP_FTYPE_RESOURCE);
    // output filter of type AP_FTYPE_RESOURCE => only the body will be read ( the headers_out not set yet)
    ap_register_output_filter(gNameOut, outputFilterHandler, NULL, AP_FTYPE_RESOURCE);
    // output filter of type AP_FTYPE_CONNECTION => only the response header will be read
    ap_register_output_filter(gNameOut2, outputFilterHandler2, NULL, AP_FTYPE_TRANSCODE);
    ap_hook_insert_filter(&insertInputFilter, NULL, NULL, APR_HOOK_FIRST);
    ap_hook_insert_filter(&insertOutputFilter, NULL, NULL, APR_HOOK_LAST);
    ap_hook_insert_filter(&insertOutputFilter2, NULL, NULL, APR_HOOK_LAST);

    ap_hook_translate_name(&translateHook, NULL, NULL, APR_HOOK_MIDDLE);
#endif
}

} // End namespace

/// Apache module declaration
module AP_MODULE_DECLARE_DATA compare_module = {
    STANDARD20_MODULE_STUFF,
    CompareModule::createDirConfig,
    0, // merge_dir_config
    0, // create_server_config
    0, // merge_server_config
    CompareModule::gCmds,
    CompareModule::registerHooks
};
<commit_msg>removed ap_hook_insert_filter for the input filter, to be able to specify it via conf<commit_after>/*
* mod_compare - compares apache requests
*
* Copyright (C) 2013 Orange
*
* 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.
*/

#include <httpd.h>
#include <http_config.h>
#include <http_request.h>
#include <http_protocol.h>
#include <http_connection.h>
#include <apr_pools.h>
#include <apr_hooks.h>
#include "apr_strings.h"
#include <unistd.h>
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/interprocess/sync/named_mutex.hpp>
#include <exception>
#include <set>
#include <sstream>
#include <sys/syscall.h>
#include <algorithm>
#include <boost/tokenizer.hpp>
#include <fstream>
#include <unixd.h>

#include "mod_compare.hh"

#define MOD_REWRITE_NAME "mod_rewrite.c"

namespace alg = boost::algorithm;

namespace CompareModule {

const char* gName = "Compare";
const char* gNameOut = "CompareOut";
const char* gNameOut2 = "CompareOut2";
const char* c_COMPONENT_VERSION = "Compare/1.0";
const char* c_named_mutex = "mod_compare_log_mutex";
bool gRem = boost::interprocess::named_mutex::remove(c_named_mutex);
std::ofstream gFile;
const char * gFilePath = "/var/opt/hosting/log/apache2/compare_diff.log";
bool gWriteInFile = true;
std::string gLogFacility;

boost::interprocess::named_mutex &getGlobalMutex() {
    static boost::interprocess::named_mutex *gMutex = NULL;
    try {
        if (!gMutex) {
            gMutex = new boost::interprocess::named_mutex(boost::interprocess::open_or_create, c_named_mutex);
        }
        return *gMutex;
    } catch (boost::interprocess::interprocess_exception& e) {
        // Just in case the log has not been init yet
        Log::init();
        Log::error(42, "Cannot initialize global mutex named: %s. What: %s", c_named_mutex, e.what());
        throw e;
    }
}

CompareConf::CompareConf(): mCompareDisabled(false), mIsActive(false) {
}

apr_status_t CompareConf::cleaner(void *self) {
    if(self){
        CompareConf *c = reinterpret_cast<CompareConf *>(self);

        c->~CompareConf();
    }
    return 0;
}

/**
 * @brief allocate a pointer to a string which will hold the path for the dir config if mod_compare is active on it
 * @param pPool the apache pool on which to allocate data
 * @param pDirName the directory name for which to create data
 * @return a void pointer to newly allocated object
 */
void *
createDirConfig(apr_pool_t *pPool, char *pDirName)
{
    void *addr= apr_pcalloc(pPool, sizeof(class CompareConf));
    new (addr) CompareConf();
    apr_pool_cleanup_register(pPool, addr, CompareConf::cleaner,  apr_pool_cleanup_null);
    return addr;
}

/**
 * @brief Initialize logging post-config
 * @param pPool the apache pool
 * @param pServer the corresponding server record
 * @return Always OK
 */
int
postConfig(apr_pool_t * pPool, apr_pool_t * pLog, apr_pool_t * pTemp, server_rec * pServer) {
    Log::init();

    ap_add_version_component(pPool, c_COMPONENT_VERSION) ;

    if( !gWriteInFile ){
        return APR_SUCCESS;
    }

    apr_pool_cleanup_register(pPool, NULL, apr_pool_cleanup_null, closeLogFile);
    return openLogFile(gFilePath, std::ofstream::out | std::ofstream::app);

}

apr_status_t
closeLogFile(void *) {

    gFile.close();
    return APR_SUCCESS;
}

apr_status_t openLogFile(const char * filepath,std::ios_base::openmode mode) {

    gFile.open(filepath,mode);
    if (!gFile.is_open()){
        Log::error(43,"Couldn't open correctly the file");
        return 400; // to modify
    }
    if ( chown(filepath, unixd_config.user_id, unixd_config.group_id) < 0 ) {
       Log::error(528, "Failed to change ownership of shared mem file %s to child user %s, error %d (%s)", filepath, unixd_config.user_name, errno, strerror(errno) );
    }
    gFile.close();
    return APR_SUCCESS;
}

void
childInit(apr_pool_t *pPool, server_rec *pServer)
{
    if( gWriteInFile ){
        gFile.open(gFilePath, std::ofstream::out | std::ofstream::app );
        if (!gFile.is_open()){
            Log::error(43,"Couldn't open correctly the file");
        }
    }
}

/**
 * @brief Set the list of errors which stop the comparison
 * @param pParams miscellaneous data
 * @param pCfg user data for the directory/location
 * @param pListType the type of list (STOP or IGNORE)
 * @param pValue the reg_ex to insert in the list
 * @return NULL if parameters are valid, otherwise a string describing the error
 */
const char*
setBodyList(cmd_parms* pParams, void* pCfg, const char* pListType, const char* pValue) {
    if (!pValue || strlen(pValue) == 0) {
        return "Missing reg_ex value for the body";
    }

    if (!pListType || strlen(pListType) == 0) {
        return "Missing the type of list";
    }

    CompareConf *lConf = reinterpret_cast<CompareConf *>(pCfg);
    std::string lListType(pListType);
    std::string lValue(pValue);

    if (strcmp("STOP", pListType) == 0)
    {
        lConf->mCompBody.addStopRegex(lValue);
    }
    else if(strcmp("IGNORE", pListType) == 0)
    {
        lConf->mCompBody.addIgnoreRegex(lValue);
    }
    else
    {
        return "Invalid value for the list type";
    }

    return NULL;
}

/**
 * @brief Set the list of errors to ignore in the comparison
 * @param pParams miscellaneous data
 * @param pCfg user data for the directory/location
 * @param pListType the type of list (STOP or IGNORE)
 * @param pHeader the header for which to apply the regex
 * @param pValue the reg_ex to insert in the list
 * @return NULL if parameters are valid, otherwise a string describing the error
 */
const char* setHeaderList(cmd_parms* pParams, void* pCfg, const char* pListType, const char* pAffectedKey,const char* pValue) {
    if (!pValue || strlen(pValue) == 0) {
        return "Missing reg_ex value for the header";
    }

    if (!pAffectedKey || strlen(pAffectedKey) == 0) {
            return "Missing header value";
        }

    if (!pListType || strlen(pListType) == 0) {
        return "Missing the type list";
    }

    CompareConf *lConf = reinterpret_cast<CompareConf *>(pCfg);
    std::string lHeader(pAffectedKey);
    std::string lValue(pValue);

    if (strcmp("STOP", pListType) == 0)
    {
        lConf->mCompHeader.addStopRegex(lHeader, lValue);
    }
    else if(strcmp("IGNORE", pListType) == 0)
    {
        lConf->mCompHeader.addIgnoreRegex(lHeader, lValue);
    }
    else
    {
        return "Invalid value for the list type";
    }

    return NULL;
}

/**
 * @brief Enable/Disable the utilization of the libws-diff tools
 * @param pParams miscellaneous data
 * @param pCfg user data for the directory/location
 * @param pValue the value
 * @return NULL if parameters are valid, otherwise a string describing the error
 */
const char*
setDisableLibwsdiff(cmd_parms* pParams, void* pCfg, const char* pValue) {
    Log::init();
	CompareConf *lConf = reinterpret_cast<CompareConf *>(pCfg);
	lConf->mCompareDisabled= strcmp(pValue, "1")==0 || strcmp(pValue, "true")==0;
    if(lConf->mCompareDisabled){
    	Log::warn(42,"The use of the diffing library \nlibws-diff has been disabled!");
    }
    return NULL;
}

const char*
setCompareLog(cmd_parms* pParams, void* pCfg, const char* pType, const char* pValue) {

    if (!pType || strlen(pValue) == 0) {
            return "Missing log type";
        }

    if (!pValue || strlen(pValue) == 0) {
        return "Missing file path or facility";
    }

    if (strcmp("FILE", pType) == 0)
    {
        gWriteInFile = true;
        gFilePath = pValue;
    }
    else if(strcmp("SYSLOG", pType) == 0)
    {
        gLogFacility = std::string(pValue);
        gWriteInFile = false;
        //closes the log if it was initialized
        Log::close();
        //initializes the log
        Log::init(gLogFacility);
    }
    else
    {
        return "Invalid value for the log type";
    }

    return NULL;

}

const char*
setCompare(cmd_parms* pParams, void* pCfg, const char* pValue) {
    CompareConf *lConf = reinterpret_cast<CompareConf *>(pCfg);

    lConf->mIsActive= true;

#ifndef UNIT_TESTING
        if (!ap_find_linked_module(MOD_REWRITE_NAME)) {
            return "'mod_rewrite' is not loaded, Enable mod_rewrite to use mod_compare";
        }
#endif

    return NULL;
}

/** @brief Declaration of configuration commands */
    command_rec gCmds[] = {
        // AP_INIT_(directive,
        //          function,
        //          void * extra data,
        //          overrides to allow in order to enable,
        //          help message),
        AP_INIT_TAKE2("BodyList",
                      reinterpret_cast<const char *(*)()>(&setBodyList),
                      0,
                      ACCESS_CONF,
                      "List of reg_ex to apply to the body for the comparison."),
        AP_INIT_TAKE3("HeaderList",
                      reinterpret_cast<const char *(*)()>(&setHeaderList),
                      0,
                      ACCESS_CONF,
                      "List of reg_ex to apply to the Header for the comparison."),
        AP_INIT_NO_ARGS("Compare",
                      reinterpret_cast<const char *(*)()>(&setCompare),
                      0,
                      ACCESS_CONF,
                      "Activate mod_compare."),
        AP_INIT_TAKE2("CompareLog",
                      reinterpret_cast<const char *(*)()>(&setCompareLog),
                      0,
                      OR_ALL,
                      "Log to a facility instead of a file."),
        AP_INIT_TAKE1("DisableLibwsdiff",
                      reinterpret_cast<const char *(*)()>(&setDisableLibwsdiff),
                      0,
                      ACCESS_CONF,
                      "Disable the use of libws-diff tools. Print raw serialization of the data in the log file."),
        {0}
    };

#ifndef UNIT_TESTING

static void insertInputFilter(request_rec *pRequest) {
    CompareConf *lConf = reinterpret_cast<CompareConf *>(ap_get_module_config(pRequest->per_dir_config, &compare_module));
    assert(lConf);
    if (lConf->mIsActive){
        ap_add_input_filter(gName, NULL, pRequest, pRequest->connection);
    }
}

static void insertOutputFilter(request_rec *pRequest) {
    CompareConf *lConf = reinterpret_cast<CompareConf *>(ap_get_module_config(pRequest->per_dir_config, &compare_module));
    assert(lConf);
    if (lConf->mIsActive){
        ap_add_output_filter(gNameOut, NULL, pRequest, pRequest->connection);
    }
}

static void insertOutputFilter2(request_rec *pRequest) {
    CompareConf *lConf = reinterpret_cast<CompareConf *>(ap_get_module_config(pRequest->per_dir_config, &compare_module));
    assert(lConf);
    if (lConf->mIsActive){
        ap_add_output_filter(gNameOut2, NULL, pRequest, pRequest->connection);
    }
}
#endif

/**
 * @brief register hooks in apache
 * @param pPool the apache pool
 */
void
registerHooks(apr_pool_t *pPool) {
#ifndef UNIT_TESTING
    ap_hook_post_config(postConfig, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_child_init(&childInit, NULL, NULL, APR_HOOK_MIDDLE);
    ap_register_input_filter(gName, inputFilterHandler, NULL, AP_FTYPE_RESOURCE);
    // output filter of type AP_FTYPE_RESOURCE => only the body will be read ( the headers_out not set yet)
    ap_register_output_filter(gNameOut, outputFilterHandler, NULL, AP_FTYPE_RESOURCE);
    // output filter of type AP_FTYPE_CONNECTION => only the response header will be read
    ap_register_output_filter(gNameOut2, outputFilterHandler2, NULL, AP_FTYPE_TRANSCODE);
    // ap_hook_insert_filter(&insertInputFilter, NULL, NULL, APR_HOOK_FIRST);
    ap_hook_insert_filter(&insertOutputFilter, NULL, NULL, APR_HOOK_LAST);
    ap_hook_insert_filter(&insertOutputFilter2, NULL, NULL, APR_HOOK_LAST);

    ap_hook_translate_name(&translateHook, NULL, NULL, APR_HOOK_MIDDLE);
#endif
}

} // End namespace

/// Apache module declaration
module AP_MODULE_DECLARE_DATA compare_module = {
    STANDARD20_MODULE_STUFF,
    CompareModule::createDirConfig,
    0, // merge_dir_config
    0, // create_server_config
    0, // merge_server_config
    CompareModule::gCmds,
    CompareModule::registerHooks
};
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2007 The Hewlett-Packard Development Company
 * All rights reserved.
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2003-2007 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Gabe Black
 */

#include "arch/x86/generated/decoder.hh"
#include "arch/x86/faults.hh"
#include "arch/x86/isa_traits.hh"
#include "base/trace.hh"
#include "cpu/thread_context.hh"
#include "debug/Faults.hh"
#include "sim/full_system.hh"

namespace X86ISA
{
    void X86FaultBase::invoke(ThreadContext * tc, StaticInstPtr inst)
    {
        if (!FullSystem) {
            FaultBase::invoke(tc, inst);
            return;
        }

        PCState pcState = tc->pcState();
        Addr pc = pcState.pc();
        DPRINTF(Faults, "RIP %#x: vector %d: %s\n",
                pc, vector, describe());
        using namespace X86ISAInst::RomLabels;
        HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
        MicroPC entry;
        if (m5reg.mode == LongMode) {
            if (isSoft()) {
                entry = extern_label_longModeSoftInterrupt;
            } else {
                entry = extern_label_longModeInterrupt;
            }
        } else {
            entry = extern_label_legacyModeInterrupt;
        }
        tc->setIntReg(INTREG_MICRO(1), vector);
        tc->setIntReg(INTREG_MICRO(7), pc);
        if (errorCode != (uint64_t)(-1)) {
            if (m5reg.mode == LongMode) {
                entry = extern_label_longModeInterruptWithError;
            } else {
                panic("Legacy mode interrupts with error codes "
                        "aren't implementde.\n");
            }
            // Software interrupts shouldn't have error codes. If one
            // does, there would need to be microcode to set it up.
            assert(!isSoft());
            tc->setIntReg(INTREG_MICRO(15), errorCode);
        }
        pcState.upc(romMicroPC(entry));
        pcState.nupc(romMicroPC(entry) + 1);
        tc->pcState(pcState);
    }

    std::string
    X86FaultBase::describe() const
    {
        std::stringstream ss;
        ccprintf(ss, "%s", mnemonic());
        if (errorCode != (uint64_t)(-1)) {
            ccprintf(ss, "(%#x)", errorCode);
        }

        return ss.str();
    }

    void X86Trap::invoke(ThreadContext * tc, StaticInstPtr inst)
    {
        X86FaultBase::invoke(tc);
        if (!FullSystem)
            return;

        // This is the same as a fault, but it happens -after- the
        // instruction.
        PCState pc = tc->pcState();
        pc.uEnd();
    }

    void X86Abort::invoke(ThreadContext * tc, StaticInstPtr inst)
    {
        panic("Abort exception!");
    }

    void
    InvalidOpcode::invoke(ThreadContext * tc, StaticInstPtr inst)
    {
        if (FullSystem) {
            X86Fault::invoke(tc, inst);
        } else {
            panic("Unrecognized/invalid instruction executed:\n %s",
                    inst->machInst);
        }
    }

    void PageFault::invoke(ThreadContext * tc, StaticInstPtr inst)
    {
        if (FullSystem) {
            HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
            X86FaultBase::invoke(tc);
            /*
             * If something bad happens while trying to enter the page fault
             * handler, I'm pretty sure that's a double fault and then all
             * bets are off. That means it should be safe to update this
             * state now.
             */
            if (m5reg.mode == LongMode) {
                tc->setMiscReg(MISCREG_CR2, addr);
            } else {
                tc->setMiscReg(MISCREG_CR2, (uint32_t)addr);
            }
        } else {
            PageFaultErrorCode code = errorCode;
            const char *modeStr = "";
            if (code.fetch)
                modeStr = "execute";
            else if (code.write)
                modeStr = "write";
            else
                modeStr = "read";
            panic("Tried to %s unmapped address %#x.\n", modeStr, addr);
        }
    }

    std::string
    PageFault::describe() const
    {
        std::stringstream ss;
        ccprintf(ss, "%s at %#x", X86FaultBase::describe(), addr);
        return ss.str();
    }

    void
    InitInterrupt::invoke(ThreadContext *tc, StaticInstPtr inst)
    {
        DPRINTF(Faults, "Init interrupt.\n");
        // The otherwise unmodified integer registers should be set to 0.
        for (int index = 0; index < NUM_INTREGS; index++) {
            tc->setIntReg(index, 0);
        }

        CR0 cr0 = tc->readMiscReg(MISCREG_CR0);
        CR0 newCR0 = 1 << 4;
        newCR0.cd = cr0.cd;
        newCR0.nw = cr0.nw;
        tc->setMiscReg(MISCREG_CR0, newCR0);
        tc->setMiscReg(MISCREG_CR2, 0);
        tc->setMiscReg(MISCREG_CR3, 0);
        tc->setMiscReg(MISCREG_CR4, 0);

        tc->setMiscReg(MISCREG_RFLAGS, 0x0000000000000002ULL);

        tc->setMiscReg(MISCREG_EFER, 0);

        SegAttr dataAttr = 0;
        dataAttr.dpl = 0;
        dataAttr.unusable = 0;
        dataAttr.defaultSize = 0;
        dataAttr.longMode = 0;
        dataAttr.avl = 0;
        dataAttr.granularity = 0;
        dataAttr.present = 1;
        dataAttr.type = 3;
        dataAttr.writable = 1;
        dataAttr.readable = 1;
        dataAttr.expandDown = 0;
        dataAttr.system = 1;

        for (int seg = 0; seg != NUM_SEGMENTREGS; seg++) {
            tc->setMiscReg(MISCREG_SEG_SEL(seg), 0);
            tc->setMiscReg(MISCREG_SEG_BASE(seg), 0);
            tc->setMiscReg(MISCREG_SEG_EFF_BASE(seg), 0);
            tc->setMiscReg(MISCREG_SEG_LIMIT(seg), 0xffff);
            tc->setMiscReg(MISCREG_SEG_ATTR(seg), dataAttr);
        }

        SegAttr codeAttr = 0;
        codeAttr.dpl = 0;
        codeAttr.unusable = 0;
        codeAttr.defaultSize = 0;
        codeAttr.longMode = 0;
        codeAttr.avl = 0;
        codeAttr.granularity = 0;
        codeAttr.present = 1;
        codeAttr.type = 10;
        codeAttr.writable = 0;
        codeAttr.readable = 1;
        codeAttr.expandDown = 0;
        codeAttr.system = 1;

        tc->setMiscReg(MISCREG_CS, 0xf000);
        tc->setMiscReg(MISCREG_CS_BASE,
                0x00000000ffff0000ULL);
        tc->setMiscReg(MISCREG_CS_EFF_BASE,
                0x00000000ffff0000ULL);
        // This has the base value pre-added.
        tc->setMiscReg(MISCREG_CS_LIMIT, 0xffffffff);
        tc->setMiscReg(MISCREG_CS_ATTR, codeAttr);

        PCState pc(0x000000000000fff0ULL + tc->readMiscReg(MISCREG_CS_BASE));
        tc->pcState(pc);

        tc->setMiscReg(MISCREG_TSG_BASE, 0);
        tc->setMiscReg(MISCREG_TSG_LIMIT, 0xffff);

        tc->setMiscReg(MISCREG_IDTR_BASE, 0);
        tc->setMiscReg(MISCREG_IDTR_LIMIT, 0xffff);

        tc->setMiscReg(MISCREG_TSL, 0);
        tc->setMiscReg(MISCREG_TSL_BASE, 0);
        tc->setMiscReg(MISCREG_TSL_LIMIT, 0xffff);
        tc->setMiscReg(MISCREG_TSL_ATTR, 0);

        tc->setMiscReg(MISCREG_TR, 0);
        tc->setMiscReg(MISCREG_TR_BASE, 0);
        tc->setMiscReg(MISCREG_TR_LIMIT, 0xffff);
        tc->setMiscReg(MISCREG_TR_ATTR, 0);

        // This value should be the family/model/stepping of the processor.
        // (page 418). It should be consistent with the value from CPUID, but
        // the actual value probably doesn't matter much.
        tc->setIntReg(INTREG_RDX, 0);

        tc->setMiscReg(MISCREG_DR0, 0);
        tc->setMiscReg(MISCREG_DR1, 0);
        tc->setMiscReg(MISCREG_DR2, 0);
        tc->setMiscReg(MISCREG_DR3, 0);

        tc->setMiscReg(MISCREG_DR6, 0x00000000ffff0ff0ULL);
        tc->setMiscReg(MISCREG_DR7, 0x0000000000000400ULL);

        // Update the handy M5 Reg.
        tc->setMiscReg(MISCREG_M5_REG, 0);
        MicroPC entry = X86ISAInst::RomLabels::extern_label_initIntHalt;
        pc.upc(romMicroPC(entry));
        pc.nupc(romMicroPC(entry) + 1);
        tc->pcState(pc);
    }

    void
    StartupInterrupt::invoke(ThreadContext *tc, StaticInstPtr inst)
    {
        DPRINTF(Faults, "Startup interrupt with vector %#x.\n", vector);
        HandyM5Reg m5Reg = tc->readMiscReg(MISCREG_M5_REG);
        if (m5Reg.mode != LegacyMode || m5Reg.submode != RealMode) {
            panic("Startup IPI recived outside of real mode. "
                    "Don't know what to do. %d, %d", m5Reg.mode, m5Reg.submode);
        }

        tc->setMiscReg(MISCREG_CS, vector << 8);
        tc->setMiscReg(MISCREG_CS_BASE, vector << 12);
        tc->setMiscReg(MISCREG_CS_EFF_BASE, vector << 12);
        // This has the base value pre-added.
        tc->setMiscReg(MISCREG_CS_LIMIT, 0xffff);

        tc->pcState(tc->readMiscReg(MISCREG_CS_BASE));
    }
} // namespace X86ISA

<commit_msg>x86: Initialize the MXCSR register<commit_after>/*
 * Copyright (c) 2007 The Hewlett-Packard Development Company
 * All rights reserved.
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2003-2007 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Gabe Black
 */

#include "arch/x86/generated/decoder.hh"
#include "arch/x86/faults.hh"
#include "arch/x86/isa_traits.hh"
#include "base/trace.hh"
#include "cpu/thread_context.hh"
#include "debug/Faults.hh"
#include "sim/full_system.hh"

namespace X86ISA
{
    void X86FaultBase::invoke(ThreadContext * tc, StaticInstPtr inst)
    {
        if (!FullSystem) {
            FaultBase::invoke(tc, inst);
            return;
        }

        PCState pcState = tc->pcState();
        Addr pc = pcState.pc();
        DPRINTF(Faults, "RIP %#x: vector %d: %s\n",
                pc, vector, describe());
        using namespace X86ISAInst::RomLabels;
        HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
        MicroPC entry;
        if (m5reg.mode == LongMode) {
            if (isSoft()) {
                entry = extern_label_longModeSoftInterrupt;
            } else {
                entry = extern_label_longModeInterrupt;
            }
        } else {
            entry = extern_label_legacyModeInterrupt;
        }
        tc->setIntReg(INTREG_MICRO(1), vector);
        tc->setIntReg(INTREG_MICRO(7), pc);
        if (errorCode != (uint64_t)(-1)) {
            if (m5reg.mode == LongMode) {
                entry = extern_label_longModeInterruptWithError;
            } else {
                panic("Legacy mode interrupts with error codes "
                        "aren't implementde.\n");
            }
            // Software interrupts shouldn't have error codes. If one
            // does, there would need to be microcode to set it up.
            assert(!isSoft());
            tc->setIntReg(INTREG_MICRO(15), errorCode);
        }
        pcState.upc(romMicroPC(entry));
        pcState.nupc(romMicroPC(entry) + 1);
        tc->pcState(pcState);
    }

    std::string
    X86FaultBase::describe() const
    {
        std::stringstream ss;
        ccprintf(ss, "%s", mnemonic());
        if (errorCode != (uint64_t)(-1)) {
            ccprintf(ss, "(%#x)", errorCode);
        }

        return ss.str();
    }

    void X86Trap::invoke(ThreadContext * tc, StaticInstPtr inst)
    {
        X86FaultBase::invoke(tc);
        if (!FullSystem)
            return;

        // This is the same as a fault, but it happens -after- the
        // instruction.
        PCState pc = tc->pcState();
        pc.uEnd();
    }

    void X86Abort::invoke(ThreadContext * tc, StaticInstPtr inst)
    {
        panic("Abort exception!");
    }

    void
    InvalidOpcode::invoke(ThreadContext * tc, StaticInstPtr inst)
    {
        if (FullSystem) {
            X86Fault::invoke(tc, inst);
        } else {
            panic("Unrecognized/invalid instruction executed:\n %s",
                    inst->machInst);
        }
    }

    void PageFault::invoke(ThreadContext * tc, StaticInstPtr inst)
    {
        if (FullSystem) {
            HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
            X86FaultBase::invoke(tc);
            /*
             * If something bad happens while trying to enter the page fault
             * handler, I'm pretty sure that's a double fault and then all
             * bets are off. That means it should be safe to update this
             * state now.
             */
            if (m5reg.mode == LongMode) {
                tc->setMiscReg(MISCREG_CR2, addr);
            } else {
                tc->setMiscReg(MISCREG_CR2, (uint32_t)addr);
            }
        } else {
            PageFaultErrorCode code = errorCode;
            const char *modeStr = "";
            if (code.fetch)
                modeStr = "execute";
            else if (code.write)
                modeStr = "write";
            else
                modeStr = "read";
            panic("Tried to %s unmapped address %#x.\n", modeStr, addr);
        }
    }

    std::string
    PageFault::describe() const
    {
        std::stringstream ss;
        ccprintf(ss, "%s at %#x", X86FaultBase::describe(), addr);
        return ss.str();
    }

    void
    InitInterrupt::invoke(ThreadContext *tc, StaticInstPtr inst)
    {
        DPRINTF(Faults, "Init interrupt.\n");
        // The otherwise unmodified integer registers should be set to 0.
        for (int index = 0; index < NUM_INTREGS; index++) {
            tc->setIntReg(index, 0);
        }

        CR0 cr0 = tc->readMiscReg(MISCREG_CR0);
        CR0 newCR0 = 1 << 4;
        newCR0.cd = cr0.cd;
        newCR0.nw = cr0.nw;
        tc->setMiscReg(MISCREG_CR0, newCR0);
        tc->setMiscReg(MISCREG_CR2, 0);
        tc->setMiscReg(MISCREG_CR3, 0);
        tc->setMiscReg(MISCREG_CR4, 0);

        tc->setMiscReg(MISCREG_RFLAGS, 0x0000000000000002ULL);

        tc->setMiscReg(MISCREG_EFER, 0);

        SegAttr dataAttr = 0;
        dataAttr.dpl = 0;
        dataAttr.unusable = 0;
        dataAttr.defaultSize = 0;
        dataAttr.longMode = 0;
        dataAttr.avl = 0;
        dataAttr.granularity = 0;
        dataAttr.present = 1;
        dataAttr.type = 3;
        dataAttr.writable = 1;
        dataAttr.readable = 1;
        dataAttr.expandDown = 0;
        dataAttr.system = 1;

        for (int seg = 0; seg != NUM_SEGMENTREGS; seg++) {
            tc->setMiscReg(MISCREG_SEG_SEL(seg), 0);
            tc->setMiscReg(MISCREG_SEG_BASE(seg), 0);
            tc->setMiscReg(MISCREG_SEG_EFF_BASE(seg), 0);
            tc->setMiscReg(MISCREG_SEG_LIMIT(seg), 0xffff);
            tc->setMiscReg(MISCREG_SEG_ATTR(seg), dataAttr);
        }

        SegAttr codeAttr = 0;
        codeAttr.dpl = 0;
        codeAttr.unusable = 0;
        codeAttr.defaultSize = 0;
        codeAttr.longMode = 0;
        codeAttr.avl = 0;
        codeAttr.granularity = 0;
        codeAttr.present = 1;
        codeAttr.type = 10;
        codeAttr.writable = 0;
        codeAttr.readable = 1;
        codeAttr.expandDown = 0;
        codeAttr.system = 1;

        tc->setMiscReg(MISCREG_CS, 0xf000);
        tc->setMiscReg(MISCREG_CS_BASE,
                0x00000000ffff0000ULL);
        tc->setMiscReg(MISCREG_CS_EFF_BASE,
                0x00000000ffff0000ULL);
        // This has the base value pre-added.
        tc->setMiscReg(MISCREG_CS_LIMIT, 0xffffffff);
        tc->setMiscReg(MISCREG_CS_ATTR, codeAttr);

        PCState pc(0x000000000000fff0ULL + tc->readMiscReg(MISCREG_CS_BASE));
        tc->pcState(pc);

        tc->setMiscReg(MISCREG_TSG_BASE, 0);
        tc->setMiscReg(MISCREG_TSG_LIMIT, 0xffff);

        tc->setMiscReg(MISCREG_IDTR_BASE, 0);
        tc->setMiscReg(MISCREG_IDTR_LIMIT, 0xffff);

        tc->setMiscReg(MISCREG_TSL, 0);
        tc->setMiscReg(MISCREG_TSL_BASE, 0);
        tc->setMiscReg(MISCREG_TSL_LIMIT, 0xffff);
        tc->setMiscReg(MISCREG_TSL_ATTR, 0);

        tc->setMiscReg(MISCREG_TR, 0);
        tc->setMiscReg(MISCREG_TR_BASE, 0);
        tc->setMiscReg(MISCREG_TR_LIMIT, 0xffff);
        tc->setMiscReg(MISCREG_TR_ATTR, 0);

        // This value should be the family/model/stepping of the processor.
        // (page 418). It should be consistent with the value from CPUID, but
        // the actual value probably doesn't matter much.
        tc->setIntReg(INTREG_RDX, 0);

        tc->setMiscReg(MISCREG_DR0, 0);
        tc->setMiscReg(MISCREG_DR1, 0);
        tc->setMiscReg(MISCREG_DR2, 0);
        tc->setMiscReg(MISCREG_DR3, 0);

        tc->setMiscReg(MISCREG_DR6, 0x00000000ffff0ff0ULL);
        tc->setMiscReg(MISCREG_DR7, 0x0000000000000400ULL);

        tc->setMiscReg(MISCREG_MXCSR, 0x1f80);

        // Update the handy M5 Reg.
        tc->setMiscReg(MISCREG_M5_REG, 0);
        MicroPC entry = X86ISAInst::RomLabels::extern_label_initIntHalt;
        pc.upc(romMicroPC(entry));
        pc.nupc(romMicroPC(entry) + 1);
        tc->pcState(pc);
    }

    void
    StartupInterrupt::invoke(ThreadContext *tc, StaticInstPtr inst)
    {
        DPRINTF(Faults, "Startup interrupt with vector %#x.\n", vector);
        HandyM5Reg m5Reg = tc->readMiscReg(MISCREG_M5_REG);
        if (m5Reg.mode != LegacyMode || m5Reg.submode != RealMode) {
            panic("Startup IPI recived outside of real mode. "
                    "Don't know what to do. %d, %d", m5Reg.mode, m5Reg.submode);
        }

        tc->setMiscReg(MISCREG_CS, vector << 8);
        tc->setMiscReg(MISCREG_CS_BASE, vector << 12);
        tc->setMiscReg(MISCREG_CS_EFF_BASE, vector << 12);
        // This has the base value pre-added.
        tc->setMiscReg(MISCREG_CS_LIMIT, 0xffff);

        tc->pcState(tc->readMiscReg(MISCREG_CS_BASE));
    }
} // namespace X86ISA

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: SvXMLAutoCorrectExport.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 04:47:27 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svx.hxx"
#ifndef _SV_XMLAUTOCORRECTEXPORT_HXX
#include <SvXMLAutoCorrectExport.hxx>
#endif
#define _SVSTDARR_STRINGSISORTDTOR
#define _SVSTDARR_STRINGSDTOR
#include <svtools/svstdarr.hxx>
#ifndef _XMLOFF_XMLTOKEN_HXX
#include <xmloff/xmltoken.hxx>
#endif

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star;
using namespace ::xmloff::token;
using namespace ::rtl;

// #110680#
SvXMLAutoCorrectExport::SvXMLAutoCorrectExport(
    const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
    const SvxAutocorrWordList *  pNewAutocorr_List,
    const rtl::OUString &rFileName,
    com::sun::star::uno::Reference< com::sun::star::xml::sax::XDocumentHandler> &rHandler)
:   SvXMLExport( xServiceFactory, rFileName, rHandler ),
    pAutocorr_List( pNewAutocorr_List )
{
    _GetNamespaceMap().Add( GetXMLToken ( XML_NP_BLOCK_LIST),
                            GetXMLToken ( XML_N_BLOCK_LIST ),
                            XML_NAMESPACE_BLOCKLIST );
}

sal_uInt32 SvXMLAutoCorrectExport::exportDoc(enum XMLTokenEnum eClass)
{
    GetDocHandler()->startDocument();

    AddAttribute ( XML_NAMESPACE_NONE,
                   _GetNamespaceMap().GetAttrNameByKey ( XML_NAMESPACE_BLOCKLIST ),
                   _GetNamespaceMap().GetNameByKey ( XML_NAMESPACE_BLOCKLIST ) );
    {
        SvXMLElementExport aRoot (*this, XML_NAMESPACE_BLOCKLIST, XML_BLOCK_LIST, sal_True, sal_True);
        sal_uInt16 nBlocks= pAutocorr_List->Count();
        for ( sal_uInt16 i = 0; i < nBlocks; i++)
        {
            SvxAutocorrWord* p = pAutocorr_List->GetObject(i);

            AddAttribute( XML_NAMESPACE_BLOCKLIST,
                          XML_ABBREVIATED_NAME,
                          OUString(p->GetShort()));
            AddAttribute( XML_NAMESPACE_BLOCKLIST,
                          XML_NAME,
                          OUString(p->IsTextOnly() ? p->GetLong() : p->GetShort()));

            SvXMLElementExport aBlock( *this, XML_NAMESPACE_BLOCKLIST, XML_BLOCK, sal_True, sal_True);
        }
    }
    GetDocHandler()->endDocument();
    return 0;
}

// #110680#
SvXMLExceptionListExport::SvXMLExceptionListExport(
    const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
    const SvStringsISortDtor &rNewList,
    const rtl::OUString &rFileName,
    com::sun::star::uno::Reference< com::sun::star::xml::sax::XDocumentHandler> &rHandler)
:   SvXMLExport( xServiceFactory, rFileName, rHandler ),
    rList( rNewList )
{
    _GetNamespaceMap().Add( GetXMLToken ( XML_NP_BLOCK_LIST ),
                            GetXMLToken ( XML_N_BLOCK_LIST ),
                            XML_NAMESPACE_BLOCKLIST );
}

sal_uInt32 SvXMLExceptionListExport::exportDoc(enum XMLTokenEnum eClass)
{
    GetDocHandler()->startDocument();

    AddAttribute ( XML_NAMESPACE_NONE,
                   _GetNamespaceMap().GetAttrNameByKey ( XML_NAMESPACE_BLOCKLIST ),
                   _GetNamespaceMap().GetNameByKey ( XML_NAMESPACE_BLOCKLIST ) );
    {
        SvXMLElementExport aRoot (*this, XML_NAMESPACE_BLOCKLIST, XML_BLOCK_LIST, sal_True, sal_True);
        sal_uInt16 nBlocks= rList.Count();
        for ( sal_uInt16 i = 0; i < nBlocks; i++)
        {
            AddAttribute( XML_NAMESPACE_BLOCKLIST,
                          XML_ABBREVIATED_NAME,
                          OUString( *rList[i] ) );
            SvXMLElementExport aBlock( *this, XML_NAMESPACE_BLOCKLIST, XML_BLOCK, sal_True, sal_True);
        }
    }
    GetDocHandler()->endDocument();
    return 0;
}
<commit_msg>INTEGRATION: CWS sb59 (1.6.488); FILE MERGED 2006/08/03 13:51:39 cl 1.6.488.1: removed compiler warnings<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: SvXMLAutoCorrectExport.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: obo $ $Date: 2006-10-12 12:33:34 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svx.hxx"
#ifndef _SV_XMLAUTOCORRECTEXPORT_HXX
#include <SvXMLAutoCorrectExport.hxx>
#endif
#define _SVSTDARR_STRINGSISORTDTOR
#define _SVSTDARR_STRINGSDTOR
#include <svtools/svstdarr.hxx>
#ifndef _XMLOFF_XMLTOKEN_HXX
#include <xmloff/xmltoken.hxx>
#endif

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star;
using namespace ::xmloff::token;
using namespace ::rtl;

// #110680#
SvXMLAutoCorrectExport::SvXMLAutoCorrectExport(
    const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
    const SvxAutocorrWordList *  pNewAutocorr_List,
    const rtl::OUString &rFileName,
    com::sun::star::uno::Reference< com::sun::star::xml::sax::XDocumentHandler> &rHandler)
:   SvXMLExport( xServiceFactory, rFileName, rHandler ),
    pAutocorr_List( pNewAutocorr_List )
{
    _GetNamespaceMap().Add( GetXMLToken ( XML_NP_BLOCK_LIST),
                            GetXMLToken ( XML_N_BLOCK_LIST ),
                            XML_NAMESPACE_BLOCKLIST );
}

sal_uInt32 SvXMLAutoCorrectExport::exportDoc(enum XMLTokenEnum /*eClass*/)
{
    GetDocHandler()->startDocument();

    AddAttribute ( XML_NAMESPACE_NONE,
                   _GetNamespaceMap().GetAttrNameByKey ( XML_NAMESPACE_BLOCKLIST ),
                   _GetNamespaceMap().GetNameByKey ( XML_NAMESPACE_BLOCKLIST ) );
    {
        SvXMLElementExport aRoot (*this, XML_NAMESPACE_BLOCKLIST, XML_BLOCK_LIST, sal_True, sal_True);
        sal_uInt16 nBlocks= pAutocorr_List->Count();
        for ( sal_uInt16 i = 0; i < nBlocks; i++)
        {
            SvxAutocorrWord* p = pAutocorr_List->GetObject(i);

            AddAttribute( XML_NAMESPACE_BLOCKLIST,
                          XML_ABBREVIATED_NAME,
                          OUString(p->GetShort()));
            AddAttribute( XML_NAMESPACE_BLOCKLIST,
                          XML_NAME,
                          OUString(p->IsTextOnly() ? p->GetLong() : p->GetShort()));

            SvXMLElementExport aBlock( *this, XML_NAMESPACE_BLOCKLIST, XML_BLOCK, sal_True, sal_True);
        }
    }
    GetDocHandler()->endDocument();
    return 0;
}

// #110680#
SvXMLExceptionListExport::SvXMLExceptionListExport(
    const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
    const SvStringsISortDtor &rNewList,
    const rtl::OUString &rFileName,
    com::sun::star::uno::Reference< com::sun::star::xml::sax::XDocumentHandler> &rHandler)
:   SvXMLExport( xServiceFactory, rFileName, rHandler ),
    rList( rNewList )
{
    _GetNamespaceMap().Add( GetXMLToken ( XML_NP_BLOCK_LIST ),
                            GetXMLToken ( XML_N_BLOCK_LIST ),
                            XML_NAMESPACE_BLOCKLIST );
}

sal_uInt32 SvXMLExceptionListExport::exportDoc(enum XMLTokenEnum /*eClass*/)
{
    GetDocHandler()->startDocument();

    AddAttribute ( XML_NAMESPACE_NONE,
                   _GetNamespaceMap().GetAttrNameByKey ( XML_NAMESPACE_BLOCKLIST ),
                   _GetNamespaceMap().GetNameByKey ( XML_NAMESPACE_BLOCKLIST ) );
    {
        SvXMLElementExport aRoot (*this, XML_NAMESPACE_BLOCKLIST, XML_BLOCK_LIST, sal_True, sal_True);
        sal_uInt16 nBlocks= rList.Count();
        for ( sal_uInt16 i = 0; i < nBlocks; i++)
        {
            AddAttribute( XML_NAMESPACE_BLOCKLIST,
                          XML_ABBREVIATED_NAME,
                          OUString( *rList[i] ) );
            SvXMLElementExport aBlock( *this, XML_NAMESPACE_BLOCKLIST, XML_BLOCK, sal_True, sal_True);
        }
    }
    GetDocHandler()->endDocument();
    return 0;
}
<|endoftext|>