/* ------------------------------------------------------------------------------ MetaCam - Extract EXIF information from digital camera files, with support for Vendor specific blocks. Copyright (C) 2000 Daniel Stephens (daniel@cheeseplant.org) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ------------------------------------------------------------------------------ */ static const char *rcsid __attribute__((unused))="$Id: ocontext.cc,v 1.5 2004/08/21 17:23:24 daniel Exp $"; #include "odrivers.h" #include OutputContext::~OutputContext() { } OutputDriver::~OutputDriver() { } DisplayOutputContext::~DisplayOutputContext() { } ostream & DisplayOutputContext::startBlock(const char *hdr) { static const char *static_pad = " "; static const int padl = strlen(static_pad); if (in_block) endBlock(); int hlen = strlen(hdr); if (hlen < padl) { o_stream << &static_pad[hlen]; } o_stream << hdr << ": "; in_block = true; return o_stream; } ostream & DisplayOutputContext::startBlock(const string &hdr) { static const char *static_pad = " "; static const int padl = strlen(static_pad); if (in_block) endBlock(); int hlen = hdr.length(); if (hlen < padl) { o_stream << &static_pad[hlen]; } o_stream << hdr << ": "; in_block = true; return o_stream; } ostream & DisplayOutputContext::os() { if (!in_block) { cerr << "Attempted to access output stream outside of block!" << endl; in_block = true; } return o_stream; } void DisplayOutputContext::endBlock() { if (!in_block) return; os() << endl; in_block = false; } DisplayOutputDriver::~DisplayOutputDriver() { // Nothing } void DisplayOutputDriver::startFile(const char *fname) { os << "File: " << fname << endl; } OutputContext * DisplayOutputDriver::startGroup(const char *header) { static const char *DASH_LINE = "--------------------------------------------------"; static const int DASH_LEN = strlen(DASH_LINE); if (current_context) endGroup(); int hlen = strlen(header); os << " " << header; if (hlen < DASH_LEN) { os << " " << &DASH_LINE[hlen]; } os << endl; return new DisplayOutputContext(os); } OutputContext * DisplayOutputDriver::startGroup(const string &header) { static const char *DASH_LINE = "--------------------------------------------------"; static const int DASH_LEN = strlen(DASH_LINE); if (current_context) endGroup(); int hlen = header.length(); os << " " << header; if (hlen < DASH_LEN) { os << " " << &DASH_LINE[hlen]; } os << endl; return new DisplayOutputContext(os); } void DisplayOutputDriver::endGroup() { if (current_context) { current_context->endBlock(); delete current_context; current_context = 0; } } void DisplayOutputDriver::endFile() { endGroup(); os << endl; } void DisplayOutputDriver::close() { endFile(); } XMLOutputContext::~XMLOutputContext() { // Does nothing } ostream & XMLOutputContext::startBlock(const char *hdr) { if (in_block) endBlock(); driver.outputRaw(" str()); driver.outputLine("/>"); delete str; str = 0; in_block = false; } XMLOutputDriver::XMLOutputDriver(ostream &o) : os(o), current_context(0), is_open(true), in_file(false) { outputLine(""); outputLine(""); } XMLOutputDriver::~XMLOutputDriver() { if (is_open) close(); } void XMLOutputDriver::startFile(const char *fname) { if (in_file) endFile(); outputRaw(" "); in_file = true; } OutputContext * XMLOutputDriver::startGroup(const char *header) { if (current_context) endGroup(); outputRaw(" "); current_context = new XMLOutputContext(*this); return current_context; } OutputContext * XMLOutputDriver::startGroup(const string &header) { if (current_context) endGroup(); outputRaw(" "); current_context = new XMLOutputContext(*this); return current_context; } void XMLOutputDriver::endGroup() { if (current_context) { current_context->endBlock(); delete current_context; current_context = 0; outputLine(" "); } } void XMLOutputDriver::endFile() { if (in_file) { endGroup(); outputLine(" "); in_file = false; } } void XMLOutputDriver::close() { if (is_open) { endFile(); outputLine(""); is_open = false; } } static const char *HEXES = "0123456789ABCDEF"; void XMLOutputDriver::outputCooked(const string &buf) { outputCooked(buf.data()); } void XMLOutputDriver::outputCooked(const char *buf) { char tmphex[8]; int last_output = 0; int i; for (i=0; buf[i]; ++i) { char c= buf[i]; if (isalnum(c)) continue; const char *encode =0; if ((c < ' ') || (c > 126)) { tmphex[0] = '&'; tmphex[1] = '#'; tmphex[2] = HEXES[(c >> 4) & 15]; tmphex[3] = HEXES[c & 15]; tmphex[4] = 0; encode = tmphex; } else if (c == '&') { encode = "&"; } else if (c == '<') { encode = "<"; } else if (c == '>') { encode = ">"; } else if (c == '\"') { encode = """; } if (!encode) continue; if (last_output < i) { os.write(&buf[last_output], i); } os << encode; last_output = i+1; } if (last_output < i) { os.write(&buf[last_output], i); } }