(file) Return to printxml.cpp CVS log (file) (dir) Up to [OMI] / omi / xml / printxml

File: [OMI] / omi / xml / printxml / printxml.cpp (download)
Revision: 1.4, Mon Apr 20 17:20:37 2015 UTC (9 years, 2 months ago) by krisbash
Branch: MAIN
CVS Tags: OMI_1_0_8_2, OMI_1_0_8_1, HEAD
Changes since 1.3: +0 -0 lines
OMI 1.0.8-1

/*
**==============================================================================
**
** Open Management Infrastructure (OMI)
**
** Copyright (c) Microsoft Corporation
** 
** 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 
**
** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 
** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 
** MERCHANTABLITY OR NON-INFRINGEMENT. 
**
** See the Apache 2 License for the specific language governing permissions 
** and limitations under the License.
**
**==============================================================================
*/

#include <iostream>
#include <vector>
#include <cstdio>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <xml/xml.h>
#include <unistd.h>
#include <memory.h>
#include <stdlib.h>

using namespace std;
const char* arg0;

bool Inhale(const char* path, vector<char>& data)
{
    struct stat st;

    if (stat(path, &st) != 0)
    {
        cerr << arg0 << ": failed to stat file: " << path << endl;
        exit(1);
    }

    data.reserve(st.st_size + 1);

    FILE* is = fopen(path, "r");

    if (!is)
        return false;

    size_t n;
    char buf[4096];

    while ((n = fread(buf, 1, sizeof(buf), is)) != 0)
    {
        data.insert(data.end(), buf, buf + n);
    }

    data.push_back('\0');

    fclose(is);

    return true;
}

static void Indent(size_t level)
{
    size_t n = level * 2;

    for (size_t i = 0; i < n; i++)
    {
        putchar(' ');
    }
}

static void Print(const char* path)
{
    XML xml;
    XML_Elem e;
    int r;
    vector<char> data;
    size_t level = 0;

    if (!Inhale(path, data))
    {
        cerr << arg0 << ": failed to open " << path << endl;
        exit(1);
    }

    XML_Init(&xml);
    XML_SetText(&xml, &data[0]);

    while ((r = XML_Next(&xml, &e)) == 0)
    {
        switch (e.type)
        {
            case XML_NONE:
                break;
            case XML_INSTRUCTION:
            case XML_START:
            {
                Indent(level);

                if (e.type == XML_START)
                {
                    printf("<%.*s", (int)e.size, e.data);
                    level++;
                }
                else
                    printf("<?%.*s", (int)e.size, e.data);

                if (e.attrsSize)
                    printf(" ");

                for (size_t i = 0; i < e.attrsSize; i++)
                {
                    const XML_Attr& a = e.attrs[i];

                    printf("%s=\"%s\"", a.name, a.value);

                    if (i + 1 != e.attrsSize)
                    {
                        printf(" ");
                    }
                }

                if (e.type == XML_START)
                    printf(">\n");
                else
                    printf("?>\n");
                break;
            }
            case XML_END:
            {
                level--;
                Indent(level);
                printf("</%.*s>\n", (int)e.size, e.data);

                break;
            }
            case XML_CHARS:
            {
                Indent(level);
                printf("%.*s\n", (int)e.size, e.data);
                break;
            }
            case XML_COMMENT:
            {
                Indent(level);
                printf("<!--%.*s-->\n", (int)e.size, e.data);
                break;
            }
        }
    }

    if (r != 1)
    {
        char msg[1024];
        XML_FormatError(&xml, msg, sizeof(msg));
        printf("%s:%s\n", path, msg);
        exit(1);
    }
}

int main(int argc, char** argv)
{
    arg0 = argv[0];

    if (argc != 2)
    {
        cerr << "Usage: " << arg0 << " file" << endl;
        exit(1);
    }

    Print(argv[1]);

    return 0;
}

ViewCVS 0.9.2