From bb76335e5a434a6737676f6afd520e60914fcc7c Mon Sep 17 00:00:00 2001 From: Bernhard Amann Date: Mon, 3 Dec 2012 10:42:50 -0800 Subject: [PATCH] intermediate commit - it has been over a month since I touched this... --- src/AsciiInputOutput.cc | 149 ++++++++++++++++++++++++++++++++++++++++ src/AsciiInputOutput.h | 14 ++++ 2 files changed, 163 insertions(+) create mode 100644 src/AsciiInputOutput.cc create mode 100644 src/AsciiInputOutput.h diff --git a/src/AsciiInputOutput.cc b/src/AsciiInputOutput.cc new file mode 100644 index 0000000000..8e0227b4ab --- /dev/null +++ b/src/AsciiInputOutput.cc @@ -0,0 +1,149 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "config.h" + + +bool AsciiInputOutput::ValToText(ODesc* desc, Value* val, const Field* field) + { + if ( ! val->present ) + { + desc->AddN(unset_field, unset_field_len); + return true; + } + + switch ( val->type ) { + + case TYPE_BOOL: + desc->Add(val->val.int_val ? "T" : "F"); + break; + + case TYPE_INT: + desc->Add(val->val.int_val); + break; + + case TYPE_COUNT: + case TYPE_COUNTER: + desc->Add(val->val.uint_val); + break; + + case TYPE_PORT: + desc->Add(val->val.port_val.port); + break; + + case TYPE_SUBNET: + desc->Add(Render(val->val.subnet_val)); + break; + + case TYPE_ADDR: + desc->Add(Render(val->val.addr_val)); + break; + + case TYPE_DOUBLE: + // Rendering via Add() truncates trailing 0s after the + // decimal point. The difference with TIME/INTERVAL is mainly + // to keep the log format consistent. + desc->Add(val->val.double_val); + break; + + case TYPE_INTERVAL: + case TYPE_TIME: + // Rendering via Render() keeps trailing 0s after the decimal + // point. The difference with DOUBLEis mainly to keep the log + // format consistent. + desc->Add(Render(val->val.double_val)); + break; + + case TYPE_ENUM: + case TYPE_STRING: + case TYPE_FILE: + case TYPE_FUNC: + { + int size = val->val.string_val.length; + const char* data = val->val.string_val.data; + + if ( ! size ) + { + desc->AddN(empty_field, empty_field_len); + break; + } + + if ( size == unset_field_len && memcmp(data, unset_field, size) == 0 ) + { + // The value we'd write out would match exactly the + // place-holder we use for unset optional fields. We + // escape the first character so that the output + // won't be ambigious. + static const char hex_chars[] = "0123456789abcdef"; + char hex[6] = "\\x00"; + hex[2] = hex_chars[((*data) & 0xf0) >> 4]; + hex[3] = hex_chars[(*data) & 0x0f]; + desc->AddRaw(hex, 4); + + ++data; + --size; + } + + if ( size ) + desc->AddN(data, size); + + break; + } + + case TYPE_TABLE: + { + if ( ! val->val.set_val.size ) + { + desc->AddN(empty_field, empty_field_len); + break; + } + + desc->AddEscapeSequence(set_separator, set_separator_len); + for ( int j = 0; j < val->val.set_val.size; j++ ) + { + if ( j > 0 ) + desc->AddRaw(set_separator, set_separator_len); + + if ( ! DoWriteOne(desc, val->val.set_val.vals[j], field) ) + { + desc->RemoveEscapeSequence(set_separator, set_separator_len); + return false; + } + } + desc->RemoveEscapeSequence(set_separator, set_separator_len); + + break; + } + + case TYPE_VECTOR: + { + if ( ! val->val.vector_val.size ) + { + desc->AddN(empty_field, empty_field_len); + break; + } + + desc->AddEscapeSequence(set_separator, set_separator_len); + for ( int j = 0; j < val->val.vector_val.size; j++ ) + { + if ( j > 0 ) + desc->AddRaw(set_separator, set_separator_len); + + if ( ! DoWriteOne(desc, val->val.vector_val.vals[j], field) ) + { + desc->RemoveEscapeSequence(set_separator, set_separator_len); + return false; + } + } + desc->RemoveEscapeSequence(set_separator, set_separator_len); + + break; + } + + default: + Error(Fmt("unsupported field format %d for %s", val->type, field->name)); + return false; + } + + return true; + } + diff --git a/src/AsciiInputOutput.h b/src/AsciiInputOutput.h new file mode 100644 index 0000000000..fd34b6d398 --- /dev/null +++ b/src/AsciiInputOutput.h @@ -0,0 +1,14 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#ifndef AsciiInputOutput_h +#define AsciiInputOutput_h + +class AsciiInputOutput { + public: + // converts a threading value to the corresponding ascii representation + // returns false & logs an error with reporter in case an error occurs + bool ValToText(ODesc* desc, Value* val, const Field* field); + +}; + +#endif /* AsciiInputOuput_h */