/*
 * Copyright (C) 2005 The Android Open Source Project
 *
 * 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 <binder/TextOutput.h>

#include <binder/Debug.h>

#include <utils/String8.h>
#include <utils/String16.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

namespace android {

// ---------------------------------------------------------------------------

TextOutput::TextOutput() { 
}

TextOutput::~TextOutput() { 
}

// ---------------------------------------------------------------------------

TextOutput& operator<<(TextOutput& to, bool val)
{
    if (val) to.print("true", 4);
    else to.print("false", 5);
    return to;
}

TextOutput& operator<<(TextOutput& to, int val)
{
    char buf[16];
    sprintf(buf, "%d", val);
    to.print(buf, strlen(buf));
    return to;
}

TextOutput& operator<<(TextOutput& to, long val)
{
    char buf[16];
    sprintf(buf, "%ld", val);
    to.print(buf, strlen(buf));
    return to;
}

TextOutput& operator<<(TextOutput& to, unsigned int val)
{
    char buf[16];
    sprintf(buf, "%u", val);
    to.print(buf, strlen(buf));
    return to;
}

TextOutput& operator<<(TextOutput& to, unsigned long val)
{
    char buf[16];
    sprintf(buf, "%lu", val);
    to.print(buf, strlen(buf));
    return to;
}

TextOutput& operator<<(TextOutput& to, long long val)
{
    char buf[32];
    sprintf(buf, "%Ld", val);
    to.print(buf, strlen(buf));
    return to;
}

TextOutput& operator<<(TextOutput& to, unsigned long long val)
{
    char buf[32];
    sprintf(buf, "%Lu", val);
    to.print(buf, strlen(buf));
    return to;
}

static TextOutput& print_float(TextOutput& to, double value)
{
    char buf[64];
    sprintf(buf, "%g", value);
    if( !strchr(buf, '.') && !strchr(buf, 'e') &&
        !strchr(buf, 'E') ) {
        strncat(buf, ".0", sizeof(buf)-1);
    }
    to.print(buf, strlen(buf));
    return to;
}

TextOutput& operator<<(TextOutput& to, float val)
{
    return print_float(to,val);
}

TextOutput& operator<<(TextOutput& to, double val)
{
    return print_float(to,val);
}

TextOutput& operator<<(TextOutput& to, const void* val)
{
    char buf[32];
    snprintf(buf, sizeof(buf), "%p", val);
    to.print(buf, strlen(buf));
    return to;
}

TextOutput& operator<<(TextOutput& to, const String8& val)
{
    to << val.string();
    return to;
}

TextOutput& operator<<(TextOutput& to, const String16& val)
{
    to << String8(val).string();
    return to;
}

static void textOutputPrinter(void* cookie, const char* txt)
{
    ((TextOutput*)cookie)->print(txt, strlen(txt));
}

TextOutput& operator<<(TextOutput& to, const TypeCode& val)
{
    printTypeCode(val.typeCode(), textOutputPrinter, (void*)&to);
    return to;
}

HexDump::HexDump(const void *buf, size_t size, size_t bytesPerLine)
    : mBuffer(buf)
    , mSize(size)
    , mBytesPerLine(bytesPerLine)
    , mSingleLineCutoff(16)
    , mAlignment(4)
    , mCArrayStyle(false)
{
    if (bytesPerLine >= 16) mAlignment = 4;
    else if (bytesPerLine >= 8) mAlignment = 2;
    else mAlignment = 1;
}

TextOutput& operator<<(TextOutput& to, const HexDump& val)
{
    printHexData(0, val.buffer(), val.size(), val.bytesPerLine(),
        val.singleLineCutoff(), val.alignment(), val.carrayStyle(),
        textOutputPrinter, (void*)&to);
    return to;
}

}; // namespace android
