BufferedTextOutput.cpp revision edbf3b6af777b721cd2a1ef461947e51e88241e1
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/* 2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License. 6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at 7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and 14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License. 15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/BufferedTextOutput.h> 18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Atomic.h> 20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Debug.h> 21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Log.h> 22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/RefBase.h> 23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Vector.h> 24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/threads.h> 25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <private/utils/Static.h> 27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdio.h> 29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdlib.h> 30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstruct BufferedTextOutput::BufferState : public RefBase 36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project BufferState(int32_t _seq) 38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : seq(_seq) 39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project , buffer(NULL) 40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project , bufferPos(0) 41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project , bufferSize(0) 42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project , atFront(true) 43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project , indent(0) 44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project , bundle(0) { 45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ~BufferState() { 47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project free(buffer); 48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t append(const char* txt, size_t len) { 51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if ((len+bufferPos) > bufferSize) { 52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project void* b = realloc(buffer, ((len+bufferPos)*3)/2); 53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!b) return NO_MEMORY; 54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project buffer = (char*)b; 55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project memcpy(buffer+bufferPos, txt, len); 57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bufferPos += len; 58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project void restart() { 62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bufferPos = 0; 63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project atFront = true; 64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (bufferSize > 256) { 65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project void* b = realloc(buffer, 256); 66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (b) { 67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project buffer = (char*)b; 68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bufferSize = 256; 69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int32_t seq; 74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char* buffer; 75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t bufferPos; 76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t bufferSize; 77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bool atFront; 78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int32_t indent; 79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int32_t bundle; 80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; 81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstruct BufferedTextOutput::ThreadState 83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Vector<sp<BufferedTextOutput::BufferState> > states; 85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; 86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic mutex_t gMutex; 88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic thread_store_t tls; 90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectBufferedTextOutput::ThreadState* BufferedTextOutput::getThreadState() 92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ThreadState* ts = (ThreadState*) thread_store_get( &tls ); 94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (ts) return ts; 95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ts = new ThreadState; 96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project thread_store_set( &tls, ts, threadDestructor ); 97edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return ts; 98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid BufferedTextOutput::threadDestructor(void *st) 101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project delete ((ThreadState*)st); 103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic volatile int32_t gSequence = 0; 106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic volatile int32_t gFreeBufferIndex = -1; 108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic int32_t allocBufferIndex() 110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int32_t res = -1; 112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mutex_lock(&gMutex); 114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (gFreeBufferIndex >= 0) { 116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project res = gFreeBufferIndex; 117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project gFreeBufferIndex = gTextBuffers[res]; 118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project gTextBuffers.editItemAt(res) = -1; 119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project res = gTextBuffers.size(); 122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project gTextBuffers.add(-1); 123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mutex_unlock(&gMutex); 126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return res; 128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic void freeBufferIndex(int32_t idx) 131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mutex_lock(&gMutex); 133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project gTextBuffers.editItemAt(idx) = gFreeBufferIndex; 134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project gFreeBufferIndex = idx; 135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mutex_unlock(&gMutex); 136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectBufferedTextOutput::BufferedTextOutput(uint32_t flags) 141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : mFlags(flags) 142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project , mSeq(android_atomic_inc(&gSequence)) 143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project , mIndex(allocBufferIndex()) 144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mGlobalState = new BufferState(mSeq); 146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mGlobalState) mGlobalState->incStrong(this); 147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectBufferedTextOutput::~BufferedTextOutput() 150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mGlobalState) mGlobalState->decStrong(this); 152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project freeBufferIndex(mIndex); 153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t BufferedTextOutput::print(const char* txt, size_t len) 156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project //printf("BufferedTextOutput: printing %d\n", len); 158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project AutoMutex _l(mLock); 160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project BufferState* b = getBuffer(); 161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const char* const end = txt+len; 163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err; 165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project while (txt < end) { 167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Find the next line. 168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const char* first = txt; 169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project while (txt < end && *txt != '\n') txt++; 170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Include this and all following empty lines. 172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project while (txt < end && *txt == '\n') txt++; 173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Special cases for first data on a line. 175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (b->atFront) { 176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (b->indent > 0) { 177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // If this is the start of a line, add the indent. 178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const char* prefix = stringForIndent(b->indent); 179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project err = b->append(prefix, strlen(prefix)); 180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err != NO_ERROR) return err; 181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else if (*(txt-1) == '\n' && !b->bundle) { 183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Fast path: if we are not indenting or bundling, and 184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // have been given one or more complete lines, just write 185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // them out without going through the buffer. 186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Slurp up all of the lines. 188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const char* lastLine = txt+1; 189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project while (txt < end) { 190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (*txt++ == '\n') lastLine = txt; 191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project struct iovec vec; 193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project vec.iov_base = (void*)first; 194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project vec.iov_len = lastLine-first; 195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project //printf("Writing %d bytes of data!\n", vec.iov_len); 196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project writeLines(vec, 1); 197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project txt = lastLine; 198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project continue; 199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Append the new text to the buffer. 203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project err = b->append(first, txt-first); 204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err != NO_ERROR) return err; 205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project b->atFront = *(txt-1) == '\n'; 206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // If we have finished a line and are not bundling, write 208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // it out. 209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project //printf("Buffer is now %d bytes\n", b->bufferPos); 210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (b->atFront && !b->bundle) { 211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project struct iovec vec; 212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project vec.iov_base = b->buffer; 213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project vec.iov_len = b->bufferPos; 214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project //printf("Writing %d bytes of data!\n", vec.iov_len); 215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project writeLines(vec, 1); 216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project b->restart(); 217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid BufferedTextOutput::moveIndent(int delta) 224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project AutoMutex _l(mLock); 226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project BufferState* b = getBuffer(); 227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project b->indent += delta; 228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (b->indent < 0) b->indent = 0; 229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid BufferedTextOutput::pushBundle() 232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project AutoMutex _l(mLock); 234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project BufferState* b = getBuffer(); 235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project b->bundle++; 236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid BufferedTextOutput::popBundle() 239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project AutoMutex _l(mLock); 241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project BufferState* b = getBuffer(); 242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project b->bundle--; 243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOG_FATAL_IF(b->bundle < 0, 244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "TextOutput::popBundle() called more times than pushBundle()"); 245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (b->bundle < 0) b->bundle = 0; 246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (b->bundle == 0) { 248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Last bundle, write out data if it is complete. If it is not 249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // complete, don't write until the last line is done... this may 250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // or may not be the write thing to do, but it's the easiest. 251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (b->bufferPos > 0 && b->atFront) { 252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project struct iovec vec; 253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project vec.iov_base = b->buffer; 254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project vec.iov_len = b->bufferPos; 255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project writeLines(vec, 1); 256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project b->restart(); 257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectBufferedTextOutput::BufferState* BufferedTextOutput::getBuffer() const 262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if ((mFlags&MULTITHREADED) != 0) { 264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ThreadState* ts = getThreadState(); 265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (ts) { 266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project while (ts->states.size() <= (size_t)mIndex) ts->states.add(NULL); 267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project BufferState* bs = ts->states[mIndex].get(); 268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (bs != NULL && bs->seq == mSeq) return bs; 269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ts->states.editItemAt(mIndex) = new BufferState(mIndex); 271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bs = ts->states[mIndex].get(); 272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (bs != NULL) return bs; 273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mGlobalState; 277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 280