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 17002e1e58dfe19dd3e49a59c6827cbf51573941a2Mathias Agopian#include <binder/BufferedTextOutput.h> 18002e1e58dfe19dd3e49a59c6827cbf51573941a2Mathias Agopian#include <binder/Debug.h> 19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Atomic.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 26002e1e58dfe19dd3e49a59c6827cbf51573941a2Mathias Agopian#include <private/binder/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) { 52ed7a50cc7d490ae7aece2d16422c5f7941876468Christopher Tate size_t newSize = ((len+bufferPos)*3)/2; 53ed7a50cc7d490ae7aece2d16422c5f7941876468Christopher Tate if (newSize < (len+bufferPos)) return NO_MEMORY; // overflow 54ed7a50cc7d490ae7aece2d16422c5f7941876468Christopher Tate void* b = realloc(buffer, newSize); 55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!b) return NO_MEMORY; 56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project buffer = (char*)b; 57ed7a50cc7d490ae7aece2d16422c5f7941876468Christopher Tate bufferSize = newSize; 58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project memcpy(buffer+bufferPos, txt, len); 60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bufferPos += len; 61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project void restart() { 65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bufferPos = 0; 66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project atFront = true; 67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (bufferSize > 256) { 68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project void* b = realloc(buffer, 256); 69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (b) { 70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project buffer = (char*)b; 71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bufferSize = 256; 72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int32_t seq; 77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char* buffer; 78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t bufferPos; 79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t bufferSize; 80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bool atFront; 81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int32_t indent; 82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int32_t bundle; 83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; 84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstruct BufferedTextOutput::ThreadState 86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Vector<sp<BufferedTextOutput::BufferState> > states; 88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; 89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic mutex_t gMutex; 91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic thread_store_t tls; 93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectBufferedTextOutput::ThreadState* BufferedTextOutput::getThreadState() 95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ThreadState* ts = (ThreadState*) thread_store_get( &tls ); 97edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (ts) return ts; 98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ts = new ThreadState; 99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project thread_store_set( &tls, ts, threadDestructor ); 100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return ts; 101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid BufferedTextOutput::threadDestructor(void *st) 104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project delete ((ThreadState*)st); 106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic volatile int32_t gSequence = 0; 109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic volatile int32_t gFreeBufferIndex = -1; 111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic int32_t allocBufferIndex() 113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int32_t res = -1; 115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mutex_lock(&gMutex); 117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (gFreeBufferIndex >= 0) { 119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project res = gFreeBufferIndex; 120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project gFreeBufferIndex = gTextBuffers[res]; 121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project gTextBuffers.editItemAt(res) = -1; 122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project res = gTextBuffers.size(); 125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project gTextBuffers.add(-1); 126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mutex_unlock(&gMutex); 129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return res; 131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic void freeBufferIndex(int32_t idx) 134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mutex_lock(&gMutex); 136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project gTextBuffers.editItemAt(idx) = gFreeBufferIndex; 137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project gFreeBufferIndex = idx; 138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mutex_unlock(&gMutex); 139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectBufferedTextOutput::BufferedTextOutput(uint32_t flags) 144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : mFlags(flags) 145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project , mSeq(android_atomic_inc(&gSequence)) 146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project , mIndex(allocBufferIndex()) 147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mGlobalState = new BufferState(mSeq); 149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mGlobalState) mGlobalState->incStrong(this); 150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectBufferedTextOutput::~BufferedTextOutput() 153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mGlobalState) mGlobalState->decStrong(this); 155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project freeBufferIndex(mIndex); 156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t BufferedTextOutput::print(const char* txt, size_t len) 159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project //printf("BufferedTextOutput: printing %d\n", len); 161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project AutoMutex _l(mLock); 163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project BufferState* b = getBuffer(); 164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const char* const end = txt+len; 166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err; 168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project while (txt < end) { 170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Find the next line. 171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const char* first = txt; 172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project while (txt < end && *txt != '\n') txt++; 173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Include this and all following empty lines. 175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project while (txt < end && *txt == '\n') txt++; 176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Special cases for first data on a line. 178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (b->atFront) { 179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (b->indent > 0) { 180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // If this is the start of a line, add the indent. 181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const char* prefix = stringForIndent(b->indent); 182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project err = b->append(prefix, strlen(prefix)); 183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err != NO_ERROR) return err; 184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else if (*(txt-1) == '\n' && !b->bundle) { 186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Fast path: if we are not indenting or bundling, and 187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // have been given one or more complete lines, just write 188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // them out without going through the buffer. 189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Slurp up all of the lines. 191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const char* lastLine = txt+1; 192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project while (txt < end) { 193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (*txt++ == '\n') lastLine = txt; 194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project struct iovec vec; 196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project vec.iov_base = (void*)first; 197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project vec.iov_len = lastLine-first; 198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project //printf("Writing %d bytes of data!\n", vec.iov_len); 199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project writeLines(vec, 1); 200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project txt = lastLine; 201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project continue; 202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Append the new text to the buffer. 206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project err = b->append(first, txt-first); 207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err != NO_ERROR) return err; 208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project b->atFront = *(txt-1) == '\n'; 209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // If we have finished a line and are not bundling, write 211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // it out. 212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project //printf("Buffer is now %d bytes\n", b->bufferPos); 213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (b->atFront && !b->bundle) { 214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project struct iovec vec; 215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project vec.iov_base = b->buffer; 216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project vec.iov_len = b->bufferPos; 217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project //printf("Writing %d bytes of data!\n", vec.iov_len); 218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project writeLines(vec, 1); 219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project b->restart(); 220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid BufferedTextOutput::moveIndent(int delta) 227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project AutoMutex _l(mLock); 229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project BufferState* b = getBuffer(); 230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project b->indent += delta; 231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (b->indent < 0) b->indent = 0; 232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid BufferedTextOutput::pushBundle() 235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project AutoMutex _l(mLock); 237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project BufferState* b = getBuffer(); 238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project b->bundle++; 239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid BufferedTextOutput::popBundle() 242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project AutoMutex _l(mLock); 244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project BufferState* b = getBuffer(); 245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project b->bundle--; 246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOG_FATAL_IF(b->bundle < 0, 247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "TextOutput::popBundle() called more times than pushBundle()"); 248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (b->bundle < 0) b->bundle = 0; 249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (b->bundle == 0) { 251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Last bundle, write out data if it is complete. If it is not 252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // complete, don't write until the last line is done... this may 253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // or may not be the write thing to do, but it's the easiest. 254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (b->bufferPos > 0 && b->atFront) { 255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project struct iovec vec; 256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project vec.iov_base = b->buffer; 257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project vec.iov_len = b->bufferPos; 258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project writeLines(vec, 1); 259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project b->restart(); 260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectBufferedTextOutput::BufferState* BufferedTextOutput::getBuffer() const 265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if ((mFlags&MULTITHREADED) != 0) { 267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ThreadState* ts = getThreadState(); 268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (ts) { 269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project while (ts->states.size() <= (size_t)mIndex) ts->states.add(NULL); 270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project BufferState* bs = ts->states[mIndex].get(); 271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (bs != NULL && bs->seq == mSeq) return bs; 272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ts->states.editItemAt(mIndex) = new BufferState(mIndex); 274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bs = ts->states[mIndex].get(); 275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (bs != NULL) return bs; 276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mGlobalState; 280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 283